diff options
author | Simon Riggs <simon@2ndQuadrant.com> | 2018-04-02 21:12:47 +0100 |
---|---|---|
committer | Simon Riggs <simon@2ndQuadrant.com> | 2018-04-02 21:12:47 +0100 |
commit | 354f13855e6381d288dfaa52bcd4f2cb0fd4a5eb (patch) | |
tree | 92710660450acee59be62dea485cc26ab147f332 /src/backend/parser/parse_clause.c | |
parent | e6597dc3533946b98acba7871bd4ca1f7a3d4c1d (diff) | |
download | postgresql-354f13855e6381d288dfaa52bcd4f2cb0fd4a5eb.tar.gz postgresql-354f13855e6381d288dfaa52bcd4f2cb0fd4a5eb.zip |
Modified files for MERGE
Diffstat (limited to 'src/backend/parser/parse_clause.c')
-rw-r--r-- | src/backend/parser/parse_clause.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 3a02307bd99..3cb761b4ed0 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -76,9 +76,6 @@ static RangeTblEntry *transformRangeTableFunc(ParseState *pstate, RangeTableFunc *t); static TableSampleClause *transformRangeTableSample(ParseState *pstate, RangeTableSample *rts); -static Node *transformFromClauseItem(ParseState *pstate, Node *n, - RangeTblEntry **top_rte, int *top_rti, - List **namespace); static Node *buildMergedJoinVar(ParseState *pstate, JoinType jointype, Var *l_colvar, Var *r_colvar); static ParseNamespaceItem *makeNamespaceItem(RangeTblEntry *rte, @@ -139,6 +136,7 @@ transformFromClause(ParseState *pstate, List *frmList) n = transformFromClauseItem(pstate, n, &rte, &rtindex, + NULL, NULL, &namespace); checkNameSpaceConflicts(pstate, pstate->p_namespace, namespace); @@ -1096,13 +1094,20 @@ getRTEForSpecialRelationTypes(ParseState *pstate, RangeVar *rv) * * *top_rti: receives the rangetable index of top_rte. (Ditto.) * + * *right_rte: receives the RTE corresponding to the right side of the + * jointree. Only MERGE really needs to know about this and only MERGE passes a + * non-NULL pointer. + * + * *right_rti: receives the rangetable index of the right_rte. + * * *namespace: receives a List of ParseNamespaceItems for the RTEs exposed * as table/column names by this item. (The lateral_only flags in these items * are indeterminate and should be explicitly set by the caller before use.) */ -static Node * +Node * transformFromClauseItem(ParseState *pstate, Node *n, RangeTblEntry **top_rte, int *top_rti, + RangeTblEntry **right_rte, int *right_rti, List **namespace) { if (IsA(n, RangeVar)) @@ -1194,7 +1199,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, /* Recursively transform the contained relation */ rel = transformFromClauseItem(pstate, rts->relation, - top_rte, top_rti, namespace); + top_rte, top_rti, NULL, NULL, namespace); /* Currently, grammar could only return a RangeVar as contained rel */ rtr = castNode(RangeTblRef, rel); rte = rt_fetch(rtr->rtindex, pstate->p_rtable); @@ -1222,6 +1227,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, List *l_namespace, *r_namespace, *my_namespace, + *save_namespace, *l_colnames, *r_colnames, *res_colnames, @@ -1240,6 +1246,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, j->larg = transformFromClauseItem(pstate, j->larg, &l_rte, &l_rtindex, + NULL, NULL, &l_namespace); /* @@ -1263,12 +1270,34 @@ transformFromClauseItem(ParseState *pstate, Node *n, sv_namespace_length = list_length(pstate->p_namespace); pstate->p_namespace = list_concat(pstate->p_namespace, l_namespace); + /* + * If we are running MERGE, don't make the other RTEs visible while + * parsing the source relation. It mustn't see them. + * + * Currently, only MERGE passes non-NULL value for right_rte, so we + * can safely deduce if we're running MERGE or not by just looking at + * the right_rte. If that ever changes, we should look at other means + * to find that. + */ + if (right_rte) + { + save_namespace = pstate->p_namespace; + pstate->p_namespace = NIL; + } + /* And now we can process the RHS */ j->rarg = transformFromClauseItem(pstate, j->rarg, &r_rte, &r_rtindex, + NULL, NULL, &r_namespace); + /* + * And now restore the namespace again so that join-quals can see it. + */ + if (right_rte) + pstate->p_namespace = save_namespace; + /* Remove the left-side RTEs from the namespace list again */ pstate->p_namespace = list_truncate(pstate->p_namespace, sv_namespace_length); @@ -1295,6 +1324,12 @@ transformFromClauseItem(ParseState *pstate, Node *n, expandRTE(r_rte, r_rtindex, 0, -1, false, &r_colnames, &r_colvars); + if (right_rte) + *right_rte = r_rte; + + if (right_rti) + *right_rti = r_rtindex; + /* * Natural join does not explicitly specify columns; must generate * columns to join. Need to run through the list of columns from each |