aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_clause.c
diff options
context:
space:
mode:
authorSimon Riggs <simon@2ndQuadrant.com>2018-04-02 21:12:47 +0100
committerSimon Riggs <simon@2ndQuadrant.com>2018-04-02 21:12:47 +0100
commit354f13855e6381d288dfaa52bcd4f2cb0fd4a5eb (patch)
tree92710660450acee59be62dea485cc26ab147f332 /src/backend/parser/parse_clause.c
parente6597dc3533946b98acba7871bd4ca1f7a3d4c1d (diff)
downloadpostgresql-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.c45
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