diff options
Diffstat (limited to 'ext/pdo_mysql/mysql_driver.c')
-rw-r--r-- | ext/pdo_mysql/mysql_driver.c | 95 |
1 files changed, 53 insertions, 42 deletions
diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index c5c04adf8a..980a285c0d 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -1,7 +1,5 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | - +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | @@ -34,7 +32,7 @@ #endif #include "zend_exceptions.h" -#if defined(PDO_USE_MYSQLND) +#ifdef PDO_USE_MYSQLND # define pdo_mysql_init(persistent) mysqlnd_init(MYSQLND_CLIENT_NO_FLAG, persistent) #else # define pdo_mysql_init(persistent) mysql_init(NULL) @@ -75,12 +73,20 @@ int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int lin if (einfo->errcode) { if (einfo->errcode == 2014) { - einfo->errmsg = pestrdup( - "Cannot execute queries while other unbuffered queries are active. " - "Consider using PDOStatement::fetchAll(). Alternatively, if your code " - "is only ever going to run against mysql, you may enable query " - "buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.", - dbh->is_persistent); + if (mysql_more_results(H->server)) { + einfo->errmsg = pestrdup( + "Cannot execute queries while there are pending result sets. " + "Consider unsetting the previous PDOStatement or calling " + "PDOStatement::closeCursor()", + dbh->is_persistent); + } else { + einfo->errmsg = pestrdup( + "Cannot execute queries while other unbuffered queries are active. " + "Consider using PDOStatement::fetchAll(). Alternatively, if your code " + "is only ever going to run against mysql, you may enable query " + "buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.", + dbh->is_persistent); + } } else if (einfo->errcode == 2057) { einfo->errmsg = pestrdup( "A stored procedure returning result sets of different size was called. " @@ -223,8 +229,7 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len S->num_params = mysql_stmt_param_count(S->stmt); if (S->num_params) { - S->params_given = 0; -#if defined(PDO_USE_MYSQLND) +#ifdef PDO_USE_MYSQLND S->params = NULL; #else S->params = ecalloc(S->num_params, sizeof(MYSQL_BIND)); @@ -464,7 +469,7 @@ static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_ ZVAL_STRING(return_value, (char *)mysql_get_host_info(H->server)); break; case PDO_ATTR_SERVER_INFO: { -#if defined(PDO_USE_MYSQLND) +#ifdef PDO_USE_MYSQLND zend_string *tmp; if (mysqlnd_stat(H->server, &tmp) == PASS) { @@ -502,13 +507,11 @@ static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_ case PDO_MYSQL_ATTR_MAX_BUFFER_SIZE: ZVAL_LONG(return_value, H->max_buffer_size); break; -#else +#endif + case PDO_MYSQL_ATTR_LOCAL_INFILE: - ZVAL_BOOL( - return_value, - (H->server->data->options->flags & CLIENT_LOCAL_FILES) == CLIENT_LOCAL_FILES); + ZVAL_BOOL(return_value, H->local_infile); break; -#endif default: PDO_DBG_RETURN(0); @@ -536,11 +539,11 @@ static int pdo_mysql_check_liveness(pdo_dbh_t *dbh) /* {{{ pdo_mysql_request_shutdown */ static void pdo_mysql_request_shutdown(pdo_dbh_t *dbh) { - pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; - PDO_DBG_ENTER("pdo_mysql_request_shutdown"); PDO_DBG_INF_FMT("dbh=%p", dbh); + #ifdef PDO_USE_MYSQLND + pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; if (H->server) { mysqlnd_end_psession(H->server); } @@ -548,6 +551,21 @@ static void pdo_mysql_request_shutdown(pdo_dbh_t *dbh) } /* }}} */ +#ifdef PDO_USE_MYSQLND +# define pdo_mysql_get_server_status(m) mysqlnd_get_server_status(m) +#else +# define pdo_mysql_get_server_status(m) (m)->server_status +#endif + +/* {{{ pdo_mysql_in_transaction */ +static int pdo_mysql_in_transaction(pdo_dbh_t *dbh) +{ + pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; + PDO_DBG_ENTER("pdo_mysql_in_transaction"); + PDO_DBG_RETURN((pdo_mysql_get_server_status(H->server) & SERVER_STATUS_IN_TRANS) != 0); +} +/* }}} */ + /* {{{ mysql_methods */ static const struct pdo_dbh_methods mysql_methods = { mysql_handle_closer, @@ -564,7 +582,7 @@ static const struct pdo_dbh_methods mysql_methods = { pdo_mysql_check_liveness, NULL, pdo_mysql_request_shutdown, - NULL + pdo_mysql_in_transaction }; /* }}} */ @@ -597,7 +615,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) |CLIENT_MULTI_RESULTS #endif ; -#if defined(PDO_USE_MYSQLND) +#ifdef PDO_USE_MYSQLND size_t dbname_len = 0; size_t password_len = 0; #endif @@ -630,7 +648,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) pdo_mysql_error(dbh); goto cleanup; } -#if defined(PDO_USE_MYSQLND) +#ifdef PDO_USE_MYSQLND if (dbh->is_persistent) { mysqlnd_restart_psession(H->server); } @@ -655,7 +673,6 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* handle MySQL options */ if (driver_options) { zend_long connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30); - unsigned int local_infile = (unsigned int) pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_LOCAL_INFILE, 0); zend_string *init_cmd = NULL; #ifndef PDO_USE_MYSQLND zend_string *default_file = NULL, *default_group = NULL; @@ -689,17 +706,15 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) goto cleanup; } + if (pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_LOCAL_INFILE, 0)) { + H->local_infile = 1; #ifndef PDO_USE_MYSQLND - if (PG(open_basedir) && PG(open_basedir)[0] != '\0') { - local_infile = 0; - } + if (PG(open_basedir) && PG(open_basedir)[0] != '\0') { + H->local_infile = 0; + } #endif -#if defined(MYSQL_OPT_LOCAL_INFILE) || defined(PDO_USE_MYSQLND) - if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) { - pdo_mysql_error(dbh); - goto cleanup; } -#endif + #ifdef MYSQL_OPT_RECONNECT /* since 5.0.3, the default for this option is 0 if not specified. * we want the old behaviour @@ -803,23 +818,19 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) } } #endif - } else { -#if defined(MYSQL_OPT_LOCAL_INFILE) || defined(PDO_USE_MYSQLND) - // in case there are no driver options disable 'local infile' explicitly - unsigned int local_infile = 0; - if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) { - pdo_mysql_error(dbh); - goto cleanup; - } -#endif } -#ifdef PDO_MYSQL_HAS_CHARSET + /* Always explicitly set the LOCAL_INFILE option. */ + unsigned int local_infile = H->local_infile; + if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) { + pdo_mysql_error(dbh); + goto cleanup; + } + if (vars[0].optval && mysql_options(H->server, MYSQL_SET_CHARSET_NAME, vars[0].optval)) { pdo_mysql_error(dbh); goto cleanup; } -#endif dbname = vars[1].optval; host = vars[2].optval; |