aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/create_table.sgml9
-rw-r--r--doc/src/sgml/ref/create_table_as.sgml95
-rw-r--r--src/backend/commands/prepare.c6
-rw-r--r--src/backend/executor/execMain.c47
-rw-r--r--src/backend/nodes/copyfuncs.c10
-rw-r--r--src/backend/nodes/equalfuncs.c10
-rw-r--r--src/backend/nodes/outfuncs.c7
-rw-r--r--src/backend/nodes/readfuncs.c5
-rw-r--r--src/backend/parser/analyze.c6
-rw-r--r--src/backend/parser/gram.y36
-rw-r--r--src/include/nodes/parsenodes.h45
-rw-r--r--src/test/regress/expected/temp.out28
-rw-r--r--src/test/regress/expected/without_oid.out15
-rw-r--r--src/test/regress/input/tablespace.source11
-rw-r--r--src/test/regress/output/tablespace.source21
-rw-r--r--src/test/regress/sql/temp.sql19
-rw-r--r--src/test/regress/sql/without_oid.sql12
17 files changed, 322 insertions, 60 deletions
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 5dfeca1953c..a4cdc250187 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -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>
diff --git a/doc/src/sgml/ref/create_table_as.sgml b/doc/src/sgml/ref/create_table_as.sgml
index 201188d99cc..7e7fa7b6731 100644
--- a/doc/src/sgml/ref/create_table_as.sgml
+++ b/doc/src/sgml/ref/create_table_as.sgml
@@ -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>
@@ -114,6 +117,65 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
</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>
<para>
@@ -170,6 +232,20 @@ 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>
<refsect1>
@@ -190,13 +266,6 @@ CREATE TABLE films_recent AS
<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;
this is not currently implemented by <productname>PostgreSQL</>.
The behavior provided by <productname>PostgreSQL</> is equivalent
@@ -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>
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index f0afdbba367..4fd43d7f496 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -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);
}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index a0f9cfedd3f..99c3bca0a9a 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -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,11 +731,20 @@ 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
*/
intoName = parseTree->into->relname;
@@ -747,13 +757,44 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
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
*/
tupdesc = CreateTupleDescCopy(tupType);
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);
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 6578bf37afd..91f06df039a 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -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;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index a9fdc95f6bb..9a2a5fd0d59 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -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;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index d6d63ee096f..9884b0e4db4 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -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);
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index eb2886d8437..19cb6e9544f 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -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);
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index abfb0fbf303..057ff415185 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -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);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 88d32d837d4..6cb6f96fa4f 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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),
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 0efe47fc6e5..a251e0759d3 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -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 */
diff --git a/src/test/regress/expected/temp.out b/src/test/regress/expected/temp.out
index 897ae751bd9..c9a14fc435b 100644
--- a/src/test/regress/expected/temp.out
+++ b/src/test/regress/expected/temp.out
@@ -64,6 +64,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;
CREATE TEMP TABLE temptest(col int) ON COMMIT DROP;
@@ -79,9 +94,22 @@ SELECT * FROM temptest;
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);
diff --git a/src/test/regress/expected/without_oid.out b/src/test/regress/expected/without_oid.out
index fbe617f9495..5e46aa8ebee 100644
--- a/src/test/regress/expected/without_oid.out
+++ b/src/test/regress/expected/without_oid.out
@@ -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;
diff --git a/src/test/regress/input/tablespace.source b/src/test/regress/input/tablespace.source
index d094bd70811..9e2c3580947 100644
--- a/src/test/regress/input/tablespace.source
+++ b/src/test/regress/input/tablespace.source
@@ -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
diff --git a/src/test/regress/output/tablespace.source b/src/test/regress/output/tablespace.source
index 42c4bc628d5..d75493fb0b6 100644
--- a/src/test/regress/output/tablespace.source
+++ b/src/test/regress/output/tablespace.source
@@ -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;
diff --git a/src/test/regress/sql/temp.sql b/src/test/regress/sql/temp.sql
index 972d511ab76..6a4b8561449 100644
--- a/src/test/regress/sql/temp.sql
+++ b/src/test/regress/sql/temp.sql
@@ -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;
diff --git a/src/test/regress/sql/without_oid.sql b/src/test/regress/sql/without_oid.sql
index 06c9c69245b..1a10a8533df 100644
--- a/src/test/regress/sql/without_oid.sql
+++ b/src/test/regress/sql/without_oid.sql
@@ -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;