mirror of https://github.com/postgres/postgres
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.
This commit is contained in:
parent
56c9b73c1d
commit
108a0ec87d
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 ---------- */
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
* ----------------------
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue