OSDN Git Service

First phase of SCHEMA changes, concentrating on fixing the grammar and
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 21 Mar 2002 16:02:16 +0000 (16:02 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 21 Mar 2002 16:02:16 +0000 (16:02 +0000)
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.

52 files changed:
doc/src/sgml/xfunc.sgml
src/backend/catalog/aclchk.c
src/backend/catalog/heap.c
src/backend/commands/command.c
src/backend/commands/creatinh.c
src/backend/commands/explain.c
src/backend/commands/sequence.c
src/backend/commands/trigger.c
src/backend/commands/vacuum.c
src/backend/commands/view.c
src/backend/executor/execMain.c
src/backend/executor/spi.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/makefuncs.c
src/backend/nodes/nodeFuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/print.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/util/clauses.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/parse_agg.c
src/backend/parser/parse_clause.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_func.c
src/backend/parser/parse_node.c
src/backend/parser/parse_relation.c
src/backend/parser/parse_target.c
src/backend/rewrite/rewriteDefine.c
src/backend/rewrite/rewriteManip.c
src/backend/tcop/postgres.c
src/backend/tcop/pquery.c
src/backend/tcop/utility.c
src/backend/utils/adt/ruleutils.c
src/include/catalog/catversion.h
src/include/commands/command.h
src/include/nodes/makefuncs.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/nodes/primnodes.h
src/include/parser/analyze.h
src/include/parser/parse_agg.h
src/include/parser/parse_expr.h
src/include/parser/parse_func.h
src/include/parser/parse_relation.h
src/test/regress/expected/alter_table.out
src/test/regress/expected/errors.out
src/test/regress/expected/rules.out
src/test/regress/expected/union.out
src/test/regress/input/misc.source
src/test/regress/output/misc.source

index 73c0287..262c1e2 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$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,12 +329,12 @@ 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>
@@ -341,16 +342,34 @@ SELECT name(new_emp());
 ------
  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:
 --  SELECT EMP.name AS youngster FROM EMP WHERE EMP.age &lt; 30
@@ -368,19 +387,6 @@ SELECT name(EMP) AS youngster
     </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
      result to it:
index 2bdacbd..2244827 100644 (file)
@@ -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;
index e7bb128..629ffe7 100644 (file)
@@ -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.
index c32be8b..5821e1d 100644 (file)
@@ -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);
+}
index c9dee0c..04854a2 100644 (file)
@@ -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;
index e230ba5..95263a5 100644 (file)
@@ -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:
index 0e57d90..e9df639 100644 (file)
@@ -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 */
index e25b83b..5bef86e 100644 (file)
@@ -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);
 
index 6b94db1..836091c 100644 (file)
@@ -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);
index 9d1254a..74a3ac2 100644 (file)
@@ -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;
index 35a5c2d..9b8e358 100644 (file)
@@ -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);
index c8c65b1..f09f907 100644 (file)
@@ -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;
index ebdc7cf..fb68866 100644 (file)
@@ -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.171 2002/03/20 19:43:58 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.172 2002/03/21 16:00:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -733,18 +733,6 @@ _copyVar(Var *from)
        return newnode;
 }
 
-static Attr *
-_copyAttr(Attr *from)
-{
-       Attr       *newnode = makeNode(Attr);
-
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
-       Node_Copy(from, newnode, attrs);
-
-       return newnode;
-}
-
 /* ----------------
  *             _copyOper
  * ----------------
@@ -1515,8 +1503,7 @@ _copyFkConstraint(FkConstraint *from)
 
        if (from->constr_name)
                newnode->constr_name = pstrdup(from->constr_name);
-       if (from->pktable_name)
-               newnode->pktable_name = pstrdup(from->pktable_name);
+       Node_Copy(from, newnode, pktable);
        Node_Copy(from, newnode, fk_attrs);
        Node_Copy(from, newnode, pk_attrs);
        if (from->match_type)
@@ -1553,38 +1540,46 @@ _copyAExpr(A_Expr *from)
        return newnode;
 }
 
-static A_Const *
-_copyAConst(A_Const *from)
+static ColumnRef *
+_copyColumnRef(ColumnRef *from)
 {
-       A_Const    *newnode = makeNode(A_Const);
+       ColumnRef          *newnode = makeNode(ColumnRef);
 
-       newnode->val = *((Value *) (copyObject(&(from->val))));
-       Node_Copy(from, newnode, typename);
+       Node_Copy(from, newnode, fields);
+       Node_Copy(from, newnode, indirection);
 
        return newnode;
 }
 
-static ParamNo *
-_copyParamNo(ParamNo *from)
+static ParamRef *
+_copyParamRef(ParamRef *from)
 {
-       ParamNo    *newnode = makeNode(ParamNo);
+       ParamRef    *newnode = makeNode(ParamRef);
 
        newnode->number = from->number;
-       Node_Copy(from, newnode, typename);
+       Node_Copy(from, newnode, fields);
        Node_Copy(from, newnode, indirection);
 
        return newnode;
 }
 
+static A_Const *
+_copyAConst(A_Const *from)
+{
+       A_Const    *newnode = makeNode(A_Const);
+
+       newnode->val = *((Value *) (copyObject(&(from->val))));
+       Node_Copy(from, newnode, typename);
+
+       return newnode;
+}
+
 static Ident *
 _copyIdent(Ident *from)
 {
        Ident      *newnode = makeNode(Ident);
 
-       if (from->name)
-               newnode->name = pstrdup(from->name);
-       Node_Copy(from, newnode, indirection);
-       newnode->isRel = from->isRel;
+       newnode->name = pstrdup(from->name);
 
        return newnode;
 }
@@ -1614,6 +1609,18 @@ _copyAIndices(A_Indices *from)
        return newnode;
 }
 
+static ExprFieldSelect *
+_copyExprFieldSelect(ExprFieldSelect *from)
+{
+       ExprFieldSelect    *newnode = makeNode(ExprFieldSelect);
+
+       Node_Copy(from, newnode, arg);
+       Node_Copy(from, newnode, fields);
+       Node_Copy(from, newnode, indirection);
+
+       return newnode;
+}
+
 static ResTarget *
 _copyResTarget(ResTarget *from)
 {
@@ -1654,15 +1661,32 @@ _copySortGroupBy(SortGroupBy *from)
        return newnode;
 }
 
+static Alias *
+_copyAlias(Alias *from)
+{
+       Alias      *newnode = makeNode(Alias);
+
+       if (from->aliasname)
+               newnode->aliasname = pstrdup(from->aliasname);
+       Node_Copy(from, newnode, colnames);
+
+       return newnode;
+}
+
 static RangeVar *
 _copyRangeVar(RangeVar *from)
 {
        RangeVar   *newnode = makeNode(RangeVar);
 
+       if (from->catalogname)
+               newnode->catalogname = pstrdup(from->catalogname);
+       if (from->schemaname)
+               newnode->schemaname = pstrdup(from->schemaname);
        if (from->relname)
                newnode->relname = pstrdup(from->relname);
        newnode->inhOpt = from->inhOpt;
-       Node_Copy(from, newnode, name);
+       newnode->istemp = from->istemp;
+       Node_Copy(from, newnode, alias);
 
        return newnode;
 }
@@ -1673,7 +1697,7 @@ _copyRangeSubselect(RangeSubselect *from)
        RangeSubselect *newnode = makeNode(RangeSubselect);
 
        Node_Copy(from, newnode, subquery);
-       Node_Copy(from, newnode, name);
+       Node_Copy(from, newnode, alias);
 
        return newnode;
 }
@@ -1756,11 +1780,9 @@ _copyQuery(Query *from)
        newnode->commandType = from->commandType;
        Node_Copy(from, newnode, utilityStmt);
        newnode->resultRelation = from->resultRelation;
-       if (from->into)
-               newnode->into = pstrdup(from->into);
+       Node_Copy(from, newnode, into);
        newnode->isPortal = from->isPortal;
        newnode->isBinary = from->isBinary;
-       newnode->isTemp = from->isTemp;
        newnode->hasAggs = from->hasAggs;
        newnode->hasSubLinks = from->hasSubLinks;
        newnode->originalQuery = from->originalQuery;
@@ -1798,8 +1820,7 @@ _copyInsertStmt(InsertStmt *from)
 {
        InsertStmt *newnode = makeNode(InsertStmt);
 
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
        Node_Copy(from, newnode, cols);
        Node_Copy(from, newnode, targetList);
        Node_Copy(from, newnode, selectStmt);
@@ -1812,10 +1833,8 @@ _copyDeleteStmt(DeleteStmt *from)
 {
        DeleteStmt *newnode = makeNode(DeleteStmt);
 
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
        Node_Copy(from, newnode, whereClause);
-       newnode->inhOpt = from->inhOpt;
 
        return newnode;
 }
@@ -1825,12 +1844,10 @@ _copyUpdateStmt(UpdateStmt *from)
 {
        UpdateStmt *newnode = makeNode(UpdateStmt);
 
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
        Node_Copy(from, newnode, targetList);
        Node_Copy(from, newnode, whereClause);
        Node_Copy(from, newnode, fromClause);
-       newnode->inhOpt = from->inhOpt;
 
        return newnode;
 }
@@ -1841,9 +1858,7 @@ _copySelectStmt(SelectStmt *from)
        SelectStmt *newnode = makeNode(SelectStmt);
 
        Node_Copy(from, newnode, distinctClause);
-       if (from->into)
-               newnode->into = pstrdup(from->into);
-       newnode->istemp = from->istemp;
+       Node_Copy(from, newnode, into);
        Node_Copy(from, newnode, intoColNames);
        Node_Copy(from, newnode, targetList);
        Node_Copy(from, newnode, fromClause);
@@ -1885,9 +1900,7 @@ _copyAlterTableStmt(AlterTableStmt *from)
        AlterTableStmt *newnode = makeNode(AlterTableStmt);
 
        newnode->subtype = from->subtype;
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
-       newnode->inhOpt = from->inhOpt;
+       Node_Copy(from, newnode, relation);
        if (from->name)
                newnode->name = pstrdup(from->name);
        Node_Copy(from, newnode, def);
@@ -1951,8 +1964,7 @@ _copyClusterStmt(ClusterStmt *from)
 {
        ClusterStmt *newnode = makeNode(ClusterStmt);
 
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
        if (from->indexname)
                newnode->indexname = pstrdup(from->indexname);
 
@@ -1965,8 +1977,7 @@ _copyCopyStmt(CopyStmt *from)
        CopyStmt   *newnode = makeNode(CopyStmt);
 
        newnode->binary = from->binary;
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
        newnode->oids = from->oids;
        newnode->direction = from->direction;
        if (from->filename)
@@ -1984,11 +1995,10 @@ _copyCreateStmt(CreateStmt *from)
 {
        CreateStmt *newnode = makeNode(CreateStmt);
 
-       newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
        Node_Copy(from, newnode, tableElts);
-       Node_Copy(from, newnode, inhRelnames);
+       Node_Copy(from, newnode, inhRelations);
        Node_Copy(from, newnode, constraints);
-       newnode->istemp = from->istemp;
        newnode->hasoids = from->hasoids;
 
        return newnode;
@@ -2024,7 +2034,7 @@ _copyDropStmt(DropStmt *from)
 {
        DropStmt   *newnode = makeNode(DropStmt);
 
-       Node_Copy(from, newnode, names);
+       Node_Copy(from, newnode, objects);
        newnode->removeType = from->removeType;
        newnode->behavior = from->behavior;
 
@@ -2036,7 +2046,7 @@ _copyTruncateStmt(TruncateStmt *from)
 {
        TruncateStmt *newnode = makeNode(TruncateStmt);
 
-       newnode->relName = pstrdup(from->relName);
+       Node_Copy(from, newnode, relation);
 
        return newnode;
 }
@@ -2047,6 +2057,8 @@ _copyCommentStmt(CommentStmt *from)
        CommentStmt *newnode = makeNode(CommentStmt);
 
        newnode->objtype = from->objtype;
+       if (from->objschema)
+               newnode->objschema = pstrdup(from->objschema);
        newnode->objname = pstrdup(from->objname);
        if (from->objproperty)
                newnode->objproperty = pstrdup(from->objproperty);
@@ -2075,7 +2087,7 @@ _copyIndexStmt(IndexStmt *from)
        IndexStmt  *newnode = makeNode(IndexStmt);
 
        newnode->idxname = pstrdup(from->idxname);
-       newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
        newnode->accessMethod = pstrdup(from->accessMethod);
        Node_Copy(from, newnode, indexParams);
        Node_Copy(from, newnode, whereClause);
@@ -2140,8 +2152,7 @@ _copyRenameStmt(RenameStmt *from)
 {
        RenameStmt *newnode = makeNode(RenameStmt);
 
-       newnode->relname = pstrdup(from->relname);
-       newnode->inhOpt = from->inhOpt;
+       Node_Copy(from, newnode, relation);
        if (from->column)
                newnode->column = pstrdup(from->column);
        if (from->newname)
@@ -2155,10 +2166,10 @@ _copyRuleStmt(RuleStmt *from)
 {
        RuleStmt   *newnode = makeNode(RuleStmt);
 
+       Node_Copy(from, newnode, relation);
        newnode->rulename = pstrdup(from->rulename);
        Node_Copy(from, newnode, whereClause);
        newnode->event = from->event;
-       Node_Copy(from, newnode, object);
        newnode->instead = from->instead;
        Node_Copy(from, newnode, actions);
 
@@ -2170,8 +2181,7 @@ _copyNotifyStmt(NotifyStmt *from)
 {
        NotifyStmt *newnode = makeNode(NotifyStmt);
 
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
 
        return newnode;
 }
@@ -2181,8 +2191,7 @@ _copyListenStmt(ListenStmt *from)
 {
        ListenStmt *newnode = makeNode(ListenStmt);
 
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
 
        return newnode;
 }
@@ -2192,8 +2201,7 @@ _copyUnlistenStmt(UnlistenStmt *from)
 {
        UnlistenStmt *newnode = makeNode(UnlistenStmt);
 
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
 
        return newnode;
 }
@@ -2213,8 +2221,7 @@ _copyViewStmt(ViewStmt *from)
 {
        ViewStmt   *newnode = makeNode(ViewStmt);
 
-       if (from->viewname)
-               newnode->viewname = pstrdup(from->viewname);
+       Node_Copy(from, newnode, view);
        Node_Copy(from, newnode, aliases);
        Node_Copy(from, newnode, query);
 
@@ -2298,8 +2305,7 @@ _copyVacuumStmt(VacuumStmt *from)
        newnode->analyze = from->analyze;
        newnode->freeze = from->freeze;
        newnode->verbose = from->verbose;
-       if (from->vacrel)
-               newnode->vacrel = pstrdup(from->vacrel);
+       Node_Copy(from, newnode, relation);
        Node_Copy(from, newnode, va_cols);
 
        return newnode;
@@ -2322,8 +2328,7 @@ _copyCreateSeqStmt(CreateSeqStmt *from)
 {
        CreateSeqStmt *newnode = makeNode(CreateSeqStmt);
 
-       if (from->seqname)
-               newnode->seqname = pstrdup(from->seqname);
+       Node_Copy(from, newnode, sequence);
        Node_Copy(from, newnode, options);
 
        return newnode;
@@ -2370,8 +2375,7 @@ _copyCreateTrigStmt(CreateTrigStmt *from)
 
        if (from->trigname)
                newnode->trigname = pstrdup(from->trigname);
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
        if (from->funcname)
                newnode->funcname = pstrdup(from->funcname);
        Node_Copy(from, newnode, args);
@@ -2389,8 +2393,7 @@ _copyCreateTrigStmt(CreateTrigStmt *from)
        newnode->isconstraint = from->isconstraint;
        newnode->deferrable = from->deferrable;
        newnode->initdeferred = from->initdeferred;
-       if (from->constrrelname)
-               newnode->constrrelname = pstrdup(from->constrrelname);
+       Node_Copy(from, newnode, constrrel);
 
        return newnode;
 }
@@ -2402,8 +2405,7 @@ _copyDropTrigStmt(DropTrigStmt *from)
 
        if (from->trigname)
                newnode->trigname = pstrdup(from->trigname);
-       if (from->relname)
-               newnode->relname = pstrdup(from->relname);
+       Node_Copy(from, newnode, relation);
 
        return newnode;
 }
@@ -2488,7 +2490,7 @@ _copyLockStmt(LockStmt *from)
 {
        LockStmt   *newnode = makeNode(LockStmt);
 
-       Node_Copy(from, newnode, rellist);
+       Node_Copy(from, newnode, relations);
 
        newnode->mode = from->mode;
 
@@ -2548,6 +2550,7 @@ _copyReindexStmt(ReindexStmt *from)
        ReindexStmt *newnode = makeNode(ReindexStmt);
 
        newnode->reindexType = from->reindexType;
+       Node_Copy(from, newnode, relation);
        if (from->name)
                newnode->name = pstrdup(from->name);
        newnode->force = from->force;
@@ -2556,6 +2559,19 @@ _copyReindexStmt(ReindexStmt *from)
        return newnode;
 }
 
+static CreateSchemaStmt *
+_copyCreateSchemaStmt(CreateSchemaStmt *from)
+{
+       CreateSchemaStmt *newnode = makeNode(CreateSchemaStmt);
+
+       newnode->schemaname = pstrdup(from->schemaname);
+       if (from->authid)
+               newnode->authid = pstrdup(from->authid);
+       Node_Copy(from, newnode, schemaElts);
+
+       return newnode;
+}
+
 
 /* ****************************************************************
  *                                     pg_list.h copy functions
@@ -2888,6 +2904,9 @@ copyObject(void *from)
                case T_LoadStmt:
                        retval = _copyLoadStmt(from);
                        break;
+               case T_CreateDomainStmt:
+                       retval = _copyCreateDomainStmt(from);
+                       break;
                case T_CreatedbStmt:
                        retval = _copyCreatedbStmt(from);
                        break;
@@ -2960,19 +2979,22 @@ copyObject(void *from)
                case T_CheckPointStmt:
                        retval = (void *) makeNode(CheckPointStmt);
                        break;
+               case T_CreateSchemaStmt:
+                       retval = _copyCreateSchemaStmt(from);
+                       break;
 
                case T_A_Expr:
                        retval = _copyAExpr(from);
                        break;
-               case T_Attr:
-                       retval = _copyAttr(from);
+               case T_ColumnRef:
+                       retval = _copyColumnRef(from);
+                       break;
+               case T_ParamRef:
+                       retval = _copyParamRef(from);
                        break;
                case T_A_Const:
                        retval = _copyAConst(from);
                        break;
-               case T_ParamNo:
-                       retval = _copyParamNo(from);
-                       break;
                case T_Ident:
                        retval = _copyIdent(from);
                        break;
@@ -2982,6 +3004,9 @@ copyObject(void *from)
                case T_A_Indices:
                        retval = _copyAIndices(from);
                        break;
+               case T_ExprFieldSelect:
+                       retval = _copyExprFieldSelect(from);
+                       break;
                case T_ResTarget:
                        retval = _copyResTarget(from);
                        break;
@@ -2991,6 +3016,9 @@ copyObject(void *from)
                case T_SortGroupBy:
                        retval = _copySortGroupBy(from);
                        break;
+               case T_Alias:
+                       retval = _copyAlias(from);
+                       break;
                case T_RangeVar:
                        retval = _copyRangeVar(from);
                        break;
@@ -3045,9 +3073,6 @@ copyObject(void *from)
                case T_FuncWithArgs:
                        retval = _copyFuncWithArgs(from);
                        break;
-               case T_CreateDomainStmt:
-                       retval = _copyCreateDomainStmt(from);
-                       break;
 
                default:
                        elog(ERROR, "copyObject: don't know how to copy node type %d",
index c7ed489..9788fd2 100644 (file)
@@ -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.119 2002/03/20 19:44:01 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.120 2002/03/21 16:00:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -579,14 +579,12 @@ _equalQuery(Query *a, Query *b)
                return false;
        if (a->resultRelation != b->resultRelation)
                return false;
-       if (!equalstr(a->into, b->into))
+       if (!equal(a->into, b->into))
                return false;
        if (a->isPortal != b->isPortal)
                return false;
        if (a->isBinary != b->isBinary)
                return false;
-       if (a->isTemp != b->isTemp)
-               return false;
        if (a->hasAggs != b->hasAggs)
                return false;
        if (a->hasSubLinks != b->hasSubLinks)
@@ -629,7 +627,7 @@ _equalQuery(Query *a, Query *b)
 static bool
 _equalInsertStmt(InsertStmt *a, InsertStmt *b)
 {
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equal(a->cols, b->cols))
                return false;
@@ -644,12 +642,10 @@ _equalInsertStmt(InsertStmt *a, InsertStmt *b)
 static bool
 _equalDeleteStmt(DeleteStmt *a, DeleteStmt *b)
 {
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equal(a->whereClause, b->whereClause))
                return false;
-       if (a->inhOpt != b->inhOpt)
-               return false;
 
        return true;
 }
@@ -657,7 +653,7 @@ _equalDeleteStmt(DeleteStmt *a, DeleteStmt *b)
 static bool
 _equalUpdateStmt(UpdateStmt *a, UpdateStmt *b)
 {
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equal(a->targetList, b->targetList))
                return false;
@@ -665,8 +661,6 @@ _equalUpdateStmt(UpdateStmt *a, UpdateStmt *b)
                return false;
        if (!equal(a->fromClause, b->fromClause))
                return false;
-       if (a->inhOpt != b->inhOpt)
-               return false;
 
        return true;
 }
@@ -676,9 +670,7 @@ _equalSelectStmt(SelectStmt *a, SelectStmt *b)
 {
        if (!equal(a->distinctClause, b->distinctClause))
                return false;
-       if (!equalstr(a->into, b->into))
-               return false;
-       if (a->istemp != b->istemp)
+       if (!equal(a->into, b->into))
                return false;
        if (!equal(a->intoColNames, b->intoColNames))
                return false;
@@ -738,9 +730,7 @@ _equalAlterTableStmt(AlterTableStmt *a, AlterTableStmt *b)
 {
        if (a->subtype != b->subtype)
                return false;
-       if (!equalstr(a->relname, b->relname))
-               return false;
-       if (a->inhOpt != b->inhOpt)
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equalstr(a->name, b->name))
                return false;
@@ -795,7 +785,7 @@ _equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
 static bool
 _equalClusterStmt(ClusterStmt *a, ClusterStmt *b)
 {
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equalstr(a->indexname, b->indexname))
                return false;
@@ -808,7 +798,7 @@ _equalCopyStmt(CopyStmt *a, CopyStmt *b)
 {
        if (a->binary != b->binary)
                return false;
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
        if (a->oids != b->oids)
                return false;
@@ -827,16 +817,14 @@ _equalCopyStmt(CopyStmt *a, CopyStmt *b)
 static bool
 _equalCreateStmt(CreateStmt *a, CreateStmt *b)
 {
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equal(a->tableElts, b->tableElts))
                return false;
-       if (!equal(a->inhRelnames, b->inhRelnames))
+       if (!equal(a->inhRelations, b->inhRelations))
                return false;
        if (!equal(a->constraints, b->constraints))
                return false;
-       if (a->istemp != b->istemp)
-               return false;
        if (a->hasoids != b->hasoids)
                return false;
 
@@ -874,7 +862,7 @@ _equalDefineStmt(DefineStmt *a, DefineStmt *b)
 static bool
 _equalDropStmt(DropStmt *a, DropStmt *b)
 {
-       if (!equal(a->names, b->names))
+       if (!equal(a->objects, b->objects))
                return false;
        if (a->removeType != b->removeType)
                return false;
@@ -887,7 +875,7 @@ _equalDropStmt(DropStmt *a, DropStmt *b)
 static bool
 _equalTruncateStmt(TruncateStmt *a, TruncateStmt *b)
 {
-       if (!equalstr(a->relName, b->relName))
+       if (!equal(a->relation, b->relation))
                return false;
 
        return true;
@@ -900,6 +888,8 @@ _equalCommentStmt(CommentStmt *a, CommentStmt *b)
                return false;
        if (!equalstr(a->objname, b->objname))
                return false;
+       if (!equalstr(a->objschema, b->objschema))
+               return false;
        if (!equalstr(a->objproperty, b->objproperty))
                return false;
        if (!equal(a->objlist, b->objlist))
@@ -930,7 +920,7 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
 {
        if (!equalstr(a->idxname, b->idxname))
                return false;
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equalstr(a->accessMethod, b->accessMethod))
                return false;
@@ -1006,9 +996,7 @@ _equalRemoveOperStmt(RemoveOperStmt *a, RemoveOperStmt *b)
 static bool
 _equalRenameStmt(RenameStmt *a, RenameStmt *b)
 {
-       if (!equalstr(a->relname, b->relname))
-               return false;
-       if (a->inhOpt != b->inhOpt)
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equalstr(a->column, b->column))
                return false;
@@ -1021,14 +1009,14 @@ _equalRenameStmt(RenameStmt *a, RenameStmt *b)
 static bool
 _equalRuleStmt(RuleStmt *a, RuleStmt *b)
 {
+       if (!equal(a->relation, b->relation))
+               return false;
        if (!equalstr(a->rulename, b->rulename))
                return false;
        if (!equal(a->whereClause, b->whereClause))
                return false;
        if (a->event != b->event)
                return false;
-       if (!equal(a->object, b->object))
-               return false;
        if (a->instead != b->instead)
                return false;
        if (!equal(a->actions, b->actions))
@@ -1040,7 +1028,7 @@ _equalRuleStmt(RuleStmt *a, RuleStmt *b)
 static bool
 _equalNotifyStmt(NotifyStmt *a, NotifyStmt *b)
 {
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
 
        return true;
@@ -1049,7 +1037,7 @@ _equalNotifyStmt(NotifyStmt *a, NotifyStmt *b)
 static bool
 _equalListenStmt(ListenStmt *a, ListenStmt *b)
 {
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
 
        return true;
@@ -1058,7 +1046,7 @@ _equalListenStmt(ListenStmt *a, ListenStmt *b)
 static bool
 _equalUnlistenStmt(UnlistenStmt *a, UnlistenStmt *b)
 {
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
 
        return true;
@@ -1076,7 +1064,7 @@ _equalTransactionStmt(TransactionStmt *a, TransactionStmt *b)
 static bool
 _equalViewStmt(ViewStmt *a, ViewStmt *b)
 {
-       if (!equalstr(a->viewname, b->viewname))
+       if (!equal(a->view, b->view))
                return false;
        if (!equal(a->aliases, b->aliases))
                return false;
@@ -1160,7 +1148,7 @@ _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
                return false;
        if (a->verbose != b->verbose)
                return false;
-       if (!equalstr(a->vacrel, b->vacrel))
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equal(a->va_cols, b->va_cols))
                return false;
@@ -1184,7 +1172,7 @@ _equalExplainStmt(ExplainStmt *a, ExplainStmt *b)
 static bool
 _equalCreateSeqStmt(CreateSeqStmt *a, CreateSeqStmt *b)
 {
-       if (!equalstr(a->seqname, b->seqname))
+       if (!equal(a->sequence, b->sequence))
                return false;
        if (!equal(a->options, b->options))
                return false;
@@ -1226,7 +1214,7 @@ _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
 {
        if (!equalstr(a->trigname, b->trigname))
                return false;
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
        if (!equalstr(a->funcname, b->funcname))
                return false;
@@ -1252,7 +1240,7 @@ _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
                return false;
        if (a->initdeferred != b->initdeferred)
                return false;
-       if (!equalstr(a->constrrelname, b->constrrelname))
+       if (!equal(a->constrrel, b->constrrel))
                return false;
 
        return true;
@@ -1263,7 +1251,7 @@ _equalDropTrigStmt(DropTrigStmt *a, DropTrigStmt *b)
 {
        if (!equalstr(a->trigname, b->trigname))
                return false;
-       if (!equalstr(a->relname, b->relname))
+       if (!equal(a->relation, b->relation))
                return false;
 
        return true;
@@ -1340,7 +1328,7 @@ _equalDropUserStmt(DropUserStmt *a, DropUserStmt *b)
 static bool
 _equalLockStmt(LockStmt *a, LockStmt *b)
 {
-       if (!equal(a->rellist, b->rellist))
+       if (!equal(a->relations, b->relations))
                return false;
        if (a->mode != b->mode)
                return false;
@@ -1397,6 +1385,8 @@ _equalReindexStmt(ReindexStmt *a, ReindexStmt *b)
 {
        if (a->reindexType != b->reindexType)
                return false;
+       if (!equal(a->relation, b->relation))
+               return false;
        if (!equalstr(a->name, b->name))
                return false;
        if (a->force != b->force)
@@ -1408,6 +1398,19 @@ _equalReindexStmt(ReindexStmt *a, ReindexStmt *b)
 }
 
 static bool
+_equalCreateSchemaStmt(CreateSchemaStmt *a, CreateSchemaStmt *b)
+{
+       if (!equalstr(a->schemaname, b->schemaname))
+               return false;
+       if (!equalstr(a->authid, b->authid))
+               return false;
+       if (!equal(a->schemaElts, b->schemaElts))
+               return false;
+
+       return true;
+}
+
+static bool
 _equalAExpr(A_Expr *a, A_Expr *b)
 {
        if (a->oper != b->oper)
@@ -1423,13 +1426,9 @@ _equalAExpr(A_Expr *a, A_Expr *b)
 }
 
 static bool
-_equalAttr(Attr *a, Attr *b)
+_equalColumnRef(ColumnRef *a, ColumnRef *b)
 {
-       if (strcmp(a->relname, b->relname) != 0)
-               return false;
-       if (!equal(a->paramNo, b->paramNo))
-               return false;
-       if (!equal(a->attrs, b->attrs))
+       if (!equal(a->fields, b->fields))
                return false;
        if (!equal(a->indirection, b->indirection))
                return false;
@@ -1438,25 +1437,25 @@ _equalAttr(Attr *a, Attr *b)
 }
 
 static bool
-_equalAConst(A_Const *a, A_Const *b)
+_equalParamRef(ParamRef *a, ParamRef *b)
 {
-       if (!equal(&a->val, &b->val))
+       if (a->number != b->number)
                return false;
-       if (!equal(a->typename, b->typename))
+       if (!equal(a->fields, b->fields))
+               return false;
+       if (!equal(a->indirection, b->indirection))
                return false;
 
        return true;
 }
 
 static bool
-_equalParamNo(ParamNo *a, ParamNo *b)
+_equalAConst(A_Const *a, A_Const *b)
 {
-       if (a->number != b->number)
+       if (!equal(&a->val, &b->val))
                return false;
        if (!equal(a->typename, b->typename))
                return false;
-       if (!equal(a->indirection, b->indirection))
-               return false;
 
        return true;
 }
@@ -1466,10 +1465,6 @@ _equalIdent(Ident *a, Ident *b)
 {
        if (!equalstr(a->name, b->name))
                return false;
-       if (!equal(a->indirection, b->indirection))
-               return false;
-       if (a->isRel != b->isRel)
-               return false;
 
        return true;
 }
@@ -1501,6 +1496,19 @@ _equalAIndices(A_Indices *a, A_Indices *b)
 }
 
 static bool
+_equalExprFieldSelect(ExprFieldSelect *a, ExprFieldSelect *b)
+{
+       if (!equal(a->arg, b->arg))
+               return false;
+       if (!equal(a->fields, b->fields))
+               return false;
+       if (!equal(a->indirection, b->indirection))
+               return false;
+
+       return true;
+}
+
+static bool
 _equalResTarget(ResTarget *a, ResTarget *b)
 {
        if (!equalstr(a->name, b->name))
@@ -1536,13 +1544,30 @@ _equalSortGroupBy(SortGroupBy *a, SortGroupBy *b)
 }
 
 static bool
+_equalAlias(Alias *a, Alias *b)
+{
+       if (!equalstr(a->aliasname, b->aliasname))
+               return false;
+       if (!equal(a->colnames, b->colnames))
+               return false;
+
+       return true;
+}
+
+static bool
 _equalRangeVar(RangeVar *a, RangeVar *b)
 {
+       if (!equalstr(a->catalogname, b->catalogname))
+               return false;
+       if (!equalstr(a->schemaname, b->schemaname))
+               return false;
        if (!equalstr(a->relname, b->relname))
                return false;
        if (a->inhOpt != b->inhOpt)
                return false;
-       if (!equal(a->name, b->name))
+       if (a->istemp != b->istemp)
+               return false;
+       if (!equal(a->alias, b->alias))
                return false;
 
        return true;
@@ -1553,7 +1578,7 @@ _equalRangeSubselect(RangeSubselect *a, RangeSubselect *b)
 {
        if (!equal(a->subquery, b->subquery))
                return false;
-       if (!equal(a->name, b->name))
+       if (!equal(a->alias, b->alias))
                return false;
 
        return true;
@@ -1704,7 +1729,7 @@ _equalFkConstraint(FkConstraint *a, FkConstraint *b)
 {
        if (!equalstr(a->constr_name, b->constr_name))
                return false;
-       if (!equalstr(a->pktable_name, b->pktable_name))
+       if (!equal(a->pktable, b->pktable))
                return false;
        if (!equal(a->fk_attrs, b->fk_attrs))
                return false;
@@ -2111,19 +2136,22 @@ equal(void *a, void *b)
                case T_CheckPointStmt:
                        retval = true;
                        break;
+               case T_CreateSchemaStmt:
+                       retval = _equalCreateSchemaStmt(a, b);
+                       break;
 
                case T_A_Expr:
                        retval = _equalAExpr(a, b);
                        break;
-               case T_Attr:
-                       retval = _equalAttr(a, b);
+               case T_ColumnRef:
+                       retval = _equalColumnRef(a, b);
+                       break;
+               case T_ParamRef:
+                       retval = _equalParamRef(a, b);
                        break;
                case T_A_Const:
                        retval = _equalAConst(a, b);
                        break;
-               case T_ParamNo:
-                       retval = _equalParamNo(a, b);
-                       break;
                case T_Ident:
                        retval = _equalIdent(a, b);
                        break;
@@ -2133,6 +2161,9 @@ equal(void *a, void *b)
                case T_A_Indices:
                        retval = _equalAIndices(a, b);
                        break;
+               case T_ExprFieldSelect:
+                       retval = _equalExprFieldSelect(a, b);
+                       break;
                case T_ResTarget:
                        retval = _equalResTarget(a, b);
                        break;
@@ -2142,6 +2173,9 @@ equal(void *a, void *b)
                case T_SortGroupBy:
                        retval = _equalSortGroupBy(a, b);
                        break;
+               case T_Alias:
+                       retval = _equalAlias(a, b);
+                       break;
                case T_RangeVar:
                        retval = _equalRangeVar(a, b);
                        break;
index 36f8460..d8bf80a 100644 (file)
@@ -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;
 }
index 5d43a8e..401b34b 100644 (file)
@@ -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;
index 3699fc3..aff46e6 100644 (file)
@@ -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 ");
@@ -143,6 +142,13 @@ _outIndexStmt(StringInfo str, IndexStmt *node)
 }
 
 static void
+_outNotifyStmt(StringInfo str, NotifyStmt *node)
+{
+       appendStringInfo(str, "NOTIFY :relation ");
+       _outNode(str, node->relation);
+}
+
+static void
 _outSelectStmt(StringInfo str, SelectStmt *node)
 {
        /* XXX this is pretty durn incomplete */
