mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fixed bug #47803
Executing prepared statements is succesfull only for the first two statements The reworked patch descends to the bug #69526 which is fixed by this as well. The broken logic in the current code was, that SQLDescribeParam was executed in odbc_execute every time. This piece is now moved into odbc_prepare and the results are carried on in an additional structure. Since the ext/odbc headers are not being currently installed and the corresponding structs like odbc_result are not used outside ext/odbc, the binary compatibility persists. Executing SQLDescribeParam only once in odbc_prepare is also an optimization as the filds usually won't change that fast and thus requestind the descriptions on every execution is not required.
This commit is contained in:
parent
9623d2dd83
commit
ff115e285a
2 changed files with 30 additions and 18 deletions
|
@ -442,6 +442,9 @@ static void _free_odbc_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||||
* zend_list_delete(res->conn_ptr->id);
|
* zend_list_delete(res->conn_ptr->id);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
if (res->param_info) {
|
||||||
|
efree(res->param_info);
|
||||||
|
}
|
||||||
efree(res);
|
efree(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1183,6 +1186,7 @@ PHP_FUNCTION(odbc_prepare)
|
||||||
odbc_result *result = NULL;
|
odbc_result *result = NULL;
|
||||||
odbc_connection *conn;
|
odbc_connection *conn;
|
||||||
RETCODE rc;
|
RETCODE rc;
|
||||||
|
int i;
|
||||||
#ifdef HAVE_SQL_EXTENDED_FETCH
|
#ifdef HAVE_SQL_EXTENDED_FETCH
|
||||||
SQLUINTEGER scrollopts;
|
SQLUINTEGER scrollopts;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1196,6 +1200,7 @@ PHP_FUNCTION(odbc_prepare)
|
||||||
result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
|
result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
|
||||||
|
|
||||||
result->numparams = 0;
|
result->numparams = 0;
|
||||||
|
result->param_info = NULL;
|
||||||
|
|
||||||
rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
|
rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
|
||||||
if (rc == SQL_INVALID_HANDLE) {
|
if (rc == SQL_INVALID_HANDLE) {
|
||||||
|
@ -1252,6 +1257,19 @@ PHP_FUNCTION(odbc_prepare)
|
||||||
zend_list_addref(conn->id);
|
zend_list_addref(conn->id);
|
||||||
result->conn_ptr = conn;
|
result->conn_ptr = conn;
|
||||||
result->fetched = 0;
|
result->fetched = 0;
|
||||||
|
|
||||||
|
result->param_info = (odbc_param_info *) safe_emalloc(sizeof(odbc_param_info), result->numparams, 0);
|
||||||
|
for (i=0;i<result->numparams;i++) {
|
||||||
|
rc = SQLDescribeParam(result->stmt, (SQLUSMALLINT)(i+1), &result->param_info[i].sqltype, &result->param_info[i].precision,
|
||||||
|
&result->param_info[i].scale, &result->param_info[i].nullable);
|
||||||
|
if (rc == SQL_ERROR) {
|
||||||
|
odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParameter");
|
||||||
|
SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
|
||||||
|
efree(result->param_info);
|
||||||
|
efree(result);
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
ZEND_REGISTER_RESOURCE(return_value, result, le_result);
|
ZEND_REGISTER_RESOURCE(return_value, result, le_result);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
@ -1272,9 +1290,7 @@ PHP_FUNCTION(odbc_execute)
|
||||||
params_t *params = NULL;
|
params_t *params = NULL;
|
||||||
char *filename;
|
char *filename;
|
||||||
unsigned char otype;
|
unsigned char otype;
|
||||||
SQLSMALLINT sqltype, ctype, scale;
|
SQLSMALLINT ctype;
|
||||||
SQLSMALLINT nullable;
|
|
||||||
SQLULEN precision;
|
|
||||||
odbc_result *result;
|
odbc_result *result;
|
||||||
int numArgs, i, ne;
|
int numArgs, i, ne;
|
||||||
RETCODE rc;
|
RETCODE rc;
|
||||||
|
@ -1332,22 +1348,10 @@ PHP_FUNCTION(odbc_execute)
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = SQLDescribeParam(result->stmt, (SQLUSMALLINT)i, &sqltype, &precision, &scale, &nullable);
|
|
||||||
params[i-1].vallen = Z_STRLEN_PP(tmp);
|
params[i-1].vallen = Z_STRLEN_PP(tmp);
|
||||||
params[i-1].fp = -1;
|
params[i-1].fp = -1;
|
||||||
if (rc == SQL_ERROR) {
|
|
||||||
odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParameter");
|
|
||||||
SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
|
|
||||||
for (i = 0; i < result->numparams; i++) {
|
|
||||||
if (params[i].fp != -1) {
|
|
||||||
close(params[i].fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
efree(params);
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_SQL_BINARY(sqltype)) {
|
if (IS_SQL_BINARY(result->param_info[i-1].sqltype)) {
|
||||||
ctype = SQL_C_BINARY;
|
ctype = SQL_C_BINARY;
|
||||||
} else {
|
} else {
|
||||||
ctype = SQL_C_CHAR;
|
ctype = SQL_C_CHAR;
|
||||||
|
@ -1394,7 +1398,7 @@ PHP_FUNCTION(odbc_execute)
|
||||||
params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0);
|
params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0);
|
||||||
|
|
||||||
rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT,
|
rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT,
|
||||||
ctype, sqltype, precision, scale,
|
ctype, result->param_info[i-1].sqltype, result->param_info[i-1].precision, result->param_info[i-1].scale,
|
||||||
(void *)params[i-1].fp, 0,
|
(void *)params[i-1].fp, 0,
|
||||||
¶ms[i-1].vallen);
|
¶ms[i-1].vallen);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1406,7 +1410,7 @@ PHP_FUNCTION(odbc_execute)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT,
|
rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT,
|
||||||
ctype, sqltype, precision, scale,
|
ctype, result->param_info[i-1].sqltype, result->param_info[i-1].precision, result->param_info[i-1].scale,
|
||||||
Z_STRVAL_PP(tmp), 0,
|
Z_STRVAL_PP(tmp), 0,
|
||||||
¶ms[i-1].vallen);
|
¶ms[i-1].vallen);
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,6 +233,13 @@ typedef struct odbc_result_value {
|
||||||
SQLLEN coltype;
|
SQLLEN coltype;
|
||||||
} odbc_result_value;
|
} odbc_result_value;
|
||||||
|
|
||||||
|
typedef struct odbc_param_info {
|
||||||
|
SQLSMALLINT sqltype;
|
||||||
|
SQLSMALLINT scale;
|
||||||
|
SQLSMALLINT nullable;
|
||||||
|
SQLULEN precision;
|
||||||
|
} odbc_param_info;
|
||||||
|
|
||||||
typedef struct odbc_result {
|
typedef struct odbc_result {
|
||||||
ODBC_SQL_STMT_T stmt;
|
ODBC_SQL_STMT_T stmt;
|
||||||
odbc_result_value *values;
|
odbc_result_value *values;
|
||||||
|
@ -244,6 +251,7 @@ typedef struct odbc_result {
|
||||||
long longreadlen;
|
long longreadlen;
|
||||||
int binmode;
|
int binmode;
|
||||||
int fetched;
|
int fetched;
|
||||||
|
odbc_param_info * param_info;
|
||||||
odbc_connection *conn_ptr;
|
odbc_connection *conn_ptr;
|
||||||
} odbc_result;
|
} odbc_result;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue