aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2002-11-09 23:56:39 +0000
committerBruce Momjian <bruce@momjian.us>2002-11-09 23:56:39 +0000
commitebb531836ada81958bbf95c60dd05dc58eb3e810 (patch)
treef15c094f02bf8b9b5493e35defbd8ee2d1a3be2c /src/backend/commands/tablecmds.c
parentf2ef470196530e862b01c95e3b599e29102c887e (diff)
downloadpostgresql-ebb531836ada81958bbf95c60dd05dc58eb3e810.tar.gz
postgresql-ebb531836ada81958bbf95c60dd05dc58eb3e810.zip
Add code to handle [ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP }]
for temp tables. Gavin Sherry
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c218
1 files changed, 216 insertions, 2 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 62d61b315c6..40a790ca17e 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -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);
+}
+