summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite_statement.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-12-17 12:05:37 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-12-22 15:56:34 +0100
commitcaa710037e663fd78f67533b29611183090068b2 (patch)
tree7acbcdf527eb148899d6cb90e9f2cb233a3ec2ed /ext/pdo_sqlite/sqlite_statement.c
parent57d69b51373bfb1aa5117022c63c93c612e707f6 (diff)
downloadphp-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.c26
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;
}