From a317e436e8073fde92d87b7a56a6f38504c3fb0b Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Thu, 1 Mar 2018 19:58:50 -0300 Subject: [PATCH v4 2/3] Make some static functions work on TupleDesc rather than Relation --- src/backend/optimizer/prep/preptlist.c | 23 ++++++++--------- src/backend/optimizer/prep/prepunion.c | 45 ++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index 8603feef2b..b6e658fe81 100644 --- a/src/backend/optimizer/prep/preptlist.c +++ b/src/backend/optimizer/prep/preptlist.c @@ -54,7 +54,7 @@ static List *expand_targetlist(List *tlist, int command_type, - Index result_relation, Relation rel); + Index result_relation, TupleDesc tupdesc); /* @@ -116,7 +116,8 @@ preprocess_targetlist(PlannerInfo *root) tlist = parse->targetList; if (command_type == CMD_INSERT || command_type == CMD_UPDATE) tlist = expand_targetlist(tlist, command_type, - result_relation, target_relation); + result_relation, + RelationGetDescr(target_relation)); /* * Add necessary junk columns for rowmarked rels. These values are needed @@ -230,7 +231,7 @@ preprocess_targetlist(PlannerInfo *root) expand_targetlist(parse->onConflict->onConflictSet, CMD_UPDATE, result_relation, - target_relation); + RelationGetDescr(target_relation)); if (target_relation) heap_close(target_relation, NoLock); @@ -247,13 +248,13 @@ preprocess_targetlist(PlannerInfo *root) /* * expand_targetlist - * Given a target list as generated by the parser and a result relation, - * add targetlist entries for any missing attributes, and ensure the - * non-junk attributes appear in proper field order. + * Given a target list as generated by the parser and a result relation's + * tuple descriptor, add targetlist entries for any missing attributes, and + * ensure the non-junk attributes appear in proper field order. */ static List * expand_targetlist(List *tlist, int command_type, - Index result_relation, Relation rel) + Index result_relation, TupleDesc tupdesc) { List *new_tlist = NIL; ListCell *tlist_item; @@ -266,14 +267,14 @@ expand_targetlist(List *tlist, int command_type, * The rewriter should have already ensured that the TLEs are in correct * order; but we have to insert TLEs for any missing attributes. * - * Scan the tuple description in the relation's relcache entry to make - * sure we have all the user attributes in the right order. + * Scan the tuple description to make sure we have all the user attributes + * in the right order. */ - numattrs = RelationGetNumberOfAttributes(rel); + numattrs = tupdesc->natts; for (attrno = 1; attrno <= numattrs; attrno++) { - Form_pg_attribute att_tup = TupleDescAttr(rel->rd_att, attrno - 1); + Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1); TargetEntry *new_tle = NULL; if (tlist_item != NULL) diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index b586f941a8..d0d9812da6 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -113,10 +113,10 @@ static void expand_single_inheritance_child(PlannerInfo *root, PlanRowMark *top_parentrc, Relation childrel, List **appinfos, RangeTblEntry **childrte_p, Index *childRTindex_p); -static void make_inh_translation_list(Relation oldrelation, - Relation newrelation, - Index newvarno, - List **translated_vars); +static List *make_inh_translation_list(TupleDesc old_tupdesc, + TupleDesc new_tupdesc, + char *new_rel_name, + Index newvarno); static Bitmapset *translate_col_privs(const Bitmapset *parent_privs, List *translated_vars); static Node *adjust_appendrel_attrs_mutator(Node *node, @@ -1730,8 +1730,11 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte, appinfo->child_relid = childRTindex; appinfo->parent_reltype = parentrel->rd_rel->reltype; appinfo->child_reltype = childrel->rd_rel->reltype; - make_inh_translation_list(parentrel, childrel, childRTindex, - &appinfo->translated_vars); + appinfo->translated_vars = + make_inh_translation_list(RelationGetDescr(parentrel), + RelationGetDescr(childrel), + RelationGetRelationName(childrel), + childRTindex); appinfo->parent_reloid = parentOID; *appinfos = lappend(*appinfos, appinfo); @@ -1788,22 +1791,23 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte, /* * make_inh_translation_list - * Build the list of translations from parent Vars to child Vars for - * an inheritance child. + * Build the list of translations from parent Vars ("old" rel) to child + * Vars ("new" rel) for an inheritance child. * * For paranoia's sake, we match type/collation as well as attribute name. */ -static void -make_inh_translation_list(Relation oldrelation, Relation newrelation, - Index newvarno, - List **translated_vars) +static List * +make_inh_translation_list(TupleDesc old_tupdesc, TupleDesc new_tupdesc, + char *new_rel_name, + Index newvarno) { List *vars = NIL; - TupleDesc old_tupdesc = RelationGetDescr(oldrelation); - TupleDesc new_tupdesc = RelationGetDescr(newrelation); int oldnatts = old_tupdesc->natts; int newnatts = new_tupdesc->natts; int old_attno; + bool equal_tupdescs; + + equal_tupdescs = equalTupleDescs(old_tupdesc, new_tupdesc); for (old_attno = 0; old_attno < oldnatts; old_attno++) { @@ -1827,10 +1831,9 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation, attcollation = att->attcollation; /* - * When we are generating the "translation list" for the parent table - * of an inheritance set, no need to search for matches. + * When the tupledescs are identical, no need to search for matches. */ - if (oldrelation == newrelation) + if (equal_tupdescs) { vars = lappend(vars, makeVar(newvarno, (AttrNumber) (old_attno + 1), @@ -1867,16 +1870,16 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation, } if (new_attno >= newnatts) elog(ERROR, "could not find inherited attribute \"%s\" of relation \"%s\"", - attname, RelationGetRelationName(newrelation)); + attname, new_rel_name); } /* Found it, check type and collation match */ if (atttypid != att->atttypid || atttypmod != att->atttypmod) elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's type", - attname, RelationGetRelationName(newrelation)); + attname, new_rel_name); if (attcollation != att->attcollation) elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's collation", - attname, RelationGetRelationName(newrelation)); + attname, new_rel_name); vars = lappend(vars, makeVar(newvarno, (AttrNumber) (new_attno + 1), @@ -1886,7 +1889,7 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation, 0)); } - *translated_vars = vars; + return vars; } /* -- 2.11.0