]> granicus.if.org Git - php/commitdiff
Refactor PDO's last inserted ID handler to use and return zend_string
authorGeorge Peter Banyard <girgias@php.net>
Mon, 18 Jan 2021 16:29:32 +0000 (16:29 +0000)
committerGeorge Peter Banyard <girgias@php.net>
Tue, 19 Jan 2021 11:54:25 +0000 (11:54 +0000)
Closes GH-6617

UPGRADING.INTERNALS
ext/pdo/pdo.c
ext/pdo/pdo_dbh.c
ext/pdo/php_pdo_driver.h
ext/pdo_dblib/dblib_driver.c
ext/pdo_mysql/mysql_driver.c
ext/pdo_oci/oci_driver.c
ext/pdo_pgsql/pgsql_driver.c
ext/pdo_sqlite/sqlite_driver.c

index fcd5773fe5146685e62255efedb148055da867ad..39b26f3dae80c4e3517a83eab3f3f80b6b61d04d 100644 (file)
@@ -58,3 +58,6 @@ PHP 8.1 INTERNALS UPGRADE NOTES
       char* and size_t length.
     - The doer handler now accepts a zend_string* instead of char* + size_t
       pair for the SQL statement.
+    - The last_id handler now returns a zend_string* instead of returning a
+      char* and the length as an out param, and accepts a zend_string* instead
+      of char* for the optional sequence/table name.
index a66596ee544720f45ef1d217e8c659b3e2661c41..8ab9003fa815bb67ce2c65eed8eded9d6abae5ff 100644 (file)
@@ -248,8 +248,9 @@ PDO_API int php_pdo_parse_data_source(const char *data_source, zend_ulong data_s
 }
 /* }}} */
 
+/* TODO Refactor */
 static const char digit_vec[] = "0123456789";
-PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
+PDO_API zend_string *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
 {
        char buffer[65];
        char outbuf[65] = "";
@@ -257,17 +258,15 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
        zend_long long_val;
        char *dst = outbuf;
 
+       if (i64 == 0) {
+               return ZSTR_CHAR('0');
+       }
+
        if (i64 < 0) {
                i64 = -i64;
                *dst++ = '-';
        }
 
-       if (i64 == 0) {
-               *dst++ = '0';
-               *dst++ = '\0';
-               return estrdup(outbuf);
-       }
-
        p = &buffer[sizeof(buffer)-1];
        *p = '\0';
 
@@ -286,7 +285,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
        while ((*dst++ = *p++) != 0)
                ;
        *dst = '\0';
-       return estrdup(outbuf);
+       return zend_string_init(outbuf, strlen(outbuf), 0);
 }
 /* }}} */
 
index 2b1e7eab6be09e2e96ab9855195f5765f87b3d35..c1b3495a1b30fafc01b02c65b6dc8c08421a59e4 100644 (file)
@@ -941,12 +941,12 @@ PHP_METHOD(PDO, exec)
 PHP_METHOD(PDO, lastInsertId)
 {
        pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS);
-       char *name = NULL;
-       size_t namelen;
+       zend_string *name = NULL;
+       zend_string *last_id = NULL;
 
        ZEND_PARSE_PARAMETERS_START(0, 1)
                Z_PARAM_OPTIONAL
-               Z_PARAM_STRING_OR_NULL(name, namelen)
+               Z_PARAM_STR_OR_NULL(name)
        ZEND_PARSE_PARAMETERS_END();
 
        PDO_CONSTRUCT_CHECK;
@@ -956,19 +956,13 @@ PHP_METHOD(PDO, lastInsertId)
        if (!dbh->methods->last_id) {
                pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support lastInsertId()");
                RETURN_FALSE;
-       } else {
-               size_t id_len;
-               char *id;
-               id = dbh->methods->last_id(dbh, name, &id_len);
-               if (!id) {
-                       PDO_HANDLE_DBH_ERR();
-                       RETURN_FALSE;
-               } else {
-                       //??? use zend_string ?
-                       RETVAL_STRINGL(id, id_len);
-                       efree(id);
-               }
        }
+       last_id = dbh->methods->last_id(dbh, name);
+       if (!last_id) {
+               PDO_HANDLE_DBH_ERR();
+               RETURN_FALSE;
+       }
+       RETURN_STR(last_id);
 }
 /* }}} */
 
index f29749c4acb3c677e9e5f392bef5df7c2591197c..775ffd240f946faa1dd7e271aea3a875b4de9a57 100644 (file)
@@ -33,7 +33,7 @@ typedef unsigned __int64 pdo_uint64_t;
 typedef long long int pdo_int64_t;
 typedef unsigned long long int pdo_uint64_t;
 #endif
-PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64);
+PDO_API zend_string *php_pdo_int64_to_str(pdo_int64_t i64);
 
 #ifndef TRUE
 # define TRUE 1