@@ -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);
@@ -964,6 +957,15 @@ _outTargetEntry(StringInfo str, TargetEntry *node)
 }
 
 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)
 {
        appendStringInfo(str, " RTE :rtekind %d :relname ",
@@ -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
@@ -1337,6 +1366,17 @@ _outAConst(StringInfo str, A_Const *node)
 }
 
 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)
 {
        appendStringInfo(str, " CONSTRAINT :name ");
@@ -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 ",
index 0d92994..ebc5d53 100644 (file)
@@ -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;
index c079412..66dd317 100644 (file)
@@ -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);
@@ -211,6 +192,25 @@ _readQuery(void)
 }
 
 /* ----------------
+ *             _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)
index 6585fb1..41cc4cd 100644 (file)
@@ -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:
index 98f5030..109062c 100644 (file)
@@ -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.220 2002/03/12 00:51:52 tgl Exp $
+ *     $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.221 2002/03/21 16:00:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #endif
 
 
+/* State shared by transformCreateSchemaStmt and its subroutines */
+typedef struct
+{
+       const char *stmtType;           /* "CREATE TABLE" or "ALTER TABLE" */
+       char       *schemaname;         /* name of schema */
+       char       *authid;                     /* owner of schema */
+       List       *tables;                     /* CREATE TABLE items */
+       List       *views;                      /* CREATE VIEW items */
+       List       *grants;                     /* GRANT items */
+       List       *fwconstraints;      /* Forward referencing FOREIGN KEY constraints */
+       List       *alters;                     /* Generated ALTER items (from the above) */
+       List       *ixconstraints;      /* index-creating constraints */
+       List       *blist;                      /* "before list" of things to do before
+                                                                * creating the schema */
+       List       *alist;                      /* "after list" of things to do after
+                                                                * creating the schema */
+} CreateSchemaStmtContext;
+
 /* State shared by transformCreateStmt and its subroutines */
 typedef struct
 {
        const char *stmtType;           /* "CREATE TABLE" or "ALTER TABLE" */
-       char       *relname;            /* name of relation */
-       List       *inhRelnames;        /* names of relations to inherit from */
-       bool            istemp;                 /* is it to be a temp relation? */
+       RangeVar   *relation;           /* relation to create */
+       List       *inhRelations;       /* relations to inherit from */
        bool            hasoids;                /* does relation have an OID column? */
        Oid                     relOid;                 /* OID of table, if ALTER TABLE case */
        List       *columns;            /* ColumnDef items */
@@ -330,8 +347,8 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
        qry->commandType = CMD_DELETE;
 
        /* set up range table with just the result rel */
-       qry->resultRelation = setTargetTable(pstate, stmt->relname,
-                                                                                interpretInhOption(stmt->inhOpt),
+       qry->resultRelation = setTargetTable(pstate, stmt->relation->relname,
+                                                                                interpretInhOption(stmt->relation->inhOpt),
                                                                                 true);
 
        qry->distinctClause = NIL;
@@ -398,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->relname,
+       qry->resultRelation = setTargetTable(pstate, stmt->relation->relname,
                                                                                 false, false);
 
        /*
@@ -443,7 +460,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
                 */
                rte = addRangeTableEntryForSubquery(pstate,
                                                                                        selectQuery,
-                                                                                       makeAttr("*SELECT*", NULL),
+                                                                                       makeAlias("*SELECT*", NIL),
                                                                                        true);
                rtr = makeNode(RangeTblRef);
                /* assume new rte is at end */
@@ -515,14 +532,15 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
        foreach(tl, qry->targetList)
        {
                TargetEntry *tle = (TargetEntry *) lfirst(tl);
-               Ident      *id;
+               ResTarget   *col;
 
                Assert(!tle->resdom->resjunk);
                if (icolumns == NIL || attnos == NIL)
                        elog(ERROR, "INSERT has more expressions than target columns");
-               id = (Ident *) lfirst(icolumns);
-               updateTargetListEntry(pstate, tle, id->name, lfirsti(attnos),
-                                                         id->indirection);
+               col = (ResTarget *) lfirst(icolumns);
+               Assert(IsA(col, ResTarget));
+               updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
+                                                         col->indirection);
                icolumns = lnext(icolumns);
                attnos = lnext(attnos);
        }
@@ -691,9 +709,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
        List       *elements;
 
        cxt.stmtType = "CREATE TABLE";
-       cxt.relname = stmt->relname;
-       cxt.inhRelnames = stmt->inhRelnames;
-       cxt.istemp = stmt->istemp;
+       cxt.relation = stmt->relation;
+       cxt.inhRelations = stmt->inhRelations;
        cxt.hasoids = stmt->hasoids;
        cxt.relOid = InvalidOid;
        cxt.columns = NIL;
@@ -805,7 +822,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
                 * conflicting constraints the user wrote (like a different
                 * DEFAULT).
                 */
-               sname = makeObjectName(cxt->relname, column->colname, "seq");
+               sname = makeObjectName((cxt->relation)->relname, column->colname, "seq");
 
                /*
                 * Create an expression tree representing the function call
@@ -845,12 +862,12 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
                 * CREATE/ALTER TABLE.
                 */
                sequence = makeNode(CreateSeqStmt);
-               sequence->seqname = pstrdup(sname);
-               sequence->istemp = cxt->istemp;
+               sequence->sequence = copyObject(cxt->relation);
+               sequence->sequence->relname = pstrdup(sname);
                sequence->options = NIL;
 
                elog(NOTICE, "%s will create implicit sequence '%s' for SERIAL column '%s.%s'",
-               cxt->stmtType, sequence->seqname, cxt->relname, column->colname);
+               cxt->stmtType, sequence->sequence->relname, (cxt->relation)->relname, column->colname);
 
                cxt->blist = lappend(cxt->blist, sequence);
        }
@@ -875,9 +892,6 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
                        Ident      *id = makeNode(Ident);
 
                        id->name = column->colname;
-                       id->indirection = NIL;
-                       id->isRel = false;
-
                        fkconstraint->fk_attrs = makeList1(id);
 
                        cxt->fkconstraints = lappend(cxt->fkconstraints, fkconstraint);
@@ -891,7 +905,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
                        case CONSTR_NULL:
                                if (saw_nullable && column->is_not_null)
                                        elog(ERROR, "%s/(NOT) NULL conflicting declaration for '%s.%s'",
-                                                cxt->stmtType, cxt->relname, column->colname);
+                                                cxt->stmtType, (cxt->relation)->relname, column->colname);
                                column->is_not_null = FALSE;
                                saw_nullable = true;
                                break;
@@ -899,7 +913,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
                        case CONSTR_NOTNULL:
                                if (saw_nullable && !column->is_not_null)
                                        elog(ERROR, "%s/(NOT) NULL conflicting declaration for '%s.%s'",
-                                                cxt->stmtType, cxt->relname, column->colname);
+                                                cxt->stmtType, (cxt->relation)->relname, column->colname);
                                column->is_not_null = TRUE;
                                saw_nullable = true;
                                break;
@@ -907,14 +921,14 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
                        case CONSTR_DEFAULT:
                                if (column->raw_default != NULL)
                                        elog(ERROR, "%s/DEFAULT multiple values specified for '%s.%s'",
-                                                cxt->stmtType, cxt->relname, column->colname);
+                                                cxt->stmtType, (cxt->relation)->relname, column->colname);
                                column->raw_default = constraint->raw_expr;
                                Assert(constraint->cooked_expr == NULL);
                                break;
 
                        case CONSTR_PRIMARY:
                                if (constraint->name == NULL)
-                                       constraint->name = makeObjectName(cxt->relname,
+                                       constraint->name = makeObjectName((cxt->relation)->relname,
                                                                                                          NULL,
                                                                                                          "pkey");
                                if (constraint->keys == NIL)
@@ -928,7 +942,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
 
                        case CONSTR_UNIQUE:
                                if (constraint->name == NULL)
-                                       constraint->name = makeObjectName(cxt->relname,
+                                       constraint->name = makeObjectName((cxt->relation)->relname,
                                                                                                          column->colname,
                                                                                                          "key");
                                if (constraint->keys == NIL)
@@ -942,7 +956,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
 
                        case CONSTR_CHECK:
                                if (constraint->name == NULL)
-                                       constraint->name = makeObjectName(cxt->relname,
+                                       constraint->name = makeObjectName((cxt->relation)->relname,
                                                                                                          column->colname,
                                                                                                          NULL);
                                cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
@@ -970,7 +984,7 @@ transformTableConstraint(ParseState *pstate, CreateStmtContext *cxt,
        {
                case CONSTR_PRIMARY:
                        if (constraint->name == NULL)
-                               constraint->name = makeObjectName(cxt->relname,
+                               constraint->name = makeObjectName((cxt->relation)->relname,
                                                                                                  NULL,
                                                                                                  "pkey");
                        cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
@@ -1034,21 +1048,21 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
                        /* In ALTER TABLE case, a primary index might already exist */
                        if (cxt->pkey != NULL ||
                                (OidIsValid(cxt->relOid) &&
-                                relationHasPrimaryKey(cxt->relname)))
+                                relationHasPrimaryKey((cxt->relation)->relname)))
                                elog(ERROR, "%s / PRIMARY KEY multiple primary keys"
                                         " for table '%s' are not allowed",
-                                        cxt->stmtType, cxt->relname);
+                                        cxt->stmtType, (cxt->relation)->relname);
                        cxt->pkey = index;
                }
 
                if (constraint->name != NULL)
                        index->idxname = pstrdup(constraint->name);
                else if (constraint->contype == CONSTR_PRIMARY)
-                       index->idxname = makeObjectName(cxt->relname, NULL, "pkey");
+                       index->idxname = makeObjectName((cxt->relation)->relname, NULL, "pkey");
                else
                        index->idxname = NULL;          /* will set it later */
 
-               index->relname = cxt->relname;
+               index->relation = cxt->relation;
                index->accessMethod = DEFAULT_INDEX_TYPE;
                index->indexParams = NIL;
                index->whereClause = NULL;
@@ -1089,19 +1103,19 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
                                 */
                                found = true;
                        }
-                       else if (cxt->inhRelnames)
+                       else if (cxt->inhRelations)
                        {
                                /* try inherited tables */
                                List       *inher;
 
-                               foreach(inher, cxt->inhRelnames)
+                               foreach(inher, cxt->inhRelations)
                                {
-                                       Value      *inh = lfirst(inher);
+                                       RangeVar   *inh = lfirst(inher);
                                        Relation        rel;
                                        int                     count;
 
-                                       Assert(IsA(inh, String));
-                                       rel = heap_openr(strVal(inh), AccessShareLock);
+                                       Assert(IsA(inh, RangeVar));
+                                       rel = heap_openr(inh->relname, AccessShareLock);
                                        if (rel->rd_rel->relkind != RELKIND_RELATION)
                                                elog(ERROR, "inherited table \"%s\" is not a relation",
                                                         strVal(inh));
@@ -1257,7 +1271,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
                if (index->idxname == NULL && index->indexParams != NIL)
                {
                        iparam = lfirst(index->indexParams);
-                       index->idxname = CreateIndexName(cxt->relname, iparam->name,
+                       index->idxname = CreateIndexName((cxt->relation)->relname, iparam->name,
                                                                                         "key", cxt->alist);
                }
                if (index->idxname == NULL)             /* should not happen */
@@ -1268,7 +1282,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
                         cxt->stmtType,
                         (strcmp(cxt->stmtType, "ALTER TABLE") == 0) ? "ADD " : "",
                         (index->primary ? "PRIMARY KEY" : "UNIQUE"),
-                        index->idxname, cxt->relname);
+                        index->idxname, (cxt->relation)->relname);
        }
 }
 
@@ -1328,7 +1342,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                 */
                if (fkconstraint->pk_attrs == NIL)
                {
-                       if (strcmp(fkconstraint->pktable_name, cxt->relname) != 0)
+                       if (strcmp(fkconstraint->pktable->relname, (cxt->relation)->relname) != 0)
                                transformFkeyGetPrimaryKey(fkconstraint, pktypoid);
                        else if (cxt->pkey != NULL)
                        {
@@ -1342,8 +1356,6 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                                        Ident      *pkattr = (Ident *) makeNode(Ident);
 
                                        pkattr->name = pstrdup(ielem->name);
-                                       pkattr->indirection = NIL;
-                                       pkattr->isRel = false;
                                        fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs,
                                                                                                         pkattr);
                                        if (attnum >= INDEX_MAX_KEYS)
@@ -1360,13 +1372,13 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                                        transformFkeyGetPrimaryKey(fkconstraint, pktypoid);
                                else
                                        elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found",
-                                                fkconstraint->pktable_name);
+                                                fkconstraint->pktable->relname);
                        }
                }
                else
                {
                        /* Validate the specified referenced key list */
-                       if (strcmp(fkconstraint->pktable_name, cxt->relname) != 0)
+                       if (strcmp(fkconstraint->pktable->relname, (cxt->relation)->relname) != 0)
                                transformFkeyCheckAttrs(fkconstraint, pktypoid);
                        else
                        {
@@ -1422,7 +1434,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                                                transformFkeyCheckAttrs(fkconstraint, pktypoid);
                                        else
                                                elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
-                                                        fkconstraint->pktable_name);
+                                                        fkconstraint->pktable->relname);
                                }
                        }
                }
@@ -1447,7 +1459,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                 */
                fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
                fk_trigger->trigname = fkconstraint->constr_name;
-               fk_trigger->relname = cxt->relname;
+               fk_trigger->relation = cxt->relation;
                fk_trigger->funcname = "RI_FKey_check_ins";
                fk_trigger->before = false;
                fk_trigger->row = true;
@@ -1462,15 +1474,15 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                fk_trigger->isconstraint = true;
                fk_trigger->deferrable = fkconstraint->deferrable;
                fk_trigger->initdeferred = fkconstraint->initdeferred;
-               fk_trigger->constrrelname = fkconstraint->pktable_name;
+               fk_trigger->constrrel = fkconstraint->pktable;
 
                fk_trigger->args = NIL;
                fk_trigger->args = lappend(fk_trigger->args,
                                                                   makeString(fkconstraint->constr_name));
                fk_trigger->args = lappend(fk_trigger->args,
-                                                                  makeString(cxt->relname));
+                                                                  makeString((cxt->relation)->relname));
                fk_trigger->args = lappend(fk_trigger->args,
-                                                                makeString(fkconstraint->pktable_name));
+                                                                makeString(fkconstraint->pktable->relname));
                fk_trigger->args = lappend(fk_trigger->args,
                                                                   makeString(fkconstraint->match_type));
                fk_attr = fkconstraint->fk_attrs;
@@ -1478,7 +1490,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                if (length(fk_attr) != length(pk_attr))
                        elog(ERROR, "number of key attributes in referenced table must be equal to foreign key"
                                 "\n\tIllegal FOREIGN KEY definition references \"%s\"",
-                                fkconstraint->pktable_name);
+                                fkconstraint->pktable->relname);
 
                while (fk_attr != NIL)
                {
@@ -1502,7 +1514,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                 */
                fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
                fk_trigger->trigname = fkconstraint->constr_name;
-               fk_trigger->relname = fkconstraint->pktable_name;
+               fk_trigger->relation = fkconstraint->pktable;
                fk_trigger->before = false;
                fk_trigger->row = true;
                fk_trigger->actions[0] = 'd';
@@ -1515,7 +1527,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                fk_trigger->isconstraint = true;
                fk_trigger->deferrable = fkconstraint->deferrable;
                fk_trigger->initdeferred = fkconstraint->initdeferred;
-               fk_trigger->constrrelname = cxt->relname;
+               fk_trigger->constrrel = cxt->relation;
                switch ((fkconstraint->actions & FKCONSTR_ON_DELETE_MASK)
                                >> FKCONSTR_ON_DELETE_SHIFT)
                {
@@ -1545,9 +1557,9 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                fk_trigger->args = lappend(fk_trigger->args,
                                                                   makeString(fkconstraint->constr_name));
                fk_trigger->args = lappend(fk_trigger->args,
-                                                                  makeString(cxt->relname));
+                                                                  makeString((cxt->relation)->relname));
                fk_trigger->args = lappend(fk_trigger->args,
-                                                                makeString(fkconstraint->pktable_name));
+                                                                makeString(fkconstraint->pktable->relname));
                fk_trigger->args = lappend(fk_trigger->args,
                                                                   makeString(fkconstraint->match_type));
                fk_attr = fkconstraint->fk_attrs;
@@ -1574,7 +1586,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                 */
                fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
                fk_trigger->trigname = fkconstraint->constr_name;
-               fk_trigger->relname = fkconstraint->pktable_name;
+               fk_trigger->relation = fkconstraint->pktable;
                fk_trigger->before = false;
                fk_trigger->row = true;
                fk_trigger->actions[0] = 'u';
@@ -1587,7 +1599,7 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                fk_trigger->isconstraint = true;
                fk_trigger->deferrable = fkconstraint->deferrable;
                fk_trigger->initdeferred = fkconstraint->initdeferred;
-               fk_trigger->constrrelname = cxt->relname;
+               fk_trigger->constrrel = cxt->relation;
                switch ((fkconstraint->actions & FKCONSTR_ON_UPDATE_MASK)
                                >> FKCONSTR_ON_UPDATE_SHIFT)
                {
@@ -1617,9 +1629,9 @@ transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
                fk_trigger->args = lappend(fk_trigger->args,
                                                                   makeString(fkconstraint->constr_name));
                fk_trigger->args = lappend(fk_trigger->args,
-                                                                  makeString(cxt->relname));
+                                                                  makeString((cxt->relation)->relname));
                fk_trigger->args = lappend(fk_trigger->args,
-                                                                makeString(fkconstraint->pktable_name));
+                                                                makeString(fkconstraint->pktable->relname));
                fk_trigger->args = lappend(fk_trigger->args,
                                                                   makeString(fkconstraint->match_type));
                fk_attr = fkconstraint->fk_attrs;
@@ -1672,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->relname, NULL, false, true);
+               rte = addRangeTableEntry(pstate, stmt->relation->relname, NULL, false, true);
 
                /* no to join list, yes to namespace */
                addRTEtoQuery(pstate, rte, false, true);
@@ -1712,7 +1724,7 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
         * beforehand.  We don't need to hold a refcount on the relcache
         * entry, however.
         */
-       heap_close(heap_openr(stmt->object->relname, AccessExclusiveLock),
+       heap_close(heap_openr(stmt->relation->relname, AccessExclusiveLock),
                           NoLock);
 
        /*
@@ -1721,11 +1733,11 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
         * rule qualification.
         */
        Assert(pstate->p_rtable == NIL);
-       oldrte = addRangeTableEntry(pstate, stmt->object->relname,
-                                                               makeAttr("*OLD*", NULL),
+       oldrte = addRangeTableEntry(pstate, stmt->relation->relname,
+                                                               makeAlias("*OLD*", NIL),
                                                                false, true);
-       newrte = addRangeTableEntry(pstate, stmt->object->relname,
-                                                               makeAttr("*NEW*", NULL),
+       newrte = addRangeTableEntry(pstate, stmt->relation->relname,
+                                                               makeAlias("*NEW*", NIL),
                                                                false, true);
        /* Must override addRangeTableEntry's default access-check flags */
        oldrte->checkForRead = false;
@@ -1812,11 +1824,11 @@ 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->object->relname,
-                                                                               makeAttr("*OLD*", NULL),
+                       oldrte = addRangeTableEntry(sub_pstate, stmt->relation->relname,
+                                                                               makeAlias("*OLD*", NIL),
                                                                                false, false);
-                       newrte = addRangeTableEntry(sub_pstate, stmt->object->relname,
-                                                                               makeAttr("*NEW*", NULL),
+                       newrte = addRangeTableEntry(sub_pstate, stmt->relation->relname,
+                                                                               makeAlias("*NEW*", NIL),
                                                                                false, false);
                        oldrte->checkForRead = false;
                        newrte->checkForRead = false;
@@ -1950,8 +1962,8 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
                if (!IsTransactionBlock())
                        elog(ERROR, "DECLARE CURSOR may only be used in begin/end transaction blocks");
 
-               qry->into = stmt->portalname;
-               qry->isTemp = stmt->istemp;
+               qry->into = makeNode(RangeVar);
+               qry->into->relname = stmt->portalname;
                qry->isPortal = TRUE;
                qry->isBinary = stmt->binary;   /* internal portal */
        }
@@ -1959,7 +1971,6 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
        {
                /* SELECT */
                qry->into = stmt->into;
-               qry->isTemp = stmt->istemp;
                qry->isPortal = FALSE;
                qry->isBinary = FALSE;
        }
@@ -2033,8 +2044,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
        int                     leftmostRTI;
        Query      *leftmostQuery;
        SetOperationStmt *sostmt;
-       char       *into;
-       bool            istemp;
+       RangeVar   *into;
        List       *intoColNames;
        char       *portalname;
        bool            binary;
@@ -2065,14 +2075,12 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
        Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) &&
                   leftmostSelect->larg == NULL);
        into = leftmostSelect->into;
-       istemp = leftmostSelect->istemp;
        intoColNames = leftmostSelect->intoColNames;
        portalname = stmt->portalname;
        binary = stmt->binary;
 
        /* clear them to prevent complaints in transformSetOperationTree() */
        leftmostSelect->into = NULL;
-       leftmostSelect->istemp = false;
        leftmostSelect->intoColNames = NIL;
        stmt->portalname = NULL;
        stmt->binary = false;
@@ -2174,8 +2182,8 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
                if (!IsTransactionBlock())
                        elog(ERROR, "DECLARE CURSOR may only be used in begin/end transaction blocks");
 
-               qry->into = portalname;
-               qry->isTemp = istemp;
+               qry->into = makeNode(RangeVar);
+               qry->into->relname = portalname;
                qry->isPortal = TRUE;
                qry->isBinary = binary; /* internal portal */
        }
