]> granicus.if.org Git - php/commitdiff
Implement FR #41146 - Add "description" with exteneded flag pg_meta_data().
authorYasuo Ohgaki <yohgaki@php.net>
Sun, 16 Feb 2014 21:19:47 +0000 (06:19 +0900)
committerYasuo Ohgaki <yohgaki@php.net>
Sun, 16 Feb 2014 21:24:10 +0000 (06:24 +0900)
pg_meta_data(resource $conn, string $table [, bool extended])
It also made pg_meta_data() return "is enum" always.

ext/pgsql/pgsql.c
ext/pgsql/php_pgsql.h
ext/pgsql/tests/11pg_meta_data.phpt
ext/pgsql/tests/pg_meta_data_001.phpt

index a4d2d4a0e03bfa42e8b131dd93edc1dd432e0f15..f8e15a370e2e4b1d3b93087d5bd0611ba1a4373b 100644 (file)
@@ -5172,7 +5172,7 @@ PHP_FUNCTION(pg_get_pid)
 /* {{{ php_pgsql_meta_data
  * TODO: Add meta_data cache for better performance
  */
-PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta TSRMLS_DC) 
+PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta, zend_bool extended TSRMLS_DC)
 {
        PGresult *pg_result;
        char *src, *tmp_name, *tmp_name2 = NULL;
@@ -5196,10 +5196,25 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z
                tmp_name = "public";
        }
 
-       smart_str_appends(&querystr, 
-                       "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 = '");
+       if (extended) {
+               smart_str_appends(&querystr,
+                                                 "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotNULL, a.atthasdef, a.attndims, t.typtype, "
+                                                 "d.description "
+                                                 "FROM pg_class as c "
+                                                 " JOIN pg_attribute a ON (a.attrelid = c.oid) "
+                                                 " JOIN pg_type t ON (a.atttypid = t.oid) "
+                                                 " JOIN pg_namespace n ON (c.relnamespace = n.oid) "
+                                                 " LEFT JOIN pg_description d ON (d.objoid=a.attrelid AND d.objsubid=a.attnum AND c.oid=d.objoid) "
+                                                 "WHERE a.attnum > 0  AND c.relname = '");
+       } else {
+               smart_str_appends(&querystr,
+                                                 "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotnull, a.atthasdef, a.attndims, t.typtype "
+                                                 "FROM pg_class as c "
+                                                 " JOIN pg_attribute a ON (a.attrelid = c.oid) "
+                                                 " JOIN pg_type t ON (a.atttypid = t.oid) "
+                                                 " JOIN pg_namespace n ON (c.relnamespace = n.oid) "
+                                                 "WHERE a.attnum > 0 AND c.relname = '");
+       }
        escaped = (char *)safe_emalloc(strlen(tmp_name2), 2, 1);
        new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, strlen(tmp_name2), NULL);
        if (new_len) {
@@ -5207,7 +5222,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z
        }
        efree(escaped);
 
-       smart_str_appends(&querystr, "' AND c.relnamespace = n.oid AND n.nspname = '");
+       smart_str_appends(&querystr, "' AND n.nspname = '");
        escaped = (char *)safe_emalloc(strlen(tmp_name), 2, 1);
        new_len = PQescapeStringConn(pg_link, escaped, tmp_name, strlen(tmp_name), NULL);
        if (new_len) {
@@ -5215,7 +5230,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z
        }
        efree(escaped);
 
-       smart_str_appends(&querystr, "' AND a.atttypid = t.oid ORDER BY a.attnum;");
+       smart_str_appends(&querystr, "' ORDER BY a.attnum;");
        smart_str_0(&querystr);
        efree(src);
 
@@ -5232,28 +5247,41 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z
                char *name;
                MAKE_STD_ZVAL(elem);
                array_init(elem);
+               /* pg_attribute.attnum */
                add_assoc_long(elem, "num", atoi(PQgetvalue(pg_result,i,1)));
+               /* pg_type.typname */
                add_assoc_string(elem, "type", PQgetvalue(pg_result,i,2), 1);
+               /* pg_attribute.attlen */
                add_assoc_long(elem, "len", atoi(PQgetvalue(pg_result,i,3)));
