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 73c0287d446e2ef41a300387b6ba59a57b0a5a91..262c1e2e8c7b2b41a164018baec182f83f7e7515 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,28 +329,46 @@ ERROR:  function declared to return emp returns varchar instead of text at colum
      there are some unpleasant restrictions on how functions returning
      composite types can be used.  Briefly, when calling a function that
      returns a row, we cannot retrieve the entire row.  We must either
-     project a single attribute out of the row or pass the entire row into
+     extract a single attribute out of the row or pass the entire row into
      another function.  (Trying to display the entire row value will yield
      a meaningless number.)  For example,
 
 <programlisting>
-SELECT name(new_emp());
+SELECT (new_emp()).name;
 </programlisting>
 
 <screen>
  name
 ------
  None
+</screen>
+
+     We need the extra parentheses to keep the parser from getting confused:
+
+<screen>
+SELECT new_emp().name;
+ERROR:  parser: parse error at or near "."
 </screen>
     </para>
 
     <para>
-     This example makes use of the
-     function notation for projecting attributes.  The  simple  way 
-     to explain this is that we can usually use the
+     Another approach is to use
+     functional notation for extracting attributes.  The  simple  way 
+     to explain this is that we can use the
      notations <literal>attribute(table)</>  and  <literal>table.attribute</>
      interchangeably:
 
+<programlisting>
+SELECT name(new_emp());
+</programlisting>
+
+<screen>
+ name
+------
+ None
+</screen>
+    </para>
+
 <programlisting>
 --
 -- this is the same as:
@@ -367,19 +386,6 @@ SELECT name(EMP) AS youngster
 </screen>
     </para>
 
-    <para>
-   The reason why, in general, we must use the function
-        syntax  for projecting attributes of function return
-        values is that the parser  just  doesn't  understand
-        the  dot syntax for projection when combined
-        with function calls.
-
-<screen>
-SELECT new_emp().name AS nobody;
-ERROR:  parser: parse error at or near "."
-</screen>
-    </para>
-
     <para>
      Another way to use a function returning a row result is to declare a
      second function accepting a row type parameter, and pass the function
index 2bdacbdf3b3cdc68510802d6639d2d5fc48c4212..2244827f7c4ec39f0e0ddeac0b944c00dfd89436 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 e7bb12807688fa0e1f407f889c05a4d777d59df5..629ffe7c2e9e05806c9f639d52245142ce0d2bdb 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 c32be8b02f397cd9f52009167f5659a7036ac4d8..5821e1d10366acc1ca49b77e12ea0abe1dc1ed5f 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 c9dee0cbbedb870708208f61e603d5cb5147d33d..04854a2afa1a481bb933d1564e6d4e4e36eca0d8 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 e230ba598a00fae5a6a56d5269f2a33e9a6361c1..95263a5da08d44dd9391ed00cb7273b7af84151a 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 0e57d90dfbcada59ffa86021ada6c00f4203259a..e9df6392bc083591565d106dd0f4c4f70f80adb4 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 e25b83b4556cf4675e300b47d44b83cbf70092c0..5bef86e30610ce1f69a01242c4e5cf8c63f632cc 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 6b94db107772ad2a1b1d81bd6455c72f599bf5db..836091c583f45224f2834e0079ad666006e48733 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 9d1254a4cb0bfd7373a5f57adaa5be22aac8176b..74a3ac2bcaa63cd64662595c2e19e28c683671a4 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 35a5c2d713871577ffaf74483384d9a922d528e6..9b8e3586024178765e8ff7621f941193d882b713 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 c8c65b1cee43039a9734c8cb07535312b454e65a..f09f90744e8fcae68cf416368dccadc3295d56af 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 ebdc7cf1165892dceef19391d751d470f0480302..fb68866c53ed50950e0558ce5de3db582b304f7f 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 c7ed489e091dbd6e1bcd382657ac1c980e0578bd..9788fd2f526abab37efc4b0eba2c8a281ef7fc88 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)
@@ -1407,6 +1397,19 @@ _equalReindexStmt(ReindexStmt *a, ReindexStmt *b)
    return true;
 }
 
+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)
 {
@@ -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;
 }
@@ -1500,6 +1495,19 @@ _equalAIndices(A_Indices *a, A_Indices *b)
    return true;
 }
 
+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)
 {
@@ -1535,14 +1543,31 @@ _equalSortGroupBy(SortGroupBy *a, SortGroupBy *b)
    return true;
 }
 