@@ -2183,7 +2191,6 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
        {
                /* SELECT */
                qry->into = into;
-               qry->isTemp = istemp;
                qry->isPortal = FALSE;
                qry->isBinary = FALSE;
        }
@@ -2325,8 +2332,7 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
                sprintf(selectName, "*SELECT* %d", length(pstate->p_rtable) + 1);
                rte = addRangeTableEntryForSubquery(pstate,
                                                                                        selectQuery,
-                                                                                       makeAttr(pstrdup(selectName),
-                                                                                                        NULL),
+                                                                                       makeAlias(selectName, NIL),
                                                                                        false);
 
                /*
@@ -2468,8 +2474,8 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
        qry->commandType = CMD_UPDATE;
        pstate->p_is_update = true;
 
-       qry->resultRelation = setTargetTable(pstate, stmt->relname,
-                                                                                interpretInhOption(stmt->inhOpt),
+       qry->resultRelation = setTargetTable(pstate, stmt->relation->relname,
+                                                                                interpretInhOption(stmt->relation->inhOpt),
                                                                                 true);
 
        /*
@@ -2553,11 +2559,11 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
        {
                case 'A':
                        cxt.stmtType = "ALTER TABLE";
-                       cxt.relname = stmt->relname;
-                       cxt.inhRelnames = NIL;
-                       cxt.istemp = is_temp_rel_name(stmt->relname);
+                       cxt.relation = stmt->relation;
+                       cxt.inhRelations = NIL;
+                       cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname);
                        cxt.relOid = GetSysCacheOid(RELNAME,
-                                                                               PointerGetDatum(stmt->relname),
+                                                                               PointerGetDatum((stmt->relation)->relname),
                                                                                0, 0, 0);
                        cxt.hasoids = SearchSysCacheExists(ATTNUM,
                                                                                        ObjectIdGetDatum(cxt.relOid),
@@ -2585,11 +2591,11 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
 
                case 'C':
                        cxt.stmtType = "ALTER TABLE";
-                       cxt.relname = stmt->relname;
-                       cxt.inhRelnames = NIL;
-                       cxt.istemp = is_temp_rel_name(stmt->relname);
+                       cxt.relation = stmt->relation;
+                       cxt.inhRelations = NIL;
+                       cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname);
                        cxt.relOid = GetSysCacheOid(RELNAME,
-                                                                               PointerGetDatum(stmt->relname),
+                                                                               PointerGetDatum((stmt->relation)->relname),
                                                                                0, 0, 0);
                        cxt.hasoids = SearchSysCacheExists(ATTNUM,
                                                                                        ObjectIdGetDatum(cxt.relOid),
@@ -2713,15 +2719,18 @@ transformTypeRefsList(ParseState *pstate, List *l)
 static void
 transformTypeRef(ParseState *pstate, TypeName *tn)
 {
-       Attr       *att;
+       ColumnRef  *cref;
        Node       *n;
        Var                *v;
        char       *tyn;
 
        if (tn->attrname == NULL)
                return;
-       att = makeAttr(tn->name, tn->attrname);
-       n = transformExpr(pstate, (Node *) att, EXPR_COLUMN_FIRST);
+       /* XXX this needs work; can't type name be qualified? */
+       cref = makeNode(ColumnRef);
+       cref->fields = makeList2(makeString(tn->name), makeString(tn->attrname));
+       cref->indirection = NIL;
+       n = transformExpr(pstate, (Node *) cref);
        if (!IsA(n, Var))
                elog(ERROR, "unsupported expression in %%TYPE");
        v = (Var *) n;
@@ -2791,7 +2800,7 @@ transformForUpdate(Query *qry, List *forUpdate)
                                RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
 
                                ++i;
-                               if (strcmp(rte->eref->relname, relname) == 0)
+                               if (strcmp(rte->eref->aliasname, relname) == 0)
                                {
                                        if (rte->subquery)
                                        {
@@ -2835,11 +2844,11 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid)
        /*
         * Open the referenced table
         */
-       pkrel = heap_openr(fkconstraint->pktable_name, AccessShareLock);
+       pkrel = heap_openr(fkconstraint->pktable->relname, AccessShareLock);
 
        if (pkrel->rd_rel->relkind != RELKIND_RELATION)
                elog(ERROR, "Referenced relation \"%s\" is not a table",
-                        fkconstraint->pktable_name);
+                        fkconstraint->pktable->relname);
 
        /*
         * Get the list of index OIDs for the table from the relcache, and
@@ -2901,7 +2910,7 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid)
        }
        if (!found)
                elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
-                        fkconstraint->pktable_name);
+                        fkconstraint->pktable->relname);
 
        freeList(indexoidlist);
        heap_close(pkrel, AccessShareLock);
@@ -2928,11 +2937,11 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid)
        /*
         * Open the referenced table
         */
-       pkrel = heap_openr(fkconstraint->pktable_name, AccessShareLock);
+       pkrel = heap_openr(fkconstraint->pktable->relname, AccessShareLock);
 
        if (pkrel->rd_rel->relkind != RELKIND_RELATION)
                elog(ERROR, "Referenced relation \"%s\" is not a table",
-                        fkconstraint->pktable_name);
+                        fkconstraint->pktable->relname);
 
        /*
         * Get the list of index OIDs for the table from the relcache, and
@@ -2965,7 +2974,7 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid)
         */
        if (indexStruct == NULL)
                elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found",
-                        fkconstraint->pktable_name);
+                        fkconstraint->pktable->relname);
 
        /*
         * Now build the list of PK attributes from the indkey definition
@@ -2977,8 +2986,6 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid)
                Ident      *pkattr = makeNode(Ident);
 
                pkattr->name = pstrdup(NameStr(*attnumAttName(pkrel, pkattno)));
-               pkattr->indirection = NIL;
-               pkattr->isRel = false;
                pktypoid[attnum++] = attnumTypeId(pkrel, pkattno);
 
                fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs, pkattr);
@@ -3070,14 +3077,14 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
        if (sysatt)
                return sysatt->atttypid;
        /* Look for column among inherited columns (if CREATE TABLE case) */
-       foreach(inher, cxt->inhRelnames)
+       foreach(inher, cxt->inhRelations)
        {
-               Value      *inh = lfirst(inher);
+               RangeVar   *inh = lfirst(inher);
                Relation        rel;
                int                     count;
 
-               Assert(IsA(inh, String));
-               rel = heap_openr(strVal(inh), AccessShareLock);
+               Assert(IsA(inh, RangeVar));
+               rel = heap_openr(inh->relname, AccessShareLock);
                if (rel->rd_rel->relkind != RELKIND_RELATION)
                        elog(ERROR, "inherited table \"%s\" is not a relation",
                                 strVal(inh));
@@ -3248,3 +3255,104 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
 
        ReleaseSysCache(ctype);
 }
+
+/*
+ * analyzeCreateSchemaStmt -
+ *       analyzes the "create schema" statement
+ *
+ * Split the schema element list into individual commands and place
+ * them in the result list in an order such that there are no
+ * forward references (e.g. GRANT to a table created later in the list).
+ *
+ * SQL92 also allows constraints to make forward references, so thumb through
+ * the table columns and move forward references to a posterior alter-table
+ * command.
+ *
+ * The result is a list of parse nodes that still need to be analyzed ---
+ * but we can't analyze the later commands until we've executed the earlier
+ * ones, because of possible inter-object references.
+ *
+ * Note: Called from commands/command.c
+ */
+List *
+analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
+{
+       CreateSchemaStmtContext cxt;
+       List       *result;
+       List       *elements;
+
+       cxt.stmtType = "CREATE SCHEMA";
+       cxt.schemaname = stmt->schemaname;
+       cxt.authid = stmt->authid;
+       cxt.tables = NIL;
+       cxt.views = NIL;
+       cxt.grants = NIL;
+       cxt.fwconstraints = NIL;
+       cxt.alters = NIL;
+       cxt.blist = NIL;
+       cxt.alist = NIL;
+
+       /*
+        * Run through each schema element in the schema element list.
+        * Separate statements by type, and do preliminary analysis.
+        */
+       foreach(elements, stmt->schemaElts)
+       {
+               Node       *element = lfirst(elements);
+
+               switch (nodeTag(element))
+               {
+                       case T_CreateStmt:
+                               {
+                                       CreateStmt *elp = (CreateStmt *) element;
+
+                                       if (elp->relation->schemaname == NULL)
+                                               elp->relation->schemaname = cxt.schemaname;
+                                       else if (strcmp(cxt.schemaname, elp->relation->schemaname))
+                                               elog(ERROR, "New table refers to a schema (%s)"
+                                                       " different from the one being created (%s)",
+                                                       elp->relation->schemaname, cxt.schemaname);
+
+                                       /*
+                                        * XXX todo: deal with constraints
+                                        */
+
+                                       cxt.tables = lappend(cxt.tables, element);
+                               }
+                               break;
+
+                       case T_ViewStmt:
+                               {
+                                       ViewStmt *elp = (ViewStmt *) element;
+
+                                       if (elp->view->schemaname == NULL)
+                                               elp->view->schemaname = cxt.schemaname;
+                                       else if (strcmp(cxt.schemaname, elp->view->schemaname))
+                                               elog(ERROR, "New view refers to a schema (%s)"
+                                                       " different from the one being created (%s)",
+                                                       elp->view->schemaname, cxt.schemaname);
+
+                                       /*
+                                        * XXX todo: deal with references between views
+                                        */
+
+                                       cxt.views = lappend(cxt.views, element);
+                               }
+                               break;
+
+                       case T_GrantStmt:
+                               cxt.grants = lappend(cxt.grants, element);
+                               break;
+
+                       default:
+                               elog(ERROR, "parser: unsupported schema node (internal error)");
+               }
+       }
+
+       result = NIL;   
+       result = nconc(result, cxt.tables);
+       result = nconc(result, cxt.views);
+       result = nconc(result, cxt.grants);
+
+       return result;
+}
index 6951653..f94eaea 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.294 2002/03/20 19:44:21 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.295 2002/03/21 16:00:50 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -98,6 +98,7 @@ static void doNegateFloat(Value *v);
 
 %}
 
+
 %union
 {
        int                                     ival;
@@ -108,19 +109,17 @@ static void doNegateFloat(Value *v);
        List                            *list;
        Node                            *node;
        Value                           *value;
-
-       Attr                            *attr;
-       Ident                           *ident;
+       ColumnRef                       *columnref;
 
        TypeName                        *typnam;
        DefElem                         *defelt;
        SortGroupBy                     *sortgroupby;
        JoinExpr                        *jexpr;
        IndexElem                       *ielem;
+       Alias                           *alias;
        RangeVar                        *range;
        A_Indices                       *aind;
        ResTarget                       *target;
-       ParamNo                         *paramno;
        PrivTarget                      *privtarget;
 
        VersionStmt                     *vstmt;
@@ -129,7 +128,7 @@ static void doNegateFloat(Value *v);
        InsertStmt                      *istmt;
 }
 
-%type <node>   stmt,
+%type <node>   stmt, schema_stmt,
                AlterDatabaseSetStmt, AlterGroupStmt, AlterSchemaStmt, AlterTableStmt,
                AlterUserStmt, AlterUserSetStmt, AnalyzeStmt,
                ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt,
@@ -166,11 +165,12 @@ static void doNegateFloat(Value *v);
 %type <list>   OptUserList
 %type <defelt> OptUserElem
 
+%type <str>            OptSchemaName
+%type <list>   OptSchemaEltList
+
 %type <boolean>        TriggerActionTime, TriggerForSpec, opt_trusted, opt_procedural
 %type <str>            opt_lancompiler
 
-%type <str>            OptConstrFromTable
-
 %type <str>            TriggerEvents
 %type <value>  TriggerFuncArg
 
@@ -178,6 +178,8 @@ static void doNegateFloat(Value *v);
                database_name, access_method_clause, access_method, attr_name,
                class, index_name, name, func_name, file_name
 
+%type <range>  qualified_name, OptConstrFromTable
+
 %type <str>            opt_id,
                all_Op, MathOp, opt_name,
                OptUseOp, opt_class, SpecialRuleRelation
@@ -193,17 +195,19 @@ static void doNegateFloat(Value *v);
 %type <chr>    TriggerOneEvent
 
 %type <list>   stmtblock, stmtmulti,
-               into_clause, OptTempTableName, relation_name_list,
                OptTableElementList, OptInherit, definition, opt_distinct,
                opt_with, func_args, func_args_list, func_as,
                oper_argtypes, RuleActionList, RuleActionMulti,
                opt_column_list, columnList, opt_name_list,
                sort_clause, sortby_list, index_params, index_list, name_list,
-               from_clause, from_list, opt_array_bounds,
-               expr_list, attrs, target_list, update_target_list,
+               from_clause, from_list, opt_array_bounds, qualified_name_list,
+               expr_list, attrs, opt_attrs, target_list, update_target_list,
+               insert_column_list,
                def_list, opt_indirection, group_clause, TriggerFuncArgs,
                select_limit, opt_select_limit
 
+%type <range>  into_clause, OptTempTableName
+
 %type <typnam> func_arg, func_return, func_type, aggr_argtype
 
 %type <boolean>        opt_arg, TriggerForOpt, TriggerForType, OptTemp, OptWithOids
@@ -240,7 +244,7 @@ static void doNegateFloat(Value *v);
 %type <node>   OptTableElement, ConstraintElem
 %type <node>   columnDef
 %type <defelt> def_elem
-%type <node>   def_arg, columnElem, where_clause,
+%type <node>   def_arg, columnElem, where_clause, insert_column_item,
                                a_expr, b_expr, c_expr, AexprConst,
                                in_expr, having_clause
 %type <list>   row_descriptor, row_list, in_expr_nodes
@@ -252,14 +256,14 @@ static void doNegateFloat(Value *v);
 %type <list>   OptCreateAs, CreateAsList
 %type <node>   CreateAsElement
 %type <value>  NumericOnly, FloatOnly, IntegerOnly
-%type <attr>   event_object, attr, alias_clause
+%type <columnref>      columnref
+%type <alias>  alias_clause
 %type <sortgroupby>            sortby
 %type <ielem>  index_elem, func_index
 %type <node>   table_ref
 %type <jexpr>  joined_table
 %type <range>  relation_expr
 %type <target> target_el, update_target_el
-%type <paramno> ParamNo
 
 %type <typnam> Typename, SimpleTypename, ConstTypename
                                GenericType, Numeric, Character, ConstDatetime, ConstInterval, Bit
@@ -290,6 +294,7 @@ static void doNegateFloat(Value *v);
 
 %type <boolean> opt_as
 
+
 /*
  * If you make any token changes, remember to:
  *             - use "yacc -d" and update parse.h
@@ -753,35 +758,57 @@ DropGroupStmt: DROP GROUP UserId
  *
  *****************************************************************************/
 
-CreateSchemaStmt:  CREATE SCHEMA UserId
+CreateSchemaStmt:  CREATE SCHEMA OptSchemaName AUTHORIZATION UserId OptSchemaEltList
                                {
-                                       /* for now, just make this the same as CREATE DATABASE */
-                                       CreatedbStmt *n = makeNode(CreatedbStmt);
-                                       n->dbname = $3;
-                                       n->dbowner = NULL;
-                                       n->dbpath = NULL;
-                                       n->dbtemplate = NULL;
-                                       n->encoding = -1;
+                                       CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
+                                       /* One can omit the schema name or the authorization id... */
+                                       if ($3 != NULL)
+                                               n->schemaname = $3;
+                                       else
+                                               n->schemaname = $5;
+                                       n->authid = $5;
+                                       n->schemaElts = $6;
+                                       $$ = (Node *)n;
+                               }
+               | CREATE SCHEMA ColId OptSchemaEltList
+                               {
+                                       CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
+                                       /* ...but not both */
+                                       n->schemaname = $3;
+                                       n->authid = NULL;
+                                       n->schemaElts = $4;
                                        $$ = (Node *)n;
                                }
                ;
 
-AlterSchemaStmt:  ALTER SCHEMA UserId
+AlterSchemaStmt:  ALTER SCHEMA ColId
                                {
                                        elog(ERROR, "ALTER SCHEMA not yet supported");
                                }
                ;
 
-DropSchemaStmt:  DROP SCHEMA UserId
+DropSchemaStmt:  DROP SCHEMA ColId
                                {
-                                       DropdbStmt *n = makeNode(DropdbStmt);
-                                       n->dbname = $3;
-                                       $$ = (Node *)n;
+                                       elog(ERROR, "DROP SCHEMA not yet supported");
                                }
                ;
 
+OptSchemaName: ColId                                                           { $$ = $1; }
+               | /* EMPTY */                                                           { $$ = NULL; }
+               ;
+
+OptSchemaEltList: OptSchemaEltList schema_stmt         { $$ = lappend($1, $2); }
+               | /* EMPTY */                                                           { $$ = NIL; }
+               ;
 
+/*
+ *     schema_stmt are the ones that can show up inside a CREATE SCHEMA
+ *     statement (in addition to by themselves).
+ */
+schema_stmt: CreateStmt
+               | GrantStmt
+               | ViewStmt
+               ;
 
 /*****************************************************************************
  *
@@ -978,6 +1005,7 @@ opt_encoding:  Sconst                                              { $$ = $1; }
 
 ColId_or_Sconst: ColId                                         { $$ = $1; }
                | SCONST                                                        { $$ = $1; }
+               ;
 
 
 VariableShowStmt:  SHOW ColId
@@ -1073,8 +1101,7 @@ AlterTableStmt:
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'A';
-                                       n->relname = $3->relname;
-                                       n->inhOpt = $3->inhOpt;
+                                       n->relation = $3;
                                        n->def = $6;
                                        $$ = (Node *)n;
                                }
@@ -1083,8 +1110,7 @@ AlterTableStmt:
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'T';
-                                       n->relname = $3->relname;
-                                       n->inhOpt = $3->inhOpt;
+                                       n->relation = $3;
                                        n->name = $6;
                                        n->def = $7;
                                        $$ = (Node *)n;
@@ -1094,8 +1120,7 @@ AlterTableStmt:
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'S';
-                                       n->relname = $3->relname;
-                                       n->inhOpt = $3->inhOpt;
+                                       n->relation = $3;
                                        n->name = $6;
                                        n->def = (Node *) makeInteger($9);
                                        $$ = (Node *)n;
@@ -1105,8 +1130,7 @@ AlterTableStmt:
                 {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'M';
-                                       n->relname = $3->relname;
-                                       n->inhOpt = $3->inhOpt;
+                                       n->relation = $3;
                                        n->name = $6;
                                        n->def = (Node *) makeString($9);
                                        $$ = (Node *)n;
@@ -1116,8 +1140,7 @@ AlterTableStmt:
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'D';
-                                       n->relname = $3->relname;
-                                       n->inhOpt = $3->inhOpt;
+                                       n->relation = $3;
                                        n->name = $6;
                                        n->behavior = $7;
                                        $$ = (Node *)n;
@@ -1127,8 +1150,7 @@ AlterTableStmt:
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'C';
-                                       n->relname = $3->relname;
-                                       n->inhOpt = $3->inhOpt;
+                                       n->relation = $3;
                                        n->def = $5;
                                        $$ = (Node *)n;
                                }
@@ -1137,28 +1159,27 @@ AlterTableStmt:
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'X';
-                                       n->relname = $3->relname;
-                                       n->inhOpt = $3->inhOpt;
+                                       n->relation = $3;
                                        n->name = $6;
                                        n->behavior = $7;
                                        $$ = (Node *)n;
                                }
 /* ALTER TABLE <name> CREATE TOAST TABLE */
-               | ALTER TABLE relation_name CREATE TOAST TABLE
+               | ALTER TABLE qualified_name CREATE TOAST TABLE
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'E';
-                                       n->relname = $3;
-                                       n->inhOpt = INH_NO;
+                                       $3->inhOpt = INH_NO;
+                                       n->relation = $3;
                                        $$ = (Node *)n;
                                }
 /* ALTER TABLE <name> OWNER TO UserId */
-               | ALTER TABLE relation_name OWNER TO UserId
+               | ALTER TABLE qualified_name OWNER TO UserId
                                {
                                        AlterTableStmt *n = makeNode(AlterTableStmt);
                                        n->subtype = 'U';
-                                       n->relname = $3;
-                                       n->inhOpt = INH_NO;
+                                       $3->inhOpt = INH_NO;
+                                       n->relation = $3;
                                        n->name = $6;
                                        $$ = (Node *)n;
                                }
@@ -1183,7 +1204,8 @@ drop_behavior: CASCADE                                    { $$ = CASCADE; }
 opt_drop_behavior: CASCADE                             { $$ = CASCADE; }
                | RESTRICT                                              { $$ = RESTRICT; }
                | /* EMPTY */                                   { $$ = RESTRICT; /* default */ }
-        ;
+               ;
+
 
 
 /*****************************************************************************
@@ -1214,11 +1236,11 @@ opt_id:  ColId                                                                  { $$ = $1; }
  *
  *****************************************************************************/
 
-CopyStmt:  COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
+CopyStmt:  COPY opt_binary qualified_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
                                {
                                        CopyStmt *n = makeNode(CopyStmt);
                                        n->binary = $2;
-                                       n->relname = $3;
+                                       n->relation = $3;
                                        n->oids = $4;
                                        n->direction = $5;
                                        n->filename = $6;
@@ -1263,8 +1285,9 @@ opt_using:        USING                                                           { $$ = TRUE; }
                | /*EMPTY*/                                                             { $$ = TRUE; }
                ;
 
-copy_null:      WITH NULL_P AS Sconst                  { $$ = $4; }
-                | /*EMPTY*/                                            { $$ = "\\N"; }
+copy_null:  WITH NULL_P AS Sconst                              { $$ = $4; }
+               | /*EMPTY*/                                                             { $$ = "\\N"; }
+               ;
 
 /*****************************************************************************
  *
@@ -1273,14 +1296,14 @@ copy_null:      WITH NULL_P AS Sconst                   { $$ = $4; }
  *
  *****************************************************************************/
 
-CreateStmt:  CREATE OptTemp TABLE relation_name '(' OptTableElementList ')' OptInherit OptWithOids
+CreateStmt:  CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptInherit OptWithOids
                                {
                                        CreateStmt *n = makeNode(CreateStmt);
-                                       n->relname = $4;
+                                       $4->istemp = $2;
+                                       n->relation = $4;
                                        n->tableElts = $6;
-                                       n->inhRelnames = $8;
+                                       n->inhRelations = $8;
                                        n->constraints = NIL;
-                                       n->istemp = $2;
                                        n->hasoids = $9;
                                        $$ = (Node *)n;
                                }
@@ -1448,10 +1471,7 @@ ColConstraintElem:
                                        n->name = NULL;
                                        if (exprIsNullConstant($2))
                                        {
-                                               /*
-                                                * DEFAULT NULL should be reported as empty expr
-                                                * Required for NOT NULL Domain overrides
-                                                */
+                                               /* DEFAULT NULL should be reported as empty expr */
                                                n->raw_expr = NULL;
                                        }
                                        else
@@ -1462,11 +1482,11 @@ ColConstraintElem:
                                        n->keys = NULL;
                                        $$ = (Node *)n;
                                }
-                       | REFERENCES ColId opt_column_list key_match key_actions 
+                       | REFERENCES qualified_name opt_column_list key_match key_actions 
                                {
                                        FkConstraint *n = makeNode(FkConstraint);
                                        n->constr_name          = NULL;
-                                       n->pktable_name         = $2;
+                                       n->pktable                      = $2;
                                        n->fk_attrs                     = NIL;
                                        n->pk_attrs                     = $3;
                                        n->match_type           = $4;
@@ -1573,12 +1593,12 @@ ConstraintElem:  CHECK '(' a_expr ')'
                                        n->keys = $4;
                                        $$ = (Node *)n;
                                }
-               | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list
+               | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list
                                key_match key_actions ConstraintAttributeSpec
                                {
                                        FkConstraint *n = makeNode(FkConstraint);
                                        n->constr_name          = NULL;
-                                       n->pktable_name         = $7;
+                                       n->pktable                      = $7;
                                        n->fk_attrs                     = $4;
                                        n->pk_attrs                     = $8;
                                        n->match_type           = $9;
@@ -1589,6 +1609,24 @@ ConstraintElem:  CHECK '(' a_expr ')'
                                }
                ;
 
