summaryrefslogtreecommitdiff
path: root/ext/pdo_dblib/dblib_stmt.c
diff options
context:
space:
mode:
authorAdam Baratz <abaratz@wayfair.com>2016-04-06 12:18:53 +0200
committerAnatol Belski <ab@php.net>2016-04-06 12:18:53 +0200
commit1e1500a2bc30e0f7b0846e16567ffb3728f57eef (patch)
tree059846cc41bc1f6b66687d516cade356203a59fd /ext/pdo_dblib/dblib_stmt.c
parent354a682c3830cecce0e15ecff370865857e7fcd8 (diff)
downloadphp-git-1e1500a2bc30e0f7b0846e16567ffb3728f57eef.tar.gz
return zvals instead of strings, cast or not based on stringify attribute
Diffstat (limited to 'ext/pdo_dblib/dblib_stmt.c')
-rw-r--r--ext/pdo_dblib/dblib_stmt.c230
1 files changed, 164 insertions, 66 deletions
diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c
index 49b75ee2bb..6098ae515d 100644
--- a/ext/pdo_dblib/dblib_stmt.c
+++ b/ext/pdo_dblib/dblib_stmt.c
@@ -232,7 +232,7 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno)
}
col->maxlen = dbcollen(H->link, colno+1);
- col->param_type = PDO_PARAM_STR;
+ col->param_type = PDO_PARAM_ZVAL;
return 1;
}
@@ -245,78 +245,161 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
pdo_dblib_db_handle *H = S->H;
int coltype;
- unsigned int tmp_len;
- char *tmp_ptr = NULL;
+ char *data, *tmp_data;
+ unsigned int data_len, tmp_data_len;
+ zval *zv = NULL;
coltype = dbcoltype(H->link, colno+1);
-
- *len = dbdatlen(H->link, colno+1);
- *ptr = dbdata(H->link, colno+1);
-
- if (*len == 0 && *ptr == NULL) {
- return 1;
- }
-
- switch (coltype) {
- case SQLVARBINARY:
- case SQLBINARY:
- case SQLIMAGE:
- case SQLTEXT:
- /* FIXME: Above types should be returned as a stream as they can be VERY large */
- case SQLCHAR:
- case SQLVARCHAR:
- tmp_ptr = emalloc(*len + 1);
- memcpy(tmp_ptr, *ptr, *len);
- tmp_ptr[*len] = '\0';
- *ptr = tmp_ptr;
- break;
- case SQLMONEY:
- case SQLMONEY4:
- case SQLMONEYN: {
- DBFLT8 money_value;
- dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, 8);
- *len = spprintf(&tmp_ptr, 0, "%.4f", money_value);
- *ptr = tmp_ptr;
- break;
- }
- case SQLUNIQUE: {
- *len = 37;
- tmp_ptr = emalloc(*len + 1);
- *len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len);
- php_strtoupper(tmp_ptr, *len);
- tmp_ptr[36] = '\0';
- *ptr = tmp_ptr;
- break;
+ data = dbdata(H->link, colno+1);
+ data_len = dbdatlen(H->link, colno+1);
+
+ if (data_len != 0 || data != NULL) {
+ if (stmt->dbh->stringify) {
+ switch (coltype) {
+ case SQLFLT4:
+ case SQLFLT8:
+ case SQLINT4:
+ case SQLINT2:
+ case SQLINT1:
+ case SQLBIT: {
+ if (dbwillconvert(coltype, SQLCHAR)) {
+ tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
+ tmp_data = emalloc(tmp_data_len);
+ data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, tmp_data, -1);
+
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRING(zv, tmp_data);
+
+ efree(tmp_data);
+ }
+ break;
+ }
+ }
}
- case SQLDATETIM4:
- case SQLDATETIME: {
- DBDATETIME dt;
- DBDATEREC di;
-
- dbconvert(H->link, coltype, (BYTE*) *ptr, -1, SQLDATETIME, (LPBYTE) &dt, -1);
- dbdatecrack(H->link, &di, &dt);
- *len = spprintf((char**) &tmp_ptr, 20, "%d-%02d-%02d %02d:%02d:%02d",
+ if (!zv) {
+ switch (coltype) {
+ case SQLCHAR:
+ case SQLVARCHAR:
+ case SQLTEXT: {
+#if ilia_0
+ while (data_len>0 && data[data_len-1] == ' ') { /* nuke trailing whitespace */
+ data_len--;
+ }
+#endif
+ }
+ case SQLVARBINARY:
+ case SQLBINARY:
+ case SQLIMAGE: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRINGL(zv, data, data_len);
+
+ break;
+ }
+ case SQLDATETIME:
+ case SQLDATETIM4: {
+ int dl;
+ DBDATEREC di;
+ DBDATEREC dt;
+
+ dbconvert(H->link, coltype, data, -1, SQLDATETIME, (LPBYTE) &dt, -1);
+ dbdatecrack(H->link, &di, (DBDATETIME *) &dt);
+
+ dl = spprintf(&tmp_data, 20, "%d-%02d-%02d %02d:%02d:%02d",
#if defined(PHP_DBLIB_IS_MSSQL) || defined(MSDBLIB)
- di.year, di.month, di.day, di.hour, di.minute, di.second
+ di.year, di.month, di.day, di.hour, di.minute, di.second
+#else
+ di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond
+#endif
+ );
+
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRINGL(zv, tmp_data, dl);
+
+ efree(tmp_data);
+
+ break;
+ }
+ case SQLFLT4: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_DOUBLE(zv, (double) (*(DBFLT4 *) data));
+
+ break;
+ }
+ case SQLFLT8: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_DOUBLE(zv, (double) (*(DBFLT8 *) data));
+
+ break;
+ }
+ case SQLINT4: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_LONG(zv, (long) ((int) *(DBINT *) data));
+
+ break;
+ }
+ case SQLINT2: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_LONG(zv, (long) ((int) *(DBSMALLINT *) data));
+
+ break;
+ }
+ case SQLINT1:
+ case SQLBIT: {
+ zv = emalloc(sizeof(zval));
+ ZVAL_LONG(zv, (long) ((int) *(DBTINYINT *) data));
+
+ break;
+ }
+ case SQLMONEY:
+ case SQLMONEY4:
+ case SQLMONEYN: {
+ DBFLT8 money_value;
+ dbconvert(NULL, coltype, data, 8, SQLFLT8, (LPBYTE)&money_value, -1);
+
+ zv = emalloc(sizeof(zval));
+ ZVAL_DOUBLE(zv, money_value);
+
+ if (stmt->dbh->stringify) {
+ convert_to_string(zv);
+ }
+
+ break;
+ }
+#ifdef SQLUNIQUE
+ case SQLUNIQUE: {
#else
- di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond
+ case 36: { /* FreeTDS hack */
#endif
- );
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRINGL(zv, data, 16); /* uniqueidentifier is a 16-byte binary number */
- *ptr = (char*) tmp_ptr;
- break;
- }
- default:
- if (dbwillconvert(coltype, SQLCHAR)) {
- tmp_len = 32 + (2 * (*len)); /* FIXME: We allocate more than we need here */
- tmp_ptr = emalloc(tmp_len);
- *len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, -1);
- *ptr = tmp_ptr;
- } else {
- *len = 0; /* FIXME: Silently fails and returns null on conversion errors */
- *ptr = NULL;
+ break;
+ }
+ default: {
+ if (dbwillconvert(coltype, SQLCHAR)) {
+ tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
+ tmp_data = emalloc(tmp_data_len);
+ data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, tmp_data, -1);
+
+ zv = emalloc(sizeof(zval));
+ ZVAL_STRING(zv, tmp_data);
+
+ efree(tmp_data);
+ }
+
+ break;
+ }
}
+ }
+ }
+
+ if (zv != NULL) {
+ *ptr = (char*)zv;
+ *len = sizeof(zval);
+ } else {
+ *ptr = NULL;
+ *len = 0;
}
*caller_frees = 1;
@@ -335,6 +418,7 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zva
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
pdo_dblib_db_handle *H = S->H;
DBTYPEINFO* dbtypeinfo;
+ int coltype;
if(colno >= stmt->column_count || colno < 0) {
return FAILURE;
@@ -346,14 +430,28 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zva
if(!dbtypeinfo) return FAILURE;
+ coltype = dbcoltype(H->link, colno+1);
+
add_assoc_long(return_value, "max_length", dbcollen(H->link, colno+1) );
add_assoc_long(return_value, "precision", (int) dbtypeinfo->precision );
add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale );
add_assoc_string(return_value, "column_source", dbcolsource(H->link, colno+1));
- add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(dbcoltype(H->link, colno+1)));
- add_assoc_long(return_value, "native_type_id", dbcoltype(H->link, colno+1));
+ add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(coltype));
+ add_assoc_long(return_value, "native_type_id", coltype);
add_assoc_long(return_value, "native_usertype_id", dbcolutype(H->link, colno+1));
+ switch (coltype) {
+ case SQLBIT:
+ case SQLINT1:
+ case SQLINT2:
+ case SQLINT4:
+ add_assoc_long(return_value, "pdo_type", PDO_PARAM_INT);
+ break;
+ default:
+ add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
+ break;
+ }
+
return 1;
}