-               if (!strcmp(PQgetvalue(pg_result,i,4), "t")) {
-                       add_assoc_bool(elem, "not null", 1);
-               }
-               else {
+               /* pg_attribute.attnonull */
+               !strcmp(PQgetvalue(pg_result,i,4), "t") ?
+                       add_assoc_bool(elem, "not null", 1) :
                        add_assoc_bool(elem, "not null", 0);
-               }
-               if (!strcmp(PQgetvalue(pg_result,i,5), "t")) {
-                       add_assoc_bool(elem, "has default", 1);
-               }
-               else {
+               /* pg_attribute.atthasdef */
+               !strcmp(PQgetvalue(pg_result,i,5), "t") ?
+                       add_assoc_bool(elem, "has default", 1) :
                        add_assoc_bool(elem, "has default", 0);
-               }
+               /* pg_attribute.attndims */
                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 {
+               /* pg_type.typtype */
+               !strcmp(PQgetvalue(pg_result,i,7), "e") ?
+                       add_assoc_bool(elem, "is enum", 1) :
                        add_assoc_bool(elem, "is enum", 0);
-               }
+               if (extended) {
+                       /* pg_type.typtype */
+                       !strcmp(PQgetvalue(pg_result,i,7), "b") ?
+                               add_assoc_bool(elem, "is base", 1) :
+                               add_assoc_bool(elem, "is base", 0);
+                       !strcmp(PQgetvalue(pg_result,i,7), "c") ?
+                               add_assoc_bool(elem, "is composite", 1) :
+                               add_assoc_bool(elem, "is composite", 0);
+                       !strcmp(PQgetvalue(pg_result,i,7), "p") ?
+                               add_assoc_bool(elem, "is pesudo", 1) :
+                               add_assoc_bool(elem, "is pesudo", 0);
+                       /* pg_description.description */
+                       add_assoc_string(elem, "description", PQgetvalue(pg_result,i,8), 1);
+               }
+               /* pg_attribute.attname */
                name = PQgetvalue(pg_result,i,0);
                add_assoc_zval(meta, name, elem);
        }
@@ -5265,39 +5293,29 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z
 /* }}} */
 
 
-/* {{{ proto array pg_meta_data(resource db, string table)
+/* {{{ proto array pg_meta_data(resource db, string table [, bool extended])
    Get meta_data */
 PHP_FUNCTION(pg_meta_data)
 {
        zval *pgsql_link;
        char *table_name;
        uint table_name_len;
+       zend_bool extended=0;
        PGconn *pgsql;
        int id = -1;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs",
-                                                         &pgsql_link, &table_name, &table_name_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|b",
+                                                         &pgsql_link, &table_name, &table_name_len, &extended) == FAILURE) {
                return;
        }
 
        ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
-       
+
        array_init(return_value);
-       if (php_pgsql_meta_data(pgsql, table_name, return_value TSRMLS_CC) == FAILURE) {
+       if (php_pgsql_meta_data(pgsql, table_name, return_value, extended TSRMLS_CC) == FAILURE) {
                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);
-               }
-       }
 }
 /* }}} */
 
@@ -5508,7 +5526,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
        array_init(meta);
 
 /* table_name is escaped by php_pgsql_meta_data */
-       if (php_pgsql_meta_data(pg_link, table_name, meta TSRMLS_CC) == FAILURE) {
+       if (php_pgsql_meta_data(pg_link, table_name, meta, 0 TSRMLS_CC) == FAILURE) {
                zval_dtor(meta);
                FREE_ZVAL(meta);
                return FAILURE;
index 4e0eca808a75faab9091835c4428c12c2c0777f0..9aa3883a5a852ca2d63364a90475fa4f02ff330b 100644 (file)
@@ -202,7 +202,7 @@ PHP_FUNCTION(pg_select);
 #define PGSQL_DML_ESCAPE            (1<<12)    /* No convert, but escape only */
 
 /* exported functions */
-PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta TSRMLS_DC);
+PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta, zend_bool extended TSRMLS_DC);
 PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, const zval *values, zval *result, ulong opt TSRMLS_DC);
 PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *values, ulong opt, char **sql TSRMLS_DC);
 PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *values, zval *ids, ulong opt , char **sql TSRMLS_DC);