+opt_column_list:  '(' columnList ')'                   { $$ = $2; }
+               | /*EMPTY*/                                                             { $$ = NIL; }
+               ;
+
+columnList:  columnList ',' columnElem
+                               { $$ = lappend($1, $3); }
+               | columnElem
+                               { $$ = makeList1($1); }
+               ;
+
+columnElem:  ColId
+                               {
+                                       Ident *id = makeNode(Ident);
+                                       id->name = $1;
+                                       $$ = (Node *)id;
+                               }
+               ;
+
 key_match:  MATCH FULL
                        {
                                $$ = "FULL";
@@ -1624,7 +1662,7 @@ key_reference:  NO ACTION                         { $$ = FKCONSTR_ON_KEY_NOACTION; }
                | SET DEFAULT                                   { $$ = FKCONSTR_ON_KEY_SETDEFAULT; }
                ;
 
-OptInherit:  INHERITS '(' relation_name_list ')'       { $$ = $3; }
+OptInherit:  INHERITS '(' qualified_name_list ')'      { $$ = $3; }
                | /*EMPTY*/                                                                     { $$ = NIL; }
                ;
 
@@ -1639,7 +1677,7 @@ OptWithOids:  WITH OIDS                                           { $$ = TRUE; }
  * SELECT ... INTO.
  */
 
-CreateAsStmt:  CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt
+CreateAsStmt:  CREATE OptTemp TABLE qualified_name OptCreateAs AS SelectStmt
                                {
                                        /*
                                         * When the SelectStmt is a set-operation tree, we must
@@ -1651,7 +1689,7 @@ CreateAsStmt:  CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt
                                        SelectStmt *n = findLeftmostSelect((SelectStmt *) $7);
                                        if (n->into != NULL)
                                                elog(ERROR,"CREATE TABLE AS may not specify INTO");
-                                       n->istemp = $2;
+                                       $4->istemp = $2;
                                        n->into = $4;
                                        n->intoColNames = $5;
                                        $$ = $7;
@@ -1687,11 +1725,11 @@ CreateAsElement:  ColId
  *
  *****************************************************************************/
 
-CreateSeqStmt:  CREATE OptTemp SEQUENCE relation_name OptSeqList
+CreateSeqStmt:  CREATE OptTemp SEQUENCE qualified_name OptSeqList
                                {
                                        CreateSeqStmt *n = makeNode(CreateSeqStmt);
-                                       n->istemp = $2;
-                                       n->seqname = $4;
+                                       $4->istemp = $2;
+                                       n->sequence = $4;
                                        n->options = $5;
                                        $$ = (Node *)n;
                                }
@@ -1742,6 +1780,7 @@ OptSeqElem:  CACHE NumericOnly
 
 NumericOnly:  FloatOnly                                        { $$ = $1; }
                        | IntegerOnly                           { $$ = $1; }
+               ;
 
 FloatOnly:  FCONST
                                {
@@ -1791,6 +1830,7 @@ opt_trusted:  TRUSTED                     { $$ = TRUE; }
 
 opt_lancompiler: LANCOMPILER Sconst { $$ = $2; }
                        | /*EMPTY*/                     { $$ = ""; }
+               ;
 
 DropPLangStmt:  DROP opt_procedural LANGUAGE ColId_or_Sconst
                        {
@@ -1813,12 +1853,12 @@ opt_procedural: PROCEDURAL              { $$ = TRUE; }
  *****************************************************************************/
 
 CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
-                               relation_name TriggerForSpec EXECUTE PROCEDURE
+                               qualified_name TriggerForSpec EXECUTE PROCEDURE
                                name '(' TriggerFuncArgs ')'
                                {
                                        CreateTrigStmt *n = makeNode(CreateTrigStmt);
                                        n->trigname = $3;
-                                       n->relname = $7;
+                                       n->relation = $7;
                                        n->funcname = $11;
                                        n->args = $13;
                                        n->before = $4;
@@ -1832,17 +1872,17 @@ CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
                                        n->isconstraint  = FALSE;
                                        n->deferrable    = FALSE;
                                        n->initdeferred  = FALSE;
-                                       n->constrrelname = NULL;
+                                       n->constrrel = NULL;
                                        $$ = (Node *)n;
                                }
                | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
-                               relation_name OptConstrFromTable 
+                               qualified_name OptConstrFromTable 
                                ConstraintAttributeSpec
                                FOR EACH ROW EXECUTE PROCEDURE name '(' TriggerFuncArgs ')'
                                {
                                        CreateTrigStmt *n = makeNode(CreateTrigStmt);
                                        n->trigname = $4;
-                                       n->relname = $8;
+                                       n->relation = $8;
                                        n->funcname = $16;
                                        n->args = $18;
                                        n->before = FALSE;
@@ -1857,7 +1897,7 @@ CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
                                        n->deferrable = ($10 & 1) != 0;
                                        n->initdeferred = ($10 & 2) != 0;
 
-                                       n->constrrelname = $9;
+                                       n->constrrel = $9;
                                        $$ = (Node *)n;
                                }
                ;
@@ -1937,9 +1977,9 @@ TriggerFuncArg:  ICONST
 
 OptConstrFromTable:                    /* Empty */
                                {
-                                       $$ = "";
+                                       $$ = NULL;
                                }
-               | FROM relation_name
+               | FROM qualified_name
                                {
                                        $$ = $2;
                                }
@@ -1983,11 +2023,11 @@ ConstraintTimeSpec: INITIALLY IMMEDIATE
                ;
 
 
-DropTrigStmt:  DROP TRIGGER name ON relation_name
+DropTrigStmt:  DROP TRIGGER name ON qualified_name
                                {
                                        DropTrigStmt *n = makeNode(DropTrigStmt);
                                        n->trigname = $3;
-                                       n->relname = $5;
+                                       n->relation = $5;
                                        $$ = (Node *) n;
                                }
                ;
@@ -2063,11 +2103,14 @@ def_arg:  func_return                                   {  $$ = (Node *)$1; }
  *
  *****************************************************************************/
 
-DropStmt:  DROP drop_type name_list opt_drop_behavior
+/* DropStmt needs to use qualified_name_list as many of the objects
+ * are relations or other schema objects (names can be schema-qualified) */
+DropStmt:  DROP drop_type qualified_name_list opt_drop_behavior
                                {
                                        DropStmt *n = makeNode(DropStmt);
                                        n->removeType = $2;
-                                       n->names = $3;
+                                       n->objects = $3;
                                        n->behavior = $4;
                                        $$ = (Node *)n;
                                }
@@ -2089,10 +2132,10 @@ drop_type: TABLE                                                                { $$ = DROP_TABLE; }
  *
  *****************************************************************************/
 
-TruncateStmt:  TRUNCATE opt_table relation_name
+TruncateStmt:  TRUNCATE opt_table qualified_name
                                {
                                        TruncateStmt *n = makeNode(TruncateStmt);
-                                       n->relName = $3;
+                                       n->relation = $3;
                                        $$ = (Node *)n;
                                }
                        ;
@@ -2120,20 +2163,41 @@ CommentStmt:    COMMENT ON comment_type name IS comment_text
                                n->comment = $6;
                                $$ = (Node *) n;
                        }
-               | COMMENT ON COLUMN relation_name '.' attr_name IS comment_text
+               | COMMENT ON COLUMN ColId '.' attr_name IS comment_text
                        {
+                               /*
+                                * We can't use qualified_name here as the '.' causes a shift/red; 
+                                * with ColId we do not test for NEW and OLD as table names, but it is OK
+                                * as they would fail anyway as COMMENT cannot appear in a RULE.
+                                * ColumnRef is also innapropriate as we don't take subscripts
+                                * or '*' and have a very precise number of elements (2 or 3)
+                                * so we do it from scratch.
+                                */
                                CommentStmt *n = makeNode(CommentStmt);
                                n->objtype = COLUMN;
+                               n->objschema = NULL;
                                n->objname = $4;
                                n->objproperty = $6;
                                n->objlist = NULL;
                                n->comment = $8;
                                $$ = (Node *) n;
                        }
+               | COMMENT ON COLUMN ColId '.' ColId '.' attr_name IS comment_text
+                       {
+                               CommentStmt *n = makeNode(CommentStmt);
+                               n->objtype = COLUMN;
+                               n->objschema = $4;
+                               n->objname = $6;
+                               n->objproperty = $8;
+                               n->objlist = NULL;
+                               n->comment = $10;
+                               $$ = (Node *) n;
+                       }
                | COMMENT ON AGGREGATE name '(' aggr_argtype ')' IS comment_text
                        {
                                CommentStmt *n = makeNode(CommentStmt);
                                n->objtype = AGGREGATE;
+                               n->objschema = NULL;
                                n->objname = $4;
                                n->objproperty = NULL;
                                n->objlist = makeList1($6);
@@ -2145,6 +2209,7 @@ CommentStmt:      COMMENT ON comment_type name IS comment_text
                                /* Obsolete syntax, but must support for awhile */
                                CommentStmt *n = makeNode(CommentStmt);
                                n->objtype = AGGREGATE;
+                               n->objschema = NULL;
                                n->objname = $4;
                                n->objproperty = NULL;
                                n->objlist = makeList1($5);
@@ -2155,6 +2220,7 @@ CommentStmt:      COMMENT ON comment_type name IS comment_text
                        {
                                CommentStmt *n = makeNode(CommentStmt);
                                n->objtype = FUNCTION;
+                               n->objschema = NULL;
                                n->objname = $4;
                                n->objproperty = NULL;
                                n->objlist = $5;
@@ -2165,18 +2231,21 @@ CommentStmt:    COMMENT ON comment_type name IS comment_text
                        {
                                CommentStmt *n = makeNode(CommentStmt);
                                n->objtype = OPERATOR;
+                               n->objschema = NULL;
                                n->objname = $4;
                                n->objproperty = NULL;
                                n->objlist = $6;
                                n->comment = $9;
                                $$ = (Node *) n;
                        }
-               | COMMENT ON TRIGGER name ON relation_name IS comment_text
+               | COMMENT ON TRIGGER name ON qualified_name IS comment_text
                        {
                                CommentStmt *n = makeNode(CommentStmt);
                                n->objtype = TRIGGER;
+                               /* NOTE: schemaname here refers to the table in objproperty */
+                               n->objschema = $6->schemaname;
                                n->objname = $4;
-                               n->objproperty = $6;
+                               n->objproperty = $6->relname;
                                n->objlist = NULL;
                                n->comment = $8;
                                $$ = (Node *) n;
@@ -2414,14 +2483,14 @@ privilege: SELECT    { $$ = SELECT; }
 
 /* Don't bother trying to fold the first two rules into one using
    opt_table.  You're going to get conflicts. */
-privilege_target: relation_name_list
+privilege_target: qualified_name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
                                        n->objtype = TABLE;
                                        n->objs = $1;
                                        $$ = n;
                                }
-                       | TABLE relation_name_list
+                       | TABLE qualified_name_list
                                {
                                        PrivTarget *n = makeNode(PrivTarget);
                                        n->objtype = TABLE;
@@ -2513,13 +2582,13 @@ function_with_argtypes: func_name func_args
  *
  *****************************************************************************/
 
-IndexStmt:     CREATE index_opt_unique INDEX index_name ON relation_name
+IndexStmt:     CREATE index_opt_unique INDEX index_name ON qualified_name
                        access_method_clause '(' index_params ')' where_clause
                                {
                                        IndexStmt *n = makeNode(IndexStmt);
                                        n->unique = $2;
                                        n->idxname = $4;
-                                       n->relname = $6;
+                                       n->relation = $6;
                                        n->accessMethod = $7;
                                        n->indexParams = $9;
                                        n->whereClause = $11;
@@ -2783,11 +2852,21 @@ oper_argtypes:  Typename
  *
  *****************************************************************************/
 
-ReindexStmt:  REINDEX reindex_type name opt_force
+ReindexStmt:  REINDEX reindex_type qualified_name opt_force
                                {
                                        ReindexStmt *n = makeNode(ReindexStmt);
                                        n->reindexType = $2;
+                                       n->relation = $3;
+                                       n->name = NULL;
+                                       n->force = $4;
+                                       $$ = (Node *)n;
+                               }
+               | REINDEX DATABASE name opt_force
+                               {
+                                       ReindexStmt *n = makeNode(ReindexStmt);
+                                       n->reindexType = DATABASE;
                                        n->name = $3;
+                                       n->relation = NULL;
                                        n->force = $4;
                                        $$ = (Node *)n;
                                }
@@ -2795,8 +2874,8 @@ ReindexStmt:  REINDEX reindex_type name opt_force
 
 reindex_type:  INDEX                                                           {  $$ = INDEX; }
                | TABLE                                                                         {  $$ = TABLE; }
-               | DATABASE                                                                      {  $$ = DATABASE; }
                ;
+
 opt_force:     FORCE                                                                   {  $$ = TRUE; }
                | /* EMPTY */                                                           {  $$ = FALSE; }
                ;
@@ -2813,8 +2892,7 @@ opt_force:        FORCE                                                                   {  $$ = TRUE; }
 RenameStmt:  ALTER TABLE relation_expr RENAME opt_column opt_name TO name
                                {
                                        RenameStmt *n = makeNode(RenameStmt);
-                                       n->relname = $3->relname;
-                                       n->inhOpt = $3->inhOpt;
+                                       n->relation = $3;
                                        n->column = $6;
                                        n->newname = $8;
                                        $$ = (Node *)n;
@@ -2832,23 +2910,20 @@ opt_column:  COLUMN                                             { $$ = COLUMN; }
 
 /*****************************************************************************
  *
- *             QUERY:  Define Rewrite Rule , Define Tuple Rule
- *                             Define Rule <old rules >
- *
- *             only rewrite rule is supported -- ay 9/94
+ *             QUERY:  Define Rewrite Rule
  *
  *****************************************************************************/
 
 RuleStmt:  CREATE RULE name AS
                   { QueryIsRule=TRUE; }
-                  ON event TO event_object where_clause
+                  ON event TO qualified_name where_clause
                   DO opt_instead RuleActionList
                                {
                                        RuleStmt *n = makeNode(RuleStmt);
+                                       n->relation = $9;
                                        n->rulename = $3;
-                                       n->event = $7;
-                                       n->object = $9;
                                        n->whereClause = $10;
+                                       n->event = $7;
                                        n->instead = $12;
                                        n->actions = $13;
                                        $$ = (Node *)n;
@@ -2888,24 +2963,6 @@ RuleActionStmtOrEmpty:   RuleActionStmt
                                { $$ = (Node *)NULL; }
                ;
 
-event_object:  relation_name '.' attr_name
-                               {
-                                       $$ = makeNode(Attr);
-                                       $$->relname = $1;
-                                       $$->paramNo = NULL;
-                                       $$->attrs = makeList1(makeString($3));
-                                       $$->indirection = NIL;
-                               }
-               | relation_name
-                               {
-                                       $$ = makeNode(Attr);
-                                       $$->relname = $1;
-                                       $$->paramNo = NULL;
-                                       $$->attrs = NIL;
-                                       $$->indirection = NIL;
-                               }
-               ;
-
 /* change me to select, update, etc. some day */
 event: SELECT                                                  { $$ = CMD_SELECT; }
                | UPDATE                                                { $$ = CMD_UPDATE; }
@@ -2921,40 +2978,42 @@ opt_instead:  INSTEAD                                   { $$ = TRUE; }
 /*****************************************************************************
  *
  *             QUERY:
- *                             NOTIFY <relation_name>  can appear both in rule bodies and
+ *                             NOTIFY <qualified_name> can appear both in rule bodies and
  *                             as a query-level command
  *
  *****************************************************************************/
 
-NotifyStmt:  NOTIFY relation_name
+NotifyStmt:  NOTIFY qualified_name
                                {
                                        NotifyStmt *n = makeNode(NotifyStmt);
-                                       n->relname = $2;
+                                       n->relation = $2;
                                        $$ = (Node *)n;
                                }
                ;
 
-ListenStmt:  LISTEN relation_name
+ListenStmt:  LISTEN qualified_name
                                {
                                        ListenStmt *n = makeNode(ListenStmt);
-                                       n->relname = $2;
+                                       n->relation = $2;
                                        $$ = (Node *)n;
                                }
-;
+               ;
 
-UnlistenStmt:  UNLISTEN relation_name
+UnlistenStmt:  UNLISTEN qualified_name
                                {
                                        UnlistenStmt *n = makeNode(UnlistenStmt);
-                                       n->relname = $2;
+                                       n->relation = $2;
                                        $$ = (Node *)n;
                                }
                | UNLISTEN '*'
                                {
                                        UnlistenStmt *n = makeNode(UnlistenStmt);
-                                       n->relname = "*";
+                                       n->relation = makeNode(RangeVar);
+                                       n->relation->relname = "*";
+                                       n->relation->schemaname = NULL;
                                        $$ = (Node *)n;
                                }
-;
+               ;
 
 
 /*****************************************************************************
@@ -3036,10 +3095,10 @@ opt_chain: AND NO CHAIN
  *
  *****************************************************************************/
 
-ViewStmt:  CREATE VIEW name opt_column_list AS SelectStmt
+ViewStmt:  CREATE VIEW qualified_name opt_column_list AS SelectStmt
                                {
                                        ViewStmt *n = makeNode(ViewStmt);
-                                       n->viewname = $3;
+                                       n->view = $3;
                                        n->aliases = $4;
                                        n->query = (Query *) $6;
                                        $$ = (Node *)n;
@@ -3067,7 +3126,6 @@ LoadStmt:  LOAD file_name
  *
  *             CREATE DATABASE
  *
- *
  *****************************************************************************/
 
 CreatedbStmt:  CREATE DATABASE database_name WITH createdb_opt_list
@@ -3192,21 +3250,6 @@ opt_equal: '='                                                           { $$ = TRUE; }
 
 /*****************************************************************************
  *
- *             DROP DATABASE
- *
- *****************************************************************************/
-
-DropdbStmt:    DROP DATABASE database_name
-                               {
-                                       DropdbStmt *n = makeNode(DropdbStmt);
-                                       n->dbname = $3;
-                                       $$ = (Node *)n;
-                               }
-               ;
-
-
-/*****************************************************************************
- *
  *             ALTER DATABASE
  *
  *****************************************************************************/
@@ -3229,10 +3272,25 @@ AlterDatabaseSetStmt: ALTER DATABASE database_name VariableSetStmt
                                }
                ;
 
+
 /*****************************************************************************
  *
- * Manipulate a domain
+ *             DROP DATABASE
+ *
+ *****************************************************************************/
+
+DropdbStmt:    DROP DATABASE database_name
+                               {
+                                       DropdbStmt *n = makeNode(DropdbStmt);
+                                       n->dbname = $3;
+                                       $$ = (Node *)n;
+                               }
+               ;
+
+
+/*****************************************************************************
  *
+ * Manipulate a domain
  *
  *****************************************************************************/
 
@@ -3254,17 +3312,18 @@ opt_as: AS      {$$ = TRUE; }
        | /* EMPTY */   {$$ = FALSE; }
        ;
 
+
 /*****************************************************************************
  *
  *             QUERY:
- *                             cluster <index_name> on <relation_name>
+ *                             cluster <index_name> on <qualified_name>
  *
  *****************************************************************************/
 
-ClusterStmt:  CLUSTER index_name ON relation_name
+ClusterStmt:  CLUSTER index_name ON qualified_name
                                {
                                   ClusterStmt *n = makeNode(ClusterStmt);
-                                  n->relname = $4;
+                                  n->relation = $4;
                                   n->indexname = $2;
                                   $$ = (Node*)n;
                                }
@@ -3286,11 +3345,11 @@ VacuumStmt:  VACUUM opt_full opt_freeze opt_verbose
                                        n->full = $2;
                                        n->freeze = $3;
                                        n->verbose = $4;
-                                       n->vacrel = NULL;
+                                       n->relation = NULL;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
                                }
-               | VACUUM opt_full opt_freeze opt_verbose relation_name
+               | VACUUM opt_full opt_freeze opt_verbose qualified_name
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
                                        n->vacuum = true;
@@ -3298,7 +3357,7 @@ VacuumStmt:  VACUUM opt_full opt_freeze opt_verbose
                                        n->full = $2;
                                        n->freeze = $3;
                                        n->verbose = $4;
-                                       n->vacrel = $5;
+                                       n->relation = $5;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
                                }
@@ -3321,11 +3380,11 @@ AnalyzeStmt:  analyze_keyword opt_verbose
                                        n->full = false;
                                        n->freeze = false;
                                        n->verbose = $2;
-                                       n->vacrel = NULL;
+                                       n->relation = NULL;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
                                }
-               | analyze_keyword opt_verbose relation_name opt_name_list
+               | analyze_keyword opt_verbose qualified_name opt_name_list
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
                                        n->vacuum = false;
@@ -3333,7 +3392,7 @@ AnalyzeStmt:  analyze_keyword opt_verbose
                                        n->full = false;
                                        n->freeze = false;
                                        n->verbose = $2;
-                                       n->vacrel = $3;
+                                       n->relation = $3;
                                        n->va_cols = $4;
                                        $$ = (Node *)n;
                                }
@@ -3413,15 +3472,9 @@ OptimizableStmt:  SelectStmt
  *
  *****************************************************************************/
 
-/* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
- * originally. When the second rule of 'insert_rest' was changed to use the
- * new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/reduce
- * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to
- * accept the same statements without any shift/reduce conflicts
- */
-InsertStmt:  INSERT INTO relation_name insert_rest
+InsertStmt:  INSERT INTO qualified_name insert_rest
                                {
-                                       $4->relname = $3;
+                                       $4->relation = $3;
                                        $$ = (Node *) $4;
                                }
                ;
@@ -3447,14 +3500,14 @@ insert_rest:  VALUES '(' target_list ')'
                                        $$->targetList = NIL;
                                        $$->selectStmt = $1;
                                }
-               | '(' columnList ')' VALUES '(' target_list ')'
+               | '(' insert_column_list ')' VALUES '(' target_list ')'
                                {
                                        $$ = makeNode(InsertStmt);
                                        $$->cols = $2;
                                        $$->targetList = $6;
                                        $$->selectStmt = NULL;
                                }
-               | '(' columnList ')' SelectStmt
+               | '(' insert_column_list ')' SelectStmt
                                {
                                        $$ = makeNode(InsertStmt);
                                        $$->cols = $2;
@@ -3463,22 +3516,19 @@ insert_rest:  VALUES '(' target_list ')'
                                }
                ;
 
-opt_column_list:  '(' columnList ')'                   { $$ = $2; }
-               | /*EMPTY*/                                                             { $$ = NIL; }
-               ;
-
-columnList:  columnList ',' columnElem
+insert_column_list:  insert_column_list ',' insert_column_item
                                { $$ = lappend($1, $3); }
-               | columnElem
+               | insert_column_item
                                { $$ = makeList1($1); }
                ;
 
-columnElem:  ColId opt_indirection
+insert_column_item:  ColId opt_indirection
                                {
-                                       Ident *id = makeNode(Ident);
-                                       id->name = $1;
-                                       id->indirection = $2;
-                                       $$ = (Node *)id;
+                                       ResTarget *n = makeNode(ResTarget);
+                                       n->name = $1;
+                                       n->indirection = $2;
+                                       n->val = NULL;
+                                       $$ = (Node *)n;
                                }
                ;
 
@@ -3493,18 +3543,17 @@ columnElem:  ColId opt_indirection
 DeleteStmt:  DELETE FROM relation_expr where_clause
                                {
                                        DeleteStmt *n = makeNode(DeleteStmt);
-                                       n->relname = $3->relname;
-                                       n->inhOpt = $3->inhOpt;
+                                       n->relation = $3;
                                        n->whereClause = $4;
                                        $$ = (Node *)n;
                                }
                ;
 
-LockStmt:      LOCK_P opt_table relation_name_list opt_lock
+LockStmt:      LOCK_P opt_table qualified_name_list opt_lock
                                {
                                        LockStmt *n = makeNode(LockStmt);
 
-                                       n->rellist = $3;
+                                       n->relations = $3;
                                        n->mode = $4;
                                        $$ = (Node *)n;
                                }
@@ -3538,8 +3587,7 @@ UpdateStmt:  UPDATE relation_expr
                          where_clause
                                {
                                        UpdateStmt *n = makeNode(UpdateStmt);
-                                       n->relname = $2->relname;
-                                       n->inhOpt = $2->inhOpt;
+                                       n->relation = $2;
                                        n->targetList = $4;
                                        n->fromClause = $5;
                                        n->whereClause = $6;
@@ -3687,8 +3735,7 @@ simple_select: SELECT opt_distinct target_list
                                        SelectStmt *n = makeNode(SelectStmt);
                                        n->distinctClause = $2;
                                        n->targetList = $3;
-                                       n->istemp = (bool) ((Value *) lfirst($4))->val.ival;
-                                       n->into = (char *) lnext($4);
+                                       n->into = $4;
                                        n->intoColNames = NIL;
                                        n->fromClause = $5;
                                        n->whereClause = $6;
@@ -3710,40 +3757,56 @@ simple_select: SELECT opt_distinct target_list
                        }
                ; 
 
-               /* easy way to return two values. Can someone improve this?  bjm */
 into_clause:  INTO OptTempTableName            { $$ = $2; }
-               | /*EMPTY*/                                             { $$ = makeList1(makeInteger(FALSE)); }
+               | /*EMPTY*/             { $$ = NULL; }
                ;
 
 /*
  * Redundancy here is needed to avoid shift/reduce conflicts,
  * since TEMP is not a reserved word.  See also OptTemp.
- *
- * The result is a cons cell (not a true list!) containing
- * a boolean and a table name.
  */
-OptTempTableName:  TEMPORARY opt_table relation_name
-                               { $$ = lcons(makeInteger(TRUE), (List *) $3); }
-                       | TEMP opt_table relation_name
-                               { $$ = lcons(makeInteger(TRUE), (List *) $3); }
-                       | LOCAL TEMPORARY opt_table relation_name
-                               { $$ = lcons(makeInteger(TRUE), (List *) $4); }
-                       | LOCAL TEMP opt_table relation_name
-                               { $$ = lcons(makeInteger(TRUE), (List *) $4); }
-                       | GLOBAL TEMPORARY opt_table relation_name
+OptTempTableName:  TEMPORARY opt_table qualified_name
+                               { 
+                                       $$ = $3;
+                                       $$->istemp = true;
+                               }
+                       | TEMP opt_table qualified_name
+                               { 
+                                       $$ = $3;
+                                       $$->istemp = true;
+                               }
+                       | LOCAL TEMPORARY opt_table qualified_name
+                               { 
+                                       $$ = $4;
+                                       $$->istemp = true;
+                               }
+                       | LOCAL TEMP opt_table qualified_name
+                               { 
+                                       $$ = $4;
+                                       $$->istemp = true;
+                               }
+                       | GLOBAL TEMPORARY opt_table qualified_name
                                {
                                        elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
-                                       $$ = lcons(makeInteger(TRUE), (List *) $4);
+                                       $$ = $4;
+                                       $$->istemp = true;
                                }
-                       | GLOBAL TEMP opt_table relation_name
+                       | GLOBAL TEMP opt_table qualified_name
                                {
                                        elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
-                                       $$ = lcons(makeInteger(TRUE), (List *) $4);
+                                       $$ = $4;
+                                       $$->istemp = true;
+                               }
+                       | TABLE qualified_name
+                               { 
+                                       $$ = $2;
+                                       $$->istemp = false;
+                               }
+                       | qualified_name
+                               { 
+                                       $$ = $1;
+                                       $$->istemp = false;
                                }
-                       | TABLE relation_name
-                               { $$ = lcons(makeInteger(FALSE), (List *) $2); }
-                       | relation_name
-                               { $$ = lcons(makeInteger(FALSE), (List *) $1); }
                ;
 
 opt_table:  TABLE                                                              { $$ = TRUE; }
@@ -3878,13 +3941,6 @@ select_offset_value:     Iconst
  *     ...however, recursive addattr and rename supported.  make special
  *     cases for these.
  */
-relation_name_list:  name_list;
-
-name_list:  name
-                               {       $$ = makeList1(makeString($1)); }
-               | name_list ',' name
-                               {       $$ = lappend($1, makeString($3)); }
-               ;
 
 group_clause:  GROUP BY expr_list                              { $$ = $3; }
                | /*EMPTY*/                                                             { $$ = NIL; }
@@ -3938,7 +3994,7 @@ table_ref:  relation_expr
                                }
                | relation_expr alias_clause
                                {
-                                       $1->name = $2;
+                                       $1->alias = $2;
                                        $$ = (Node *) $1;
                                }
                | select_with_parens
@@ -3962,7 +4018,7 @@ table_ref:  relation_expr
                                {
                                        RangeSubselect *n = makeNode(RangeSubselect);
                                        n->subquery = $1;
-                                       n->name = $2;
+                                       n->alias = $2;
                                        $$ = (Node *) n;
                                }
                | joined_table
@@ -4077,25 +4133,25 @@ joined_table:  '(' joined_table ')'
 
 alias_clause:  AS ColId '(' name_list ')'
                                {
-                                       $$ = makeNode(Attr);
-                                       $$->relname = $2;
-                                       $$->attrs = $4;
+                                       $$ = makeNode(Alias);
+                                       $$->aliasname = $2;
+                                       $$->colnames = $4;
                                }
                | AS ColId
                                {
-                                       $$ = makeNode(Attr);
-                                       $$->relname = $2;
+                                       $$ = makeNode(Alias);
+                                       $$->aliasname = $2;
                                }
                | ColId '(' name_list ')'
                                {
-                                       $$ = makeNode(Attr);
-                                       $$->relname = $1;
-                                       $$->attrs = $3;
+                                       $$ = makeNode(Alias);
+                                       $$->aliasname = $1;
+                                       $$->colnames = $3;
                                }
                | ColId
                                {
-                                       $$ = makeNode(Attr);
-                                       $$->relname = $1;
+                                       $$ = makeNode(Alias);
+                                       $$->aliasname = $1;
                                }
                ;
 
@@ -4124,29 +4180,26 @@ join_qual:  USING '(' name_list ')'                             { $$ = (Node *) $3; }
                ;
 
 
-relation_expr: relation_name
+relation_expr: qualified_name
                                {
                                        /* default inheritance */
-                                       $$ = makeNode(RangeVar);
-                                       $$->relname = $1;
+                                       $$ = $1;
                                        $$->inhOpt = INH_DEFAULT;
-                                       $$->name = NULL;
+                                       $$->alias = NULL;
                                }
-               | relation_name '*'
+               | qualified_name '*'
                                {
                                        /* inheritance query */
-                                       $$ = makeNode(RangeVar);
-                                       $$->relname = $1;
+                                       $$ = $1;
                                        $$->inhOpt = INH_YES;
-                                       $$->name = NULL;
+                                       $$->alias = NULL;
                                }
-               | ONLY relation_name
+               | ONLY qualified_name
                                {
                                        /* no inheritance */
-                                       $$ = makeNode(RangeVar);
-                                       $$->relname = $2;
+                                       $$ = $2;
                                        $$->inhOpt = INH_NO;
-                                       $$->name = NULL;
+                                       $$->alias = NULL;
                 }
                ;
 
@@ -4357,6 +4410,7 @@ bit:  BIT opt_varying
                                        else type = xlateSqlType("bit");
                                        $$ = type;
                                }
+               ;
 
 
 /*
@@ -5010,20 +5064,32 @@ b_expr:  c_expr
  * inside parentheses, such as function arguments; that cannot introduce
  * ambiguity to the b_expr syntax.
  */
-c_expr:  attr
+c_expr:  columnref
                                {       $$ = (Node *) $1;  }
-               | ColId opt_indirection
+               | AexprConst
+                               {       $$ = $1;  }
+               | PARAM attrs opt_indirection
                                {
-                                       /* could be a column name or a relation_name */
-                                       Ident *n = makeNode(Ident);
-                                       n->name = $1;
-                                       n->indirection = $2;
+                                       /*
+                                        * PARAM without field names is considered a constant,
+                                        * but with 'em, it is not.  Not very consistent ...
+                                        */
+                                       ParamRef *n = makeNode(ParamRef);
+                                       n->number = $1;
+                                       n->fields = $2;
+                                       n->indirection = $3;
                                        $$ = (Node *)n;
                                }
-               | AexprConst
-                               {       $$ = $1;  }
                | '(' a_expr ')'
                                {       $$ = $2; }
+               | '(' a_expr ')' attrs opt_indirection
+                               {
+                                       ExprFieldSelect *n = makeNode(ExprFieldSelect);
+                                       n->arg = $2;
+                                       n->fields = $4;
+                                       n->indirection = $5;
+                                       $$ = (Node *)n;
+                               }
                | CAST '(' a_expr AS Typename ')'
                                {       $$ = makeTypeCast($3, $5); }
                | case_expr
@@ -5569,34 +5635,40 @@ case_arg:  a_expr
                                {       $$ = NULL; }
                ;
 
-attr:  relation_name '.' attrs opt_indirection
+/*
+ * columnref starts with relation_name not ColId, so that OLD and NEW
+ * references can be accepted.  Note that when there are more than two
+ * dotted names, the first name is not actually a relation name...
+ */
+columnref: relation_name opt_indirection
                                {
-                                       $$ = makeNode(Attr);
-                                       $$->relname = $1;
-                                       $$->paramNo = NULL;
-                                       $$->attrs = $3;
-                                       $$->indirection = $4;
+                                       $$ = makeNode(ColumnRef);
+                                       $$->fields = makeList1(makeString($1));
+                                       $$->indirection = $2;
                                }
-               | ParamNo '.' attrs opt_indirection
+               | relation_name attrs opt_indirection
                                {
-                                       $$ = makeNode(Attr);
-                                       $$->relname = NULL;
-                                       $$->paramNo = $1;
-                                       $$->attrs = $3;
-                                       $$->indirection = $4;
+                                       $$ = makeNode(ColumnRef);
+                                       $$->fields = lcons(makeString($1), $2);
+                                       $$->indirection = $3;
                                }
                ;
 
-attrs:   attr_name
-                               { $$ = makeList1(makeString($1)); }
-               | attrs '.' attr_name
+attrs:   opt_attrs '.' attr_name
                                { $$ = lappend($1, makeString($3)); }
-               | attrs '.' '*'
+               | opt_attrs '.' '*'
                                { $$ = lappend($1, makeString("*")); }
                ;
 
+opt_attrs: /*EMPTY*/
+                               { $$ = NIL; }
+               | opt_attrs '.' attr_name
+                               { $$ = lappend($1, makeString($3)); }
+               ;
+
 opt_empty_parentheses: '(' ')' { $$ = TRUE; }
                                        | /*EMPTY*/ { $$ = TRUE; }
+               ;
 
 /*****************************************************************************
  *
@@ -5617,39 +5689,25 @@ target_el:  a_expr AS ColLabel
                                {
                                        $$ = makeNode(ResTarget);
                                        $$->name = $3;
-                                       $$->indirection = NULL;
+                                       $$->indirection = NIL;
                                        $$->val = (Node *)$1;
                                }
                | a_expr
                                {
                                        $$ = makeNode(ResTarget);
                                        $$->name = NULL;
-                                       $$->indirection = NULL;
+                                       $$->indirection = NIL;
                                        $$->val = (Node *)$1;
                                }
-               | relation_name '.' '*'
-                               {
-                                       Attr *att = makeNode(Attr);
-                                       att->relname = $1;
-                                       att->paramNo = NULL;
-                                       att->attrs = makeList1(makeString("*"));
-                                       att->indirection = NIL;
-                                       $$ = makeNode(ResTarget);
-                                       $$->name = NULL;
-                                       $$->indirection = NULL;
-                                       $$->val = (Node *)att;
-                               }
                | '*'
                                {
-                                       Attr *att = makeNode(Attr);
-                                       att->relname = "*";
-                                       att->paramNo = NULL;
-                                       att->attrs = NULL;
-                                       att->indirection = NIL;
+                                       ColumnRef *n = makeNode(ColumnRef);
+                                       n->fields = makeList1(makeString("*"));
+                                       n->indirection = NIL;
                                        $$ = makeNode(ResTarget);
                                        $$->name = NULL;
-                                       $$->indirection = NULL;
-                                       $$->val = (Node *)att;
+                                       $$->indirection = NIL;
+                                       $$->val = (Node *)n;
                                }
                ;
 
@@ -5685,6 +5743,42 @@ relation_name:   SpecialRuleRelation
                                        $$ = $1;
                                }
                ;
+               
+qualified_name_list:  qualified_name
+                               {       $$ = makeList1($1); }
+               | qualified_name_list ',' qualified_name
+                               {       $$ = lappend($1, $3); }
+               ;
+
+qualified_name: ColId
+                               {
+                                       $$ = makeNode(RangeVar);
+                                       $$->catalogname = NULL;
+                                       $$->schemaname = NULL;
+                                       $$->relname = $1;
+                               }
+               | ColId '.' ColId
+                               {
+                                       $$ = makeNode(RangeVar);
+                                       $$->catalogname = NULL;
+                                       $$->schemaname = $1;
+                                       $$->relname = $3;
+                               }
+               | ColId '.' ColId '.' ColId
+                               {
+                                       $$ = makeNode(RangeVar);
+                                       $$->catalogname = $1;
+                                       $$->schemaname = $3;
+                                       $$->relname = $5;
+                               }
+               ;
+
+name_list:  name
+                               {       $$ = makeList1(makeString($1)); }
+               | name_list ',' name
+                               {       $$ = lappend($1, makeString($3)); }
+               ;
+
 
 name:                                  ColId                   { $$ = $1; };
 database_name:                 ColId                   { $$ = $1; };
@@ -5761,8 +5855,14 @@ AexprConst:  Iconst
 
                                        $$ = (Node *)n;
                                }
-               | ParamNo
-                               {       $$ = (Node *)$1;  }
+               | PARAM opt_indirection
+                               {
+                                       ParamRef *n = makeNode(ParamRef);
+                                       n->number = $1;
+                                       n->fields = NIL;
+                                       n->indirection = $2;
+                                       $$ = (Node *)n;
+                               }
                | TRUE_P
                                {
                                        A_Const *n = makeNode(A_Const);
@@ -5791,14 +5891,6 @@ AexprConst:  Iconst
                                }
                ;
 
-ParamNo:  PARAM opt_indirection
-                               {
-                                       $$ = makeNode(ParamNo);
-                                       $$->number = $1;
-                                       $$->indirection = $2;
-                               }
-               ;
-
 Iconst:  ICONST                                                        { $$ = $1; };
 Sconst:  SCONST                                                        { $$ = $1; };
 UserId:  ColId                                                 { $$ = $1; };
@@ -5866,7 +5958,6 @@ unreserved_keyword:
                | AGGREGATE                                             { $$ = "aggregate"; }
                | ALTER                                                 { $$ = "alter"; }
                | AT                                                    { $$ = "at"; }
-               | AUTHORIZATION                                 { $$ = "authorization"; }
                | BACKWARD                                              { $$ = "backward"; }
                | BEFORE                                                { $$ = "before"; }
                | BEGIN_TRANS                                   { $$ = "begin"; }
@@ -5883,7 +5974,6 @@ unreserved_keyword:
                | COMMITTED                                             { $$ = "committed"; }
                | CONSTRAINTS                                   { $$ = "constraints"; }
                | COPY                                                  { $$ = "copy"; }
-               | CREATE                                                { $$ = "create"; }
                | CREATEDB                                              { $$ = "createdb"; }
                | CREATEUSER                                    { $$ = "createuser"; }
                | CURSOR                                                { $$ = "cursor"; }
@@ -5909,7 +5999,6 @@ unreserved_keyword:
                | FORWARD                                               { $$ = "forward"; }
                | FUNCTION                                              { $$ = "function"; }
                | GLOBAL                                                { $$ = "global"; }
-               | GRANT                                                 { $$ = "grant"; }
                | HANDLER                                               { $$ = "handler"; }
                | HOUR_P                                                { $$ = "hour"; }
                | IMMEDIATE                                             { $$ = "immediate"; }
@@ -6061,7 +6150,8 @@ col_name_keyword:
  *  - thomas 2000-11-28
  */
 func_name_keyword:
-                 BETWEEN                                               { $$ = "between"; }
+                 AUTHORIZATION                                 { $$ = "authorization"; }
+               | BETWEEN                                               { $$ = "between"; }
                | BINARY                                                { $$ = "binary"; }
                | CROSS                                                 { $$ = "cross"; }
                | FREEZE                                                { $$ = "freeze"; }
@@ -6104,6 +6194,7 @@ reserved_keyword:
                | COLLATE                                               { $$ = "collate"; }
                | COLUMN                                                { $$ = "column"; }
                | CONSTRAINT                                    { $$ = "constraint"; }
+               | CREATE                                                { $$ = "create"; }
                | CURRENT_DATE                                  { $$ = "current_date"; }
                | CURRENT_TIME                                  { $$ = "current_time"; }
                | CURRENT_TIMESTAMP                             { $$ = "current_timestamp"; }
@@ -6120,6 +6211,7 @@ reserved_keyword:
                | FOR                                                   { $$ = "for"; }
                | FOREIGN                                               { $$ = "foreign"; }
                | FROM                                                  { $$ = "from"; }
+               | GRANT                                                 { $$ = "grant"; }
                | GROUP                                                 { $$ = "group"; }
                | HAVING                                                { $$ = "having"; }
                | INITIALLY                                             { $$ = "initially"; }
@@ -6189,7 +6281,7 @@ static Node *
 makeTypeCast(Node *arg, TypeName *typename)
 {
        /*
-        * If arg is an A_Const or ParamNo, just stick the typename into the
+        * If arg is an A_Const, just stick the typename into the
         * field reserved for it --- unless there's something there already!
         * (We don't want to collapse x::type1::type2 into just x::type2.)
         * Otherwise, generate a TypeCast node.
@@ -6200,12 +6292,6 @@ makeTypeCast(Node *arg, TypeName *typename)
                ((A_Const *) arg)->typename = typename;
                return arg;
        }
-       else if (IsA(arg, ParamNo) &&
-                        ((ParamNo *) arg)->typename == NULL)
-       {
-               ((ParamNo *) arg)->typename = typename;
-               return arg;
-       }
        else
        {
                TypeCast *n = makeNode(TypeCast);
index d6ad0a0..dc939a7 100644 (file)
@@ -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;
index 2f1eda4..6e8868f 100644 (file)
@@ -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)
        {
index 6409ef3..73cd89f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.110 2002/03/20 19:44:25 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.111 2002/03/21 16:01:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,6 +17,7 @@
 
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
+#include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/params.h"
 #include "parser/analyze.h"
@@ -41,8 +42,7 @@ bool          Transform_null_equals = false;
 static Node *parser_typecast_constant(Value *expr, TypeName *typename);
 static Node *parser_typecast_expression(ParseState *pstate,
                                                   Node *expr, TypeName *typename);
-static Node *transformAttr(ParseState *pstate, Attr *att, int precedence);
-static Node *transformIdent(ParseState *pstate, Ident *ident, int precedence);
+static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
 static Node *transformIndirection(ParseState *pstate, Node *basenode,
                                         List *indirection);
 
@@ -85,7 +85,7 @@ parse_expr_init(void)
  * input and output of transformExpr; see SubLink for example.
  */
 Node *
-transformExpr(ParseState *pstate, Node *expr, int precedence)
+transformExpr(ParseState *pstate, Node *expr)
 {
        Node       *result = NULL;
 
@@ -105,9 +105,37 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 
        switch (nodeTag(expr))
        {
-               case T_Attr:
+               case T_ColumnRef:
                        {
-                               result = transformAttr(pstate, (Attr *) expr, precedence);
+                               result = transformColumnRef(pstate, (ColumnRef *) expr);
+                               break;
+                       }
+               case T_ParamRef:
+                       {
+                               ParamRef   *pref = (ParamRef *) expr;
+                               int                     paramno = pref->number;
+                               Oid                     paramtyp = param_type(paramno);
+                               Param      *param;
+                               List       *fields;
+
+                               if (!OidIsValid(paramtyp))
+                                       elog(ERROR, "Parameter '$%d' is out of range", paramno);
+                               param = makeNode(Param);
+                               param->paramkind = PARAM_NUM;
+                               param->paramid = (AttrNumber) paramno;
+                               param->paramname = "<unnamed>";
+                               param->paramtype = paramtyp;
+                               result = (Node *) param;
+                               /* handle qualification, if any */
+                               foreach(fields, pref->fields)
+                               {
+                                       result = ParseFuncOrColumn(pstate, strVal(lfirst(fields)),
+                                                                                          makeList1(result),
+                                                                                          false, false, true);
+                               }
+                               /* handle subscripts, if any */
+                               result = transformIndirection(pstate, result,
+                                                                                         pref->indirection);
                                break;
                        }
                case T_A_Const:
@@ -121,31 +149,28 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                        result = (Node *) make_const(val);
                                break;
                        }
-               case T_ParamNo:
+               case T_ExprFieldSelect:
                        {
-                               ParamNo    *pno = (ParamNo *) expr;
-                               int                     paramno = pno->number;
-                               Oid                     toid = param_type(paramno);
-                               Param      *param = makeNode(Param);
+                               ExprFieldSelect *efs = (ExprFieldSelect *) expr;
+                               List       *fields;
 
-                               if (!OidIsValid(toid))
-                                       elog(ERROR, "Parameter '$%d' is out of range", paramno);
-                               param->paramkind = PARAM_NUM;
-                               param->paramid = (AttrNumber) paramno;
-                               param->paramname = "<unnamed>";
-                               param->paramtype = toid;
-                               result = transformIndirection(pstate, (Node *) param,
-                                                                                         pno->indirection);
-                               /* cope with typecast applied to param */
-                               if (pno->typename != NULL)
-                                       result = parser_typecast_expression(pstate, result,
-                                                                                                               pno->typename);
+                               result = transformExpr(pstate, efs->arg);
+                               /* handle qualification, if any */
+                               foreach(fields, efs->fields)
+                               {
+                                       result = ParseFuncOrColumn(pstate, strVal(lfirst(fields)),
+                                                                                          makeList1(result),
+                                                                                          false, false, true);
+                               }
+                               /* handle subscripts, if any */
+                               result = transformIndirection(pstate, result,
+                                                                                         efs->indirection);
                                break;
                        }
                case T_TypeCast:
                        {
                                TypeCast   *tc = (TypeCast *) expr;
-                               Node       *arg = transformExpr(pstate, tc->arg, precedence);
+                               Node       *arg = transformExpr(pstate, tc->arg);
 
                                result = parser_typecast_expression(pstate, arg, tc->typename);
                                break;
@@ -179,17 +204,14 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                                                        n->arg = a->lexpr;
 
                                                                result = transformExpr(pstate,
-                                                                                                          (Node *) n,
-                                                                                                          precedence);
+                                                                                                          (Node *) n);
                                                        }
                                                        else
                                                        {
                                                                Node       *lexpr = transformExpr(pstate,
-                                                                                                                               a->lexpr,
-                                                                                                                        precedence);
+                                                                                                                               a->lexpr);
                                                                Node       *rexpr = transformExpr(pstate,
-                                                                                                                               a->rexpr,
-                                                                                                                        precedence);
+                                                                                                                               a->rexpr);
 
                                                                result = (Node *) make_op(a->opname,
                                                                                                                  lexpr,
@@ -200,11 +222,9 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                        case AND:
                                                {
                                                        Node       *lexpr = transformExpr(pstate,
-                                                                                                                         a->lexpr,
-                                                                                                                         precedence);
+                                                                                                                         a->lexpr);
                                                        Node       *rexpr = transformExpr(pstate,
-                                                                                                                         a->rexpr,
-                                                                                                                         precedence);
+                                                                                                                         a->rexpr);
                                                        Expr       *expr = makeNode(Expr);
 
                                                        if (!coerce_to_boolean(pstate, &lexpr))
@@ -226,11 +246,9 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                        case OR:
                                                {
                                                        Node       *lexpr = transformExpr(pstate,
-                                                                                                                         a->lexpr,
-                                                                                                                         precedence);
+                                                                                                                         a->lexpr);
                                                        Node       *rexpr = transformExpr(pstate,
-                                                                                                                         a->rexpr,
-                                                                                                                         precedence);
+                                                                                                                         a->rexpr);
                                                        Expr       *expr = makeNode(Expr);
 
                                                        if (!coerce_to_boolean(pstate, &lexpr))
@@ -252,8 +270,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                        case NOT:
                                                {
                                                        Node       *rexpr = transformExpr(pstate,
-                                                                                                                         a->rexpr,
-                                                                                                                         precedence);
+                                                                                                                         a->rexpr);
                                                        Expr       *expr = makeNode(Expr);
 
                                                        if (!coerce_to_boolean(pstate, &rexpr))
@@ -270,11 +287,6 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                }
                                break;
                        }
