]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Add TABLESPACE and ON COMMIT clauses to CREATE TABLE AS. ON COMMIT is
authorNeil Conway <neilc@samurai.com>
Sun, 19 Feb 2006 00:04:28 +0000 (00:04 +0000)
committerNeil Conway <neilc@samurai.com>
Sun, 19 Feb 2006 00:04:28 +0000 (00:04 +0000)
required by the SQL standard, and TABLESPACE is useful functionality.
Patch from Kris Jurka, minor editorialization by Neil Conway.

17 files changed:
doc/src/sgml/ref/create_table.sgml
doc/src/sgml/ref/create_table_as.sgml
src/backend/commands/prepare.c
src/backend/executor/execMain.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/include/nodes/parsenodes.h
src/test/regress/expected/temp.out
src/test/regress/expected/without_oid.out
src/test/regress/input/tablespace.source
src/test/regress/output/tablespace.source
src/test/regress/sql/temp.sql
src/test/regress/sql/without_oid.sql

index 5dfeca1953c3fa5ab793c1232a7191b114ceb342..a4cdc2501876f0255c6b458e5ba9d7273631fa1d 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.99 2006/01/16 20:48:49 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.100 2006/02/19 00:04:26 neilc Exp $
 PostgreSQL documentation
 -->
 
@@ -580,9 +580,10 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
         <term><literal>DELETE ROWS</literal></term>
         <listitem>
          <para>
-          All rows in the temporary table will be deleted at the
-          end of each transaction block.  Essentially, an automatic
-          <xref linkend="sql-truncate"> is done at each commit.
+          All rows in the temporary table will be deleted at the end
+          of each transaction block.  Essentially, an automatic <xref
+          linkend="sql-truncate" endterm="sql-truncate-title"> is done
+          at each commit.
          </para>
         </listitem>
        </varlistentry>
index 201188d99cc67a6d4bf82716016455c015f1f317..7e7fa7b6731c5543e4fd78ee93645e276a6d023e 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.31 2005/11/01 21:09:50 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.32 2006/02/19 00:04:26 neilc Exp $
 PostgreSQL documentation
 -->
 
@@ -21,7 +21,10 @@ PostgreSQL documentation
  <refsynopsisdiv>
 <synopsis>
 CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replaceable>
