Обсуждение: Allow arbitrary levels of analyze/rewriting
Hi, This patch will allow arbitrary levels of analyze / rewriting by making the static variables extra_before and extra_after automatic so we can use recursion. It gets much easier to generate extra commands now, and one can rest assured that the extra commands will be properly analyzed/rewritten. Without this patch, if a command produced by transformation tries to use these static lists their first contents would be lost with unpredictable results. I know I could fix this by just using nconc() instead of assignments, but the resulting order of the commands would not be exactly what one could expect. -- Fernando Nasser Red Hat Canada Ltd. E-Mail: fnasser@redhat.com 2323 Yonge Street, Suite #300 Toronto, Ontario M4P 2C9Index: src/backend/parser/analyze.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/parser/analyze.c,v retrieving revision 1.213 diff -c -p -r1.213 analyze.c *** src/backend/parser/analyze.c 2002/01/03 23:21:31 1.213 --- src/backend/parser/analyze.c 2002/02/12 15:35:58 *************** typedef struct *** 64,80 **** } CreateStmtContext; ! static Query *transformStmt(ParseState *pstate, Node *stmt); static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt); static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt); ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt); static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt); static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt); ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt); static void transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt, ColumnDef *column); --- 64,85 ---- } CreateStmtContext; ! static Query *transformStmt(ParseState *pstate, Node *stmt, ! List **extras_before, List **extras_after); static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt, ! List **extras_before, List **extras_after); static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt); ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt, ! List **extras_before, List **extras_after); static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt); static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt, ! List **extras_before, List **extras_after); ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, ! List **extras_before, List **extras_after); static void transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt, ColumnDef *column); *************** static Oid transformFkeyGetColType(Creat *** 101,109 **** static void release_pstate_resources(ParseState *pstate); static FromExpr *makeFromExpr(List *fromlist, Node *quals); - /* kluge to return extra info from transformCreateStmt() */ - static List *extras_before; - static List *extras_after; /* --- 106,111 ---- *************** parse_analyze(Node *parseTree, ParseStat *** 121,137 **** List *result = NIL; ParseState *pstate = make_parsestate(parentParseState); Query *query; ! extras_before = extras_after = NIL; ! ! query = transformStmt(pstate, parseTree); release_pstate_resources(pstate); while (extras_before != NIL) { ! result = lappend(result, ! transformStmt(pstate, lfirst(extras_before))); ! release_pstate_resources(pstate); extras_before = lnext(extras_before); } --- 123,138 ---- List *result = NIL; ParseState *pstate = make_parsestate(parentParseState); Query *query; + /* Lists to return extra commands from transformation */ + List *extras_before = NIL; + List *extras_after = NIL; ! query = transformStmt(pstate, parseTree, &extras_before, &extras_after); release_pstate_resources(pstate); while (extras_before != NIL) { ! result = nconc(result, parse_analyze(lfirst(extras_before), pstate)); extras_before = lnext(extras_before); } *************** parse_analyze(Node *parseTree, ParseStat *** 139,147 **** while (extras_after != NIL) { ! result = lappend(result, ! transformStmt(pstate, lfirst(extras_after))); ! release_pstate_resources(pstate); extras_after = lnext(extras_after); } --- 140,146 ---- while (extras_after != NIL) { ! result = nconc(result, parse_analyze(lfirst(extras_after), pstate)); extras_after = lnext(extras_after); } *************** release_pstate_resources(ParseState *pst *** 164,170 **** * transform a Parse tree into a Query tree. */ static Query * ! transformStmt(ParseState *pstate, Node *parseTree) { Query *result = NULL; --- 163,170 ---- * transform a Parse tree into a Query tree. */ static Query * ! transformStmt(ParseState *pstate, Node *parseTree, ! List **extras_before, List **extras_after) { Query *result = NULL; *************** transformStmt(ParseState *pstate, Node * *** 174,180 **** * Non-optimizable statements */ case T_CreateStmt: ! result = transformCreateStmt(pstate, (CreateStmt *) parseTree); break; case T_IndexStmt: --- 174,181 ---- * Non-optimizable statements */ case T_CreateStmt: ! result = transformCreateStmt(pstate, (CreateStmt *) parseTree, ! extras_before, extras_after); break; case T_IndexStmt: *************** transformStmt(ParseState *pstate, Node * *** 182,195 **** break; case T_RuleStmt: ! result = transformRuleStmt(pstate, (RuleStmt *) parseTree); break; case T_ViewStmt: { ViewStmt *n = (ViewStmt *) parseTree; ! n->query = transformStmt(pstate, (Node *) n->query); /* * If a list of column names was given, run through and --- 183,198 ---- break; case T_RuleStmt: ! result = transformRuleStmt(pstate, (RuleStmt *) parseTree, ! extras_before, extras_after); break; case T_ViewStmt: { ViewStmt *n = (ViewStmt *) parseTree; ! n->query = transformStmt(pstate, (Node *) n->query, ! extras_before, extras_after); /* * If a list of column names was given, run through and *************** transformStmt(ParseState *pstate, Node * *** 239,258 **** result = makeNode(Query); result->commandType = CMD_UTILITY; ! n->query = transformStmt(pstate, (Node *) n->query); result->utilityStmt = (Node *) parseTree; } break; case T_AlterTableStmt: ! result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree); break; /* * Optimizable statements */ case T_InsertStmt: ! result = transformInsertStmt(pstate, (InsertStmt *) parseTree); break; case T_DeleteStmt: --- 242,264 ---- result = makeNode(Query); result->commandType = CMD_UTILITY; ! n->query = transformStmt(pstate, (Node *) n->query, ! extras_before, extras_after); result->utilityStmt = (Node *) parseTree; } break; case T_AlterTableStmt: ! result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree, ! extras_before, extras_after); break; /* * Optimizable statements */ case T_InsertStmt: ! result = transformInsertStmt(pstate, (InsertStmt *) parseTree, ! extras_before, extras_after); break; case T_DeleteStmt: *************** transformDeleteStmt(ParseState *pstate, *** 337,343 **** * transform an Insert Statement */ static Query * ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt) { Query *qry = makeNode(Query); List *sub_rtable; --- 343,350 ---- * transform an Insert Statement */ static Query * ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt, ! List **extras_before, List **extras_after) { Query *qry = makeNode(Query); List *sub_rtable; *************** transformInsertStmt(ParseState *pstate, *** 402,408 **** sub_pstate->p_rtable = sub_rtable; sub_pstate->p_namespace = sub_namespace; ! selectQuery = transformStmt(sub_pstate, stmt->selectStmt); release_pstate_resources(sub_pstate); pfree(sub_pstate); --- 409,420 ---- sub_pstate->p_rtable = sub_rtable; sub_pstate->p_namespace = sub_namespace; ! /* ! * Note: we are not expecting that extras_before and extras_after ! * are going to be used by the transformation of the SELECT statement. ! */ ! selectQuery = transformStmt(sub_pstate, stmt->selectStmt, ! extras_before, extras_after); release_pstate_resources(sub_pstate); pfree(sub_pstate); *************** CreateIndexName(char *table_name, char * *** 658,664 **** * - thomas 1997-12-02 */ static Query * ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt) { CreateStmtContext cxt; Query *q; --- 670,677 ---- * - thomas 1997-12-02 */ static Query * ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt, ! List **extras_before, List **extras_after) { CreateStmtContext cxt; Query *q; *************** transformCreateStmt(ParseState *pstate, *** 728,735 **** q->utilityStmt = (Node *) stmt; stmt->tableElts = cxt.columns; stmt->constraints = cxt.ckconstraints; ! extras_before = cxt.blist; ! extras_after = cxt.alist; return q; } --- 741,748 ---- q->utilityStmt = (Node *) stmt; stmt->tableElts = cxt.columns; stmt->constraints = cxt.ckconstraints; ! *extras_before = nconc (*extras_before, cxt.blist); ! *extras_after = nconc (cxt.alist, *extras_after); return q; } *************** transformIndexStmt(ParseState *pstate, I *** 1668,1674 **** * trees which is transformed into a list of query trees. */ static Query * ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt) { Query *qry; RangeTblEntry *oldrte; --- 1681,1688 ---- * trees which is transformed into a list of query trees. */ static Query * ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt, ! List **extras_before, List **extras_after) { Query *qry; RangeTblEntry *oldrte; *************** transformRuleStmt(ParseState *pstate, Ru *** 1797,1803 **** addRTEtoQuery(sub_pstate, newrte, false, true); /* Transform the rule action statement */ ! top_subqry = transformStmt(sub_pstate, action); /* * We cannot support utility-statement actions (eg NOTIFY) --- 1811,1818 ---- addRTEtoQuery(sub_pstate, newrte, false, true); /* Transform the rule action statement */ ! top_subqry = transformStmt(sub_pstate, action, ! extras_before, extras_after); /* * We cannot support utility-statement actions (eg NOTIFY) *************** transformUpdateStmt(ParseState *pstate, *** 2494,2500 **** * transform an Alter Table Statement */ static Query * ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt) { CreateStmtContext cxt; Query *qry; --- 2509,2516 ---- * transform an Alter Table Statement */ static Query * ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, ! List **extras_before, List **extras_after) { CreateStmtContext cxt; Query *qry; *************** transformAlterTableStmt(ParseState *psta *** 2534,2541 **** transformFKConstraints(pstate, &cxt); ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints; ! extras_before = cxt.blist; ! extras_after = cxt.alist; break; case 'C': --- 2550,2557 ---- transformFKConstraints(pstate, &cxt); ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints; ! *extras_before = nconc(*extras_before, cxt.blist); ! *extras_after = nconc(cxt.alist, *extras_after); break; case 'C': *************** transformAlterTableStmt(ParseState *psta *** 2571,2578 **** Assert(cxt.columns == NIL); stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints); ! extras_before = cxt.blist; ! extras_after = cxt.alist; break; default: --- 2587,2594 ---- Assert(cxt.columns == NIL); stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints); ! *extras_before = nconc(*extras_before, cxt.blist); ! *extras_after = nconc(cxt.alist, *extras_after); break; default:
This has been saved for the 7.3 release: http://candle.pha.pa.us/cgi-bin/pgpatches2 --------------------------------------------------------------------------- Fernando Nasser wrote: > Hi, > > This patch will allow arbitrary levels of analyze / rewriting > by making the static variables extra_before and extra_after > automatic so we can use recursion. > > It gets much easier to generate extra commands now, and one can rest > assured that the extra commands will be properly analyzed/rewritten. > > > Without this patch, if a command produced by transformation tries to > use these static lists their first contents would be lost with > unpredictable results. I know I could fix this by just using nconc() > instead of assignments, but the resulting order of the commands would > not be exactly what one could expect. > > -- > Fernando Nasser > Red Hat Canada Ltd. E-Mail: fnasser@redhat.com > 2323 Yonge Street, Suite #300 > Toronto, Ontario M4P 2C9 > Index: src/backend/parser/analyze.c > =================================================================== > RCS file: /projects/cvsroot/pgsql/src/backend/parser/analyze.c,v > retrieving revision 1.213 > diff -c -p -r1.213 analyze.c > *** src/backend/parser/analyze.c 2002/01/03 23:21:31 1.213 > --- src/backend/parser/analyze.c 2002/02/12 15:35:58 > *************** typedef struct > *** 64,80 **** > } CreateStmtContext; > > > ! static Query *transformStmt(ParseState *pstate, Node *stmt); > static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); > ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt); > static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt); > ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt); > static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); > static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); > static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt); > static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); > ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt); > ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt); > static void transformColumnDefinition(ParseState *pstate, > CreateStmtContext *cxt, > ColumnDef *column); > --- 64,85 ---- > } CreateStmtContext; > > > ! static Query *transformStmt(ParseState *pstate, Node *stmt, > ! List **extras_before, List **extras_after); > static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); > ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt, > ! List **extras_before, List **extras_after); > static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt); > ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt, > ! List **extras_before, List **extras_after); > static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); > static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); > static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt); > static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); > ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt, > ! List **extras_before, List **extras_after); > ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, > ! List **extras_before, List **extras_after); > static void transformColumnDefinition(ParseState *pstate, > CreateStmtContext *cxt, > ColumnDef *column); > *************** static Oid transformFkeyGetColType(Creat > *** 101,109 **** > static void release_pstate_resources(ParseState *pstate); > static FromExpr *makeFromExpr(List *fromlist, Node *quals); > > - /* kluge to return extra info from transformCreateStmt() */ > - static List *extras_before; > - static List *extras_after; > > > /* > --- 106,111 ---- > *************** parse_analyze(Node *parseTree, ParseStat > *** 121,137 **** > List *result = NIL; > ParseState *pstate = make_parsestate(parentParseState); > Query *query; > > ! extras_before = extras_after = NIL; > ! > ! query = transformStmt(pstate, parseTree); > release_pstate_resources(pstate); > > while (extras_before != NIL) > { > ! result = lappend(result, > ! transformStmt(pstate, lfirst(extras_before))); > ! release_pstate_resources(pstate); > extras_before = lnext(extras_before); > } > > --- 123,138 ---- > List *result = NIL; > ParseState *pstate = make_parsestate(parentParseState); > Query *query; > + /* Lists to return extra commands from transformation */ > + List *extras_before = NIL; > + List *extras_after = NIL; > > ! query = transformStmt(pstate, parseTree, &extras_before, &extras_after); > release_pstate_resources(pstate); > > while (extras_before != NIL) > { > ! result = nconc(result, parse_analyze(lfirst(extras_before), pstate)); > extras_before = lnext(extras_before); > } > > *************** parse_analyze(Node *parseTree, ParseStat > *** 139,147 **** > > while (extras_after != NIL) > { > ! result = lappend(result, > ! transformStmt(pstate, lfirst(extras_after))); > ! release_pstate_resources(pstate); > extras_after = lnext(extras_after); > } > > --- 140,146 ---- > > while (extras_after != NIL) > { > ! result = nconc(result, parse_analyze(lfirst(extras_after), pstate)); > extras_after = lnext(extras_after); > } > > *************** release_pstate_resources(ParseState *pst > *** 164,170 **** > * transform a Parse tree into a Query tree. > */ > static Query * > ! transformStmt(ParseState *pstate, Node *parseTree) > { > Query *result = NULL; > > --- 163,170 ---- > * transform a Parse tree into a Query tree. > */ > static Query * > ! transformStmt(ParseState *pstate, Node *parseTree, > ! List **extras_before, List **extras_after) > { > Query *result = NULL; > > *************** transformStmt(ParseState *pstate, Node * > *** 174,180 **** > * Non-optimizable statements > */ > case T_CreateStmt: > ! result = transformCreateStmt(pstate, (CreateStmt *) parseTree); > break; > > case T_IndexStmt: > --- 174,181 ---- > * Non-optimizable statements > */ > case T_CreateStmt: > ! result = transformCreateStmt(pstate, (CreateStmt *) parseTree, > ! extras_before, extras_after); > break; > > case T_IndexStmt: > *************** transformStmt(ParseState *pstate, Node * > *** 182,195 **** > break; > > case T_RuleStmt: > ! result = transformRuleStmt(pstate, (RuleStmt *) parseTree); > break; > > case T_ViewStmt: > { > ViewStmt *n = (ViewStmt *) parseTree; > > ! n->query = transformStmt(pstate, (Node *) n->query); > > /* > * If a list of column names was given, run through and > --- 183,198 ---- > break; > > case T_RuleStmt: > ! result = transformRuleStmt(pstate, (RuleStmt *) parseTree, > ! extras_before, extras_after); > break; > > case T_ViewStmt: > { > ViewStmt *n = (ViewStmt *) parseTree; > > ! n->query = transformStmt(pstate, (Node *) n->query, > ! extras_before, extras_after); > > /* > * If a list of column names was given, run through and > *************** transformStmt(ParseState *pstate, Node * > *** 239,258 **** > > result = makeNode(Query); > result->commandType = CMD_UTILITY; > ! n->query = transformStmt(pstate, (Node *) n->query); > result->utilityStmt = (Node *) parseTree; > } > break; > > case T_AlterTableStmt: > ! result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree); > break; > > /* > * Optimizable statements > */ > case T_InsertStmt: > ! result = transformInsertStmt(pstate, (InsertStmt *) parseTree); > break; > > case T_DeleteStmt: > --- 242,264 ---- > > result = makeNode(Query); > result->commandType = CMD_UTILITY; > ! n->query = transformStmt(pstate, (Node *) n->query, > ! extras_before, extras_after); > result->utilityStmt = (Node *) parseTree; > } > break; > > case T_AlterTableStmt: > ! result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree, > ! extras_before, extras_after); > break; > > /* > * Optimizable statements > */ > case T_InsertStmt: > ! result = transformInsertStmt(pstate, (InsertStmt *) parseTree, > ! extras_before, extras_after); > break; > > case T_DeleteStmt: > *************** transformDeleteStmt(ParseState *pstate, > *** 337,343 **** > * transform an Insert Statement > */ > static Query * > ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt) > { > Query *qry = makeNode(Query); > List *sub_rtable; > --- 343,350 ---- > * transform an Insert Statement > */ > static Query * > ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt, > ! List **extras_before, List **extras_after) > { > Query *qry = makeNode(Query); > List *sub_rtable; > *************** transformInsertStmt(ParseState *pstate, > *** 402,408 **** > sub_pstate->p_rtable = sub_rtable; > sub_pstate->p_namespace = sub_namespace; > > ! selectQuery = transformStmt(sub_pstate, stmt->selectStmt); > > release_pstate_resources(sub_pstate); > pfree(sub_pstate); > --- 409,420 ---- > sub_pstate->p_rtable = sub_rtable; > sub_pstate->p_namespace = sub_namespace; > > ! /* > ! * Note: we are not expecting that extras_before and extras_after > ! * are going to be used by the transformation of the SELECT statement. > ! */ > ! selectQuery = transformStmt(sub_pstate, stmt->selectStmt, > ! extras_before, extras_after); > > release_pstate_resources(sub_pstate); > pfree(sub_pstate); > *************** CreateIndexName(char *table_name, char * > *** 658,664 **** > * - thomas 1997-12-02 > */ > static Query * > ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt) > { > CreateStmtContext cxt; > Query *q; > --- 670,677 ---- > * - thomas 1997-12-02 > */ > static Query * > ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt, > ! List **extras_before, List **extras_after) > { > CreateStmtContext cxt; > Query *q; > *************** transformCreateStmt(ParseState *pstate, > *** 728,735 **** > q->utilityStmt = (Node *) stmt; > stmt->tableElts = cxt.columns; > stmt->constraints = cxt.ckconstraints; > ! extras_before = cxt.blist; > ! extras_after = cxt.alist; > > return q; > } > --- 741,748 ---- > q->utilityStmt = (Node *) stmt; > stmt->tableElts = cxt.columns; > stmt->constraints = cxt.ckconstraints; > ! *extras_before = nconc (*extras_before, cxt.blist); > ! *extras_after = nconc (cxt.alist, *extras_after); > > return q; > } > *************** transformIndexStmt(ParseState *pstate, I > *** 1668,1674 **** > * trees which is transformed into a list of query trees. > */ > static Query * > ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt) > { > Query *qry; > RangeTblEntry *oldrte; > --- 1681,1688 ---- > * trees which is transformed into a list of query trees. > */ > static Query * > ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt, > ! List **extras_before, List **extras_after) > { > Query *qry; > RangeTblEntry *oldrte; > *************** transformRuleStmt(ParseState *pstate, Ru > *** 1797,1803 **** > addRTEtoQuery(sub_pstate, newrte, false, true); > > /* Transform the rule action statement */ > ! top_subqry = transformStmt(sub_pstate, action); > > /* > * We cannot support utility-statement actions (eg NOTIFY) > --- 1811,1818 ---- > addRTEtoQuery(sub_pstate, newrte, false, true); > > /* Transform the rule action statement */ > ! top_subqry = transformStmt(sub_pstate, action, > ! extras_before, extras_after); > > /* > * We cannot support utility-statement actions (eg NOTIFY) > *************** transformUpdateStmt(ParseState *pstate, > *** 2494,2500 **** > * transform an Alter Table Statement > */ > static Query * > ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt) > { > CreateStmtContext cxt; > Query *qry; > --- 2509,2516 ---- > * transform an Alter Table Statement > */ > static Query * > ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, > ! List **extras_before, List **extras_after) > { > CreateStmtContext cxt; > Query *qry; > *************** transformAlterTableStmt(ParseState *psta > *** 2534,2541 **** > transformFKConstraints(pstate, &cxt); > > ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints; > ! extras_before = cxt.blist; > ! extras_after = cxt.alist; > break; > > case 'C': > --- 2550,2557 ---- > transformFKConstraints(pstate, &cxt); > > ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints; > ! *extras_before = nconc(*extras_before, cxt.blist); > ! *extras_after = nconc(cxt.alist, *extras_after); > break; > > case 'C': > *************** transformAlterTableStmt(ParseState *psta > *** 2571,2578 **** > > Assert(cxt.columns == NIL); > stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints); > ! extras_before = cxt.blist; > ! extras_after = cxt.alist; > break; > > default: > --- 2587,2594 ---- > > Assert(cxt.columns == NIL); > stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints); > ! *extras_before = nconc(*extras_before, cxt.blist); > ! *extras_after = nconc(cxt.alist, *extras_after); > break; > > default: > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/users-lounge/docs/faq.html -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Your patch has been added to the PostgreSQL unapplied patches list at: http://candle.pha.pa.us/cgi-bin/pgpatches I will try to apply it within the next 48 hours. --------------------------------------------------------------------------- Fernando Nasser wrote: > Hi, > > This patch will allow arbitrary levels of analyze / rewriting > by making the static variables extra_before and extra_after > automatic so we can use recursion. > > It gets much easier to generate extra commands now, and one can rest > assured that the extra commands will be properly analyzed/rewritten. > > > Without this patch, if a command produced by transformation tries to > use these static lists their first contents would be lost with > unpredictable results. I know I could fix this by just using nconc() > instead of assignments, but the resulting order of the commands would > not be exactly what one could expect. > > -- > Fernando Nasser > Red Hat Canada Ltd. E-Mail: fnasser@redhat.com > 2323 Yonge Street, Suite #300 > Toronto, Ontario M4P 2C9 > Index: src/backend/parser/analyze.c > =================================================================== > RCS file: /projects/cvsroot/pgsql/src/backend/parser/analyze.c,v > retrieving revision 1.213 > diff -c -p -r1.213 analyze.c > *** src/backend/parser/analyze.c 2002/01/03 23:21:31 1.213 > --- src/backend/parser/analyze.c 2002/02/12 15:35:58 > *************** typedef struct > *** 64,80 **** > } CreateStmtContext; > > > ! static Query *transformStmt(ParseState *pstate, Node *stmt); > static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); > ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt); > static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt); > ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt); > static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); > static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); > static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt); > static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); > ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt); > ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt); > static void transformColumnDefinition(ParseState *pstate, > CreateStmtContext *cxt, > ColumnDef *column); > --- 64,85 ---- > } CreateStmtContext; > > > ! static Query *transformStmt(ParseState *pstate, Node *stmt, > ! List **extras_before, List **extras_after); > static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); > ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt, > ! List **extras_before, List **extras_after); > static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt); > ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt, > ! List **extras_before, List **extras_after); > static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); > static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); > static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt); > static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); > ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt, > ! List **extras_before, List **extras_after); > ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, > ! List **extras_before, List **extras_after); > static void transformColumnDefinition(ParseState *pstate, > CreateStmtContext *cxt, > ColumnDef *column); > *************** static Oid transformFkeyGetColType(Creat > *** 101,109 **** > static void release_pstate_resources(ParseState *pstate); > static FromExpr *makeFromExpr(List *fromlist, Node *quals); > > - /* kluge to return extra info from transformCreateStmt() */ > - static List *extras_before; > - static List *extras_after; > > > /* > --- 106,111 ---- > *************** parse_analyze(Node *parseTree, ParseStat > *** 121,137 **** > List *result = NIL; > ParseState *pstate = make_parsestate(parentParseState); > Query *query; > > ! extras_before = extras_after = NIL; > ! > ! query = transformStmt(pstate, parseTree); > release_pstate_resources(pstate); > > while (extras_before != NIL) > { > ! result = lappend(result, > ! transformStmt(pstate, lfirst(extras_before))); > ! release_pstate_resources(pstate); > extras_before = lnext(extras_before); > } > > --- 123,138 ---- > List *result = NIL; > ParseState *pstate = make_parsestate(parentParseState); > Query *query; > + /* Lists to return extra commands from transformation */ > + List *extras_before = NIL; > + List *extras_after = NIL; > > ! query = transformStmt(pstate, parseTree, &extras_before, &extras_after); > release_pstate_resources(pstate); > > while (extras_before != NIL) > { > ! result = nconc(result, parse_analyze(lfirst(extras_before), pstate)); > extras_before = lnext(extras_before); > } > > *************** parse_analyze(Node *parseTree, ParseStat > *** 139,147 **** > > while (extras_after != NIL) > { > ! result = lappend(result, > ! transformStmt(pstate, lfirst(extras_after))); > ! release_pstate_resources(pstate); > extras_after = lnext(extras_after); > } > > --- 140,146 ---- > > while (extras_after != NIL) > { > ! result = nconc(result, parse_analyze(lfirst(extras_after), pstate)); > extras_after = lnext(extras_after); > } > > *************** release_pstate_resources(ParseState *pst > *** 164,170 **** > * transform a Parse tree into a Query tree. > */ > static Query * > ! transformStmt(ParseState *pstate, Node *parseTree) > { > Query *result = NULL; > > --- 163,170 ---- > * transform a Parse tree into a Query tree. > */ > static Query * > ! transformStmt(ParseState *pstate, Node *parseTree, > ! List **extras_before, List **extras_after) > { > Query *result = NULL; > > *************** transformStmt(ParseState *pstate, Node * > *** 174,180 **** > * Non-optimizable statements > */ > case T_CreateStmt: > ! result = transformCreateStmt(pstate, (CreateStmt *) parseTree); > break; > > case T_IndexStmt: > --- 174,181 ---- > * Non-optimizable statements > */ > case T_CreateStmt: > ! result = transformCreateStmt(pstate, (CreateStmt *) parseTree, > ! extras_before, extras_after); > break; > > case T_IndexStmt: > *************** transformStmt(ParseState *pstate, Node * > *** 182,195 **** > break; > > case T_RuleStmt: > ! result = transformRuleStmt(pstate, (RuleStmt *) parseTree); > break; > > case T_ViewStmt: > { > ViewStmt *n = (ViewStmt *) parseTree; > > ! n->query = transformStmt(pstate, (Node *) n->query); > > /* > * If a list of column names was given, run through and > --- 183,198 ---- > break; > > case T_RuleStmt: > ! result = transformRuleStmt(pstate, (RuleStmt *) parseTree, > ! extras_before, extras_after); > break; > > case T_ViewStmt: > { > ViewStmt *n = (ViewStmt *) parseTree; > > ! n->query = transformStmt(pstate, (Node *) n->query, > ! extras_before, extras_after); > > /* > * If a list of column names was given, run through and > *************** transformStmt(ParseState *pstate, Node * > *** 239,258 **** > > result = makeNode(Query); > result->commandType = CMD_UTILITY; > ! n->query = transformStmt(pstate, (Node *) n->query); > result->utilityStmt = (Node *) parseTree; > } > break; > > case T_AlterTableStmt: > ! result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree); > break; > > /* > * Optimizable statements > */ > case T_InsertStmt: > ! result = transformInsertStmt(pstate, (InsertStmt *) parseTree); > break; > > case T_DeleteStmt: > --- 242,264 ---- > > result = makeNode(Query); > result->commandType = CMD_UTILITY; > ! n->query = transformStmt(pstate, (Node *) n->query, > ! extras_before, extras_after); > result->utilityStmt = (Node *) parseTree; > } > break; > > case T_AlterTableStmt: > ! result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree, > ! extras_before, extras_after); > break; > > /* > * Optimizable statements > */ > case T_InsertStmt: > ! result = transformInsertStmt(pstate, (InsertStmt *) parseTree, > ! extras_before, extras_after); > break; > > case T_DeleteStmt: > *************** transformDeleteStmt(ParseState *pstate, > *** 337,343 **** > * transform an Insert Statement > */ > static Query * > ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt) > { > Query *qry = makeNode(Query); > List *sub_rtable; > --- 343,350 ---- > * transform an Insert Statement > */ > static Query * > ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt, > ! List **extras_before, List **extras_after) > { > Query *qry = makeNode(Query); > List *sub_rtable; > *************** transformInsertStmt(ParseState *pstate, > *** 402,408 **** > sub_pstate->p_rtable = sub_rtable; > sub_pstate->p_namespace = sub_namespace; > > ! selectQuery = transformStmt(sub_pstate, stmt->selectStmt); > > release_pstate_resources(sub_pstate); > pfree(sub_pstate); > --- 409,420 ---- > sub_pstate->p_rtable = sub_rtable; > sub_pstate->p_namespace = sub_namespace; > > ! /* > ! * Note: we are not expecting that extras_before and extras_after > ! * are going to be used by the transformation of the SELECT statement. > ! */ > ! selectQuery = transformStmt(sub_pstate, stmt->selectStmt, > ! extras_before, extras_after); > > release_pstate_resources(sub_pstate); > pfree(sub_pstate); > *************** CreateIndexName(char *table_name, char * > *** 658,664 **** > * - thomas 1997-12-02 > */ > static Query * > ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt) > { > CreateStmtContext cxt; > Query *q; > --- 670,677 ---- > * - thomas 1997-12-02 > */ > static Query * > ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt, > ! List **extras_before, List **extras_after) > { > CreateStmtContext cxt; > Query *q; > *************** transformCreateStmt(ParseState *pstate, > *** 728,735 **** > q->utilityStmt = (Node *) stmt; > stmt->tableElts = cxt.columns; > stmt->constraints = cxt.ckconstraints; > ! extras_before = cxt.blist; > ! extras_after = cxt.alist; > > return q; > } > --- 741,748 ---- > q->utilityStmt = (Node *) stmt; > stmt->tableElts = cxt.columns; > stmt->constraints = cxt.ckconstraints; > ! *extras_before = nconc (*extras_before, cxt.blist); > ! *extras_after = nconc (cxt.alist, *extras_after); > > return q; > } > *************** transformIndexStmt(ParseState *pstate, I > *** 1668,1674 **** > * trees which is transformed into a list of query trees. > */ > static Query * > ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt) > { > Query *qry; > RangeTblEntry *oldrte; > --- 1681,1688 ---- > * trees which is transformed into a list of query trees. > */ > static Query * > ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt, > ! List **extras_before, List **extras_after) > { > Query *qry; > RangeTblEntry *oldrte; > *************** transformRuleStmt(ParseState *pstate, Ru > *** 1797,1803 **** > addRTEtoQuery(sub_pstate, newrte, false, true); > > /* Transform the rule action statement */ > ! top_subqry = transformStmt(sub_pstate, action); > > /* > * We cannot support utility-statement actions (eg NOTIFY) > --- 1811,1818 ---- > addRTEtoQuery(sub_pstate, newrte, false, true); > > /* Transform the rule action statement */ > ! top_subqry = transformStmt(sub_pstate, action, > ! extras_before, extras_after); > > /* > * We cannot support utility-statement actions (eg NOTIFY) > *************** transformUpdateStmt(ParseState *pstate, > *** 2494,2500 **** > * transform an Alter Table Statement > */ > static Query * > ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt) > { > CreateStmtContext cxt; > Query *qry; > --- 2509,2516 ---- > * transform an Alter Table Statement > */ > static Query * > ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, > ! List **extras_before, List **extras_after) > { > CreateStmtContext cxt; > Query *qry; > *************** transformAlterTableStmt(ParseState *psta > *** 2534,2541 **** > transformFKConstraints(pstate, &cxt); > > ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints; > ! extras_before = cxt.blist; > ! extras_after = cxt.alist; > break; > > case 'C': > --- 2550,2557 ---- > transformFKConstraints(pstate, &cxt); > > ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints; > ! *extras_before = nconc(*extras_before, cxt.blist); > ! *extras_after = nconc(cxt.alist, *extras_after); > break; > > case 'C': > *************** transformAlterTableStmt(ParseState *psta > *** 2571,2578 **** > > Assert(cxt.columns == NIL); > stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints); > ! extras_before = cxt.blist; > ! extras_after = cxt.alist; > break; > > default: > --- 2587,2594 ---- > > Assert(cxt.columns == NIL); > stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints); > ! *extras_before = nconc(*extras_before, cxt.blist); > ! *extras_after = nconc(cxt.alist, *extras_after); > break; > > default: > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/users-lounge/docs/faq.html -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Patch applied. Thanks. --------------------------------------------------------------------------- Fernando Nasser wrote: > Hi, > > This patch will allow arbitrary levels of analyze / rewriting > by making the static variables extra_before and extra_after > automatic so we can use recursion. > > It gets much easier to generate extra commands now, and one can rest > assured that the extra commands will be properly analyzed/rewritten. > > > Without this patch, if a command produced by transformation tries to > use these static lists their first contents would be lost with > unpredictable results. I know I could fix this by just using nconc() > instead of assignments, but the resulting order of the commands would > not be exactly what one could expect. > > -- > Fernando Nasser > Red Hat Canada Ltd. E-Mail: fnasser@redhat.com > 2323 Yonge Street, Suite #300 > Toronto, Ontario M4P 2C9 > Index: src/backend/parser/analyze.c > =================================================================== > RCS file: /projects/cvsroot/pgsql/src/backend/parser/analyze.c,v > retrieving revision 1.213 > diff -c -p -r1.213 analyze.c > *** src/backend/parser/analyze.c 2002/01/03 23:21:31 1.213 > --- src/backend/parser/analyze.c 2002/02/12 15:35:58 > *************** typedef struct > *** 64,80 **** > } CreateStmtContext; > > > ! static Query *transformStmt(ParseState *pstate, Node *stmt); > static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); > ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt); > static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt); > ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt); > static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); > static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); > static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt); > static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); > ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt); > ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt); > static void transformColumnDefinition(ParseState *pstate, > CreateStmtContext *cxt, > ColumnDef *column); > --- 64,85 ---- > } CreateStmtContext; > > > ! static Query *transformStmt(ParseState *pstate, Node *stmt, > ! List **extras_before, List **extras_after); > static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); > ! static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt, > ! List **extras_before, List **extras_after); > static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt); > ! static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt, > ! List **extras_before, List **extras_after); > static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); > static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); > static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt); > static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); > ! static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt, > ! List **extras_before, List **extras_after); > ! static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, > ! List **extras_before, List **extras_after); > static void transformColumnDefinition(ParseState *pstate, > CreateStmtContext *cxt, > ColumnDef *column); > *************** static Oid transformFkeyGetColType(Creat > *** 101,109 **** > static void release_pstate_resources(ParseState *pstate); > static FromExpr *makeFromExpr(List *fromlist, Node *quals); > > - /* kluge to return extra info from transformCreateStmt() */ > - static List *extras_before; > - static List *extras_after; > > > /* > --- 106,111 ---- > *************** parse_analyze(Node *parseTree, ParseStat > *** 121,137 **** > List *result = NIL; > ParseState *pstate = make_parsestate(parentParseState); > Query *query; > > ! extras_before = extras_after = NIL; > ! > ! query = transformStmt(pstate, parseTree); > release_pstate_resources(pstate); > > while (extras_before != NIL) > { > ! result = lappend(result, > ! transformStmt(pstate, lfirst(extras_before))); > ! release_pstate_resources(pstate); > extras_before = lnext(extras_before); > } > > --- 123,138 ---- > List *result = NIL; > ParseState *pstate = make_parsestate(parentParseState); > Query *query; > + /* Lists to return extra commands from transformation */ > + List *extras_before = NIL; > + List *extras_after = NIL; > > ! query = transformStmt(pstate, parseTree, &extras_before, &extras_after); > release_pstate_resources(pstate); > > while (extras_before != NIL) > { > ! result = nconc(result, parse_analyze(lfirst(extras_before), pstate)); > extras_before = lnext(extras_before); > } > > *************** parse_analyze(Node *parseTree, ParseStat > *** 139,147 **** > > while (extras_after != NIL) > { > ! result = lappend(result, > ! transformStmt(pstate, lfirst(extras_after))); > ! release_pstate_resources(pstate); > extras_after = lnext(extras_after); > } > > --- 140,146 ---- > > while (extras_after != NIL) > { > ! result = nconc(result, parse_analyze(lfirst(extras_after), pstate)); > extras_after = lnext(extras_after); > } > > *************** release_pstate_resources(ParseState *pst > *** 164,170 **** > * transform a Parse tree into a Query tree. > */ > static Query * > ! transformStmt(ParseState *pstate, Node *parseTree) > { > Query *result = NULL; > > --- 163,170 ---- > * transform a Parse tree into a Query tree. > */ > static Query * > ! transformStmt(ParseState *pstate, Node *parseTree, > ! List **extras_before, List **extras_after) > { > Query *result = NULL; > > *************** transformStmt(ParseState *pstate, Node * > *** 174,180 **** > * Non-optimizable statements > */ > case T_CreateStmt: > ! result = transformCreateStmt(pstate, (CreateStmt *) parseTree); > break; > > case T_IndexStmt: > --- 174,181 ---- > * Non-optimizable statements > */ > case T_CreateStmt: > ! result = transformCreateStmt(pstate, (CreateStmt *) parseTree, > ! extras_before, extras_after); > break; > > case T_IndexStmt: > *************** transformStmt(ParseState *pstate, Node * > *** 182,195 **** > break; > > case T_RuleStmt: > ! result = transformRuleStmt(pstate, (RuleStmt *) parseTree); > break; > > case T_ViewStmt: > { > ViewStmt *n = (ViewStmt *) parseTree; > > ! n->query = transformStmt(pstate, (Node *) n->query); > > /* > * If a list of column names was given, run through and > --- 183,198 ---- > break; > > case T_RuleStmt: > ! result = transformRuleStmt(pstate, (RuleStmt *) parseTree, > ! extras_before, extras_after); > break; > > case T_ViewStmt: > { > ViewStmt *n = (ViewStmt *) parseTree; > > ! n->query = transformStmt(pstate, (Node *) n->query, > ! extras_before, extras_after); > > /* > * If a list of column names was given, run through and > *************** transformStmt(ParseState *pstate, Node * > *** 239,258 **** > > result = makeNode(Query); > result->commandType = CMD_UTILITY; > ! n->query = transformStmt(pstate, (Node *) n->query); > result->utilityStmt = (Node *) parseTree; > } > break; > > case T_AlterTableStmt: > ! result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree); > break; > > /* > * Optimizable statements > */ > case T_InsertStmt: > ! result = transformInsertStmt(pstate, (InsertStmt *) parseTree); > break; > > case T_DeleteStmt: > --- 242,264 ---- > > result = makeNode(Query); > result->commandType = CMD_UTILITY; > ! n->query = transformStmt(pstate, (Node *) n->query, > ! extras_before, extras_after); > result->utilityStmt = (Node *) parseTree; > } > break; > > case T_AlterTableStmt: > ! result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree, > ! extras_before, extras_after); > break; > > /* > * Optimizable statements > */ > case T_InsertStmt: > ! result = transformInsertStmt(pstate, (InsertStmt *) parseTree, > ! extras_before, extras_after); > break; > > case T_DeleteStmt: > *************** transformDeleteStmt(ParseState *pstate, > *** 337,343 **** > * transform an Insert Statement > */ > static Query * > ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt) > { > Query *qry = makeNode(Query); > List *sub_rtable; > --- 343,350 ---- > * transform an Insert Statement > */ > static Query * > ! transformInsertStmt(ParseState *pstate, InsertStmt *stmt, > ! List **extras_before, List **extras_after) > { > Query *qry = makeNode(Query); > List *sub_rtable; > *************** transformInsertStmt(ParseState *pstate, > *** 402,408 **** > sub_pstate->p_rtable = sub_rtable; > sub_pstate->p_namespace = sub_namespace; > > ! selectQuery = transformStmt(sub_pstate, stmt->selectStmt); > > release_pstate_resources(sub_pstate); > pfree(sub_pstate); > --- 409,420 ---- > sub_pstate->p_rtable = sub_rtable; > sub_pstate->p_namespace = sub_namespace; > > ! /* > ! * Note: we are not expecting that extras_before and extras_after > ! * are going to be used by the transformation of the SELECT statement. > ! */ > ! selectQuery = transformStmt(sub_pstate, stmt->selectStmt, > ! extras_before, extras_after); > > release_pstate_resources(sub_pstate); > pfree(sub_pstate); > *************** CreateIndexName(char *table_name, char * > *** 658,664 **** > * - thomas 1997-12-02 > */ > static Query * > ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt) > { > CreateStmtContext cxt; > Query *q; > --- 670,677 ---- > * - thomas 1997-12-02 > */ > static Query * > ! transformCreateStmt(ParseState *pstate, CreateStmt *stmt, > ! List **extras_before, List **extras_after) > { > CreateStmtContext cxt; > Query *q; > *************** transformCreateStmt(ParseState *pstate, > *** 728,735 **** > q->utilityStmt = (Node *) stmt; > stmt->tableElts = cxt.columns; > stmt->constraints = cxt.ckconstraints; > ! extras_before = cxt.blist; > ! extras_after = cxt.alist; > > return q; > } > --- 741,748 ---- > q->utilityStmt = (Node *) stmt; > stmt->tableElts = cxt.columns; > stmt->constraints = cxt.ckconstraints; > ! *extras_before = nconc (*extras_before, cxt.blist); > ! *extras_after = nconc (cxt.alist, *extras_after); > > return q; > } > *************** transformIndexStmt(ParseState *pstate, I > *** 1668,1674 **** > * trees which is transformed into a list of query trees. > */ > static Query * > ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt) > { > Query *qry; > RangeTblEntry *oldrte; > --- 1681,1688 ---- > * trees which is transformed into a list of query trees. > */ > static Query * > ! transformRuleStmt(ParseState *pstate, RuleStmt *stmt, > ! List **extras_before, List **extras_after) > { > Query *qry; > RangeTblEntry *oldrte; > *************** transformRuleStmt(ParseState *pstate, Ru > *** 1797,1803 **** > addRTEtoQuery(sub_pstate, newrte, false, true); > > /* Transform the rule action statement */ > ! top_subqry = transformStmt(sub_pstate, action); > > /* > * We cannot support utility-statement actions (eg NOTIFY) > --- 1811,1818 ---- > addRTEtoQuery(sub_pstate, newrte, false, true); > > /* Transform the rule action statement */ > ! top_subqry = transformStmt(sub_pstate, action, > ! extras_before, extras_after); > > /* > * We cannot support utility-statement actions (eg NOTIFY) > *************** transformUpdateStmt(ParseState *pstate, > *** 2494,2500 **** > * transform an Alter Table Statement > */ > static Query * > ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt) > { > CreateStmtContext cxt; > Query *qry; > --- 2509,2516 ---- > * transform an Alter Table Statement > */ > static Query * > ! transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, > ! List **extras_before, List **extras_after) > { > CreateStmtContext cxt; > Query *qry; > *************** transformAlterTableStmt(ParseState *psta > *** 2534,2541 **** > transformFKConstraints(pstate, &cxt); > > ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints; > ! extras_before = cxt.blist; > ! extras_after = cxt.alist; > break; > > case 'C': > --- 2550,2557 ---- > transformFKConstraints(pstate, &cxt); > > ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints; > ! *extras_before = nconc(*extras_before, cxt.blist); > ! *extras_after = nconc(cxt.alist, *extras_after); > break; > > case 'C': > *************** transformAlterTableStmt(ParseState *psta > *** 2571,2578 **** > > Assert(cxt.columns == NIL); > stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints); > ! extras_before = cxt.blist; > ! extras_after = cxt.alist; > break; > > default: > --- 2587,2594 ---- > > Assert(cxt.columns == NIL); > stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints); > ! *extras_before = nconc(*extras_before, cxt.blist); > ! *extras_after = nconc(cxt.alist, *extras_after); > break; > > default: > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/users-lounge/docs/faq.html -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026