-               case T_Ident:
-                       {
-                               result = transformIdent(pstate, (Ident *) expr, precedence);
-                               break;
-                       }
                case T_FuncCall:
                        {
                                FuncCall   *fn = (FuncCall *) expr;
@@ -283,14 +295,13 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                /* transform the list of arguments */
                                foreach(args, fn->args)
                                        lfirst(args) = transformExpr(pstate,
-                                                                                                (Node *) lfirst(args),
-                                                                                                precedence);
+                                                                                                (Node *) lfirst(args));
                                result = ParseFuncOrColumn(pstate,
                                                                                   fn->funcname,
                                                                                   fn->args,
                                                                                   fn->agg_star,
                                                                                   fn->agg_distinct,
-                                                                                  precedence);
+                                                                                  false);
                                break;
                        }
                case T_SubLink:
@@ -357,8 +368,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                        List       *elist;
 
                                        foreach(elist, left_list)
-                                               lfirst(elist) = transformExpr(pstate, lfirst(elist),
-                                                                                                         precedence);
+                                               lfirst(elist) = transformExpr(pstate, lfirst(elist));
 
                                        Assert(IsA(sublink->oper, A_Expr));
                                        op = ((A_Expr *) sublink->oper)->opname;
@@ -455,7 +465,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                                a->rexpr = warg;
                                                warg = (Node *) a;
                                        }
-                                       neww->expr = transformExpr(pstate, warg, precedence);
+                                       neww->expr = transformExpr(pstate, warg);
 
                                        if (!coerce_to_boolean(pstate, &neww->expr))
                                                elog(ERROR, "WHEN clause must have a boolean result");
@@ -472,7 +482,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                                n->val.type = T_Null;
                                                warg = (Node *) n;
                                        }
-                                       neww->result = transformExpr(pstate, warg, precedence);
+                                       neww->result = transformExpr(pstate, warg);
 
                                        newargs = lappend(newargs, neww);
                                        typeids = lappendi(typeids, exprType(neww->result));
@@ -496,7 +506,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                        n->val.type = T_Null;
                                        defresult = (Node *) n;
                                }
-                               newc->defresult = transformExpr(pstate, defresult, precedence);
+                               newc->defresult = transformExpr(pstate, defresult);
 
                                /*
                                 * Note: default result is considered the most significant
@@ -534,7 +544,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                        {
                                NullTest   *n = (NullTest *) expr;
 
-                               n->arg = transformExpr(pstate, n->arg, precedence);
+                               n->arg = transformExpr(pstate, n->arg);
                                /* the argument can be any type, so don't coerce it */
                                result = expr;
                                break;
@@ -544,7 +554,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                        {
                                BooleanTest *b = (BooleanTest *) expr;
 
-                               b->arg = transformExpr(pstate, b->arg, precedence);
+                               b->arg = transformExpr(pstate, b->arg);
 
                                if (!coerce_to_boolean(pstate, &b->arg))
                                {
@@ -627,47 +637,183 @@ transformIndirection(ParseState *pstate, Node *basenode, List *indirection)
 }
 
 static Node *
-transformAttr(ParseState *pstate, Attr *att, int precedence)
+transformColumnRef(ParseState *pstate, ColumnRef *cref)
 {
-       Node       *basenode;
+       int                     numnames = length(cref->fields);
+       Node       *node;
+       RangeVar   *rv;
+
+       /*----------
+        * The allowed syntaxes are:
+        *
+        * A            First try to resolve as unqualified column name;
+        *                      if no luck, try to resolve as unqual. table name (A.*).
+        * A.B          A is an unqual. table name; B is either a
+        *                      column or function name (trying column name first).
+        * A.B.C        schema A, table B, col or func name C.
+        * A.B.C.D      catalog A, schema B, table C, col or func D.
+        * A.*          A is an unqual. table name; means whole-row value.
+        * A.B.*        whole-row value of table B in schema A.
+        * A.B.C.*      whole-row value of table C in schema B in catalog A.
+        *
+        * We do not need to cope with bare "*"; that will only be accepted by
+        * the grammar at the top level of a SELECT list, and transformTargetList
+        * will take care of it before it ever gets here.
+        *
+        * Currently, if a catalog name is given then it must equal the current
+        * database name; we check it here and then discard it.
+        *
+        * For whole-row references, the result is an untransformed RangeVar,
+        * which will work as the argument to a function call, but not in any
+        * other context at present.  (We could instead coerce to a whole-row Var,
+        * but that will fail for subselect and join RTEs, because there is no
+        * pg_type entry for their rowtypes.)
+        *----------
+        */
+       switch (numnames)
+       {
+               case 1:
+               {
+                       char   *name = strVal(lfirst(cref->fields));
 
-       basenode = ParseNestedFuncOrColumn(pstate, att, precedence);
-       return transformIndirection(pstate, basenode, att->indirection);
-}
+                       /* Try to identify as an unqualified column */
+                       node = colnameToVar(pstate, name);
+                       if (node == NULL)
+                       {
+                               /*
+                                * Not known as a column of any range-table entry, so
+                                * try to find the name as a relation ... but not if
+                                * subscripts appear.  Note also that only relations
+                                * already entered into the rangetable will be recognized.
+                                */
+                               int             levels_up;
 
-static Node *
-transformIdent(ParseState *pstate, Ident *ident, int precedence)
-{
-       Node       *result = NULL;
-       int                     sublevels_up;
+                               if (cref->indirection == NIL &&
+                                       refnameRangeTblEntry(pstate, name, &levels_up) != NULL)
+                               {
+                                       rv = makeNode(RangeVar);
+                                       rv->relname = name;
+                                       rv->inhOpt = INH_DEFAULT;
+                                       node = (Node *) rv;
+                               }
+                               else
+                                       elog(ERROR, "Attribute \"%s\" not found", name);
+                       }
+                       break;
+               }
+               case 2:
+               {
+                       char   *name1 = strVal(lfirst(cref->fields));
+                       char   *name2 = strVal(lsecond(cref->fields));
 
-       /*
-        * try to find the ident as a relation ... but not if subscripts
-        * appear
-        */
-       if (ident->indirection == NIL &&
-               refnameRangeTblEntry(pstate, ident->name, &sublevels_up) != NULL)
-       {
-               ident->isRel = TRUE;
-               result = (Node *) ident;
-       }
+                       /* Whole-row reference? */
+                       if (strcmp(name2, "*") == 0)
+                       {
+                               rv = makeNode(RangeVar);
+                               rv->relname = name1;
+                               rv->inhOpt = INH_DEFAULT;
+                               node = (Node *) rv;
+                               break;
+                       }
 
-       if (result == NULL || precedence == EXPR_COLUMN_FIRST)
-       {
-               /* try to find the ident as a column */
-               Node       *var = colnameToVar(pstate, ident->name);
+                       /* Try to identify as a once-qualified column */
+                       node = qualifiedNameToVar(pstate, name1, name2, true);
+                       if (node == NULL)
+                       {
+                               /*
+                                * Not known as a column of any range-table entry, so
+                                * try it as a function call.  Here, we will create an
+                                * implicit RTE for tables not already entered.
+                                */
+                               rv = makeNode(RangeVar);
+                               rv->relname = name1;
+                               rv->inhOpt = INH_DEFAULT;
+                               node = ParseFuncOrColumn(pstate, name2,
+                                                                                makeList1(rv),
+                                                                                false, false, true);
+                       }
+                       break;
+               }
+               case 3:
+               {
+                       char   *name1 = strVal(lfirst(cref->fields));
+                       char   *name2 = strVal(lsecond(cref->fields));
+                       char   *name3 = strVal(lfirst(lnext(lnext(cref->fields))));
 
-               if (var != NULL)
+                       /* Whole-row reference? */
+                       if (strcmp(name3, "*") == 0)
+                       {
+                               rv = makeNode(RangeVar);
+                               rv->schemaname = name1;
+                               rv->relname = name2;
+                               rv->inhOpt = INH_DEFAULT;
+                               node = (Node *) rv;
+                               break;
+                       }
+
+                       /* Try to identify as a twice-qualified column */
+                       /* XXX do something with schema name here */
+                       node = qualifiedNameToVar(pstate, name2, name3, true);
+                       if (node == NULL)
+                       {
+                               /* Try it as a function call */
+                               rv = makeNode(RangeVar);
+                               rv->schemaname = name1;
+                               rv->relname = name2;
+                               rv->inhOpt = INH_DEFAULT;
+                               node = ParseFuncOrColumn(pstate, name3,
+                                                                                makeList1(rv),
+                                                                                false, false, true);
+                       }
+                       break;
+               }
+               case 4:
                {
-                       ident->isRel = FALSE;
-                       result = transformIndirection(pstate, var, ident->indirection);
+                       char   *name1 = strVal(lfirst(cref->fields));
+                       char   *name2 = strVal(lsecond(cref->fields));
+                       char   *name3 = strVal(lfirst(lnext(lnext(cref->fields))));
+                       char   *name4 = strVal(lfirst(lnext(lnext(lnext(cref->fields)))));
+
+                       /*
+                        * We check the catalog name and then ignore it.
+                        */
+                       if (strcmp(name1, DatabaseName) != 0)
+                               elog(ERROR, "Cross-database references are not implemented");
+
+                       /* Whole-row reference? */
+                       if (strcmp(name4, "*") == 0)
+                       {
+                               rv = makeNode(RangeVar);
+                               rv->schemaname = name2;
+                               rv->relname = name3;
+                               rv->inhOpt = INH_DEFAULT;
+                               node = (Node *) rv;
+                               break;
+                       }
+
+                       /* Try to identify as a twice-qualified column */
+                       /* XXX do something with schema name here */
+                       node = qualifiedNameToVar(pstate, name3, name4, true);
+                       if (node == NULL)
+                       {
+                               /* Try it as a function call */
+                               rv = makeNode(RangeVar);
+                               rv->schemaname = name2;
+                               rv->relname = name3;
+                               rv->inhOpt = INH_DEFAULT;
+                               node = ParseFuncOrColumn(pstate, name4,
+                                                                                makeList1(rv),
+                                                                                false, false, true);
+                       }
+                       break;
                }
+               default:
+                       elog(ERROR, "Invalid qualified name syntax (too many names)");
+                       node = NULL;            /* keep compiler quiet */
+                       break;
        }
 
-       if (result == NULL)
-               elog(ERROR, "Attribute '%s' not found", ident->name);
-
-       return result;
+       return transformIndirection(pstate, node, cref->indirection);
 }
 
 /*
@@ -748,10 +894,6 @@ exprType(Node *expr)
                case T_BooleanTest:
                        type = BOOLOID;
                        break;
-               case T_Ident:
-                       /* XXX is this right? */
-                       type = UNKNOWNOID;
-                       break;
                default:
                        elog(ERROR, "Do not know how to get type for %d node",
                                 nodeTag(expr));
index 6dc7b44..ee1bf6c 100644 (file)
@@ -8,11 +8,10 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.118 2002/03/20 19:44:29 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.119 2002/03/21 16:01:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
-
 #include "postgres.h"
 
 #include "access/genam.h"
@@ -36,8 +35,7 @@
 
 static Node *ParseComplexProjection(ParseState *pstate,
                                           char *funcname,
-                                          Node *first_arg,
-                                          bool *attisset);
+                                          Node *first_arg);
 static Oid **argtype_inherit(int nargs, Oid *argtypes);
 
 static int     find_inheritors(Oid relid, Oid **supervec);
@@ -60,75 +58,31 @@ static Oid  agg_select_candidate(Oid typeid, CandidateList candidates);
 
 
 /*
- ** ParseNestedFuncOrColumn
- **    Given a nested dot expression (i.e. (relation func ... attr), build up
- ** a tree with of Iter and Func nodes.
- */
-Node *
-ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr, int precedence)
-{
-       List       *mutator_iter;
-       Node       *retval = NULL;
-
-       if (attr->paramNo != NULL)
-       {
-               Param      *param = (Param *) transformExpr(pstate,
-                                                                                                 (Node *) attr->paramNo,
-                                                                                                       EXPR_RELATION_FIRST);
-
-               retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)),
-                                                                  makeList1(param),
-                                                                  false, false,
-                                                                  precedence);
-       }
-       else
-       {
-               Ident      *ident = makeNode(Ident);
-
-               ident->name = attr->relname;
-               ident->isRel = TRUE;
-               retval = ParseFuncOrColumn(pstate, strVal(lfirst(attr->attrs)),
-                                                                  makeList1(ident),
-                                                                  false, false,
-                                                                  precedence);
-       }
-
-       /* Do more attributes follow this one? */
-       foreach(mutator_iter, lnext(attr->attrs))
-       {
-               retval = ParseFuncOrColumn(pstate, strVal(lfirst(mutator_iter)),
-                                                                  makeList1(retval),
-                                                                  false, false,
-                                                                  precedence);
-       }
-
-       return retval;
-}
-
-/*
- *     parse function
- *
- *     This code is confusing because the database can accept
- *     relation.column, column.function, or relation.column.function.
- *     In these cases, funcname is the last parameter, and fargs are
- *     the rest.
+ *     Parse a function call
  *
- *     It can also be called as func(col) or func(col,col).
- *     In this case, Funcname is the part before parens, and fargs
- *     are the part in parens.
+ *     For historical reasons, Postgres tries to treat the notations tab.col
+ *     and col(tab) as equivalent: if a single-argument function call has an
+ *     argument of complex type and the function name matches any attribute
+ *     of the type, we take it as a column projection.
  *
- *     FYI, projection is choosing column from a table.
+ *     Hence, both cases come through here.  The is_column parameter tells us
+ *     which syntactic construct is actually being dealt with, but this is
+ *     intended to be used only to deliver an appropriate error message,
+ *     not to affect the semantics.  When is_column is true, we should have
+ *     a single argument (the putative table), function name equal to the
+ *     column name, and no aggregate decoration.
  *
+ *     In the function-call case, the argument expressions have been transformed
+ *     already.  In the column case, we may get either a transformed expression
+ *     or a RangeVar node as argument.
  */
 Node *
 ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