-    [ (<replaceable>column_name</replaceable> [, ...] ) ] [ [ WITH | WITHOUT ] OIDS ]
+    [ (<replaceable>column_name</replaceable> [, ...] ) ]
+    [ WITH OIDS | WITHOUT OIDS ]
+    [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+    [ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
     AS <replaceable>query</replaceable>
 </synopsis>
  </refsynopsisdiv>
@@ -113,6 +116,65 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
      </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><literal>ON COMMIT</literal></term>
+    <listitem>
+     <para>
+      The behavior of temporary tables at the end of a transaction
+      block can be controlled using <literal>ON COMMIT</literal>.
+      The three options are:
+
+      <variablelist>
+       <varlistentry>
+        <term><literal>PRESERVE ROWS</literal></term>
+        <listitem>
+         <para>
+          No special action is taken at the ends of transactions.
+          This is the default behavior.
+         </para>
+        </listitem>
+       </varlistentry>
+
+       <varlistentry>
+        <term><literal>DELETE ROWS</literal></term>
+        <listitem>
+         <para>
+          All rows in the temporary table will be deleted at the end
+          of each transaction block.  Essentially, an automatic <xref
+          linkend="sql-truncate" endterm="sql-truncate-title"> is done
+          at each commit.
+         </para>
+        </listitem>
+       </varlistentry>
+
+       <varlistentry>
+        <term><literal>DROP</literal></term>
+        <listitem>
+         <para>
+          The temporary table will be dropped at the end of the current
+          transaction block.
+         </para>
+        </listitem>
+       </varlistentry>
+      </variablelist>
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><literal>TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable></literal></term>
+    <listitem>
+     <para>
+      The <replaceable class="PARAMETER">tablespace</replaceable> is the name
+      of the tablespace in which the new table is to be created.
+      If not specified,
+      <xref linkend="guc-default-tablespace"> is used, or the database's
+      default tablespace if <varname>default_tablespace</> is an empty
+      string.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><replaceable>query</replaceable></term>
     <listitem>
@@ -168,6 +230,20 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
 <programlisting>
 CREATE TABLE films_recent AS
   SELECT * FROM films WHERE date_prod &gt;= '2002-01-01';
+</programlisting>
+  </para>
+
+  <para>
+   Create a new temporary table that will be dropped at commit
+   <literal>films_recent</literal> with oids consisting of only
+   recent entries from the table <literal>films</literal> using a
+   prepared statement:
+
+<programlisting>
+PREPARE recentfilms(date) AS
+  SELECT * FROM films WHERE date_prod &gt; $1;
+CREATE TEMP TABLE films_recent WITH OIDS ON COMMIT DROP AS
+  EXECUTE recentfilms('2002-01-01');
 </programlisting>
   </para>
  </refsect1>
@@ -188,13 +264,6 @@ CREATE TABLE films_recent AS
      </para>
     </listitem>
 
-    <listitem>
-     <para>
-      The standard defines an <literal>ON COMMIT</literal> clause;
-      this is not currently implemented by <productname>PostgreSQL</>.
-     </para>
-    </listitem>
-
     <listitem>
      <para>
       The standard defines a <literal>WITH [ NO ] DATA</literal> clause;
@@ -219,6 +288,14 @@ CREATE TABLE films_recent AS
       for details.
      </para>
     </listitem>
+
+    <listitem>
+     <para>
+      The <productname>PostgreSQL</productname> concept of tablespaces is not
+      part of the standard.  Hence, the clause <literal>TABLESPACE</literal>
+      is an extension.
+     </para>
+    </listitem>
    </itemizedlist>
   </para>
  </refsect1>
index f0afdbba3675d0cfbd7d7bfe99610d06be3e4821..4fd43d7f4966ec6e154d293ea930e7dc8545552a 100644 (file)
@@ -10,7 +10,7 @@
  * Copyright (c) 2002-2005, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.47 2006/01/18 06:49:26 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.48 2006/02/19 00:04:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -196,6 +196,10 @@ ExecuteQuery(ExecuteStmt *stmt, ParamListInfo params,
                                        (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                                         errmsg("prepared statement is not a SELECT")));
                query->into = copyObject(stmt->into);
+               query->intoHasOids = stmt->into_has_oids;
+               query->intoOnCommit = stmt->into_on_commit;
+               if (stmt->into_tbl_space)
+                       query->intoTableSpaceName = pstrdup(stmt->into_tbl_space);
 
                MemoryContextSwitchTo(oldContext);
        }
index a0f9cfedd3f17d7f042e73382d3c01f886ba8d34..99c3bca0a9a8202342472d9585963acbc37cff45 100644 (file)
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.265 2006/01/12 21:48:53 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.266 2006/02/19 00:04:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -37,6 +37,7 @@
 #include "catalog/heap.h"
 #include "catalog/namespace.h"
 #include "commands/tablecmds.h"
+#include "commands/tablespace.h"
 #include "commands/trigger.h"
 #include "executor/execdebug.h"
 #include "executor/execdefs.h"
@@ -730,10 +731,19 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
        {
                char       *intoName;
                Oid                     namespaceId;
+               Oid                     tablespaceId;
                AclResult       aclresult;
                Oid                     intoRelationId;
                TupleDesc       tupdesc;
 
+               /*
+                * Check consistency of arguments
+                */
+               if (parseTree->intoOnCommit != ONCOMMIT_NOOP && !parseTree->into->istemp)
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+                                        errmsg("ON COMMIT can only be used on temporary tables")));
+
                /*
                 * find namespace to create in, check permissions
                 */
@@ -746,6 +756,37 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
                        aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                                                   get_namespace_name(namespaceId));
 
