Skip to content

Commit a78aea8

Browse files
committed
Refactor PDO's last inserted ID handler to use and return zend_string
Closes GH-6617
1 parent 94ea8e2 commit a78aea8

File tree

9 files changed

+40
-46
lines changed

9 files changed

+40
-46
lines changed

UPGRADING.INTERNALS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,6 @@ PHP 8.1 INTERNALS UPGRADE NOTES
5858
char* and size_t length.
5959
- The doer handler now accepts a zend_string* instead of char* + size_t
6060
pair for the SQL statement.
61+
- The last_id handler now returns a zend_string* instead of returning a
62+
char* and the length as an out param, and accepts a zend_string* instead
63+
of char* for the optional sequence/table name.

ext/pdo/pdo.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,26 +248,25 @@ PDO_API int php_pdo_parse_data_source(const char *data_source, zend_ulong data_s
248248
}
249249
/* }}} */
250250

251+
/* TODO Refactor */
251252
static const char digit_vec[] = "0123456789";
252-
PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
253+
PDO_API zend_string *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
253254
{
254255
char buffer[65];
255256
char outbuf[65] = "";
256257
register char *p;
257258
zend_long long_val;
258259
char *dst = outbuf;
259260

261+
if (i64 == 0) {
262+
return ZSTR_CHAR('0');
263+
}
264+
260265
if (i64 < 0) {
261266
i64 = -i64;
262267
*dst++ = '-';
263268
}
264269

265-
if (i64 == 0) {
266-
*dst++ = '0';
267-
*dst++ = '\0';
268-
return estrdup(outbuf);
269-
}
270-
271270
p = &buffer[sizeof(buffer)-1];
272271
*p = '\0';
273272

@@ -286,7 +285,7 @@ PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64) /* {{{ */
286285
while ((*dst++ = *p++) != 0)
287286
;
288287
*dst = '\0';
289-
return estrdup(outbuf);
288+
return zend_string_init(outbuf, strlen(outbuf), 0);
290289
}
291290
/* }}} */
292291

ext/pdo/pdo_dbh.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -941,12 +941,12 @@ PHP_METHOD(PDO, exec)
941941
PHP_METHOD(PDO, lastInsertId)
942942
{
943943
pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS);
944-
char *name = NULL;
945-
size_t namelen;
944+
zend_string *name = NULL;
945+
zend_string *last_id = NULL;
946946

947947
ZEND_PARSE_PARAMETERS_START(0, 1)
948948
Z_PARAM_OPTIONAL
949-
Z_PARAM_STRING_OR_NULL(name, namelen)
949+
Z_PARAM_STR_OR_NULL(name)
950950
ZEND_PARSE_PARAMETERS_END();
951951

952952
PDO_CONSTRUCT_CHECK;
@@ -956,19 +956,13 @@ PHP_METHOD(PDO, lastInsertId)
956956
if (!dbh->methods->last_id) {
957957
pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support lastInsertId()");
958958
RETURN_FALSE;
959-
} else {
960-
size_t id_len;
961-
char *id;
962-
id = dbh->methods->last_id(dbh, name, &id_len);
963-
if (!id) {
964-
PDO_HANDLE_DBH_ERR();
965-
RETURN_FALSE;
966-
} else {
967-
//??? use zend_string ?
968-
RETVAL_STRINGL(id, id_len);
969-
efree(id);
970-
}
971959
}
960+
last_id = dbh->methods->last_id(dbh, name);
961+
if (!last_id) {
962+
PDO_HANDLE_DBH_ERR();
963+
RETURN_FALSE;
964+
}
965+
RETURN_STR(last_id);
972966
}
973967
/* }}} */
974968

ext/pdo/php_pdo_driver.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ typedef unsigned __int64 pdo_uint64_t;
3333
typedef long long int pdo_int64_t;
3434
typedef unsigned long long int pdo_uint64_t;
3535
#endif
36-
PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64);
36+
PDO_API zend_string *php_pdo_int64_to_str(pdo_int64_t i64);
3737

3838
#ifndef TRUE
3939
# define TRUE 1
@@ -247,9 +247,9 @@ typedef bool (*pdo_dbh_txn_func)(pdo_dbh_t *dbh);
247247
* Return true on success and false in case of failure */
248248
typedef bool (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, zend_long attr, zval *val);
249249

250-
/* return last insert id. NULL indicates error condition, otherwise, the return value
251-
* MUST be an emalloc'd NULL terminated string. */
252-
typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, size_t *len);
250+
/* return last insert id. NULL indicates error condition.
251+
* name MIGHT be NULL */
252+
typedef zend_string *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const zend_string *name);
253253

254254
/* Fetch error information.
255255
* If stmt is not null, fetch information pertaining to the statement,

ext/pdo_dblib/dblib_driver.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,14 @@ static bool dblib_handle_rollback(pdo_dbh_t *dbh)
222222
return pdo_dblib_transaction_cmd("ROLLBACK TRANSACTION", dbh);
223223
}
224224

225-
char *dblib_handle_last_id(pdo_dbh_t *dbh, const char *name, size_t *len)
225+
zend_string *dblib_handle_last_id(pdo_dbh_t *dbh, const zend_string *name)
226226
{
227227
pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
228228

229229
RETCODE ret;
230230
char *id = NULL;
231+
size_t len;
232+
zend_string *ret_id;
231233

232234
/*
233235
* 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)
260262
}
261263

262264
id = emalloc(32);
263-
*len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)-1);
264-
265+
len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)-1);
265266
dbcancel(H->link);
266-
return id;
267+
268+
ret_id = zend_string_init(id, len, 0);
269+
efree(id);
270+
return ret_id;
267271
}
268272

269273
static bool dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)

ext/pdo_mysql/mysql_driver.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,11 @@ static zend_long mysql_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
285285
/* }}} */
286286

287287
/* {{{ pdo_mysql_last_insert_id */
288-
static char *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
288+
static zend_string *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
289289
{
290290
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
291-
char *id = php_pdo_int64_to_str(mysql_insert_id(H->server));
292291
PDO_DBG_ENTER("pdo_mysql_last_insert_id");
293-
*len = strlen(id);
294-
PDO_DBG_RETURN(id);
292+
PDO_DBG_RETURN(php_pdo_int64_to_str(mysql_insert_id(H->server)));
295293
}
296294
/* }}} */
297295

ext/pdo_oci/oci_driver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ static const struct pdo_dbh_methods oci_methods = {
696696
oci_handle_commit,
697697
oci_handle_rollback,
698698
oci_handle_set_attribute,
699-
NULL,
699+
NULL, /* last_id not supported */
700700
pdo_oci_fetch_error_func,
701701
oci_handle_get_attribute,
702702
pdo_oci_check_liveness, /* check_liveness */

ext/pdo_pgsql/pgsql_driver.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -352,26 +352,25 @@ static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo
352352
return quoted_str;
353353
}
354354

355-
static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
355+
static zend_string *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
356356
{
357357
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
358-
char *id = NULL;
358+
zend_string *id = NULL;
359359
PGresult *res;
360360
ExecStatusType status;
361361

362362
if (name == NULL) {
363363
res = PQexec(H->server, "SELECT LASTVAL()");
364364
} else {
365365
const char *q[1];
366-
q[0] = name;
366+
q[0] = ZSTR_VAL(name);
367367

368368
res = PQexecParams(H->server, "SELECT CURRVAL($1)", 1, NULL, q, NULL, NULL, 0);
369369
}
370370
status = PQresultStatus(res);
371371

372372
if (res && (status == PGRES_TUPLES_OK)) {
373-
id = estrdup((char *)PQgetvalue(res, 0, 0));
374-
*len = PQgetlength(res, 0, 0);
373+
id = zend_string_init((char *)PQgetvalue(res, 0, 0), PQgetlength(res, 0, 0), 0);
375374
} else {
376375
pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res));
377376
}

ext/pdo_sqlite/sqlite_driver.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,11 @@ static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
216216
}
217217
}
218218

219-
static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
219+
static zend_string *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const zend_string *name)
220220
{
221221
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
222-
char *id;
223222

224-
id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
225-
*len = strlen(id);
226-
return id;
223+
return php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
227224
}
228225

229226
/* NB: doesn't handle binary strings... use prepared stmts for that */

0 commit comments

Comments
 (0)