-                                 bool agg_star, bool agg_distinct,
-                                 int precedence)
+                                 bool agg_star, bool agg_distinct, bool is_column)
 {
-       Oid                     rettype = InvalidOid;
-       Oid                     argrelid = InvalidOid;
-       Oid                     funcid = InvalidOid;
-       List       *i = NIL;
+       Oid                     rettype;
+       Oid                     funcid;
+       List       *i;
        Node       *first_arg = NULL;
        char       *refname;
        int                     nargs = length(fargs);
@@ -140,9 +94,8 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
        bool            retset;
        bool            must_be_agg = agg_star || agg_distinct;
        bool            could_be_agg;
-       bool            attisset = false;
-       Oid                     toid = InvalidOid;
        Expr       *expr;
+       FuncDetailCode fdresult;
 
        /*
         * Most of the rest of the parser just assumes that functions do not
@@ -157,33 +110,26 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
        if (fargs)
        {
                first_arg = lfirst(fargs);
-               if (first_arg == NULL)
+               if (first_arg == NULL)  /* should not happen */
                        elog(ERROR, "Function '%s' does not allow NULL input", funcname);
        }
 
        /*
-        * test for relation.column
-        *
-        * check for projection methods: if function takes one argument, and that
-        * argument is a relation, param, or PQ function returning a complex *
-        * type, then the function could be a projection.
+        * check for column projection: if function has one argument, and that
+        * argument is of complex type, then the function could be a projection.
         */
        /* We only have one parameter, and it's not got aggregate decoration */
        if (nargs == 1 && !must_be_agg)
        {
-               /* Is it a plain Relation name from the parser? */
-               if (IsA(first_arg, Ident) &&((Ident *) first_arg)->isRel)
+               /* Is it a not-yet-transformed RangeVar node? */
+               if (IsA(first_arg, RangeVar))
                {
-                       Ident      *ident = (Ident *) first_arg;
-
                        /* First arg is a relation. This could be a projection. */
-                       refname = ident->name;
+                       refname = ((RangeVar *) first_arg)->relname;
 
                        retval = qualifiedNameToVar(pstate, refname, funcname, true);
                        if (retval)
                                return retval;
-
-                       /* else drop through - attr is a set or function */
                }
                else if (ISCOMPLEX(exprType(first_arg)))
                {
@@ -194,24 +140,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                         */
                        retval = ParseComplexProjection(pstate,
                                                                                        funcname,
-                                                                                       first_arg,
-                                                                                       &attisset);
-                       if (attisset)
-                       {
-                               toid = exprType(first_arg);
-                               argrelid = typeidTypeRelid(toid);
-                               if (argrelid == InvalidOid)
-                                       elog(ERROR, "Type '%s' is not a relation type",
-                                                typeidTypeName(toid));
-
-                               /*
-                                * A projection must match an attribute name of the rel.
-                                */
-                               if (get_attnum(argrelid, funcname) == InvalidAttrNumber)
-                                       elog(ERROR, "No such attribute or function '%s'",
-                                                funcname);
-                       }
-
+                                                                                       first_arg);
                        if (retval)
                                return retval;
                }
@@ -226,15 +155,14 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                if (nargs != 1)
                        elog(ERROR, "Aggregate functions may only have one parameter");
                /* Agg's argument can't be a relation name, either */
-               if (IsA(first_arg, Ident) &&((Ident *) first_arg)->isRel)
+               if (IsA(first_arg, RangeVar))
                        elog(ERROR, "Aggregate functions cannot be applied to relation names");
                could_be_agg = true;
        }
        else
        {
                /* Try to parse as an aggregate if above-mentioned checks are OK */
-               could_be_agg = (nargs == 1) &&
-                       !(IsA(first_arg, Ident) &&((Ident *) first_arg)->isRel);
+               could_be_agg = (nargs == 1) && !(IsA(first_arg, RangeVar));
        }
 
        if (could_be_agg)
@@ -249,8 +177,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                                                                 ObjectIdGetDatum(basetype),
                                                                 0, 0))
                        return (Node *) ParseAgg(pstate, funcname, basetype,
-                                                                        fargs, agg_star, agg_distinct,
-                                                                        precedence);
+                                                                        fargs, agg_star, agg_distinct);
 
                /* check for aggregate-that-accepts-any-type (eg, COUNT) */
                if (SearchSysCacheExists(AGGNAME,
@@ -258,8 +185,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                                                                 ObjectIdGetDatum(0),
                                                                 0, 0))
                        return (Node *) ParseAgg(pstate, funcname, 0,
-                                                                        fargs, agg_star, agg_distinct,
-                                                                        precedence);
+                                                                        fargs, agg_star, agg_distinct);
 
                /*
                 * No exact match yet, so see if there is another entry in the
@@ -277,8 +203,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                                                                                        basetype, type, -1);
                                basetype = type;
                                return (Node *) ParseAgg(pstate, funcname, basetype,
-                                                                                fargs, agg_star, agg_distinct,
-                                                                                precedence);
+                                                                                fargs, agg_star, agg_distinct);
                        }
                        else
                        {
@@ -300,10 +225,9 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
        }
 
        /*
-        * If we dropped through to here it's really a function (or a set,
-        * which is implemented as a function). Extract arg type info and
-        * transform relation name arguments into varnodes of the appropriate
-        * form.
+        * Okay, it's not a column projection, so it must really be a function.
+        * Extract arg type info and transform RangeVar arguments into varnodes
+        * of the appropriate form.
         */
        MemSet(oid_array, 0, FUNC_MAX_ARGS * sizeof(Oid));
 
