Skip to content

Commit 552823f

Browse files
committed
Pdo\Pgsql: optimize calls to foreach(columns of the same table) getColumnMeta()
- each call queried the DB to know the name associated with the table's OID: cache the result between two calls - make pdo_pgsql_translate_oid_to_table higher-level, with the last parameter being the handle instead of the raw connection; thus the statement is cleaner, letting the handle do all memory handling on the table oid-to-name translation cache (which by the way is a driver feature more than a statement one)
1 parent 7f4a127 commit 552823f

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

ext/pdo_pgsql/pgsql_driver.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ static void pgsql_handle_closer(pdo_dbh_t *dbh) /* {{{ */
252252
PQfinish(H->server);
253253
H->server = NULL;
254254
}
255+
if (H->cached_table_name) {
256+
efree(H->cached_table_name);
257+
}
255258
if (H->einfo.errmsg) {
256259
pefree(H->einfo.errmsg, dbh->is_persistent);
257260
H->einfo.errmsg = NULL;
@@ -1445,6 +1448,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{
14451448

14461449
H->attached = 1;
14471450
H->pgoid = -1;
1451+
H->cached_table_oid = InvalidOid;
14481452

14491453
dbh->methods = &pgsql_methods;
14501454
dbh->alloc_own_columns = 1;

ext/pdo_pgsql/pgsql_statement.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -702,12 +702,22 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pd
702702
return 1;
703703
}
704704

705-
static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, PGconn *conn)
705+
static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, pdo_pgsql_db_handle *H)
706706
{
707+
PGconn *conn = H->server;
707708
char *table_name = NULL;
708709
PGresult *tmp_res;
709710
char *querystr = NULL;
710711

712+
if (oid == H->cached_table_oid) {
713+
return H->cached_table_name;
714+
}
715+
716+
if (H->cached_table_name) {
717+
efree(H->cached_table_name);
718+
H->cached_table_oid = InvalidOid;
719+
}
720+
711721
spprintf(&querystr, 0, "SELECT RELNAME FROM PG_CLASS WHERE OID=%d", oid);
712722

713723
if ((tmp_res = PQexec(conn, querystr)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) {
@@ -724,6 +734,8 @@ static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, PGcon
724734
return 0;
725735
}
726736

737+
H->cached_table_oid = oid;
738+
H->cached_table_name =
727739
table_name = estrdup(table_name);
728740

729741
PQclear(tmp_res);
@@ -752,10 +764,9 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *r
752764

753765
table_oid = PQftable(S->result, colno);
754766
add_assoc_long(return_value, "pgsql:table_oid", table_oid);
755-
table_name = pdo_pgsql_translate_oid_to_table(table_oid, S->H->server);
767+
table_name = pdo_pgsql_translate_oid_to_table(table_oid, S->H);
756768
if (table_name) {
757-
add_assoc_string(return_value, "table", table_name);
758-
efree(table_name);
769+
add_assoc_string(return_value, "table", S->H->cached_table_name);
759770
}
760771

761772
switch (S->cols[colno].pgsql_type) {

ext/pdo_pgsql/php_pdo_pgsql_int.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ typedef struct {
4343
unsigned _reserved:31;
4444
pdo_pgsql_error_info einfo;
4545
Oid pgoid;
46+
Oid cached_table_oid;
47+
char *cached_table_name;
4648
unsigned int stmt_counter;
4749
/* The following two variables have the same purpose. Unfortunately we need
4850
to keep track of two different attributes having the same effect. */

0 commit comments

Comments
 (0)