66 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
9- *$Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.213 2002/01/03 23 :21:31 tgl Exp $
9+ *$Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.214 2002/02/25 04 :21:55 momjian Exp $
1010 *
1111 *-------------------------------------------------------------------------
1212 */
@@ -64,17 +64,22 @@ typedef struct
6464}CreateStmtContext ;
6565
6666
67- static Query * transformStmt (ParseState * pstate ,Node * stmt );
67+ static Query * transformStmt (ParseState * pstate ,Node * stmt ,
68+ List * * extras_before ,List * * extras_after );
6869static Query * transformDeleteStmt (ParseState * pstate ,DeleteStmt * stmt );
69- static Query * transformInsertStmt (ParseState * pstate ,InsertStmt * stmt );
70+ static Query * transformInsertStmt (ParseState * pstate ,InsertStmt * stmt ,
71+ List * * extras_before ,List * * extras_after );
7072static Query * transformIndexStmt (ParseState * pstate ,IndexStmt * stmt );
71- static Query * transformRuleStmt (ParseState * query ,RuleStmt * stmt );
73+ static Query * transformRuleStmt (ParseState * query ,RuleStmt * stmt ,
74+ List * * extras_before ,List * * extras_after );
7275static Query * transformSelectStmt (ParseState * pstate ,SelectStmt * stmt );
7376static Query * transformSetOperationStmt (ParseState * pstate ,SelectStmt * stmt );
7477static Node * transformSetOperationTree (ParseState * pstate ,SelectStmt * stmt );
7578static Query * transformUpdateStmt (ParseState * pstate ,UpdateStmt * stmt );
76- static Query * transformCreateStmt (ParseState * pstate ,CreateStmt * stmt );
77- static Query * transformAlterTableStmt (ParseState * pstate ,AlterTableStmt * stmt );
79+ static Query * transformCreateStmt (ParseState * pstate ,CreateStmt * stmt ,
80+ List * * extras_before ,List * * extras_after );
81+ static Query * transformAlterTableStmt (ParseState * pstate ,AlterTableStmt * stmt ,
82+ List * * extras_before ,List * * extras_after );
7883static void transformColumnDefinition (ParseState * pstate ,
7984CreateStmtContext * cxt ,
8085ColumnDef * column );
@@ -101,9 +106,6 @@ static OidtransformFkeyGetColType(CreateStmtContext *cxt, char *colname);
101106static void release_pstate_resources (ParseState * pstate );
102107static FromExpr * makeFromExpr (List * fromlist ,Node * quals );
103108
104- /* kluge to return extra info from transformCreateStmt() */
105- static List * extras_before ;
106- static List * extras_after ;
107109
108110
109111/*
@@ -121,27 +123,24 @@ parse_analyze(Node *parseTree, ParseState *parentParseState)
121123List * result = NIL ;
122124ParseState * pstate = make_parsestate (parentParseState );
123125Query * query ;
126+ /* Lists to return extra commands from transformation */
127+ List * extras_before = NIL ;
128+ List * extras_after = NIL ;
124129
125- extras_before = extras_after = NIL ;
126-
127- query = transformStmt (pstate ,parseTree );
130+ query = transformStmt (pstate ,parseTree ,& extras_before ,& extras_after );
128131release_pstate_resources (pstate );
129132
130133while (extras_before != NIL )
131134{
132- result = lappend (result ,
133- transformStmt (pstate ,lfirst (extras_before )));
134- release_pstate_resources (pstate );
135+ result = nconc (result ,parse_analyze (lfirst (extras_before ),pstate ));
135136extras_before = lnext (extras_before );
136137}
137138
138139result = lappend (result ,query );
139140
140141while (extras_after != NIL )
141142{
142- result = lappend (result ,
143- transformStmt (pstate ,lfirst (extras_after )));
144- release_pstate_resources (pstate );
143+ result = nconc (result ,parse_analyze (lfirst (extras_after ),pstate ));
145144extras_after = lnext (extras_after );
146145}
147146
@@ -164,7 +163,8 @@ release_pstate_resources(ParseState *pstate)
164163 * transform a Parse tree into a Query tree.
165164 */
166165static Query *
167- transformStmt (ParseState * pstate ,Node * parseTree )
166+ transformStmt (ParseState * pstate ,Node * parseTree ,
167+ List * * extras_before ,List * * extras_after )
168168{
169169Query * result = NULL ;
170170
@@ -174,22 +174,25 @@ transformStmt(ParseState *pstate, Node *parseTree)
174174 * Non-optimizable statements
175175 */
176176case T_CreateStmt :
177- result = transformCreateStmt (pstate , (CreateStmt * )parseTree );
177+ result = transformCreateStmt (pstate , (CreateStmt * )parseTree ,
178+ extras_before ,extras_after );
178179break ;
179180
180181case T_IndexStmt :
181182result = transformIndexStmt (pstate , (IndexStmt * )parseTree );
182183break ;
183184
184185case T_RuleStmt :
185- result = transformRuleStmt (pstate , (RuleStmt * )parseTree );
186+ result = transformRuleStmt (pstate , (RuleStmt * )parseTree ,
187+ extras_before ,extras_after );
186188break ;
187189
188190case T_ViewStmt :
189191{
190192ViewStmt * n = (ViewStmt * )parseTree ;
191193
192- n -> query = transformStmt (pstate , (Node * )n -> query );
194+ n -> query = transformStmt (pstate , (Node * )n -> query ,
195+ extras_before ,extras_after );
193196
194197/*
195198 * If a list of column names was given, run through and
@@ -239,20 +242,23 @@ transformStmt(ParseState *pstate, Node *parseTree)
239242
240243result = makeNode (Query );
241244result -> commandType = CMD_UTILITY ;
242- n -> query = transformStmt (pstate , (Node * )n -> query );
245+ n -> query = transformStmt (pstate , (Node * )n -> query ,
246+ extras_before ,extras_after );
243247result -> utilityStmt = (Node * )parseTree ;
244248}
245249break ;
246250
247251case T_AlterTableStmt :
248- result = transformAlterTableStmt (pstate , (AlterTableStmt * )parseTree );
252+ result = transformAlterTableStmt (pstate , (AlterTableStmt * )parseTree ,
253+ extras_before ,extras_after );
249254break ;
250255
251256/*
252257 * Optimizable statements
253258 */
254259case T_InsertStmt :
255- result = transformInsertStmt (pstate , (InsertStmt * )parseTree );
260+ result = transformInsertStmt (pstate , (InsertStmt * )parseTree ,
261+ extras_before ,extras_after );
256262break ;
257263
258264case T_DeleteStmt :
@@ -337,7 +343,8 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
337343 * transform an Insert Statement
338344 */
339345static Query *
340- transformInsertStmt (ParseState * pstate ,InsertStmt * stmt )
346+ transformInsertStmt (ParseState * pstate ,InsertStmt * stmt ,
347+ List * * extras_before ,List * * extras_after )
341348{
342349Query * qry = makeNode (Query );
343350List * sub_rtable ;
@@ -402,7 +409,12 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
402409sub_pstate -> p_rtable = sub_rtable ;
403410sub_pstate -> p_namespace = sub_namespace ;
404411
405- selectQuery = transformStmt (sub_pstate ,stmt -> selectStmt );
412+ /*
413+ * Note: we are not expecting that extras_before and extras_after
414+ * are going to be used by the transformation of the SELECT statement.
415+ */
416+ selectQuery = transformStmt (sub_pstate ,stmt -> selectStmt ,
417+ extras_before ,extras_after );
406418
407419release_pstate_resources (sub_pstate );
408420pfree (sub_pstate );
@@ -658,7 +670,8 @@ CreateIndexName(char *table_name, char *column_name,
658670 * - thomas 1997-12-02
659671 */
660672static Query *
661- transformCreateStmt (ParseState * pstate ,CreateStmt * stmt )
673+ transformCreateStmt (ParseState * pstate ,CreateStmt * stmt ,
674+ List * * extras_before ,List * * extras_after )
662675{
663676CreateStmtContext cxt ;
664677Query * q ;
@@ -728,8 +741,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
728741q -> utilityStmt = (Node * )stmt ;
729742stmt -> tableElts = cxt .columns ;
730743stmt -> constraints = cxt .ckconstraints ;
731- extras_before = cxt .blist ;
732- extras_after = cxt .alist ;
744+ * extras_before = nconc ( * extras_before , cxt .blist ) ;
745+ * extras_after = nconc ( cxt .alist , * extras_after ) ;
733746
734747return q ;
735748}
@@ -1668,7 +1681,8 @@ transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
16681681 * trees which is transformed into a list of query trees.
16691682 */
16701683static Query *
1671- transformRuleStmt (ParseState * pstate ,RuleStmt * stmt )
1684+ transformRuleStmt (ParseState * pstate ,RuleStmt * stmt ,
1685+ List * * extras_before ,List * * extras_after )
16721686{
16731687Query * qry ;
16741688RangeTblEntry * oldrte ;
@@ -1797,7 +1811,8 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
17971811addRTEtoQuery (sub_pstate ,newrte , false, true);
17981812
17991813/* Transform the rule action statement */
1800- top_subqry = transformStmt (sub_pstate ,action );
1814+ top_subqry = transformStmt (sub_pstate ,action ,
1815+ extras_before ,extras_after );
18011816
18021817/*
18031818 * We cannot support utility-statement actions (eg NOTIFY)
@@ -2494,7 +2509,8 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
24942509 *transform an Alter Table Statement
24952510 */
24962511static Query *
2497- transformAlterTableStmt (ParseState * pstate ,AlterTableStmt * stmt )
2512+ transformAlterTableStmt (ParseState * pstate ,AlterTableStmt * stmt ,
2513+ List * * extras_before ,List * * extras_after )
24982514{
24992515CreateStmtContext cxt ;
25002516Query * qry ;
@@ -2534,8 +2550,8 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt)
25342550transformFKConstraints (pstate ,& cxt );
25352551
25362552((ColumnDef * )stmt -> def )-> constraints = cxt .ckconstraints ;
2537- extras_before = cxt .blist ;
2538- extras_after = cxt .alist ;
2553+ * extras_before = nconc ( * extras_before , cxt .blist ) ;
2554+ * extras_after = nconc ( cxt .alist , * extras_after ) ;
25392555break ;
25402556
25412557case 'C' :
@@ -2571,8 +2587,8 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt)
25712587
25722588Assert (cxt .columns == NIL );
25732589stmt -> def = (Node * )nconc (cxt .ckconstraints ,cxt .fkconstraints );
2574- extras_before = cxt .blist ;
2575- extras_after = cxt .alist ;
2590+ * extras_before = nconc ( * extras_before , cxt .blist ) ;
2591+ * extras_after = nconc ( cxt .alist , * extras_after ) ;
25762592break ;
25772593
25782594default :