summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/catalog.c13
-rw-r--r--src/backend/catalog/namespace.c80
-rw-r--r--src/backend/catalog/system_views.sql32
-rw-r--r--src/backend/catalog/toasting.c22
-rw-r--r--src/backend/storage/lmgr/lmgr.c4
-rw-r--r--src/backend/utils/cache/relcache.c6
6 files changed, 121 insertions, 36 deletions
diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c
index 049d216a787..acd107958ff 100644
--- a/src/backend/catalog/catalog.c
+++ b/src/backend/catalog/catalog.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.70 2007/03/25 19:45:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.71 2007/07/25 22:16:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,6 +24,7 @@
#include "access/transam.h"
#include "catalog/catalog.h"
#include "catalog/indexing.h"
+#include "catalog/namespace.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
@@ -196,15 +197,17 @@ IsSystemNamespace(Oid namespaceId)
/*
* IsToastNamespace
- * True iff namespace is pg_toast.
+ * True iff namespace is pg_toast or my temporary-toast-table namespace.
*
- * NOTE: the reason this isn't a macro is to avoid having to include
- * catalog/pg_namespace.h in a lot of places.
+ * Note: this will return false for temporary-toast-table namespaces belonging
+ * to other backends. Those are treated the same as other backends' regular
+ * temp table namespaces, and access is prevented where appropriate.
*/
bool
IsToastNamespace(Oid namespaceId)
{
- return namespaceId == PG_TOAST_NAMESPACE;
+ return (namespaceId == PG_TOAST_NAMESPACE) ||
+ isTempToastNamespace(namespaceId);
}
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 55379b66f65..2f8753bd2e0 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.96 2007/04/20 02:37:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.97 2007/07/25 22:16:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -152,6 +152,9 @@ static List *overrideStack = NIL;
* in a particular backend session (this happens when a CREATE TEMP TABLE
* command is first executed). Thereafter it's the OID of the temp namespace.
*
+ * myTempToastNamespace is the OID of the namespace for my temp tables' toast
+ * tables. It is set when myTempNamespace is, and is InvalidOid before that.
+ *
* myTempNamespaceSubID shows whether we've created the TEMP namespace in the
* current subtransaction. The flag propagates up the subtransaction tree,
* so the main transaction will correctly recognize the flag if all
@@ -161,6 +164,8 @@ static List *overrideStack = NIL;
*/
static Oid myTempNamespace = InvalidOid;
+static Oid myTempToastNamespace = InvalidOid;
+
static SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId;
/*
@@ -1600,8 +1605,34 @@ isTempNamespace(Oid namespaceId)
}
/*
+ * isTempToastNamespace - is the given namespace my temporary-toast-table
+ * namespace?
+ */
+bool
+isTempToastNamespace(Oid namespaceId)
+{
+ if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
+ return true;
+ return false;
+}
+
+/*
+ * isTempOrToastNamespace - is the given namespace my temporary-table
+ * namespace or my temporary-toast-table namespace?
+ */
+bool
+isTempOrToastNamespace(Oid namespaceId)
+{
+ if (OidIsValid(myTempNamespace) &&
+ (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
+ return true;
+ return false;
+}
+
+/*
* isAnyTempNamespace - is the given namespace a temporary-table namespace
- * (either my own, or another backend's)?
+ * (either my own, or another backend's)? Temporary-toast-table namespaces
+ * are included, too.
*/
bool
isAnyTempNamespace(Oid namespaceId)
@@ -1609,29 +1640,42 @@ isAnyTempNamespace(Oid namespaceId)
bool result;
char *nspname;
- /* If the namespace name starts with "pg_temp_", say "true" */
+ /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
nspname = get_namespace_name(namespaceId);
if (!nspname)
return false; /* no such namespace? */
- result = (strncmp(nspname, "pg_temp_", 8) == 0);
+ result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
+ (strncmp(nspname, "pg_toast_temp_", 14) == 0);
pfree(nspname);
return result;
}
/*
* isOtherTempNamespace - is the given namespace some other backend's
- * temporary-table namespace?
+ * temporary-table namespace (including temporary-toast-table namespaces)?
*/
bool
isOtherTempNamespace(Oid namespaceId)
{
/* If it's my own temp namespace, say "false" */
- if (isTempNamespace(namespaceId))
+ if (isTempOrToastNamespace(namespaceId))
return false;
- /* Else, if the namespace name starts with "pg_temp_", say "true" */
+ /* Else, if it's any temp namespace, say "true" */
return isAnyTempNamespace(namespaceId);
}
+/*
+ * GetTempToastNamespace - get the OID of my temporary-toast-table namespace,
+ * which must already be assigned. (This is only used when creating a toast
+ * table for a temp table, so we must have already done InitTempTableNamespace)
+ */
+Oid
+GetTempToastNamespace(void)
+{
+ Assert(OidIsValid(myTempToastNamespace));
+ return myTempToastNamespace;
+}
+
/*
* GetOverrideSearchPath - fetch current search path definition in form
@@ -2006,6 +2050,7 @@ InitTempTableNamespace(void)
{
char namespaceName[NAMEDATALEN];
Oid namespaceId;
+ Oid toastspaceId;
Assert(!OidIsValid(myTempNamespace));
@@ -2055,11 +2100,30 @@ InitTempTableNamespace(void)
}
/*
+ * If the corresponding temp-table namespace doesn't exist yet, create it.
+ * (We assume there is no need to clean it out if it does exist, since
+ * dropping a parent table should make its toast table go away.)
+ */
+ snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
+ MyBackendId);
+
+ toastspaceId = GetSysCacheOid(NAMESPACENAME,
+ CStringGetDatum(namespaceName),
+ 0, 0, 0);
+ if (!OidIsValid(toastspaceId))
+ {
+ toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
+ /* Advance command counter to make namespace visible */
+ CommandCounterIncrement();
+ }
+
+ /*
* Okay, we've prepared the temp namespace ... but it's not committed yet,
* so all our work could be undone by transaction rollback. Set flag for
* AtEOXact_Namespace to know what to do.
*/
myTempNamespace = namespaceId;
+ myTempToastNamespace = toastspaceId;
/* It should not be done already. */
AssertState(myTempNamespaceSubID == InvalidSubTransactionId);
@@ -2089,6 +2153,7 @@ AtEOXact_Namespace(bool isCommit)
else
{
myTempNamespace = InvalidOid;
+ myTempToastNamespace = InvalidOid;
baseSearchPathValid = false; /* need to rebuild list */
}
myTempNamespaceSubID = InvalidSubTransactionId;
@@ -2140,6 +2205,7 @@ AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
myTempNamespaceSubID = InvalidSubTransactionId;
/* TEMP namespace creation failed, so reset state */
myTempNamespace = InvalidOid;
+ myTempToastNamespace = InvalidOid;
baseSearchPathValid = false; /* need to rebuild list */
}
}
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index c5f8810d0af..c091c855708 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -3,7 +3,7 @@
*
* Copyright (c) 1996-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.38 2007/06/28 00:02:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.39 2007/07/25 22:16:18 tgl Exp $
*/
CREATE VIEW pg_roles AS
@@ -221,11 +221,13 @@ CREATE VIEW pg_stat_all_tables AS
CREATE VIEW pg_stat_sys_tables AS
SELECT * FROM pg_stat_all_tables
- WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+ schemaname ~ '^pg_toast';
CREATE VIEW pg_stat_user_tables AS
SELECT * FROM pg_stat_all_tables
- WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+ schemaname !~ '^pg_toast';
CREATE VIEW pg_statio_all_tables AS
SELECT
@@ -254,11 +256,13 @@ CREATE VIEW pg_statio_all_tables AS
CREATE VIEW pg_statio_sys_tables AS
SELECT * FROM pg_statio_all_tables
- WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+ schemaname ~ '^pg_toast';
CREATE VIEW pg_statio_user_tables AS
SELECT * FROM pg_statio_all_tables
- WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+ schemaname !~ '^pg_toast';
CREATE VIEW pg_stat_all_indexes AS
SELECT
@@ -278,11 +282,13 @@ CREATE VIEW pg_stat_all_indexes AS
CREATE VIEW pg_stat_sys_indexes AS
SELECT * FROM pg_stat_all_indexes
- WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+ schemaname ~ '^pg_toast';
CREATE VIEW pg_stat_user_indexes AS
SELECT * FROM pg_stat_all_indexes
- WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+ schemaname !~ '^pg_toast';
CREATE VIEW pg_statio_all_indexes AS
SELECT
@@ -302,11 +308,13 @@ CREATE VIEW pg_statio_all_indexes AS
CREATE VIEW pg_statio_sys_indexes AS
SELECT * FROM pg_statio_all_indexes
- WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+ schemaname ~ '^pg_toast';
CREATE VIEW pg_statio_user_indexes AS
SELECT * FROM pg_statio_all_indexes
- WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+ schemaname !~ '^pg_toast';
CREATE VIEW pg_statio_all_sequences AS
SELECT
@@ -322,11 +330,13 @@ CREATE VIEW pg_statio_all_sequences AS
CREATE VIEW pg_statio_sys_sequences AS
SELECT * FROM pg_statio_all_sequences
- WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname IN ('pg_catalog', 'information_schema') OR
+ schemaname ~ '^pg_toast';
CREATE VIEW pg_statio_user_sequences AS
SELECT * FROM pg_statio_all_sequences
- WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
+ WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+ schemaname !~ '^pg_toast';
CREATE VIEW pg_stat_activity AS
SELECT
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 463f038c0f7..2fe44f59f8c 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.6 2007/04/06 04:21:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.7 2007/07/25 22:16:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,6 +21,7 @@
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/indexing.h"
+#include "catalog/namespace.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_type.h"
@@ -108,6 +109,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
Relation class_rel;
Oid toast_relid;
Oid toast_idxid;
+ Oid namespaceid;
char toast_relname[NAMEDATALEN];
char toast_idxname[NAMEDATALEN];
IndexInfo *indexInfo;
@@ -173,16 +175,20 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
tupdesc->attrs[2]->attstorage = 'p';
/*
- * Note: the toast relation is placed in the regular pg_toast namespace
- * even if its master relation is a temp table. There cannot be any
- * naming collision, and the toast rel will be destroyed when its master
- * is, so there's no need to handle the toast rel as temp.
- *
+ * Toast tables for regular relations go in pg_toast; those for temp
+ * relations go into the per-backend temp-toast-table namespace.
+ */
+ if (rel->rd_istemp)
+ namespaceid = GetTempToastNamespace();
+ else
+ namespaceid = PG_TOAST_NAMESPACE;
+
+ /*
* XXX would it make sense to apply the master's reloptions to the toast
- * table?
+ * table? Or maybe some toast-specific reloptions?
*/
toast_relid = heap_create_with_catalog(toast_relname,
- PG_TOAST_NAMESPACE,
+ namespaceid,
rel->rd_rel->reltablespace,
toastOid,
rel->rd_rel->relowner,
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 6f6c609f53d..1c5db363203 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.91 2007/06/19 20:13:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.92 2007/07/25 22:16:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -619,7 +619,7 @@ LockTagIsTemp(const LOCKTAG *tag)
/* field1 is dboid, field2 is reloid for all of these */
if ((Oid) tag->locktag_field1 == InvalidOid)
return false; /* shared, so not temp */
- if (isTempNamespace(get_rel_namespace((Oid) tag->locktag_field2)))
+ if (isTempOrToastNamespace(get_rel_namespace((Oid) tag->locktag_field2)))
return true;
break;
case LOCKTAG_TRANSACTION:
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 45cb103adee..f69fb0c9362 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.261 2007/05/27 03:50:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.262 2007/07/25 22:16:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -838,7 +838,7 @@ RelationBuildDesc(Oid targetRelId, Relation oldrelation)
relation->rd_isnailed = false;
relation->rd_createSubid = InvalidSubTransactionId;
relation->rd_newRelfilenodeSubid = InvalidSubTransactionId;
- relation->rd_istemp = isTempNamespace(relation->rd_rel->relnamespace);
+ relation->rd_istemp = isTempOrToastNamespace(relation->rd_rel->relnamespace);
/*
* initialize the tuple descriptor (relation->rd_att).
@@ -2315,7 +2315,7 @@ RelationBuildLocalRelation(const char *relname,
need_eoxact_work = true;
/* is it a temporary relation? */
- rel->rd_istemp = isTempNamespace(relnamespace);
+ rel->rd_istemp = isTempOrToastNamespace(relnamespace);
/*
* create a new tuple descriptor from the one passed in. We do this