@@ -112,7 +112,7 @@ ZEND_TSRMLS_CACHE_DEFINE()
112
112
ZEND_GET_MODULE (pgsql )
113
113
#endif
114
114
115
- static int le_link , le_plink , le_result , le_lofp , le_string ;
115
+ static int le_link , le_plink , le_result , le_lofp ;
116
116
117
117
/* Compatibility definitions */
118
118
@@ -278,9 +278,9 @@ static void _free_result(zend_resource *rsrc)
278
278
}
279
279
/* }}} */
280
280
281
- static void release_string (zend_resource * rsrc )
281
+ static void release_string (zval * zv )
282
282
{
283
- zend_string_release ((zend_string * ) rsrc -> ptr );
283
+ zend_string_release ((zend_string * ) Z_PTR_P ( zv ) );
284
284
}
285
285
286
286
static bool _php_pgsql_identifier_is_escaped (const char * identifier , size_t len ) /* {{{ */
@@ -356,7 +356,6 @@ PHP_MINIT_FUNCTION(pgsql)
356
356
le_plink = zend_register_list_destructors_ex (NULL , _close_pgsql_plink , "pgsql link persistent" , module_number );
357
357
le_result = zend_register_list_destructors_ex (_free_result , NULL , "pgsql result" , module_number );
358
358
le_lofp = zend_register_list_destructors_ex (_free_ptr , NULL , "pgsql large object" , module_number );
359
- le_string = zend_register_list_destructors_ex (release_string , NULL , "pgsql string" , module_number );
360
359
/* libpq version */
361
360
php_libpq_version (buf , sizeof (buf ));
362
361
REGISTER_STRING_CONSTANT ("PGSQL_LIBPQ_VERSION" , buf , CONST_CS | CONST_PERSISTENT );
@@ -480,6 +479,8 @@ PHP_RINIT_FUNCTION(pgsql)
480
479
{
481
480
PGG (default_link ) = NULL ;
482
481
PGG (num_links ) = PGG (num_persistent );
482
+ zend_hash_init (& PGG (field_oids ), 0 , NULL , release_string , 0 );
483
+ zend_hash_init (& PGG (table_oids ), 0 , NULL , release_string , 0 );
483
484
return SUCCESS ;
484
485
}
485
486
/* }}} */
@@ -490,6 +491,8 @@ PHP_RSHUTDOWN_FUNCTION(pgsql)
490
491
/* clean up notice messages */
491
492
zend_hash_clean (& PGG (notices ));
492
493
zend_hash_clean (& PGG (hashes ));
494
+ zend_hash_destroy (& PGG (field_oids ));
495
+ zend_hash_destroy (& PGG (table_oids ));
493
496
/* clean up persistent connection */
494
497
zend_hash_apply (& EG (persistent_list ), (apply_func_t ) _rollback_transactions );
495
498
return SUCCESS ;
@@ -1481,61 +1484,47 @@ static inline bool is_valid_oid_string(zend_string *oid, Oid *return_oid)
1481
1484
}
1482
1485
1483
1486
/* {{{ get_field_name */
1484
- static zend_string * get_field_name (PGconn * pgsql , Oid oid , HashTable * list )
1487
+ static zend_string * get_field_name (PGconn * pgsql , Oid oid )
1485
1488
{
1486
- smart_str str = {0 };
1487
- zend_resource * field_type ;
1488
- zend_string * ret = NULL ;
1489
+ zend_string * ret = zend_hash_index_find_ptr (& PGG (field_oids ), oid );
1490
+ if (ret ) {
1491
+ zend_string_addref (ret );
1492
+ return ret ;
1493
+ }
1489
1494
1490
- /* try to lookup the type in the resource list */
1491
- smart_str_appends (& str , "pgsql_oid_" );
1492
- smart_str_append_unsigned (& str , oid );
1493
- smart_str_0 (& str );
1495
+ PGresult * result = PQexec (pgsql , "select oid,typname from pg_type" );
1496
+ if (!result || PQresultStatus (result ) != PGRES_TUPLES_OK ) {
1497
+ if (result ) {
1498
+ PQclear (result );
1499
+ }
1500
+ return ZSTR_EMPTY_ALLOC ();
1501
+ }
1494
1502
1495
- if ((field_type = zend_hash_find_ptr (list , str .s )) != NULL ) {
1496
- ret = zend_string_copy ((zend_string * ) field_type -> ptr );
1497
- } else { /* hash all oid's */
1498
- int i , num_rows ;
1499
- int oid_offset ,name_offset ;
1500
- char * tmp_oid , * end_ptr , * tmp_name ;
1501
- zend_resource new_oid_entry ;
1502
- PGresult * result ;
1503
-
1504
- if ((result = PQexec (pgsql , "select oid,typname from pg_type" )) == NULL || PQresultStatus (result ) != PGRES_TUPLES_OK ) {
1505
- if (result ) {
1506
- PQclear (result );
1507
- }
1508
- smart_str_free (& str );
1509
- return ZSTR_EMPTY_ALLOC ();
1503
+ int num_rows = PQntuples (result );
1504
+ int oid_offset = PQfnumber (result ,"oid" );
1505
+ int name_offset = PQfnumber (result ,"typname" );
1506
+ for (int i = 0 ; i < num_rows ; i ++ ) {
1507
+ char * tmp_oid_str = PQgetvalue (result , i , oid_offset );
1508
+ if (!tmp_oid_str ) {
1509
+ continue ;
1510
1510
}
1511
- num_rows = PQntuples (result );
1512
- oid_offset = PQfnumber (result ,"oid" );
1513
- name_offset = PQfnumber (result ,"typname" );
1514
1511
1515
- for ( i = 0 ; i < num_rows ; i ++ ) {
1516
- if (( tmp_oid = PQgetvalue ( result , i , oid_offset )) == NULL ) {
1517
- continue ;
1518
- }
1512
+ char * tmp_name = PQgetvalue ( result , i , name_offset );
1513
+ if (! tmp_name ) {
1514
+ continue ;
1515
+ }
1519
1516
1520
- smart_str_free (& str );
1521
- smart_str_appends (& str , "pgsql_oid_" );
1522
- smart_str_appends (& str , tmp_oid );
1523
- smart_str_0 (& str );
1517
+ char * end_ptr ;
1518
+ Oid tmp_oid = strtoul (tmp_oid_str , & end_ptr , 10 );
1524
1519
1525
- if ((tmp_name = PQgetvalue (result ,i ,name_offset ))== NULL ) {
1526
- continue ;
1527
- }
1528
- new_oid_entry .type = le_string ;
1529
- new_oid_entry .ptr = zend_string_init (tmp_name , strlen (tmp_name ), 0 );
1530
- zend_hash_update_mem (list , str .s , (void * ) & new_oid_entry , sizeof (zend_resource ));
1531
- if (!ret && strtoul (tmp_oid , & end_ptr , 10 )== oid ) {
1532
- ret = zend_string_copy (new_oid_entry .ptr );
1533
- }
1520
+ zend_string * name = zend_string_init (tmp_name , strlen (tmp_name ), 0 );
1521
+ zend_hash_index_update_ptr (& PGG (field_oids ), tmp_oid , name );
1522
+ if (!ret && tmp_oid == oid ) {
1523
+ ret = zend_string_copy (name );
1534
1524
}
1535
- PQclear (result );
1536
1525
}
1537
1526
1538
- smart_str_free ( & str );
1527
+ PQclear ( result );
1539
1528
return ret ;
1540
1529
}
1541
1530
/* }}} */
@@ -1547,10 +1536,6 @@ PHP_FUNCTION(pg_field_table)
1547
1536
pgsql_result_handle * pg_result ;
1548
1537
zend_long fnum = -1 ;
1549
1538
bool return_oid = 0 ;
1550
- Oid oid ;
1551
- smart_str hash_key = {0 };
1552
- char * table_name ;
1553
- zend_resource * field_table ;
1554
1539
1555
1540
if (zend_parse_parameters (ZEND_NUM_ARGS (), "rl|b" , & result , & fnum , & return_oid ) == FAILURE ) {
1556
1541
RETURN_THROWS ();
@@ -1570,8 +1555,7 @@ PHP_FUNCTION(pg_field_table)
1570
1555
RETURN_THROWS ();
1571
1556
}
1572
1557
1573
- oid = PQftable (pg_result -> result , (int )fnum );
1574
-
1558
+ Oid oid = PQftable (pg_result -> result , (int )fnum );
1575
1559
if (InvalidOid == oid ) {
1576
1560
RETURN_FALSE ;
1577
1561
}
@@ -1580,49 +1564,37 @@ PHP_FUNCTION(pg_field_table)
1580
1564
PGSQL_RETURN_OID (oid );
1581
1565
}
1582
1566
1583
- /* try to lookup the table name in the resource list */
1584
- smart_str_appends (& hash_key , "pgsql_table_oid_" );
1585
- smart_str_append_unsigned (& hash_key , oid );
1586
- smart_str_0 (& hash_key );
1587
-
1588
- if ((field_table = zend_hash_find_ptr (& EG (regular_list ), hash_key .s )) != NULL ) {
1589
- smart_str_free (& hash_key );
1590
- RETURN_STR_COPY ((zend_string * )field_table -> ptr );
1591
- } else { /* Not found, lookup by querying PostgreSQL system tables */
1592
- PGresult * tmp_res ;
1593
- smart_str querystr = {0 };
1594
- zend_resource new_field_table ;
1595
-
1596
- smart_str_appends (& querystr , "select relname from pg_class where oid=" );
1597
- smart_str_append_unsigned (& querystr , oid );
1598
- smart_str_0 (& querystr );
1599
-
1600
- if ((tmp_res = PQexec (pg_result -> conn , ZSTR_VAL (querystr .s ))) == NULL || PQresultStatus (tmp_res ) != PGRES_TUPLES_OK ) {
1601
- if (tmp_res ) {
1602
- PQclear (tmp_res );
1603
- }
1604
- smart_str_free (& querystr );
1605
- smart_str_free (& hash_key );
1606
- RETURN_FALSE ;
1607
- }
1567
+ zend_string * field_table = zend_hash_index_find_ptr (& PGG (table_oids ), oid );
1568
+ if (field_table ) {
1569
+ RETURN_STR_COPY (field_table );
1570
+ }
1608
1571
1609
- smart_str_free (& querystr );
1572
+ /* Not found, lookup by querying PostgreSQL system tables */
1573
+ smart_str querystr = {0 };
1574
+ smart_str_appends (& querystr , "select relname from pg_class where oid=" );
1575
+ smart_str_append_unsigned (& querystr , oid );
1576
+ smart_str_0 (& querystr );
1610
1577
1611
- if ((table_name = PQgetvalue (tmp_res , 0 , 0 )) == NULL ) {
1578
+ PGresult * tmp_res = PQexec (pg_result -> conn , ZSTR_VAL (querystr .s ));
1579
+ smart_str_free (& querystr );
1580
+ if (!tmp_res || PQresultStatus (tmp_res ) != PGRES_TUPLES_OK ) {
1581
+ if (tmp_res ) {
1612
1582
PQclear (tmp_res );
1613
- smart_str_free (& hash_key );
1614
- RETURN_FALSE ;
1615
1583
}
1584
+ RETURN_FALSE ;
1585
+ }
1616
1586
1617
- new_field_table .type = le_string ;
1618
- new_field_table .ptr = zend_string_init (table_name , strlen (table_name ), 0 );
1619
- zend_hash_update_mem (& EG (regular_list ), hash_key .s , (void * )& new_field_table , sizeof (zend_resource ));
1620
-
1621
- smart_str_free (& hash_key );
1587
+ char * table_name = PQgetvalue (tmp_res , 0 , 0 );
1588
+ if (!table_name ) {
1622
1589
PQclear (tmp_res );
1623
- RETURN_STR_COPY ( new_field_table . ptr ) ;
1590
+ RETURN_FALSE ;
1624
1591
}
1625
1592
1593
+ field_table = zend_string_init (table_name , strlen (table_name ), 0 );
1594
+ zend_hash_index_update_ptr (& PGG (table_oids ), oid , field_table );
1595
+
1596
+ PQclear (tmp_res );
1597
+ RETURN_STR_COPY (field_table );
1626
1598
}
1627
1599
/* }}} */
1628
1600
@@ -1668,8 +1640,7 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ
1668
1640
RETURN_LONG (PQfsize (pgsql_result , (int )field ));
1669
1641
break ;
1670
1642
case PHP_PG_FIELD_TYPE :
1671
- RETURN_STR (get_field_name (
1672
- pg_result -> conn , PQftype (pgsql_result , (int )field ), & EG (regular_list )));
1643
+ RETURN_STR (get_field_name (pg_result -> conn , PQftype (pgsql_result , (int )field )));
1673
1644
break ;
1674
1645
case PHP_PG_FIELD_TYPE_OID :
1675
1646
0 commit comments