Commit: 25aae37229a439109c020150d0f496ef4a237ecd Author: Matteo Beccati <mbecc...@php.net> Sun, 2 Jun 2013 06:29:35 +0200 Parents: 79803bebdea2827d66c0f96fd3dbaf4a2747ff27 Branches: PHP-5.3 PHP-5.4 PHP-5.5 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=25aae37229a439109c020150d0f496ef4a237ecd Log: Fixed bug #64609 (pg_convert enum type support) Bugs: https://bugs.php.net/64609 Changed paths: M NEWS M ext/pgsql/pgsql.c A ext/pgsql/tests/bug64609.phpt Diff: diff --git a/NEWS b/NEWS index 7889832..a1fbbcd 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,9 @@ PHP NEWS - PDO_pgsql: . Fixed bug #64949 (Buffer overflow in _pdo_pgsql_error). (Remi) +- pgsql: + - Fixed bug #64609 (pg_convert enum type support). (Matteo) + ?? ??? 2013, PHP 5.3.26 ### DO NOT ADD ENTRIES HERE, ADD THEM ABOVE FOR 5.3.27 ### diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index a0faed1..c5d9a4a 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -4875,7 +4875,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z } smart_str_appends(&querystr, - "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotNULL, a.atthasdef, a.attndims " + "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotnull, a.atthasdef, a.attndims, t.typtype = 'e' " "FROM pg_class as c, pg_attribute a, pg_type t, pg_namespace n " "WHERE a.attnum > 0 AND a.attrelid = c.oid AND c.relname = '"); tmp_name2 = php_addslashes(tmp_name2, strlen(tmp_name2), &new_len, 0 TSRMLS_CC); @@ -4921,6 +4921,12 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z add_assoc_bool(elem, "has default", 0); } add_assoc_long(elem, "array dims", atoi(PQgetvalue(pg_result,i,6))); + if (!strcmp(PQgetvalue(pg_result,i,7), "t")) { + add_assoc_bool(elem, "is enum", 1); + } + else { + add_assoc_bool(elem, "is enum", 0); + } name = PQgetvalue(pg_result,i,0); add_assoc_zval(meta, name, elem); } @@ -4954,7 +4960,18 @@ PHP_FUNCTION(pg_meta_data) zval_dtor(return_value); /* destroy array */ RETURN_FALSE; } -} + else { + HashPosition pos; + zval **val; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(return_value), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_P(return_value), (void **)&val, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_P(return_value), &pos)) { + /* delete newly added entry, in order to keep BC */ + zend_hash_del_key_or_index(Z_ARRVAL_PP(val), "is enum", sizeof("is enum"), 0, HASH_DEL_KEY); + } + } +} /* }}} */ /* {{{ php_pgsql_get_data_type @@ -5136,8 +5153,9 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con char *field = NULL; uint field_len = -1; ulong num_idx = -1; - zval *meta, **def, **type, **not_null, **has_default, **val, *new_val; + zval *meta, **def, **type, **not_null, **has_default, **is_enum, **val, *new_val; int new_len, key_type, err = 0, skip_field; + php_pgsql_data_type data_type; assert(pg_link != NULL); assert(Z_TYPE_P(values) == IS_ARRAY); @@ -5188,17 +5206,30 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'has default'"); err = 1; } + if (!err && zend_hash_find(Z_ARRVAL_PP(def), "is enum", sizeof("is enum"), (void **)&is_enum) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'is enum'"); + err = 1; + } if (!err && (Z_TYPE_PP(val) == IS_ARRAY || Z_TYPE_PP(val) == IS_OBJECT || Z_TYPE_PP(val) == IS_CONSTANT_ARRAY)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects scaler values as field values"); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects scalar values as field values"); err = 1; } if (err) { break; /* break out for() */ } ALLOC_INIT_ZVAL(new_val); - switch(php_pgsql_get_data_type(Z_STRVAL_PP(type), Z_STRLEN_PP(type))) + + if (Z_BVAL_PP(is_enum)) { + /* enums need to be treated like strings */ + data_type = PG_TEXT; + } + else { + data_type = php_pgsql_get_data_type(Z_STRVAL_PP(type), Z_STRLEN_PP(type)); + } + + switch(data_type) { case PG_BOOL: switch (Z_TYPE_PP(val)) { diff --git a/ext/pgsql/tests/bug64609.phpt b/ext/pgsql/tests/bug64609.phpt new file mode 100644 index 0000000..0df6301 --- /dev/null +++ b/ext/pgsql/tests/bug64609.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #64609 (pg_convert enum type support) +--SKIPIF-- +<?php +include("skipif.inc"); +skip_server_version('8.3', '<'); +?> +--FILE-- +<?php +error_reporting(E_ALL); + +include 'config.inc'; + +$db = pg_connect($conn_str); +pg_query("BEGIN"); +pg_query("CREATE TYPE t_enum AS ENUM ('ok', 'ko')"); +pg_query("CREATE TABLE test_enum (a t_enum)"); + +$fields = array('a' => 'ok'); +$converted = pg_convert($db, 'test_enum', $fields); + +pg_query("ROLLBACK"); + +var_dump($converted); +?> +--EXPECT-- +array(1) { + ["a"]=> + string(4) "'ok'" +} -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php