summaryrefslogtreecommitdiff
path: root/ext/odbc/php_odbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/odbc/php_odbc.c')
-rw-r--r--ext/odbc/php_odbc.c70
1 files changed, 41 insertions, 29 deletions
diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
index 11fecbd617..f432dcd551 100644
--- a/ext/odbc/php_odbc.c
+++ b/ext/odbc/php_odbc.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 |
@@ -387,7 +387,7 @@ const zend_function_entry odbc_functions[] = {
};
/* }}} */
-ZEND_DECLARE_MODULE_GLOBALS(odbc)
+PHP_ODBC_API ZEND_DECLARE_MODULE_GLOBALS(odbc)
static PHP_GINIT_FUNCTION(odbc);
/* {{{ odbc_module_entry
@@ -412,7 +412,7 @@ zend_module_entry odbc_module_entry = {
#ifdef COMPILE_DL_ODBC
#ifdef ZTS
-ZEND_TSRMLS_CACHE_DEFINE();
+ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(odbc)
#endif
@@ -434,7 +434,8 @@ static void _free_odbc_result(zend_resource *rsrc)
efree(res->values);
res->values = NULL;
}
- if (res->stmt) {
+ /* If aborted via timer expiration, don't try to call any unixODBC function */
+ if (res->stmt && !(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) {
#if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) || defined(HAVE_SOLID_35)
SQLTransact(res->conn_ptr->henv, res->conn_ptr->hdbc,
(SQLUSMALLINT) SQL_COMMIT);
@@ -445,6 +446,9 @@ static void _free_odbc_result(zend_resource *rsrc)
* zend_list_delete(res->conn_ptr->id);
*/
}
+ if (res->param_info) {
+ efree(res->param_info);
+ }
efree(res);
}
}
@@ -484,9 +488,12 @@ static void _close_odbc_conn(zend_resource *rsrc)
}
} ZEND_HASH_FOREACH_END();
- safe_odbc_disconnect(conn->hdbc);
- SQLFreeConnect(conn->hdbc);
- SQLFreeEnv(conn->henv);
+ /* If aborted via timer expiration, don't try to call any unixODBC function */
+ if (!(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) {
+ safe_odbc_disconnect(conn->hdbc);
+ SQLFreeConnect(conn->hdbc);
+ SQLFreeEnv(conn->henv);
+ }
efree(conn);
ODBCG(num_links)--;
}
@@ -509,9 +516,12 @@ static void _close_odbc_pconn(zend_resource *rsrc)
}
} ZEND_HASH_FOREACH_END();
- safe_odbc_disconnect(conn->hdbc);
- SQLFreeConnect(conn->hdbc);
- SQLFreeEnv(conn->henv);
+ /* If aborted via timer expiration, don't try to call any unixODBC function */
+ if (!(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) {
+ safe_odbc_disconnect(conn->hdbc);
+ SQLFreeConnect(conn->hdbc);
+ SQLFreeEnv(conn->henv);
+ }
free(conn);
ODBCG(num_links)--;
@@ -1184,6 +1194,7 @@ PHP_FUNCTION(odbc_prepare)
odbc_result *result = NULL;
odbc_connection *conn;
RETCODE rc;
+ int i;
#ifdef HAVE_SQL_EXTENDED_FETCH
SQLUINTEGER scrollopts;
#endif
@@ -1199,6 +1210,7 @@ PHP_FUNCTION(odbc_prepare)
result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
result->numparams = 0;
+ result->param_info = NULL;
rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
if (rc == SQL_INVALID_HANDLE) {
@@ -1255,6 +1267,20 @@ PHP_FUNCTION(odbc_prepare)
Z_ADDREF_P(pv_conn);
result->conn_ptr = conn;
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;
+ }
+ }
+
RETURN_RES(zend_register_resource(result, le_result));
}
/* }}} */
@@ -1275,9 +1301,7 @@ PHP_FUNCTION(odbc_execute)
params_t *params = NULL;
char *filename;
unsigned char otype;
- SQLSMALLINT sqltype, ctype, scale;
- SQLSMALLINT nullable;
- SQLULEN precision;
+ SQLSMALLINT ctype;
odbc_result *result;
int numArgs, i, ne;
RETCODE rc;
@@ -1337,22 +1361,10 @@ PHP_FUNCTION(odbc_execute)
RETURN_FALSE;
}
- rc = SQLDescribeParam(result->stmt, (SQLUSMALLINT)i, &sqltype, &precision, &scale, &nullable);
params[i-1].vallen = Z_STRLEN_P(tmp);
params[i-1].fp = -1;
- if (rc == SQL_ERROR) {
- odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParam");
- 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;
} else {
ctype = SQL_C_CHAR;
@@ -1399,7 +1411,7 @@ PHP_FUNCTION(odbc_execute)
params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0);
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 *)(intptr_t)params[i-1].fp, 0,
&params[i-1].vallen);
} else {
@@ -1411,7 +1423,7 @@ PHP_FUNCTION(odbc_execute)
}
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_P(tmp), 0,
&params[i-1].vallen);
}
@@ -1530,7 +1542,7 @@ PHP_FUNCTION(odbc_cursor)
result->stmt, state, &error, errormsg,
sizeof(errormsg)-1, &errormsgsize);
if (!strncmp(state,"S1015",5)) {
- snprintf(cursorname, max_len+1, "php_curs_%d", (int)result->stmt);
+ snprintf(cursorname, max_len+1, "php_curs_" ZEND_ULONG_FMT, (zend_ulong)result->stmt);
if (SQLSetCursorName(result->stmt,cursorname,SQL_NTS) != SQL_SUCCESS) {
odbc_sql_error(result->conn_ptr, result->stmt, "SQLSetCursorName");
RETVAL_FALSE;