Skip to content

Commit 10e9791

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 551a9ef commit 10e9791

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

ext/pdo_pgsql/pgsql_driver.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ 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+
H->cached_table_name = NULL;
258+
}
255259
if (H->einfo.errmsg) {
256260
pefree(H->einfo.errmsg, dbh->is_persistent);
257261
H->einfo.errmsg = NULL;
@@ -1445,6 +1449,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{
14451449

14461450
H->attached = 1;
14471451
H->pgoid = -1;
1452+
H->cached_table_oid = InvalidOid;
14481453

14491454
dbh->methods = &pgsql_methods;
14501455
dbh->alloc_own_columns = 1;

ext/pdo_pgsql/pgsql_statement.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -702,12 +702,23 @@ 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_name = NULL;
719+
H->cached_table_oid = InvalidOid;
720+
}
721+
711722
spprintf(&querystr, 0, "SELECT RELNAME FROM PG_CLASS WHERE OID=%d", oid);
712723

713724
if ((tmp_res = PQexec(conn, querystr)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) {
@@ -724,6 +735,8 @@ static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, PGcon
724735
return 0;
725736
}
726737

738+
H->cached_table_oid = oid;
739+
H->cached_table_name = estrdup(table_name);
727740
table_name = estrdup(table_name);
728741

729742
PQclear(tmp_res);
@@ -752,10 +765,9 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *r
752765

753766
table_oid = PQftable(S->result, colno);
754767
add_assoc_long(return_value, "pgsql:table_oid", table_oid);
755-
table_name = pdo_pgsql_translate_oid_to_table(table_oid, S->H->server);
768+
table_name = pdo_pgsql_translate_oid_to_table(table_oid, S->H);
756769
if (table_name) {
757-
add_assoc_string(return_value, "table", table_name);
758-
efree(table_name);
770+
add_assoc_string(return_value, "table", S->H->cached_table_name);
759771
}
760772

761773
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)