diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 629ffe7c2e..9df788406a 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 31df6cabd7..b9741e0f3a 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 91f5d14a37..0f9bf525ef 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 95263a5da0..19df98531c 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; } - /* 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); 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->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 + 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 5bcf4f8232..d0b1f7d4d5 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 74a3ac2bca..3b4bf7da13 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 fb68866c53..2c1e5b675f 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 9788fd2f52..6adc87c404 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 $ * *------------------------------------------------------------------------- */ @@ -831,21 +831,6 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b) return true; } -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) { @@ -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 d8bf80a52e..649fb38c11 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 aff46e6ba3..195db0165d 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 ebc5d536e7..7254d46c17 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 66dd317f39..150e98d6e4 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 b2f18780fc..83d454c4d6 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 109062c529..adefcd040c 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 f94eaea509..fa6bf35fb9 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 6e8868f8ea..c2f578f4e6 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 ee1bf6c057..f02ee04b69 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 5cf868a4d1..3701539af5 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 a4b7816517..cc56cb6d18 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 e118654e40..aebc7b94f8 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 8443fe6591..68358f4966 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 1f0046887f..af6b943e34 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 0e4472faff..d834023439 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, @@ -700,6 +699,29 @@ deparse_context_for_plan(int outer_varno, Node *outercontext, return makeList1(dpns); } +/* + * 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 * @@ -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) + switch (rte->rtekind) { - /* Normal relation RTE */ - appendStringInfo(buf, "%s%s", - only_marker(rte), - quote_identifier(rte->relname)); - } - else - { - /* 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 f4ebb6261c..1157780111 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 5e0fa208cf..e931772b07 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 4cc9801e85..90f5df63d3 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 2de7c03cf6..52c224b18f 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 95aba8dfaa..34510c0d79 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 4f5d139011..883130f90a 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 @@ -1057,19 +1056,6 @@ typedef struct CreateSeqStmt List *options; } 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 36820ad4df..3b97a800af 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 656c70a688..038931d9b6 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 4c2dec5d10..e1343bf4fc 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 fbdb5f6634..89dda37bf7 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);