summaryrefslogtreecommitdiff
path: root/src/backend/parser/analyze.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-10-15 19:53:59 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2010-10-15 19:55:25 -0400
commit07f1264dda0e776a7e329b091c127059bce8cc54 (patch)
treec77493be3b7c010de069a431035b80db720b0969 /src/backend/parser/analyze.c
parent6ab42ae36713b1e6f961c37e22f99d3e6267523b (diff)
Allow WITH clauses to be attached to INSERT, UPDATE, DELETE statements.
This is not the hoped-for facility of using INSERT/UPDATE/DELETE inside a WITH, but rather the other way around. It seems useful in its own right anyway. Note: catversion bumped because, although the contents of stored rules might look compatible, there's actually a subtle semantic change. A single Query containing a WITH and INSERT...VALUES now represents writing the WITH before the INSERT, not before the VALUES. While it's not clear that that matters to anyone, it seems like a good idea to have it cited in the git history for catversion.h. Original patch by Marko Tiikkaja, with updating and cleanup by Hitoshi Harada.
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r--src/backend/parser/analyze.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 21342e8a9d7..bb2bf04e177 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -283,6 +283,13 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
qry->commandType = CMD_DELETE;
+ /* process the WITH clause independently of all else */
+ if (stmt->withClause)
+ {
+ qry->hasRecursive = stmt->withClause->recursive;
+ qry->cteList = transformWithClause(pstate, stmt->withClause);
+ }
+
/* set up range table with just the result rel */
qry->resultRelation = setTargetTable(pstate, stmt->relation,
interpretInhOption(stmt->relation->inhOpt),
@@ -340,9 +347,19 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
ListCell *attnos;
ListCell *lc;
+ /* There can't be any outer WITH to worry about */
+ Assert(pstate->p_ctenamespace == NIL);
+
qry->commandType = CMD_INSERT;
pstate->p_is_insert = true;
+ /* process the WITH clause independently of all else */
+ if (stmt->withClause)
+ {
+ qry->hasRecursive = stmt->withClause->recursive;
+ qry->cteList = transformWithClause(pstate, stmt->withClause);
+ }
+
/*
* We have three cases to deal with: DEFAULT VALUES (selectStmt == NULL),
* VALUES list, or general SELECT input. We special-case VALUES, both for
@@ -376,8 +393,6 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
pstate->p_relnamespace = NIL;
sub_varnamespace = pstate->p_varnamespace;
pstate->p_varnamespace = NIL;
- /* There can't be any outer WITH to worry about */
- Assert(pstate->p_ctenamespace == NIL);
}
else
{
@@ -518,13 +533,6 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
List *exprsLists = NIL;
int sublist_length = -1;
- /* process the WITH clause */
- if (selectStmt->withClause)
- {
- qry->hasRecursive = selectStmt->withClause->recursive;
- qry->cteList = transformWithClause(pstate, selectStmt->withClause);
- }
-
foreach(lc, selectStmt->valuesLists)
{
List *sublist = (List *) lfirst(lc);
@@ -618,13 +626,6 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
Assert(list_length(valuesLists) == 1);
- /* process the WITH clause */
- if (selectStmt->withClause)
- {
- qry->hasRecursive = selectStmt->withClause->recursive;
- qry->cteList = transformWithClause(pstate, selectStmt->withClause);
- }
-
/* Do basic expression transformation (same as a ROW() expr) */
exprList = transformExpressionList(pstate,
(List *) linitial(valuesLists));
@@ -1794,6 +1795,13 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
qry->commandType = CMD_UPDATE;
pstate->p_is_update = true;
+ /* process the WITH clause independently of all else */
+ if (stmt->withClause)
+ {
+ qry->hasRecursive = stmt->withClause->recursive;
+ qry->cteList = transformWithClause(pstate, stmt->withClause);
+ }
+
qry->resultRelation = setTargetTable(pstate, stmt->relation,
interpretInhOption(stmt->relation->inhOpt),
true,