Avoid invoking PQfnumber in loop constructs
authorDaniel Gustafsson
Fri, 27 Aug 2021 14:24:33 +0000 (16:24 +0200)
committerDaniel Gustafsson
Fri, 27 Aug 2021 14:24:33 +0000 (16:24 +0200)
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 
Reviewed-by: Nathan Bossart
Discussion: https://postgr.es/m/OS0PR01MB57164C392783F29F6D0ECA0B94139@OS0PR01MB5716.jpnprd01.prod.outlook.com

src/bin/pg_dump/pg_dump.c

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