Don't bother to attach column name lists to RowExprs of named types.
authorTom Lane <[email protected]>
Thu, 17 Mar 2022 22:25:44 +0000 (18:25 -0400)
committerTom Lane <[email protected]>
Thu, 17 Mar 2022 22:25:44 +0000 (18:25 -0400)
If a RowExpr is marked as returning a named composite type, we aren't
going to consult its colnames list; we'll use the attribute names
shown for the type in pg_attribute.  Hence, skip storing that list,
to save a few nanoseconds when copying the expression tree around.

Discussion: https://postgr.es/m/2950001.1638729947@sss.pgh.pa.us

src/backend/optimizer/prep/prepjointree.c
src/backend/optimizer/util/var.c
src/backend/rewrite/rewriteManip.c
src/include/nodes/primnodes.h

index 282589dec812b752840a6ec70f35ca26363e639b..74823e8437a7b7558d6afcd245f8c27fcc3bdc29 100644 (file)
@@ -2279,8 +2279,8 @@ pullup_replace_vars_callback(Var *var,
         * If generating an expansion for a var of a named rowtype (ie, this
         * is a plain relation RTE), then we must include dummy items for
         * dropped columns.  If the var is RECORD (ie, this is a JOIN), then
-        * omit dropped columns. Either way, attach column names to the
-        * RowExpr for use of ruleutils.c.
+        * omit dropped columns.  In the latter case, attach column names to
+        * the RowExpr for use of the executor and ruleutils.c.
         *
         * In order to be able to cache the results, we always generate the
         * expansion with varlevelsup = 0, and then adjust if needed.
@@ -2301,7 +2301,7 @@ pullup_replace_vars_callback(Var *var,
        rowexpr->args = fields;
        rowexpr->row_typeid = var->vartype;
        rowexpr->row_format = COERCE_IMPLICIT_CAST;
-       rowexpr->colnames = colnames;
+       rowexpr->colnames = (var->vartype == RECORDOID) ? colnames : NIL;
        rowexpr->location = var->location;
        newnode = (Node *) rowexpr;
 
index a0543b7f47b388f254db033fa5131585fec7a0dc..2b44ef3e1769ce7b8df9e903997d4151aefc499c 100644 (file)
@@ -809,6 +809,7 @@ flatten_join_alias_vars_mutator(Node *node,
            rowexpr->args = fields;
            rowexpr->row_typeid = var->vartype;
            rowexpr->row_format = COERCE_IMPLICIT_CAST;
+           /* vartype will always be RECORDOID, so we always need colnames */
            rowexpr->colnames = colnames;
            rowexpr->location = var->location;
 
index 708e5453e31234bff29ce3eb072716b96d2096d7..101c39553ae55d290ea3f7935a5dddbb87719256 100644 (file)
@@ -1424,8 +1424,8 @@ ReplaceVarsFromTargetList_callback(Var *var,
         * If generating an expansion for a var of a named rowtype (ie, this
         * is a plain relation RTE), then we must include dummy items for
         * dropped columns.  If the var is RECORD (ie, this is a JOIN), then
-        * omit dropped columns.  Either way, attach column names to the
-        * RowExpr for use of ruleutils.c.
+        * omit dropped columns.  In the latter case, attach column names to
+        * the RowExpr for use of the executor and ruleutils.c.
         */
        expandRTE(rcon->target_rte,
                  var->varno, var->varlevelsup, var->location,
@@ -1438,7 +1438,7 @@ ReplaceVarsFromTargetList_callback(Var *var,
        rowexpr->args = fields;
        rowexpr->row_typeid = var->vartype;
        rowexpr->row_format = COERCE_IMPLICIT_CAST;
-       rowexpr->colnames = colnames;
+       rowexpr->colnames = (var->vartype == RECORDOID) ? colnames : NIL;
        rowexpr->location = var->location;
 
        return (Node *) rowexpr;
index dab5c4ff5de49666f61d116533977c00e1ccf3ed..439e4b4a9db83ee622171a9af247cfed78379e33 100644 (file)
@@ -1052,15 +1052,13 @@ typedef struct ArrayExpr
  * than vice versa.)  It is important not to assume that length(args) is
  * the same as the number of columns logically present in the rowtype.
  *
- * colnames provides field names in cases where the names can't easily be
- * obtained otherwise.  Names *must* be provided if row_typeid is RECORDOID.
- * If row_typeid identifies a known composite type, colnames can be NIL to
- * indicate the type's cataloged field names apply.  Note that colnames can
- * be non-NIL even for a composite type, and typically is when the RowExpr
- * was created by expanding a whole-row Var.  This is so that we can retain
- * the column alias names of the RTE that the Var referenced (which would
- * otherwise be very difficult to extract from the parsetree).  Like the
- * args list, colnames is one-for-one with physical fields of the rowtype.
+ * colnames provides field names if the ROW() result is of type RECORD.
+ * Names *must* be provided if row_typeid is RECORDOID; but if it is a
+ * named composite type, colnames will be ignored in favor of using the
+ * type's cataloged field names, so colnames should be NIL.  Like the
+ * args list, colnames is defined to be one-for-one with physical fields
+ * of the rowtype (although dropped columns shouldn't appear in the
+ * RECORD case, so this fine point is currently moot).
  */
 typedef struct RowExpr
 {