Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ext/pdo_pgsql/pgsql_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ static void pgsql_handle_closer(pdo_dbh_t *dbh) /* {{{ */
PQfinish(H->server);
H->server = NULL;
}
if (H->cached_table_name) {
H->cached_table_oid = InvalidOid;
efree(H->cached_table_name);
H->cached_table_name = NULL;
}
if (H->einfo.errmsg) {
pefree(H->einfo.errmsg, dbh->is_persistent);
H->einfo.errmsg = NULL;
Expand Down Expand Up @@ -1542,6 +1547,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{

H->attached = 1;
H->pgoid = -1;
H->cached_table_oid = InvalidOid;

dbh->methods = &pgsql_methods;
dbh->alloc_own_columns = 1;
Expand Down
23 changes: 21 additions & 2 deletions ext/pdo_pgsql/pgsql_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,12 +814,29 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pd
return 1;
}

static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, PGconn *conn)
static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, pdo_pgsql_db_handle *H)
{
PGconn *conn = H->server;
char *table_name = NULL;
PGresult *tmp_res;
char *querystr = NULL;

if (oid == InvalidOid) {
/* InvalidOid is emitted when not selecting from a table (e.g. "SELECT 1"). No need of
* a database roundtrip.
*/
return NULL;
}
if (oid == H->cached_table_oid) {
return H->cached_table_name ? estrdup(H->cached_table_name) : NULL;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can optimise it by not copying it just returning as const char * and returning cached_table_name instead since add_assoc_string copies it anyway wdyt ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look at it but I think my very first version precisely worked like that, and it looked uncomfortable to me as I thought I was breaking the (implicit) contract of pdo_pgsql_translate_oid_to_table made to return a persistent string.

So if I use this shortcut, I'll add a big comment at its top telling that it is the caller's responsibility to persist that string (it can get overwritten or even freed in case the statement is close).

}

if (H->cached_table_name) {
efree(H->cached_table_name);
H->cached_table_name = NULL;
H->cached_table_oid = InvalidOid;
}

spprintf(&querystr, 0, "SELECT RELNAME FROM PG_CLASS WHERE OID=%d", oid);

if ((tmp_res = PQexec(conn, querystr)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) {
Expand All @@ -836,6 +853,8 @@ static zend_always_inline char * pdo_pgsql_translate_oid_to_table(Oid oid, PGcon
return 0;
}

H->cached_table_oid = oid;
H->cached_table_name = estrdup(table_name);
table_name = estrdup(table_name);

PQclear(tmp_res);
Expand Down Expand Up @@ -864,7 +883,7 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *r

table_oid = PQftable(S->result, colno);
add_assoc_long(return_value, "pgsql:table_oid", table_oid);
table_name = pdo_pgsql_translate_oid_to_table(table_oid, S->H->server);
table_name = pdo_pgsql_translate_oid_to_table(table_oid, S->H);
if (table_name) {
add_assoc_string(return_value, "table", table_name);
efree(table_name);
Expand Down
2 changes: 2 additions & 0 deletions ext/pdo_pgsql/php_pdo_pgsql_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ typedef struct {
unsigned _reserved:31;
pdo_pgsql_error_info einfo;
Oid pgoid;
Oid cached_table_oid;
char *cached_table_name;
unsigned int stmt_counter;
bool emulate_prepares;
bool disable_prepares;
Expand Down
Loading