diff options
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/catalog/catalog.c | 13 | ||||
| -rw-r--r-- | src/backend/catalog/namespace.c | 80 | ||||
| -rw-r--r-- | src/backend/catalog/system_views.sql | 32 | ||||
| -rw-r--r-- | src/backend/catalog/toasting.c | 22 | ||||
| -rw-r--r-- | src/backend/storage/lmgr/lmgr.c | 4 | ||||
| -rw-r--r-- | src/backend/utils/cache/relcache.c | 6 |
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 |