+               /*
+                * Select tablespace to use.  If not specified, use default_tablespace
+                * (which may in turn default to database's default).
+                */
+               if (parseTree->intoTableSpaceName)
+               {
+                       tablespaceId = get_tablespace_oid(parseTree->intoTableSpaceName);
+                       if (!OidIsValid(tablespaceId))
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                                                errmsg("tablespace \"%s\" does not exist",
+                                                               parseTree->intoTableSpaceName)));
+               } else
+               {
+                       tablespaceId = GetDefaultTablespace();
+                       /* note InvalidOid is OK in this case */
+               }
+
+               /* Check permissions except when using the database's default */
+               if (OidIsValid(tablespaceId))
+               {
+                       AclResult       aclresult;
+
+                       aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
+                                                                                          ACL_CREATE);
+
+                       if (aclresult != ACLCHECK_OK)
+                               aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
+                                                          get_tablespace_name(tablespaceId));
+               }
+
                /*
                 * have to copy tupType to get rid of constraints
                 */
@@ -753,7 +794,7 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
 
                intoRelationId = heap_create_with_catalog(intoName,
                                                                                                  namespaceId,
-                                                                                                 InvalidOid,
+                                                                                                 tablespaceId,
                                                                                                  InvalidOid,
                                                                                                  GetUserId(),
                                                                                                  tupdesc,
@@ -761,7 +802,7 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
                                                                                                  false,
                                                                                                  true,
                                                                                                  0,
-                                                                                                 ONCOMMIT_NOOP,
+                                                                                                 parseTree->intoOnCommit,
                                                                                                  allowSystemTableMods);
 
                FreeTupleDesc(tupdesc);
index 6578bf37afddcc48406cb32cf3e81639917878b7..91f06df039af84b22b444a4738caa8bfe30fc15b 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.326 2006/02/04 19:06:46 adunstan Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.327 2006/02/19 00:04:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1662,6 +1662,8 @@ _copyQuery(Query *from)
        COPY_SCALAR_FIELD(resultRelation);
        COPY_NODE_FIELD(into);
        COPY_SCALAR_FIELD(intoHasOids);
+       COPY_SCALAR_FIELD(intoOnCommit);
+       COPY_STRING_FIELD(intoTableSpaceName);
        COPY_SCALAR_FIELD(hasAggs);
        COPY_SCALAR_FIELD(hasSubLinks);
        COPY_NODE_FIELD(rtable);
@@ -1729,6 +1731,8 @@ _copySelectStmt(SelectStmt *from)
        COPY_NODE_FIELD(into);
        COPY_NODE_FIELD(intoColNames);
        COPY_SCALAR_FIELD(intoHasOids);
+       COPY_SCALAR_FIELD(intoOnCommit);
+       COPY_STRING_FIELD(intoTableSpaceName);
        COPY_NODE_FIELD(targetList);
        COPY_NODE_FIELD(fromClause);
        COPY_NODE_FIELD(whereClause);
@@ -2631,6 +2635,10 @@ _copyExecuteStmt(ExecuteStmt *from)
 
        COPY_STRING_FIELD(name);
        COPY_NODE_FIELD(into);
+       COPY_SCALAR_FIELD(into_contains_oids);
+       COPY_SCALAR_FIELD(into_has_oids);
+       COPY_SCALAR_FIELD(into_on_commit);
+       COPY_STRING_FIELD(into_tbl_space);
        COPY_NODE_FIELD(params);
 
        return newnode;
index a9fdc95f6bbbebd01d415114d7d3b12a85fc7246..9a2a5fd0d59b65633a234519887db3a74b64c8d4 100644 (file)
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.262 2006/02/04 19:06:46 adunstan Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.263 2006/02/19 00:04:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -673,6 +673,8 @@ _equalQuery(Query *a, Query *b)
        COMPARE_SCALAR_FIELD(resultRelation);
        COMPARE_NODE_FIELD(into);
        COMPARE_SCALAR_FIELD(intoHasOids);
+       COMPARE_SCALAR_FIELD(intoOnCommit);
+       COMPARE_STRING_FIELD(intoTableSpaceName);
        COMPARE_SCALAR_FIELD(hasAggs);
        COMPARE_SCALAR_FIELD(hasSubLinks);
        COMPARE_NODE_FIELD(rtable);
