Add TABLESPACE and ON COMMIT clauses to CREATE TABLE AS. ON COMMIT is

required by the SQL standard, and TABLESPACE is useful functionality.
Patch from Kris Jurka, minor editorialization by Neil Conway.
This commit is contained in:
Neil Conway 2006-02-19 00:04:28 +00:00
parent 8c5dfbabff
commit 85c0eac1af
17 changed files with 322 additions and 60 deletions

View 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>

View 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>

View 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);
}

View 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);

View 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;

View 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;

View 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);

View 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);

View 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);

View 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),

View 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 */

View 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);

View 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;

View 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

View 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;

View 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;

View 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;