diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 1999-10-07 04:23:24 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 1999-10-07 04:23:24 +0000 |
commit | 3eb1c8227751aecede58e742a13b07127a7e2652 (patch) | |
tree | c2f606088b1536e385811667c7f032552b89afa6 /src/backend/parser/parse_relation.c | |
parent | 4040fcfa78065882aa16895906ff8398aaaf1c23 (diff) | |
download | postgresql-3eb1c8227751aecede58e742a13b07127a7e2652.tar.gz postgresql-3eb1c8227751aecede58e742a13b07127a7e2652.zip |
Fix planner and rewriter to follow SQL semantics for tables that are
mentioned in FROM but not elsewhere in the query: such tables should be
joined over anyway. Aside from being more standards-compliant, this allows
removal of some very ugly hacks for COUNT(*) processing. Also, allow
HAVING clause without aggregate functions, since SQL does. Clean up
CREATE RULE statement-list syntax the same way Bruce just fixed the
main stmtmulti production.
CAUTION: addition of a field to RangeTblEntry nodes breaks stored rules;
you will have to initdb if you have any rules.
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r-- | src/backend/parser/parse_relation.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index e664615e6df..fcbd6fedd2c 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.31 1999/09/29 18:16:04 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.32 1999/10/07 04:23:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -144,7 +144,7 @@ colnameRangeTableEntry(ParseState *pstate, char *colname) { RangeTblEntry *rte = lfirst(et); - /* only entries on outer(non-function?) scope */ + /* only consider RTEs mentioned in FROM or UPDATE/DELETE */ if (!rte->inFromCl && rte != pstate->p_target_rangetblentry) continue; @@ -178,45 +178,51 @@ addRangeTableEntry(ParseState *pstate, char *relname, char *refname, bool inh, - bool inFromCl) + bool inFromCl, + bool inJoinSet) { Relation relation; - RangeTblEntry *rte = makeNode(RangeTblEntry); + RangeTblEntry *rte; int sublevels_up; if (pstate != NULL) { - if (refnameRangeTablePosn(pstate, refname, &sublevels_up) != 0 && - (!inFromCl || sublevels_up == 0)) + int rt_index = refnameRangeTablePosn(pstate, refname, + &sublevels_up); + + if (rt_index != 0 && (!inFromCl || sublevels_up == 0)) { if (!strcmp(refname, "*CURRENT*") || !strcmp(refname, "*NEW*")) - { - int rt_index = refnameRangeTablePosn(pstate, refname, &sublevels_up); - return (RangeTblEntry *) nth(rt_index - 1, pstate->p_rtable); - } elog(ERROR, "Table name '%s' specified more than once", refname); } } + rte = makeNode(RangeTblEntry); + rte->relname = pstrdup(relname); rte->refname = pstrdup(refname); + /* Get the rel's OID. This access also ensures that we have an + * up-to-date relcache entry for the rel. We don't need to keep + * it open, however. + */ relation = heap_openr(relname, AccessShareLock); rte->relid = RelationGetRelid(relation); heap_close(relation, AccessShareLock); /* - * Flags - zero or more from inheritance,union,version or recursive - * (transitive closure) [we don't support them all -- ay 9/94 ] + * Flags: this RTE should be expanded to include descendant tables, + * this RTE is in the FROM clause, this RTE should be included in + * the planner's final join. */ rte->inh = inh; - - /* RelOID */ rte->inFromCl = inFromCl; + rte->inJoinSet = inJoinSet; + rte->skipAcl = false; /* always starts out false */ /* - * close the relation we're done with it for now. + * Add completed RTE to range table list. */ if (pstate != NULL) pstate->p_rtable = lappend(pstate->p_rtable, rte); @@ -240,7 +246,8 @@ expandAll(ParseState *pstate, char *relname, char *refname, int *this_resno) rte = refnameRangeTableEntry(pstate, refname); if (rte == NULL) { - rte = addRangeTableEntry(pstate, relname, refname, FALSE, FALSE); + rte = addRangeTableEntry(pstate, relname, refname, + FALSE, FALSE, TRUE); #ifdef WARN_FROM elog(NOTICE,"Adding missing FROM-clause entry%s for table %s", pstate->parentParseState != NULL ? " in subquery" : "", |