summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorYasuo Ohgaki <yohgaki@php.net>2014-02-17 06:19:47 +0900
committerYasuo Ohgaki <yohgaki@php.net>2014-02-17 06:24:10 +0900
commit5fd6365c7751dc3dcc37765bf39c559ae8454ca9 (patch)
treec18add6e53f057502f8e9cb1d47fd91a8968a003 /ext
parenta9c0d319eb107eed271604ec7fbb41c131bec393 (diff)
downloadphp-git-5fd6365c7751dc3dcc37765bf39c559ae8454ca9.tar.gz
Implement FR #41146 - Add "description" with exteneded flag pg_meta_data().
pg_meta_data(resource $conn, string $table [, bool extended]) It also made pg_meta_data() return "is enum" always.
Diffstat (limited to 'ext')
-rw-r--r--ext/pgsql/pgsql.c96
-rw-r--r--ext/pgsql/php_pgsql.h2
-rw-r--r--ext/pgsql/tests/11pg_meta_data.phpt12
-rw-r--r--ext/pgsql/tests/pg_meta_data_001.phpt69
4 files changed, 132 insertions, 47 deletions
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index a4d2d4a0e0..f8e15a370e 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -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;
diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h
index 4e0eca808a..9aa3883a5a 100644
--- a/ext/pgsql/php_pgsql.h
+++ b/ext/pgsql/php_pgsql.h
@@ -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);
diff --git a/ext/pgsql/tests/11pg_meta_data.phpt b/ext/pgsql/tests/11pg_meta_data.phpt
index a7f8ed47fc..5374ccb619 100644
--- a/ext/pgsql/tests/11pg_meta_data.phpt
+++ b/ext/pgsql/tests/11pg_meta_data.phpt
@@ -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)
}
}
diff --git a/ext/pgsql/tests/pg_meta_data_001.phpt b/ext/pgsql/tests/pg_meta_data_001.phpt
index 2841de83d1..a7bb381de6 100644
--- a/ext/pgsql/tests/pg_meta_data_001.phpt
+++ b/ext/pgsql/tests/pg_meta_data_001.phpt
@@ -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) ""
}
}