diff options
author | Matteo Beccati <mbeccati@php.net> | 2009-10-07 17:40:16 +0000 |
---|---|---|
committer | Matteo Beccati <mbeccati@php.net> | 2009-10-07 17:40:16 +0000 |
commit | 9ee8dd90a37bde92c387e473fa756c896f8d941e (patch) | |
tree | 8732125324189495aa0fd842f8fc8fc0d2e6a656 /ext | |
parent | 309fced64dacb409053684ab1eb837bb9bb758c4 (diff) | |
download | php-git-9ee8dd90a37bde92c387e473fa756c896f8d941e.tar.gz |
- Fixed bug #48764 (PDO_pgsql::query always uses implicit prepared statements if v3 proto available)
# original patch by Mark Kirkwood
Diffstat (limited to 'ext')
-rw-r--r-- | ext/pdo_pgsql/pdo_pgsql.c | 2 | ||||
-rw-r--r-- | ext/pdo_pgsql/pgsql_driver.c | 26 | ||||
-rw-r--r-- | ext/pdo_pgsql/php_pdo_pgsql_int.h | 7 | ||||
-rw-r--r-- | ext/pdo_pgsql/tests/bug48764.phpt | 134 |
4 files changed, 161 insertions, 8 deletions
diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c index b23c67d2ec..4259ae38d7 100644 --- a/ext/pdo_pgsql/pdo_pgsql.c +++ b/ext/pdo_pgsql/pdo_pgsql.c @@ -85,8 +85,8 @@ ZEND_GET_MODULE(pdo_pgsql) */ PHP_MINIT_FUNCTION(pdo_pgsql) { - php_pdo_register_driver(&pdo_pgsql_driver); REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT", PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT); + php_pdo_register_driver(&pdo_pgsql_driver); return SUCCESS; } /* }}} */ diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 4d4d8dbb9d..7ccbe09b3e 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -239,15 +239,13 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, } #if HAVE_PQPREPARE - else if (driver_options) { - if (pdo_attr_lval(driver_options, - PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, 0 TSRMLS_CC) == 1) { - emulate = 1; - } else if (pdo_attr_lval(driver_options, PDO_ATTR_EMULATE_PREPARES, - 0 TSRMLS_CC) == 1) { + if (pdo_attr_lval(driver_options, PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, H->disable_native_prepares TSRMLS_CC) == 1 || + pdo_attr_lval(driver_options, PDO_ATTR_EMULATE_PREPARES, H->emulate_prepares TSRMLS_CC) == 1) { emulate = 1; } + } else { + emulate = H->disable_native_prepares || H->emulate_prepares; } if (!emulate && PQprotocolVersion(H->server) > 2) { @@ -625,7 +623,21 @@ static const zend_function_entry *pdo_pgsql_get_driver_methods(pdo_dbh_t *dbh, i static int pdo_pgsql_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC) { - return 0; + pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; + + switch (attr) { +#if HAVE_PQPREPARE + case PDO_ATTR_EMULATE_PREPARES: + H->emulate_prepares = Z_LVAL_P(val); + return 1; + case PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT: + H->disable_native_prepares = Z_LVAL_P(val); + return 1; +#endif + + default: + return 0; + } } static struct pdo_dbh_methods pgsql_methods = { diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index e73320661c..50b478f340 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -43,6 +43,13 @@ typedef struct { unsigned _reserved:31; pdo_pgsql_error_info einfo; Oid pgoid; +#if HAVE_PQPREPARE + /* The following two variables have the same purpose. Unfortunately we need + to keep track of two different attributes having the same effect. + It might be worth to deprecate the driver specific one soon. */ + int emulate_prepares; + int disable_native_prepares; +#endif } pdo_pgsql_db_handle; typedef struct { diff --git a/ext/pdo_pgsql/tests/bug48764.phpt b/ext/pdo_pgsql/tests/bug48764.phpt new file mode 100644 index 0000000000..67e8f3971f --- /dev/null +++ b/ext/pdo_pgsql/tests/bug48764.phpt @@ -0,0 +1,134 @@ +--TEST-- +Bug #48764 (PDO_pgsql::query always uses implicit prepared statements if v3 proto available) +--SKIPIF-- +<?php +if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded'); +require dirname(__FILE__) . '/config.inc'; +require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc'; +PDOTest::skip(); + +$db = PDOTest::factory(); + +$client_version = $db->getAttribute(PDO::ATTR_CLIENT_VERSION); +$server_version = $db->getAttribute(PDO::ATTR_SERVER_VERSION); + +if (version_compare($server_version, '7.4', '<') || version_compare($client_version, '7.4', '<')) { + die('skip'); +} + +?> +--FILE-- +<?php +require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc'; +$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt'); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +echo "Test 1\n"; +bug($db); + +echo "Test 2\n"; +bug($db, array(PDO::ATTR_EMULATE_PREPARES => 0)); +bug($db, array(PDO::ATTR_EMULATE_PREPARES => 1)); + +echo "Test 3\n"; +bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0)); +bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 1)); + +echo "Test 4\n"; +$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1); +bug($db); +$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); +bug($db); + +echo "Test 5\n"; +$db->setAttribute(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, 1); +bug($db); +$db->setAttribute(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, 0); +bug($db); + + +putenv('PDOTEST_ATTR='.serialize(array( + PDO::ATTR_EMULATE_PREPARES => 1, +))); +$db = PDOTest::factory('PDO', false); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +echo "Test 6\n"; +bug($db); +bug($db, array(PDO::ATTR_EMULATE_PREPARES => 0)); +bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0)); + + +putenv('PDOTEST_ATTR='.serialize(array( + PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 1, +))); + +$db = PDOTest::factory('PDO', false); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +echo "Test 7\n"; +bug($db); +bug($db, array(PDO::ATTR_EMULATE_PREPARES => 0)); +bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0)); + + +putenv('PDOTEST_ATTR='.serialize(array( + PDO::ATTR_EMULATE_PREPARES => 1, + PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 1, +))); + +$db = PDOTest::factory('PDO', false); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +echo "Test 8\n"; +bug($db); +bug($db, array(PDO::ATTR_EMULATE_PREPARES => 0)); +bug($db, array(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0)); +bug($db, array( + PDO::ATTR_EMULATE_PREPARES => 0, + PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => 0, +)); + + +putenv('PDOTEST_ATTR'); + + +function bug($db, $options = array()) { + try { + $stmt = $db->prepare("SELECT ?", $options); + $stmt->execute(array(1)); + echo "OK\n"; + } catch (PDOException $e) { + // Indetermined data type when using native prepared statements + echo $e->getCode()."\n"; + } +} + +--EXPECT-- +Test 1 +42P18 +Test 2 +42P18 +OK +Test 3 +42P18 +OK +Test 4 +OK +42P18 +Test 5 +OK +42P18 +Test 6 +OK +42P18 +OK +Test 7 +OK +OK +42P18 +Test 8 +OK +OK +OK +42P18 |