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

Reply via email to