mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-28 00:51:50 +02:00
Add code to handle [ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP }]
for temp tables. Gavin Sherry
This commit is contained in:
parent
f2ef470196
commit
ebb531836a
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.56 2002/09/02 06:20:53 momjian Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.57 2002/11/09 23:56:38 momjian Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ 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 ]
|
[ 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,10 +107,11 @@ 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. Existing permanent tables with the same name are not
|
session or optionally at the end of the current transaction
|
||||||
visible to the current session while the temporary table exists,
|
(See ON COMMIT below). Existing permanent tables with the same
|
||||||
unless they are referenced with schema-qualified names.
|
name are not visible to the current session while the temporary
|
||||||
Any indexes created on a temporary table are automatically
|
table exists, unless they are referenced with schema-qualified
|
||||||
|
names. Any indexes created on a temporary table are automatically
|
||||||
temporary as well.
|
temporary as well.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -487,9 +488,54 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>ON COMMIT</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The behaviour of temporary tables at the end of a transaction
|
||||||
|
block can be controlled using <literal>ON COMMIT</literal>.
|
||||||
|
The table will exhibit the same behavior at the end of
|
||||||
|
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>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>PRESERVE ROWS</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The rows in the temporary table will persist after the
|
||||||
|
transaction block.
|
||||||
|
</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 the transaction block.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>DROP</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The temporary table will be dropped at the end of the transaction.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.135 2002/10/22 22:44:36 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.136 2002/11/09 23:56:38 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Transaction aborts can now occur two ways:
|
* Transaction aborts can now occur two ways:
|
||||||
@ -166,6 +166,7 @@
|
|||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "commands/async.h"
|
#include "commands/async.h"
|
||||||
|
#include "commands/tablecmds.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
#include "commands/user.h"
|
#include "commands/user.h"
|
||||||
#include "executor/spi.h"
|
#include "executor/spi.h"
|
||||||
@ -1026,6 +1027,7 @@ CommitTransaction(void)
|
|||||||
AtEOXact_hash();
|
AtEOXact_hash();
|
||||||
AtEOXact_nbtree();
|
AtEOXact_nbtree();
|
||||||
AtEOXact_rtree();
|
AtEOXact_rtree();
|
||||||
|
AtEOXact_temp_relations(true,s->blockState);
|
||||||
AtEOXact_Namespace(true);
|
AtEOXact_Namespace(true);
|
||||||
AtEOXact_CatCache(true);
|
AtEOXact_CatCache(true);
|
||||||
AtEOXact_Files();
|
AtEOXact_Files();
|
||||||
@ -1136,6 +1138,7 @@ AbortTransaction(void)
|
|||||||
AtEOXact_hash();
|
AtEOXact_hash();
|
||||||
AtEOXact_nbtree();
|
AtEOXact_nbtree();
|
||||||
AtEOXact_rtree();
|
AtEOXact_rtree();
|
||||||
|
AtEOXact_temp_relations(false,s->blockState);
|
||||||
AtEOXact_Namespace(false);
|
AtEOXact_Namespace(false);
|
||||||
AtEOXact_CatCache(false);
|
AtEOXact_CatCache(false);
|
||||||
AtEOXact_Files();
|
AtEOXact_Files();
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.53 2002/11/01 22:52:33 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.54 2002/11/09 23:56:38 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -34,6 +34,7 @@
|
|||||||
#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"
|
||||||
@ -197,6 +198,7 @@ Boot_CreateStmt:
|
|||||||
tupdesc,
|
tupdesc,
|
||||||
RELKIND_RELATION,
|
RELKIND_RELATION,
|
||||||
$3,
|
$3,
|
||||||
|
ATEOXACTNOOP,
|
||||||
true);
|
true);
|
||||||
elog(DEBUG3, "relation created with oid %u", id);
|
elog(DEBUG3, "relation created with oid %u", id);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.232 2002/10/21 22:06:18 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.233 2002/11/09 23:56:39 momjian Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -31,17 +31,20 @@
|
|||||||
|
|
||||||
#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"
|
||||||
#include "catalog/pg_statistic.h"
|
#include "catalog/pg_statistic.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
|
#include "commands/tablecmds.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
@ -670,12 +673,14 @@ 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 */
|
||||||
bool allow_system_table_mods)
|
bool allow_system_table_mods)
|
||||||
{
|
{
|
||||||
Relation pg_class_desc;
|
Relation pg_class_desc;
|
||||||
@ -717,6 +722,25 @@ 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.
|
||||||
*
|
*
|
||||||
@ -1147,6 +1171,14 @@ 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
|
||||||
|
@ -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.38 2002/11/02 18:41:21 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.39 2002/11/09 23:56:39 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -34,6 +34,7 @@
|
|||||||
#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"
|
||||||
@ -1670,6 +1671,7 @@ RemoveTempRelationsCallback(void)
|
|||||||
|
|
||||||
CommitTransactionCommand(true);
|
CommitTransactionCommand(true);
|
||||||
}
|
}
|
||||||
|
free_temp_rels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.91 2002/11/02 21:20:40 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.92 2002/11/09 23:56:39 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#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"
|
||||||
@ -203,6 +204,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,
|
||||||
allowSystemTableMods);
|
allowSystemTableMods);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8,12 +8,13 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.51 2002/11/02 22:02:08 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.52 2002/11/09 23:56:39 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/xact.h"
|
||||||
#include "access/genam.h"
|
#include "access/genam.h"
|
||||||
#include "access/tuptoaster.h"
|
#include "access/tuptoaster.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
@ -48,9 +49,10 @@
|
|||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
|
||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
static List *temprels = NIL;
|
||||||
|
|
||||||
static List *MergeAttributes(List *schema, List *supers, bool istemp,
|
static List *MergeAttributes(List *schema, List *supers, bool istemp,
|
||||||
List **supOids, List **supconstr, bool *supHasOids);
|
List **supOids, List **supconstr, bool *supHasOids);
|
||||||
@ -116,6 +118,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
|||||||
int i;
|
int i;
|
||||||
AttrNumber attnum;
|
AttrNumber attnum;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Truncate relname to appropriate length (probably a waste of time,
|
* Truncate relname to appropriate length (probably a waste of time,
|
||||||
* as parser should have done this already).
|
* as parser should have done this already).
|
||||||
@ -222,6 +225,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
|||||||
descriptor,
|
descriptor,
|
||||||
relkind,
|
relkind,
|
||||||
false,
|
false,
|
||||||
|
stmt->ateoxact,
|
||||||
allowSystemTableMods);
|
allowSystemTableMods);
|
||||||
|
|
||||||
StoreCatalogInheritance(relationId, inheritOids);
|
StoreCatalogInheritance(relationId, inheritOids);
|
||||||
@ -3783,11 +3787,18 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
|||||||
* when its master is, so there's no need to handle the toast rel as
|
* when its master is, so there's no need to handle the toast rel as
|
||||||
* temp.
|
* temp.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pass ATEOXACTNOOP for ateoxact since we want heap_drop_with_catalog()
|
||||||
|
* to remove TOAST tables for temp tables, not AtEOXact_temp_relations()
|
||||||
|
*/
|
||||||
|
|
||||||
toast_relid = heap_create_with_catalog(toast_relname,
|
toast_relid = heap_create_with_catalog(toast_relname,
|
||||||
PG_TOAST_NAMESPACE,
|
PG_TOAST_NAMESPACE,
|
||||||
tupdesc,
|
tupdesc,
|
||||||
RELKIND_TOASTVALUE,
|
RELKIND_TOASTVALUE,
|
||||||
shared_relation,
|
shared_relation,
|
||||||
|
ATEOXACTNOOP,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
/* make the toast relation visible, else index creation will fail */
|
/* make the toast relation visible, else index creation will fail */
|
||||||
@ -3922,3 +3933,206 @@ needs_toast_table(Relation rel)
|
|||||||
MAXALIGN(data_length);
|
MAXALIGN(data_length);
|
||||||
return (tuple_length > TOAST_TUPLE_THRESHOLD);
|
return (tuple_length > TOAST_TUPLE_THRESHOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To handle ON COMMIT { DROP | PRESERVE ROWS | DELETE ROWS }
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
AtEOXact_temp_relations(bool iscommit, int bstate)
|
||||||
|
{
|
||||||
|
List *l,
|
||||||
|
*prev;
|
||||||
|
MemoryContext oldctx;
|
||||||
|
|
||||||
|
if (temprels == NIL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These loops are tricky because we are removing items from the List
|
||||||
|
* while we are traversing it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Remove 'dead' entries on commit and clear 'dead' status on abort */
|
||||||
|
l = temprels;
|
||||||
|
prev = NIL;
|
||||||
|
while (l != NIL)
|
||||||
|
{
|
||||||
|
TempTable *t = lfirst(l);
|
||||||
|
|
||||||
|
if (t->dead)
|
||||||
|
{
|
||||||
|
if (iscommit)
|
||||||
|
{
|
||||||
|
/* Remove from temprels, since the user has DROP'd */
|
||||||
|
oldctx = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
if (prev == NIL)
|
||||||
|
{
|
||||||
|
pfree(t);
|
||||||
|
temprels = lnext(l);
|
||||||
|
pfree(l);
|
||||||
|
l = temprels;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pfree(t);
|
||||||
|
lnext(prev) = lnext(l);
|
||||||
|
pfree(l);
|
||||||
|
l = lnext(prev);
|
||||||
|
}
|
||||||
|
MemoryContextSwitchTo(oldctx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* user dropped but now we're aborted */
|
||||||
|
t->dead = false;
|
||||||
|
}
|
||||||
|
prev = l;
|
||||||
|
l = lnext(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((iscommit && bstate != TBLOCK_END) ||
|
||||||
|
(!iscommit && bstate != TBLOCK_ABORT))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Perform per-xact actions */
|
||||||
|
l = temprels;
|
||||||
|
prev = NIL;
|
||||||
|
|
||||||
|
if (iscommit)
|
||||||
|
{
|
||||||
|
while (l != NIL)
|
||||||
|
{
|
||||||
|
TempTable *t = lfirst(l);
|
||||||
|
|
||||||
|
if (t->ateoxact == ATEOXACTDROP)
|
||||||
|
{
|
||||||
|
ObjectAddress object;
|
||||||
|
|
||||||
|
object.classId = RelOid_pg_class;
|
||||||
|
object.objectId = t->relid;
|
||||||
|
object.objectSubId = 0;
|
||||||
|
|
||||||
|
performDeletion(&object, DROP_CASCADE);
|
||||||
|
oldctx = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
|
||||||
|
if (prev == NIL)
|
||||||
|
{
|
||||||
|
pfree(t);
|
||||||
|
temprels = lnext(l);
|
||||||
|
pfree(l);
|
||||||
|
l = temprels;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pfree(t);
|
||||||
|
lnext(prev) = lnext(l);
|
||||||
|
pfree(l);
|
||||||
|
l = lnext(prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryContextSwitchTo(oldctx);
|
||||||
|
CommandCounterIncrement();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (t->ateoxact == ATEOXACTDELETE)
|
||||||
|
{
|
||||||
|
heap_truncate(t->relid);
|
||||||
|
CommandCounterIncrement();
|
||||||
|
}
|
||||||
|
prev = l;
|
||||||
|
l = lnext(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Abort --- remove entries added by this xact */
|
||||||
|
TransactionId curtid = GetCurrentTransactionId();
|
||||||
|
|
||||||
|
oldctx = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
|
||||||
|
while (l != NIL)
|
||||||
|
{
|
||||||
|
TempTable *t = lfirst(l);
|
||||||
|
|
||||||
|
if (t->tid == curtid)
|
||||||
|
{
|
||||||
|
if (prev == NIL)
|
||||||
|
{
|
||||||
|
pfree(t);
|
||||||
|
temprels = lnext(l);
|
||||||
|
pfree(l);
|
||||||
|
l = temprels;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pfree(t);
|
||||||
|
lnext(prev) = lnext(l);
|
||||||
|
pfree(l);
|
||||||
|
l = lnext(prev);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
prev = l;
|
||||||
|
l = lnext(l);
|
||||||
|
}
|
||||||
|
MemoryContextSwitchTo(oldctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register a temp rel in temprels
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
reg_temp_rel(TempTable * t)
|
||||||
|
{
|
||||||
|
temprels = lcons(t, temprels);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return the ON COMMIT/ateoxact value for a given temp rel
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
free_temp_rels(void)
|
||||||
|
{
|
||||||
|
MemoryContext oldctx;
|
||||||
|
|
||||||
|
oldctx = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
while (temprels != NIL)
|
||||||
|
{
|
||||||
|
List *l = temprels;
|
||||||
|
|
||||||
|
temprels = lnext(temprels);
|
||||||
|
pfree(lfirst(l));
|
||||||
|
pfree(l);
|
||||||
|
}
|
||||||
|
MemoryContextSwitchTo(oldctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove (actually just mark for deletion, in case we abort)
|
||||||
|
* Relid from the temprels list
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
rm_temp_rel(Oid relid)
|
||||||
|
{
|
||||||
|
List *l;
|
||||||
|
|
||||||
|
foreach(l, temprels)
|
||||||
|
{
|
||||||
|
TempTable *t = lfirst(l);
|
||||||
|
|
||||||
|
if (t->relid == relid)
|
||||||
|
{
|
||||||
|
t->dead = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we get here, we're in trouble */
|
||||||
|
Assert(1==1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.180 2002/10/14 16:51:30 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.181 2002/11/09 23:56:39 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -732,6 +732,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
|
|||||||
tupdesc,
|
tupdesc,
|
||||||
RELKIND_RELATION,
|
RELKIND_RELATION,
|
||||||
false,
|
false,
|
||||||
|
ATEOXACTNOOP,
|
||||||
allowSystemTableMods);
|
allowSystemTableMods);
|
||||||
|
|
||||||
FreeTupleDesc(tupdesc);
|
FreeTupleDesc(tupdesc);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.373 2002/11/02 18:41:21 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.374 2002/11/09 23:56:39 momjian Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -54,6 +54,7 @@
|
|||||||
#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"
|
||||||
@ -224,6 +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 <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
|
||||||
@ -370,10 +372,11 @@ static void doNegateFloat(Value *v);
|
|||||||
ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNER
|
ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNER
|
||||||
|
|
||||||
PARTIAL PASSWORD PATH_P PENDANT PLACING POSITION
|
PARTIAL PASSWORD PATH_P PENDANT PLACING POSITION
|
||||||
PRECISION PREPARE PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE
|
PRECISION PRESERVE PREPARE PRIMARY PRIOR PRIVILEGES PROCEDURAL
|
||||||
|
PROCEDURE
|
||||||
|
|
||||||
READ REAL RECHECK REFERENCES REINDEX RELATIVE RENAME REPLACE
|
READ REAL RECHECK REFERENCES REINDEX RELATIVE RENAME REPLACE
|
||||||
RESET RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW
|
RESET RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS
|
||||||
RULE
|
RULE
|
||||||
|
|
||||||
SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
|
SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
|
||||||
@ -1372,15 +1375,20 @@ opt_using:
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
|
CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
|
||||||
OptInherit OptWithOids
|
OptInherit OptWithOids OptEOXact
|
||||||
{
|
{
|
||||||
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;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| CREATE OptTemp TABLE qualified_name OF qualified_name
|
| CREATE OptTemp TABLE qualified_name OF qualified_name
|
||||||
@ -1799,7 +1807,11 @@ OptWithOids:
|
|||||||
| /*EMPTY*/ { $$ = TRUE; }
|
| /*EMPTY*/ { $$ = TRUE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
OptEOXact: ON COMMIT DROP { $$ = ATEOXACTDROP; }
|
||||||
|
| ON COMMIT DELETE_P ROWS { $$ = ATEOXACTDELETE; }
|
||||||
|
| ON COMMIT PRESERVE ROWS { $$ = ATEOXACTPRESERVE; }
|
||||||
|
| /*EMPTY*/ { $$ = ATEOXACTNOOP; }
|
||||||
|
;
|
||||||
/*
|
/*
|
||||||
* Note: CREATE TABLE ... AS SELECT ... is just another spelling for
|
* Note: CREATE TABLE ... AS SELECT ... is just another spelling for
|
||||||
* SELECT ... INTO.
|
* SELECT ... INTO.
|
||||||
@ -7074,6 +7086,7 @@ unreserved_keyword:
|
|||||||
| PENDANT
|
| PENDANT
|
||||||
| PRECISION
|
| PRECISION
|
||||||
| PREPARE
|
| PREPARE
|
||||||
|
| PRESERVE
|
||||||
| PRIOR
|
| PRIOR
|
||||||
| PRIVILEGES
|
| PRIVILEGES
|
||||||
| PROCEDURAL
|
| PROCEDURAL
|
||||||
@ -7089,6 +7102,7 @@ unreserved_keyword:
|
|||||||
| RETURNS
|
| RETURNS
|
||||||
| REVOKE
|
| REVOKE
|
||||||
| ROLLBACK
|
| ROLLBACK
|
||||||
|
| ROWS
|
||||||
| RULE
|
| RULE
|
||||||
| SCHEMA
|
| SCHEMA
|
||||||
| SCROLL
|
| SCROLL
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.127 2002/09/18 21:35:22 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.128 2002/11/09 23:56:39 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -232,6 +232,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"position", POSITION},
|
{"position", POSITION},
|
||||||
{"precision", PRECISION},
|
{"precision", PRECISION},
|
||||||
{"prepare", PREPARE},
|
{"prepare", PREPARE},
|
||||||
|
{"preserve", PRESERVE},
|
||||||
{"primary", PRIMARY},
|
{"primary", PRIMARY},
|
||||||
{"prior", PRIOR},
|
{"prior", PRIOR},
|
||||||
{"privileges", PRIVILEGES},
|
{"privileges", PRIVILEGES},
|
||||||
@ -252,6 +253,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||||||
{"right", RIGHT},
|
{"right", RIGHT},
|
||||||
{"rollback", ROLLBACK},
|
{"rollback", ROLLBACK},
|
||||||
{"row", ROW},
|
{"row", ROW},
|
||||||
|
{"rows",ROWS},
|
||||||
{"rule", RULE},
|
{"rule", RULE},
|
||||||
{"schema", SCHEMA},
|
{"schema", SCHEMA},
|
||||||
{"scroll", SCROLL},
|
{"scroll", SCROLL},
|
||||||
|
@ -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.57 2002/09/04 20:31:37 momjian Exp $
|
* $Id: heap.h,v 1.58 2002/11/09 23:56:39 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -41,6 +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,
|
||||||
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,13 +7,14 @@
|
|||||||
* 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.8 2002/10/21 20:31:52 momjian Exp $
|
* $Id: tablecmds.h,v 1.9 2002/11/09 23:56:39 momjian 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);
|
||||||
@ -62,4 +63,29 @@ extern void renameatt(Oid myrelid,
|
|||||||
extern void renamerel(Oid myrelid,
|
extern void renamerel(Oid myrelid,
|
||||||
const char *newrelname);
|
const char *newrelname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Temp rel stuff
|
||||||
|
*/
|
||||||
|
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 */
|
||||||
|
#define ATEOXACTPRESERVE 1 /* preserve rows */
|
||||||
|
#define ATEOXACTDELETE 2 /* delete rows */
|
||||||
|
#define ATEOXACTDROP 3 /* drop temp table */
|
||||||
|
|
||||||
#endif /* TABLECMDS_H */
|
#endif /* TABLECMDS_H */
|
||||||
|
@ -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.210 2002/11/06 00:00:44 tgl Exp $
|
* $Id: parsenodes.h,v 1.211 2002/11/09 23:56:39 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -919,6 +919,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 ? */
|
||||||
} CreateStmt;
|
} CreateStmt;
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
|
Loading…
Reference in New Issue
Block a user