@@ -194,6 +194,11 @@ static void pgsql_link_free(pgsql_link_handle *link)
194194 FREE_HASHTABLE (link -> notices );
195195 link -> notices = NULL ;
196196 }
197+ if (link -> meta_cache ) {
198+ zend_hash_destroy (link -> meta_cache );
199+ FREE_HASHTABLE (link -> meta_cache );
200+ link -> meta_cache = NULL ;
201+ }
197202}
198203
199204static void pgsql_link_free_obj (zend_object * obj )
@@ -765,6 +770,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
765770 link -> conn = pgsql ;
766771 link -> hash = zend_string_copy (str .s );
767772 link -> notices = NULL ;
773+ link -> meta_cache = NULL ;
768774 link -> persistent = 1 ;
769775 } else { /* Non persistent connection */
770776 zval * index_ptr ;
@@ -816,6 +822,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
816822 link -> conn = pgsql ;
817823 link -> hash = zend_string_copy (str .s );
818824 link -> notices = NULL ;
825+ link -> meta_cache = NULL ;
819826 link -> persistent = 0 ;
820827
821828 /* add it to the hash */
@@ -1182,6 +1189,12 @@ PHP_FUNCTION(pg_query)
11821189 php_error_docref (NULL , E_NOTICE ,"Cannot set connection to blocking mode" );
11831190 RETURN_FALSE ;
11841191 }
1192+
1193+ if (link -> meta_cache ) {
1194+ zend_hash_destroy (link -> meta_cache );
1195+ FREE_HASHTABLE (link -> meta_cache );
1196+ link -> meta_cache = NULL ;
1197+ }
11851198 while ((pgsql_result = PQgetResult (pgsql ))) {
11861199 PQclear (pgsql_result );
11871200 leftover = true;
@@ -4550,6 +4563,8 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
45504563 size_t new_len , len ;
45514564 int i , num_rows , err ;
45524565 zval elem ;
4566+ pgsql_link_handle * link ;
4567+ link = FETCH_DEFAULT_LINK_NO_WARNING ();
45534568
45544569 ZEND_ASSERT (ZSTR_LEN (table_name ) != 0 );
45554570
@@ -4620,14 +4635,26 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
46204635 smart_str_0 (& querystr );
46214636 efree (src );
46224637
4638+ if (link && link -> meta_cache ) {
4639+ zval * meta_cache = zend_hash_find (link -> meta_cache , querystr .s );
4640+
4641+ if (meta_cache ) {
4642+ if (Z_TYPE_P (meta ) != IS_UNDEF ) {
4643+ zval_ptr_dtor (meta );
4644+ }
4645+ ZVAL_COPY (meta , meta_cache );
4646+ smart_str_free (& querystr );
4647+ return SUCCESS ;
4648+ }
4649+ }
4650+
46234651 pg_result = PQexec (pg_link , ZSTR_VAL (querystr .s ));
46244652 if (PQresultStatus (pg_result ) != PGRES_TUPLES_OK || (num_rows = PQntuples (pg_result )) == 0 ) {
46254653 php_error_docref (NULL , E_WARNING , "Table '%s' doesn't exists" , ZSTR_VAL (table_name ));
46264654 smart_str_free (& querystr );
46274655 PQclear (pg_result );
46284656 return FAILURE ;
46294657 }
4630- smart_str_free (& querystr );
46314658
46324659 for (i = 0 ; i < num_rows ; i ++ ) {
46334660 char * name ;
@@ -4658,6 +4685,21 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string
46584685 name = PQgetvalue (pg_result ,i ,0 );
46594686 add_assoc_zval (meta , name , & elem );
46604687 }
4688+
4689+ if (link ) {
4690+ if (!link -> meta_cache ) {
4691+ ALLOC_HASHTABLE (link -> meta_cache );
4692+ zend_hash_init (link -> meta_cache , 8 , NULL , ZVAL_PTR_DTOR , 0 );
4693+ }
4694+
4695+ zval meta_copy ;
4696+ ZVAL_COPY (& meta_copy , meta );
4697+ zend_string * key = zend_string_copy (querystr .s );
4698+
4699+ zend_hash_update ( link -> meta_cache , key , & meta_copy );
4700+ zend_string_release (key );
4701+ }
4702+ smart_str_free (& querystr );
46614703 PQclear (pg_result );
46624704
46634705 return SUCCESS ;
@@ -6089,6 +6131,11 @@ PHP_FUNCTION(pg_delete)
60896131 if (php_pgsql_delete (pg_link , table , ids , option , & sql ) == FAILURE ) {
60906132 RETURN_FALSE ;
60916133 }
6134+ if (link -> meta_cache ) {
6135+ zend_hash_destroy (link -> meta_cache );
6136+ FREE_HASHTABLE (link -> meta_cache );
6137+ link -> meta_cache = NULL ;
6138+ }
60926139 if (option & PGSQL_DML_STRING ) {
60936140 RETURN_STR (sql );
60946141 }
0 commit comments