index a7f8ed47fc5e6ea42e835a1e6ed770ddb1cf3769..5374ccb619bc84cfd407c489c702949f5c38219e 100644 (file)
@@ -17,7 +17,7 @@ var_dump($meta);
 --EXPECT--
 array(3) {
   ["num"]=>
-  array(6) {
+  array(7) {
     ["num"]=>
     int(1)
     ["type"]=>
@@ -30,9 +30,11 @@ array(3) {
     bool(false)
     ["array dims"]=>
     int(0)
+    ["is enum"]=>
+    bool(false)
   }
   ["str"]=>
-  array(6) {
+  array(7) {
     ["num"]=>
     int(2)
     ["type"]=>
@@ -45,9 +47,11 @@ array(3) {
     bool(false)
     ["array dims"]=>
     int(0)
+    ["is enum"]=>
+    bool(false)
   }
   ["bin"]=>
-  array(6) {
+  array(7) {
     ["num"]=>
     int(3)
     ["type"]=>
@@ -60,5 +64,7 @@ array(3) {
     bool(false)
     ["array dims"]=>
     int(0)
+    ["is enum"]=>
+    bool(false)
   }
 }
index 2841de83d199b8efe3c7912ef89aa87a7bc88637..a7bb381de6d676c26d6cbc1f25d588cf6db37fbc 100644 (file)
@@ -18,6 +18,7 @@ pg_query('CREATE TABLE foo (id INT, id3 INT)');
 
 var_dump(pg_meta_data($conn, 'foo'));
 var_dump(pg_meta_data($conn, 'phptests.foo'));
+var_dump(pg_meta_data($conn, 'phptests.foo', TRUE));
 
 
 pg_query('DROP TABLE foo');
@@ -28,7 +29,7 @@ pg_query('DROP SCHEMA phptests');
 --EXPECT--
 array(2) {
   ["id"]=>
-  array(6) {
+  array(7) {
     ["num"]=>
     int(1)
     ["type"]=>
@@ -41,9 +42,47 @@ array(2) {
     bool(false)
     ["array dims"]=>
     int(0)
+    ["is enum"]=>
+    bool(false)
   }
   ["id3"]=>
-  array(6) {
+  array(7) {
+    ["num"]=>
+    int(2)
+    ["type"]=>
+    string(4) "int4"
+    ["len"]=>
+    int(4)
+    ["not null"]=>
+    bool(false)
+    ["has default"]=>
+    bool(false)
+    ["array dims"]=>
+    int(0)
+    ["is enum"]=>
+    bool(false)
+  }
+}
+array(2) {
+  ["id"]=>
+  array(7) {
+    ["num"]=>
+    int(1)
+    ["type"]=>
+    string(4) "int4"
+    ["len"]=>
+    int(4)
+    ["not null"]=>
+    bool(false)
+    ["has default"]=>
+    bool(false)
+    ["array dims"]=>
+    int(0)
+    ["is enum"]=>
+    bool(false)
+  }
+  ["id2"]=>
+  array(7) {
     ["num"]=>
     int(2)
     ["type"]=>
@@ -56,11 +95,13 @@ array(2) {
     bool(false)
     ["array dims"]=>
     int(0)
+    ["is enum"]=>
+    bool(false)
   }
 }
 array(2) {
   ["id"]=>
-  array(6) {
+  array(11) {
     ["num"]=>
     int(1)
     ["type"]=>
@@ -73,9 +114,19 @@ array(2) {
     bool(false)
     ["array dims"]=>
     int(0)
+    ["is enum"]=>
+    bool(false)
+    ["is base"]=>
+    bool(true)
+    ["is composite"]=>
+    bool(false)
+    ["is pesudo"]=>
+    bool(false)
+    ["description"]=>
+    string(0) ""
   }
   ["id2"]=>
-  array(6) {
+  array(11) {
     ["num"]=>
     int(2)
     ["type"]=>
@@ -88,5 +139,15 @@ array(2) {
     bool(false)
     ["array dims"]=>
     int(0)
+    ["is enum"]=>
+    bool(false)
+    ["is base"]=>
+    bool(true)
+    ["is composite"]=>
+    bool(false)
+    ["is pesudo"]=>
+    bool(false)
+    ["description"]=>
+    string(0) ""
   }
 }