diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2010-10-15 19:53:59 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2010-10-15 19:55:25 -0400 |
commit | 07f1264dda0e776a7e329b091c127059bce8cc54 (patch) | |
tree | c77493be3b7c010de069a431035b80db720b0969 /src/backend/parser/analyze.c | |
parent | 6ab42ae36713b1e6f961c37e22f99d3e6267523b (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.c | 40 |
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, |