Commit 95ef6a34 authored by Tom Lane's avatar Tom Lane

First phase of SCHEMA changes, concentrating on fixing the grammar and

the parsetree representation.  As yet we don't *do* anything with schema
names, just drop 'em on the floor; but you can enter schema-compatible
command syntax, and there's even a primitive CREATE SCHEMA command.
No doc updates yet, except to note that you can now extract a field
from a function-returning-row's result with (foo(...)).fieldname.
parent 8c9c8ca2
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.49 2002/03/11 05:03:52 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.50 2002/03/21 16:00:28 tgl Exp $
-->
<chapter id="xfunc">
......@@ -306,7 +306,8 @@ CREATE FUNCTION new_emp() RETURNS EMP AS '
<para>
The target list order must be exactly the same as
that in which the columns appear in the table associated
with the composite type.
with the composite type. (Naming the columns, as we did above,
is irrelevant to the system.)
</para>
</listitem>
<listitem>
......@@ -328,28 +329,46 @@ ERROR: function declared to return emp returns varchar instead of text at colum
there are some unpleasant restrictions on how functions returning
composite types can be used. Briefly, when calling a function that
returns a row, we cannot retrieve the entire row. We must either
project a single attribute out of the row or pass the entire row into
extract a single attribute out of the row or pass the entire row into
another function. (Trying to display the entire row value will yield
a meaningless number.) For example,
<programlisting>
SELECT name(new_emp());
SELECT (new_emp()).name;
</programlisting>
<screen>
name
------
None
</screen>
We need the extra parentheses to keep the parser from getting confused:
<screen>
SELECT new_emp().name;
ERROR: parser: parse error at or near "."
</screen>
</para>
<para>
This example makes use of the
function notation for projecting attributes. The simple way
to explain this is that we can usually use the
Another approach is to use
functional notation for extracting attributes. The simple way
to explain this is that we can use the
notations <literal>attribute(table)</> and <literal>table.attribute</>
interchangeably:
<programlisting>
SELECT name(new_emp());
</programlisting>
<screen>
name
------
None
</screen>
</para>
<programlisting>
--
-- this is the same as:
......@@ -367,19 +386,6 @@ SELECT name(EMP) AS youngster
</screen>
</para>
<para>
The reason why, in general, we must use the function
syntax for projecting attributes of function return
values is that the parser just doesn't understand
the dot syntax for projection when combined
with function calls.
<screen>
SELECT new_emp().name AS nobody;
ERROR: parser: parse error at or near "."
</screen>
</para>
<para>
Another way to use a function returning a row result is to declare a
second function accepting a row type parameter, and pass the function
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.56 2002/03/06 06:09:24 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.57 2002/03/21 16:00:29 tgl Exp $
*
* NOTES
* See acl.h.
......@@ -200,7 +200,7 @@ ExecuteGrantStmt_Table(GrantStmt *stmt)
foreach(i, stmt->objects)
{
char *relname = strVal(lfirst(i));
char *relname = ((RangeVar *) lfirst(i))->relname;
Relation relation;
HeapTuple tuple;
Form_pg_class pg_class_tuple;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.189 2002/03/20 19:43:34 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.190 2002/03/21 16:00:29 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -1728,7 +1728,7 @@ AddRelationRawConstraints(Relation rel,
/*
* Transform raw parsetree to executable expression.
*/
expr = transformExpr(pstate, cdef->raw_expr, EXPR_COLUMN_FIRST);
expr = transformExpr(pstate, cdef->raw_expr);
/*
* Make sure it yields a boolean result.
......@@ -1863,7 +1863,7 @@ cookDefault(ParseState *pstate,
/*
* Transform raw parsetree to executable expression.
*/
expr = transformExpr(pstate, raw_default, EXPR_COLUMN_FIRST);
expr = transformExpr(pstate, raw_default);
/*
* Make sure default expr does not refer to any vars.
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.161 2002/03/14 22:44:50 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.162 2002/03/21 16:00:31 tgl Exp $
*
* NOTES
* The PerformAddAttribute() code, like most of the relation
......@@ -33,7 +33,7 @@
#include "catalog/pg_type.h"
#include "commands/command.h"
#include "commands/trigger.h"
#include "commands/defrem.h" /* For add constraint unique, primary */
#include "commands/defrem.h"
#include "executor/execdefs.h"
#include "executor/executor.h"
#include "miscadmin.h"
......@@ -44,7 +44,8 @@
#include "parser/parse_expr.h"
#include "parser/parse_oper.h"
#include "parser/parse_relation.h"
#include "parser/analyze.h" /* For add constraint unique, primary */
#include "parser/analyze.h"
#include "tcop/utility.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
......@@ -1279,8 +1280,7 @@ AlterTableAddConstraint(char *relationName,
* Convert the A_EXPR in raw_expr into an
* EXPR
*/
expr = transformExpr(pstate, constr->raw_expr,
EXPR_COLUMN_FIRST);
expr = transformExpr(pstate, constr->raw_expr);
/*
* Make sure it yields a boolean result.
......@@ -1366,7 +1366,7 @@ AlterTableAddConstraint(char *relationName,
List *list;
int count;
if (is_temp_rel_name(fkconstraint->pktable_name) &&
if (is_temp_rel_name(fkconstraint->pktable->relname) &&
!is_temp_rel_name(relationName))
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint.");
......@@ -1375,10 +1375,10 @@ AlterTableAddConstraint(char *relationName,
* someone doesn't delete rows out from under us.
*/
pkrel = heap_openr(fkconstraint->pktable_name, AccessExclusiveLock);
pkrel = heap_openr(fkconstraint->pktable->relname, AccessExclusiveLock);
if (pkrel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "referenced table \"%s\" not a relation",
fkconstraint->pktable_name);
fkconstraint->pktable->relname);
heap_close(pkrel, NoLock);
/*
......@@ -1417,7 +1417,7 @@ AlterTableAddConstraint(char *relationName,
else
trig.tgargs[0] = "<unknown>";
trig.tgargs[1] = (char *) relationName;
trig.tgargs[2] = fkconstraint->pktable_name;
trig.tgargs[2] = fkconstraint->pktable->relname;
trig.tgargs[3] = fkconstraint->match_type;
count = 4;
foreach(list, fkconstraint->fk_attrs)
......@@ -1936,9 +1936,10 @@ LockTableCommand(LockStmt *lockstmt)
* at a time
*/
foreach(p, lockstmt->rellist)
foreach(p, lockstmt->relations)
{
char *relname = strVal(lfirst(p));
RangeVar *relation = lfirst(p);
char *relname = relation->relname;
int aclresult;
Relation rel;
......@@ -1962,3 +1963,94 @@ LockTableCommand(LockStmt *lockstmt)
relation_close(rel, NoLock); /* close rel, keep lock */
}
}
/*
* CREATE SCHEMA
*/
void
CreateSchemaCommand(CreateSchemaStmt *stmt)
{
const char *schemaName = stmt->schemaname;
const char *authId = stmt->authid;
List *parsetree_list;
List *parsetree_item;
const char *owner_name;
Oid owner_userid;
Oid saved_userid;
saved_userid = GetUserId();
if (!authId)
{
owner_userid = saved_userid;
owner_name = GetUserName(owner_userid);
}
else if (superuser())
{
owner_name = authId;
/* The following will error out if user does not exist */
owner_userid = get_usesysid(owner_name);
/*
* Set the current user to the requested authorization so
* that objects created in the statement have the requested
* owner. (This will revert to session user on error or at
* the end of this routine.)
*/
SetUserId(owner_userid);
}
else /* not superuser */
{
owner_userid = saved_userid;
owner_name = GetUserName(owner_userid);
if (strcmp(authId, owner_name) != 0)
elog(ERROR, "CREATE SCHEMA: permission denied"
"\n\t\"%s\" is not a superuser, so cannot create a schema for \"%s\"",
owner_name, authId);
}
/* FIXME FENN: Create the schema here */
(void) schemaName; /* suppress compiler warning for now... */
/*
* Let commands in the schema-element-list know about the schema
*/
CommandCounterIncrement();
/*
* Examine the list of commands embedded in the CREATE SCHEMA command,
* and reorganize them into a sequentially executable order with no
* forward references. Note that the result is still a list of raw
* parsetrees in need of parse analysis --- we cannot, in general,
* run analyze.c on one statement until we have actually executed the
* prior ones.
*/
parsetree_list = analyzeCreateSchemaStmt(stmt);
/*
* Analyze and execute each command contained in the CREATE SCHEMA
*/
foreach(parsetree_item, parsetree_list)
{
Node *parsetree = (Node *) lfirst(parsetree_item);
List *querytree_list,
*querytree_item;
querytree_list = parse_analyze(parsetree, NULL);
foreach(querytree_item, querytree_list)
{
Query *querytree = (Query *) lfirst(querytree_item);
/* schemas should contain only utility stmts */
Assert(querytree->commandType == CMD_UTILITY);
/* do this step */
ProcessUtility(querytree->utilityStmt, None, NULL);
/* make sure later steps can see the object created here */
CommandCounterIncrement();
}
}
/* Reset current user */
SetUserId(saved_userid);
}
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.88 2002/03/20 19:43:42 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.89 2002/03/21 16:00:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -69,7 +69,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
* Truncate relname to appropriate length (probably a waste of time,
* as parser should have done this already).
*/
StrNCpy(relname, stmt->relname, NAMEDATALEN);
StrNCpy(relname, (stmt->relation)->relname, NAMEDATALEN);
/*
* Merge domain attributes into the known columns before processing table
......@@ -82,8 +82,9 @@ DefineRelation(CreateStmt *stmt, char relkind)
* Look up inheritance ancestors and generate relation schema,
* including inherited attributes.
*/
schema = MergeAttributes(schema, stmt->inhRelnames, stmt->istemp,
&inheritOids, &old_constraints, &parentHasOids);
schema = MergeAttributes(schema, stmt->inhRelations,
stmt->relation->istemp,
&inheritOids, &old_constraints, &parentHasOids);
numberOfAttributes = length(schema);
if (numberOfAttributes <= 0)
......@@ -147,7 +148,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
relationId = heap_create_with_catalog(relname, descriptor,
relkind,
stmt->hasoids || parentHasOids,
stmt->istemp,
stmt->relation->istemp,
allowSystemTableMods);
StoreCatalogInheritance(relationId, inheritOids);
......@@ -414,6 +415,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
/*
* Reject duplicate names in the list of parents, too.
*
* XXX needs to be smarter about schema-qualified table names.
*/
foreach(entry, supers)
{
......@@ -421,9 +424,10 @@ MergeAttributes(List *schema, List *supers, bool istemp,
foreach(rest, lnext(entry))
{
if (strcmp(strVal(lfirst(entry)), strVal(lfirst(rest))) == 0)
if (strcmp(((RangeVar *) lfirst(entry))->relname,
((RangeVar *) lfirst(rest))->relname) == 0)
elog(ERROR, "CREATE TABLE: inherited relation \"%s\" duplicated",
strVal(lfirst(entry)));
((RangeVar *) lfirst(entry))->relname);
}
}
......@@ -435,7 +439,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
child_attno = 0;
foreach(entry, supers)
{
char *name = strVal(lfirst(entry));
char *name = ((RangeVar *) lfirst(entry))->relname;
Relation relation;
TupleDesc tupleDesc;
TupleConstr *constr;
......
......@@ -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.71 2002/03/12 00:51:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.72 2002/03/21 16:00:32 tgl Exp $
*
*/
......@@ -310,9 +310,9 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
appendStringInfo(str, " on %s",
stringStringInfo(rte->relname));
if (strcmp(rte->eref->relname, rte->relname) != 0)
if (strcmp(rte->eref->aliasname, rte->relname) != 0)
appendStringInfo(str, " %s",
stringStringInfo(rte->eref->relname));
stringStringInfo(rte->eref->aliasname));
}
break;
case T_SubqueryScan:
......@@ -322,7 +322,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
es->rtable);
appendStringInfo(str, " %s",
stringStringInfo(rte->eref->relname));
stringStringInfo(rte->eref->aliasname));
}
break;
default:
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.71 2002/03/15 19:20:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.72 2002/03/21 16:00:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -123,7 +123,7 @@ DefineSequence(CreateSeqStmt *seq)
case SEQ_COL_NAME:
typnam->name = "name";
coldef->colname = "sequence_name";
namestrcpy(&name, seq->seqname);
namestrcpy(&name, seq->sequence->relname);
value[i - 1] = NameGetDatum(&name);
break;
case SEQ_COL_LASTVAL:
......@@ -170,15 +170,14 @@ DefineSequence(CreateSeqStmt *seq)
stmt->tableElts = lappend(stmt->tableElts, coldef);
}
stmt->relname = seq->seqname;
stmt->inhRelnames = NIL;
stmt->relation = seq->sequence;
stmt->inhRelations = NIL;
stmt->constraints = NIL;
stmt->istemp = seq->istemp;
stmt->hasoids = false;
DefineRelation(stmt, RELKIND_SEQUENCE);
rel = heap_openr(seq->seqname, AccessExclusiveLock);
rel = heap_openr(seq->sequence->relname, AccessExclusiveLock);
tupDesc = RelationGetDescr(rel);
/* Initialize first page of relation with special magic number */
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.105 2002/03/08 04:37:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.106 2002/03/21 16:00:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -71,10 +71,11 @@ CreateTrigger(CreateTrigStmt *stmt)
char *constrname = "";
Oid constrrelid = InvalidOid;
if (!allowSystemTableMods && IsSystemRelationName(stmt->relname))
elog(ERROR, "CreateTrigger: can't create trigger for system relation %s", stmt->relname);
if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname))
elog(ERROR, "CreateTrigger: can't create trigger for system relation %s",
stmt->relation->relname);
if (pg_aclcheck(stmt->relname, GetUserId(),
if (pg_aclcheck(stmt->relation->relname, GetUserId(),
stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER)
!= ACLCHECK_OK)
elog(ERROR, "permission denied");
......@@ -89,7 +90,7 @@ CreateTrigger(CreateTrigStmt *stmt)
stmt->trigname = constrtrigname;
sprintf(constrtrigname, "RI_ConstraintTrigger_%u", newoid());
if (strcmp(stmt->constrrelname, "") == 0)
if (stmt->constrrel == NULL)
constrrelid = InvalidOid;
else
{
......@@ -97,17 +98,17 @@ CreateTrigger(CreateTrigStmt *stmt)
* NoLock is probably sufficient here, since we're only
* interested in getting the relation's OID...
*/
rel = heap_openr(stmt->constrrelname, NoLock);
rel = heap_openr(stmt->constrrel->relname, NoLock);
constrrelid = rel->rd_id;
heap_close(rel, NoLock);
}
}
rel = heap_openr(stmt->relname, AccessExclusiveLock);
rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "CreateTrigger: relation \"%s\" is not a table",
stmt->relname);
stmt->relation->relname);
TRIGGER_CLEAR_TYPE(tgtype);
if (stmt->before)
......@@ -159,7 +160,7 @@ CreateTrigger(CreateTrigStmt *stmt)
if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
elog(ERROR, "CreateTrigger: trigger %s already defined on relation %s",
stmt->trigname, stmt->relname);
stmt->trigname, stmt->relation->relname);
found++;
}
systable_endscan(tgscan);
......@@ -283,11 +284,11 @@ CreateTrigger(CreateTrigStmt *stmt)
*/
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheCopy(RELNAME,
PointerGetDatum(stmt->relname),
PointerGetDatum(stmt->relation->relname),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "CreateTrigger: relation %s not found in pg_class",
stmt->relname);
stmt->relation->relname);
((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
simple_heap_update(pgrel, &tuple->t_self, tuple);
......@@ -320,19 +321,19 @@ DropTrigger(DropTrigStmt *stmt)
int found = 0;
int tgfound = 0;
if (!allowSystemTableMods && IsSystemRelationName(stmt->relname))
if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname))
elog(ERROR, "DropTrigger: can't drop trigger for system relation %s",
stmt->relname);
stmt->relation->relname);
if (!pg_ownercheck(GetUserId(), stmt->relname, RELNAME))
elog(ERROR, "%s: %s", stmt->relname,
if (!pg_ownercheck(GetUserId(), stmt->relation->relname, RELNAME))
elog(ERROR, "%s: %s", stmt->relation->relname,
aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
rel = heap_openr(stmt->relname, AccessExclusiveLock);
rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "DropTrigger: relation \"%s\" is not a table",
stmt->relname);
stmt->relation->relname);
/*
* Search pg_trigger, delete target trigger, count remaining triggers
......@@ -366,10 +367,10 @@ DropTrigger(DropTrigStmt *stmt)
if (tgfound == 0)
elog(ERROR, "DropTrigger: there is no trigger %s on relation %s",
stmt->trigname, stmt->relname);
stmt->trigname, stmt->relation->relname);
if (tgfound > 1)
elog(NOTICE, "DropTrigger: found (and deleted) %d triggers %s on relation %s",
tgfound, stmt->trigname, stmt->relname);
tgfound, stmt->trigname, stmt->relation->relname);
/*
* Update relation's pg_class entry. Crucial side-effect: other
......@@ -378,11 +379,11 @@ DropTrigger(DropTrigStmt *stmt)
*/
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheCopy(RELNAME,
PointerGetDatum(stmt->relname),
PointerGetDatum(stmt->relation->relname),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "DropTrigger: relation %s not found in pg_class",
stmt->relname);
stmt->relation->relname);
((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found;
simple_heap_update(pgrel, &tuple->t_self, tuple);
......@@ -478,20 +479,23 @@ RelationRemoveTriggers(Relation rel)
{
Form_pg_trigger pg_trigger;
Relation refrel;
DropTrigStmt stmt;
DropTrigStmt *stmt = makeNode(DropTrigStmt);
pg_trigger = (Form_pg_trigger) GETSTRUCT(tup);
stmt.trigname = pstrdup(NameStr(pg_trigger->tgname));
stmt->trigname = pstrdup(NameStr(pg_trigger->tgname));
/* May as well grab AccessExclusiveLock, since DropTrigger will. */
refrel = heap_open(pg_trigger->tgrelid, AccessExclusiveLock);
stmt.relname = pstrdup(RelationGetRelationName(refrel));
stmt->relation = makeNode(RangeVar);
/* XXX bogus: what about schema? */
stmt->relation->relname = pstrdup(RelationGetRelationName(refrel));
heap_close(refrel, NoLock);
elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"", stmt.relname);
elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"",
stmt->relation->relname);
DropTrigger(&stmt);
DropTrigger(stmt);
/*
* Need to do a command counter increment here to show up new
......@@ -500,9 +504,6 @@ RelationRemoveTriggers(Relation rel)
* FK table defined on the PK table).
*/
CommandCounterIncrement();
pfree(stmt.relname);
pfree(stmt.trigname);
}
systable_endscan(tgscan);
......
......@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.217 2002/03/06 06:09:38 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.218 2002/03/21 16:00:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -209,10 +209,10 @@ vacuum(VacuumStmt *vacstmt)
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
/* Convert vacrel, which is just a string, to a Name */
if (vacstmt->vacrel)
/* Convert relname, which is just a string, to a Name */
if (vacstmt->relation)
{
namestrcpy(&VacRel, vacstmt->vacrel);
namestrcpy(&VacRel, vacstmt->relation->relname);
VacRelName = &VacRel;
}
else
......@@ -268,7 +268,7 @@ vacuum(VacuumStmt *vacstmt)
static void
vacuum_init(VacuumStmt *vacstmt)
{
if (vacstmt->vacuum && vacstmt->vacrel == NULL)
if (vacstmt->vacuum && vacstmt->relation == NULL)
{
/*
* Compute the initially applicable OldestXmin and FreezeLimit
......@@ -308,7 +308,7 @@ vacuum_shutdown(VacuumStmt *vacstmt)
* row with info about the transaction IDs used, and try to truncate
* pg_clog.
*/
if (vacstmt->vacuum && vacstmt->vacrel == NULL)
if (vacstmt->vacuum && vacstmt->relation == NULL)
{
vac_update_dbstats(MyDatabaseId,
initialOldestXmin, initialFreezeLimit);
......
......@@ -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.58 2001/10/25 05:49:26 momjian Exp $
* $Id: view.c,v 1.59 2002/03/21 16:00:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -41,6 +41,7 @@ static void
DefineVirtualRelation(char *relname, List *tlist)
{
CreateStmt *createStmt = makeNode(CreateStmt);
RangeVar *rel = makeNode(RangeVar);
List *attrList,
*t;
......@@ -83,11 +84,13 @@ DefineVirtualRelation(char *relname, List *tlist)
* now create the parameters for keys/inheritance etc. All of them are
* nil...
*/
createStmt->relname = relname;
rel->relname = relname;
rel->schemaname = NULL; /* XXX wrong */
rel->istemp = false;
createStmt->relation = rel;
createStmt->tableElts = attrList;
createStmt->inhRelnames = NIL;
createStmt->inhRelations = NIL;
createStmt->constraints = NIL;
createStmt->istemp = false;
createStmt->hasoids = false;
/*
......@@ -101,21 +104,24 @@ FormViewRetrieveRule(char *viewName, Query *viewParse)
{
RuleStmt *rule;
char *rname;
Attr *attr;
RangeVar *rel;
/*
* Create a RuleStmt that corresponds to the suitable rewrite rule
* args for DefineQueryRewrite();
*/
rule = makeNode(RuleStmt);
rname = MakeRetrieveViewRuleName(viewName);
attr = makeNode(Attr);
attr->relname = pstrdup(viewName);
rel = makeNode(RangeVar);
rel->relname = pstrdup(viewName);
rel->inhOpt = INH_NO;
rel->alias = NULL;
rule = makeNode(RuleStmt);
rule->relation = rel;
rule->rulename = pstrdup(rname);
rule->whereClause = NULL;
rule->event = CMD_SELECT;
rule->object = attr;
rule->instead = true;
rule->actions = makeList1(viewParse);
......@@ -191,10 +197,10 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse)
* table... OLD first, then NEW....
*/
rt_entry1 = addRangeTableEntry(NULL, viewName,
makeAttr("*OLD*", NULL),
makeAlias("*OLD*", NIL),
false, false);
rt_entry2 = addRangeTableEntry(NULL, viewName,
makeAttr("*NEW*", NULL),
makeAlias("*NEW*", NIL),
false, false);
/* Must override addRangeTableEntry's default access-check flags */
rt_entry1->checkForRead = false;
......
......@@ -27,7 +27,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.152 2002/03/06 06:09:42 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.153 2002/03/21 16:00:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -707,7 +707,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
/*
* create the "into" relation
*/
intoName = parseTree->into;
intoName = parseTree->into->relname;
/*
* have to copy tupType to get rid of constraints
......@@ -718,7 +718,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
heap_create_with_catalog(intoName,
tupdesc,
RELKIND_RELATION, true,
parseTree->isTemp,
parseTree->into->istemp,
allowSystemTableMods);
FreeTupleDesc(tupdesc);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.67 2002/02/27 19:34:59 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.68 2002/03/21 16:00:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -775,7 +775,8 @@ SPI_cursor_open(char *name, void *plan, Datum *Values, char *Nulls)
/* Modify the parsetree to be a cursor */
queryTree->isPortal = true;
queryTree->into = pstrdup(name);
queryTree->into = makeNode(RangeVar);
queryTree->into->relname = pstrdup(name);
queryTree->isBinary = false;
/* Create the QueryDesc object and the executor state */
......@@ -1145,7 +1146,7 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
if (parseTree->isPortal)
{
isRetrieveIntoPortal = true;
intoName = parseTree->into;
intoName = parseTree->into->relname;
parseTree->isBinary = false; /* */
return SPI_ERROR_CURSOR;
......
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.27 2002/03/20 19:44:04 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/makefuncs.c,v 1.28 2002/03/21 16:00:40 tgl Exp $
*/
#include "postgres.h"
......@@ -159,19 +159,18 @@ makeNullConst(Oid consttype)
}
/*
* makeAttr -
* creates an Attr node
* makeAlias -
* creates an Alias node
*
* NOTE: the given name is copied, but the colnames list (if any) isn't.
*/
Attr *
makeAttr(char *relname, char *attname)
Alias *
makeAlias(const char *aliasname, List *colnames)
{
Attr *a = makeNode(Attr);
Alias *a = makeNode(Alias);
a->relname = pstrdup(relname);
a->paramNo = NULL;
if (attname != NULL)
a->attrs = makeList1(makeString(pstrdup(attname)));
a->indirection = NULL;
a->aliasname = pstrdup(aliasname);
a->colnames = colnames;
return a;
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/nodeFuncs.c,v 1.16 2001/10/28 06:25:44 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/nodeFuncs.c,v 1.17 2002/03/21 16:00:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -29,7 +29,9 @@ static bool var_is_inner(Var *var);
bool
single_node(Node *node)
{
if (IsA(node, Ident) ||IsA(node, Const) ||IsA(node, Var) ||IsA(node, Param))
if (IsA(node, Const) ||
IsA(node, Var) ||
IsA(node, Param))
return true;
else
return false;
......@@ -103,13 +105,13 @@ replace_opid(Oper *oper)
* non_null -
* Returns t if the node is a non-null constant, e.g., if the node has a
* valid `constvalue' field.
*
*/
bool
non_null(Expr *c)
{
if (IsA(c, Const) &&!((Const *) c)->constisnull)
if (IsA(c, Const) &&
!((Const *) c)->constisnull)
return true;
else
return false;
......
......@@ -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.149 2002/03/12 00:51:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.150 2002/03/21 16:00:40 tgl Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
......@@ -105,20 +105,19 @@ _outOidList(StringInfo str, List *list)
static void
_outCreateStmt(StringInfo str, CreateStmt *node)
{
appendStringInfo(str, " CREATE :relname ");
_outToken(str, node->relname);
appendStringInfo(str, " CREATE :relation ");
_outNode(str, node->relation);
appendStringInfo(str, " :columns ");
appendStringInfo(str, " :tableElts ");
_outNode(str, node->tableElts);
appendStringInfo(str, " :inhRelnames ");
_outNode(str, node->inhRelnames);
appendStringInfo(str, " :inhRelations ");
_outNode(str, node->inhRelations);
appendStringInfo(str, " :constraints ");
_outNode(str, node->constraints);
appendStringInfo(str, " :istemp %s :hasoids %s ",
booltostr(node->istemp),
appendStringInfo(str, " :hasoids %s ",
booltostr(node->hasoids));
}
......@@ -127,8 +126,8 @@ _outIndexStmt(StringInfo str, IndexStmt *node)
{
appendStringInfo(str, " INDEX :idxname ");
_outToken(str, node->idxname);
appendStringInfo(str, " :relname ");
_outToken(str, node->relname);
appendStringInfo(str, " :relation ");
_outNode(str, node->relation);
appendStringInfo(str, " :accessMethod ");
_outToken(str, node->accessMethod);
appendStringInfo(str, " :indexParams ");
......@@ -142,6 +141,13 @@ _outIndexStmt(StringInfo str, IndexStmt *node)
booltostr(node->primary));
}
static void
_outNotifyStmt(StringInfo str, NotifyStmt *node)
{
appendStringInfo(str, "NOTIFY :relation ");
_outNode(str, node->relation);
}
static void
_outSelectStmt(StringInfo str, SelectStmt *node)
{
......@@ -213,53 +219,40 @@ _outIndexElem(StringInfo str, IndexElem *node)
static void
_outQuery(StringInfo str, Query *node)
{
appendStringInfo(str, " QUERY :command %d :utility ", node->commandType);
appendStringInfo(str, " QUERY :command %d ", node->commandType);
/*
* Hack to work around missing outfuncs routines for a lot of the
* utility-statement node types. (The only one we actually *need*
* for rules support is NotifyStmt.) Someday we ought to support
* 'em all, but for the meantime do this to avoid getting lots of
* warnings when running with debug_print_parse on.
*/
if (node->utilityStmt)
{
/*
* Hack to make up for lack of outfuncs for utility-stmt nodes
*/
switch (nodeTag(node->utilityStmt))
{
case T_CreateStmt:
appendStringInfo(str, " :create ");
_outToken(str, ((CreateStmt *) (node->utilityStmt))->relname);
appendStringInfo(str, " ");
_outNode(str, node->utilityStmt);
break;
case T_IndexStmt:
appendStringInfo(str, " :index ");
_outToken(str, ((IndexStmt *) (node->utilityStmt))->idxname);
appendStringInfo(str, " on ");
_outToken(str, ((IndexStmt *) (node->utilityStmt))->relname);
appendStringInfo(str, " ");
_outNode(str, node->utilityStmt);
break;
case T_NotifyStmt:
appendStringInfo(str, " :notify ");
_outToken(str, ((NotifyStmt *) (node->utilityStmt))->relname);
_outNode(str, node->utilityStmt);
break;
default:
appendStringInfo(str, " :utility ? ");
appendStringInfo(str, "?");
break;
}
}
else
appendStringInfo(str, " :utility <>");
appendStringInfo(str, "<>");
appendStringInfo(str, " :resultRelation %d :into ",
node->resultRelation);
_outToken(str, node->into);
_outNode(str, node->into);
appendStringInfo(str, " :isPortal %s :isBinary %s :isTemp %s"
appendStringInfo(str, " :isPortal %s :isBinary %s"
" :hasAggs %s :hasSubLinks %s :rtable ",
booltostr(node->isPortal),
booltostr(node->isBinary),
booltostr(node->isTemp),
booltostr(node->hasAggs),
booltostr(node->hasSubLinks));
_outNode(str, node->rtable);
......@@ -963,6 +956,15 @@ _outTargetEntry(StringInfo str, TargetEntry *node)
_outNode(str, node->expr);
}
static void
_outAlias(StringInfo str, Alias *node)
{
appendStringInfo(str, " ALIAS :aliasname ");
_outToken(str, node->aliasname);
appendStringInfo(str, " :colnames ");
_outNode(str, node->colnames);
}
static void
_outRangeTblEntry(StringInfo str, RangeTblEntry *node)
{
......@@ -1312,19 +1314,46 @@ _outValue(StringInfo str, Value *value)
}
static void
_outIdent(StringInfo str, Ident *node)
_outRangeVar(StringInfo str, RangeVar *node)
{
appendStringInfo(str, " IDENT ");
_outToken(str, node->name);
appendStringInfo(str, " RANGEVAR :relation ");
/*
* we deliberately ignore catalogname here, since it is presently not
* semantically meaningful
*/
_outToken(str, node->schemaname);
appendStringInfo(str, " . ");
_outToken(str, node->relname);
appendStringInfo(str, " :inhopt %d :istemp %s",
(int) node->inhOpt,
booltostr(node->istemp));
appendStringInfo(str, " :alias ");
_outNode(str, node->alias);
}
static void
_outAttr(StringInfo str, Attr *node)
_outColumnRef(StringInfo str, ColumnRef *node)
{
appendStringInfo(str, " ATTR :relname ");
_outToken(str, node->relname);
appendStringInfo(str, " :attrs ");
_outNode(str, node->attrs);
appendStringInfo(str, " COLUMNREF :fields ");
_outNode(str, node->fields);
appendStringInfo(str, " :indirection ");
_outNode(str, node->indirection);
}
static void
_outParamRef(StringInfo str, ParamRef *node)
{
appendStringInfo(str, " PARAMREF :number %d :fields ", node->number);
_outNode(str, node->fields);
appendStringInfo(str, " :indirection ");
_outNode(str, node->indirection);
}
static void
_outIdent(StringInfo str, Ident *node)
{
appendStringInfo(str, " IDENT ");
_outToken(str, node->name);
}
static void
......@@ -1336,6 +1365,17 @@ _outAConst(StringInfo str, A_Const *node)
_outNode(str, node->typename);
}
static void
_outExprFieldSelect(StringInfo str, ExprFieldSelect *node)
{
appendStringInfo(str, " EXPRFIELDSELECT :arg ");
_outNode(str, node->arg);
appendStringInfo(str, " :fields ");
_outNode(str, node->fields);
appendStringInfo(str, " :indirection ");
_outNode(str, node->indirection);
}
static void
_outConstraint(StringInfo str, Constraint *node)
{
......@@ -1384,8 +1424,8 @@ _outFkConstraint(StringInfo str, FkConstraint *node)
{
appendStringInfo(str, " FKCONSTRAINT :constr_name ");
_outToken(str, node->constr_name);
appendStringInfo(str, " :pktable_name ");
_outToken(str, node->pktable_name);
appendStringInfo(str, " :pktable ");
_outNode(str, node->pktable);
appendStringInfo(str, " :fk_attrs ");
_outNode(str, node->fk_attrs);
appendStringInfo(str, " :pk_attrs ");
......@@ -1490,6 +1530,12 @@ _outNode(StringInfo str, void *obj)
case T_IndexStmt:
_outIndexStmt(str, obj);
break;
case T_NotifyStmt:
_outNotifyStmt(str, obj);
break;
case T_SelectStmt:
_outSelectStmt(str, obj);
break;
case T_ColumnDef:
_outColumnDef(str, obj);
break;
......@@ -1628,6 +1674,9 @@ _outNode(StringInfo str, void *obj)
case T_TargetEntry:
_outTargetEntry(str, obj);
break;
case T_Alias:
_outAlias(str, obj);
break;
case T_RangeTblEntry:
_outRangeTblEntry(str, obj);
break;
......@@ -1670,12 +1719,24 @@ _outNode(StringInfo str, void *obj)
case T_A_Expr:
_outAExpr(str, obj);
break;
case T_RangeVar:
_outRangeVar(str, obj);
break;
case T_ColumnRef:
_outColumnRef(str, obj);
break;
case T_ParamRef:
_outParamRef(str, obj);
break;
case T_Ident:
_outIdent(str, obj);
break;
case T_A_Const:
_outAConst(str, obj);
break;
case T_ExprFieldSelect:
_outExprFieldSelect(str, obj);
break;
case T_Constraint:
_outConstraint(str, obj);
break;
......@@ -1694,17 +1755,9 @@ _outNode(StringInfo str, void *obj)
case T_BooleanTest:
_outBooleanTest(str, obj);
break;
case T_VariableSetStmt:
break;
case T_SelectStmt:
_outSelectStmt(str, obj);
break;
case T_FuncCall:
_outFuncCall(str, obj);
break;
case T_Attr:
_outAttr(str, obj);
break;
default:
elog(WARNING, "_outNode: don't know how to print type %d ",
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.51 2001/12/20 02:39:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.52 2002/03/21 16:00:41 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -154,10 +154,10 @@ print_rt(List *rtable)
if (rte->relname)
printf("%d\t%s (%s)\t%u",
i, rte->relname, rte->eref->relname, rte->relid);
i, rte->relname, rte->eref->aliasname, rte->relid);
else
printf("%d\t[subquery] (%s)\t",
i, rte->eref->relname);
i, rte->eref->aliasname);
printf("\t%s\t%s\n",
(rte->inh ? "inh" : ""),
(rte->inFromCl ? "inFromCl" : ""));
......@@ -202,7 +202,7 @@ print_expr(Node *expr, List *rtable)
Assert(var->varno > 0 &&
(int) var->varno <= length(rtable));
rte = rt_fetch(var->varno, rtable);
relname = rte->eref->relname;
relname = rte->eref->aliasname;
attname = get_rte_attribute_name(rte, var->varattno);
}
break;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.116 2002/03/12 00:51:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.117 2002/03/21 16:00:42 tgl Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
......@@ -119,34 +119,19 @@ _readQuery(void)
local_node = makeNode(Query);
token = pg_strtok(&length); /* skip the :command */
token = pg_strtok(&length); /* get the commandType */
token = pg_strtok(&length); /* skip :command */
token = pg_strtok(&length); /* get commandType */
local_node->commandType = atoi(token);
token = pg_strtok(&length); /* skip :utility */
token = pg_strtok(&length);
if (length == 0)
local_node->utilityStmt = NULL;
else
{
/*
* Hack to make up for lack of readfuncs for utility-stmt nodes
*
* we can't get create or index here, can we?
*/
NotifyStmt *n = makeNode(NotifyStmt);
n->relname = debackslash(token, length);
local_node->utilityStmt = (Node *) n;
}
local_node->utilityStmt = nodeRead(true);
token = pg_strtok(&length); /* skip the :resultRelation */
token = pg_strtok(&length); /* skip :resultRelation */
token = pg_strtok(&length); /* get the resultRelation */
local_node->resultRelation = atoi(token);
token = pg_strtok(&length); /* skip :into */
token = pg_strtok(&length); /* get into */
local_node->into = nullable_string(token, length);
local_node->into = nodeRead(true);
token = pg_strtok(&length); /* skip :isPortal */
token = pg_strtok(&length); /* get isPortal */
......@@ -156,10 +141,6 @@ _readQuery(void)
token = pg_strtok(&length); /* get isBinary */
local_node->isBinary = strtobool(token);
token = pg_strtok(&length); /* skip :isTemp */
token = pg_strtok(&length); /* get isTemp */
local_node->isTemp = strtobool(token);
token = pg_strtok(&length); /* skip the :hasAggs */
token = pg_strtok(&length); /* get hasAggs */
local_node->hasAggs = strtobool(token);
......@@ -210,6 +191,25 @@ _readQuery(void)
return local_node;
}
/* ----------------
* _readNotifyStmt
* ----------------
*/
static NotifyStmt *
_readNotifyStmt(void)
{
NotifyStmt *local_node;
char *token;
int length;
local_node = makeNode(NotifyStmt);
token = pg_strtok(&length); /* skip :relation */
local_node->relation = nodeRead(true);
return local_node;
}
/* ----------------
* _readSortClause
* ----------------
......@@ -1394,21 +1394,93 @@ _readTargetEntry(void)
return local_node;
}
static Attr *
_readAttr(void)
static RangeVar *
_readRangeVar(void)
{
Attr *local_node;
RangeVar *local_node;
char *token;
int length;
local_node = makeNode(Attr);
local_node = makeNode(RangeVar);
token = pg_strtok(&length); /* eat :relname */
local_node->catalogname = NULL; /* not currently saved in output format */
token = pg_strtok(&length); /* eat :relation */
token = pg_strtok(&length); /* get schemaname */
local_node->schemaname = nullable_string(token, length);
token = pg_strtok(&length); /* eat "." */
token = pg_strtok(&length); /* get relname */
local_node->relname = debackslash(token, length);
local_node->relname = nullable_string(token, length);
token = pg_strtok(&length); /* eat :inhopt */
token = pg_strtok(&length); /* get inhopt */
local_node->inhOpt = (InhOption) atoi(token);
token = pg_strtok(&length); /* eat :istemp */
token = pg_strtok(&length); /* get istemp */
local_node->istemp = strtobool(token);
token = pg_strtok(&length); /* eat :alias */
local_node->alias = nodeRead(true); /* now read it */
return local_node;
}
static ColumnRef *
_readColumnRef(void)
{
ColumnRef *local_node;
char *token;
int length;
local_node = makeNode(ColumnRef);
token = pg_strtok(&length); /* eat :fields */
local_node->fields = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :indirection */
local_node->indirection = nodeRead(true); /* now read it */
return local_node;
}
static ExprFieldSelect *
_readExprFieldSelect(void)
{
ExprFieldSelect *local_node;
char *token;
int length;
local_node = makeNode(ExprFieldSelect);
token = pg_strtok(&length); /* eat :arg */
local_node->arg = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :fields */
local_node->fields = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :indirection */
local_node->indirection = nodeRead(true); /* now read it */
return local_node;
}
static Alias *
_readAlias(void)
{
Alias *local_node;
char *token;
int length;
local_node = makeNode(Alias);
token = pg_strtok(&length); /* eat :aliasname */
token = pg_strtok(&length); /* get aliasname */
local_node->aliasname = debackslash(token, length);
token = pg_strtok(&length); /* eat :attrs */
local_node->attrs = nodeRead(true); /* now read it */
token = pg_strtok(&length); /* eat :colnames */
local_node->colnames = nodeRead(true); /* now read it */
return local_node;
}
......@@ -1994,8 +2066,6 @@ parsePlanString(void)
return_value = _readArrayRef();
else if (length == 3 && strncmp(token, "VAR", length) == 0)
return_value = _readVar();
else if (length == 4 && strncmp(token, "ATTR", length) == 0)
return_value = _readAttr();
else if (length == 5 && strncmp(token, "CONST", length) == 0)
return_value = _readConst();
else if (length == 4 && strncmp(token, "FUNC", length) == 0)
......@@ -2006,6 +2076,14 @@ parsePlanString(void)
return_value = _readParam();
else if (length == 11 && strncmp(token, "TARGETENTRY", length) == 0)
return_value = _readTargetEntry();
else if (length == 8 && strncmp(token, "RANGEVAR", length) == 0)
return_value = _readRangeVar();
else if (length == 9 && strncmp(token, "COLUMNREF", length) == 0)
return_value = _readColumnRef();
else if (length == 15 && strncmp(token, "EXPRFIELDSELECT", length) == 0)
return_value = _readExprFieldSelect();
else if (length == 5 && strncmp(token, "ALIAS", length) == 0)
return_value = _readAlias();
else if (length == 3 && strncmp(token, "RTE", length) == 0)
return_value = _readRangeTblEntry();
else if (length == 4 && strncmp(token, "PATH", length) == 0)
......@@ -2032,6 +2110,8 @@ parsePlanString(void)
return_value = _readIter();
else if (length == 5 && strncmp(token, "QUERY", length) == 0)
return_value = _readQuery();
else if (length == 6 && strncmp(token, "NOTIFY", length) == 0)
return_value = _readNotifyStmt();
else if (length == 10 && strncmp(token, "SORTCLAUSE", length) == 0)
return_value = _readSortClause();
else if (length == 11 && strncmp(token, "GROUPCLAUSE", length) == 0)
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.94 2002/03/12 00:51:50 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.95 2002/03/21 16:00:44 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -687,7 +687,7 @@ check_subplans_for_ungrouped_vars_walker(Node *node,
rte = rt_fetch(var->varno, context->query->rtable);
attname = get_rte_attribute_name(rte, var->varattno);
elog(ERROR, "Sub-SELECT uses un-GROUPed attribute %s.%s from outer query",
rte->eref->relname, attname);
rte->eref->aliasname, attname);
}
}
}
......@@ -1670,7 +1670,6 @@ expression_tree_walker(Node *node,
return false;
switch (nodeTag(node))
{
case T_Ident:
case T_Const:
case T_Var:
case T_Param:
......@@ -1963,7 +1962,6 @@ expression_tree_mutator(Node *node,
return NULL;
switch (nodeTag(node))
{
case T_Ident:
case T_Const:
case T_Var:
case T_Param:
......
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.46 2001/10/25 05:49:36 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.47 2002/03/21 16:00:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -116,7 +116,7 @@ check_ungrouped_columns_walker(Node *node,
rte = rt_fetch(var->varno, context->pstate->p_rtable);
attname = get_rte_attribute_name(rte, var->varattno);
elog(ERROR, "Attribute %s.%s must be GROUPed or used in an aggregate function",
rte->eref->relname, attname);
rte->eref->aliasname, attname);
}
/* Otherwise, recurse. */
return expression_tree_walker(node, check_ungrouped_columns_walker,
......@@ -188,8 +188,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry, Node *qual)
Aggref *
ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
List *args, bool agg_star, bool agg_distinct,
int precedence)
List *args, bool agg_star, bool agg_distinct)
{
HeapTuple aggtuple;
Form_pg_aggregate aggform;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.84 2002/03/12 00:51:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.85 2002/03/21 16:00:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -285,7 +285,7 @@ transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
* transformJoinOnClause() does. Just invoke transformExpr() to fix
* up the operators, and we're done.
*/
result = transformExpr(pstate, result, EXPR_COLUMN_FIRST);
result = transformExpr(pstate, result);
/*
* We expect the result to yield bool directly, otherwise complain. We
......@@ -326,7 +326,7 @@ transformJoinOnClause(ParseState *pstate, JoinExpr *j,
pstate->p_namespace = makeList2(j->larg, j->rarg);
/* This part is just like transformWhereClause() */
result = transformExpr(pstate, j->quals, EXPR_COLUMN_FIRST);
result = transformExpr(pstate, j->quals);
if (!coerce_to_boolean(pstate, &result))
elog(ERROR, "JOIN/ON clause must return type boolean, not type %s",
......@@ -350,7 +350,7 @@ transformJoinOnClause(ParseState *pstate, JoinExpr *j,
if (!intMember(varno, containedRels))
{
elog(ERROR, "JOIN/ON clause refers to \"%s\", which is not part of JOIN",
rt_fetch(varno, pstate->p_rtable)->eref->relname);
rt_fetch(varno, pstate->p_rtable)->eref->aliasname);
}
}
freeList(clause_varnos);
......@@ -375,7 +375,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->name,
rte = addRangeTableEntry(pstate, relname, r->alias,
interpretInhOption(r->inhOpt), true);
/*
......@@ -408,7 +408,7 @@ transformRangeSubselect(ParseState *pstate, RangeSubselect *r)
* relax this, we'd have to be prepared to gin up a unique alias for
* an unlabeled subselect.
*/
if (r->name == NULL)
if (r->alias == NULL)
elog(ERROR, "sub-select in FROM must have an alias");
/*
......@@ -444,7 +444,7 @@ transformRangeSubselect(ParseState *pstate, RangeSubselect *r)
/*
* OK, build an RTE for the subquery.
*/
rte = addRangeTableEntryForSubquery(pstate, query, r->name, true);
rte = addRangeTableEntryForSubquery(pstate, query, r->alias, true);
/*
* We create a RangeTblRef, but we do not add it to the joinlist or
......@@ -748,11 +748,11 @@ transformFromClauseItem(ParseState *pstate, Node *n, List **containedRels)
*/
if (j->alias)
{
if (j->alias->attrs != NIL)
if (j->alias->colnames != NIL)
{
if (length(j->alias->attrs) > length(res_colnames))
if (length(j->alias->colnames) > length(res_colnames))
elog(ERROR, "Column alias list for \"%s\" has too many entries",
j->alias->relname);
j->alias->aliasname);
}
}
......@@ -791,7 +791,7 @@ transformWhereClause(ParseState *pstate, Node *clause)
if (clause == NULL)
return NULL;
qual = transformExpr(pstate, clause, EXPR_COLUMN_FIRST);
qual = transformExpr(pstate, clause);
if (!coerce_to_boolean(pstate, &qual))
elog(ERROR, "WHERE clause must return type boolean, not type %s",
......@@ -858,9 +858,11 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
* an expression.
*----------
*/
if (IsA(node, Ident) &&((Ident *) node)->indirection == NIL)
if (IsA(node, ColumnRef) &&
length(((ColumnRef *) node)->fields) == 1 &&
((ColumnRef *) node)->indirection == NIL)
{
char *name = ((Ident *) node)->name;
char *name = strVal(lfirst(((ColumnRef *) node)->fields));
if (clause == GROUP_CLAUSE)
{
......@@ -934,7 +936,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List *tlist, int clause)
* willing to match a resjunk target here, though the above cases must
* ignore resjunk targets.
*/
expr = transformExpr(pstate, node, EXPR_COLUMN_FIRST);
expr = transformExpr(pstate, node);
foreach(tl, tlist)
{
......
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.59 2002/03/12 00:51:55 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.60 2002/03/21 16:01:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -285,7 +285,7 @@ transformArraySubscripts(ParseState *pstate,
{
if (ai->lidx)
{
subexpr = transformExpr(pstate, ai->lidx, EXPR_COLUMN_FIRST);
subexpr = transformExpr(pstate, ai->lidx);
/* If it's not int4 already, try to coerce */
subexpr = CoerceTargetExpr(pstate, subexpr, exprType(subexpr),
INT4OID, -1);
......@@ -305,7 +305,7 @@ transformArraySubscripts(ParseState *pstate,
}
lowerIndexpr = lappend(lowerIndexpr, subexpr);
}
subexpr = transformExpr(pstate, ai->uidx, EXPR_COLUMN_FIRST);
subexpr = transformExpr(pstate, ai->uidx);
/* If it's not int4 already, try to coerce */
subexpr = CoerceTargetExpr(pstate, subexpr, exprType(subexpr),
INT4OID, -1);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.63 2002/03/12 00:51:56 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.64 2002/03/21 16:01:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -104,7 +104,7 @@ scanNameSpaceForRefname(ParseState *pstate, Node *nsnode,
int varno = ((RangeTblRef *) nsnode)->rtindex;
RangeTblEntry *rte = rt_fetch(varno, pstate->p_rtable);
if (strcmp(rte->eref->relname, refname) == 0)
if (strcmp(rte->eref->aliasname, refname) == 0)
result = (Node *) rte;
}
else if (IsA(nsnode, JoinExpr))
......@@ -113,7 +113,7 @@ scanNameSpaceForRefname(ParseState *pstate, Node *nsnode,
if (j->alias)
{
if (strcmp(j->alias->relname, refname) == 0)
if (strcmp(j->alias->aliasname, refname) == 0)
return (Node *) j; /* matched a join alias */
/*
......@@ -175,7 +175,7 @@ checkNameSpaceConflicts(ParseState *pstate, Node *namespace1,
int varno = ((RangeTblRef *) namespace1)->rtindex;
RangeTblEntry *rte = rt_fetch(varno, pstate->p_rtable);
scanNameSpaceForConflict(pstate, namespace2, rte->eref->relname);
scanNameSpaceForConflict(pstate, namespace2, rte->eref->aliasname);
}
else if (IsA(namespace1, JoinExpr))
{
......@@ -183,7 +183,7 @@ checkNameSpaceConflicts(ParseState *pstate, Node *namespace1,
if (j->alias)
{
scanNameSpaceForConflict(pstate, namespace2, j->alias->relname);
scanNameSpaceForConflict(pstate, namespace2, j->alias->aliasname);
/*
* Tables within an aliased join are invisible from outside
......@@ -268,7 +268,7 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
* Scan the user column names (or aliases) for a match. Complain if
* multiple matches.
*/
foreach(c, rte->eref->attrs)
foreach(c, rte->eref->colnames)
{
attnum++;
if (strcmp(strVal(lfirst(c)), colname) == 0)
......@@ -420,15 +420,15 @@ qualifiedNameToVar(ParseState *pstate, char *refname, char *colname,
RangeTblEntry *
addRangeTableEntry(ParseState *pstate,
char *relname,
Attr *alias,
Alias *alias,
bool inh,
bool inFromCl)
{
RangeTblEntry *rte = makeNode(RangeTblEntry);
char *refname = alias ? alias->relname : relname;
char *refname = alias ? alias->aliasname : relname;
LOCKMODE lockmode;
Relation rel;
Attr *eref;
Alias *eref;
int maxattrs;
int numaliases;
int varattno;
......@@ -447,8 +447,8 @@ addRangeTableEntry(ParseState *pstate,
rel = heap_openr(relname, lockmode);
rte->relid = RelationGetRelid(rel);
eref = alias ? (Attr *) copyObject(alias) : makeAttr(refname, NULL);
numaliases = length(eref->attrs);
eref = alias ? (Alias *) copyObject(alias) : makeAlias(refname, NIL);
numaliases = length(eref->colnames);
/*
* Since the rel is open anyway, let's check that the number of column
......@@ -459,13 +459,13 @@ addRangeTableEntry(ParseState *pstate,
elog(ERROR, "Table \"%s\" has %d columns available but %d columns specified",
refname, maxattrs, numaliases);
/* fill in any unspecified alias columns */
/* 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->attrs = lappend(eref->attrs, makeString(attrname));
eref->colnames = lappend(eref->colnames, makeString(attrname));
}
rte->eref = eref;
......@@ -512,12 +512,12 @@ addRangeTableEntry(ParseState *pstate,
RangeTblEntry *
addRangeTableEntryForSubquery(ParseState *pstate,
Query *subquery,
Attr *alias,
Alias *alias,
bool inFromCl)
{
RangeTblEntry *rte = makeNode(RangeTblEntry);
char *refname = alias->relname;
Attr *eref;
char *refname = alias->aliasname;
Alias *eref;
int numaliases;
int varattno;
List *tlistitem;
......@@ -529,7 +529,7 @@ addRangeTableEntryForSubquery(ParseState *pstate,
rte->alias = alias;
eref = copyObject(alias);
numaliases = length(eref->attrs);
numaliases = length(eref->colnames);
/* fill in any unspecified alias columns */
varattno = 0;
......@@ -546,7 +546,7 @@ addRangeTableEntryForSubquery(ParseState *pstate,
char *attrname;
attrname = pstrdup(te->resdom->resname);
eref->attrs = lappend(eref->attrs, makeString(attrname));
eref->colnames = lappend(eref->colnames, makeString(attrname));
}
}
if (varattno < numaliases)
......@@ -594,11 +594,11 @@ addRangeTableEntryForJoin(ParseState *pstate,
List *coltypmods,
List *leftcols,
List *rightcols,
Attr *alias,
Alias *alias,
bool inFromCl)
{
RangeTblEntry *rte = makeNode(RangeTblEntry);
Attr *eref;
Alias *eref;
int numaliases;
rte->rtekind = RTE_JOIN;
......@@ -612,15 +612,15 @@ addRangeTableEntryForJoin(ParseState *pstate,
rte->joinrightcols = rightcols;
rte->alias = alias;
eref = alias ? (Attr *) copyObject(alias) : makeAttr("unnamed_join", NULL);
numaliases = length(eref->attrs);
eref = alias ? (Alias *) copyObject(alias) : makeAlias("unnamed_join", NIL);
numaliases = length(eref->colnames);
/* fill in any unspecified alias columns */
if (numaliases < length(colnames))
{
while (numaliases-- > 0)
colnames = lnext(colnames);
eref->attrs = nconc(eref->attrs, colnames);
eref->colnames = nconc(eref->colnames, colnames);
}
rte->eref = eref;
......@@ -759,7 +759,7 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
rel = heap_openr(rte->relname, AccessShareLock);
maxattrs = RelationGetNumberOfAttributes(rel);
numaliases = length(rte->eref->attrs);
numaliases = length(rte->eref->colnames);
for (varattno = 0; varattno < maxattrs; varattno++)
{
......@@ -775,7 +775,7 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
char *label;
if (varattno < numaliases)
label = strVal(nth(varattno, rte->eref->attrs));
label = strVal(nth(varattno, rte->eref->colnames));
else
label = NameStr(attr->attname);
*colnames = lappend(*colnames, makeString(pstrdup(label)));
......@@ -798,7 +798,7 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
else if (rte->rtekind == RTE_SUBQUERY)
{
/* Subquery RTE */
List *aliasp = rte->eref->attrs;
List *aliasp = rte->eref->colnames;
List *tlistitem;
varattno = 0;
......@@ -836,7 +836,7 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
else if (rte->rtekind == RTE_JOIN)
{
/* Join RTE */
List *aliasp = rte->eref->attrs;
List *aliasp = rte->eref->colnames;
List *coltypes = rte->joincoltypes;
List *coltypmods = rte->joincoltypmods;
......@@ -936,8 +936,8 @@ get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
* If there is an alias, use it. (This path should always be taken
* for non-relation RTEs.)
*/
if (attnum > 0 && attnum <= length(rte->eref->attrs))
return strVal(nth(attnum - 1, rte->eref->attrs));
if (attnum > 0 && attnum <= length(rte->eref->colnames))
return strVal(nth(attnum - 1, rte->eref->colnames));
/*
* Can get here for a system attribute (which never has an alias), or
......@@ -946,7 +946,7 @@ get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
*/
if (rte->rtekind != RTE_RELATION)
elog(ERROR, "Invalid attnum %d for rangetable entry %s",
attnum, rte->eref->relname);
attnum, rte->eref->aliasname);
/*
* Use the real name of the table's column
......@@ -1002,7 +1002,7 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
}
/* falling off end of list shouldn't happen... */
elog(ERROR, "Subquery %s does not have attribute %d",
rte->eref->relname, attnum);
rte->eref->aliasname, attnum);
}
else if (rte->rtekind == RTE_JOIN)
{
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.63 2001/08/12 21:35:18 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.64 2002/03/21 16:01:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -110,63 +110,17 @@ InsertRule(char *rulname,
return rewriteObjectId;
}
/*
* for now, event_object must be a single attribute
*/
static void
ValidateRule(int event_type,
char *eobj_string,
char *eslot_string,
Node *event_qual,
List **action,
int is_instead,
Oid event_attype)
{
if (((event_type == CMD_INSERT) || (event_type == CMD_DELETE)) &&
eslot_string)
{
elog(ERROR,
"rules not allowed for insert or delete events to an attribute");
}
#ifdef NOT_USED
/*---------
* on retrieve to class.attribute do instead nothing is converted to
* 'on retrieve to class.attribute do instead:
*
* retrieve (attribute = NULL)'
*
* this is also a terrible hack that works well -- glass
*---------
*/
if (is_instead && !*action && eslot_string && event_type == CMD_SELECT)
{
char *temp_buffer = (char *) palloc(strlen(template) + 80);
sprintf(temp_buffer, template, event_attype,
get_typlen(event_attype), eslot_string,
event_attype);
*action = (List *) stringToNode(temp_buffer);
pfree(temp_buffer);
}
#endif
}
void
DefineQueryRewrite(RuleStmt *stmt)
{
CmdType event_type = stmt->event;
Attr *event_obj = stmt->object;
RangeVar *event_obj = stmt->relation;
Node *event_qual = stmt->whereClause;
CmdType event_type = stmt->event;
bool is_instead = stmt->instead;
List *action = stmt->actions;
Relation event_relation;
Oid ev_relid;
Oid ruleId;
char *eslot_string = NULL;
int event_attno;
Oid event_attype;
char *actionP,
......@@ -186,23 +140,6 @@ DefineQueryRewrite(RuleStmt *stmt)
event_relation = heap_openr(event_obj->relname, AccessExclusiveLock);
ev_relid = RelationGetRelid(event_relation);
/*
* The current rewrite handler is known to work on relation level
* rules only. And for SELECT events, it expects one non-nothing
* action that is instead and returns exactly a tuple of the rewritten
* relation. This restricts SELECT rules to views.
*
* Jan
*/
if (event_obj->attrs)
elog(ERROR, "attribute level rules currently not supported");
/*
* eslot_string = strVal(lfirst(event_obj->attrs));
*/
else
eslot_string = NULL;
/*
* No rule actions that modify OLD or NEW
*/
......@@ -358,21 +295,8 @@ DefineQueryRewrite(RuleStmt *stmt)
/*
* This rule is allowed - prepare to install it.
*/
if (eslot_string == NULL)
{
event_attno = -1;
event_attype = InvalidOid;
}
else
{
event_attno = attnameAttNum(event_relation, eslot_string);
event_attype = attnumTypeId(event_relation, event_attno);
}
/* fix bug about instead nothing */
ValidateRule(event_type, event_obj->relname,
eslot_string, event_qual, &action,
is_instead, event_attype);
event_attno = -1;
event_attype = InvalidOid;
/*
* We want the rule's table references to be checked as though by the
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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.107 2002/03/20 19:44:48 tgl Exp $
* $Id: catversion.h,v 1.108 2002/03/21 16:01:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200203191
#define CATALOG_VERSION_NO 200203211
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment