diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-12-17 12:05:37 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-12-22 15:56:34 +0100 |
commit | caa710037e663fd78f67533b29611183090068b2 (patch) | |
tree | 7acbcdf527eb148899d6cb90e9f2cb233a3ec2ed /ext/pdo_sqlite/sqlite_statement.c | |
parent | 57d69b51373bfb1aa5117022c63c93c612e707f6 (diff) | |
download | php-git-caa710037e663fd78f67533b29611183090068b2.tar.gz |
Rewrite PDO result binding
Instead of requiring the type to be determined in advance by the
describer function and then requiring get_col to return a buffer
of appropriate type, allow get_col to return an arbitrary zval.
See UPGRADING.INTERNALS for a more detailed description of the
change.
This makes the result fetching simpler, more efficient and more
flexible. The general possibility already existed via the special
PDO_PARAM_ZVAL type, but the usage was very inconvenient and/or
inefficient. Now it's possible to easily implement behavior like
"return int if it fits, otherwise string" and to avoid any kind
of complex management of temporary buffers.
This also fixes bug #40913 (our second highest voted bug of all
time, for some reason). PARAM_LOB result bindings will now
consistently return a stream resource, independently of the used
database driver.
I've tried my best to update all PDO drivers for this change, but
some of the changes may be broken, as I cannot test or even build
some of these drivers (in particular PDO dblib and PDO oci).
Fixes are appreciated -- a working CI setup would be even more
appreciated ;)
Diffstat (limited to 'ext/pdo_sqlite/sqlite_statement.c')
-rw-r--r-- | ext/pdo_sqlite/sqlite_statement.c | 26 |
1 files changed, 8 insertions, 18 deletions
diff --git a/ext/pdo_sqlite/sqlite_statement.c b/ext/pdo_sqlite/sqlite_statement.c index 3769b1e049..66ec692cf8 100644 --- a/ext/pdo_sqlite/sqlite_statement.c +++ b/ext/pdo_sqlite/sqlite_statement.c @@ -247,21 +247,11 @@ static int pdo_sqlite_stmt_describe(pdo_stmt_t *stmt, int colno) stmt->columns[colno].maxlen = SIZE_MAX; stmt->columns[colno].precision = 0; - switch (sqlite3_column_type(S->stmt, colno)) { - case SQLITE_INTEGER: - case SQLITE_FLOAT: - case SQLITE3_TEXT: - case SQLITE_BLOB: - case SQLITE_NULL: - default: - stmt->columns[colno].param_type = PDO_PARAM_STR; - break; - } - return 1; } -static int pdo_sqlite_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_t *len, int *caller_frees) +static int pdo_sqlite_stmt_get_col( + pdo_stmt_t *stmt, int colno, zval *result, enum pdo_param_type *type) { pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data; if (!S->stmt) { @@ -274,18 +264,17 @@ static int pdo_sqlite_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size } switch (sqlite3_column_type(S->stmt, colno)) { case SQLITE_NULL: - *ptr = NULL; - *len = 0; + ZVAL_NULL(result); return 1; case SQLITE_BLOB: - *ptr = (char*)sqlite3_column_blob(S->stmt, colno); - *len = sqlite3_column_bytes(S->stmt, colno); + ZVAL_STRINGL_FAST(result, + sqlite3_column_blob(S->stmt, colno), sqlite3_column_bytes(S->stmt, colno)); return 1; default: - *ptr = (char*)sqlite3_column_text(S->stmt, colno); - *len = sqlite3_column_bytes(S->stmt, colno); + ZVAL_STRINGL_FAST(result, + (char *) sqlite3_column_text(S->stmt, colno), sqlite3_column_bytes(S->stmt, colno)); return 1; } } @@ -341,6 +330,7 @@ static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *ret #endif add_assoc_zval(return_value, "flags", &flags); + add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR); return SUCCESS; } |