diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-22 02:56:37 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-03-22 02:56:37 +0000 |
commit | 108a0ec87d41393c362c5b8d8aa17d9a734e4f1a (patch) | |
tree | f437cf9d8bb1db8fdacf1c1022eac0f11e146069 /src | |
parent | 56c9b73c1d426c79a604df6d6f36293dd9f18754 (diff) | |
download | postgresql-108a0ec87d41393c362c5b8d8aa17d9a734e4f1a.tar.gz postgresql-108a0ec87d41393c362c5b8d8aa17d9a734e4f1a.zip |
A little further progress on schemas: push down RangeVars into
addRangeTableEntry calls. Remove relname field from RTEs, since
it will no longer be a useful unique identifier of relations;
we want to encourage people to rely on the relation OID instead.
Further work on dumping qual expressions in EXPLAIN, too.
Diffstat (limited to 'src')
33 files changed, 495 insertions, 311 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 629ffe7c2e9..9df788406a9 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.190 2002/03/21 16:00:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.191 2002/03/22 02:56:30 tgl Exp $ * * * INTERFACE ROUTINES @@ -45,6 +45,7 @@ #include "commands/comment.h" #include "commands/trigger.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "optimizer/clauses.h" #include "optimizer/planmain.h" #include "optimizer/prep.h" @@ -1612,7 +1613,11 @@ AddRelationRawConstraints(Relation rel, * sole rangetable entry. We need a ParseState for transformExpr. */ pstate = make_parsestate(NULL); - rte = addRangeTableEntry(pstate, relname, NULL, false, true); + rte = addRangeTableEntryForRelation(pstate, + RelationGetRelid(rel), + makeAlias(relname, NIL), + false, + true); addRTEtoQuery(pstate, rte, true, true); /* diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index 31df6cabd77..b9741e0f3a5 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.163 2002/03/21 23:27:20 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.164 2002/03/22 02:56:31 tgl Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -37,6 +37,7 @@ #include "executor/execdefs.h" #include "executor/executor.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "optimizer/clauses.h" #include "optimizer/planmain.h" #include "optimizer/prep.h" @@ -1262,8 +1263,11 @@ AlterTableAddConstraint(char *relationName, * expression we can pass to ExecQual */ pstate = make_parsestate(NULL); - rte = addRangeTableEntry(pstate, relationName, NULL, - false, true); + rte = addRangeTableEntryForRelation(pstate, + myrelid, + makeAlias(relationName, NIL), + false, + true); addRTEtoQuery(pstate, rte, true, true); /* diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index 91f5d14a37a..0f9bf525ef3 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.90 2002/03/21 23:27:20 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.91 2002/03/22 02:56:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -46,9 +46,11 @@ static List *MergeDomainAttributes(List *schema); /* ---------------------------------------------------------------- * DefineRelation * Creates a new relation. + * + * If successful, returns the OID of the new relation. * ---------------------------------------------------------------- */ -void +Oid DefineRelation(CreateStmt *stmt, char relkind) { char *relname = palloc(NAMEDATALEN); @@ -165,7 +167,7 @@ DefineRelation(CreateStmt *stmt, char relkind) * see the new rel anyway until we commit), but it keeps the lock * manager from complaining about deadlock risks. */ - rel = heap_openr(relname, AccessExclusiveLock); + rel = heap_open(relationId, AccessExclusiveLock); /* * Now add any newly specified column default values and CHECK @@ -210,11 +212,13 @@ DefineRelation(CreateStmt *stmt, char relkind) * visible to anyone else anyway, until commit). */ heap_close(rel, NoLock); + + return relationId; } /* * RemoveRelation - * Deletes a new relation. + * Deletes a relation. * * Exceptions: * BadArg if name is invalid. diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 95263a5da08..19df98531c5 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.72 2002/03/21 16:00:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.73 2002/03/22 02:56:31 tgl Exp $ * */ @@ -17,10 +17,12 @@ #include "nodes/print.h" #include "optimizer/clauses.h" #include "optimizer/planner.h" +#include "optimizer/var.h" #include "parser/parsetree.h" #include "rewrite/rewriteHandler.h" #include "tcop/pquery.h" #include "utils/builtins.h" +#include "utils/lsyscache.h" #include "utils/relcache.h" @@ -34,9 +36,12 @@ typedef struct ExplainState } ExplainState; static StringInfo Explain_PlanToString(Plan *plan, ExplainState *es); -static void ExplainOneQuery(Query *query, bool verbose, bool analyze, CommandDest dest); +static void ExplainOneQuery(Query *query, bool verbose, bool analyze, + CommandDest dest); +static void explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan, + int indent, ExplainState *es); static void show_scan_qual(List *qual, bool is_or_qual, const char *qlabel, - int scanrelid, + int scanrelid, Plan *outer_plan, StringInfo str, int indent, ExplainState *es); static void show_upper_qual(List *qual, const char *qlabel, const char *outer_name, int outer_varno, Plan *outer_plan, @@ -188,10 +193,15 @@ ExplainOneQuery(Query *query, bool verbose, bool analyze, CommandDest dest) /* * explain_outNode - - * converts a Node into ascii string and append it to 'str' + * converts a Plan node into ascii string and appends it to 'str' + * + * outer_plan, if not null, references another plan node that is the outer + * side of a join with the current node. This is only interesting for + * deciphering runtime keys of an inner indexscan. */ static void -explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) +explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan, + int indent, ExplainState *es) { List *l; Relation relation; @@ -304,15 +314,19 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) { RangeTblEntry *rte = rt_fetch(((Scan *) plan)->scanrelid, es->rtable); + char *relname; /* Assume it's on a real relation */ - Assert(rte->relname); + Assert(rte->relid); + + /* We only show the rel name, not schema name */ + relname = get_rel_name(rte->relid); appendStringInfo(str, " on %s", - stringStringInfo(rte->relname)); - if (strcmp(rte->eref->aliasname, rte->relname) != 0) + stringStringInfo(relname)); + if (strcmp(rte->eref->aliasname, relname) != 0) appendStringInfo(str, " %s", - stringStringInfo(rte->eref->aliasname)); + stringStringInfo(rte->eref->aliasname)); } break; case T_SubqueryScan: @@ -352,77 +366,93 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) { case T_IndexScan: show_scan_qual(((IndexScan *) plan)->indxqualorig, true, - "indxqual", + "Index Filter", ((Scan *) plan)->scanrelid, + outer_plan, str, indent, es); - show_scan_qual(plan->qual, false, "qual", + show_scan_qual(plan->qual, false, + "Filter", ((Scan *) plan)->scanrelid, + outer_plan, str, indent, es); break; case T_SeqScan: case T_TidScan: - show_scan_qual(plan->qual, false, "qual", + show_scan_qual(plan->qual, false, + "Filter", ((Scan *) plan)->scanrelid, + outer_plan, str, indent, es); break; case T_NestLoop: - show_upper_qual(((NestLoop *) plan)->join.joinqual, "joinqual", + show_upper_qual(((NestLoop *) plan)->join.joinqual, + "Join Cond", "outer", OUTER, outerPlan(plan), "inner", INNER, innerPlan(plan), str, indent, es); - show_upper_qual(plan->qual, "qual", + show_upper_qual(plan->qual, + "Filter", "outer", OUTER, outerPlan(plan), "inner", INNER, innerPlan(plan), str, indent, es); break; case T_MergeJoin: - show_upper_qual(((MergeJoin *) plan)->mergeclauses, "merge", + show_upper_qual(((MergeJoin *) plan)->mergeclauses, + "Merge Cond", "outer", OUTER, outerPlan(plan), "inner", INNER, innerPlan(plan), str, indent, es); - show_upper_qual(((MergeJoin *) plan)->join.joinqual, "joinqual", + show_upper_qual(((MergeJoin *) plan)->join.joinqual, + "Join Cond", "outer", OUTER, outerPlan(plan), "inner", INNER, innerPlan(plan), str, indent, es); - show_upper_qual(plan->qual, "qual", + show_upper_qual(plan->qual, + "Filter", "outer", OUTER, outerPlan(plan), "inner", INNER, innerPlan(plan), str, indent, es); break; case T_HashJoin: - show_upper_qual(((HashJoin *) plan)->hashclauses, "hash", + show_upper_qual(((HashJoin *) plan)->hashclauses, + "Hash Cond", "outer", OUTER, outerPlan(plan), "inner", INNER, innerPlan(plan), str, indent, es); - show_upper_qual(((HashJoin *) plan)->join.joinqual, "joinqual", + show_upper_qual(((HashJoin *) plan)->join.joinqual, + "Join Cond", "outer", OUTER, outerPlan(plan), "inner", INNER, innerPlan(plan), str, indent, es); - show_upper_qual(plan->qual, "qual", + show_upper_qual(plan->qual, + "Filter", "outer", OUTER, outerPlan(plan), "inner", INNER, innerPlan(plan), str, indent, es); break; case T_SubqueryScan: - show_upper_qual(plan->qual, "qual", + show_upper_qual(plan->qual, + "Filter", "subplan", 1, ((SubqueryScan *) plan)->subplan, "", 0, NULL, str, indent, es); break; case T_Agg: case T_Group: - show_upper_qual(plan->qual, "qual", + show_upper_qual(plan->qual, + "Filter", "subplan", 0, outerPlan(plan), "", 0, NULL, str, indent, es); break; case T_Result: show_upper_qual((List *) ((Result *) plan)->resconstantqual, - "constqual", + "One-Time Filter", "subplan", OUTER, outerPlan(plan), "", 0, NULL, str, indent, es); - show_upper_qual(plan->qual, "qual", + show_upper_qual(plan->qual, + "Filter", "subplan", OUTER, outerPlan(plan), "", 0, NULL, str, indent, es); @@ -446,7 +476,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) for (i = 0; i < indent; i++) appendStringInfo(str, " "); appendStringInfo(str, " -> "); - explain_outNode(str, ((SubPlan *) lfirst(lst))->plan, + explain_outNode(str, ((SubPlan *) lfirst(lst))->plan, NULL, indent + 4, es); } es->rtable = saved_rtable; @@ -458,7 +488,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) for (i = 0; i < indent; i++) appendStringInfo(str, " "); appendStringInfo(str, " -> "); - explain_outNode(str, outerPlan(plan), indent + 3, es); + explain_outNode(str, outerPlan(plan), NULL, indent + 3, es); } /* righttree */ @@ -467,7 +497,8 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) for (i = 0; i < indent; i++) appendStringInfo(str, " "); appendStringInfo(str, " -> "); - explain_outNode(str, innerPlan(plan), indent + 3, es); + explain_outNode(str, innerPlan(plan), outerPlan(plan), + indent + 3, es); } if (IsA(plan, Append)) @@ -483,7 +514,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) appendStringInfo(str, " "); appendStringInfo(str, " -> "); - explain_outNode(str, subnode, indent + 3, es); + explain_outNode(str, subnode, NULL, indent + 3, es); } } @@ -502,7 +533,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) appendStringInfo(str, " "); appendStringInfo(str, " -> "); - explain_outNode(str, subnode, indent + 3, es); + explain_outNode(str, subnode, NULL, indent + 3, es); es->rtable = saved_rtable; } @@ -522,7 +553,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) for (i = 0; i < indent; i++) appendStringInfo(str, " "); appendStringInfo(str, " -> "); - explain_outNode(str, ((SubPlan *) lfirst(lst))->plan, + explain_outNode(str, ((SubPlan *) lfirst(lst))->plan, NULL, indent + 4, es); } es->rtable = saved_rtable; @@ -535,7 +566,7 @@ Explain_PlanToString(Plan *plan, ExplainState *es) StringInfo str = makeStringInfo(); if (plan != NULL) - explain_outNode(str, plan, 0, es); + explain_outNode(str, plan, NULL, 0, es); return str; } @@ -544,10 +575,12 @@ Explain_PlanToString(Plan *plan, ExplainState *es) */ static void show_scan_qual(List *qual, bool is_or_qual, const char *qlabel, - int scanrelid, + int scanrelid, Plan *outer_plan, StringInfo str, int indent, ExplainState *es) { RangeTblEntry *rte; + Node *scancontext; + Node *outercontext; List *context; Node *node; char *exprstr; @@ -562,23 +595,43 @@ show_scan_qual(List *qual, bool is_or_qual, const char *qlabel, return; } + /* Fix qual --- indexqual requires different processing */ + if (is_or_qual) + node = make_ors_ands_explicit(qual); + else + node = (Node *) make_ands_explicit(qual); + /* Generate deparse context */ Assert(scanrelid > 0 && scanrelid <= length(es->rtable)); rte = rt_fetch(scanrelid, es->rtable); /* Assume it's on a real relation */ - Assert(rte->relname); - - context = deparse_context_for(rte->relname, rte->relid); - - /* Fix qual --- indexqual requires different processing */ - if (is_or_qual) - node = make_ors_ands_explicit(qual); + Assert(rte->relid); + scancontext = deparse_context_for_relation(rte->eref->aliasname, + rte->relid); + + /* + * If we have an outer plan that is referenced by the qual, add it to + * the deparse context. If not, don't (so that we don't force prefixes + * unnecessarily). + */ + if (outer_plan) + { + if (intMember(OUTER, pull_varnos(node))) + outercontext = deparse_context_for_subplan("outer", + outer_plan->targetlist, + es->rtable); + else + outercontext = NULL; + } else - node = (Node *) make_ands_explicit(qual); + outercontext = NULL; + + context = deparse_context_for_plan(scanrelid, scancontext, + OUTER, outercontext); /* Deparse the expression */ - exprstr = deparse_expression(node, context, false); + exprstr = deparse_expression(node, context, (outercontext != NULL)); /* And add to str */ for (i = 0; i < indent; i++) diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 5bcf4f82327..d0b1f7d4d58 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.73 2002/03/21 23:27:21 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.74 2002/03/22 02:56:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -87,6 +87,7 @@ DefineSequence(CreateSeqStmt *seq) CreateStmt *stmt = makeNode(CreateStmt); ColumnDef *coldef; TypeName *typnam; + Oid seqoid; Relation rel; Buffer buf; PageHeader page; @@ -175,9 +176,9 @@ DefineSequence(CreateSeqStmt *seq) stmt->constraints = NIL; stmt->hasoids = false; - DefineRelation(stmt, RELKIND_SEQUENCE); + seqoid = DefineRelation(stmt, RELKIND_SEQUENCE); - rel = heap_openr(seq->sequence->relname, AccessExclusiveLock); + rel = heap_open(seqoid, AccessExclusiveLock); tupDesc = RelationGetDescr(rel); /* Initialize first page of relation with special magic number */ diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 74a3ac2bcaa..3b4bf7da13f 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: view.c,v 1.59 2002/03/21 16:00:36 tgl Exp $ + * $Id: view.c,v 1.60 2002/03/22 02:56:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -37,7 +37,7 @@ * the xact... *--------------------------------------------------------------------- */ -static void +static Oid DefineVirtualRelation(char *relname, List *tlist) { CreateStmt *createStmt = makeNode(CreateStmt); @@ -96,7 +96,7 @@ DefineVirtualRelation(char *relname, List *tlist) /* * finally create the relation... */ - DefineRelation(createStmt, RELKIND_VIEW); + return DefineRelation(createStmt, RELKIND_VIEW); } static RuleStmt * @@ -176,7 +176,7 @@ DefineViewRules(char *viewName, Query *viewParse) *--------------------------------------------------------------- */ static Query * -UpdateRangeTableOfViewParse(char *viewName, Query *viewParse) +UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse) { List *new_rt; RangeTblEntry *rt_entry1, @@ -196,12 +196,12 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse) * Create the 2 new range table entries and form the new range * table... OLD first, then NEW.... */ - rt_entry1 = addRangeTableEntry(NULL, viewName, - makeAlias("*OLD*", NIL), - false, false); - rt_entry2 = addRangeTableEntry(NULL, viewName, - makeAlias("*NEW*", NIL), - false, false); + rt_entry1 = addRangeTableEntryForRelation(NULL, viewOid, + makeAlias("*OLD*", NIL), + false, false); + rt_entry2 = addRangeTableEntryForRelation(NULL, viewOid, + makeAlias("*NEW*", NIL), + false, false); /* Must override addRangeTableEntry's default access-check flags */ rt_entry1->checkForRead = false; rt_entry2->checkForRead = false; @@ -233,11 +233,14 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse) void DefineView(char *viewName, Query *viewParse) { + Oid viewOid; + /* - * Create the "view" relation NOTE: if it already exists, the xact - * will be aborted. + * Create the view relation + * + * NOTE: if it already exists, the xact will be aborted. */ - DefineVirtualRelation(viewName, viewParse->targetList); + viewOid = DefineVirtualRelation(viewName, viewParse->targetList); /* * The relation we have just created is not visible to any other @@ -250,7 +253,7 @@ DefineView(char *viewName, Query *viewParse) * The range table of 'viewParse' does not contain entries for the * "OLD" and "NEW" relations. So... add them! */ - viewParse = UpdateRangeTableOfViewParse(viewName, viewParse); + viewParse = UpdateRangeTableOfViewParse(viewOid, viewParse); /* * Now create the rules associated with the view. diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index fb68866c53e..2c1e5b675f9 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.172 2002/03/21 16:00:39 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.173 2002/03/22 02:56:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1476,8 +1476,6 @@ _copyRangeTblEntry(RangeTblEntry *from) RangeTblEntry *newnode = makeNode(RangeTblEntry); newnode->rtekind = from->rtekind; - if (from->relname) - newnode->relname = pstrdup(from->relname); newnode->relid = from->relid; Node_Copy(from, newnode, subquery); newnode->jointype = from->jointype; @@ -2004,19 +2002,6 @@ _copyCreateStmt(CreateStmt *from) return newnode; } -static VersionStmt * -_copyVersionStmt(VersionStmt *from) -{ - VersionStmt *newnode = makeNode(VersionStmt); - - newnode->relname = pstrdup(from->relname); - newnode->direction = from->direction; - newnode->fromRelname = pstrdup(from->fromRelname); - newnode->date = pstrdup(from->date); - - return newnode; -} - static DefineStmt * _copyDefineStmt(DefineStmt *from) { @@ -2847,9 +2832,6 @@ copyObject(void *from) case T_CreateStmt: retval = _copyCreateStmt(from); break; - case T_VersionStmt: - retval = _copyVersionStmt(from); - break; case T_DefineStmt: retval = _copyDefineStmt(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 9788fd2f526..6adc87c4040 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.120 2002/03/21 16:00:39 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.121 2002/03/22 02:56:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -832,21 +832,6 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b) } static bool -_equalVersionStmt(VersionStmt *a, VersionStmt *b) -{ - if (!equalstr(a->relname, b->relname)) - return false; - if (a->direction != b->direction) - return false; - if (!equalstr(a->fromRelname, b->fromRelname)) - return false; - if (!equalstr(a->date, b->date)) - return false; - - return true; -} - -static bool _equalDefineStmt(DefineStmt *a, DefineStmt *b) { if (a->defType != b->defType) @@ -1679,8 +1664,6 @@ _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b) { if (a->rtekind != b->rtekind) return false; - if (!equalstr(a->relname, b->relname)) - return false; if (a->relid != b->relid) return false; if (!equal(a->subquery, b->subquery)) @@ -2004,9 +1987,6 @@ equal(void *a, void *b) case T_CreateStmt: retval = _equalCreateStmt(a, b); break; - case T_VersionStmt: - retval = _equalVersionStmt(a, b); - break; case T_DefineStmt: retval = _equalDefineStmt(a, b); break; diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index d8bf80a52ef..649fb38c111 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.28 2002/03/21 16:00:40 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.29 2002/03/22 02:56:32 tgl Exp $ */ #include "postgres.h" @@ -190,3 +190,22 @@ makeRelabelType(Node *arg, Oid rtype, int32 rtypmod) return r; } + +/* + * makeRangeVar - + * creates a RangeVar node (rather oversimplified case) + */ +RangeVar * +makeRangeVar(char *schemaname, char *relname) +{ + RangeVar *r = makeNode(RangeVar); + + r->catalogname = NULL; + r->schemaname = schemaname; + r->relname = relname; + r->inhOpt = INH_DEFAULT; + r->istemp = false; + r->alias = NULL; + + return r; +} diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index aff46e6ba33..195db0165db 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.150 2002/03/21 16:00:40 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.151 2002/03/22 02:56:32 tgl Exp $ * * NOTES * Every (plan) node in POSTGRES has an associated "out" routine which @@ -968,25 +968,38 @@ _outAlias(StringInfo str, Alias *node) static void _outRangeTblEntry(StringInfo str, RangeTblEntry *node) { - appendStringInfo(str, " RTE :rtekind %d :relname ", - (int) node->rtekind); - _outToken(str, node->relname); - appendStringInfo(str, " :relid %u :subquery ", - node->relid); - _outNode(str, node->subquery); - appendStringInfo(str, " :jointype %d :joincoltypes ", - (int) node->jointype); - _outOidList(str, node->joincoltypes); - appendStringInfo(str, " :joincoltypmods "); - _outIntList(str, node->joincoltypmods); - appendStringInfo(str, " :joinleftcols "); - _outIntList(str, node->joinleftcols); - appendStringInfo(str, " :joinrightcols "); - _outIntList(str, node->joinrightcols); - appendStringInfo(str, " :alias "); + /* put alias + eref first to make dump more legible */ + appendStringInfo(str, " RTE :alias "); _outNode(str, node->alias); appendStringInfo(str, " :eref "); _outNode(str, node->eref); + appendStringInfo(str, " :rtekind %d ", + (int) node->rtekind); + switch (node->rtekind) + { + case RTE_RELATION: + case RTE_SPECIAL: + appendStringInfo(str, ":relid %u ", node->relid); + break; + case RTE_SUBQUERY: + appendStringInfo(str, ":subquery "); + _outNode(str, node->subquery); + break; + case RTE_JOIN: + appendStringInfo(str, ":jointype %d :joincoltypes ", + (int) node->jointype); + _outOidList(str, node->joincoltypes); + appendStringInfo(str, " :joincoltypmods "); + _outIntList(str, node->joincoltypmods); + appendStringInfo(str, " :joinleftcols "); + _outIntList(str, node->joinleftcols); + appendStringInfo(str, " :joinrightcols "); + _outIntList(str, node->joinrightcols); + break; + default: + elog(ERROR, "bogus rte kind %d", (int) node->rtekind); + break; + } appendStringInfo(str, " :inh %s :inFromCl %s :checkForRead %s" " :checkForWrite %s :checkAsUser %u", booltostr(node->inh), diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c index ebc5d536e7d..7254d46c178 100644 --- a/src/backend/nodes/print.c +++ b/src/backend/nodes/print.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.52 2002/03/21 16:00:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.53 2002/03/22 02:56:32 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -146,17 +146,17 @@ print_rt(List *rtable) List *l; int i = 1; - printf("resno\trelname(refname)\trelid\tinFromCl\n"); - printf("-----\t----------------\t-----\t--------\n"); + printf("resno\trefname \trelid\tinFromCl\n"); + printf("-----\t---------\t-----\t--------\n"); foreach(l, rtable) { RangeTblEntry *rte = lfirst(l); - if (rte->relname) - printf("%d\t%s (%s)\t%u", - i, rte->relname, rte->eref->aliasname, rte->relid); + if (rte->rtekind == RTE_RELATION) + printf("%d\t%s\t%u", + i, rte->eref->aliasname, rte->relid); else - printf("%d\t[subquery] (%s)\t", + printf("%d\t%s\t[subquery]", i, rte->eref->aliasname); printf("\t%s\t%s\n", (rte->inh ? "inh" : ""), @@ -406,19 +406,20 @@ print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label) printf("%s%s :c=%.2f..%.2f :r=%.0f :w=%d ", label, plannode_type(p), p->startup_cost, p->total_cost, p->plan_rows, p->plan_width); - if (IsA(p, Scan) ||IsA(p, SeqScan)) + if (IsA(p, Scan) || + IsA(p, SeqScan)) { RangeTblEntry *rte; rte = rt_fetch(((Scan *) p)->scanrelid, parsetree->rtable); - StrNCpy(extraInfo, rte->relname, NAMEDATALEN); + StrNCpy(extraInfo, rte->eref->aliasname, NAMEDATALEN); } else if (IsA(p, IndexScan)) { RangeTblEntry *rte; rte = rt_fetch(((IndexScan *) p)->scan.scanrelid, parsetree->rtable); - StrNCpy(extraInfo, rte->relname, NAMEDATALEN); + StrNCpy(extraInfo, rte->eref->aliasname, NAMEDATALEN); } else extraInfo[0] = '\0'; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 66dd317f394..150e98d6e49 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.117 2002/03/21 16:00:42 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.118 2002/03/22 02:56:32 tgl Exp $ * * NOTES * Most of the read functions for plan nodes are tested. (In fact, they @@ -1498,43 +1498,53 @@ _readRangeTblEntry(void) local_node = makeNode(RangeTblEntry); - token = pg_strtok(&length); /* eat :rtekind */ - token = pg_strtok(&length); /* get :rtekind */ - local_node->rtekind = (RTEKind) atoi(token); - - token = pg_strtok(&length); /* eat :relname */ - token = pg_strtok(&length); /* get :relname */ - local_node->relname = nullable_string(token, length); - - token = pg_strtok(&length); /* eat :relid */ - token = pg_strtok(&length); /* get :relid */ - local_node->relid = atooid(token); - - token = pg_strtok(&length); /* eat :subquery */ - local_node->subquery = nodeRead(true); /* now read it */ - - token = pg_strtok(&length); /* eat :jointype */ - token = pg_strtok(&length); /* get jointype */ - local_node->jointype = (JoinType) atoi(token); - - token = pg_strtok(&length); /* eat :joincoltypes */ - local_node->joincoltypes = toOidList(nodeRead(true)); - - token = pg_strtok(&length); /* eat :joincoltypmods */ - local_node->joincoltypmods = toIntList(nodeRead(true)); - - token = pg_strtok(&length); /* eat :joinleftcols */ - local_node->joinleftcols = toIntList(nodeRead(true)); - - token = pg_strtok(&length); /* eat :joinrightcols */ - local_node->joinrightcols = toIntList(nodeRead(true)); - token = pg_strtok(&length); /* eat :alias */ local_node->alias = nodeRead(true); /* now read it */ token = pg_strtok(&length); /* eat :eref */ local_node->eref = nodeRead(true); /* now read it */ + token = pg_strtok(&length); /* eat :rtekind */ + token = pg_strtok(&length); /* get rtekind */ + local_node->rtekind = (RTEKind) atoi(token); + + switch (local_node->rtekind) + { + case RTE_RELATION: + case RTE_SPECIAL: + token = pg_strtok(&length); /* eat :relid */ + token = pg_strtok(&length); /* get :relid */ + local_node->relid = atooid(token); + break; + + case RTE_SUBQUERY: + token = pg_strtok(&length); /* eat :subquery */ + local_node->subquery = nodeRead(true); /* now read it */ + break; + + case RTE_JOIN: + token = pg_strtok(&length); /* eat :jointype */ + token = pg_strtok(&length); /* get jointype */ + local_node->jointype = (JoinType) atoi(token); + + token = pg_strtok(&length); /* eat :joincoltypes */ + local_node->joincoltypes = toOidList(nodeRead(true)); + + token = pg_strtok(&length); /* eat :joincoltypmods */ + local_node->joincoltypmods = toIntList(nodeRead(true)); + + token = pg_strtok(&length); /* eat :joinleftcols */ + local_node->joinleftcols = toIntList(nodeRead(true)); + + token = pg_strtok(&length); /* eat :joinrightcols */ + local_node->joinrightcols = toIntList(nodeRead(true)); + break; + + default: + elog(ERROR, "bogus rte kind %d", (int) local_node->rtekind); + break; + } + token = pg_strtok(&length); /* eat :inh */ token = pg_strtok(&length); /* get :inh */ local_node->inh = strtobool(token); diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index b2f18780fcc..83d454c4d63 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.72 2002/03/12 00:51:49 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.73 2002/03/22 02:56:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -721,7 +721,6 @@ expand_inherted_rtentry(Query *parse, Index rti, bool dup_parent) * this point. */ childrte = copyObject(rte); - childrte->relname = get_rel_name(childOID); childrte->relid = childOID; parse->rtable = lappend(parse->rtable, childrte); childRTindex = length(parse->rtable); diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 109062c529f..adefcd040cf 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.221 2002/03/21 16:00:48 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.222 2002/03/22 02:56:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -347,7 +347,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt) qry->commandType = CMD_DELETE; /* set up range table with just the result rel */ - qry->resultRelation = setTargetTable(pstate, stmt->relation->relname, + qry->resultRelation = setTargetTable(pstate, stmt->relation, interpretInhOption(stmt->relation->inhOpt), true); @@ -415,7 +415,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt, * table is also mentioned in the SELECT part. Note that the target * table is not added to the joinlist or namespace. */ - qry->resultRelation = setTargetTable(pstate, stmt->relation->relname, + qry->resultRelation = setTargetTable(pstate, stmt->relation, false, false); /* @@ -1684,7 +1684,7 @@ transformIndexStmt(ParseState *pstate, IndexStmt *stmt) * easily support predicates on indexes created implicitly by * CREATE TABLE. Fortunately, that's not necessary. */ - rte = addRangeTableEntry(pstate, stmt->relation->relname, NULL, false, true); + rte = addRangeTableEntry(pstate, stmt->relation, NULL, false, true); /* no to join list, yes to namespace */ addRTEtoQuery(pstate, rte, false, true); @@ -1733,10 +1733,10 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt, * rule qualification. */ Assert(pstate->p_rtable == NIL); - oldrte = addRangeTableEntry(pstate, stmt->relation->relname, + oldrte = addRangeTableEntry(pstate, stmt->relation, makeAlias("*OLD*", NIL), false, true); - newrte = addRangeTableEntry(pstate, stmt->relation->relname, + newrte = addRangeTableEntry(pstate, stmt->relation, makeAlias("*NEW*", NIL), false, true); /* Must override addRangeTableEntry's default access-check flags */ @@ -1824,10 +1824,10 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt, * or they won't be accessible at all. We decide later * whether to put them in the joinlist. */ - oldrte = addRangeTableEntry(sub_pstate, stmt->relation->relname, + oldrte = addRangeTableEntry(sub_pstate, stmt->relation, makeAlias("*OLD*", NIL), false, false); - newrte = addRangeTableEntry(sub_pstate, stmt->relation->relname, + newrte = addRangeTableEntry(sub_pstate, stmt->relation, makeAlias("*NEW*", NIL), false, false); oldrte->checkForRead = false; @@ -2474,7 +2474,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) qry->commandType = CMD_UPDATE; pstate->p_is_update = true; - qry->resultRelation = setTargetTable(pstate, stmt->relation->relname, + qry->resultRelation = setTargetTable(pstate, stmt->relation, interpretInhOption(stmt->relation->inhOpt), true); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index f94eaea5098..fa6bf35fb97 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.295 2002/03/21 16:00:50 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.296 2002/03/22 02:56:33 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -122,7 +122,6 @@ static void doNegateFloat(Value *v); ResTarget *target; PrivTarget *privtarget; - VersionStmt *vstmt; DefineStmt *dstmt; RuleStmt *rstmt; InsertStmt *istmt; diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 6e8868f8ea6..c2f578f4e6d 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.85 2002/03/21 16:00:59 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.86 2002/03/22 02:56:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -116,7 +116,7 @@ transformFromClause(ParseState *pstate, List *frmList) * Returns the rangetable index of the target relation. */ int -setTargetTable(ParseState *pstate, char *relname, +setTargetTable(ParseState *pstate, RangeVar *relation, bool inh, bool alsoSource) { RangeTblEntry *rte; @@ -133,12 +133,12 @@ setTargetTable(ParseState *pstate, char *relname, * analyze.c will eventually do the corresponding heap_close(), but *not* * release the lock. */ - pstate->p_target_relation = heap_openr(relname, RowExclusiveLock); + pstate->p_target_relation = heap_openr(relation->relname, RowExclusiveLock); /* * Now build an RTE. */ - rte = addRangeTableEntry(pstate, relname, NULL, inh, false); + rte = addRangeTableEntry(pstate, relation, NULL, inh, false); pstate->p_target_rangetblentry = rte; /* assume new rte is at end */ @@ -364,7 +364,6 @@ transformJoinOnClause(ParseState *pstate, JoinExpr *j, static RangeTblRef * transformTableEntry(ParseState *pstate, RangeVar *r) { - char *relname = r->relname; RangeTblEntry *rte; RangeTblRef *rtr; @@ -375,7 +374,7 @@ transformTableEntry(ParseState *pstate, RangeVar *r) * automatically generate the range variable if not specified. However * there are times we need to know whether the entries are legitimate. */ - rte = addRangeTableEntry(pstate, relname, r->alias, + rte = addRangeTableEntry(pstate, r, r->alias, interpretInhOption(r->inhOpt), true); /* diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index ee1bf6c0578..f02ee04b696 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.119 2002/03/21 16:01:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.120 2002/03/22 02:56:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -252,7 +252,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, &sublevels_up); if (rte == NULL) - rte = addImplicitRTE(pstate, refname); + rte = addImplicitRTE(pstate, (RangeVar *) arg); vnum = RTERangeTablePosn(pstate, rte, &sublevels_up); @@ -281,7 +281,10 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, } } - toid = typenameTypeId(rte->relname); + toid = get_rel_type_id(rte->relid); + if (!OidIsValid(toid)) + elog(ERROR, "Cannot find type OID for relation %u", + rte->relid); /* replace RangeVar in the arg list */ lfirst(i) = makeVar(vnum, diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 5cf868a4d12..3701539af58 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.64 2002/03/21 16:01:09 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.65 2002/03/22 02:56:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,9 +36,9 @@ static Node *scanNameSpaceForRefname(ParseState *pstate, Node *nsnode, char *refname); static Node *scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname); -static bool isForUpdate(ParseState *pstate, char *relname); +static bool isForUpdate(ParseState *pstate, char *refname); static int specialAttNum(char *a); -static void warnAutoRange(ParseState *pstate, char *refname); +static void warnAutoRange(ParseState *pstate, RangeVar *relation); /* @@ -402,7 +402,7 @@ qualifiedNameToVar(ParseState *pstate, char *refname, char *colname, { if (!implicitRTEOK) return NULL; - rte = addImplicitRTE(pstate, refname); + rte = addImplicitRTE(pstate, makeRangeVar(NULL, refname)); } return scanRTEForColumn(pstate, rte, colname); @@ -419,13 +419,13 @@ qualifiedNameToVar(ParseState *pstate, char *refname, char *colname, */ RangeTblEntry * addRangeTableEntry(ParseState *pstate, - char *relname, + RangeVar *relation, Alias *alias, bool inh, bool inFromCl) { RangeTblEntry *rte = makeNode(RangeTblEntry); - char *refname = alias ? alias->aliasname : relname; + char *refname = alias ? alias->aliasname : relation->relname; LOCKMODE lockmode; Relation rel; Alias *eref; @@ -434,7 +434,6 @@ addRangeTableEntry(ParseState *pstate, int varattno; rte->rtekind = RTE_RELATION; - rte->relname = relname; rte->alias = alias; /* @@ -443,8 +442,8 @@ addRangeTableEntry(ParseState *pstate, * first access to a rel in a statement, be careful to get the right * access level depending on whether we're doing SELECT FOR UPDATE. */ - lockmode = isForUpdate(pstate, relname) ? RowShareLock : AccessShareLock; - rel = heap_openr(relname, lockmode); + lockmode = isForUpdate(pstate, refname) ? RowShareLock : AccessShareLock; + rel = heap_openr(relation->relname, lockmode); rte->relid = RelationGetRelid(rel); eref = alias ? (Alias *) copyObject(alias) : makeAlias(refname, NIL); @@ -457,7 +456,100 @@ addRangeTableEntry(ParseState *pstate, maxattrs = RelationGetNumberOfAttributes(rel); if (maxattrs < numaliases) elog(ERROR, "Table \"%s\" has %d columns available but %d columns specified", - refname, maxattrs, numaliases); + RelationGetRelationName(rel), maxattrs, numaliases); + + /* fill in any unspecified alias columns using actual column names */ + for (varattno = numaliases; varattno < maxattrs; varattno++) + { + char *attrname; + + attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname)); + eref->colnames = lappend(eref->colnames, makeString(attrname)); + } + rte->eref = eref; + + /* + * Drop the rel refcount, but keep the access lock till end of + * transaction so that the table can't be deleted or have its schema + * modified underneath us. + */ + heap_close(rel, NoLock); + + /*---------- + * Flags: + * - this RTE should be expanded to include descendant tables, + * - this RTE is in the FROM clause, + * - this RTE should be checked for read/write access rights. + * + * The initial default on access checks is always check-for-READ-access, + * which is the right thing for all except target tables. + *---------- + */ + rte->inh = inh; + rte->inFromCl = inFromCl; + rte->checkForRead = true; + rte->checkForWrite = false; + + rte->checkAsUser = InvalidOid; /* not set-uid by default, either */ + + /* + * Add completed RTE to pstate's range table list, but not to join + * list nor namespace --- caller must do that if appropriate. + */ + if (pstate != NULL) + pstate->p_rtable = lappend(pstate->p_rtable, rte); + + return rte; +} + +/* + * Add an entry for a relation to the pstate's range table (p_rtable). + * + * This is just like addRangeTableEntry() except that it makes an RTE + * given a relation OID instead of a RangeVar reference. + * + * Note that an alias clause *must* be supplied. + */ +RangeTblEntry * +addRangeTableEntryForRelation(ParseState *pstate, + Oid relid, + Alias *alias, + bool inh, + bool inFromCl) +{ + RangeTblEntry *rte = makeNode(RangeTblEntry); + char *refname = alias->aliasname; + LOCKMODE lockmode; + Relation rel; + Alias *eref; + int maxattrs; + int numaliases; + int varattno; + + rte->rtekind = RTE_RELATION; + rte->alias = alias; + + /* + * Get the rel's relcache entry. This access ensures that we have an + * up-to-date relcache entry for the rel. Since this is typically the + * first access to a rel in a statement, be careful to get the right + * access level depending on whether we're doing SELECT FOR UPDATE. + */ + lockmode = isForUpdate(pstate, refname) ? RowShareLock : AccessShareLock; + rel = heap_open(relid, lockmode); + rte->relid = relid; + + eref = (Alias *) copyObject(alias); + numaliases = length(eref->colnames); + + /* + * Since the rel is open anyway, let's check that the number of column + * aliases is reasonable. - Thomas 2000-02-04 + */ + maxattrs = RelationGetNumberOfAttributes(rel); + if (maxattrs < numaliases) + elog(ERROR, "Table \"%s\" has %d columns available but %d columns specified", + RelationGetRelationName(rel), maxattrs, numaliases); /* fill in any unspecified alias columns using actual column names */ for (varattno = numaliases; varattno < maxattrs; varattno++) @@ -523,7 +615,6 @@ addRangeTableEntryForSubquery(ParseState *pstate, List *tlistitem; rte->rtekind = RTE_SUBQUERY; - rte->relname = NULL; rte->relid = InvalidOid; rte->subquery = subquery; rte->alias = alias; @@ -602,7 +693,6 @@ addRangeTableEntryForJoin(ParseState *pstate, int numaliases; rte->rtekind = RTE_JOIN; - rte->relname = NULL; rte->relid = InvalidOid; rte->subquery = NULL; rte->jointype = jointype; @@ -652,10 +742,10 @@ addRangeTableEntryForJoin(ParseState *pstate, } /* - * Has the specified relname been selected FOR UPDATE? + * Has the specified refname been selected FOR UPDATE? */ static bool -isForUpdate(ParseState *pstate, char *relname) +isForUpdate(ParseState *pstate, char *refname) { /* Outer loop to check parent query levels as well as this one */ while (pstate != NULL) @@ -676,7 +766,7 @@ isForUpdate(ParseState *pstate, char *relname) { char *rname = strVal(lfirst(l)); - if (strcmp(relname, rname) == 0) + if (strcmp(refname, rname) == 0) return true; } } @@ -713,13 +803,13 @@ addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, * a conflicting name. */ RangeTblEntry * -addImplicitRTE(ParseState *pstate, char *relname) +addImplicitRTE(ParseState *pstate, RangeVar *relation) { RangeTblEntry *rte; - rte = addRangeTableEntry(pstate, relname, NULL, false, false); + rte = addRangeTableEntry(pstate, relation, NULL, false, false); addRTEtoQuery(pstate, rte, true, true); - warnAutoRange(pstate, relname); + warnAutoRange(pstate, relation); return rte; } @@ -757,7 +847,7 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte, int maxattrs; int numaliases; - rel = heap_openr(rte->relname, AccessShareLock); + rel = heap_open(rte->relid, AccessShareLock); maxattrs = RelationGetNumberOfAttributes(rel); numaliases = length(rte->eref->colnames); @@ -979,7 +1069,7 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum, /* this shouldn't happen... */ if (!HeapTupleIsValid(tp)) elog(ERROR, "Relation %s does not have attribute %d", - rte->relname, attnum); + get_rel_name(rte->relid), attnum); att_tup = (Form_pg_attribute) GETSTRUCT(tp); *vartype = att_tup->atttypid; *vartypmod = att_tup->atttypmod; @@ -1116,7 +1206,7 @@ attnumTypeId(Relation rd, int attid) * but warn about a mixture of explicit and implicit RTEs. */ static void -warnAutoRange(ParseState *pstate, char *refname) +warnAutoRange(ParseState *pstate, RangeVar *relation) { bool foundInFromCl = false; List *temp; @@ -1134,5 +1224,5 @@ warnAutoRange(ParseState *pstate, char *refname) if (foundInFromCl) elog(NOTICE, "Adding missing FROM-clause entry%s for table \"%s\"", pstate->parentParseState != NULL ? " in subquery" : "", - refname); + relation->relname); } diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index a4b78165178..cc56cb6d183 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.78 2002/03/21 16:01:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.79 2002/03/22 02:56:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -159,7 +159,7 @@ transformTargetList(ParseState *pstate, List *targetlist) rte = refnameRangeTblEntry(pstate, relname, &sublevels_up); if (rte == NULL) - rte = addImplicitRTE(pstate, relname); + rte = addImplicitRTE(pstate, makeRangeVar(NULL, relname)); p_target = nconc(p_target, expandRelAttrs(pstate, rte)); diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index e118654e404..aebc7b94f86 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.99 2002/03/12 00:51:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.100 2002/03/22 02:56:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -290,7 +290,6 @@ ApplyRetrieveRule(Query *parsetree, rte = rt_fetch(rt_index, parsetree->rtable); rte->rtekind = RTE_SUBQUERY; - rte->relname = NULL; rte->relid = InvalidOid; rte->subquery = rule_action; rte->inh = false; /* must not be set for a subquery */ @@ -485,17 +484,7 @@ fireRIRrules(Query *parsetree) else lockmode = AccessShareLock; - rel = heap_openr(rte->relname, lockmode); - - /* - * Check to see if relation's OID matches the RTE. If not, the - * RTE actually refers to an older relation that had the same - * name. Eventually we might want to reparse the referencing rule, - * but for now all we can do is punt. - */ - if (RelationGetRelid(rel) != rte->relid) - elog(ERROR, "Relation \"%s\" with OID %u no longer exists", - rte->relname, rte->relid); + rel = heap_open(rte->relid, lockmode); /* * Collect the RIR rules that we must apply @@ -773,17 +762,7 @@ RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products) * release it until end of transaction. This protects the rewriter * and planner against schema changes mid-query. */ - rt_entry_relation = heap_openr(rt_entry->relname, RowExclusiveLock); - - /* - * Check to see if relation's OID matches the RTE. If not, the RTE - * actually refers to an older relation that had the same name. - * Eventually we might want to reparse the referencing rule, but for - * now all we can do is punt. - */ - if (RelationGetRelid(rt_entry_relation) != rt_entry->relid) - elog(ERROR, "Relation \"%s\" with OID %u no longer exists", - rt_entry->relname, rt_entry->relid); + rt_entry_relation = heap_open(rt_entry->relid, RowExclusiveLock); /* * Collect and apply the appropriate rules. diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 8443fe6591b..68358f4966d 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.258 2002/03/21 16:01:25 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.259 2002/03/22 02:56:35 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -1722,7 +1722,7 @@ PostgresMain(int argc, char *argv[], const char *username) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.258 $ $Date: 2002/03/21 16:01:25 $\n"); + puts("$Revision: 1.259 $ $Date: 2002/03/22 02:56:35 $\n"); } /* @@ -2291,10 +2291,6 @@ CreateCommandTag(Node *parsetree) tag = "DROP"; break; - case T_VersionStmt: - tag = "CREATE VERSION"; - break; - case T_CreatedbStmt: tag = "CREATE DATABASE"; break; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 1f0046887f4..af6b943e349 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.137 2002/03/21 23:27:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.138 2002/03/22 02:56:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -578,10 +578,6 @@ ProcessUtility(Node *parsetree, } break; - case T_VersionStmt: - elog(ERROR, "CREATE VERSION is not currently implemented"); - break; - case T_CreatedbStmt: { CreatedbStmt *stmt = (CreatedbStmt *) parsetree; diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 0e4472faffb..d8340234397 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * back to source text * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.94 2002/03/21 16:01:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.95 2002/03/22 02:56:35 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -642,13 +642,13 @@ deparse_expression(Node *expr, List *dpcontext, bool forceprefix) /* ---------- * deparse_context_for - Build deparse context for a single relation * - * Given the name and OID of a relation, build deparsing context for an - * expression referencing only that relation (as varno 1, varlevelsup 0). - * This is sufficient for many uses of deparse_expression. + * Given the reference name (alias) and OID of a relation, build deparsing + * context for an expression referencing only that relation (as varno 1, + * varlevelsup 0). This is sufficient for many uses of deparse_expression. * ---------- */ List * -deparse_context_for(char *relname, Oid relid) +deparse_context_for(const char *aliasname, Oid relid) { deparse_namespace *dpns; RangeTblEntry *rte; @@ -658,9 +658,8 @@ deparse_context_for(char *relname, Oid relid) /* Build a minimal RTE for the rel */ rte = makeNode(RangeTblEntry); rte->rtekind = RTE_RELATION; - rte->relname = relname; rte->relid = relid; - rte->eref = makeAlias(relname, NIL); + rte->eref = makeAlias(aliasname, NIL); rte->inh = false; rte->inFromCl = true; @@ -678,9 +677,9 @@ deparse_context_for(char *relname, Oid relid) * * We assume we are dealing with an upper-level plan node having either * one or two referenceable children (pass innercontext = NULL if only one). - * The passed-in Nodes should be made using deparse_context_for_subplan. - * The resulting context will work for deparsing quals, tlists, etc of the - * plan node. + * The passed-in Nodes should be made using deparse_context_for_subplan + * and/or deparse_context_for_relation. The resulting context will work + * for deparsing quals, tlists, etc of the plan node. */ List * deparse_context_for_plan(int outer_varno, Node *outercontext, @@ -701,6 +700,29 @@ deparse_context_for_plan(int outer_varno, Node *outercontext, } /* + * deparse_context_for_relation - Build deparse context for 1 relation + * + * Helper routine to build one of the inputs for deparse_context_for_plan. + * Pass the reference name (alias) and OID of a relation. + * + * The returned node is actually a RangeTblEntry, but we declare it as just + * Node to discourage callers from assuming anything. + */ +Node * +deparse_context_for_relation(const char *aliasname, Oid relid) +{ + RangeTblEntry *rte = makeNode(RangeTblEntry); + + rte->rtekind = RTE_RELATION; + rte->relid = relid; + rte->eref = makeAlias(aliasname, NIL); + rte->inh = false; + rte->inFromCl = true; + + return (Node *) rte; +} + +/* * deparse_context_for_subplan - Build deparse context for a plan node * * Helper routine to build one of the inputs for deparse_context_for_plan. @@ -753,9 +775,8 @@ deparse_context_for_subplan(const char *name, List *tlist, } rte->rtekind = RTE_SPECIAL; /* XXX */ - rte->relname = pstrdup(name); rte->relid = InvalidOid; - rte->eref = makeAlias(rte->relname, attrs); + rte->eref = makeAlias(name, attrs); rte->inh = false; rte->inFromCl = true; @@ -1325,7 +1346,7 @@ get_insert_query_def(Query *query, deparse_context *context) */ rte = rt_fetch(query->resultRelation, query->rtable); appendStringInfo(buf, "INSERT INTO %s", - quote_identifier(rte->relname)); + quote_identifier(rte->eref->aliasname)); /* Add the insert-column-names list */ sep = " ("; @@ -1383,7 +1404,7 @@ get_update_query_def(Query *query, deparse_context *context) rte = rt_fetch(query->resultRelation, query->rtable); appendStringInfo(buf, "UPDATE %s%s SET ", only_marker(rte), - quote_identifier(rte->relname)); + quote_identifier(rte->eref->aliasname)); /* Add the comma separated list of 'attname = value' */ sep = ""; @@ -1436,7 +1457,7 @@ get_delete_query_def(Query *query, deparse_context *context) rte = rt_fetch(query->resultRelation, query->rtable); appendStringInfo(buf, "DELETE FROM %s%s", only_marker(rte), - quote_identifier(rte->relname)); + quote_identifier(rte->eref->aliasname)); /* Add a WHERE clause if given */ if (query->jointree->quals != NULL) @@ -1460,7 +1481,8 @@ get_utility_query_def(Query *query, deparse_context *context) { NotifyStmt *stmt = (NotifyStmt *) query->utilityStmt; - appendStringInfo(buf, "NOTIFY %s", quote_identifier(stmt->relation->relname)); + appendStringInfo(buf, "NOTIFY %s", + quote_identifier(stmt->relation->relname)); } else elog(ERROR, "get_utility_query_def: unexpected statement type"); @@ -2321,20 +2343,23 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) int varno = ((RangeTblRef *) jtnode)->rtindex; RangeTblEntry *rte = rt_fetch(varno, query->rtable); - if (rte->relname) - { - /* Normal relation RTE */ - appendStringInfo(buf, "%s%s", - only_marker(rte), - quote_identifier(rte->relname)); - } - else + switch (rte->rtekind) { - /* Subquery RTE */ - Assert(rte->subquery != NULL); - appendStringInfoChar(buf, '('); - get_query_def(rte->subquery, buf, context->namespaces); - appendStringInfoChar(buf, ')'); + case RTE_RELATION: + /* Normal relation RTE */ + appendStringInfo(buf, "%s%s", + only_marker(rte), + quote_identifier(get_rel_name(rte->relid))); + break; + case RTE_SUBQUERY: + /* Subquery RTE */ + appendStringInfoChar(buf, '('); + get_query_def(rte->subquery, buf, context->namespaces); + appendStringInfoChar(buf, ')'); + break; + default: + elog(ERROR, "unexpected rte kind %d", (int) rte->rtekind); + break; } if (rte->alias != NULL) { diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index f4ebb6261c2..11577801118 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.64 2002/03/20 19:44:42 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.65 2002/03/22 02:56:35 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -690,6 +690,35 @@ get_rel_name(Oid relid) return NULL; } +/* + * get_rel_type_id + * + * Returns the pg_type OID associated with a given relation. + * + * Note: not all pg_class entries have associated pg_type OIDs; so be + * careful to check for InvalidOid result. + */ +Oid +get_rel_type_id(Oid relid) +{ + HeapTuple tp; + + tp = SearchSysCache(RELOID, + ObjectIdGetDatum(relid), + 0, 0, 0); + if (HeapTupleIsValid(tp)) + { + Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp); + Oid result; + + result = reltup->reltype; + ReleaseSysCache(tp); + return result; + } + else + return InvalidOid; +} + /* ---------- TYPE CACHE ---------- */ /* diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 5e0fa208cf8..e931772b07c 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.108 2002/03/21 16:01:39 tgl Exp $ + * $Id: catversion.h,v 1.109 2002/03/22 02:56:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200203211 +#define CATALOG_VERSION_NO 200203212 #endif diff --git a/src/include/commands/creatinh.h b/src/include/commands/creatinh.h index 4cc9801e85e..90f5df63d33 100644 --- a/src/include/commands/creatinh.h +++ b/src/include/commands/creatinh.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: creatinh.h,v 1.18 2002/03/19 02:58:20 momjian Exp $ + * $Id: creatinh.h,v 1.19 2002/03/22 02:56:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,7 +16,7 @@ #include "nodes/parsenodes.h" -extern void DefineRelation(CreateStmt *stmt, char relkind); +extern Oid DefineRelation(CreateStmt *stmt, char relkind); extern void RemoveRelation(const char *name); extern void TruncateRelation(const char *name); diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index 2de7c03cf6a..52c224b18f9 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: makefuncs.h,v 1.32 2002/03/21 16:01:43 tgl Exp $ + * $Id: makefuncs.h,v 1.33 2002/03/22 02:56:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -48,4 +48,6 @@ extern Alias *makeAlias(const char *aliasname, List *colnames); extern RelabelType *makeRelabelType(Node *arg, Oid rtype, int32 rtypmod); +extern RangeVar *makeRangeVar(char *schemaname, char *relname); + #endif /* MAKEFUNC_H */ diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 95aba8dfaa4..34510c0d792 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: nodes.h,v 1.102 2002/03/21 16:01:44 tgl Exp $ + * $Id: nodes.h,v 1.103 2002/03/22 02:56:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -153,7 +153,6 @@ typedef enum NodeTag T_ClusterStmt, T_CopyStmt, T_CreateStmt, - T_VersionStmt, T_DefineStmt, T_DropStmt, T_TruncateStmt, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 4f5d139011f..883130f90a0 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.163 2002/03/21 16:01:46 tgl Exp $ + * $Id: parsenodes.h,v 1.164 2002/03/22 02:56:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -475,7 +475,7 @@ typedef struct TargetEntry * eref is the table reference name and column reference names (either * real or aliases). Note that system columns (OID etc) are not included * in the column list. - * eref->relname is required to be present, and should generally be used + * eref->aliasname is required to be present, and should generally be used * to identify the RTE for error messages etc. * * inh is TRUE for relation references that should be expanded to include @@ -521,9 +521,8 @@ typedef struct RangeTblEntry */ /* - * Fields valid for a plain relation RTE (else NULL/zero): + * Fields valid for a plain relation RTE (else zero): */ - char *relname; /* real name of the relation */ Oid relid; /* OID of the relation */ /* @@ -532,7 +531,7 @@ typedef struct RangeTblEntry Query *subquery; /* the sub-query */ /* - * Fields valid for a join RTE (else NULL): + * Fields valid for a join RTE (else NULL/zero): * * joincoltypes/joincoltypmods identify the column datatypes of the * join result. joinleftcols and joinrightcols identify the source @@ -1058,19 +1057,6 @@ typedef struct CreateSeqStmt } CreateSeqStmt; /* ---------------------- - * Create Version Statement - * ---------------------- - */ -typedef struct VersionStmt -{ - NodeTag type; - char *relname; /* the new relation */ - int direction; /* FORWARD | BACKWARD */ - char *fromRelname; /* relation to create a version */ - char *date; /* date of the snapshot */ -} VersionStmt; - -/* ---------------------- * Create {Operator|Type|Aggregate} Statement * ---------------------- */ diff --git a/src/include/parser/parse_clause.h b/src/include/parser/parse_clause.h index 36820ad4dff..3b97a800afb 100644 --- a/src/include/parser/parse_clause.h +++ b/src/include/parser/parse_clause.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parse_clause.h,v 1.27 2001/11/05 17:46:34 momjian Exp $ + * $Id: parse_clause.h,v 1.28 2002/03/22 02:56:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,7 +17,7 @@ #include "parser/parse_node.h" extern void transformFromClause(ParseState *pstate, List *frmList); -extern int setTargetTable(ParseState *pstate, char *relname, +extern int setTargetTable(ParseState *pstate, RangeVar *relation, bool inh, bool alsoSource); extern bool interpretInhOption(InhOption inhOpt); extern Node *transformWhereClause(ParseState *pstate, Node *where); diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h index 656c70a688a..038931d9b6d 100644 --- a/src/include/parser/parse_relation.h +++ b/src/include/parser/parse_relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parse_relation.h,v 1.30 2002/03/21 16:02:05 tgl Exp $ + * $Id: parse_relation.h,v 1.31 2002/03/22 02:56:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -28,7 +28,12 @@ extern Node *colnameToVar(ParseState *pstate, char *colname); extern Node *qualifiedNameToVar(ParseState *pstate, char *refname, char *colname, bool implicitRTEOK); extern RangeTblEntry *addRangeTableEntry(ParseState *pstate, - char *relname, + RangeVar *relation, + Alias *alias, + bool inh, + bool inFromCl); +extern RangeTblEntry *addRangeTableEntryForRelation(ParseState *pstate, + Oid relid, Alias *alias, bool inh, bool inFromCl); @@ -47,7 +52,7 @@ extern RangeTblEntry *addRangeTableEntryForJoin(ParseState *pstate, bool inFromCl); extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, bool addToJoinList, bool addToNameSpace); -extern RangeTblEntry *addImplicitRTE(ParseState *pstate, char *relname); +extern RangeTblEntry *addImplicitRTE(ParseState *pstate, RangeVar *relation); extern void expandRTE(ParseState *pstate, RangeTblEntry *rte, List **colnames, List **colvars); extern List *expandRelAttrs(ParseState *pstate, RangeTblEntry *rte); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 4c2dec5d106..e1343bf4fcd 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: builtins.h,v 1.172 2002/03/12 00:52:06 tgl Exp $ + * $Id: builtins.h,v 1.173 2002/03/22 02:56:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -342,9 +342,10 @@ extern Datum pg_get_userbyid(PG_FUNCTION_ARGS); extern Datum pg_get_expr(PG_FUNCTION_ARGS); extern char *deparse_expression(Node *expr, List *dpcontext, bool forceprefix); -extern List *deparse_context_for(char *relname, Oid relid); +extern List *deparse_context_for(const char *aliasname, Oid relid); extern List *deparse_context_for_plan(int outer_varno, Node *outercontext, int inner_varno, Node *innercontext); +extern Node *deparse_context_for_relation(const char *aliasname, Oid relid); extern Node *deparse_context_for_subplan(const char *name, List *tlist, List *rtable); diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index fbdb5f66346..89dda37bf7c 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: lsyscache.h,v 1.44 2002/03/20 19:45:09 tgl Exp $ + * $Id: lsyscache.h,v 1.45 2002/03/22 02:56:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -40,6 +40,7 @@ extern RegProcedure get_oprjoin(Oid opno); extern Oid get_func_rettype(Oid funcid); extern bool func_iscachable(Oid funcid); extern char *get_rel_name(Oid relid); +extern Oid get_rel_type_id(Oid relid); extern int16 get_typlen(Oid typid); extern bool get_typbyval(Oid typid); extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval); |