diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-08-11 20:46:47 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-08-11 20:46:47 +0000 |
commit | 88381ade63de931c84f53dc873c986d40b8c8b61 (patch) | |
tree | 1ec3c77e29b1d320718b64b38db10f8a8f0e0cd3 /src/backend/parser/parse_target.c | |
parent | cae912d05bfb354d81427c6ae5354eab90869fe9 (diff) | |
download | postgresql-88381ade63de931c84f53dc873c986d40b8c8b61.tar.gz postgresql-88381ade63de931c84f53dc873c986d40b8c8b61.zip |
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().
Diffstat (limited to 'src/backend/parser/parse_target.c')
-rw-r--r-- | src/backend/parser/parse_target.c | 158 |
1 files changed, 77 insertions, 81 deletions
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 2f1233da7ca..a525e8795f0 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) - { - /* - * 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) + if (strcmp(strVal(llast(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; - - switch (numnames) + int numnames = length(fields); + + 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)); + rte = refnameRangeTblEntry(pstate, schemaname, relname, + &sublevels_up); + if (rte == NULL) + rte = addImplicitRTE(pstate, makeRangeVar(schemaname, + relname)); - p_target = nconc(p_target, - expandRelAttrs(pstate, rte)); + FastConc(&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: |