diff options
author | Ondřej Surý <ondrej@sury.org> | 2010-03-09 11:57:54 +0100 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2010-03-09 11:57:54 +0100 |
commit | 855a09f4eded707941180c9d90acd17c25e29447 (patch) | |
tree | a40947efaa9876f31b6ee3956c3f3775768143bb /ext/pdo_pgsql | |
parent | c852c28a88fccf6e34a2cb091fdfa72bce2b59c7 (diff) | |
download | php-855a09f4eded707941180c9d90acd17c25e29447.tar.gz |
Imported Upstream version 5.3.2upstream/5.3.2
Diffstat (limited to 'ext/pdo_pgsql')
-rw-r--r-- | ext/pdo_pgsql/config.m4 | 2 | ||||
-rw-r--r-- | ext/pdo_pgsql/pdo_pgsql.c | 8 | ||||
-rw-r--r-- | ext/pdo_pgsql/pgsql_driver.c | 36 | ||||
-rw-r--r-- | ext/pdo_pgsql/pgsql_statement.c | 6 | ||||
-rw-r--r-- | ext/pdo_pgsql/php_pdo_pgsql.h | 4 | ||||
-rw-r--r-- | ext/pdo_pgsql/php_pdo_pgsql_int.h | 12 | ||||
-rw-r--r-- | ext/pdo_pgsql/tests/bug48764.phpt | 134 | ||||
-rw-r--r-- | ext/pdo_pgsql/tests/bug_33876.phpt | 10 | ||||
-rw-r--r-- | ext/pdo_pgsql/tests/bug_49985.phpt | 35 |
9 files changed, 220 insertions, 27 deletions
diff --git a/ext/pdo_pgsql/config.m4 b/ext/pdo_pgsql/config.m4 index 8e55524f5..f75d79196 100644 --- a/ext/pdo_pgsql/config.m4 +++ b/ext/pdo_pgsql/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4 279602 2009-04-30 12:38:43Z mbeccati $ +dnl $Id: config.m4 291414 2009-11-29 06:13:22Z rasmus $ dnl config.m4 for extension pdo_pgsql dnl vim:et:sw=2:ts=2: diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c index 40856557c..1be19cef7 100644 --- a/ext/pdo_pgsql/pdo_pgsql.c +++ b/ext/pdo_pgsql/pdo_pgsql.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_pgsql.c 277898 2009-03-28 01:58:49Z mbeccati $ */ +/* $Id: pdo_pgsql.c 293036 2010-01-03 09:23:27Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -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; } /* }}} */ @@ -128,7 +128,7 @@ PHP_MINFO_FUNCTION(pdo_pgsql) php_info_print_table_row(2, "PostgreSQL(libpq) Version", PG_VERSION); #endif php_info_print_table_row(2, "Module version", pdo_pgsql_module_entry.version); - php_info_print_table_row(2, "Revision", " $Id: pdo_pgsql.c 277898 2009-03-28 01:58:49Z mbeccati $ "); + php_info_print_table_row(2, "Revision", " $Id: pdo_pgsql.c 293036 2010-01-03 09:23:27Z sebastian $ "); php_info_print_table_end(); } diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index ef720cdac..32fd472e9 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pgsql_driver.c 279604 2009-04-30 12:56:00Z mbeccati $ */ +/* $Id: pgsql_driver.c 294444 2010-02-03 19:48:04Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -87,7 +87,7 @@ int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char * } if (!dbh->methods) { - zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s", + zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode TSRMLS_CC, "SQLSTATE[%s] [%d] %s", *pdo_err, einfo->errcode, einfo->errmsg); } @@ -232,22 +232,20 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, if (S->cursor_name) { efree(S->cursor_name); } - spprintf(&S->cursor_name, 0, "pdo_crsr_%016lx", (unsigned long) stmt); + spprintf(&S->cursor_name, 0, "pdo_crsr_%08x", ++H->stmt_counter); #if HAVE_PQPREPARE emulate = 1; #endif } #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) { @@ -264,7 +262,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, return 0; } - spprintf(&S->stmt_name, 0, "pdo_stmt_%016lx", (unsigned long)stmt); + spprintf(&S->stmt_name, 0, "pdo_stmt_%08x", ++H->stmt_counter); /* that's all for now; we'll defer the actual prepare until the first execute call */ if (nsql) { @@ -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/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index 85ae91367..8f2c8f85c 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pgsql_statement.c 281107 2009-05-25 19:41:13Z kalle $ */ +/* $Id: pgsql_statement.c 293036 2010-01-03 09:23:27Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -185,7 +185,7 @@ stmt_retry: * deallocate it and retry ONCE (thies 2005.12.15) */ if (!strcmp(sqlstate, "42P05")) { - char buf[100]; /* stmt_name == "pdo_crsr_%016lx" */ + char buf[100]; /* stmt_name == "pdo_crsr_%08x" */ PGresult *res; snprintf(buf, sizeof(buf), "DEALLOCATE %s", S->stmt_name); res = PQexec(H->server, buf); diff --git a/ext/pdo_pgsql/php_pdo_pgsql.h b/ext/pdo_pgsql/php_pdo_pgsql.h index 1760d61b4..9cdb176fd 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql.h +++ b/ext/pdo_pgsql/php_pdo_pgsql.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_pgsql.h 272370 2008-12-31 11:15:49Z sebastian $ */ +/* $Id: php_pdo_pgsql.h 293036 2010-01-03 09:23:27Z sebastian $ */ #ifndef PHP_PDO_PGSQL_H #define PHP_PDO_PGSQL_H diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index fb0a95ec3..a9c686ba1 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | + | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_pgsql_int.h 280407 2009-05-12 22:18:15Z mbeccati $ */ +/* $Id: php_pdo_pgsql_int.h 293036 2010-01-03 09:23:27Z sebastian $ */ #ifndef PHP_PDO_PGSQL_INT_H #define PHP_PDO_PGSQL_INT_H @@ -43,6 +43,14 @@ 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 + unsigned int stmt_counter; } 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 000000000..67e8f3971 --- /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 diff --git a/ext/pdo_pgsql/tests/bug_33876.phpt b/ext/pdo_pgsql/tests/bug_33876.phpt index 0ec04e8bd..48618e13d 100644 --- a/ext/pdo_pgsql/tests/bug_33876.phpt +++ b/ext/pdo_pgsql/tests/bug_33876.phpt @@ -80,10 +80,14 @@ else # Expected to fail; unless told otherwise, PDO assumes string inputs # false -> "" as string, which pgsql doesn't like -if (!$res->execute(array(false))) - print_r($res->errorInfo()); -else +if (!$res->execute(array(false))) { + $err = $res->errorInfo(); + // Strip additional lines ouputted by recent PgSQL versions + $err[2] = trim(current(explode("\n", $err[2]))); + print_r($err); +} else { print_r($res->fetchAll(PDO::FETCH_ASSOC)); +} diff --git a/ext/pdo_pgsql/tests/bug_49985.phpt b/ext/pdo_pgsql/tests/bug_49985.phpt new file mode 100644 index 000000000..26dcfc617 --- /dev/null +++ b/ext/pdo_pgsql/tests/bug_49985.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #49985 (pdo_pgsql prepare() re-use previous aborted transaction) +--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(); +?> +--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); + +$db->exec("CREATE TABLE test (a int PRIMARY KEY)"); + +for ($i = 0; $i < 3; $i++) { + try { + $db->beginTransaction(); + $stmt = $db->prepare("INSERT INTO test (a) VALUES (?)"); + var_dump($stmt->execute(array(1))); + $db->commit(); + } catch (Exception $e) { + echo trim(current(explode("\n", $e->getMessage())))."\n"; + $db->rollback(); + } +} + +?> +--EXPECTF-- +bool(true) +SQLSTATE[23505]: %s"test_pkey" +SQLSTATE[23505]: %s"test_pkey" + |