diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index e70243a008..5ff78248e0 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -3217,7 +3217,7 @@ isOtherTempNamespace(Oid namespaceId) } /* - * isTempNamespaceInUse - is the given namespace owned and actively used + * checkTempNamespaceStatus - is the given namespace owned and actively used * by a backend? * * Note: this can be used while scanning relations in pg_class to detect @@ -3225,8 +3225,8 @@ isOtherTempNamespace(Oid namespaceId) * given database. The result may be out of date quickly, so the caller * must be careful how to handle this information. */ -bool -isTempNamespaceInUse(Oid namespaceId) +TempNamespaceStatus +checkTempNamespaceStatus(Oid namespaceId) { PGPROC *proc; int backendId; @@ -3235,25 +3235,25 @@ isTempNamespaceInUse(Oid namespaceId) backendId = GetTempNamespaceBackendId(namespaceId); - /* No such temporary namespace? */ + /* No such namespace, or its name shows it's not temp? */ if (backendId == InvalidBackendId) - return false; + return TEMP_NAMESPACE_NOT_TEMP; /* Is the backend alive? */ proc = BackendIdGetProc(backendId); if (proc == NULL) - return false; + return TEMP_NAMESPACE_IDLE; /* Is the backend connected to the same database we are looking at? */ if (proc->databaseId != MyDatabaseId) - return false; + return TEMP_NAMESPACE_IDLE; /* Does the backend own the temporary namespace? */ if (proc->tempNamespaceId != namespaceId) - return false; + return TEMP_NAMESPACE_IDLE; - /* all good to go */ - return true; + /* Yup, so namespace is busy */ + return TEMP_NAMESPACE_IN_USE; } /* diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 6d1f28c327..e3a43d3296 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2071,9 +2071,10 @@ do_autovacuum(void) { /* * We just ignore it if the owning backend is still active and - * using the temporary schema. + * using the temporary schema. Also, for safety, ignore it if the + * namespace doesn't exist or isn't a temp namespace after all. */ - if (!isTempNamespaceInUse(classForm->relnamespace)) + if (checkTempNamespaceStatus(classForm->relnamespace) == TEMP_NAMESPACE_IDLE) { /* * The table seems to be orphaned -- although it might be that @@ -2243,7 +2244,7 @@ do_autovacuum(void) continue; } - if (isTempNamespaceInUse(classForm->relnamespace)) + if (checkTempNamespaceStatus(classForm->relnamespace) != TEMP_NAMESPACE_IDLE) { UnlockRelationOid(relid, AccessExclusiveLock); continue; diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index d67f93ae3b..3e3a192471 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -37,6 +37,16 @@ typedef struct _FuncCandidateList Oid args[FLEXIBLE_ARRAY_MEMBER]; /* arg types */ } *FuncCandidateList; +/* + * Result of checkTempNamespaceStatus + */ +typedef enum TempNamespaceStatus +{ + TEMP_NAMESPACE_NOT_TEMP, /* nonexistent, or non-temp namespace */ + TEMP_NAMESPACE_IDLE, /* exists, belongs to no active session */ + TEMP_NAMESPACE_IN_USE /* belongs to some active session */ +} TempNamespaceStatus; + /* * Structure for xxxOverrideSearchPath functions */ @@ -138,7 +148,7 @@ extern bool isTempToastNamespace(Oid namespaceId); extern bool isTempOrTempToastNamespace(Oid namespaceId); extern bool isAnyTempNamespace(Oid namespaceId); extern bool isOtherTempNamespace(Oid namespaceId); -extern bool isTempNamespaceInUse(Oid namespaceId); +extern TempNamespaceStatus checkTempNamespaceStatus(Oid namespaceId); extern int GetTempNamespaceBackendId(Oid namespaceId); extern Oid GetTempToastNamespace(void); extern void GetTempNamespaceState(Oid *tempNamespaceId,