summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Baratz <adambaratz@php.net>2016-11-17 11:25:31 -0500
committerAdam Baratz <adambaratz@php.net>2016-11-17 11:25:31 -0500
commit07e395a00da85bde9086b3c6acfccafb2d5afa70 (patch)
treed7b6e95d2b419c5557791b4c640834e444846696
parente5d76c956a26afac3af0d105bd9fa6e861dd4946 (diff)
downloadphp-git-07e395a00da85bde9086b3c6acfccafb2d5afa70.tar.gz
Revert "Remove PDOStatement::activeQueryString()"
This reverts commit 552c95750052a5c4879a9c67e2f2ec126567222c.
-rw-r--r--NEWS3
-rw-r--r--ext/pdo/pdo_stmt.c34
-rw-r--r--ext/pdo/tests/active_query_string.phpt60
-rw-r--r--ext/pdo_dblib/dblib_driver.c5
4 files changed, 94 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index d56d533c17..7bacef200c 100644
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,9 @@ PHP NEWS
. Added array input support to mb_convert_encoding(). (Yasuo)
. Added array input support to mb_check_encoding(). (Yasuo)
+- PDO:
+ . Add PDOStatement::activeQueryString(). (Adam Baratz)
+
- PDO_DBlib:
. Fixed bug #73234 (Emulated statements let value dictate parameter type).
(Adam Baratz)
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 7aaf76453b..413b55da92 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -486,6 +486,12 @@ static PHP_METHOD(PDOStatement, execute)
* quoted.
*/
+ /* string is leftover from previous calls so PDOStatement::activeQueryString() can access */
+ if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
+ efree(stmt->active_query_string);
+ }
+ stmt->active_query_string = NULL;
+
ret = pdo_parse_params(stmt, stmt->query_string, stmt->query_stringlen,
&stmt->active_query_string, &stmt->active_query_stringlen);
@@ -504,10 +510,6 @@ static PHP_METHOD(PDOStatement, execute)
RETURN_FALSE;
}
if (stmt->methods->executer(stmt)) {
- if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
- efree(stmt->active_query_string);
- }
- stmt->active_query_string = NULL;
if (!stmt->executed) {
/* this is the first execute */
@@ -526,10 +528,6 @@ static PHP_METHOD(PDOStatement, execute)
RETURN_BOOL(ret);
}
- if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
- efree(stmt->active_query_string);
- }
- stmt->active_query_string = NULL;
PDO_HANDLE_STMT_ERR();
RETURN_FALSE;
}
@@ -2092,6 +2090,22 @@ static PHP_METHOD(PDOStatement, closeCursor)
}
/* }}} */
+/* {{{ proto string PDOStatement::activeQueryString()
+ Fetch the last executed query string associated with the statement handle */
+static PHP_METHOD(PDOStatement, activeQueryString)
+{
+ PHP_STMT_GET_OBJ;
+
+ if (stmt->active_query_string) {
+ RETURN_STRING(stmt->active_query_string);
+ } else if (stmt->query_string) {
+ RETURN_STRING(stmt->query_string);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
/* {{{ proto void PDOStatement::debugDumpParams()
A utility for internals hackers to debug parameter internals */
static PHP_METHOD(PDOStatement, debugDumpParams)
@@ -2170,6 +2184,7 @@ const zend_function_entry pdo_dbstmt_functions[] = {
PHP_ME(PDOStatement, setFetchMode, arginfo_pdostatement_setfetchmode, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, nextRowset, arginfo_pdostatement__void, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, closeCursor, arginfo_pdostatement__void, ZEND_ACC_PUBLIC)
+ PHP_ME(PDOStatement, activeQueryString, arginfo_pdostatement__void, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, debugDumpParams, arginfo_pdostatement__void, ZEND_ACC_PUBLIC)
PHP_ME(PDOStatement, __wakeup, arginfo_pdostatement__void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(PDOStatement, __sleep, arginfo_pdostatement__void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
@@ -2317,6 +2332,9 @@ PDO_API void php_pdo_free_statement(pdo_stmt_t *stmt)
if (stmt->methods && stmt->methods->dtor) {
stmt->methods->dtor(stmt);
}
+ if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) {
+ efree(stmt->active_query_string);
+ }
if (stmt->query_string) {
efree(stmt->query_string);
}
diff --git a/ext/pdo/tests/active_query_string.phpt b/ext/pdo/tests/active_query_string.phpt
new file mode 100644
index 0000000000..a0130e0275
--- /dev/null
+++ b/ext/pdo/tests/active_query_string.phpt
@@ -0,0 +1,60 @@
+--TEST--
+PDO Common: PDOStatement::activeQueryString()
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo')) die('skip');
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+
+$db = PDOTest::factory();
+if (!$db->getAttribute(PDO::ATTR_EMULATE_PREPARES) && !$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true)) die('skip driver cannot emulate prepared statements');
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+
+$db = PDOTest::factory();
+$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
+
+$quoted_true = $db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'pgsql' ? "'t'" : '1';
+
+$stmt = $db->query('SELECT 1');
+var_dump($stmt->activeQueryString()); // works with statements without bound values
+
+$stmt = $db->prepare('SELECT :bool, :int, :string, :null');
+$stmt->bindValue(':bool', true, PDO::PARAM_BOOL);
+$stmt->bindValue(':int', 123, PDO::PARAM_INT);
+$stmt->bindValue(':string', 'foo', PDO::PARAM_STR);
+$stmt->bindValue(':null', null, PDO::PARAM_NULL);
+
+var_dump($stmt->activeQueryString()); // will return unparsed query before execution
+
+$stmt->execute();
+
+// will return parsed query after execution
+var_dump($stmt->activeQueryString() == "SELECT " . $quoted_true . ", 123, 'foo', NULL");
+// can be called repeatedly
+var_dump($stmt->activeQueryString() == "SELECT " . $quoted_true . ", 123, 'foo', NULL");
+
+$stmt->execute();
+
+// works if the statement is executed again
+var_dump($stmt->activeQueryString() == "SELECT " . $quoted_true . ", 123, 'foo', NULL");
+
+$stmt->bindValue(':int', 456, PDO::PARAM_INT);
+$stmt->execute();
+
+// works with altered values
+var_dump($stmt->activeQueryString() == "SELECT " . $quoted_true . ", 456, 'foo', NULL");
+
+?>
+--EXPECT--
+string(8) "SELECT 1"
+string(34) "SELECT :bool, :int, :string, :null"
+bool(true)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
index 70d1a1cf60..f7f9f3872b 100644
--- a/ext/pdo_dblib/dblib_driver.c
+++ b/ext/pdo_dblib/dblib_driver.c
@@ -272,6 +272,11 @@ static int dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value)
{
switch (attr) {
+ case PDO_ATTR_EMULATE_PREPARES:
+ /* this is the only option available, but expose it so common tests and whatever else can introspect */
+ ZVAL_TRUE(return_value);
+ break;
+
case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
ZVAL_BOOL(return_value, ((pdo_dblib_db_handle *)dbh->driver_data)->stringify_uniqueidentifier);
break;