+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 36f8460b46c17c81d5123bb2c5609cc04e4de869..d8bf80a52efd3eddccbb6e3965e7e76134972898 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 5d43a8e15e5e2723ffc9d2049e2381c651b02e70..401b34b88cc4cf07bbb19fe9eff9f20bc3c354c8 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 3699fc38ffb6e9e0b57d0768c5d2db88eca5f33a..aff46e6ba33aa6f7096c6b341311cd6aad0f8ed5 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 ");
@@ -142,6 +141,13 @@ _outIndexStmt(StringInfo str, IndexStmt *node)
                     booltostr(node->primary));
 }
 
+static void
+_outNotifyStmt(StringInfo str, NotifyStmt *node)
+{
+   appendStringInfo(str, "NOTIFY :relation ");
+   _outNode(str, node->relation);
+}
+
 static void
 _outSelectStmt(StringInfo str, SelectStmt *node)
 {
@@ -213,53 +219,40 @@ _outIndexElem(StringInfo str, IndexElem *node)
 static void
 _outQuery(StringInfo str, Query *node)
 {
+   appendStringInfo(str, " QUERY :command %d :utility ", node->commandType);
 
-   appendStringInfo(str, " QUERY :command %d ", node->commandType);
-
+   /*
+    * Hack to work around missing outfuncs routines for a lot of the
+    * utility-statement node types.  (The only one we actually *need*
+    * for rules support is NotifyStmt.)  Someday we ought to support
+    * 'em all, but for the meantime do this to avoid getting lots of
+    * warnings when running with debug_print_parse on.
+    */
    if (node->utilityStmt)
    {
-       /*
-        * Hack to make up for lack of outfuncs for utility-stmt nodes
-        */
        switch (nodeTag(node->utilityStmt))
        {
            case T_CreateStmt:
-               appendStringInfo(str, " :create ");
-               _outToken(str, ((CreateStmt *) (node->utilityStmt))->relname);
-               appendStringInfo(str, " ");
-               _outNode(str, node->utilityStmt);
-               break;
-
            case T_IndexStmt:
-               appendStringInfo(str, " :index ");
-               _outToken(str, ((IndexStmt *) (node->utilityStmt))->idxname);
-               appendStringInfo(str, " on ");
-               _outToken(str, ((IndexStmt *) (node->utilityStmt))->relname);
-               appendStringInfo(str, " ");
-               _outNode(str, node->utilityStmt);
-               break;
-
            case T_NotifyStmt:
-               appendStringInfo(str, " :notify ");
-               _outToken(str, ((NotifyStmt *) (node->utilityStmt))->relname);
+               _outNode(str, node->utilityStmt);
                break;
-
            default:
-               appendStringInfo(str, " :utility ? ");
+               appendStringInfo(str, "?");
+               break;
        }
    }
    else
-       appendStringInfo(str, " :utility <>");
+       appendStringInfo(str, "<>");
 
    appendStringInfo(str, " :resultRelation %d :into ",
                     node->resultRelation);
-   _outToken(str, node->into);
+   _outNode(str, node->into);
 
-   appendStringInfo(str, " :isPortal %s :isBinary %s :isTemp %s"
+   appendStringInfo(str, " :isPortal %s :isBinary %s"
                     " :hasAggs %s :hasSubLinks %s :rtable ",
                     booltostr(node->isPortal),
                     booltostr(node->isBinary),
-                    booltostr(node->isTemp),
                     booltostr(node->hasAggs),
                     booltostr(node->hasSubLinks));
    _outNode(str, node->rtable);
@@ -963,6 +956,15 @@ _outTargetEntry(StringInfo str, TargetEntry *node)
    _outNode(str, node->expr);
 }
 
+static void
+_outAlias(StringInfo str, Alias *node)
+{
+   appendStringInfo(str, " ALIAS :aliasname ");
+   _outToken(str, node->aliasname);
+   appendStringInfo(str, " :colnames ");
+   _outNode(str, node->colnames);
+}
+
 static void
 _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
 {
@@ -1312,19 +1314,46 @@ _outValue(StringInfo str, Value *value)
 }
 
 static void
-_outIdent(StringInfo str, Ident *node)
+_outRangeVar(StringInfo str, RangeVar *node)
 {
-   appendStringInfo(str, " IDENT ");
-   _outToken(str, node->name);
+   appendStringInfo(str, " RANGEVAR :relation ");
+   /*
+    * we deliberately ignore catalogname here, since it is presently not
+    * semantically meaningful
+    */
+   _outToken(str, node->schemaname);
+   appendStringInfo(str, " . ");
+   _outToken(str, node->relname);
+   appendStringInfo(str, " :inhopt %d :istemp %s",
+                   (int) node->inhOpt,
+                   booltostr(node->istemp));
+   appendStringInfo(str, " :alias ");
+   _outNode(str, node->alias);
 }
 
 static void
-_outAttr(StringInfo str, Attr *node)
+_outColumnRef(StringInfo str, ColumnRef *node)
 {
-   appendStringInfo(str, " ATTR :relname ");
-   _outToken(str, node->relname);
-   appendStringInfo(str, " :attrs ");
-   _outNode(str, node->attrs);
+   appendStringInfo(str, " COLUMNREF :fields ");
+   _outNode(str, node->fields);
+   appendStringInfo(str, " :indirection ");
+   _outNode(str, node->indirection);
+}
+
+static void
+_outParamRef(StringInfo str, ParamRef *node)
+{
+   appendStringInfo(str, " PARAMREF :number %d :fields ", node->number);
+   _outNode(str, node->fields);
+   appendStringInfo(str, " :indirection ");
+   _outNode(str, node->indirection);
+}
+
+static void
+_outIdent(StringInfo str, Ident *node)
+{
+   appendStringInfo(str, " IDENT ");
+   _outToken(str, node->name);
 }
 
 static void
@@ -1336,6 +1365,17 @@ _outAConst(StringInfo str, A_Const *node)
    _outNode(str, node->typename);
 }
 
+static void
+_outExprFieldSelect(StringInfo str, ExprFieldSelect *node)
+{
+   appendStringInfo(str, " EXPRFIELDSELECT :arg ");
+   _outNode(str, node->arg);
+   appendStringInfo(str, " :fields ");
+   _outNode(str, node->fields);
+   appendStringInfo(str, " :indirection ");
+   _outNode(str, node->indirection);
+}
+
 static void
 _outConstraint(StringInfo str, Constraint *node)
 {
@@ -1384,8 +1424,8 @@ _outFkConstraint(StringInfo str, FkConstraint *node)
 {
    appendStringInfo(str, " FKCONSTRAINT :constr_name ");
    _outToken(str, node->constr_name);
-   appendStringInfo(str, " :pktable_name ");
-   _outToken(str, node->pktable_name);
+   appendStringInfo(str, " :pktable ");
+   _outNode(str, node->pktable);
    appendStringInfo(str, " :fk_attrs ");
    _outNode(str, node->fk_attrs);
    appendStringInfo(str, " :pk_attrs ");
@@ -1490,6 +1530,12 @@ _outNode(StringInfo str, void *obj)
            case T_IndexStmt:
                _outIndexStmt(str, obj);
                break;
+           case T_NotifyStmt:
+               _outNotifyStmt(str, obj);
+               break;
+           case T_SelectStmt:
+               _outSelectStmt(str, obj);
+               break;
            case T_ColumnDef:
                _outColumnDef(str, obj);
                break;
@@ -1628,6 +1674,9 @@ _outNode(StringInfo str, void *obj)
            case T_TargetEntry:
                _outTargetEntry(str, obj);
                break;
+           case T_Alias:
+               _outAlias(str, obj);
+               break;
            case T_RangeTblEntry:
                _outRangeTblEntry(str, obj);
                break;
@@ -1670,12 +1719,24 @@ _outNode(StringInfo str, void *obj)
            case T_A_Expr:
                _outAExpr(str, obj);
                break;
+           case T_RangeVar:
+               _outRangeVar(str, obj);
+               break;
+           case T_ColumnRef:
+               _outColumnRef(str, obj);
+               break;
+           case T_ParamRef:
+               _outParamRef(str, obj);
+               break;
            case T_Ident:
                _outIdent(str, obj);
                break;
            case T_A_Const:
                _outAConst(str, obj);
                break;
+           case T_ExprFieldSelect:
+               _outExprFieldSelect(str, obj);
+               break;
            case T_Constraint:
                _outConstraint(str, obj);
                break;
@@ -1694,17 +1755,9 @@ _outNode(StringInfo str, void *obj)
            case T_BooleanTest:
                _outBooleanTest(str, obj);
                break;
-           case T_VariableSetStmt:
-               break;
-           case T_SelectStmt:
-               _outSelectStmt(str, obj);
-               break;
            case T_FuncCall:
                _outFuncCall(str, obj);
                break;
-           case T_Attr:
-               _outAttr(str, obj);
-               break;
 
            default:
                elog(WARNING, "_outNode: don't know how to print type %d ",
index 0d929941020b00c5fad25d3e7a7e773009708c3b..ebc5d536e7d2ff917af3a5eecd4aa31c792c8a14 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 c0794123b3e54552172481f644437390424df788..66dd317f394f892418b88cdb64320fd6d802b78b 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);
@@ -210,6 +191,25 @@ _readQuery(void)
    return local_node;
 }
 
+/* ----------------
+ *     _readNotifyStmt
+ * ----------------
+ */
+static NotifyStmt *
+_readNotifyStmt(void)
+{
+   NotifyStmt *local_node;
+   char       *token;
+   int         length;
+
+   local_node = makeNode(NotifyStmt);
+
+   token = pg_strtok(&length); /* skip :relation */
+   local_node->relation = nodeRead(true);
+
+   return local_node;
+}
+
 /* ----------------
  *     _readSortClause
  * ----------------
@@ -1394,21 +1394,93 @@ _readTargetEntry(void)
    return local_node;
 }
 
-static Attr *
-_readAttr(void)
+static RangeVar *
+_readRangeVar(void)
 {
-   Attr       *local_node;
+   RangeVar   *local_node;
    char       *token;
    int         length;
 
-   local_node = makeNode(Attr);
+   local_node = makeNode(RangeVar);
 
-   token = pg_strtok(&length); /* eat :relname */
+   local_node->catalogname = NULL; /* not currently saved in output format */
+
+   token = pg_strtok(&length); /* eat :relation */
+   token = pg_strtok(&length); /* get schemaname */
+   local_node->schemaname = nullable_string(token, length);
+
+   token = pg_strtok(&length); /* eat "." */
    token = pg_strtok(&length); /* get relname */
-   local_node->relname = debackslash(token, length);
+   local_node->relname = nullable_string(token, length);
+   
+   token = pg_strtok(&length); /* eat :inhopt */
+   token = pg_strtok(&length); /* get inhopt */
+   local_node->inhOpt = (InhOption) atoi(token);
+   
+   token = pg_strtok(&length); /* eat :istemp */
+   token = pg_strtok(&length); /* get istemp */
+   local_node->istemp = strtobool(token);
+
+   token = pg_strtok(&length); /* eat :alias */
+   local_node->alias = nodeRead(true); /* now read it */
+
+   return local_node;
+}
+
+static ColumnRef *
+_readColumnRef(void)
+{
+   ColumnRef  *local_node;
+   char       *token;
+   int         length;
+
+   local_node = makeNode(ColumnRef);
+
+   token = pg_strtok(&length); /* eat :fields */
+   local_node->fields = nodeRead(true); /* now read it */
+
+   token = pg_strtok(&length); /* eat :indirection */
+   local_node->indirection = nodeRead(true); /* now read it */
+
+   return local_node;
+}
+
+static ExprFieldSelect *
+_readExprFieldSelect(void)
+{
+   ExprFieldSelect  *local_node;
+   char       *token;
+   int         length;
+
+   local_node = makeNode(ExprFieldSelect);
+
+   token = pg_strtok(&length); /* eat :arg */
+   local_node->arg = nodeRead(true); /* now read it */
+
+   token = pg_strtok(&length); /* eat :fields */
+   local_node->fields = nodeRead(true); /* now read it */
+
+   token = pg_strtok(&length); /* eat :indirection */
+   local_node->indirection = nodeRead(true); /* now read it */
+
+   return local_node;
+}
+
+static Alias *
+_readAlias(void)
+{
+   Alias      *local_node;
+   char       *token;
+   int         length;
+
+   local_node = makeNode(Alias);
+
+   token = pg_strtok(&length); /* eat :aliasname */
+   token = pg_strtok(&length); /* get aliasname */
+   local_node->aliasname = debackslash(token, length);
 
-   token = pg_strtok(&length); /* eat :attrs */
-   local_node->attrs = nodeRead(true); /* now read it */
+   token = pg_strtok(&length); /* eat :colnames */
+   local_node->colnames = nodeRead(true); /* now read it */
 
    return local_node;
 }
@@ -1994,8 +2066,6 @@ parsePlanString(void)
        return_value = _readArrayRef();
    else if (length == 3 && strncmp(token, "VAR", length) == 0)
        return_value = _readVar();
-   else if (length == 4 && strncmp(token, "ATTR", length) == 0)
-       return_value = _readAttr();
    else if (length == 5 && strncmp(token, "CONST", length) == 0)
        return_value = _readConst();
    else if (length == 4 && strncmp(token, "FUNC", length) == 0)
@@ -2006,6 +2076,14 @@ parsePlanString(void)
        return_value = _readParam();
    else if (length == 11 && strncmp(token, "TARGETENTRY", length) == 0)
        return_value = _readTargetEntry();
+   else if (length == 8 && strncmp(token, "RANGEVAR", length) == 0)
+       return_value = _readRangeVar();
+   else if (length == 9 && strncmp(token, "COLUMNREF", length) == 0)
+       return_value = _readColumnRef();
+   else if (length == 15 && strncmp(token, "EXPRFIELDSELECT", length) == 0)
+       return_value = _readExprFieldSelect();
+   else if (length == 5 && strncmp(token, "ALIAS", length) == 0)
+       return_value = _readAlias();
    else if (length == 3 && strncmp(token, "RTE", length) == 0)
        return_value = _readRangeTblEntry();
    else if (length == 4 && strncmp(token, "PATH", length) == 0)
@@ -2032,6 +2110,8 @@ parsePlanString(void)
        return_value = _readIter();
    else if (length == 5 && strncmp(token, "QUERY", length) == 0)
        return_value = _readQuery();
+   else if (length == 6 && strncmp(token, "NOTIFY", length) == 0)
+       return_value = _readNotifyStmt();
    else if (length == 10 && strncmp(token, "SORTCLAUSE", length) == 0)
        return_value = _readSortClause();
    else if (length == 11 && strncmp(token, "GROUPCLAUSE", length) == 0)
index 6585fb1905da64b6395815c8ef3abc1a3a12a76a..41cc4cdd5370b51edb2abe4b46f651a453c3b328 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 98f5030f78b756706dfd3a66d1afb21b33573fc6..109062c529f50d36bb67ae91094b08b179a94776 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 6951653ce8a352d7a98525ef1648d5fd55273353..f94eaea509815a4106aa68da98e87efa03da61be 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
@@ -3190,21 +3248,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 d6ad0a07ea12a6dbf31a7ac7813a5791e09b3d83..dc939a71801e129102ab62bd44bf5dbf35e7fec6 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 2f1eda4a9bf1502bdaf1b331f5fd754295792209..6e8868f8ea680e6591054f3b0213906b83cb9bb6 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 6409ef3226a0f5725dad09cad950425d1f696cc4..73cd89fd3d84ae31b25bc9edaf651db6e51b1b8e 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 6dc7b440fa87e9e488d59bc9b2b30e391d8b83a7..ee1bf6c057874949de7747a9fb7f754ee9d538a4 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 */
@@ -470,26 +348,12 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
    expr->args = 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 be825c26f9ec6667c708bbdea5e9ac7aee9ad5e9..8b259e97c1d29a86a001db7307f6766820549f78 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 1609c89ce07b796a78b41e5d7e3bd19a4643b56b..5cf868a4d12e484c9bb2f2bccb86a34e83a2235a 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 f5791298f310c6d9197fe032fa6e702b01f9816d..a4b7816517893072774318494869333521a40abd 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 b0315157e4f7ef751d6215eb776a0407b270d849..0b47aa9c924593f07d064566102d384c5929651e 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,
@@ -186,23 +140,6 @@ DefineQueryRewrite(RuleStmt *stmt)
    event_relation = heap_openr(event_obj->relname, AccessExclusiveLock);
    ev_relid = RelationGetRelid(event_relation);
 
-   /*
-    * The current rewrite handler is known to work on relation level
-    * rules only. And for SELECT events, it expects one non-nothing
-    * action that is instead and returns exactly a tuple of the rewritten
-    * relation. This restricts SELECT rules to views.
-    *
-    * Jan
-    */
-   if (event_obj->attrs)
-       elog(ERROR, "attribute level rules currently not supported");
-
-   /*
-    * eslot_string = strVal(lfirst(event_obj->attrs));
-    */
-   else
-       eslot_string = NULL;
-
    /*
     * No rule actions that modify OLD or NEW
     */
@@ -358,21 +295,8 @@ DefineQueryRewrite(RuleStmt *stmt)
    /*
     * This rule is allowed - prepare to install it.
     */
-   if (eslot_string == NULL)
-   {
-       event_attno = -1;
-       event_attype = InvalidOid;
-   }
-   else
-   {
-       event_attno = attnameAttNum(event_relation, eslot_string);
-       event_attype = attnumTypeId(event_relation, event_attno);
-   }
-
-   /* fix bug about instead nothing */
-   ValidateRule(event_type, event_obj->relname,
-                eslot_string, event_qual, &action,
-                is_instead, event_attype);
+   event_attno = -1;
+   event_attype = InvalidOid;
 
    /*
     * We want the rule's table references to be checked as though by the
index af413cab938d701500e1b496707800738adbab81..86a158f94f966a3d7667311ec51bb59fe30eaa94 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 9542170d340a2ed3364d5bde8187edb77a885224..8443fe6591bdd9725c7621843f66e523bfaff056 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 ef4b4edd40f64d2d65b246ee2b0c2b3f997a3816..4599a27a6428512fd8c4b634270373e8c621299b 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 db8d440034f8d95a6d49e203b4960ec38f686101..9a6813635cac0e1771bb920d3937ef80acfde837 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 d47bf3bb945c9f658c7e4ff0022ffade1b4abd41..0e4472faffbda38a97c95f4e407c31e452305e8a 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 a049a2393584e8d191fcec051b65bfebdaba8bff..5e0fa208cf8c109a6a8cd6b6ebe46f16a8d558e0 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 cf09111af47891f3525fcffec4a5db9a8311e0c6..36757b1f7028c60e94d35009c18d89f36f74afa2 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 384241990b5a98d40ef1e0e9cbe89711af340c1b..2de7c03cf6ac311b79a8b5b1d082bff6196a0f16 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 d25bc5f1563616a584cbb0d2cdeb4ab632fc33a2..95aba8dfaa492c95676787fdd023c39b4128d35c 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 1b1f01bd28f7ae57732937135843d5287b086a99..4f5d139011f572887453cbe49e8072fa320952b2 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
@@ -147,22 +162,6 @@ typedef struct A_Expr
    Node       *rexpr;          /* right argument */
 } 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
  */
