summaryrefslogtreecommitdiff
path: root/ext/pdo_dblib
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_dblib
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_dblib')
-rw-r--r--ext/pdo_dblib/dblib_stmt.c69
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;
}