Avoid invoking PQfnumber in loop constructs

When looping over the resultset from a SQL query, extracting the field
number before the loop body to avoid repeated calls to PQfnumber is an
established pattern.  On very wide tables this can have a performance
impact, but it wont be noticeable in the common case. This fixes a few
queries which were extracting the field number in the loop body.

Author: Hou Zhijie <houzj.fnst@fujitsu.com>
Reviewed-by: Nathan Bossart <bossartn@amazon.com>
Discussion: https://postgr.es/m/OS0PR01MB57164C392783F29F6D0ECA0B94139@OS0PR01MB5716.jpnprd01.prod.outlook.com
This commit is contained in:
Daniel Gustafsson 2021-08-27 16:24:33 +02:00
parent abc0910e2e
commit d782d5987e

View File

@ -8696,6 +8696,26 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
{ {
DumpOptions *dopt = fout->dopt; DumpOptions *dopt = fout->dopt;
PQExpBuffer q = createPQExpBuffer(); PQExpBuffer q = createPQExpBuffer();
int i_attnum;
int i_attname;
int i_atttypname;
int i_atttypmod;
int i_attstattarget;
int i_attstorage;
int i_typstorage;
int i_attidentity;
int i_attgenerated;
int i_attisdropped;
int i_attlen;
int i_attalign;
int i_attislocal;
int i_attnotnull;
int i_attoptions;
int i_attcollation;
int i_attcompression;
int i_attfdwoptions;
int i_attmissingval;
int i_atthasdef;
for (int i = 0; i < numTables; i++) for (int i = 0; i < numTables; i++)
{ {
@ -8839,32 +8859,53 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *)); tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *));
hasdefaults = false; hasdefaults = false;
i_attnum = PQfnumber(res, "attnum");
i_attname = PQfnumber(res, "attname");
i_atttypname = PQfnumber(res, "atttypname");
i_atttypmod = PQfnumber(res, "atttypmod");
i_attstattarget = PQfnumber(res, "attstattarget");
i_attstorage = PQfnumber(res, "attstorage");
i_typstorage = PQfnumber(res, "typstorage");
i_attidentity = PQfnumber(res, "attidentity");
i_attgenerated = PQfnumber(res, "attgenerated");
i_attisdropped = PQfnumber(res, "attisdropped");
i_attlen = PQfnumber(res, "attlen");
i_attalign = PQfnumber(res, "attalign");
i_attislocal = PQfnumber(res, "attislocal");
i_attnotnull = PQfnumber(res, "attnotnull");
i_attoptions = PQfnumber(res, "attoptions");
i_attcollation = PQfnumber(res, "attcollation");
i_attcompression = PQfnumber(res, "attcompression");
i_attfdwoptions = PQfnumber(res, "attfdwoptions");
i_attmissingval = PQfnumber(res, "attmissingval");
i_atthasdef = PQfnumber(res, "atthasdef");
for (int j = 0; j < ntups; j++) for (int j = 0; j < ntups; j++)
{ {
if (j + 1 != atoi(PQgetvalue(res, j, PQfnumber(res, "attnum")))) if (j + 1 != atoi(PQgetvalue(res, j, i_attnum)))
fatal("invalid column numbering in table \"%s\"", fatal("invalid column numbering in table \"%s\"",
tbinfo->dobj.name); tbinfo->dobj.name);
tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attname"))); tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, j, i_attname));
tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "atttypname"))); tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, j, i_atttypname));
tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, PQfnumber(res, "atttypmod"))); tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));
tbinfo->attstattarget[j] = atoi(PQgetvalue(res, j, PQfnumber(res, "attstattarget"))); tbinfo->attstattarget[j] = atoi(PQgetvalue(res, j, i_attstattarget));
tbinfo->attstorage[j] = *(PQgetvalue(res, j, PQfnumber(res, "attstorage"))); tbinfo->attstorage[j] = *(PQgetvalue(res, j, i_attstorage));
tbinfo->typstorage[j] = *(PQgetvalue(res, j, PQfnumber(res, "typstorage"))); tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage));
tbinfo->attidentity[j] = *(PQgetvalue(res, j, PQfnumber(res, "attidentity"))); tbinfo->attidentity[j] = *(PQgetvalue(res, j, i_attidentity));
tbinfo->attgenerated[j] = *(PQgetvalue(res, j, PQfnumber(res, "attgenerated"))); tbinfo->attgenerated[j] = *(PQgetvalue(res, j, i_attgenerated));
tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS); tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
tbinfo->attisdropped[j] = (PQgetvalue(res, j, PQfnumber(res, "attisdropped"))[0] == 't'); tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
tbinfo->attlen[j] = atoi(PQgetvalue(res, j, PQfnumber(res, "attlen"))); tbinfo->attlen[j] = atoi(PQgetvalue(res, j, i_attlen));
tbinfo->attalign[j] = *(PQgetvalue(res, j, PQfnumber(res, "attalign"))); tbinfo->attalign[j] = *(PQgetvalue(res, j, i_attalign));
tbinfo->attislocal[j] = (PQgetvalue(res, j, PQfnumber(res, "attislocal"))[0] == 't'); tbinfo->attislocal[j] = (PQgetvalue(res, j, i_attislocal)[0] == 't');
tbinfo->notnull[j] = (PQgetvalue(res, j, PQfnumber(res, "attnotnull"))[0] == 't'); tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't');
tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attoptions"))); tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, j, i_attoptions));
tbinfo->attcollation[j] = atooid(PQgetvalue(res, j, PQfnumber(res, "attcollation"))); tbinfo->attcollation[j] = atooid(PQgetvalue(res, j, i_attcollation));
tbinfo->attcompression[j] = *(PQgetvalue(res, j, PQfnumber(res, "attcompression"))); tbinfo->attcompression[j] = *(PQgetvalue(res, j, i_attcompression));
tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attfdwoptions"))); tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, j, i_attfdwoptions));
tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attmissingval"))); tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, j, i_attmissingval));
tbinfo->attrdefs[j] = NULL; /* fix below */ tbinfo->attrdefs[j] = NULL; /* fix below */
if (PQgetvalue(res, j, PQfnumber(res, "atthasdef"))[0] == 't') if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
hasdefaults = true; hasdefaults = true;
/* these flags will be set in flagInhAttrs() */ /* these flags will be set in flagInhAttrs() */
tbinfo->inhNotNull[j] = false; tbinfo->inhNotNull[j] = false;
@ -10712,6 +10753,8 @@ dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
char *qtypname; char *qtypname;
char *qualtypname; char *qualtypname;
char *label; char *label;
int i_enumlabel;
int i_oid;
if (fout->remoteVersion >= 90100) if (fout->remoteVersion >= 90100)
appendPQExpBuffer(query, "SELECT oid, enumlabel " appendPQExpBuffer(query, "SELECT oid, enumlabel "
@ -10749,10 +10792,12 @@ dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
if (!dopt->binary_upgrade) if (!dopt->binary_upgrade)
{ {
i_enumlabel = PQfnumber(res, "enumlabel");
/* Labels with server-assigned oids */ /* Labels with server-assigned oids */
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
label = PQgetvalue(res, i, PQfnumber(res, "enumlabel")); label = PQgetvalue(res, i, i_enumlabel);
if (i > 0) if (i > 0)
appendPQExpBufferChar(q, ','); appendPQExpBufferChar(q, ',');
appendPQExpBufferStr(q, "\n "); appendPQExpBufferStr(q, "\n ");
@ -10764,11 +10809,14 @@ dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
if (dopt->binary_upgrade) if (dopt->binary_upgrade)
{ {
i_oid = PQfnumber(res, "oid");
i_enumlabel = PQfnumber(res, "enumlabel");
/* Labels with dump-assigned (preserved) oids */ /* Labels with dump-assigned (preserved) oids */
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
enum_oid = atooid(PQgetvalue(res, i, PQfnumber(res, "oid"))); enum_oid = atooid(PQgetvalue(res, i, i_oid));
label = PQgetvalue(res, i, PQfnumber(res, "enumlabel")); label = PQgetvalue(res, i, i_enumlabel);
if (i == 0) if (i == 0)
appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n"); appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");