mirror of https://github.com/postgres/postgres
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
|
||||
-->
|
||||
|
||||
|
@ -21,7 +21,7 @@ CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">t
|
|||
| <replaceable>table_constraint</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:
|
||||
|
||||
|
@ -107,10 +107,11 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
|
|||
<para>
|
||||
If specified, the table is created as a temporary table.
|
||||
Temporary tables are automatically dropped at the end of a
|
||||
session. Existing permanent tables with the same name are not
|
||||
visible to the current session while the temporary table exists,
|
||||
unless they are referenced with schema-qualified names.
|
||||
Any indexes created on a temporary table are automatically
|
||||
session or optionally at the end of the current transaction
|
||||
(See ON COMMIT below). Existing permanent tables with the same
|
||||
name are not visible to the current session while the temporary
|
||||
table exists, unless they are referenced with schema-qualified
|
||||
names. Any indexes created on a temporary table are automatically
|
||||
temporary as well.
|
||||
</para>
|
||||
|
||||
|
@ -487,9 +488,54 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
|
|||
</para>
|
||||
</listitem>
|
||||
</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>
|
||||
|
||||
|
||||
</refsect1>
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* 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
|
||||
* Transaction aborts can now occur two ways:
|
||||
|
@ -166,6 +166,7 @@
|
|||
#include "catalog/index.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "commands/async.h"
|
||||
#include "commands/tablecmds.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "commands/user.h"
|
||||
#include "executor/spi.h"
|
||||
|
@ -1026,6 +1027,7 @@ CommitTransaction(void)
|
|||
AtEOXact_hash();
|
||||
AtEOXact_nbtree();
|
||||
AtEOXact_rtree();
|
||||
AtEOXact_temp_relations(true,s->blockState);
|
||||
AtEOXact_Namespace(true);
|
||||
AtEOXact_CatCache(true);
|
||||
AtEOXact_Files();
|
||||
|
@ -1136,6 +1138,7 @@ AbortTransaction(void)
|
|||
AtEOXact_hash();
|
||||
AtEOXact_nbtree();
|
||||
AtEOXact_rtree();
|
||||
AtEOXact_temp_relations(false,s->blockState);
|
||||
AtEOXact_Namespace(false);
|
||||
AtEOXact_CatCache(false);
|
||||
AtEOXact_Files();
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
*
|
||||
* 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_namespace.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "commands/tablecmds.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "nodes/nodes.h"
|
||||
|
@ -197,6 +198,7 @@ Boot_CreateStmt:
|
|||
tupdesc,
|
||||
RELKIND_RELATION,
|
||||
$3,
|
||||
ATEOXACTNOOP,
|
||||
true);
|
||||
elog(DEBUG3, "relation created with oid %u", id);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* 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
|
||||
|
@ -31,17 +31,20 @@
|
|||
|
||||
#include "access/heapam.h"
|
||||
#include "access/genam.h"
|
||||
#include "access/xact.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/catname.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/heap.h"
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_attrdef.h"
|
||||
#include "catalog/pg_constraint.h"
|
||||
#include "catalog/pg_inherits.h"
|
||||
#include "catalog/pg_statistic.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/tablecmds.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
|
@ -670,12 +673,14 @@ AddNewRelationType(const char *typeName,
|
|||
* creates a new cataloged relation. see comments above.
|
||||
* --------------------------------
|
||||
*/
|
||||
|
||||
Oid
|
||||
heap_create_with_catalog(const char *relname,
|
||||
Oid relnamespace,
|
||||
TupleDesc tupdesc,
|
||||
char relkind,
|
||||
bool shared_relation,
|
||||
char ateoxact, /* Only used for temp relations */
|
||||
bool allow_system_table_mods)
|
||||
{
|
||||
Relation pg_class_desc;
|
||||
|
@ -717,6 +722,25 @@ heap_create_with_catalog(const char *relname,
|
|||
/* Assign an OID for the relation's tuple type */
|
||||
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.
|
||||
*
|
||||
|
@ -1147,6 +1171,14 @@ heap_drop_with_catalog(Oid rid)
|
|||
rel->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
|
||||
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
|
||||
* relation until transaction commit. This ensures no one else will
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* 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_shadow.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/tablecmds.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
|
@ -1670,6 +1671,7 @@ RemoveTempRelationsCallback(void)
|
|||
|
||||
CommitTransactionCommand(true);
|
||||
}
|
||||
free_temp_rels();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
*
|
||||
* 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/indexing.h"
|
||||
#include "catalog/catname.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "commands/cluster.h"
|
||||
#include "commands/tablecmds.h"
|
||||
#include "miscadmin.h"
|
||||
|
@ -203,6 +204,7 @@ make_new_heap(Oid OIDOldHeap, const char *NewName)
|
|||
tupdesc,
|
||||
OldHeap->rd_rel->relkind,
|
||||
OldHeap->rd_rel->relisshared,
|
||||
ATEOXACTNOOP,
|
||||
allowSystemTableMods);
|
||||
|
||||
/*
|
||||
|
|
|
@ -8,12 +8,13 @@
|
|||
*
|
||||
*
|
||||
* 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 "access/xact.h"
|
||||
#include "access/genam.h"
|
||||
#include "access/tuptoaster.h"
|
||||
#include "catalog/catalog.h"
|
||||
|
@ -48,9 +49,10 @@
|
|||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "utils/relcache.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
static List *temprels = NIL;
|
||||
|
||||
static List *MergeAttributes(List *schema, List *supers, bool istemp,
|
||||
List **supOids, List **supconstr, bool *supHasOids);
|
||||
|
@ -116,6 +118,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
|||
int i;
|
||||
AttrNumber attnum;
|
||||
|
||||
|
||||
/*
|
||||
* Truncate relname to appropriate length (probably a waste of time,
|
||||
* as parser should have done this already).
|
||||
|
@ -222,6 +225,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
|||
descriptor,
|
||||
relkind,
|
||||
false,
|
||||
stmt->ateoxact,
|
||||
allowSystemTableMods);
|
||||
|
||||
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
|
||||
* 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,
|
||||
PG_TOAST_NAMESPACE,
|
||||
tupdesc,
|
||||
RELKIND_TOASTVALUE,
|
||||
shared_relation,
|
||||
ATEOXACTNOOP,
|
||||
true);
|
||||
|
||||
/* make the toast relation visible, else index creation will fail */
|
||||
|
@ -3922,3 +3933,206 @@ needs_toast_table(Relation rel)
|
|||
MAXALIGN(data_length);
|
||||
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
|
||||
* $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,
|
||||
RELKIND_RELATION,
|
||||
false,
|
||||
ATEOXACTNOOP,
|
||||
allowSystemTableMods);
|
||||
|
||||
FreeTupleDesc(tupdesc);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*
|
||||
*
|
||||
* 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
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
|
@ -54,6 +54,7 @@
|
|||
#include "catalog/index.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/tablecmds.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "nodes/params.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 <boolean> opt_arg TriggerForType OptTemp OptWithOids
|
||||
%type <chr> OptEOXact
|
||||
|
||||
%type <list> for_update_clause opt_for_update_clause update_list
|
||||
%type <boolean> opt_all
|
||||
|
@ -370,10 +372,11 @@ static void doNegateFloat(Value *v);
|
|||
ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNER
|
||||
|
||||
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
|
||||
RESET RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW
|
||||
RESET RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS
|
||||
RULE
|
||||
|
||||
SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
|
||||
|
@ -1372,15 +1375,20 @@ opt_using:
|
|||
*****************************************************************************/
|
||||
|
||||
CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
|
||||
OptInherit OptWithOids
|
||||
OptInherit OptWithOids OptEOXact
|
||||
{
|
||||
CreateStmt *n = makeNode(CreateStmt);
|
||||
|
||||
if($2 == FALSE && $10 != ATEOXACTNOOP)
|
||||
elog(ERROR,"ON COMMIT can only be used on TEMP tables");
|
||||
|
||||
$4->istemp = $2;
|
||||
n->relation = $4;
|
||||
n->tableElts = $6;
|
||||
n->inhRelations = $8;
|
||||
n->constraints = NIL;
|
||||
n->hasoids = $9;
|
||||
n->ateoxact = $10;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| CREATE OptTemp TABLE qualified_name OF qualified_name
|
||||
|
@ -1799,7 +1807,11 @@ OptWithOids:
|
|||
| /*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
|
||||
* SELECT ... INTO.
|
||||
|
@ -7074,6 +7086,7 @@ unreserved_keyword:
|
|||
| PENDANT
|
||||
| PRECISION
|
||||
| PREPARE
|
||||
| PRESERVE
|
||||
| PRIOR
|
||||
| PRIVILEGES
|
||||
| PROCEDURAL
|
||||
|
@ -7089,6 +7102,7 @@ unreserved_keyword:
|
|||
| RETURNS
|
||||
| REVOKE
|
||||
| ROLLBACK
|
||||
| ROWS
|
||||
| RULE
|
||||
| SCHEMA
|
||||
| SCROLL
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* 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},
|
||||
{"precision", PRECISION},
|
||||
{"prepare", PREPARE},
|
||||
{"preserve", PRESERVE},
|
||||
{"primary", PRIMARY},
|
||||
{"prior", PRIOR},
|
||||
{"privileges", PRIVILEGES},
|
||||
|
@ -252,6 +253,7 @@ static const ScanKeyword ScanKeywords[] = {
|
|||
{"right", RIGHT},
|
||||
{"rollback", ROLLBACK},
|
||||
{"row", ROW},
|
||||
{"rows",ROWS},
|
||||
{"rule", RULE},
|
||||
{"schema", SCHEMA},
|
||||
{"scroll", SCROLL},
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* 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,
|
||||
char relkind,
|
||||
bool shared_relation,
|
||||
char ateoxact,
|
||||
bool allow_system_table_mods);
|
||||
|
||||
extern void heap_drop_with_catalog(Oid rid);
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* 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
|
||||
#define TABLECMDS_H
|
||||
|
||||
#include "access/htup.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
|
||||
extern void AlterTableAddColumn(Oid myrelid, bool recurse, ColumnDef *colDef);
|
||||
|
@ -62,4 +63,29 @@ extern void renameatt(Oid myrelid,
|
|||
extern void renamerel(Oid myrelid,
|
||||
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 */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* 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 *constraints; /* constraints (list of Constraint nodes) */
|
||||
bool hasoids; /* should it have OIDs? */
|
||||
char ateoxact; /* what do we do at COMMIT for TEMP ? */
|
||||
} CreateStmt;
|
||||
|
||||
/* ----------
|
||||
|
|
Loading…
Reference in New Issue