@@ -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;
 
 /*
@@ -324,6 +319,21 @@ typedef struct A_Indices
    Node       *uidx;
 } 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)
@@ -358,15 +368,37 @@ typedef struct SortGroupBy
    Node       *node;           /* Expression  */
 } 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 */
@@ -703,6 +732,22 @@ typedef struct SetOperationStmt
  *     field in Query.
  *****************************************************************************/
 
+/* ----------------------
+ *     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
  *
@@ -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 43e4d5a41e20673cc5ee9c4a7705ab060708abf6..f7323058251e7fb142f84a90b0b7931b34013d85 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 09cdde3786e2a930235f5205c5106e2ee1b5d947..7d520eef5c3a917a29d664a9d37f8d0082109c5c 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 22d046e48fc34bd932c5dccaa7e4c5bb5919287b..666e4ede7645706e5b8acc3b434534bba5956b0f 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 6c906420de74aa793d273b262120597f395bc316..e330f8c249a44a479b0f07d7c4d31aeee1a78c91 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 ff70080f2173287dc8ce0dacbc533bbe59d6c648..603ea9369c620bfd0db0f6c6ffa442c35d3a3917 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 1b579850f4eeac7ce4014c06a5fded3ddc4cc35a..656c70a688a01c1e22db268e8790fe786f6a5883 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 0e01eeaef5a5412e725cc4298ecb2cc7c0d2a9a5..ae5a7f4f635fbc99d6a1cf17086d614ae7241e81 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 f767c875a9b47632e3f81cc93859a2c0e1146b00..625c6d7499d8ac8f3585e37cf016ad00a35c3f05 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 4f54ed3a7cc2fd616408b624c83d1c1330fc17c7..8633aa56708abdcdc1d2aeb2d457b40117295858 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 fb24220156004d9688ed212c6a7d33711e99ae70..0adad8c119d314a4572789ba47287651fdade9ee 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 9c7a707f1c0efd498c591035f787a5ebdd9d15c3..18bf4e8af7d778be8a4cf7ddbdb496068b405034 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 e3a5109a02c7c79ac3a267ac3fbd7c96c2f4ac54..971ccfca10c72514032ce146db2370b91a862ba2 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