summaryrefslogtreecommitdiff
path: root/ext/pdo_mysql/mysql_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_mysql/mysql_driver.c')
-rw-r--r--ext/pdo_mysql/mysql_driver.c95
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;