On Sat, Feb 23, 2019 at 12:29 AM Michael Paquier <mich...@paquier.xyz>
wrote:

> On Fri, Feb 22, 2019 at 09:45:42AM -0500, Tom Lane wrote:
> > +1 ... maybe "(dropped)", because we tend to use parens for this sort
> > of thing, I think.
>
> +1.  Using "dropped" sounds good to me in this context.  Perhaps we
> could have something more fancy like what's used for dropped columns?
> It would be nice to get a reference to a schema, like say "dropped
> temporary schema".
>

I think that's unnecessary given the context:

2019-02-23 15:43:56.375 CET [17250] LOG:  autovacuum: dropping orphan temp
table "postgres.(dropped).bar"

That said, it just moves the crash. Turns out the problem goes a lot deeper
than just the logging, it's basically the cleanup of orphaned temp tables
that's completely broken if you drop the namespace.

TRAP: FailedAssertion("!(relation->rd_backend != (-1))", File:
"relcache.c", Line: 1085)
2019-02-23 15:43:56.378 CET [17146] LOG:  server process (PID 17250) was
terminated by signal 6: Aborted

#2  0x0000563e0fe4bc83 in ExceptionalCondition
(conditionName=conditionName@entry=0x563e10035fb0 "!(relation->rd_backend
!= (-1))",
    errorType=errorType@entry=0x563e0fe9bf9d "FailedAssertion",
fileName=fileName@entry=0x563e100357dc "relcache.c",
    lineNumber=lineNumber@entry=1085) at assert.c:54
#3  0x0000563e0fe40e18 in RelationBuildDesc (targetRelId=24580,
insertIt=insertIt@entry=true) at relcache.c:1085
#4  0x0000563e0fe41a86 in RelationIdGetRelation (relationId=<optimized
out>, relationId@entry=24580) at relcache.c:1894
#5  0x0000563e0fa24b4c in relation_open (relationId=relationId@entry=24580,
lockmode=lockmode@entry=8) at relation.c:59
#6  0x0000563e0fadcfea in heap_drop_with_catalog (relid=24580) at
heap.c:1856
#7  0x0000563e0fad9145 in doDeletion (flags=21, object=<optimized out>) at
dependency.c:1329
#8  deleteOneObject (flags=21, depRel=0x7ffd80db4808, object=<optimized
out>) at dependency.c:1231
#9  deleteObjectsInList (targetObjects=targetObjects@entry=0x563e10640110,
depRel=depRel@entry=0x7ffd80db4808, flags=flags@entry=21)
    at dependency.c:271
#10 0x0000563e0fad91f0 in performDeletion (object=object@entry=0x7ffd80db4944,
behavior=behavior@entry=DROP_CASCADE,
    flags=flags@entry=21) at dependency.c:352
#11 0x0000563e0fa13532 in do_autovacuum () at autovacuum.c:2269


So basically I think it's the wrong approach to try to fix this error
message. We need to fix the underlying problem. Which is the ability to
drop the temp table schemas and then create temp tables which ahve no
schemas.

We could try to recreate the namespace if dropped. But a quick fix around
that just moved coredumps around to a lot of other dependent places.

I think we're better off just peventing the explicit drop of a temp schema.
See attached?

We'd also want to block things like:
ALTER SCHEMA pg_temp_3 RENAME TO foobar;
DROP SCHEMA foobar;

Are there any more things beyond RENAME we need to block?

-- 
 Magnus Hagander
 Me: https://www.hagander.net/ <http://www.hagander.net/>
 Work: https://www.redpill-linpro.com/ <http://www.redpill-linpro.com/>
diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c
index f26a2f4779..c9841e2dc2 100644
--- a/src/backend/commands/dropcmds.c
+++ b/src/backend/commands/dropcmds.c
@@ -101,6 +101,23 @@ RemoveObjects(DropStmt *stmt)
 						 errhint("Use DROP AGGREGATE to drop aggregate functions.")));
 		}
 
+		/*
+		 * Don't allow dropping of temp namespaces, since there can still be
+		 * references to the oids all over.
+		 * We have to look at the name of the schema, since the checks for isTempNamespace()
+		 * only checks if it's *our* temp one,gi
+		 */
+		if (stmt->removeType == OBJECT_SCHEMA)
+		{
+			char *name = get_namespace_name(address.objectId);
+			if (name && (strncmp(name, "pg_temp_", 8) == 0 || strncmp(name, "pg_toast_temp_", 14) == 0))
+				ereport(ERROR,
+						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+						 errmsg("cannot drop temporary schema \"%s\"",
+								get_namespace_name(address.objectId)),
+						 errhint("temporary schemas are dropped automatically when the session ends.")));
+		}
+
 		/* Check permissions. */
 		namespaceId = get_object_namespace(&address);
 		if (!OidIsValid(namespaceId) ||

Reply via email to