Browse Source

- Fixed bug #48764 (PDO_pgsql::query always uses implicit prepared statements if v3 proto available)

# original patch by Mark Kirkwood
experimental/5.3-FPM
Matteo Beccati 17 years ago
parent
commit
9ee8dd90a3
  1. 2
      ext/pdo_pgsql/pdo_pgsql.c
  2. 26
      ext/pdo_pgsql/pgsql_driver.c
  3. 7
      ext/pdo_pgsql/php_pdo_pgsql_int.h
  4. 134
      ext/pdo_pgsql/tests/bug48764.phpt

2
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;
}
/* }}} */

26
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 = {

7
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 {

134
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
Loading…
Cancel
Save