@@ -247,9 +247,9 @@ typedef bool (*pdo_dbh_txn_func)(pdo_dbh_t *dbh);
  * Return true on success and false in case of failure */
 typedef bool (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, zend_long attr, zval *val);
 
-/* return last insert id.  NULL indicates error condition, otherwise, the return value
- * MUST be an emalloc'd NULL terminated string. */
-typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, size_t *len);
+/* return last insert id.  NULL indicates error condition.
+ * name MIGHT be NULL */
+typedef zend_string *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const zend_string *name);
 
 /* Fetch error information.
  * If stmt is not null, fetch information pertaining to the statement,
index f66ade482e2062eb2cadca55ad6bae783c92b99d..ae45da6beb4255d4a6943c3c10026f68872abad2 100644 (file)
@@ -222,12 +222,14 @@ static bool dblib_handle_rollback(pdo_dbh_t *dbh)
        return pdo_dblib_transaction_cmd("ROLLBACK TRANSACTION", dbh);
 }
 
-char *dblib_handle_last_id(pdo_dbh_t *dbh, const char *name, size_t *len)
+zend_string *dblib_handle_last_id(pdo_dbh_t *dbh, const zend_string *name)
 {
        pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
 
        RETCODE ret;
        char *id = NULL;
+       size_t len;
+       zend_string *ret_id;
 
        /*
         * Would use scope_identity() but it's not implemented on Sybase
@@ -260,10 +262,12 @@ char *dblib_handle_last_id(pdo_dbh_t *dbh, const char *name, size_t *len)
        }
 
        id = emalloc(32);
-       *len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)-1);
-
+       len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)-1);
        dbcancel(H->link);
-       return id;
+
+       ret_id = zend_string_init(id, len, 0);
+       efree(id);
+       return ret_id;
 }
 
 static bool dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
index cc70af6990c1443be094d9438eca88768ecb2d7c..6b42335878da89adde52bf48d50d66b4a39faace 100644 (file)
@@ -285,13 +285,11 @@ static zend_long mysql_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
 /* }}} */
 
 /* {{{ pdo_mysql_last_insert_id */
-static char *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
+static zend_string *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
 {
        pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
-       char *id = php_pdo_int64_to_str(mysql_insert_id(H->server));
        PDO_DBG_ENTER("pdo_mysql_last_insert_id");
-       *len = strlen(id);
-       PDO_DBG_RETURN(id);
+       PDO_DBG_RETURN(php_pdo_int64_to_str(mysql_insert_id(H->server)));
 }
 /* }}} */
 
index 8fae3ccd0546ccc5f53f7df620b540b5d6b611e1..dd4a7bb171318b545f3d702bcf2d894edcfc4bd8 100644 (file)
@@ -696,7 +696,7 @@ static const struct pdo_dbh_methods oci_methods = {
        oci_handle_commit,
        oci_handle_rollback,
        oci_handle_set_attribute,
-       NULL,
+       NULL, /* last_id not supported */
        pdo_oci_fetch_error_func,
        oci_handle_get_attribute,
        pdo_oci_check_liveness, /* check_liveness */
index 606623d708d6441e8a2ec4447e14549941549aa1..5f2827334a86e439f9eedc8ad2ff2fbe822b4f64 100644 (file)
@@ -352,10 +352,10 @@ static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo
        return quoted_str;
 }
 
-static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
+static zend_string *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
 {
        pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
-       char *id = NULL;
+       zend_string *id = NULL;
        PGresult *res;
        ExecStatusType status;
 
@@ -363,15 +363,14 @@ static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *
                res = PQexec(H->server, "SELECT LASTVAL()");
        } else {
                const char *q[1];
-               q[0] = name;
+               q[0] = ZSTR_VAL(name);
 
                res = PQexecParams(H->server, "SELECT CURRVAL($1)", 1, NULL, q, NULL, NULL, 0);
        }
        status = PQresultStatus(res);
 
        if (res && (status == PGRES_TUPLES_OK)) {
-               id = estrdup((char *)PQgetvalue(res, 0, 0));
-               *len = PQgetlength(res, 0, 0);
+               id = zend_string_init((char *)PQgetvalue(res, 0, 0), PQgetlength(res, 0, 0), 0);
        } else {
                pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res));
        }
index abf2e2253ff7c8c2c00de001d81e2f48105b0988..a48c77f9e88bcf7b285f5cbc24964dcf3ad82592 100644 (file)
@@ -216,14 +216,11 @@ static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
        }
 }
 
-static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
+static zend_string *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
 {
        pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
-       char *id;
 
-       id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
-       *len = strlen(id);
-       return id;
+       return php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
 }
 
 /* NB: doesn't handle binary strings... use prepared stmts for that */