From 88381ade63de931c84f53dc873c986d40b8c8b61 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 11 Aug 2003 20:46:47 +0000 Subject: [PATCH] Code cleanup inspired by recent resname bug report (doesn't fix the bug yet, though). Avoid using nth() to fetch tlist entries; provide a common routine get_tle_by_resno() to search a tlist for a particular resno. This replaces a couple uses of nth() and a dozen hand-coded search loops. Also, replace a few uses of nth(length-1, list) with llast(). --- src/backend/catalog/pg_proc.c | 4 +- src/backend/commands/comment.c | 10 +- src/backend/commands/explain.c | 29 ++-- src/backend/executor/execJunk.c | 12 +- src/backend/optimizer/path/allpaths.c | 14 +- src/backend/optimizer/plan/createplan.c | 9 +- src/backend/parser/parse_relation.c | 46 ++++--- src/backend/parser/parse_target.c | 158 +++++++++++----------- src/backend/rewrite/rewriteManip.c | 170 +----------------------- src/backend/utils/adt/not_in.c | 4 +- src/backend/utils/adt/tid.c | 9 +- src/include/parser/parsetree.h | 12 +- 12 files changed, 161 insertions(+), 316 deletions(-) diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 0181eb9b14..323fc8e68c 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.104 2003/08/04 02:39:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.105 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -371,7 +371,7 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList) } /* find the final query */ - parse = (Query *) nth(length(queryTreeList) - 1, queryTreeList); + parse = (Query *) llast(queryTreeList); cmd = parse->commandType; tlist = parse->targetList; diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 4ed3614506..df09337d72 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -7,7 +7,7 @@ * Copyright (c) 1996-2003, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.69 2003/08/04 23:59:37 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.70 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -365,7 +365,7 @@ CommentAttribute(List *qualname, char *comment) if (nnames < 2) /* parser messed up */ elog(ERROR, "must specify relation and attribute"); relname = ltruncate(nnames - 1, listCopy(qualname)); - attrname = strVal(nth(nnames - 1, qualname)); + attrname = strVal(llast(qualname)); /* Open the containing relation to ensure it won't go away meanwhile */ rel = makeRangeVarFromNameList(relname); @@ -583,7 +583,7 @@ CommentRule(List *qualname, char *comment) /* New-style: rule and relname both provided */ Assert(nnames >= 2); relname = ltruncate(nnames - 1, listCopy(qualname)); - rulename = strVal(nth(nnames - 1, qualname)); + rulename = strVal(llast(qualname)); /* Open the owning relation to ensure it won't go away meanwhile */ rel = makeRangeVarFromNameList(relname); @@ -778,7 +778,7 @@ CommentTrigger(List *qualname, char *comment) if (nnames < 2) /* parser messed up */ elog(ERROR, "must specify relation and trigger"); relname = ltruncate(nnames - 1, listCopy(qualname)); - trigname = strVal(nth(nnames - 1, qualname)); + trigname = strVal(llast(qualname)); /* Open the owning relation to ensure it won't go away meanwhile */ rel = makeRangeVarFromNameList(relname); @@ -856,7 +856,7 @@ CommentConstraint(List *qualname, char *comment) if (nnames < 2) /* parser messed up */ elog(ERROR, "must specify relation and constraint"); relName = ltruncate(nnames - 1, listCopy(qualname)); - conName = strVal(nth(nnames - 1, qualname)); + conName = strVal(llast(qualname)); /* Open the owning relation to ensure it won't go away meanwhile */ rel = makeRangeVarFromNameList(relName); diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 6e2b857271..e664b3e494 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994-5, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.114 2003/08/08 21:41:30 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.115 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -947,7 +947,6 @@ show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols, List *context; bool useprefix; int keyno; - List *tl; char *exprstr; Relids varnos; int i; @@ -993,25 +992,17 @@ show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols, { /* find key expression in tlist */ AttrNumber keyresno = keycols[keyno]; + TargetEntry *target = get_tle_by_resno(tlist, keyresno); - foreach(tl, tlist) - { - TargetEntry *target = (TargetEntry *) lfirst(tl); - - if (target->resdom->resno == keyresno) - { - /* Deparse the expression, showing any top-level cast */ - exprstr = deparse_expression((Node *) target->expr, context, - useprefix, true); - /* And add to str */ - if (keyno > 0) - appendStringInfo(str, ", "); - appendStringInfo(str, "%s", exprstr); - break; - } - } - if (tl == NIL) + if (!target) elog(ERROR, "no tlist entry for key %d", keyresno); + /* Deparse the expression, showing any top-level cast */ + exprstr = deparse_expression((Node *) target->expr, context, + useprefix, true); + /* And add to str */ + if (keyno > 0) + appendStringInfo(str, ", "); + appendStringInfo(str, "%s", exprstr); } appendStringInfo(str, "\n"); diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c index e976729a80..654fc7811a 100644 --- a/src/backend/executor/execJunk.c +++ b/src/backend/executor/execJunk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.35 2003/08/04 02:39:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.36 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -185,10 +185,7 @@ ExecGetJunkAttribute(JunkFilter *junkfilter, { List *targetList; List *t; - Resdom *resdom; AttrNumber resno; - char *resname; - bool resjunk; TupleDesc tupType; HeapTuple tuple; @@ -202,11 +199,10 @@ ExecGetJunkAttribute(JunkFilter *junkfilter, foreach(t, targetList) { TargetEntry *tle = lfirst(t); + Resdom *resdom = tle->resdom; - resdom = tle->resdom; - resname = resdom->resname; - resjunk = resdom->resjunk; - if (resjunk && (strcmp(resname, attrName) == 0)) + if (resdom->resjunk && resdom->resname && + (strcmp(resdom->resname, attrName) == 0)) { /* We found it ! */ resno = resdom->resno; diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 118a701e34..1c53c8e9f5 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.106 2003/08/04 02:40:00 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.107 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -726,8 +726,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual, foreach(vl, vars) { Var *var = (Var *) lfirst(vl); - List *tl; - TargetEntry *tle = NULL; + TargetEntry *tle; Assert(var->varno == rti); @@ -748,13 +747,8 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual, } /* Must find the tlist element referenced by the Var */ - foreach(tl, subquery->targetList) - { - tle = (TargetEntry *) lfirst(tl); - if (tle->resdom->resno == var->varattno) - break; - } - Assert(tl != NIL); + tle = get_tle_by_resno(subquery->targetList, var->varattno); + Assert(tle != NULL); Assert(!tle->resdom->resjunk); /* If subquery uses DISTINCT or DISTINCT ON, check point 3 */ diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 8abcfc576c..2f7fd02fb4 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.153 2003/08/08 21:41:48 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.154 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -28,6 +28,7 @@ #include "optimizer/restrictinfo.h" #include "optimizer/tlist.h" #include "optimizer/var.h" +#include "parser/parsetree.h" #include "parser/parse_clause.h" #include "parser/parse_expr.h" #include "utils/lsyscache.h" @@ -626,8 +627,8 @@ create_unique_plan(Query *root, UniquePath *best_path) { TargetEntry *tle; - tle = nth(groupColIdx[groupColPos] - 1, my_tlist); - Assert(tle->resdom->resno == groupColIdx[groupColPos]); + tle = get_tle_by_resno(my_tlist, groupColIdx[groupColPos]); + Assert(tle != NULL); sortList = addTargetToSortList(NULL, tle, sortList, my_tlist, NIL, false); } @@ -1975,7 +1976,7 @@ make_sort_from_groupcols(Query *root, foreach(i, groupcls) { GroupClause *grpcl = (GroupClause *) lfirst(i); - TargetEntry *tle = nth(grpColIdx[grpno] - 1, sub_tlist); + TargetEntry *tle = get_tle_by_resno(sub_tlist, grpColIdx[grpno]); Resdom *resdom = tle->resdom; /* diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index f9c3a8ba03..b8c2d8c8e3 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.87 2003/08/04 02:40:02 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.88 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1599,21 +1599,14 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum, case RTE_SUBQUERY: { /* Subselect RTE --- get type info from subselect's tlist */ - List *tlistitem; + TargetEntry *te = get_tle_by_resno(rte->subquery->targetList, + attnum); - foreach(tlistitem, rte->subquery->targetList) - { - TargetEntry *te = (TargetEntry *) lfirst(tlistitem); - - if (te->resdom->resjunk || te->resdom->resno != attnum) - continue; - *vartype = te->resdom->restype; - *vartypmod = te->resdom->restypmod; - return; - } - /* falling off end of list shouldn't happen... */ - elog(ERROR, "subquery %s does not have attribute %d", - rte->eref->aliasname, attnum); + if (te == NULL || te->resdom->resjunk) + elog(ERROR, "subquery %s does not have attribute %d", + rte->eref->aliasname, attnum); + *vartype = te->resdom->restype; + *vartypmod = te->resdom->restypmod; } break; case RTE_FUNCTION: @@ -1777,6 +1770,29 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum) return result; } +/* + * Given a targetlist and a resno, return the matching TargetEntry + * + * Returns NULL if resno is not present in list. + * + * Note: we need to search, rather than just indexing with nth(), because + * not all tlists are sorted by resno. + */ +TargetEntry * +get_tle_by_resno(List *tlist, AttrNumber resno) +{ + List *i; + + foreach(i, tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(i); + + if (tle->resdom->resno == resno) + return tle; + } + return NULL; +} + /* * given relation and att name, return id of variable * diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 2f1233da7c..a525e8795f 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.110 2003/08/04 02:40:02 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.111 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -100,49 +100,55 @@ transformTargetEntry(ParseState *pstate, List * transformTargetList(ParseState *pstate, List *targetlist) { - List *p_target = NIL; + FastList p_target; + List *o_target; - while (targetlist != NIL) + FastListInit(&p_target); + + foreach(o_target, targetlist) { - ResTarget *res = (ResTarget *) lfirst(targetlist); + ResTarget *res = (ResTarget *) lfirst(o_target); if (IsA(res->val, ColumnRef)) { ColumnRef *cref = (ColumnRef *) res->val; List *fields = cref->fields; - int numnames = length(fields); - if (numnames == 1 && strcmp(strVal(lfirst(fields)), "*") == 0) + if (strcmp(strVal(llast(fields)), "*") == 0) { - /* - * Target item is a single '*', expand all tables (eg. - * SELECT * FROM emp) - */ - p_target = nconc(p_target, - ExpandAllTables(pstate)); - } - else if (strcmp(strVal(nth(numnames - 1, fields)), "*") == 0) - { - /* - * Target item is relation.*, expand that table (eg. - * SELECT emp.*, dname FROM emp, dept) - */ - char *schemaname; - char *relname; - RangeTblEntry *rte; - int sublevels_up; + int numnames = length(fields); - switch (numnames) + if (numnames == 1) { - case 2: - schemaname = NULL; - relname = strVal(lfirst(fields)); - break; - case 3: - schemaname = strVal(lfirst(fields)); - relname = strVal(lsecond(fields)); - break; - case 4: + /* + * Target item is a single '*', expand all tables + * (e.g., SELECT * FROM emp) + */ + FastConc(&p_target, + ExpandAllTables(pstate)); + } + else + { + /* + * Target item is relation.*, expand that table + * (e.g., SELECT emp.*, dname FROM emp, dept) + */ + char *schemaname; + char *relname; + RangeTblEntry *rte; + int sublevels_up; + + switch (numnames) + { + case 2: + schemaname = NULL; + relname = strVal(lfirst(fields)); + break; + case 3: + schemaname = strVal(lfirst(fields)); + relname = strVal(lsecond(fields)); + break; + case 4: { char *name1 = strVal(lfirst(fields)); @@ -152,57 +158,56 @@ transformTargetList(ParseState *pstate, List *targetlist) */ if (strcmp(name1, get_database_name(MyDatabaseId)) != 0) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cross-database references are not implemented"))); + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cross-database references are not implemented"))); schemaname = strVal(lsecond(fields)); relname = strVal(lthird(fields)); break; } - default: - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("improper qualified name (too many dotted names): %s", - NameListToString(fields)))); - schemaname = NULL; /* keep compiler quiet */ - relname = NULL; - break; + default: + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("improper qualified name (too many dotted names): %s", + NameListToString(fields)))); + schemaname = NULL; /* keep compiler quiet */ + relname = NULL; + break; + } + + rte = refnameRangeTblEntry(pstate, schemaname, relname, + &sublevels_up); + if (rte == NULL) + rte = addImplicitRTE(pstate, makeRangeVar(schemaname, + relname)); + + FastConc(&p_target, + expandRelAttrs(pstate, rte)); } - - rte = refnameRangeTblEntry(pstate, schemaname, relname, - &sublevels_up); - if (rte == NULL) - rte = addImplicitRTE(pstate, makeRangeVar(schemaname, - relname)); - - p_target = nconc(p_target, - expandRelAttrs(pstate, rte)); } else { /* Plain ColumnRef node, treat it as an expression */ - p_target = lappend(p_target, - transformTargetEntry(pstate, - res->val, - NULL, - res->name, - false)); + FastAppend(&p_target, + transformTargetEntry(pstate, + res->val, + NULL, + res->name, + false)); } } else { /* Everything else but ColumnRef */ - p_target = lappend(p_target, - transformTargetEntry(pstate, - res->val, - NULL, - res->name, - false)); + FastAppend(&p_target, + transformTargetEntry(pstate, + res->val, + NULL, + res->name, + false)); } - - targetlist = lnext(targetlist); } - return p_target; + return FastListValue(&p_target); } @@ -264,23 +269,14 @@ markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var) case RTE_SUBQUERY: { /* Subselect-in-FROM: copy up from the subselect */ - List *subtl; + TargetEntry *te = get_tle_by_resno(rte->subquery->targetList, + attnum); - foreach(subtl, rte->subquery->targetList) - { - TargetEntry *subte = (TargetEntry *) lfirst(subtl); - - if (subte->resdom->resjunk || - subte->resdom->resno != attnum) - continue; - res->resorigtbl = subte->resdom->resorigtbl; - res->resorigcol = subte->resdom->resorigcol; - break; - } - /* falling off end of list shouldn't happen... */ - if (subtl == NIL) + if (te == NULL || te->resdom->resjunk) elog(ERROR, "subquery %s does not have attribute %d", rte->eref->aliasname, attnum); + res->resorigtbl = te->resdom->resorigtbl; + res->resorigcol = te->resdom->resorigcol; } break; case RTE_JOIN: diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index 3d0cf931c6..d9c7967f7c 100644 --- a/src/backend/rewrite/rewriteManip.c +++ b/src/backend/rewrite/rewriteManip.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.77 2003/08/08 21:41:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.78 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -838,44 +838,6 @@ AddInvertedQual(Query *parsetree, Node *qual) } -/* Find a targetlist entry by resno */ -static Node * -FindMatchingNew(List *tlist, int attno) -{ - List *i; - - foreach(i, tlist) - { - TargetEntry *tle = lfirst(i); - - if (tle->resdom->resno == attno) - return (Node *) tle->expr; - } - return NULL; -} - -#ifdef NOT_USED - -/* Find a targetlist entry by resname */ -static Node * -FindMatchingTLEntry(List *tlist, char *e_attname) -{ - List *i; - - foreach(i, tlist) - { - TargetEntry *tle = lfirst(i); - char *resname; - - resname = tle->resdom->resname; - if (strcmp(e_attname, resname) == 0) - return tle->expr; - } - return NULL; -} -#endif - - /* * ResolveNew - replace Vars with corresponding items from a targetlist * @@ -908,7 +870,7 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context) if (this_varno == context->target_varno && this_varlevelsup == context->sublevels_up) { - Node *n; + TargetEntry *tle; /* band-aid: don't do the wrong thing with a whole-tuple Var */ if (var->varattno == InvalidAttrNumber) @@ -916,9 +878,9 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot handle whole-tuple reference"))); - n = FindMatchingNew(context->targetlist, var->varattno); + tle = get_tle_by_resno(context->targetlist, var->varattno); - if (n == NULL) + if (tle == NULL) { if (context->event == CMD_UPDATE) { @@ -937,7 +899,8 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context) else { /* Make a copy of the tlist item to return */ - n = copyObject(n); + Node *n = copyObject(tle->expr); + /* Adjust varlevelsup if tlist item is from higher query */ if (this_varlevelsup > 0) IncrementVarSublevelsUp(n, this_varlevelsup, 0); @@ -985,124 +948,3 @@ ResolveNew(Node *node, int target_varno, int sublevels_up, (void *) &context, 0); } - - -#ifdef NOT_USED - -/* - * HandleRIRAttributeRule - * Replace Vars matching a given RT index with copies of TL expressions. - * - * Handles 'on retrieve to relation.attribute - * do instead retrieve (attribute = expression) w/qual' - */ - -typedef struct -{ - List *rtable; - List *targetlist; - int rt_index; - int attr_num; - int *modified; - int *badsql; - int sublevels_up; -} HandleRIRAttributeRule_context; - -static Node * -HandleRIRAttributeRule_mutator(Node *node, - HandleRIRAttributeRule_context * context) -{ - if (node == NULL) - return NULL; - if (IsA(node, Var)) - { - Var *var = (Var *) node; - int this_varno = var->varno; - int this_varattno = var->varattno; - int this_varlevelsup = var->varlevelsup; - - if (this_varno == context->rt_index && - this_varattno == context->attr_num && - this_varlevelsup == context->sublevels_up) - { - if (var->vartype == 32) - { /* HACK: disallow SET variables */ - *context->modified = TRUE; - *context->badsql = TRUE; - return (Node *) makeNullConst(var->vartype); - } - else - { - char *name_to_look_for; - - name_to_look_for = get_attname(getrelid(this_varno, - context->rtable), - this_varattno); - if (name_to_look_for) - { - Node *n; - - *context->modified = TRUE; - n = FindMatchingTLEntry(context->targetlist, - name_to_look_for); - if (n == NULL) - return (Node *) makeNullConst(var->vartype); - /* Make a copy of the tlist item to return */ - n = copyObject(n); - - /* - * Adjust varlevelsup if tlist item is from higher - * query - */ - if (this_varlevelsup > 0) - IncrementVarSublevelsUp(n, this_varlevelsup, 0); - return n; - } - } - } - /* otherwise fall through to copy the var normally */ - } - - if (IsA(node, Query)) - { - /* Recurse into RTE subquery or not-yet-planned sublink subquery */ - Query *newnode; - - context->sublevels_up++; - newnode = query_tree_mutator((Query *) node, - HandleRIRAttributeRule_mutator, - (void *) context, - 0); - context->sublevels_up--; - return (Node *) newnode; - } - return expression_tree_mutator(node, HandleRIRAttributeRule_mutator, - (void *) context); -} - -void -HandleRIRAttributeRule(Query *parsetree, - List *rtable, - List *targetlist, - int rt_index, - int attr_num, - int *modified, - int *badsql) -{ - HandleRIRAttributeRule_context context; - - context.rtable = rtable; - context.targetlist = targetlist; - context.rt_index = rt_index; - context.attr_num = attr_num; - context.modified = modified; - context.badsql = badsql; - context.sublevels_up = 0; - - query_tree_mutator(parsetree, - HandleRIRAttributeRule_mutator, - (void *) &context, - QTW_DONT_COPY_QUERY); -} - -#endif /* NOT_USED */ diff --git a/src/backend/utils/adt/not_in.c b/src/backend/utils/adt/not_in.c index a92c13841f..42ce2d2fcb 100644 --- a/src/backend/utils/adt/not_in.c +++ b/src/backend/utils/adt/not_in.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.35 2003/08/04 02:40:05 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.36 2003/08/11 20:46:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -63,7 +63,7 @@ int4notin(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_NAME), errmsg("invalid name syntax"), errhint("Must provide \"relationname.attributename\"."))); - attribute = strVal(nth(nnames - 1, names)); + attribute = strVal(llast(names)); names = ltruncate(nnames - 1, names); relrv = makeRangeVarFromNameList(names); diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c index ee5a7bb6ad..efc5f78a37 100644 --- a/src/backend/utils/adt/tid.c +++ b/src/backend/utils/adt/tid.c @@ -8,14 +8,13 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.39 2003/08/04 02:40:05 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.40 2003/08/11 20:46:46 tgl Exp $ * * NOTES * input routine largely stolen from boxin(). * *------------------------------------------------------------------------- */ - #include "postgres.h" #include @@ -26,6 +25,7 @@ #include "catalog/namespace.h" #include "catalog/pg_type.h" #include "libpq/pqformat.h" +#include "parser/parsetree.h" #include "utils/builtins.h" @@ -223,6 +223,7 @@ currtid_for_view(Relation viewrel, ItemPointer tid) if (att->attrs[i]->atttypid != TIDOID) elog(ERROR, "ctid isn't of type TID"); tididx = i; + break; } } if (tididx < 0) @@ -241,7 +242,7 @@ currtid_for_view(Relation viewrel, ItemPointer tid) if (length(rewrite->actions) != 1) elog(ERROR, "only one select rule is allowed in views"); query = (Query *) lfirst(rewrite->actions); - tle = (TargetEntry *) nth(tididx, query->targetList); + tle = get_tle_by_resno(query->targetList, tididx+1); if (tle && tle->expr && IsA(tle->expr, Var)) { Var *var = (Var *) tle->expr; @@ -250,7 +251,7 @@ currtid_for_view(Relation viewrel, ItemPointer tid) if (var->varno > 0 && var->varno < INNER && var->varattno == SelfItemPointerAttributeNumber) { - rte = (RangeTblEntry *) nth(var->varno - 1, query->rtable); + rte = rt_fetch(var->varno, query->rtable); if (rte) { heap_close(viewrel, AccessShareLock); diff --git a/src/include/parser/parsetree.h b/src/include/parser/parsetree.h index a172b25bd3..d69acffeff 100644 --- a/src/include/parser/parsetree.h +++ b/src/include/parser/parsetree.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsetree.h,v 1.21 2003/08/04 02:40:14 momjian Exp $ + * $Id: parsetree.h,v 1.22 2003/08/11 20:46:47 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,7 +20,7 @@ /* ---------------- - * range table macros + * range table operations * ---------------- */ @@ -55,4 +55,12 @@ extern char *get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum); extern void get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum, Oid *vartype, int32 *vartypmod); + +/* ---------------- + * target list operations + * ---------------- + */ + +extern TargetEntry *get_tle_by_resno(List *tlist, AttrNumber resno); + #endif /* PARSETREE_H */