Commit f9b5b41e authored by Tom Lane's avatar Tom Lane

Code review for ON COMMIT patch. Make the actual on-commit action happen

before commit, not after :-( --- the original coding is not only unsafe
if an error occurs while it's processing, but it generates an invalid
sequence of WAL entries.  Resurrect 7.2 logic for deleting items when
no longer needed.  Use an enum instead of random macros.  Editorialize
on names used for routines and constants.  Teach backend/nodes routines
about new field in CreateTable struct.  Add a regression test.
parent 1b342df0
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.57 2002/11/09 23:56:38 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.58 2002/11/11 22:19:20 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -21,7 +21,8 @@ CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">t ...@@ -21,7 +21,8 @@ CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">t
| <replaceable>table_constraint</replaceable> } [, ... ] | <replaceable>table_constraint</replaceable> } [, ... ]
) )
[ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ] [ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
[ WITH OIDS | WITHOUT OIDS ] [ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
where <replaceable class="PARAMETER">column_constraint</replaceable> is: where <replaceable class="PARAMETER">column_constraint</replaceable> is:
...@@ -107,8 +108,8 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is: ...@@ -107,8 +108,8 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
<para> <para>
If specified, the table is created as a temporary table. If specified, the table is created as a temporary table.
Temporary tables are automatically dropped at the end of a Temporary tables are automatically dropped at the end of a
session or optionally at the end of the current transaction session, or optionally at the end of the current transaction
(See ON COMMIT below). Existing permanent tables with the same (see ON COMMIT below). Existing permanent tables with the same
name are not visible to the current session while the temporary name are not visible to the current session while the temporary
table exists, unless they are referenced with schema-qualified table exists, unless they are referenced with schema-qualified
names. Any indexes created on a temporary table are automatically names. Any indexes created on a temporary table are automatically
...@@ -493,22 +494,17 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is: ...@@ -493,22 +494,17 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
<term><literal>ON COMMIT</literal></term> <term><literal>ON COMMIT</literal></term>
<listitem> <listitem>
<para> <para>
The behaviour of temporary tables at the end of a transaction The behavior of temporary tables at the end of a transaction
block can be controlled using <literal>ON COMMIT</literal>. block can be controlled using <literal>ON COMMIT</literal>.
The table will exhibit the same behavior at the end of The three options are:
transaction blocks for the duration of the session unless
ON COMMIT DROP is specified or the temporary table is dropped.
</para>
<para>
The three parameters to ON COMMIT are:
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><literal>PRESERVE ROWS</literal></term> <term><literal>PRESERVE ROWS</literal></term>
<listitem> <listitem>
<para> <para>
The rows in the temporary table will persist after the No special action is taken at the ends of transactions.
transaction block. This is the default behavior.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -518,7 +514,8 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is: ...@@ -518,7 +514,8 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
<listitem> <listitem>
<para> <para>
All rows in the temporary table will be deleted at the All rows in the temporary table will be deleted at the
end of the transaction block. end of each transaction block. Essentially, an automatic
<xref linkend="sql-truncate"> is done at each commit.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -527,7 +524,8 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is: ...@@ -527,7 +524,8 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
<term><literal>DROP</literal></term> <term><literal>DROP</literal></term>
<listitem> <listitem>
<para> <para>
The temporary table will be dropped at the end of the transaction. The temporary table will be dropped at the end of the current
transaction block.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.136 2002/11/09 23:56:38 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.137 2002/11/11 22:19:20 tgl Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
...@@ -951,6 +951,12 @@ CommitTransaction(void) ...@@ -951,6 +951,12 @@ CommitTransaction(void)
*/ */
DeferredTriggerEndXact(); DeferredTriggerEndXact();
/*
* Similarly, let ON COMMIT management do its thing before we start
* to commit.
*/
PreCommit_on_commit_actions();
/* Prevent cancel/die interrupt while cleaning up */ /* Prevent cancel/die interrupt while cleaning up */
HOLD_INTERRUPTS(); HOLD_INTERRUPTS();
...@@ -1027,7 +1033,7 @@ CommitTransaction(void) ...@@ -1027,7 +1033,7 @@ CommitTransaction(void)
AtEOXact_hash(); AtEOXact_hash();
AtEOXact_nbtree(); AtEOXact_nbtree();
AtEOXact_rtree(); AtEOXact_rtree();
AtEOXact_temp_relations(true,s->blockState); AtEOXact_on_commit_actions(true);
AtEOXact_Namespace(true); AtEOXact_Namespace(true);
AtEOXact_CatCache(true); AtEOXact_CatCache(true);
AtEOXact_Files(); AtEOXact_Files();
...@@ -1138,7 +1144,7 @@ AbortTransaction(void) ...@@ -1138,7 +1144,7 @@ AbortTransaction(void)
AtEOXact_hash(); AtEOXact_hash();
AtEOXact_nbtree(); AtEOXact_nbtree();
AtEOXact_rtree(); AtEOXact_rtree();
AtEOXact_temp_relations(false,s->blockState); AtEOXact_on_commit_actions(false);
AtEOXact_Namespace(false); AtEOXact_Namespace(false);
AtEOXact_CatCache(false); AtEOXact_CatCache(false);
AtEOXact_Files(); AtEOXact_Files();
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.54 2002/11/09 23:56:38 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.55 2002/11/11 22:19:21 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "catalog/pg_class.h" #include "catalog/pg_class.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "commands/defrem.h" #include "commands/defrem.h"
#include "commands/tablecmds.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "nodes/nodes.h" #include "nodes/nodes.h"
...@@ -198,7 +197,7 @@ Boot_CreateStmt: ...@@ -198,7 +197,7 @@ Boot_CreateStmt:
tupdesc, tupdesc,
RELKIND_RELATION, RELKIND_RELATION,
$3, $3,
ATEOXACTNOOP, ONCOMMIT_NOOP,
true); true);
elog(DEBUG3, "relation created with oid %u", id); elog(DEBUG3, "relation created with oid %u", id);
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.233 2002/11/09 23:56:39 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.234 2002/11/11 22:19:21 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -31,14 +31,12 @@ ...@@ -31,14 +31,12 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "access/genam.h" #include "access/genam.h"
#include "access/xact.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/dependency.h" #include "catalog/dependency.h"
#include "catalog/heap.h" #include "catalog/heap.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_attrdef.h" #include "catalog/pg_attrdef.h"
#include "catalog/pg_constraint.h" #include "catalog/pg_constraint.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
...@@ -673,14 +671,13 @@ AddNewRelationType(const char *typeName, ...@@ -673,14 +671,13 @@ AddNewRelationType(const char *typeName,
* creates a new cataloged relation. see comments above. * creates a new cataloged relation. see comments above.
* -------------------------------- * --------------------------------
*/ */
Oid Oid
heap_create_with_catalog(const char *relname, heap_create_with_catalog(const char *relname,
Oid relnamespace, Oid relnamespace,
TupleDesc tupdesc, TupleDesc tupdesc,
char relkind, char relkind,
bool shared_relation, bool shared_relation,
char ateoxact, /* Only used for temp relations */ OnCommitAction oncommit,
bool allow_system_table_mods) bool allow_system_table_mods)
{ {
Relation pg_class_desc; Relation pg_class_desc;
...@@ -722,25 +719,6 @@ heap_create_with_catalog(const char *relname, ...@@ -722,25 +719,6 @@ heap_create_with_catalog(const char *relname,
/* Assign an OID for the relation's tuple type */ /* Assign an OID for the relation's tuple type */
new_type_oid = newoid(); new_type_oid = newoid();
/*
* Add to temprels if we are a temp relation now that we have oid
*/
if(isTempNamespace(relnamespace)) {
TempTable *t;
MemoryContext oldcxt;
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
t = (TempTable *) palloc(sizeof(TempTable));
t->relid = new_rel_oid;
t->ateoxact = ateoxact;
t->tid = GetCurrentTransactionId();
t->dead = false;
reg_temp_rel(t);
MemoryContextSwitchTo(oldcxt);
}
/* /*
* now create an entry in pg_class for the relation. * now create an entry in pg_class for the relation.
* *
...@@ -804,6 +782,12 @@ heap_create_with_catalog(const char *relname, ...@@ -804,6 +782,12 @@ heap_create_with_catalog(const char *relname,
*/ */
StoreConstraints(new_rel_desc, tupdesc); StoreConstraints(new_rel_desc, tupdesc);
/*
* If there's a special on-commit action, remember it
*/
if (oncommit != ONCOMMIT_NOOP)
register_on_commit_action(new_rel_oid, oncommit);
/* /*
* ok, the relation has been cataloged, so close our relations and * ok, the relation has been cataloged, so close our relations and
* return the oid of the newly created relation. * return the oid of the newly created relation.
...@@ -1164,6 +1148,11 @@ heap_drop_with_catalog(Oid rid) ...@@ -1164,6 +1148,11 @@ heap_drop_with_catalog(Oid rid)
*/ */
DeleteRelationTuple(RelationGetRelid(rel)); DeleteRelationTuple(RelationGetRelid(rel));
/*
* forget any ON COMMIT action for the rel
*/
remove_on_commit_action(rid);
/* /*
* unlink the relation's physical file and finish up. * unlink the relation's physical file and finish up.
*/ */
...@@ -1171,14 +1160,6 @@ heap_drop_with_catalog(Oid rid) ...@@ -1171,14 +1160,6 @@ heap_drop_with_catalog(Oid rid)
rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE) rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
smgrunlink(DEFAULT_SMGR, rel); smgrunlink(DEFAULT_SMGR, rel);
/*
* Keep temprels up to date so that we don't have ON COMMIT execution
* problems at the end of the next transaction block
*/
if(isTempNamespace(RelationGetNamespace(rel)))
rm_temp_rel(rid);
/* /*
* Close relcache entry, but *keep* AccessExclusiveLock on the * Close relcache entry, but *keep* AccessExclusiveLock on the
* relation until transaction commit. This ensures no one else will * relation until transaction commit. This ensures no one else will
...@@ -1941,12 +1922,13 @@ RelationTruncateIndexes(Oid heapId) ...@@ -1941,12 +1922,13 @@ RelationTruncateIndexes(Oid heapId)
* *
* This routine is used to truncate the data from the * This routine is used to truncate the data from the
* storage manager of any data within the relation handed * storage manager of any data within the relation handed
* to this routine. * to this routine. This is not transaction-safe!
*/ */
void void
heap_truncate(Oid rid) heap_truncate(Oid rid)
{ {
Relation rel; Relation rel;
Oid toastrelid;
/* Open relation for processing, and grab exclusive access on it. */ /* Open relation for processing, and grab exclusive access on it. */
rel = heap_open(rid, AccessExclusiveLock); rel = heap_open(rid, AccessExclusiveLock);
...@@ -1965,6 +1947,11 @@ heap_truncate(Oid rid) ...@@ -1965,6 +1947,11 @@ heap_truncate(Oid rid)
/* If this relation has indexes, truncate the indexes too */ /* If this relation has indexes, truncate the indexes too */
RelationTruncateIndexes(rid); RelationTruncateIndexes(rid);
/* If it has a toast table, recursively truncate that too */
toastrelid = rel->rd_rel->reltoastrelid;
if (OidIsValid(toastrelid))
heap_truncate(toastrelid);
/* /*
* Close the relation, but keep exclusive lock on it until commit. * Close the relation, but keep exclusive lock on it until commit.
*/ */
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.39 2002/11/09 23:56:39 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.40 2002/11/11 22:19:21 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_shadow.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/tablecmds.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
...@@ -1671,7 +1670,6 @@ RemoveTempRelationsCallback(void) ...@@ -1671,7 +1670,6 @@ RemoveTempRelationsCallback(void)
CommitTransactionCommand(true); CommitTransactionCommand(true);
} }
free_temp_rels();
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.92 2002/11/09 23:56:39 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.93 2002/11/11 22:19:21 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/namespace.h"
#include "commands/cluster.h" #include "commands/cluster.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "miscadmin.h" #include "miscadmin.h"
...@@ -204,7 +203,7 @@ make_new_heap(Oid OIDOldHeap, const char *NewName) ...@@ -204,7 +203,7 @@ make_new_heap(Oid OIDOldHeap, const char *NewName)
tupdesc, tupdesc,
OldHeap->rd_rel->relkind, OldHeap->rd_rel->relkind,
OldHeap->rd_rel->relisshared, OldHeap->rd_rel->relisshared,
ATEOXACTNOOP, ONCOMMIT_NOOP,
allowSystemTableMods); allowSystemTableMods);
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.89 2002/11/10 00:10:20 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.90 2002/11/11 22:19:21 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -193,6 +193,7 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -193,6 +193,7 @@ DefineSequence(CreateSeqStmt *seq)
stmt->inhRelations = NIL; stmt->inhRelations = NIL;
stmt->constraints = NIL; stmt->constraints = NIL;
stmt->hasoids = false; stmt->hasoids = false;
stmt->oncommit = ONCOMMIT_NOOP;
seqoid = DefineRelation(stmt, RELKIND_SEQUENCE); seqoid = DefineRelation(stmt, RELKIND_SEQUENCE);
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.15 2002/09/21 18:39:25 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.16 2002/11/11 22:19:22 tgl Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -846,6 +846,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist) ...@@ -846,6 +846,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
createStmt->inhRelations = NIL; createStmt->inhRelations = NIL;
createStmt->constraints = NIL; createStmt->constraints = NIL;
createStmt->hasoids = false; createStmt->hasoids = false;
createStmt->oncommit = ONCOMMIT_NOOP;
/* /*
* finally create the relation... * finally create the relation...
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.72 2002/09/22 19:42:50 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.73 2002/11/11 22:19:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -137,6 +137,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) ...@@ -137,6 +137,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
createStmt->inhRelations = NIL; createStmt->inhRelations = NIL;
createStmt->constraints = NIL; createStmt->constraints = NIL;
createStmt->hasoids = false; createStmt->hasoids = false;
createStmt->oncommit = ONCOMMIT_NOOP;
/* /*
* finally create the relation (this will error out if there's an * finally create the relation (this will error out if there's an
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.183 2002/11/11 03:02:18 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.184 2002/11/11 22:19:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -732,7 +732,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) ...@@ -732,7 +732,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
tupdesc, tupdesc,
RELKIND_RELATION, RELKIND_RELATION,
false, false,
ATEOXACTNOOP, ONCOMMIT_NOOP,
allowSystemTableMods); allowSystemTableMods);
FreeTupleDesc(tupdesc); FreeTupleDesc(tupdesc);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.216 2002/11/06 22:31:23 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.217 2002/11/11 22:19:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2037,6 +2037,7 @@ _copyCreateStmt(CreateStmt *from) ...@@ -2037,6 +2037,7 @@ _copyCreateStmt(CreateStmt *from)
Node_Copy(from, newnode, inhRelations); Node_Copy(from, newnode, inhRelations);
Node_Copy(from, newnode, constraints); Node_Copy(from, newnode, constraints);
newnode->hasoids = from->hasoids; newnode->hasoids = from->hasoids;
newnode->oncommit = from->oncommit;
return newnode; return newnode;
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.162 2002/11/06 00:00:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.163 2002/11/11 22:19:22 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -840,6 +840,8 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b) ...@@ -840,6 +840,8 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
return false; return false;
if (a->hasoids != b->hasoids) if (a->hasoids != b->hasoids)
return false; return false;
if (a->oncommit != b->oncommit)
return false;
return true; return true;
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.178 2002/11/06 22:31:24 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.179 2002/11/11 22:19:22 tgl Exp $
* *
* NOTES * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
...@@ -117,8 +117,9 @@ _outCreateStmt(StringInfo str, CreateStmt *node) ...@@ -117,8 +117,9 @@ _outCreateStmt(StringInfo str, CreateStmt *node)
appendStringInfo(str, " :constraints "); appendStringInfo(str, " :constraints ");
_outNode(str, node->constraints); _outNode(str, node->constraints);
appendStringInfo(str, " :hasoids %s ", appendStringInfo(str, " :hasoids %s :oncommit %d ",
booltostr(node->hasoids)); booltostr(node->hasoids),
(int) node->oncommit);
} }
static void static void
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.375 2002/11/10 00:10:20 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.376 2002/11/11 22:19:23 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -54,7 +54,6 @@ ...@@ -54,7 +54,6 @@
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/tablecmds.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "nodes/params.h" #include "nodes/params.h"
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
...@@ -106,6 +105,7 @@ static void doNegateFloat(Value *v); ...@@ -106,6 +105,7 @@ static void doNegateFloat(Value *v);
bool boolean; bool boolean;
JoinType jtype; JoinType jtype;
DropBehavior dbehavior; DropBehavior dbehavior;
OnCommitAction oncommit;
List *list; List *list;
Node *node; Node *node;
Value *value; Value *value;
...@@ -225,7 +225,7 @@ static void doNegateFloat(Value *v); ...@@ -225,7 +225,7 @@ static void doNegateFloat(Value *v);
%type <typnam> func_arg func_return func_type aggr_argtype %type <typnam> func_arg func_return func_type aggr_argtype
%type <boolean> opt_arg TriggerForType OptTemp OptWithOids %type <boolean> opt_arg TriggerForType OptTemp OptWithOids
%type <chr> OptEOXact %type <oncommit> OnCommitOption
%type <list> for_update_clause opt_for_update_clause update_list %type <list> for_update_clause opt_for_update_clause update_list
%type <boolean> opt_all %type <boolean> opt_all
...@@ -1375,24 +1375,20 @@ opt_using: ...@@ -1375,24 +1375,20 @@ opt_using:
*****************************************************************************/ *****************************************************************************/
CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
OptInherit OptWithOids OptEOXact OptInherit OptWithOids OnCommitOption
{ {
CreateStmt *n = makeNode(CreateStmt); CreateStmt *n = makeNode(CreateStmt);
if($2 == FALSE && $10 != ATEOXACTNOOP)
elog(ERROR,"ON COMMIT can only be used on TEMP tables");
$4->istemp = $2; $4->istemp = $2;
n->relation = $4; n->relation = $4;
n->tableElts = $6; n->tableElts = $6;
n->inhRelations = $8; n->inhRelations = $8;
n->constraints = NIL; n->constraints = NIL;
n->hasoids = $9; n->hasoids = $9;
n->ateoxact = $10; n->oncommit = $10;
$$ = (Node *)n; $$ = (Node *)n;
} }
| CREATE OptTemp TABLE qualified_name OF qualified_name | CREATE OptTemp TABLE qualified_name OF qualified_name
'(' OptTableElementList ')' OptWithOids '(' OptTableElementList ')' OptWithOids OnCommitOption
{ {
/* SQL99 CREATE TABLE OF <UDT> (cols) seems to be satisfied /* SQL99 CREATE TABLE OF <UDT> (cols) seems to be satisfied
* by our inheritance capabilities. Let's try it... * by our inheritance capabilities. Let's try it...
...@@ -1404,6 +1400,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' ...@@ -1404,6 +1400,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->inhRelations = makeList1($6); n->inhRelations = makeList1($6);
n->constraints = NIL; n->constraints = NIL;
n->hasoids = $10; n->hasoids = $10;
n->oncommit = $11;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -1807,11 +1804,13 @@ OptWithOids: ...@@ -1807,11 +1804,13 @@ OptWithOids:
| /*EMPTY*/ { $$ = TRUE; } | /*EMPTY*/ { $$ = TRUE; }
; ;
OptEOXact: ON COMMIT DROP { $$ = ATEOXACTDROP; } OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; }
| ON COMMIT DELETE_P ROWS { $$ = ATEOXACTDELETE; } | ON COMMIT DELETE_P ROWS { $$ = ONCOMMIT_DELETE_ROWS; }
| ON COMMIT PRESERVE ROWS { $$ = ATEOXACTPRESERVE; } | ON COMMIT PRESERVE ROWS { $$ = ONCOMMIT_PRESERVE_ROWS; }
| /*EMPTY*/ { $$ = ATEOXACTNOOP; } | /*EMPTY*/ { $$ = ONCOMMIT_NOOP; }
; ;
/* /*
* Note: CREATE TABLE ... AS SELECT ... is just another spelling for * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
* SELECT ... INTO. * SELECT ... INTO.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.128 2002/11/09 23:56:39 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.129 2002/11/11 22:19:23 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -253,7 +253,7 @@ static const ScanKeyword ScanKeywords[] = { ...@@ -253,7 +253,7 @@ static const ScanKeyword ScanKeywords[] = {
{"right", RIGHT}, {"right", RIGHT},
{"rollback", ROLLBACK}, {"rollback", ROLLBACK},
{"row", ROW}, {"row", ROW},
{"rows",ROWS}, {"rows", ROWS},
{"rule", RULE}, {"rule", RULE},
{"schema", SCHEMA}, {"schema", SCHEMA},
{"scroll", SCROLL}, {"scroll", SCROLL},
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: heap.h,v 1.58 2002/11/09 23:56:39 momjian Exp $ * $Id: heap.h,v 1.59 2002/11/11 22:19:23 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -41,7 +41,7 @@ extern Oid heap_create_with_catalog(const char *relname, ...@@ -41,7 +41,7 @@ extern Oid heap_create_with_catalog(const char *relname,
TupleDesc tupdesc, TupleDesc tupdesc,
char relkind, char relkind,
bool shared_relation, bool shared_relation,
char ateoxact, OnCommitAction oncommit,
bool allow_system_table_mods); bool allow_system_table_mods);
extern void heap_drop_with_catalog(Oid rid); extern void heap_drop_with_catalog(Oid rid);
......
...@@ -7,14 +7,13 @@ ...@@ -7,14 +7,13 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: tablecmds.h,v 1.9 2002/11/09 23:56:39 momjian Exp $ * $Id: tablecmds.h,v 1.10 2002/11/11 22:19:24 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef TABLECMDS_H #ifndef TABLECMDS_H
#define TABLECMDS_H #define TABLECMDS_H
#include "access/htup.h"
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
extern void AlterTableAddColumn(Oid myrelid, bool recurse, ColumnDef *colDef); extern void AlterTableAddColumn(Oid myrelid, bool recurse, ColumnDef *colDef);
...@@ -63,29 +62,10 @@ extern void renameatt(Oid myrelid, ...@@ -63,29 +62,10 @@ extern void renameatt(Oid myrelid,
extern void renamerel(Oid myrelid, extern void renamerel(Oid myrelid,
const char *newrelname); const char *newrelname);
/* extern void register_on_commit_action(Oid relid, OnCommitAction action);
* Temp rel stuff extern void remove_on_commit_action(Oid relid);
*/
typedef struct TempTable
{
Oid relid; /* relid of temp relation */
char ateoxact; /* what to do at end of xact */
TransactionId tid; /* trans id where in rel was created */
bool dead; /* table was dropped in the current xact */
} TempTable;
extern void AtEOXact_temp_relations(bool iscommit, int bstate);
extern void reg_temp_rel(TempTable *t);
extern void free_temp_rels(void);
extern void rm_temp_rel(Oid relid);
/*
* What to do at commit time for temporary relations
*/
#define ATEOXACTNOOP 0 /* no operation at commit */ extern void PreCommit_on_commit_actions(void);
#define ATEOXACTPRESERVE 1 /* preserve rows */ extern void AtEOXact_on_commit_actions(bool isCommit);
#define ATEOXACTDELETE 2 /* delete rows */
#define ATEOXACTDROP 3 /* drop temp table */
#endif /* TABLECMDS_H */ #endif /* TABLECMDS_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parsenodes.h,v 1.211 2002/11/09 23:56:39 momjian Exp $ * $Id: parsenodes.h,v 1.212 2002/11/11 22:19:24 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -911,6 +911,16 @@ typedef struct CopyStmt ...@@ -911,6 +911,16 @@ typedef struct CopyStmt
* implementation). * implementation).
* ---------------------- * ----------------------
*/ */
/* 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 typedef struct CreateStmt
{ {
NodeTag type; NodeTag type;
...@@ -919,7 +929,7 @@ typedef struct CreateStmt ...@@ -919,7 +929,7 @@ typedef struct CreateStmt
List *inhRelations; /* relations to inherit from */ List *inhRelations; /* relations to inherit from */
List *constraints; /* constraints (list of Constraint nodes) */ List *constraints; /* constraints (list of Constraint nodes) */
bool hasoids; /* should it have OIDs? */ bool hasoids; /* should it have OIDs? */
char ateoxact; /* what do we do at COMMIT for TEMP ? */ OnCommitAction oncommit; /* what do we do at COMMIT? */
} CreateStmt; } CreateStmt;
/* ---------- /* ----------
......
...@@ -5,21 +5,31 @@ ...@@ -5,21 +5,31 @@
-- test temp table/index masking -- test temp table/index masking
CREATE TABLE temptest(col int); CREATE TABLE temptest(col int);
CREATE INDEX i_temptest ON temptest(col); CREATE INDEX i_temptest ON temptest(col);
CREATE TEMP TABLE temptest(col int); CREATE TEMP TABLE temptest(tcol int);
CREATE INDEX i_temptest ON temptest(col); CREATE INDEX i_temptest ON temptest(tcol);
SELECT * FROM temptest;
tcol
------
(0 rows)
DROP INDEX i_temptest; DROP INDEX i_temptest;
DROP TABLE temptest; DROP TABLE temptest;
SELECT * FROM temptest;
col
-----
(0 rows)
DROP INDEX i_temptest; DROP INDEX i_temptest;
DROP TABLE temptest; DROP TABLE temptest;
-- test temp table selects -- test temp table selects
CREATE TABLE temptest(col int); CREATE TABLE temptest(col int);
INSERT INTO temptest VALUES (1); INSERT INTO temptest VALUES (1);
CREATE TEMP TABLE temptest(col int); CREATE TEMP TABLE temptest(tcol float);
INSERT INTO temptest VALUES (2); INSERT INTO temptest VALUES (2.1);
SELECT * FROM temptest; SELECT * FROM temptest;
col tcol
----- ------
2 2.1
(1 row) (1 row)
DROP TABLE temptest; DROP TABLE temptest;
...@@ -30,9 +40,46 @@ SELECT * FROM temptest; ...@@ -30,9 +40,46 @@ SELECT * FROM temptest;
(1 row) (1 row)
DROP TABLE temptest; DROP TABLE temptest;
CREATE TEMP TABLE temptest(col int);
-- test temp table deletion -- test temp table deletion
CREATE TEMP TABLE temptest(col int);
\c regression \c regression
SET autocommit TO 'on'; SET autocommit TO 'on';
SELECT * FROM temptest; SELECT * FROM temptest;
ERROR: Relation "temptest" does not exist ERROR: Relation "temptest" does not exist
-- Test ON COMMIT DELETE ROWS
CREATE TEMP TABLE temptest(col int) ON COMMIT DELETE ROWS;
BEGIN;
INSERT INTO temptest VALUES (1);
INSERT INTO temptest VALUES (2);
SELECT * FROM temptest;
col
-----
1
2
(2 rows)
COMMIT;
SELECT * FROM temptest;
col
-----
(0 rows)
DROP TABLE temptest;
-- Test ON COMMIT DROP
BEGIN;
CREATE TEMP TABLE temptest(col int) ON COMMIT DROP;
INSERT INTO temptest VALUES (1);
INSERT INTO temptest VALUES (2);
SELECT * FROM temptest;
col
-----
1
2
(2 rows)
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 TEMP tables
...@@ -9,14 +9,18 @@ CREATE TABLE temptest(col int); ...@@ -9,14 +9,18 @@ CREATE TABLE temptest(col int);
CREATE INDEX i_temptest ON temptest(col); CREATE INDEX i_temptest ON temptest(col);
CREATE TEMP TABLE temptest(col int); CREATE TEMP TABLE temptest(tcol int);
CREATE INDEX i_temptest ON temptest(col); CREATE INDEX i_temptest ON temptest(tcol);
SELECT * FROM temptest;
DROP INDEX i_temptest; DROP INDEX i_temptest;
DROP TABLE temptest; DROP TABLE temptest;
SELECT * FROM temptest;
DROP INDEX i_temptest; DROP INDEX i_temptest;
DROP TABLE temptest; DROP TABLE temptest;
...@@ -27,9 +31,9 @@ CREATE TABLE temptest(col int); ...@@ -27,9 +31,9 @@ CREATE TABLE temptest(col int);
INSERT INTO temptest VALUES (1); INSERT INTO temptest VALUES (1);
CREATE TEMP TABLE temptest(col int); CREATE TEMP TABLE temptest(tcol float);
INSERT INTO temptest VALUES (2); INSERT INTO temptest VALUES (2.1);
SELECT * FROM temptest; SELECT * FROM temptest;
...@@ -39,12 +43,44 @@ SELECT * FROM temptest; ...@@ -39,12 +43,44 @@ SELECT * FROM temptest;
DROP TABLE temptest; DROP TABLE temptest;
CREATE TEMP TABLE temptest(col int);
-- test temp table deletion -- test temp table deletion
CREATE TEMP TABLE temptest(col int);
\c regression \c regression
SET autocommit TO 'on'; SET autocommit TO 'on';
SELECT * FROM temptest; SELECT * FROM temptest;
-- Test ON COMMIT DELETE ROWS
CREATE TEMP TABLE temptest(col int) ON COMMIT DELETE ROWS;
BEGIN;
INSERT INTO temptest VALUES (1);
INSERT INTO temptest VALUES (2);
SELECT * FROM temptest;
COMMIT;
SELECT * FROM temptest;
DROP TABLE temptest;
-- Test ON COMMIT DROP
BEGIN;
CREATE TEMP TABLE temptest(col int) ON COMMIT DROP;
INSERT INTO temptest VALUES (1);
INSERT INTO temptest VALUES (2);
SELECT * FROM temptest;
COMMIT;
SELECT * FROM temptest;
-- ON COMMIT is only allowed for TEMP
CREATE TABLE temptest(col int) ON COMMIT DELETE ROWS;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment