diff options
author | Anatol Belski <ab@php.net> | 2016-04-05 15:13:17 +0200 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2016-04-05 15:13:17 +0200 |
commit | ea4d27f47c47a197e3178f2a73e5f6d5655cbc02 (patch) | |
tree | e947b5ed0844138edd1f20e897df21c5319e20c5 /ext/pdo_pgsql | |
parent | b132aa49d1dced234ffc65a5757f46fe6c0450c7 (diff) | |
parent | df8f927446a53a7b4482d663295fe9ce2d72ec62 (diff) | |
download | php-git-ea4d27f47c47a197e3178f2a73e5f6d5655cbc02.tar.gz |
Merge branch 'PHP-7.0'
* PHP-7.0:
update NEWS
fix and extend test
Don't roundtrip to the database to get the column type if you already know it
Diffstat (limited to 'ext/pdo_pgsql')
-rw-r--r-- | ext/pdo_pgsql/pgsql_statement.c | 81 | ||||
-rw-r--r-- | ext/pdo_pgsql/tests/bug62498.phpt | 184 |
2 files changed, 240 insertions, 25 deletions
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index efa0aa787e..6a18d6dfb0 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -36,13 +36,27 @@ #endif /* from postgresql/src/include/catalog/pg_type.h */ +#define BOOLLABEL "bool" #define BOOLOID 16 +#define BYTEALABEL "bytea" #define BYTEAOID 17 -#define INT8OID 20 +#define DATELABEL "date" +#define DATEOID 1082 +#define INT2LABEL "int2" #define INT2OID 21 +#define INT4LABEL "int4" #define INT4OID 23 -#define TEXTOID 25 +#define INT8LABEL "int8" +#define INT8OID 20 #define OIDOID 26 +#define TEXTLABEL "text" +#define TEXTOID 25 +#define TIMESTAMPLABEL "timestamp" +#define TIMESTAMPOID 1114 +#define VARCHARLABEL "varchar" +#define VARCHAROID 1043 + + static int pgsql_stmt_dtor(pdo_stmt_t *stmt) { @@ -591,29 +605,46 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *r array_init(return_value); add_assoc_long(return_value, "pgsql:oid", S->cols[colno].pgsql_type); - /* Fetch metadata from Postgres system catalogue */ - spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", S->cols[colno].pgsql_type); - res = PQexec(S->H->server, q); - efree(q); - - status = PQresultStatus(res); - - if (status != PGRES_TUPLES_OK) { - /* Failed to get system catalogue, but return success - * with the data we have collected so far - */ - goto done; - } - - /* We want exactly one row returned */ - if (1 != PQntuples(res)) { - goto done; - } - - add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0)); -done: - PQclear(res); - return 1; + switch (S->cols[colno].pgsql_type) { + case BOOLOID: + add_assoc_string(return_value, "native_type", BOOLLABEL); + break; + case BYTEAOID: + add_assoc_string(return_value, "native_type", BYTEALABEL); + break; + case INT8OID: + add_assoc_string(return_value, "native_type", INT8LABEL); + break; + case INT2OID: + add_assoc_string(return_value, "native_type", INT2LABEL); + break; + case INT4OID: + add_assoc_string(return_value, "native_type", INT4LABEL); + break; + case TEXTOID: + add_assoc_string(return_value, "native_type", TEXTLABEL); + break; + case VARCHAROID: + add_assoc_string(return_value, "native_type", VARCHARLABEL); + break; + case DATEOID: + add_assoc_string(return_value, "native_type", DATELABEL); + break; + case TIMESTAMPOID: + add_assoc_string(return_value, "native_type", TIMESTAMPLABEL); + break; + default: + /* Fetch metadata from Postgres system catalogue */ + spprintf(&q, 0, "SELECT TYPNAME FROM PG_TYPE WHERE OID=%u", S->cols[colno].pgsql_type); + res = PQexec(S->H->server, q); + efree(q); + status = PQresultStatus(res); + if (status == PGRES_TUPLES_OK && 1 == PQntuples(res)) { + add_assoc_string(return_value, "native_type", PQgetvalue(res, 0, 0)); + } + PQclear(res); + } + return 1; } static int pdo_pgsql_stmt_cursor_closer(pdo_stmt_t *stmt) diff --git a/ext/pdo_pgsql/tests/bug62498.phpt b/ext/pdo_pgsql/tests/bug62498.phpt new file mode 100644 index 0000000000..e4ca3dec4f --- /dev/null +++ b/ext/pdo_pgsql/tests/bug62498.phpt @@ -0,0 +1,184 @@ +--TEST-- +PDO PgSQL Bug #62498 (pdo_pgsql inefficient when getColumnMeta() is used) +--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 +echo "Begin test...\n"; + +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); + +// create the table +$db->exec("CREATE TEMPORARY TABLE bugtest_62498 (int2col INT2, int4col INT4, int8col INT8, stringcol VARCHAR(255), boolcol BOOLEAN, datecol DATE, textcol TEXT, tscol TIMESTAMP, byteacol BYTEA)"); + +// insert some data +$statement = $db->prepare("INSERT INTO bugtest_62498 (int2col, int4col, int8col, stringcol, boolcol, datecol, textcol, tscol, byteacol) VALUES (:int2val, :int4val, :int8val, :stringval, :boolval, :dateval, :textval, :tsval, :byteaval)"); +$vals = array( + "int2val" => "42", + "int4val" => "42", + "int8val" => "42", + "stringval" => "The Answer", + "boolval" => true, + "dateval" => '2015-12-14', + "textval" => "some text", + "tsval" => 19990108, + "byteaval" => 0, +); +$statement->execute($vals); + +$select = $db->query('SELECT int2col, int4col, int8col, stringcol, boolcol, datecol, textcol, tscol, byteacol FROM bugtest_62498'); +$meta = []; +for ($i=0; $i < count($vals); $i++) { + $meta[] = $select->getColumnMeta($i); +} +var_dump($meta); + +?> +Done +--EXPECT-- +Begin test... +array(9) { + [0]=> + array(6) { + ["pgsql:oid"]=> + int(21) + ["native_type"]=> + string(4) "int2" + ["name"]=> + string(7) "int2col" + ["len"]=> + int(2) + ["precision"]=> + int(-1) + ["pdo_type"]=> + int(1) + } + [1]=> + array(6) { + ["pgsql:oid"]=> + int(23) + ["native_type"]=> + string(4) "int4" + ["name"]=> + string(7) "int4col" + ["len"]=> + int(4) + ["precision"]=> + int(-1) + ["pdo_type"]=> + int(1) + } + [2]=> + array(6) { + ["pgsql:oid"]=> + int(20) + ["native_type"]=> + string(4) "int8" + ["name"]=> + string(7) "int8col" + ["len"]=> + int(8) + ["precision"]=> + int(-1) + ["pdo_type"]=> + int(1) + } + [3]=> + array(6) { + ["pgsql:oid"]=> + int(1043) + ["native_type"]=> + string(7) "varchar" + ["name"]=> + string(9) "stringcol" + ["len"]=> + int(-1) + ["precision"]=> + int(259) + ["pdo_type"]=> + int(2) + } + [4]=> + array(6) { + ["pgsql:oid"]=> + int(16) + ["native_type"]=> + string(4) "bool" + ["name"]=> + string(7) "boolcol" + ["len"]=> + int(1) + ["precision"]=> + int(-1) + ["pdo_type"]=> + int(5) + } + [5]=> + array(6) { + ["pgsql:oid"]=> + int(1082) + ["native_type"]=> + string(4) "date" + ["name"]=> + string(7) "datecol" + ["len"]=> + int(4) + ["precision"]=> + int(-1) + ["pdo_type"]=> + int(2) + } + [6]=> + array(6) { + ["pgsql:oid"]=> + int(25) + ["native_type"]=> + string(4) "text" + ["name"]=> + string(7) "textcol" + ["len"]=> + int(-1) + ["precision"]=> + int(-1) + ["pdo_type"]=> + int(2) + } + [7]=> + array(6) { + ["pgsql:oid"]=> + int(1114) + ["native_type"]=> + string(9) "timestamp" + ["name"]=> + string(5) "tscol" + ["len"]=> + int(8) + ["precision"]=> + int(-1) + ["pdo_type"]=> + int(2) + } + [8]=> + array(6) { + ["pgsql:oid"]=> + int(17) + ["native_type"]=> + string(5) "bytea" + ["name"]=> + string(8) "byteacol" + ["len"]=> + int(-1) + ["precision"]=> + int(-1) + ["pdo_type"]=> + int(3) + } +} +Done |