summaryrefslogtreecommitdiff
path: root/ext/pdo_firebird/firebird_statement.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_firebird/firebird_statement.c')
-rw-r--r--ext/pdo_firebird/firebird_statement.c88
1 files changed, 58 insertions, 30 deletions
diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c
index 337ce3fb66..64968428bd 100644
--- a/ext/pdo_firebird/firebird_statement.c
+++ b/ext/pdo_firebird/firebird_statement.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2015 The PHP Group |
+ | Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -98,9 +98,22 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
break;
}
S->cursor_open = 0;
- /* assume all params have been bound */
- if (isc_dsql_execute(H->isc_status, &H->tr, &S->stmt, PDO_FB_SQLDA_VERSION, S->in_sqlda)) {
+ /* allocate storage for the output data */
+ if (S->out_sqlda.sqld) {
+ unsigned int i;
+ for (i = 0; i < S->out_sqlda.sqld; i++) {
+ XSQLVAR *var = &S->out_sqlda.sqlvar[i];
+ var->sqlind = (void*)ecalloc(1, var->sqllen + 2 * sizeof(short));
+ var->sqldata = &((char*)var->sqlind)[sizeof(short)];
+ }
+ }
+
+ if (S->statement_type == isc_info_sql_stmt_exec_procedure) {
+ if (isc_dsql_execute2(H->isc_status, &H->tr, &S->stmt, PDO_FB_SQLDA_VERSION, S->in_sqlda, &S->out_sqlda)) {
+ break;
+ }
+ } else if (isc_dsql_execute(H->isc_status, &H->tr, &S->stmt, PDO_FB_SQLDA_VERSION, S->in_sqlda)) {
break;
}
@@ -139,8 +152,8 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
}
*S->name = 0;
- S->cursor_open = (S->out_sqlda.sqln > 0); /* A cursor is opened, when more than zero columns returned */
- S->exhausted = !S->cursor_open;
+ S->cursor_open = S->out_sqlda.sqln && (S->statement_type != isc_info_sql_stmt_exec_procedure);
+ S->exhausted = !S->out_sqlda.sqln; /* There are data to fetch */
return 1;
} while (0);
@@ -162,6 +175,11 @@ static int firebird_stmt_fetch(pdo_stmt_t *stmt, /* {{{ */
strcpy(stmt->error_code, "HY000");
H->last_app_error = "Cannot fetch from a closed cursor";
} else if (!S->exhausted) {
+ if (S->statement_type == isc_info_sql_stmt_exec_procedure) {
+ stmt->row_count = 1;
+ S->exhausted = 1;
+ return 1;
+ }
if (isc_dsql_fetch(H->isc_status, &S->stmt, PDO_FB_SQLDA_VERSION, &S->out_sqlda)) {
if (H->isc_status[0] && H->isc_status[1]) {
RECORD_ERROR(stmt);
@@ -169,9 +187,6 @@ static int firebird_stmt_fetch(pdo_stmt_t *stmt, /* {{{ */
S->exhausted = 1;
return 0;
}
- if (S->statement_type == isc_info_sql_stmt_exec_procedure) {
- S->exhausted = 1;
- }
stmt->row_count++;
return 1;
}
@@ -188,17 +203,13 @@ static int firebird_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */
int colname_len;
char *cp;
- /* allocate storage for the column */
- var->sqlind = (void*)ecalloc(1, var->sqllen + 2*sizeof(short));
- var->sqldata = &((char*)var->sqlind)[sizeof(short)];
-
colname_len = (S->H->fetch_table_names && var->relname_length)
? (var->aliasname_length + var->relname_length + 1)
: (var->aliasname_length);
col->precision = -var->sqlscale;
col->maxlen = var->sqllen;
col->name = zend_string_alloc(colname_len, 0);
- cp = col->name->val;
+ cp = ZSTR_VAL(col->name);
if (colname_len > var->aliasname_length) {
memmove(cp, var->relname, var->relname_length);
cp += var->relname_length;
@@ -223,7 +234,7 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ *
{
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
pdo_firebird_db_handle *H = S->H;
- isc_blob_handle blobh = NULL;
+ isc_blob_handle blobh = PDO_FIREBIRD_HANDLE_INITIALIZER;
char const bl_item = isc_info_blob_total_length;
char bl_info[20];
unsigned short i;
@@ -367,7 +378,7 @@ static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, /* {{
break;
case SQL_LONG:
*ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
- *len = slprintf(*ptr, CHAR_BUF_LEN, "%ld", *(ISC_LONG*)var->sqldata);
+ *len = slprintf(*ptr, CHAR_BUF_LEN, "%d", *(ISC_LONG*)var->sqldata);
break;
case SQL_INT64:
*ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
@@ -412,7 +423,8 @@ static int firebird_bind_blob(pdo_stmt_t *stmt, ISC_QUAD *blob_id, zval *param)
{
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
pdo_firebird_db_handle *H = S->H;
- isc_blob_handle h = NULL;
+ isc_blob_handle h = PDO_FIREBIRD_HANDLE_INITIALIZER;
+ zval data;
zend_ulong put_cnt = 0, rem_cnt;
unsigned short chunk_size;
int result = 1;
@@ -422,14 +434,16 @@ static int firebird_bind_blob(pdo_stmt_t *stmt, ISC_QUAD *blob_id, zval *param)
return 0;
}
- SEPARATE_ZVAL(param);
- convert_to_string_ex(param);
+ data = *param;
- for (rem_cnt = Z_STRLEN_P(param); rem_cnt > 0; rem_cnt -= chunk_size) {
+ if (Z_TYPE_P(param) != IS_STRING) {
+ zval_copy_ctor(&data);
+ convert_to_string(&data);
+ }
+ for (rem_cnt = Z_STRLEN(data); rem_cnt > 0; rem_cnt -= chunk_size) {
chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt;
-
- if (isc_put_segment(H->isc_status, &h, chunk_size, &Z_STRVAL_P(param)[put_cnt])) {
+ if (isc_put_segment(H->isc_status, &h, chunk_size, &Z_STRVAL(data)[put_cnt])) {
RECORD_ERROR(stmt);
result = 0;
break;
@@ -437,7 +451,9 @@ static int firebird_bind_blob(pdo_stmt_t *stmt, ISC_QUAD *blob_id, zval *param)
put_cnt += chunk_size;
}
- zval_dtor(param);
+ if (Z_TYPE_P(param) != IS_STRING) {
+ zval_dtor(&data);
+ }
if (isc_close_blob(H->isc_status, &h)) {
RECORD_ERROR(stmt);
@@ -475,10 +491,10 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
for (i = 0; i < sqlda->sqld; ++i) {
XSQLVAR *var = &sqlda->sqlvar[i];
- if ((var->aliasname_length && !strncasecmp(param->name->val, var->aliasname,
- min(param->name->len, var->aliasname_length)))
- || (var->sqlname_length && !strncasecmp(param->name->val, var->sqlname,
- min(param->name->len, var->sqlname_length)))) {
+ if ((var->aliasname_length && !strncasecmp(ZSTR_VAL(param->name), var->aliasname,
+ min(ZSTR_LEN(param->name), var->aliasname_length)))
+ || (var->sqlname_length && !strncasecmp(ZSTR_VAL(param->name), var->sqlname,
+ min(ZSTR_LEN(param->name), var->sqlname_length)))) {
param->paramno = i;
break;
}
@@ -523,12 +539,13 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
}
if (Z_TYPE_P(parameter) == IS_RESOURCE) {
- php_stream *stm;
+ php_stream *stm = NULL;
php_stream_from_zval_no_verify(stm, parameter);
if (stm) {
+ zend_string *mem = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
zval_ptr_dtor(parameter);
- ZVAL_STR(parameter, php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0));
+ ZVAL_STR(parameter, mem ? mem : ZSTR_EMPTY_ALLOC());
} else {
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
return 0;
@@ -541,8 +558,19 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
S->H->last_app_error = "Cannot bind to array field";
return 0;
- case SQL_BLOB:
+ case SQL_BLOB: {
+ if (Z_TYPE_P(parameter) == IS_NULL) {
+ /* Check if field allow NULL values */
+ if (~var->sqltype & 1) {
+ strcpy(stmt->error_code, "HY105");
+ S->H->last_app_error = "Parameter requires non-null value";
+ return 0;
+ }
+ *var->sqlind = -1;
+ return 1;
+ }
return firebird_bind_blob(stmt, (ISC_QUAD*)var->sqldata, parameter);
+ }
}
/* check if a NULL should be inserted */
@@ -631,7 +659,7 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
}
case PDO_PARAM_EVT_NORMALIZE:
if (!param->is_param) {
- char *s = param->name->val;
+ char *s = ZSTR_VAL(param->name);
while (*s != '\0') {
*s = toupper(*s);
s++;