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_dblib | |
| 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_dblib')
| -rw-r--r-- | ext/pdo_dblib/dblib_stmt.c | 69 |
1 files changed, 12 insertions, 57 deletions
diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index 0dca4c79cf..03e69a4ac0 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -251,7 +251,6 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno) } col->maxlen = dbcollen(H->link, colno+1); - col->param_type = PDO_PARAM_ZVAL; return 1; } @@ -304,14 +303,12 @@ static int pdo_dblib_stmt_should_stringify_col(pdo_stmt_t *stmt, int coltype) return 0; } -static void pdo_dblib_stmt_stringify_col(int coltype, LPBYTE data, DBINT data_len, zval **ptr) +static void pdo_dblib_stmt_stringify_col(int coltype, LPBYTE data, DBINT data_len, zval *zv) { DBCHAR *tmp_data; - DBINT tmp_data_len; - zval *zv; /* FIXME: We allocate more than we need here */ - tmp_data_len = 32 + (2 * (data_len)); + DBINT tmp_data_len = 32 + (2 * (data_len)); switch (coltype) { case SQLDATETIME: @@ -326,7 +323,6 @@ static void pdo_dblib_stmt_stringify_col(int coltype, LPBYTE data, DBINT data_le tmp_data = emalloc(tmp_data_len); data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, (LPBYTE) tmp_data, tmp_data_len); - zv = emalloc(sizeof(zval)); if (data_len > 0) { /* to prevent overflows, tmp_data_len is provided as a dest len for dbconvert() * this code previously passed a dest len of -1 @@ -342,12 +338,9 @@ static void pdo_dblib_stmt_stringify_col(int coltype, LPBYTE data, DBINT data_le } efree(tmp_data); - - *ptr = zv; } -static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, - zend_ulong *len, int *caller_frees) +static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *zv, enum pdo_param_type *type) { pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; @@ -357,7 +350,6 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, LPBYTE data; DBCHAR *tmp_data; DBINT data_len, tmp_data_len; - zval *zv = NULL; coltype = dbcoltype(H->link, colno+1); data = dbdata(H->link, colno+1); @@ -365,10 +357,8 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, if (data_len != 0 || data != NULL) { if (pdo_dblib_stmt_should_stringify_col(stmt, coltype) && dbwillconvert(coltype, SQLCHAR)) { - pdo_dblib_stmt_stringify_col(coltype, data, data_len, &zv); - } - - if (!zv) { + pdo_dblib_stmt_stringify_col(coltype, data, data_len, zv); + } else { switch (coltype) { case SQLCHAR: case SQLVARCHAR: @@ -382,7 +372,6 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, case SQLVARBINARY: case SQLBINARY: case SQLIMAGE: { - zv = emalloc(sizeof(zval)); ZVAL_STRINGL(zv, (DBCHAR *) data, data_len); break; @@ -407,50 +396,31 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, #endif ); - zv = emalloc(sizeof(zval)); ZVAL_STRINGL(zv, tmp_data, dl); efree(tmp_data); break; } - case SQLFLT4: { - zv = emalloc(sizeof(zval)); + case SQLFLT4: ZVAL_DOUBLE(zv, *(DBFLT4 *) data); - break; - } - case SQLFLT8: { - zv = emalloc(sizeof(zval)); + case SQLFLT8: ZVAL_DOUBLE(zv, *(DBFLT8 *) data); - break; - } - case SQLINT8: { - zv = emalloc(sizeof(zval)); + case SQLINT8: ZVAL_LONG(zv, *(DBBIGINT *) data); - break; - } - case SQLINT4: { - zv = emalloc(sizeof(zval)); + case SQLINT4: ZVAL_LONG(zv, *(DBINT *) data); - break; - } - case SQLINT2: { - zv = emalloc(sizeof(zval)); + case SQLINT2: ZVAL_LONG(zv, *(DBSMALLINT *) data); - break; - } case SQLINT1: - case SQLBIT: { - zv = emalloc(sizeof(zval)); + case SQLBIT: ZVAL_LONG(zv, *(DBTINYINT *) data); - break; - } case SQLDECIMAL: case SQLNUMERIC: case SQLMONEY: @@ -458,10 +428,7 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, case SQLMONEYN: { DBFLT8 float_value; dbconvert(NULL, coltype, data, 8, SQLFLT8, (LPBYTE) &float_value, -1); - - zv = emalloc(sizeof(zval)); ZVAL_DOUBLE(zv, float_value); - break; } @@ -472,12 +439,10 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, tmp_data = safe_emalloc(tmp_data_len, sizeof(char), 1); data_len = dbconvert(NULL, SQLUNIQUE, data, data_len, SQLCHAR, (LPBYTE) tmp_data, tmp_data_len); php_strtoupper(tmp_data, data_len); - zv = emalloc(sizeof(zval)); ZVAL_STRINGL(zv, tmp_data, data_len); efree(tmp_data); } else { /* 16-byte binary representation */ - zv = emalloc(sizeof(zval)); ZVAL_STRINGL(zv, (DBCHAR *) data, 16); } break; @@ -485,7 +450,7 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, default: { if (dbwillconvert(coltype, SQLCHAR)) { - pdo_dblib_stmt_stringify_col(coltype, data, data_len, &zv); + pdo_dblib_stmt_stringify_col(coltype, data, data_len, zv); } break; @@ -494,16 +459,6 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, } } - if (zv != NULL) { - *ptr = (char*)zv; - *len = sizeof(zval); - } else { - *ptr = NULL; - *len = 0; - } - - *caller_frees = 1; - return 1; } |