@@ -732,6 +734,8 @@ _equalSelectStmt(SelectStmt *a, SelectStmt *b)
        COMPARE_NODE_FIELD(into);
        COMPARE_NODE_FIELD(intoColNames);
        COMPARE_SCALAR_FIELD(intoHasOids);
+       COMPARE_SCALAR_FIELD(intoOnCommit);
+       COMPARE_STRING_FIELD(intoTableSpaceName);
        COMPARE_NODE_FIELD(targetList);
        COMPARE_NODE_FIELD(fromClause);
        COMPARE_NODE_FIELD(whereClause);
@@ -1493,6 +1497,10 @@ _equalExecuteStmt(ExecuteStmt *a, ExecuteStmt *b)
 {
        COMPARE_STRING_FIELD(name);
        COMPARE_NODE_FIELD(into);
+       COMPARE_SCALAR_FIELD(into_contains_oids);
+       COMPARE_SCALAR_FIELD(into_has_oids);
+       COMPARE_SCALAR_FIELD(into_on_commit);
+       COMPARE_STRING_FIELD(into_tbl_space);
        COMPARE_NODE_FIELD(params);
 
        return true;
index d6d63ee096f487a63630580543e75b864064bb97..9884b0e4db4fa76288525db804714a5893e47e5b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.267 2006/01/31 21:39:23 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.268 2006/02/19 00:04:26 neilc Exp $
  *
  * NOTES
  *       Every node type that can appear in stored rules' parsetrees *must*
@@ -1374,6 +1374,8 @@ _outSelectStmt(StringInfo str, SelectStmt *node)
        WRITE_NODE_FIELD(into);
        WRITE_NODE_FIELD(intoColNames);
        WRITE_ENUM_FIELD(intoHasOids, ContainsOids);
+       WRITE_ENUM_FIELD(intoOnCommit, OnCommitAction);
+       WRITE_STRING_FIELD(intoTableSpaceName);
        WRITE_NODE_FIELD(targetList);
        WRITE_NODE_FIELD(fromClause);
        WRITE_NODE_FIELD(whereClause);
@@ -1504,6 +1506,9 @@ _outQuery(StringInfo str, Query *node)
 
        WRITE_INT_FIELD(resultRelation);
        WRITE_NODE_FIELD(into);
+       WRITE_BOOL_FIELD(intoHasOids);
+       WRITE_ENUM_FIELD(intoOnCommit, OnCommitAction);
+       WRITE_STRING_FIELD(intoTableSpaceName);
        WRITE_BOOL_FIELD(hasAggs);
        WRITE_BOOL_FIELD(hasSubLinks);
        WRITE_NODE_FIELD(rtable);
index eb2886d843700f735edcba07ccb88d8b0dc675e1..19cb6e9544f9c4d2006fd732bb6162a0009a6107 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.183 2005/12/28 01:29:59 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.184 2006/02/19 00:04:26 neilc Exp $
  *
  * NOTES
  *       Path and Plan nodes do not have any readfuncs support, because we
@@ -140,6 +140,9 @@ _readQuery(void)
        READ_NODE_FIELD(utilityStmt);
        READ_INT_FIELD(resultRelation);
        READ_NODE_FIELD(into);
+       READ_BOOL_FIELD(intoHasOids);
+       READ_ENUM_FIELD(intoOnCommit, OnCommitAction);
+       READ_STRING_FIELD(intoTableSpaceName);
        READ_BOOL_FIELD(hasAggs);
        READ_BOOL_FIELD(hasSubLinks);
        READ_NODE_FIELD(rtable);
index abfb0fbf30347a71ed235eaac33d9c2c9240d79c..057ff41518553448e87d4947b4beaffd85568c60 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *     $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.328 2006/01/15 22:18:46 neilc Exp $
+ *     $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.329 2006/02/19 00:04:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1818,6 +1818,8 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
                applyColumnNames(qry->targetList, stmt->intoColNames);
 
        qry->intoHasOids = interpretOidsOption(stmt->intoHasOids);
+       qry->intoOnCommit = stmt->intoOnCommit;
+       qry->intoTableSpaceName = stmt->intoTableSpaceName;
 
        /* mark column origins */
        markTargetListOrigins(pstate, qry->targetList);
@@ -2662,6 +2664,8 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
 
        paramtypes = FetchPreparedStatementParams(stmt->name);
 
+       stmt->into_has_oids = interpretOidsOption(stmt->into_contains_oids);
+
        if (stmt->params || paramtypes)
        {
                int                     nparams = list_length(stmt->params);
index 88d32d837d45b70ef3ab564730168b4434d87140..6cb6f96fa4f5ea7480d2f42d0b6b2c29384e1b09 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.529 2006/02/12 19:11:01 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.530 2006/02/19 00:04:27 neilc Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -239,7 +239,7 @@ static void doNegateFloat(Value *v);
 
 %type <boolean>  TriggerForType OptTemp
 %type <oncommit> OnCommitOption
-%type <withoids> OptWithOids WithOidsAs
+%type <withoids> OptWithOids
 
 %type <node>   for_locking_clause opt_for_locking_clause
 %type <list>   locked_rels_list
@@ -2171,7 +2171,8 @@ OptConsTableSpace:   USING INDEX TABLESPACE name  { $$ = $4; }
  */
 
 CreateAsStmt:
-                       CREATE OptTemp TABLE qualified_name OptCreateAs WithOidsAs SelectStmt
+               CREATE OptTemp TABLE qualified_name OptCreateAs
+                       OptWithOids OnCommitOption OptTableSpace AS SelectStmt
                                {
                                        /*
                                         * When the SelectStmt is a set-operation tree, we must
@@ -2180,7 +2181,7 @@ CreateAsStmt:
                                         * to find it.  Similarly, the output column names must
                                         * be attached to that Select's target list.
                                         */
-                                       SelectStmt *n = findLeftmostSelect((SelectStmt *) $7);
+                                       SelectStmt *n = findLeftmostSelect((SelectStmt *) $10);
                                        if (n->into != NULL)
                                                ereport(ERROR,
                                                                (errcode(ERRCODE_SYNTAX_ERROR),
@@ -2189,22 +2190,12 @@ CreateAsStmt:
                                        n->into = $4;
                                        n->intoColNames = $5;
                                        n->intoHasOids = $6;
-                                       $$ = $7;
+                                       n->intoOnCommit = $7;
+                                       n->intoTableSpaceName = $8;
+                                       $$ = $10;
                                }
                ;
 
-/*
- * To avoid a shift/reduce conflict in CreateAsStmt, we need to
- * include the 'AS' terminal in the parsing of WITH/WITHOUT
- * OIDS. Unfortunately that means this production is effectively a
- * duplicate of OptWithOids.
- */
-WithOidsAs:
-                       WITH OIDS AS                                                    { $$ = MUST_HAVE_OIDS; }
-                       | WITHOUT OIDS AS                                               { $$ = MUST_NOT_HAVE_OIDS; }
-                       | AS                                                                    { $$ = DEFAULT_OIDS; }
-                       ;
-
 OptCreateAs:
                        '(' CreateAsList ')'                                    { $$ = $2; }
                        | /*EMPTY*/                                                             { $$ = NIL; }
@@ -5066,13 +5057,18 @@ ExecuteStmt: EXECUTE name execute_param_clause
                                        n->into = NULL;
                                        $$ = (Node *) n;
                                }
-                       | CREATE OptTemp TABLE qualified_name OptCreateAs AS EXECUTE name execute_param_clause
+                       | CREATE OptTemp TABLE qualified_name OptCreateAs
+                               OptWithOids OnCommitOption OptTableSpace AS
+                               EXECUTE name execute_param_clause
                                {
                                        ExecuteStmt *n = makeNode(ExecuteStmt);
-                                       n->name = $8;
-                                       n->params = $9;
+                                       n->name = $11;
+                                       n->params = $12;
                                        $4->istemp = $2;
                                        n->into = $4;
+                                       n->into_contains_oids = $6;
+                                       n->into_on_commit = $7;
+                                       n->into_tbl_space = $8;
                                        if ($5)
                                                ereport(ERROR,
                                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
index 0efe47fc6e5d5a62f5d12a55f3b1e2af8f961e3c..a251e0759d394c1b5cd49698de369a8a4a987b74 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.300 2006/02/04 19:06:46 adunstan Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.301 2006/02/19 00:04:27 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,6 +27,16 @@ typedef enum QuerySource
        QSRC_NON_INSTEAD_RULE           /* added by non-INSTEAD rule */
 } QuerySource;
 
+/* What to do at commit time for temporary relations */
+typedef enum OnCommitAction
+{
+       ONCOMMIT_NOOP,                          /* No ON COMMIT clause (do nothing) */
+       ONCOMMIT_PRESERVE_ROWS,         /* ON COMMIT PRESERVE ROWS (do nothing) */
+       ONCOMMIT_DELETE_ROWS,           /* ON COMMIT DELETE ROWS */
+       ONCOMMIT_DROP                           /* ON COMMIT DROP */
+} OnCommitAction;
+
+
 /*
  * Grantable rights are encoded so that we can OR them together in a bitmask.
  * The present representation of AclItem limits us to 16 distinct rights,
@@ -82,6 +92,8 @@ typedef struct Query
 
        RangeVar   *into;                       /* target relation for SELECT INTO */
        bool            intoHasOids;    /* should target relation contain OIDs? */
+       OnCommitAction  intoOnCommit;           /* what do we do at COMMIT? */
+       char       *intoTableSpaceName; /* table space to use, or NULL */
 
        bool            hasAggs;                /* has aggregates in tlist or havingQual */
        bool            hasSubLinks;    /* has subquery SubLink */
@@ -674,14 +686,16 @@ typedef struct SelectStmt
        /*
         * These fields are used only in "leaf" SelectStmts.
         *
-        * into, intoColNames and intoHasOids are a kluge; they belong somewhere
-        * else...
+        * into, intoColNames, intoHasOids, intoOnCommit, and
+        * intoTableSpaceName are a kluge; they belong somewhere else...
         */
        List       *distinctClause; /* NULL, list of DISTINCT ON exprs, or
                                                                 * lcons(NIL,NIL) for all (SELECT DISTINCT) */
        RangeVar   *into;                       /* target table (for select into table) */
        List       *intoColNames;       /* column names for into table */
        ContainsOids intoHasOids;       /* should target table have OIDs? */
+       OnCommitAction  intoOnCommit;           /* what do we do at COMMIT? */
+       char       *intoTableSpaceName;         /* table space to use, or NULL */
        List       *targetList;         /* the target list (of ResTarget) */
        List       *fromClause;         /* the FROM clause */
        Node       *whereClause;        /* WHERE qualification */
@@ -976,15 +990,6 @@ typedef struct CopyStmt
  * ----------------------
  */
 
-/* What to do at commit time for temporary relations */
-typedef enum OnCommitAction
-{
-       ONCOMMIT_NOOP,                          /* No ON COMMIT clause (do nothing) */
-       ONCOMMIT_PRESERVE_ROWS,         /* ON COMMIT PRESERVE ROWS (do nothing) */
-       ONCOMMIT_DELETE_ROWS,           /* ON COMMIT DELETE ROWS */
-       ONCOMMIT_DROP                           /* ON COMMIT DROP */
-} OnCommitAction;
-
 typedef struct CreateStmt
 {
        NodeTag         type;
@@ -1862,10 +1867,14 @@ typedef struct PrepareStmt
 
 typedef struct ExecuteStmt
 {
-       NodeTag         type;
-       char       *name;                       /* The name of the plan to execute */
-       RangeVar   *into;                       /* Optional table to store results in */
-       List       *params;                     /* Values to assign to parameters */
+       NodeTag                 type;
+       char               *name;                               /* The name of the plan to execute */
+       RangeVar           *into;                               /* Optional table to store results in */
+       ContainsOids    into_contains_oids;     /* Should it have OIDs? */
+       bool                    into_has_oids;          /* Merge GUC info with user input */
+       OnCommitAction  into_on_commit;         /* What do we do at COMMIT? */
+       char               *into_tbl_space;             /* Tablespace to use, or NULL */
+       List               *params;                             /* Values to assign to parameters */
 } ExecuteStmt;
 
 
@@ -1887,7 +1896,7 @@ typedef struct DropOwnedStmt
        NodeTag         type;
        List       *roles;
        DropBehavior behavior;
-}      DropOwnedStmt;
+} DropOwnedStmt;
 
 /*
  *             REASSIGN OWNED statement
@@ -1897,6 +1906,6 @@ typedef struct ReassignOwnedStmt
        NodeTag         type;
        List       *roles;
        char       *newrole;
-}      ReassignOwnedStmt;
+} ReassignOwnedStmt;
 
 #endif   /* PARSENODES_H */
index 897ae751bd9f6560db1c29e026bbf269c798999a..c9a14fc435b555d53070dc2e362a75fa35fa8274 100644 (file)
@@ -63,6 +63,21 @@ SELECT * FROM temptest;
 -----
 (0 rows)
 
+DROP TABLE temptest;
+BEGIN;
+CREATE TEMP TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1;
+SELECT * FROM temptest;
+ col 
+-----
+   1
+(1 row)
+
+COMMIT;
+SELECT * FROM temptest;
+ col 
+-----
+(0 rows)
+
 DROP TABLE temptest;
 -- Test ON COMMIT DROP
 BEGIN;
@@ -76,12 +91,25 @@ SELECT * FROM temptest;
    2
 (2 rows)
 
+COMMIT;
+SELECT * FROM temptest;
+ERROR:  relation "temptest" does not exist
+BEGIN;
+CREATE TEMP TABLE temptest(col) ON COMMIT DROP AS SELECT 1;
+SELECT * FROM temptest;
+ col 
+-----
+   1
+(1 row)
+
 COMMIT;
 SELECT * FROM temptest;
 ERROR:  relation "temptest" does not exist
 -- ON COMMIT is only allowed for TEMP
 CREATE TABLE temptest(col int) ON COMMIT DELETE ROWS;
 ERROR:  ON COMMIT can only be used on temporary tables
+CREATE TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1;
+ERROR:  ON COMMIT can only be used on temporary tables
 -- Test foreign keys
 BEGIN;
 CREATE TEMP TABLE temptest1(col int PRIMARY KEY);
index fbe617f94959f5a4eb39eb3fe7ebaaa5552f1fab..5e46aa8ebee80557b7ee2145beee1610006cbc08 100644 (file)
@@ -76,6 +76,21 @@ SELECT count(oid) FROM create_table_test2;
 -- should fail
 SELECT count(oid) FROM create_table_test3;
 ERROR:  column "oid" does not exist
+PREPARE table_source(int) AS
+    SELECT a + b AS c1, a - b AS c2, $1 AS c3 FROM create_table_test;
+CREATE TABLE execute_with WITH OIDS AS EXECUTE table_source(1);
+CREATE TABLE execute_without WITHOUT OIDS AS EXECUTE table_source(2);
+SELECT count(oid) FROM execute_with;
+ count 
+-------
+     2
+(1 row)
+
+-- should fail
+SELECT count(oid) FROM execute_without;
+ERROR:  column "oid" does not exist
 DROP TABLE create_table_test;
 DROP TABLE create_table_test2;
 DROP TABLE create_table_test3;
+DROP TABLE execute_with;
+DROP TABLE execute_without;
index d094bd70811cabcac08cef4070a17c004b46ec93..9e2c35809478013da49b60ebfba1ae14995c8ea6 100644 (file)
@@ -12,6 +12,17 @@ SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
 INSERT INTO testschema.foo VALUES(1);
 INSERT INTO testschema.foo VALUES(2);
 
+-- tables from dynamic sources
+CREATE TABLE testschema.asselect TABLESPACE testspace AS SELECT 1;
+SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
+    where c.reltablespace = t.oid AND c.relname = 'asselect';
+
+PREPARE selectsource(int) AS SELECT $1;
+CREATE TABLE testschema.asexecute TABLESPACE testspace
+    AS EXECUTE selectsource(2);
+SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
+    where c.reltablespace = t.oid AND c.relname = 'asexecute';
+
 -- index
 CREATE INDEX foo_idx on testschema.foo(i) TABLESPACE testspace;
 SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
index 42c4bc628d50f992e190e64bfab31a09661e935f..d75493fb0b60b8f0397414cb525264ff3c81efff 100644 (file)
@@ -13,6 +13,25 @@ SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
 
 INSERT INTO testschema.foo VALUES(1);
 INSERT INTO testschema.foo VALUES(2);
+-- tables from dynamic sources
+CREATE TABLE testschema.asselect TABLESPACE testspace AS SELECT 1;
+SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
+    where c.reltablespace = t.oid AND c.relname = 'asselect';
+ relname  |  spcname  
+----------+-----------
+ asselect | testspace
+(1 row)
+
+PREPARE selectsource(int) AS SELECT $1;
+CREATE TABLE testschema.asexecute TABLESPACE testspace
+    AS EXECUTE selectsource(2);
+SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
+    where c.reltablespace = t.oid AND c.relname = 'asexecute';
+  relname  |  spcname  
+-----------+-----------
+ asexecute | testspace
+(1 row)
+
 -- index
 CREATE INDEX foo_idx on testschema.foo(i) TABLESPACE testspace;
 SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c
@@ -32,6 +51,8 @@ ERROR:  tablespace "nosuchspace" does not exist
 DROP TABLESPACE testspace;
 ERROR:  tablespace "testspace" is not empty
 DROP SCHEMA testschema CASCADE;
+NOTICE:  drop cascades to table testschema.asexecute
+NOTICE:  drop cascades to table testschema.asselect
 NOTICE:  drop cascades to table testschema.foo
 -- Should succeed
 DROP TABLESPACE testspace;
index 972d511ab7635bf659bdabee4b8884831db1f9dd..6a4b8561449a676bb6790baaf06cde35cc55b35b 100644 (file)
@@ -66,6 +66,16 @@ SELECT * FROM temptest;
 
 DROP TABLE temptest;
 
+BEGIN;
+CREATE TEMP TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1;
+
+SELECT * FROM temptest;
+COMMIT;
+
+SELECT * FROM temptest;
+
+DROP TABLE temptest;
+
 -- Test ON COMMIT DROP
 
 BEGIN;
@@ -80,9 +90,18 @@ COMMIT;
 
 SELECT * FROM temptest;
 
+BEGIN;
+CREATE TEMP TABLE temptest(col) ON COMMIT DROP AS SELECT 1;
+
+SELECT * FROM temptest;
+COMMIT;
+
+SELECT * FROM temptest;
+
 -- ON COMMIT is only allowed for TEMP
 
 CREATE TABLE temptest(col int) ON COMMIT DELETE ROWS;
+CREATE TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1;
 
 -- Test foreign keys
 BEGIN;
index 06c9c69245b927d73b70fad8156346cf6a5c9884..1a10a8533dff3d0f502b43f5f857e46052192de8 100644 (file)
@@ -74,6 +74,18 @@ SELECT count(oid) FROM create_table_test2;
 -- should fail
 SELECT count(oid) FROM create_table_test3;
 
+PREPARE table_source(int) AS
+    SELECT a + b AS c1, a - b AS c2, $1 AS c3 FROM create_table_test;
+
+CREATE TABLE execute_with WITH OIDS AS EXECUTE table_source(1);
+CREATE TABLE execute_without WITHOUT OIDS AS EXECUTE table_source(2);
+
+SELECT count(oid) FROM execute_with;
+-- should fail
+SELECT count(oid) FROM execute_without;
+
 DROP TABLE create_table_test;
 DROP TABLE create_table_test2;
 DROP TABLE create_table_test3;
+DROP TABLE execute_with;
+DROP TABLE execute_without;