]> granicus.if.org Git - php/commitdiff
Added pg_field_table() as per req: #36750
authorEdin Kadribasic <edink@php.net>
Thu, 16 Mar 2006 14:58:56 +0000 (14:58 +0000)
committerEdin Kadribasic <edink@php.net>
Thu, 16 Mar 2006 14:58:56 +0000 (14:58 +0000)
ext/pgsql/pgsql.c
ext/pgsql/php_pgsql.h

index 99d5ab5434cb1aa78452bbec6585073257dde617..0ab76f78e3dbf6ab94c91eed081a72af18afe319 100644 (file)
@@ -151,6 +151,7 @@ zend_function_entry pgsql_functions[] = {
        PHP_FE(pg_field_type_oid, NULL)
        PHP_FE(pg_field_prtlen, NULL)
        PHP_FE(pg_field_is_null,NULL)
+       PHP_FE(pg_field_table,  NULL)
        /* async message function */
        PHP_FE(pg_get_notify,   NULL)
        PHP_FE(pg_get_pid,      NULL)
@@ -1694,6 +1695,95 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC)
 }
 /* }}} */                      
 
+/* {{{ proto mixed pg_field_table(resource result, int field_number[, bool oid_only])
+   Returns the name of the table field belongs to, or table's oid if oid_only is true */
+PHP_FUNCTION(pg_field_table)
+{
+       zval *result;
+       pgsql_result_handle *pg_result;
+       long fnum = -1;
+       zend_bool return_oid = 0;
+       Oid oid;
+       smart_str hash_key = {0};
+       char *table_name;
+       zend_rsrc_list_entry *field_table;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|b!", &result, &fnum, &return_oid) == FAILURE) {
+               return;
+       }
+
+       ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result);
+
+       if (fnum < 0 || fnum >= PQnfields(pg_result->result)) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified");
+               RETURN_FALSE;
+       }
+
+       oid = PQftable(pg_result->result, fnum);
+
+       if (InvalidOid == oid) {
+               RETURN_FALSE;
+       }
+
+
+       if (return_oid) {
+               if (oid > LONG_MAX) {
+                       smart_str oidstr = {0};
+                       smart_str_append_unsigned(&oidstr, oid);
+                       smart_str_0(&oidstr);
+                       RETURN_STRINGL(oidstr.c, oidstr.len, 0);
+               } else {
+                       RETURN_LONG((long)oid);
+               }
+       }
+
+       /* try to lookup the table name in the resource list */
+       smart_str_appends(&hash_key, "pgsql_table_oid_");
+       smart_str_append_unsigned(&hash_key, oid);
+       smart_str_0(&hash_key);
+
+       if (zend_hash_find(&EG(regular_list), hash_key.c, hash_key.len+1, (void **) &field_table) == SUCCESS) {
+               smart_str_free(&hash_key);
+               RETURN_STRING((char *)field_table->ptr, 1);
+       } else { /* Not found, lookup by querying PostgreSQL system tables */
+               PGresult *tmp_res;
+               smart_str querystr = {0};
+               zend_rsrc_list_entry new_field_table;
+
+               smart_str_appends(&querystr, "select relname from pg_class where oid=");
+               smart_str_append_unsigned(&querystr, oid);
+               smart_str_0(&querystr);
+
+
+               if ((tmp_res = PQexec(pg_result->conn, querystr.c)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) {
+                       if (tmp_res) {
+                               PQclear(tmp_res);
+                       }
+                       smart_str_free(&querystr);
+                       smart_str_free(&hash_key);
+                       RETURN_FALSE;
+               }
+
+               smart_str_free(&querystr);
+
+               if ((table_name = PQgetvalue(tmp_res, 0, 0)) == NULL) {
+                       PQclear(tmp_res);
+                       smart_str_free(&hash_key);
+                       RETURN_FALSE;
+               }
+
+               Z_TYPE(new_field_table) = le_string;
+               new_field_table.ptr = estrdup(table_name);
+               zend_hash_update(&EG(regular_list), hash_key.c, hash_key.len+1, (void *) &new_field_table, sizeof(zend_rsrc_list_entry), NULL);
+
+               smart_str_free(&hash_key);
+               PQclear(tmp_res);
+               RETURN_STRING(table_name, 1);
+       }
+
+}
+/* }}} */                      
+
 #define PHP_PG_FIELD_NAME 1
 #define PHP_PG_FIELD_SIZE 2
 #define PHP_PG_FIELD_TYPE 3
index a24e2e693e57fa71ce836a6fd22ad69da2b32ea2..2cd097fca7342a13f72864ddfbf4cc8577bdb64c 100644 (file)
@@ -125,6 +125,7 @@ PHP_FUNCTION(pg_field_type);
 PHP_FUNCTION(pg_field_type_oid);
 PHP_FUNCTION(pg_field_prtlen);
 PHP_FUNCTION(pg_field_is_null);
+PHP_FUNCTION(pg_field_table);
 /* async message functions */
 PHP_FUNCTION(pg_get_notify);
 PHP_FUNCTION(pg_get_pid);