@@ -311,8 +235,9 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
        foreach(i, fargs)
        {
                Node       *arg = lfirst(i);
+               Oid                     toid;
 
-               if (IsA(arg, Ident) &&((Ident *) arg)->isRel)
+               if (IsA(arg, RangeVar))
                {
                        RangeTblEntry *rte;
                        int                     vnum;
@@ -321,7 +246,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                        /*
                         * a relation
                         */
-                       refname = ((Ident *) arg)->name;
+                       refname = ((RangeVar *) arg)->relname;
 
                        rte = refnameRangeTblEntry(pstate, refname,
                                                                           &sublevels_up);
@@ -346,16 +271,9 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                                 * RTE is a join or subselect; must fail for lack of a
                                 * named tuple type
                                 */
-                               if (nargs == 1)
-                               {
-                                       /*
-                                        * Here, we probably have an unrecognized attribute of
-                                        * a sub-select; again can't tell if it was x.f or
-                                        * f(x)
-                                        */
-                                       elog(ERROR, "No such attribute or function %s.%s",
+                               if (is_column)
+                                       elog(ERROR, "No such attribute %s.%s",
                                                 refname, funcname);
-                               }
                                else
                                {
                                        elog(ERROR, "Cannot pass result of sub-select or join %s to a function",
@@ -365,93 +283,53 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 
                        toid = typenameTypeId(rte->relname);
 
-                       /* replace it in the arg list */
+                       /* replace RangeVar in the arg list */
                        lfirst(i) = makeVar(vnum,
                                                                InvalidAttrNumber,
                                                                toid,
                                                                sizeof(Pointer),
                                                                sublevels_up);
                }
-               else if (!attisset)
-                       toid = exprType(arg);
                else
-               {
-                       /* if attisset is true, we already set toid for the single arg */
-               }
+                       toid = exprType(arg);
 
                oid_array[argn++] = toid;
        }
 
        /*
-        * Is it a set, or a function?
+        * func_get_detail looks up the function in the catalogs, does
+        * disambiguation for polymorphic functions, handles inheritance,
+        * and returns the funcid and type and set or singleton status of
+        * the function's return value.  it also returns the true argument
+        * types to the function.
         */
-       if (attisset)
-       {                                                       /* we know all of these fields already */
-
+       fdresult = func_get_detail(funcname, fargs, nargs, oid_array,
+                                                          &funcid, &rettype, &retset,
+                                                          &true_oid_array);
+       if (fdresult == FUNCDETAIL_COERCION)
+       {
                /*
-                * We create a funcnode with a placeholder function seteval(). At
-                * runtime, seteval() will execute the function identified by the
-                * funcid it receives as parameter.
-                *
-                * Example: retrieve (emp.mgr.name).  The plan for this will scan the
-                * emp relation, projecting out the mgr attribute, which is a
-                * funcid. This function is then called (via seteval()) and "name"
-                * is projected from its result.
+                * We can do it as a trivial coercion. coerce_type can handle
+                * these cases, so why duplicate code...
                 */
-               funcid = F_SETEVAL;
-               rettype = toid;
-               retset = true;
-               true_oid_array = oid_array;
+               return coerce_type(pstate, lfirst(fargs),
+                                                  oid_array[0], rettype, -1);
        }
-       else
+       if (fdresult != FUNCDETAIL_NORMAL)
        {
-               FuncDetailCode fdresult;
-
                /*
-                * func_get_detail looks up the function in the catalogs, does
-                * disambiguation for polymorphic functions, handles inheritance,
-                * and returns the funcid and type and set or singleton status of
-                * the function's return value.  it also returns the true argument
-                * types to the function.
+                * Oops.  Time to die.
+                *
+                * If we are dealing with the attribute notation rel.function,
+                * give an error message that is appropriate for that case.
                 */
-               fdresult = func_get_detail(funcname, fargs, nargs, oid_array,
-                                                                  &funcid, &rettype, &retset,
-                                                                  &true_oid_array);
-               if (fdresult == FUNCDETAIL_COERCION)
-               {
-                       /*
-                        * We can do it as a trivial coercion. coerce_type can handle
-                        * these cases, so why duplicate code...
-                        */
-                       return coerce_type(pstate, lfirst(fargs),
-                                                          oid_array[0], rettype, -1);
-               }
-               if (fdresult != FUNCDETAIL_NORMAL)
-               {
-                       /*
-                        * Oops.  Time to die.
-                        *
-                        * If there is a single argument of complex type, we might be
-                        * dealing with the PostQuel notation rel.function instead of
-                        * the more usual function(rel).  Give a nonspecific error
-                        * message that will cover both cases.
-                        */
-                       if (nargs == 1)
-                       {
-                               Type            tp = typeidType(oid_array[0]);
-
-                               if (typeTypeFlag(tp) == 'c')
-                                       elog(ERROR, "No such attribute or function '%s'",
-                                                funcname);
-                               ReleaseSysCache(tp);
-                       }
-
-                       /* Else generate a detailed complaint */
-                       func_error(NULL, funcname, nargs, oid_array,
-                                          "Unable to identify a function that satisfies the "
-                                          "given argument types"
-                                          "\n\tYou may need to add explicit typecasts");
-               }
+               if (is_column)
+                       elog(ERROR, "Attribute \"%s\" not found", funcname);
+               /* Else generate a detailed complaint */
+               func_error(NULL, funcname, nargs, oid_array,
+                                  "Unable to identify a function that satisfies the "
+                                  "given argument types"
+                                  "\n\tYou may need to add explicit typecasts");
        }
 
        /* got it */
@@ -471,25 +349,11 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
        retval = (Node *) expr;
 
        /*
-        * For sets, we want to project out the desired attribute of the
-        * tuples.
-        */
-       if (attisset)
-       {
-               FieldSelect *fselect;
-
-               fselect = setup_field_select(retval, funcname, argrelid);
-               rettype = fselect->resulttype;
-               retval = (Node *) fselect;
-       }
-
-       /*
         * if the function returns a set of values, then we need to iterate
         * over all the returned values in the executor, so we stick an iter
         * node here.  if it returns a singleton, then we don't need the iter
         * node.
         */
-
        if (retset)
        {
                Iter       *iter = makeNode(Iter);
@@ -1497,10 +1361,10 @@ make_arguments(ParseState *pstate,
 }
 
 /*
- ** setup_field_select
- **            Build a FieldSelect node that says which attribute to project to.
- **            This routine is called by ParseFuncOrColumn() when we have found
- **            a projection on a function result or parameter.
+ * setup_field_select
+ *             Build a FieldSelect node that says which attribute to project to.
+ *             This routine is called by ParseFuncOrColumn() when we have found
+ *             a projection on a function result or parameter.
  */
 static FieldSelect *
 setup_field_select(Node *input, char *attname, Oid relid)
@@ -1521,18 +1385,31 @@ setup_field_select(Node *input, char *attname, Oid relid)
 /*
  * ParseComplexProjection -
  *       handles function calls with a single argument that is of complex type.
- *       This routine returns NULL if it can't handle the projection (eg. sets).
+ *       If the function call is actually a column projection, return a suitably
+ *       transformed expression tree.  If not, return NULL.
+ *
+ * NB: argument is expected to be transformed already, ie, not a RangeVar.
  */
 static Node *
 ParseComplexProjection(ParseState *pstate,
                                           char *funcname,
-                                          Node *first_arg,
-                                          bool *attisset)
+                                          Node *first_arg)
 {
-       Oid                     argtype;
+       Oid                     argtype = exprType(first_arg);
        Oid                     argrelid;
+       AttrNumber      attnum;
        FieldSelect *fselect;
 
+       argrelid = typeidTypeRelid(argtype);
+       if (!argrelid)
+               return NULL;                    /* probably should not happen */
+       attnum = get_attnum(argrelid, funcname);
+       if (attnum == InvalidAttrNumber)
+               return NULL;                    /* funcname does not match any column */
+
+       /*
+        * Check for special cases where we don't want to return a FieldSelect.
+        */
        switch (nodeTag(first_arg))
        {
                case T_Iter:
@@ -1540,75 +1417,42 @@ ParseComplexProjection(ParseState *pstate,
                                Iter       *iter = (Iter *) first_arg;
 
                                /*
-                                * If the argument of the Iter returns a tuple, funcname
-                                * may be a projection.  If so, we stick the FieldSelect
+                                * If it's an Iter, we stick the FieldSelect
                                 * *inside* the Iter --- this is klugy, but necessary
                                 * because ExecTargetList() currently does the right thing
                                 * only when the Iter node is at the top level of a
                                 * targetlist item.
+                                *
+                                * XXX Iter should go away altogether...
                                 */
-                               argtype = iter->itertype;
-                               argrelid = typeidTypeRelid(argtype);
-                               if (argrelid &&
-                                       get_attnum(argrelid, funcname) != InvalidAttrNumber)
-                               {
-                                       fselect = setup_field_select(iter->iterexpr,
-                                                                                                funcname, argrelid);
-                                       iter->iterexpr = (Node *) fselect;
-                                       iter->itertype = fselect->resulttype;
-                                       return (Node *) iter;
-                               }
+                               fselect = setup_field_select(iter->iterexpr,
+                                                                                        funcname, argrelid);
+                               iter->iterexpr = (Node *) fselect;
+                               iter->itertype = fselect->resulttype;
+                               return (Node *) iter;
                                break;
                        }
                case T_Var:
                        {
-                               /*
-                                * The argument is a set, so this is either a projection
-                                * or a function call on this set.
-                                */
-                               *attisset = true;
-                               break;
-                       }
-               case T_Expr:
-                       {
-                               Expr       *expr = (Expr *) first_arg;
-                               Func       *funcnode;
-
-                               if (expr->opType != FUNC_EXPR)
-                                       break;
+                               Var                *var = (Var *) first_arg;
 
                                /*
-                                * If the argument is a function returning a tuple,
-                                * funcname may be a projection
+                                * If the Var is a whole-row tuple, we can just replace it
+                                * with a simple Var reference.
                                 */
-                               funcnode = (Func *) expr->oper;
-                               argtype = funcnode->functype;
-                               argrelid = typeidTypeRelid(argtype);
-                               if (argrelid &&
-                                       get_attnum(argrelid, funcname) != InvalidAttrNumber)
+                               if (var->varattno == InvalidAttrNumber)
                                {
-                                       fselect = setup_field_select((Node *) expr,
-                                                                                                funcname, argrelid);
-                                       return (Node *) fselect;
-                               }
-                               break;
-                       }
-               case T_Param:
-                       {
-                               Param      *param = (Param *) first_arg;
+                                       Oid             vartype;
+                                       int32   vartypmod;
 
-                               /*
-                                * If the Param is a complex type, this could be a
-                                * projection
-                                */
-                               argtype = param->paramtype;
-                               argrelid = typeidTypeRelid(argtype);
-                               if (argrelid &&
-                                       get_attnum(argrelid, funcname) != InvalidAttrNumber)
-                               {
-                                       fselect = setup_field_select((Node *) param,
-                                                                                                funcname, argrelid);
-                                       return (Node *) fselect;
+                                       get_atttypetypmod(argrelid, attnum,
+                                                                         &vartype, &vartypmod);
+
+                                       return (Node *) makeVar(var->varno,
+                                                                                       attnum,
+                                                                                       vartype,
+                                                                                       vartypmod,
+                                                                                       var->varlevelsup);
                                }
                                break;
                        }
@@ -1616,7 +1460,9 @@ ParseComplexProjection(ParseState *pstate,
                        break;
        }
 
-       return NULL;
+       /* Else generate a FieldSelect expression */
+       fselect = setup_field_select(first_arg, funcname, argrelid);
+       return (Node *) fselect;
 }
 
 /*
index be825c2..8b259e9 100644 (file)
@@ -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);
index 1609c89..5cf868a 100644 (file)
@@ -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)
        {
index f579129..a4b7816 100644 (file)
@@ -8,13 +8,13 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.77 2002/03/12 00:51:56 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.78 2002/03/21 16:01:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
-
 #include "postgres.h"
 
+#include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "parser/parsetree.h"
 #include "parser/parse_coerce.h"
@@ -56,9 +56,9 @@ transformTargetEntry(ParseState *pstate,
 
        /* Transform the node if caller didn't do it already */
        if (expr == NULL)
-               expr = transformExpr(pstate, node, EXPR_COLUMN_FIRST);
+               expr = transformExpr(pstate, node);
 
-       if (IsA(expr, Ident) &&((Ident *) expr)->isRel)
+       if (IsA(expr, RangeVar))
                elog(ERROR, "You can't use relation names alone in the target list, try relation.*.");
 
        type_id = exprType(expr);
@@ -99,11 +99,13 @@ transformTargetList(ParseState *pstate, List *targetlist)
        {
                ResTarget  *res = (ResTarget *) lfirst(targetlist);
 
-               if (IsA(res->val, Attr))
+               if (IsA(res->val, ColumnRef))
                {
-                       Attr       *att = (Attr *) res->val;
+                       ColumnRef  *cref = (ColumnRef *) res->val;
+                       List       *fields = cref->fields;
+                       int                     numnames = length(fields);
 
-                       if (att->relname != NULL && strcmp(att->relname, "*") == 0)
+                       if (numnames == 1 && strcmp(strVal(lfirst(fields)), "*") == 0)
                        {
                                /*
                                 * Target item is a single '*', expand all tables (eg.
@@ -112,27 +114,59 @@ transformTargetList(ParseState *pstate, List *targetlist)
                                p_target = nconc(p_target,
                                                                 ExpandAllTables(pstate));
                        }
-                       else if (att->attrs != NIL &&
-                                        strcmp(strVal(lfirst(att->attrs)), "*") == 0)
+                       else if (strcmp(strVal(nth(numnames-1, fields)), "*") == 0)
                        {
                                /*
                                 * Target item is relation.*, expand that table (eg.
                                 * SELECT emp.*, dname FROM emp, dept)
                                 */
+                               char       *schemaname;
+                               char       *relname;
                                RangeTblEntry *rte;
                                int                     sublevels_up;
 
-                               rte = refnameRangeTblEntry(pstate, att->relname,
+                               switch (numnames)
+                               {
+                                       case 2:
+                                               schemaname = NULL;
+                                               relname = strVal(lfirst(fields));
+                                               break;
+                                       case 3:
+                                               schemaname = strVal(lfirst(fields));
+                                               relname = strVal(lsecond(fields));
+                                               break;
+                                       case 4:
+                                       {
+                                               char   *name1 = strVal(lfirst(fields));
+
+                                               /*
+                                                * We check the catalog name and then ignore it.
+                                                */
+                                               if (strcmp(name1, DatabaseName) != 0)
+                                                       elog(ERROR, "Cross-database references are not implemented");
+                                               schemaname = strVal(lsecond(fields));
+                                               relname = strVal(lfirst(lnext(lnext(fields))));
+                                               break;
+                                       }
+                                       default:
+                                               elog(ERROR, "Invalid qualified name syntax (too many names)");
+                                               schemaname = NULL; /* keep compiler quiet */
+                                               relname = NULL;
+                                               break;
+                               }
+
+                               /* XXX do something with schema name */
+                               rte = refnameRangeTblEntry(pstate, relname,
                                                                                   &sublevels_up);
                                if (rte == NULL)
-                                       rte = addImplicitRTE(pstate, att->relname);
+                                       rte = addImplicitRTE(pstate, relname);
 
                                p_target = nconc(p_target,
                                                                 expandRelAttrs(pstate, rte));
                        }
                        else
                        {
-                               /* Plain Attr node, treat it as an expression */
+                               /* Plain ColumnRef node, treat it as an expression */
                                p_target = lappend(p_target,
                                                                   transformTargetEntry(pstate,
                                                                                                                res->val,
@@ -143,7 +177,7 @@ transformTargetList(ParseState *pstate, List *targetlist)
                }
                else
                {
-                       /* Everything else but Attr */
+                       /* Everything else but ColumnRef */
                        p_target = lappend(p_target,
                                                           transformTargetEntry(pstate,
                                                                                                        res->val,
@@ -317,10 +351,9 @@ CoerceTargetExpr(ParseState *pstate,
 
 /*
  * checkInsertTargets -
- *       generate a list of column names if not supplied or
+ *       generate a list of INSERT column targets if not supplied, or
  *       test supplied column names to make sure they are in target table.
  *       Also return an integer list of the columns' attribute numbers.
- *       (used exclusively for inserts)
  */
 List *
 checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
@@ -338,17 +371,16 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
 
                for (i = 0; i < numcol; i++)
                {
-                       Ident      *id = makeNode(Ident);
+                       ResTarget          *col = makeNode(ResTarget);
 
 #ifdef _DROP_COLUMN_HACK__
                        if (COLUMN_IS_DROPPED(attr[i]))
                                continue;
 #endif   /* _DROP_COLUMN_HACK__ */
-                       id->name = palloc(NAMEDATALEN);
-                       StrNCpy(id->name, NameStr(attr[i]->attname), NAMEDATALEN);
-                       id->indirection = NIL;
-                       id->isRel = false;
-                       cols = lappend(cols, id);
+                       col->name = pstrdup(NameStr(attr[i]->attname));
+                       col->indirection = NIL;
+                       col->val = NULL;
+                       cols = lappend(cols, col);
                        *attrnos = lappendi(*attrnos, i + 1);
                }
        }
@@ -361,7 +393,7 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
 
                foreach(tl, cols)
                {
-                       char       *name = ((Ident *) lfirst(tl))->name;
+                       char       *name = ((ResTarget *) lfirst(tl))->name;
                        int                     attrno;
 
                        /* Lookup column name, elog on failure */
@@ -458,19 +490,35 @@ FigureColnameInternal(Node *node, char **name)
                case T_Ident:
                        *name = ((Ident *) node)->name;
                        return 2;
-               case T_Attr:
+               case T_ColumnRef:
                        {
-                               List       *attrs = ((Attr *) node)->attrs;
+                               List       *fields = ((ColumnRef *) node)->fields;
 
-                               if (attrs)
+                               while (lnext(fields) != NIL)
+                                       fields = lnext(fields);
+                               if (strcmp(strVal(lfirst(fields)), "*") != 0)
                                {
-                                       while (lnext(attrs) != NIL)
-                                               attrs = lnext(attrs);
-                                       *name = strVal(lfirst(attrs));
+                                       *name = strVal(lfirst(fields));
                                        return 2;
                                }
                        }
                        break;
+               case T_ExprFieldSelect:
+                       {
+                               List       *fields = ((ExprFieldSelect *) node)->fields;
+
+                               if (fields)
+                               {
+                                       while (lnext(fields) != NIL)
+                                               fields = lnext(fields);
+                                       if (strcmp(strVal(lfirst(fields)), "*") != 0)
+                                       {
+                                               *name = strVal(lfirst(fields));
+                                               return 2;
+                                       }
+                               }
+                       }
+                       break;
                case T_FuncCall:
                        *name = ((FuncCall *) node)->funcname;
                        return 2;
index b031515..0b47aa9 100644 (file)
@@ -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,
@@ -187,23 +141,6 @@ DefineQueryRewrite(RuleStmt *stmt)
        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
         */
        foreach(l, action)
@@ -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
index af413ca..86a158f 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.62 2002/03/12 00:51:58 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.63 2002/03/21 16:01:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -573,9 +573,9 @@ getInsertSelectQuery(Query *parsetree, Query ***subquery_ptr)
         * they've been pushed down to the SELECT.
         */
        if (length(parsetree->rtable) >= 2 &&
-               strcmp(rt_fetch(PRS2_OLD_VARNO, parsetree->rtable)->eref->relname,
+               strcmp(rt_fetch(PRS2_OLD_VARNO, parsetree->rtable)->eref->aliasname,
                           "*OLD*") == 0 &&
-               strcmp(rt_fetch(PRS2_NEW_VARNO, parsetree->rtable)->eref->relname,
+               strcmp(rt_fetch(PRS2_NEW_VARNO, parsetree->rtable)->eref->aliasname,
                           "*NEW*") == 0)
                return parsetree;
        Assert(parsetree->jointree && IsA(parsetree->jointree, FromExpr));
@@ -589,9 +589,9 @@ getInsertSelectQuery(Query *parsetree, Query ***subquery_ptr)
                  selectquery->commandType == CMD_SELECT))
                elog(ERROR, "getInsertSelectQuery: expected to find SELECT subquery");
        if (length(selectquery->rtable) >= 2 &&
-        strcmp(rt_fetch(PRS2_OLD_VARNO, selectquery->rtable)->eref->relname,
+        strcmp(rt_fetch(PRS2_OLD_VARNO, selectquery->rtable)->eref->aliasname,
                        "*OLD*") == 0 &&
-        strcmp(rt_fetch(PRS2_NEW_VARNO, selectquery->rtable)->eref->relname,
+        strcmp(rt_fetch(PRS2_NEW_VARNO, selectquery->rtable)->eref->aliasname,
                        "*NEW*") == 0)
        {
                if (subquery_ptr)
index 9542170..8443fe6 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.257 2002/03/19 16:10:48 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.258 2002/03/21 16:01:25 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.257 $ $Date: 2002/03/19 16:10:48 $\n");
+               puts("$Revision: 1.258 $ $Date: 2002/03/21 16:01:25 $\n");
        }
 
        /*
@@ -2216,6 +2216,10 @@ CreateCommandTag(Node *parsetree)
                        tag = "CREATE DOMAIN";
                        break;
 
+               case T_CreateSchemaStmt:
+                       tag = "CREATE";
+                       break;
+
                case T_CreateStmt:
                        tag = "CREATE";
                        break;
index ef4b4ed..4599a27 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.50 2002/03/06 06:10:10 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.51 2002/03/21 16:01:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -181,12 +181,12 @@ ProcessQuery(Query *parsetree,
         */
        if (isRetrieveIntoPortal)
        {
-               intoName = parsetree->into;
+               intoName = parsetree->into->relname;
                portal = PreparePortal(intoName);
                oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
                parsetree = copyObject(parsetree);
                plan = copyObject(plan);
-               intoName = parsetree->into    /* use copied name in QueryDesc */
+               intoName = parsetree->into->relname;    /* use copied name in QueryDesc */
 
                /*
                 * We stay in portal's memory context for now, so that query desc,
index db8d440..9a68136 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.135 2002/03/20 19:44:35 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.136 2002/03/21 16:01:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -218,6 +218,14 @@ ProcessUtility(Node *parsetree,
                        /*
                         * relation and attribute manipulation
                         */
+               case T_CreateSchemaStmt:
+                       {
+                               CreateSchemaStmt  *stmt = (CreateSchemaStmt *) parsetree;
+
+                               CreateSchemaCommand(stmt);
+                       }
+                       break;
+
                case T_CreateStmt:
                        DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION);
 
@@ -226,19 +234,19 @@ ProcessUtility(Node *parsetree,
                         * secondary relation too.
                         */
                        CommandCounterIncrement();
-                       AlterTableCreateToastTable(((CreateStmt *) parsetree)->relname,
+                       AlterTableCreateToastTable(((CreateStmt *) parsetree)->relation->relname,
                                                                           true);
                        break;
 
                case T_DropStmt:
                        {
                                DropStmt   *stmt = (DropStmt *) parsetree;
-                               List       *args = stmt->names;
+                               List       *args = stmt->objects;
                                List       *arg;
 
                                foreach(arg, args)
                                {
-                                       relname = strVal(lfirst(arg));
+                                       relname = ((RangeVar *) lfirst(arg))->relname;
 
                                        switch (stmt->removeType)
                                        {
@@ -299,7 +307,8 @@ ProcessUtility(Node *parsetree,
 
                case T_TruncateStmt:
                        {
-                               TruncateRelation(((TruncateStmt *) parsetree)->relName);
+                               relname = ((TruncateStmt *) parsetree)->relation->relname;
+                               TruncateRelation(relname);
                        }
                        break;
 
@@ -322,7 +331,7 @@ ProcessUtility(Node *parsetree,
                                if (stmt->direction != FROM)
                                        SetQuerySnapshot();
 
-                               DoCopy(stmt->relname,
+                               DoCopy(stmt->relation->relname,
                                           stmt->binary,
                                           stmt->oids,
                                           (bool) (stmt->direction == FROM),
@@ -345,7 +354,7 @@ ProcessUtility(Node *parsetree,
                        {
                                RenameStmt *stmt = (RenameStmt *) parsetree;
 
-                               relname = stmt->relname;
+                               relname = stmt->relation->relname;
                                if (!allowSystemTableMods && IsSystemRelationName(relname))
                                        elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
                                                 relname);
@@ -380,7 +389,7 @@ ProcessUtility(Node *parsetree,
                                        renameatt(relname,      /* relname */
                                                          stmt->column,         /* old att name */
                                                          stmt->newname,        /* new att name */
-                                                         interpretInhOption(stmt->inhOpt));            /* recursive? */
+                                                         interpretInhOption(stmt->relation->inhOpt));          /* recursive? */
                                }
                        }
                        break;
@@ -398,47 +407,47 @@ ProcessUtility(Node *parsetree,
                                switch (stmt->subtype)
                                {
                                        case 'A':       /* ADD COLUMN */
-                                               AlterTableAddColumn(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableAddColumn(stmt->relation->relname,
+                                                                               interpretInhOption((stmt->relation)->inhOpt),
                                                                                        (ColumnDef *) stmt->def);
                                                break;
                                        case 'T':       /* ALTER COLUMN DEFAULT */
-                                               AlterTableAlterColumnDefault(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableAlterColumnDefault(stmt->relation->relname,
+                                                                               interpretInhOption((stmt->relation)->inhOpt),
                                                                                                         stmt->name,
                                                                                                         stmt->def);
                                                break;
                                        case 'S':       /* ALTER COLUMN STATISTICS */
                                        case 'M':   /* ALTER COLUMN STORAGE */
-                                               AlterTableAlterColumnFlags(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableAlterColumnFlags(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
                                                                                                                stmt->name,
                                                                                                                stmt->def,
                                                                                                        &(stmt->subtype));
                                                break;
                                        case 'D':       /* DROP COLUMN */
-                                               AlterTableDropColumn(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableDropColumn(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
                                                                                         stmt->name,
                                                                                         stmt->behavior);
                                                break;
                                        case 'C':       /* ADD CONSTRAINT */
-                                               AlterTableAddConstraint(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableAddConstraint(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
                                                                                                (List *) stmt->def);
                                                break;
                                        case 'X':       /* DROP CONSTRAINT */
-                                               AlterTableDropConstraint(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableDropConstraint(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
                                                                                                 stmt->name,
                                                                                                 stmt->behavior);
                                                break;
                                        case 'E':       /* CREATE TOAST TABLE */
-                                               AlterTableCreateToastTable(stmt->relname,
+                                               AlterTableCreateToastTable(stmt->relation->relname,
                                                                                                   false);
                                                break;
                                        case 'U':       /* ALTER OWNER */
-                                               AlterTableOwner(stmt->relname,
+                                               AlterTableOwner(stmt->relation->relname,
                                                                                stmt->name);
                                                break;
                                        default:        /* oops */
@@ -487,7 +496,7 @@ ProcessUtility(Node *parsetree,
                        {
                                ViewStmt   *stmt = (ViewStmt *) parsetree;
 
-                               DefineView(stmt->viewname, stmt->query);                /* retrieve parsetree */
+                               DefineView(stmt->view->relname, stmt->query);   /* retrieve parsetree */
                        }
                        break;
 
@@ -499,17 +508,17 @@ ProcessUtility(Node *parsetree,
                        {
                                IndexStmt  *stmt = (IndexStmt *) parsetree;
 
-                               relname = stmt->relname;
+                               relname = stmt->relation->relname;
                                if (!allowSystemTableMods && IsSystemRelationName(relname))
                                        elog(ERROR, "CREATE INDEX: relation \"%s\" is a system catalog",
                                                 relname);
                                if (!pg_ownercheck(GetUserId(), relname, RELNAME))
                                        elog(ERROR, "permission denied");
 
-                               DefineIndex(stmt->relname,              /* relation name */
-                                                       stmt->idxname,          /* index name */
-                                                       stmt->accessMethod, /* am name */
-                                                       stmt->indexParams,      /* parameters */
+                               DefineIndex(stmt->relation->relname,    /* relation */
+                                                       stmt->idxname,                          /* index name */
+                                                       stmt->accessMethod,             /* am name */
+                                                       stmt->indexParams,                      /* parameters */
                                                        stmt->unique,
                                                        stmt->primary,
                                                        (Expr *) stmt->whereClause,
@@ -522,7 +531,7 @@ ProcessUtility(Node *parsetree,
                                RuleStmt   *stmt = (RuleStmt *) parsetree;
                                int                     aclcheck_result;
 
-                               relname = stmt->object->relname;
+                               relname = stmt->relation->relname;
                                aclcheck_result = pg_aclcheck(relname, GetUserId(), ACL_RULE);
                                if (aclcheck_result != ACLCHECK_OK)
                                        elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
@@ -603,7 +612,7 @@ ProcessUtility(Node *parsetree,
                        {
                                NotifyStmt *stmt = (NotifyStmt *) parsetree;
 
-                               Async_Notify(stmt->relname);
+                               Async_Notify(stmt->relation->relname);
                        }
                        break;
 
@@ -611,7 +620,7 @@ ProcessUtility(Node *parsetree,
                        {
                                ListenStmt *stmt = (ListenStmt *) parsetree;
 
-                               Async_Listen(stmt->relname, MyProcPid);
+                               Async_Listen(stmt->relation->relname, MyProcPid);
                        }
                        break;
 
@@ -619,7 +628,7 @@ ProcessUtility(Node *parsetree,
                        {
                                UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
 
-                               Async_Unlisten(stmt->relname, MyProcPid);
+                               Async_Unlisten(stmt->relation->relname, MyProcPid);
                        }
                        break;
 
@@ -636,7 +645,7 @@ ProcessUtility(Node *parsetree,
                        {
                                ClusterStmt *stmt = (ClusterStmt *) parsetree;
 
-                               relname = stmt->relname;
+                               relname = stmt->relation->relname;
                                if (IsSystemRelationName(relname))
                                        elog(ERROR, "CLUSTER: relation \"%s\" is a system catalog",
                                                 relname);
@@ -712,7 +721,6 @@ ProcessUtility(Node *parsetree,
 
                        /*
                         * ******************************** DOMAIN statements ****
-                        *
                         */
                case T_CreateDomainStmt:
                        DefineDomain((CreateDomainStmt *) parsetree);
@@ -720,9 +728,7 @@ ProcessUtility(Node *parsetree,
 
                        /*
                         * ******************************** USER statements ****
-                        *
                         */
-
                case T_CreateUserStmt:
                        CreateUser((CreateUserStmt *) parsetree);
                        break;
@@ -774,7 +780,7 @@ ProcessUtility(Node *parsetree,
                                switch (stmt->reindexType)
                                {
                                        case INDEX:
-                                               relname = (char *) stmt->name;
+                                               relname = (char *) stmt->relation->relname;
                                                if (IsSystemRelationName(relname))
                                                {
                                                        if (!allowSystemTableMods)
@@ -789,7 +795,7 @@ ProcessUtility(Node *parsetree,
                                                ReindexIndex(relname, stmt->force);
                                                break;
                                        case TABLE:
-                                               relname = (char *) stmt->name;
+                                               relname = (char *) stmt->relation->relname;
                                                if (!pg_ownercheck(GetUserId(), relname, RELNAME))
                                                        elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
                                                ReindexTable(relname, stmt->force);
index d47bf3b..0e4472f 100644 (file)
@@ -3,7 +3,7 @@
  *                             back to source text
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.93 2002/03/12 00:51:59 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.94 2002/03/21 16:01:34 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -48,6 +48,7 @@
 #include "catalog/pg_shadow.h"
 #include "executor/spi.h"
 #include "lib/stringinfo.h"
+#include "nodes/makefuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/tlist.h"
 #include "parser/keywords.h"
@@ -659,8 +660,7 @@ deparse_context_for(char *relname, Oid relid)
        rte->rtekind = RTE_RELATION;
        rte->relname = relname;
        rte->relid = relid;
-       rte->eref = makeNode(Attr);
-       rte->eref->relname = relname;
+       rte->eref = makeAlias(relname, NIL);
        rte->inh = false;
        rte->inFromCl = true;
 
@@ -755,9 +755,7 @@ deparse_context_for_subplan(const char *name, List *tlist,
        rte->rtekind = RTE_SPECIAL;     /* XXX */
        rte->relname = pstrdup(name);
        rte->relid = InvalidOid;
-       rte->eref = makeNode(Attr);
-       rte->eref->relname = rte->relname;
-       rte->eref->attrs = attrs;
+       rte->eref = makeAlias(rte->relname, attrs);
        rte->inh = false;
        rte->inFromCl = true;
 
@@ -1462,7 +1460,7 @@ get_utility_query_def(Query *query, deparse_context *context)
        {
                NotifyStmt *stmt = (NotifyStmt *) query->utilityStmt;
 
-               appendStringInfo(buf, "NOTIFY %s", quote_identifier(stmt->relname));
+               appendStringInfo(buf, "NOTIFY %s", quote_identifier(stmt->relation->relname));
        }
        else
                elog(ERROR, "get_utility_query_def: unexpected statement type");
@@ -1512,7 +1510,7 @@ get_names_for_var(Var *var, deparse_context *context,
        if (rte->rtekind == RTE_JOIN && rte->alias == NULL)
                *refname = NULL;
        else
-               *refname = rte->eref->relname;
+               *refname = rte->eref->aliasname;
 
        if (var->varattno == InvalidAttrNumber)
                *attname = NULL;
@@ -1758,12 +1756,11 @@ get_rule_expr(Node *node, deparse_context *context)
                                /*
                                 * If the argument is simple enough, we could emit
                                 * arg.fieldname, but most cases where FieldSelect is used
-                                * are *not* simple.  For now, always use the projection-
-                                * function syntax.
+                                * are *not* simple.  So, always use parenthesized syntax.
                                 */
-                               appendStringInfo(buf, "%s(", quote_identifier(fieldname));
+                               appendStringInfoChar(buf, '(');
                                get_rule_expr(fselect->arg, context);
-                               appendStringInfoChar(buf, ')');
+                               appendStringInfo(buf, ").%s", quote_identifier(fieldname));
                        }
                        break;
 
@@ -2302,9 +2299,9 @@ get_from_clause(Query *query, deparse_context *context)
 
                        if (!rte->inFromCl)
                                continue;
-                       if (strcmp(rte->eref->relname, "*NEW*") == 0)
+                       if (strcmp(rte->eref->aliasname, "*NEW*") == 0)
                                continue;
-                       if (strcmp(rte->eref->relname, "*OLD*") == 0)
+                       if (strcmp(rte->eref->aliasname, "*OLD*") == 0)
                                continue;
                }
 
@@ -2342,15 +2339,15 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
                if (rte->alias != NULL)
                {
                        appendStringInfo(buf, " %s",
-                                                        quote_identifier(rte->alias->relname));
-                       if (rte->alias->attrs != NIL)
+                                                        quote_identifier(rte->alias->aliasname));
+                       if (rte->alias->colnames != NIL)
                        {
                                List       *col;
 
                                appendStringInfo(buf, "(");
-                               foreach(col, rte->alias->attrs)
+                               foreach(col, rte->alias->colnames)
                                {
-                                       if (col != rte->alias->attrs)
+                                       if (col != rte->alias->colnames)
                                                appendStringInfo(buf, ", ");
                                        appendStringInfo(buf, "%s",
                                                                  quote_identifier(strVal(lfirst(col))));
@@ -2420,15 +2417,15 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
                if (j->alias != NULL)
                {
                        appendStringInfo(buf, " %s",
-                                                        quote_identifier(j->alias->relname));
-                       if (j->alias->attrs != NIL)
+                                                        quote_identifier(j->alias->aliasname));
+                       if (j->alias->colnames != NIL)
                        {
                                List       *col;
 
                                appendStringInfo(buf, "(");
-                               foreach(col, j->alias->attrs)
+                               foreach(col, j->alias->colnames)
                                {
-                                       if (col != j->alias->attrs)
+                                       if (col != j->alias->colnames)
                                                appendStringInfo(buf, ", ");
                                        appendStringInfo(buf, "%s",
                                                                  quote_identifier(strVal(lfirst(col))));
index a049a23..5e0fa20 100644 (file)
@@ -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
index cf09111..36757b1 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: command.h,v 1.33 2002/03/05 05:33:29 momjian Exp $
+ * $Id: command.h,v 1.34 2002/03/21 16:01:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -72,4 +72,9 @@ extern void AlterTableOwner(const char *relationName, const char *newOwnerName);
  */
 extern void LockTableCommand(LockStmt *lockstmt);
 
+/*
+ * SCHEMA
+ */
+extern void CreateSchemaCommand(CreateSchemaStmt *parsetree);
+
 #endif   /* COMMAND_H */
index 3842419..2de7c03 100644 (file)
@@ -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.31 2002/03/20 19:45:01 tgl Exp $
+ * $Id: makefuncs.h,v 1.32 2002/03/21 16:01:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,7 +44,7 @@ extern Const *makeConst(Oid consttype,
 
 extern Const *makeNullConst(Oid consttype);
 
-extern Attr *makeAttr(char *relname, char *attname);
+extern Alias *makeAlias(const char *aliasname, List *colnames);
 
 extern RelabelType *makeRelabelType(Node *arg, Oid rtype, int32 rtypmod);
 
index d25bc5f..95aba8d 100644 (file)
@@ -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.101 2002/03/19 02:18:23 momjian Exp $
+ * $Id: nodes.h,v 1.102 2002/03/21 16:01:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -195,21 +195,24 @@ typedef enum NodeTag
        T_DropGroupStmt,
        T_ReindexStmt,
        T_CheckPointStmt,
+       T_CreateSchemaStmt,
        T_AlterDatabaseSetStmt,
        T_AlterUserSetStmt,
 
        T_A_Expr = 700,
-       T_Attr,
-       T_A_Const,
-       T_ParamNo,
+       T_ColumnRef,
+       T_ParamRef,
        T_Ident,
+       T_A_Const,
        T_FuncCall,
        T_A_Indices,
+       T_ExprFieldSelect,
        T_ResTarget,
        T_TypeCast,
-       T_RangeSubselect,
        T_SortGroupBy,
+       T_Alias,
        T_RangeVar,
+       T_RangeSubselect,
        T_TypeName,
        T_IndexElem,
        T_ColumnDef,
index 1b1f01b..4f5d139 100644 (file)
@@ -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.162 2002/03/20 19:45:02 tgl Exp $
+ * $Id: parsenodes.h,v 1.163 2002/03/21 16:01:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -49,10 +49,10 @@ typedef struct Query
                                                                 * statement */
 
        int                     resultRelation; /* target relation (index into rtable) */
-       char       *into;                       /* portal (cursor) name */
+       struct RangeVar *into;          /* target relation or portal (cursor) 
+                                                                * for portal just name is meaningful */
        bool            isPortal;               /* is this a retrieve into portal? */
        bool            isBinary;               /* binary portal? */
-       bool            isTemp;                 /* is 'into' a temp table? */
 
        bool            hasAggs;                /* has aggregates in tlist or havingQual */
        bool            hasSubLinks;    /* has subquery SubLink */
@@ -125,15 +125,30 @@ typedef struct TypeName
 } TypeName;
 
 /*
- * ParamNo - specifies a parameter reference
+ * ColumnRef - specifies a reference to a column, or possibly a whole tuple
+ *
+ *             The "fields" list must be nonempty; its last component may be "*"
+ *             instead of a field name.  Subscripts are optional.
+ */
+typedef struct ColumnRef
+{
+       NodeTag         type;
+       List       *fields;                     /* field names (list of Value strings) */
+       List       *indirection;        /* subscripts (list of A_Indices) */
+} ColumnRef;
+
+/*
+ * ParamRef - specifies a parameter reference
+ *
+ *             The parameter could be qualified with field names and/or subscripts
  */
-typedef struct ParamNo
+typedef struct ParamRef
 {
        NodeTag         type;
        int                     number;                 /* the number of the parameter */
-       TypeName   *typename;           /* the typecast */
-       List       *indirection;        /* array references */
-} ParamNo;
+       List       *fields;                     /* field names (list of Value strings) */
+       List       *indirection;        /* subscripts (list of A_Indices) */
+} ParamRef;
 
 /*
  * A_Expr - binary expressions
@@ -148,22 +163,6 @@ typedef struct A_Expr
 } A_Expr;
 
 /*
- * Attr -
- *       specifies an Attribute (ie. a Column); could have nested dots or
- *       array references.
- *
- */
-typedef struct Attr
-{
-       NodeTag         type;
-       char       *relname;            /* name of relation (can be "*") */
-       ParamNo    *paramNo;            /* or a parameter */
-       List       *attrs;                      /* attributes (possibly nested); list of
-                                                                * Values (strings) */
-       List       *indirection;        /* array refs (list of A_Indices') */
-} Attr;
-
-/*
  * A_Const - a constant expression
  */
 typedef struct A_Const
@@ -176,11 +175,11 @@ typedef struct A_Const
 /*
  * TypeCast - a CAST expression
  *
- * NOTE: for mostly historical reasons, A_Const and ParamNo parsenodes contain
+ * NOTE: for mostly historical reasons, A_Const parsenodes contain
  * room for a TypeName; we only generate a separate TypeCast node if the
- * argument to be casted is neither of those kinds of nodes.  In theory either
- * representation would work, but it is convenient (especially for A_Const)
- * to have the target type immediately available.
+ * argument to be casted is not a constant.  In theory either representation
+ * would work, but it is convenient to have the target type immediately
+ * available while resolving a constant's datatype.
  */
 typedef struct TypeCast
 {
@@ -284,17 +283,13 @@ typedef struct ColumnDef
 
 /*
  * Ident -
- *       an identifier (could be an attribute or a relation name). Depending
- *       on the context at transformStmt time, the identifier is treated as
- *       either a relation name (in which case, isRel will be set) or an
- *       attribute (in which case, it will be transformed into an Attr).
+ *       an unqualified identifier.  This is currently used only in the context
+ *       of column name lists.
  */
 typedef struct Ident
 {
        NodeTag         type;
        char       *name;                       /* its name */
-       List       *indirection;        /* array references */
-       bool            isRel;                  /* is this a relation or a column? */
 } Ident;
 
 /*
@@ -325,6 +320,21 @@ typedef struct A_Indices
 } A_Indices;
 
 /*
+ * ExprFieldSelect - select a field and/or array element from an expression
+ *
+ *             This is used in the raw parsetree to represent selection from an
+ *             arbitrary expression (not a column or param reference).  Either
+ *             fields or indirection may be NIL if not used.
+ */
+typedef struct ExprFieldSelect
+{
+       NodeTag         type;
+       Node       *arg;                        /* the thing being selected from */
+       List       *fields;                     /* field names (list of Value strings) */
+       List       *indirection;        /* subscripts (list of A_Indices) */
+} ExprFieldSelect;
+
+/*
  * ResTarget -
  *       result target (used in target list of pre-transformed Parse trees)
  *
@@ -359,14 +369,36 @@ typedef struct SortGroupBy
 } SortGroupBy;
 
 /*
+ * Alias -
+ *       specifies an alias for a range variable; the alias might also
+ *       specify renaming of columns within the table.
+ */
+typedef struct Alias
+{
+       NodeTag         type;
+       char       *aliasname;          /* aliased rel name (never qualified) */
+       List       *colnames;           /* optional list of column aliases */
+       /* Note: colnames is a list of Value nodes (always strings) */
+} Alias;
+
+/*
  * RangeVar - range variable, used in FROM clauses
+ *
+ * Also used to represent table names in utility statements; there, the alias
+ * field is not used, and inhOpt shows whether to apply the operation
+ * recursively to child tables.  In some contexts it is also useful to carry
+ * a TEMP table indication here.
  */
 typedef struct RangeVar
 {
        NodeTag         type;
-       char       *relname;            /* the relation name */
-       InhOption       inhOpt;                 /* expand rel by inheritance? */
-       Attr       *name;                       /* optional table alias & column aliases */
+       char       *catalogname;        /* the catalog (database) name, or NULL */
+       char       *schemaname;         /* the schema name, or NULL */
+       char       *relname;            /* the relation/sequence name */
+       InhOption       inhOpt;                 /* expand rel by inheritance? 
+                                                                * recursively act on children? */
+       bool            istemp;                 /* is this a temp relation/sequence? */
+       Alias      *alias;                      /* table alias & optional column aliases */
 } RangeVar;
 
 /*
@@ -376,7 +408,7 @@ typedef struct RangeSubselect
 {
        NodeTag         type;
        Node       *subquery;           /* the untransformed sub-select clause */
-       Attr       *name;                       /* table alias & optional column aliases */
+       Alias      *alias;                      /* table alias & optional column aliases */
 } RangeSubselect;
 
 /*
@@ -437,7 +469,7 @@ typedef struct TargetEntry
  *       like outer joins and join-output-column aliasing.)  Other special
  *       RTE types also exist, as indicated by RTEKind.
  *
- *       alias is an Attr node representing the AS alias-clause attached to the
+ *       alias is an Alias node representing the AS alias-clause attached to the
  *       FROM expression, or NULL if no clause.
  *
  *       eref is the table reference name and column reference names (either
@@ -489,7 +521,7 @@ typedef struct RangeTblEntry
         */
 
        /*
-        * Fields valid for a plain relation or inh_relation RTE (else NULL/zero):
+        * Fields valid for a plain relation RTE (else NULL/zero):
         */
        char       *relname;            /* real name of the relation */
        Oid                     relid;                  /* OID of the relation */
@@ -517,8 +549,8 @@ typedef struct RangeTblEntry
        /*
         * Fields valid in all RTEs:
         */
-       Attr       *alias;                      /* user-written alias clause, if any */
-       Attr       *eref;                       /* expanded reference names */
+       Alias      *alias;                      /* user-written alias clause, if any */
+       Alias      *eref;                       /* expanded reference names */
        bool            inh;                    /* inheritance requested? */
        bool            inFromCl;               /* present in FROM clause */
        bool            checkForRead;   /* check rel for read access */
@@ -570,7 +602,7 @@ typedef SortClause GroupClause;
 typedef struct InsertStmt
 {
        NodeTag         type;
-       char       *relname;            /* relation to insert into */
+       RangeVar   *relation;           /* relation to insert into */
        List       *cols;                       /* optional: names of the target columns */
 
        /*
@@ -589,9 +621,8 @@ typedef struct InsertStmt
 typedef struct DeleteStmt
 {
        NodeTag         type;
-       char       *relname;            /* relation to delete from */
+       RangeVar   *relation;           /* relation to delete from */
        Node       *whereClause;        /* qualifications */
-       InhOption       inhOpt;                 /* recursively act on children? */
 } DeleteStmt;
 
 /* ----------------------
@@ -601,11 +632,10 @@ typedef struct DeleteStmt
 typedef struct UpdateStmt
 {
        NodeTag         type;
-       char       *relname;            /* relation to update */
+       RangeVar   *relation;           /* relation to update */
        List       *targetList;         /* the target list (of ResTarget) */
        Node       *whereClause;        /* qualifications */
-       List       *fromClause;         /* the from clause */
-       InhOption       inhOpt;                 /* recursively act on children? */
+       List       *fromClause;         /* optional from clause for more tables */
 } UpdateStmt;
 
 /* ----------------------
@@ -639,8 +669,7 @@ typedef struct SelectStmt
        List       *distinctClause; /* NULL, list of DISTINCT ON exprs, or
                                                                 * lcons(NIL,NIL) for all (SELECT
                                                                 * DISTINCT) */
-       char       *into;                       /* name of table (for select into table) */
-       bool            istemp;                 /* into is a temp table? */
+       RangeVar   *into;                       /* target table (for select into table) */
        List       *intoColNames;       /* column names for into table */
        List       *targetList;         /* the target list (of ResTarget) */
        List       *fromClause;         /* the FROM clause */
@@ -704,6 +733,22 @@ typedef struct SetOperationStmt
  *****************************************************************************/
 
 /* ----------------------
+ *             Create Schema Statement
+ *
+ * NOTE: the schemaElts list contains raw parsetrees for component statements
+ * of the schema, such as CREATE TABLE, GRANT, etc.  These are analyzed and
+ * executed after the schema itself is created.
+ * ----------------------
+ */
+typedef struct CreateSchemaStmt
+{
+       NodeTag         type;
+       char       *schemaname;         /* the name of the schema to create */
+       char       *authid;                     /* the owner of the created schema */
+       List       *schemaElts;         /* schema components (list of parsenodes) */
+} CreateSchemaStmt;
+
+/* ----------------------
  *     Alter Table
  *
  * The fields are used in different ways by the different variants of
@@ -725,8 +770,7 @@ typedef struct AlterTableStmt
                                                                 *      U = change owner
                                                                 *------------
                                                                 */
-       char       *relname;            /* table to work on */
-       InhOption       inhOpt;                 /* recursively act on children? */
+       RangeVar   *relation;           /* table to work on */
        char       *name;                       /* column or constraint name to act on, or
                                                                 * new owner */
        Node       *def;                        /* definition of new column or constraint */
@@ -743,12 +787,12 @@ typedef struct GrantStmt
        NodeTag         type;
        bool            is_grant;               /* not revoke */
        int                     objtype;
-       List       *objects;            /* list of names (as Value strings) */
+       List       *objects;            /* list of names (as Value strings)
+                                                                * or relations (as RangeVar's) */
        List       *privileges;         /* integer list of privilege codes */
        List       *grantees;           /* list of PrivGrantee nodes */
 } GrantStmt;
 
-
 typedef struct PrivGrantee
 {
        NodeTag         type;
@@ -756,7 +800,6 @@ typedef struct PrivGrantee
        char       *groupname;
 } PrivGrantee;
 
-
 typedef struct FuncWithArgs
 {
        NodeTag         type;
@@ -764,7 +807,6 @@ typedef struct FuncWithArgs
        List       *funcargs;           /* list of Typename nodes */
 } FuncWithArgs;
 
-
 /* This is only used internally in gram.y. */
 typedef struct PrivTarget
 {
@@ -773,7 +815,6 @@ typedef struct PrivTarget
        List       *objs;
 } PrivTarget;
 
-
 /* ----------------------
  *             Close Portal Statement
  * ----------------------
@@ -792,7 +833,7 @@ typedef struct CopyStmt
 {
        NodeTag         type;
        bool            binary;                 /* is a binary copy? */
-       char       *relname;            /* the relation to copy */
+       RangeVar   *relation;           /* the relation to copy */
        bool            oids;                   /* copy oid's? */
        int                     direction;              /* TO or FROM */
        char       *filename;           /* if NULL, use stdin/stdout */
@@ -813,12 +854,10 @@ typedef struct CopyStmt
 typedef struct CreateStmt
 {
        NodeTag         type;
-       char       *relname;            /* name of relation to create */
+       RangeVar   *relation;           /* relation to create */
        List       *tableElts;          /* column definitions (list of ColumnDef) */
-       List       *inhRelnames;        /* relations to inherit from (list of
-                                                                * T_String Values) */
+       List       *inhRelations;       /* relations to inherit from */
        List       *constraints;        /* constraints (list of Constraint nodes) */
-       bool            istemp;                 /* is this a temp table? */
        bool            hasoids;                /* should it have OIDs? */
 } CreateStmt;
 
@@ -886,7 +925,7 @@ typedef struct FkConstraint
 {
        NodeTag         type;
        char       *constr_name;        /* Constraint name */
-       char       *pktable_name;       /* Primary key table name */
+       RangeVar   *pktable;            /* Primary key table */
        List       *fk_attrs;           /* Attributes of foreign key */
        List       *pk_attrs;           /* Corresponding attrs in PK table */
        char       *match_type;         /* FULL or PARTIAL */
@@ -904,7 +943,7 @@ typedef struct CreateTrigStmt
 {
        NodeTag         type;
        char       *trigname;           /* TRIGGER' name */
-       char       *relname;            /* triggered relation */
+       RangeVar   *relation;           /* triggered relation */
        char       *funcname;           /* function to call (or NULL) */
        List       *args;                       /* list of (T_String) Values or NULL */
        bool            before;                 /* BEFORE/AFTER */
@@ -920,14 +959,14 @@ typedef struct CreateTrigStmt
        bool            isconstraint;   /* This is an RI trigger */
        bool            deferrable;             /* [NOT] DEFERRABLE */
        bool            initdeferred;   /* INITIALLY {DEFERRED|IMMEDIATE} */
-       char       *constrrelname;      /* opposite relation */
+       RangeVar   *constrrel;          /* opposite relation */
 } CreateTrigStmt;
 
 typedef struct DropTrigStmt
 {
        NodeTag         type;
        char       *trigname;           /* TRIGGER' name */
-       char       *relname;            /* triggered relation */
+       RangeVar   *relation;           /* triggered relation */
 } DropTrigStmt;
 
 /* ----------------------
@@ -1014,8 +1053,7 @@ typedef struct DropGroupStmt
 typedef struct CreateSeqStmt
 {
        NodeTag         type;
-       char       *seqname;            /* the relation to create */
-       bool            istemp;                 /* is this a temp sequence? */
+       RangeVar   *sequence;           /* the sequence to create */
        List       *options;
 } CreateSeqStmt;
 
@@ -1072,7 +1110,7 @@ typedef struct CreateDomainStmt
 typedef struct DropStmt
 {
        NodeTag         type;
-       List       *names;
+       List       *objects;
        int                     removeType;
        int                     behavior;               /* CASCADE or RESTRICT drop behavior */
 } DropStmt;
@@ -1084,7 +1122,7 @@ typedef struct DropStmt
 typedef struct TruncateStmt
 {
        NodeTag         type;
-       char       *relName;            /* relation to be truncated */
+       RangeVar   *relation;           /* relation to be truncated */
 } TruncateStmt;
 
 /* ----------------------
@@ -1095,6 +1133,8 @@ typedef struct CommentStmt
 {
        NodeTag         type;
        int                     objtype;                /* Object's type */
+       char       *objschema;          /* Schema where object is defined,
+                                                                * if object is schema specific */
        char       *objname;            /* Name of the object */
        char       *objproperty;        /* Property Id (such as column) */
        List       *objlist;            /* Arguments for VAL objects */
@@ -1132,7 +1172,7 @@ typedef struct IndexStmt
 {
        NodeTag         type;
        char       *idxname;            /* name of the index */
-       char       *relname;            /* name of relation to index on */
+       RangeVar   *relation;           /* relation to build index on */
        char       *accessMethod;       /* name of access method (eg. btree) */
        List       *indexParams;        /* a list of IndexElem */
        Node       *whereClause;        /* qualification (partial-index predicate) */
@@ -1192,14 +1232,13 @@ typedef struct RemoveOperStmt
 } RemoveOperStmt;
 
 /* ----------------------
- *             Alter Table Statement
+ *             Alter Table Rename Statement
  * ----------------------
  */
 typedef struct RenameStmt
 {
        NodeTag         type;
-       char       *relname;            /* relation to be altered */
-       InhOption       inhOpt;                 /* recursively act on children? */
+       RangeVar   *relation;           /* relation to be altered */
        char       *column;                     /* if NULL, rename the relation name to
                                                                 * the new name. Otherwise, rename this
                                                                 * column name. */
@@ -1213,10 +1252,10 @@ typedef struct RenameStmt
 typedef struct RuleStmt
 {
        NodeTag         type;
+       RangeVar   *relation;           /* relation the rule is for */
        char       *rulename;           /* name of the rule */
        Node       *whereClause;        /* qualifications */
-       CmdType         event;                  /* RETRIEVE */
-       struct Attr *object;            /* object affected */
+       CmdType         event;                  /* SELECT, INSERT, etc */
        bool            instead;                /* is a 'do instead'? */
        List       *actions;            /* the action statements */
 } RuleStmt;
@@ -1228,7 +1267,7 @@ typedef struct RuleStmt
 typedef struct NotifyStmt
 {
        NodeTag         type;
-       char       *relname;            /* relation to notify */
+       RangeVar   *relation;           /* qualified name to notify */
 } NotifyStmt;
 
 /* ----------------------
@@ -1238,7 +1277,7 @@ typedef struct NotifyStmt
 typedef struct ListenStmt
 {
        NodeTag         type;
-       char       *relname;            /* relation to listen on */
+       RangeVar   *relation;           /* qualified name to listen on */
 } ListenStmt;
 
 /* ----------------------
@@ -1248,7 +1287,7 @@ typedef struct ListenStmt
 typedef struct UnlistenStmt
 {
        NodeTag         type;
-       char       *relname;            /* relation to unlisten on */
+       RangeVar   *relation;           /* qualified name to unlisten on, or '*' */
 } UnlistenStmt;
 
 /* ----------------------
@@ -1268,7 +1307,7 @@ typedef struct TransactionStmt
 typedef struct ViewStmt
 {
        NodeTag         type;
-       char       *viewname;           /* name of the view */
+       RangeVar   *view;                       /* the view to be created */
        List       *aliases;            /* target column names */
        Query      *query;                      /* the SQL statement */
 } ViewStmt;
@@ -1283,7 +1322,6 @@ typedef struct LoadStmt
        char       *filename;           /* file to load */
 } LoadStmt;
 
-
 /* ----------------------
  *             Createdb Statement
  * ----------------------
@@ -1327,7 +1365,7 @@ typedef struct DropdbStmt
 typedef struct ClusterStmt
 {
        NodeTag         type;
-       char       *relname;            /* relation being indexed */
+       RangeVar   *relation;           /* relation being indexed */
        char       *indexname;          /* original index defined */
 } ClusterStmt;
 
@@ -1346,8 +1384,7 @@ typedef struct VacuumStmt
        bool            analyze;                /* do ANALYZE step */
        bool            freeze;                 /* early-freeze option */
        bool            verbose;                /* print progress info */
-       char       *vacrel;                     /* name of single table to process, or
-                                                                * NULL */
+       RangeVar   *relation;           /* single table to process, or NULL */
        List       *va_cols;            /* list of column names, or NIL for all */
 } VacuumStmt;
 
@@ -1413,7 +1450,7 @@ typedef struct VariableResetStmt
 typedef struct LockStmt
 {
        NodeTag         type;
-       List       *rellist;            /* relations to lock */
+       List       *relations;          /* relations to lock */
        int                     mode;                   /* lock mode */
 } LockStmt;
 
@@ -1436,7 +1473,8 @@ typedef struct ReindexStmt
 {
        NodeTag         type;
        int                     reindexType;    /* INDEX|TABLE|DATABASE */
-       const char *name;                       /* name to reindex */
+       RangeVar   *relation;           /* Table or index to reindex */
+       const char *name;                       /* name of database to reindex */
        bool            force;
        bool            all;
 } ReindexStmt;
index 43e4d5a..f732305 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: primnodes.h,v 1.58 2002/03/12 00:52:02 tgl Exp $
+ * $Id: primnodes.h,v 1.59 2002/03/21 16:01:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -508,7 +508,7 @@ typedef struct RangeTblRef
  * If he writes ON() then only "quals" is set. Note that NATURAL/USING
  * are not equivalent to ON() since they also affect the output column list.
  *
- * alias is an Attr node representing the AS alias-clause attached to the
+ * alias is an Alias node representing the AS alias-clause attached to the
  * join expression, or NULL if no clause.  NB: presence or absence of the
  * alias has a critical impact on semantics, because a join with an alias
  * restricts visibility of the tables/columns inside it.
@@ -527,7 +527,7 @@ typedef struct JoinExpr
        Node       *rarg;                       /* right subtree */
        List       *using;                      /* USING clause, if any (list of String) */
        Node       *quals;                      /* qualifiers on join, if any */
-       struct Attr *alias;                     /* user-written alias clause, if any */
+       struct Alias *alias;            /* user-written alias clause, if any */
        int                     rtindex;                /* RT index assigned for join */
 } JoinExpr;
 
index 09cdde3..7d520ee 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: analyze.h,v 1.18 2001/11/05 17:46:34 momjian Exp $
+ * $Id: analyze.h,v 1.19 2002/03/21 16:01:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,6 +16,7 @@
 #include "parser/parse_node.h"
 
 extern List *parse_analyze(Node *parseTree, ParseState *parentParseState);
+extern List *analyzeCreateSchemaStmt(CreateSchemaStmt *stmt);
 
 extern void CheckSelectForUpdate(Query *qry);
 
index 22d046e..666e4ed 100644 (file)
@@ -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_agg.h,v 1.20 2001/11/05 17:46:34 momjian Exp $
+ * $Id: parse_agg.h,v 1.21 2002/03/21 16:01:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,8 +19,7 @@
 extern void AddAggToParseState(ParseState *pstate, Aggref *aggref);
 extern void parseCheckAggregates(ParseState *pstate, Query *qry, Node *qual);
 extern 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);
 extern void agg_error(char *caller, char *aggname, Oid basetypeID);
 
 #endif   /* PARSE_AGG_H */
index 6c90642..e330f8c 100644 (file)
@@ -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_expr.h,v 1.25 2001/11/05 17:46:34 momjian Exp $
+ * $Id: parse_expr.h,v 1.26 2002/03/21 16:01:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "parser/parse_node.h"
 
-#define EXPR_COLUMN_FIRST      1
-#define EXPR_RELATION_FIRST 2
 
+/* GUC parameters */
 extern int     max_expr_depth;
 extern bool Transform_null_equals;
 
-extern Node *transformExpr(ParseState *pstate, Node *expr, int precedence);
+extern Node *transformExpr(ParseState *pstate, Node *expr);
 extern Oid     exprType(Node *expr);
 extern int32 exprTypmod(Node *expr);
 extern bool exprIsLengthCoercion(Node *expr, int32 *coercedTypmod);
index ff70080..603ea93 100644 (file)
@@ -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_func.h,v 1.35 2001/11/05 17:46:35 momjian Exp $
+ * $Id: parse_func.h,v 1.36 2002/03/21 16:02:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,12 +47,9 @@ typedef enum
 } FuncDetailCode;
 
 
-extern Node *ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr,
-                                               int precedence);
 extern Node *ParseFuncOrColumn(ParseState *pstate,
                                  char *funcname, List *fargs,
-                                 bool agg_star, bool agg_distinct,
-                                 int precedence);
+                                 bool agg_star, bool agg_distinct, bool is_column);
 
 extern FuncDetailCode func_get_detail(char *funcname, List *fargs,
                                int nargs, Oid *argtypes,
index 1b57985..656c70a 100644 (file)
@@ -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.29 2002/03/12 00:52:04 tgl Exp $
+ * $Id: parse_relation.h,v 1.30 2002/03/21 16:02:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,12 +29,12 @@ extern Node *qualifiedNameToVar(ParseState *pstate, char *refname,
                                   char *colname, bool implicitRTEOK);
 extern RangeTblEntry *addRangeTableEntry(ParseState *pstate,
                                   char *relname,
-                                  Attr *alias,
+                                  Alias *alias,
                                   bool inh,
                                   bool inFromCl);
 extern RangeTblEntry *addRangeTableEntryForSubquery(ParseState *pstate,
                                                          Query *subquery,
-                                                         Attr *alias,
+                                                         Alias *alias,
                                                          bool inFromCl);
 extern RangeTblEntry *addRangeTableEntryForJoin(ParseState *pstate,
                                                  List *colnames,
@@ -43,7 +43,7 @@ extern RangeTblEntry *addRangeTableEntryForJoin(ParseState *pstate,
                                                  List *coltypmods,
                                                  List *leftcols,
                                                  List *rightcols,
-                                                 Attr *alias,
+                                                 Alias *alias,
                                                  bool inFromCl);
 extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
                          bool addToJoinList, bool addToNameSpace);
index 0e01eea..ae5a7f4 100644 (file)
@@ -396,7 +396,7 @@ drop table atacc1;
 create table atacc1 ( test int );
 -- add a check constraint (fails)
 alter table atacc1 add constraint atacc_test1 check (test1>3);
-ERROR:  Attribute 'test1' not found
+ERROR:  Attribute "test1" not found
 drop table atacc1;
 -- something a little more complicated
 create table atacc1 ( test int, test2 int, test3 int);
index f767c87..625c6d7 100644 (file)
@@ -22,19 +22,19 @@ select * from nonesuch;
 ERROR:  parser: parse error at or near "select"
 -- bad name in target list
 select nonesuch from pg_database;
-ERROR:  Attribute 'nonesuch' not found
+ERROR:  Attribute "nonesuch" not found
 -- bad attribute name on lhs of operator
 select * from pg_database where nonesuch = pg_database.datname;
-ERROR:  Attribute 'nonesuch' not found
+ERROR:  Attribute "nonesuch" not found
 -- bad attribute name on rhs of operator
 select * from pg_database where pg_database.datname = nonesuch;
-ERROR:  Attribute 'nonesuch' not found
+ERROR:  Attribute "nonesuch" not found
 -- bad select distinct on syntax, distinct attribute missing
 select distinct on (foobar) from pg_database;
 ERROR:  parser: parse error at or near "from"
 -- bad select distinct on syntax, distinct attribute not in target list
 select distinct on (foobar) * from pg_database;
-ERROR:  Attribute 'foobar' not found
+ERROR:  Attribute "foobar" not found
 --
 -- DELETE
  
index 4f54ed3..8633aa5 100644 (file)
@@ -1177,7 +1177,7 @@ drop rule foorule;
 -- this should fail because f1 is not exposed for unqualified reference:
 create rule foorule as on insert to foo where f1 < 100
 do instead insert into foo2 values (f1);
-ERROR:  Attribute 'f1' not found
+ERROR:  Attribute "f1" not found
 -- this is the correct way:
 create rule foorule as on insert to foo where f1 < 100
 do instead insert into foo2 values (new.f1);
index fb24220..0adad8c 100644 (file)
@@ -406,7 +406,7 @@ ORDER BY q2,q1;
 
 -- This should fail, because q2 isn't a name of an EXCEPT output column
 SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1;
-ERROR:  Attribute 'q2' not found
+ERROR:  Attribute "q2" not found
 -- But this should work:
 SELECT q1 FROM int8_tbl EXCEPT (((SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1)));
         q1        
index 9c7a707..18bf4e8 100644 (file)
@@ -170,44 +170,44 @@ SELECT class, aa, a FROM a_star*;
 -- joe and sally play basketball, and
 -- everyone else does nothing.
 --
-SELECT p.name, p.hobbies.name FROM ONLY person p;
+SELECT p.name, name(p.hobbies) FROM ONLY person p;
 
 --
 -- as above, but jeff also does post_hacking.
 --
-SELECT p.name, p.hobbies.name FROM person* p;
+SELECT p.name, name(p.hobbies) FROM person* p;
 
 --
 -- the next two queries demonstrate how functions generate bogus duplicates.
 -- this is a "feature" ..
 --
-SELECT DISTINCT hobbies_r.name, hobbies_r.equipment.name FROM hobbies_r;
+SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r;
 
-SELECT hobbies_r.name, hobbies_r.equipment.name FROM hobbies_r;
+SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r;
 
 --
 -- mike needs advil and peet's coffee,
 -- joe and sally need hightops, and
 -- everyone else is fine.
 --
-SELECT p.name, p.hobbies.name, p.hobbies.equipment.name FROM ONLY person p;
+SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p;
 
 --
 -- as above, but jeff needs advil and peet's coffee as well.
 --
-SELECT p.name, p.hobbies.name, p.hobbies.equipment.name FROM person* p;
+SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p;
 
 --
 -- just like the last two, but make sure that the target list fixup and
 -- unflattening is being done correctly.
 --
-SELECT p.hobbies.equipment.name, p.name, p.hobbies.name FROM ONLY person p;
+SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p;
 
-SELECT p.hobbies.equipment.name, p.name, p.hobbies.name FROM person* p;
+SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p;
 
-SELECT p.hobbies.equipment.name, p.hobbies.name, p.name FROM ONLY person p;
+SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p;
 
-SELECT p.hobbies.equipment.name, p.hobbies.name, p.name FROM person* p;
+SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p;
 
 SELECT user_relns() AS user_relns
    ORDER BY user_relns;
index e3a5109..971ccfc 100644 (file)
@@ -442,7 +442,7 @@ SELECT class, aa, a FROM a_star*;
 -- joe and sally play basketball, and
 -- everyone else does nothing.
 --
-SELECT p.name, p.hobbies.name FROM ONLY person p;
+SELECT p.name, name(p.hobbies) FROM ONLY person p;
  name  |    name     
 -------+-------------
  mike  | posthacking
@@ -453,7 +453,7 @@ SELECT p.name, p.hobbies.name FROM ONLY person p;
 --
 -- as above, but jeff also does post_hacking.
 --
-SELECT p.name, p.hobbies.name FROM person* p;
+SELECT p.name, name(p.hobbies) FROM person* p;
  name  |    name     
 -------+-------------
  mike  | posthacking
@@ -466,7 +466,7 @@ SELECT p.name, p.hobbies.name FROM person* p;
 -- the next two queries demonstrate how functions generate bogus duplicates.
 -- this is a "feature" ..
 --
-SELECT DISTINCT hobbies_r.name, hobbies_r.equipment.name FROM hobbies_r;
+SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r;
     name     |     name      
 -------------+---------------
  basketball  | hightops
@@ -475,7 +475,7 @@ SELECT DISTINCT hobbies_r.name, hobbies_r.equipment.name FROM hobbies_r;
  skywalking  | guts
 (4 rows)
 
-SELECT hobbies_r.name, hobbies_r.equipment.name FROM hobbies_r;
+SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r;
     name     |     name      
 -------------+---------------
  posthacking | advil
@@ -492,7 +492,7 @@ SELECT hobbies_r.name, hobbies_r.equipment.name FROM hobbies_r;
 -- joe and sally need hightops, and
 -- everyone else is fine.
 --
-SELECT p.name, p.hobbies.name, p.hobbies.equipment.name FROM ONLY person p;
+SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p;
  name  |    name     |     name      
 -------+-------------+---------------
  mike  | posthacking | advil
@@ -504,7 +504,7 @@ SELECT p.name, p.hobbies.name, p.hobbies.equipment.name FROM ONLY person p;
 --
 -- as above, but jeff needs advil and peet's coffee as well.
 --
-SELECT p.name, p.hobbies.name, p.hobbies.equipment.name FROM person* p;
+SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p;
  name  |    name     |     name      
 -------+-------------+---------------
  mike  | posthacking | advil
@@ -519,7 +519,7 @@ SELECT p.name, p.hobbies.name, p.hobbies.equipment.name FROM person* p;
 -- just like the last two, but make sure that the target list fixup and
 -- unflattening is being done correctly.
 --
-SELECT p.hobbies.equipment.name, p.name, p.hobbies.name FROM ONLY person p;
+SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p;
      name      | name  |    name     
 ---------------+-------+-------------
  advil         | mike  | posthacking
@@ -528,7 +528,7 @@ SELECT p.hobbies.equipment.name, p.name, p.hobbies.name FROM ONLY person p;
  hightops      | sally | basketball
 (4 rows)
 
-SELECT p.hobbies.equipment.name, p.name, p.hobbies.name FROM person* p;
+SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p;
      name      | name  |    name     
 ---------------+-------+-------------
  advil         | mike  | posthacking
@@ -539,7 +539,7 @@ SELECT p.hobbies.equipment.name, p.name, p.hobbies.name FROM person* p;
  peet's coffee | jeff  | posthacking
 (6 rows)
 
-SELECT p.hobbies.equipment.name, p.hobbies.name, p.name FROM ONLY person p;
+SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p;
      name      |    name     | name  
 ---------------+-------------+-------
  advil         | posthacking | mike
@@ -548,7 +548,7 @@ SELECT p.hobbies.equipment.name, p.hobbies.name, p.name FROM ONLY person p;
  hightops      | basketball  | sally
 (4 rows)
 
-SELECT p.hobbies.equipment.name, p.hobbies.name, p.name FROM person* p;
+SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p;
      name      |    name     | name  
 ---------------+-------------+-------
  advil         | posthacking | mike