Hi all,

While looking at another bug I have noticed that it is possible to
create an extension directly using a temporary schema, which is
crazy.  A simple example:
=# create extension pg_prewarm with schema pg_temp_3;
CREATE EXTENSION
=# \dx pg_prewarm
           List of installed extensions
    Name    | Version |  Schema   |      Description
------------+---------+-----------+-----------------------
 pg_prewarm | 1.2     | pg_temp_3 | prewarm relation data
(1 row)

When also creating some extensions, like pageinspect, then the error
message gets a bit crazier, complaining about things not existing.
This combination makes no actual sense, so wouldn't it be better to
restrict the case?  When trying to use ALTER EXTENSION SET SCHEMA we
already have a similar error:
=# alter extension pageinspect set schema pg_temp_3;
ERROR:  0A000: cannot move objects into or out of temporary schemas
LOCATION:  CheckSetNamespace, namespace.c:2954

Attached is an idea of patch, the test case is a bit bulky to remain
portable though.

Thoughts?
--
Michael
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 1f85f223a0..057cf80eb7 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1473,6 +1473,16 @@ CreateExtensionInternal(char *extensionName,
 		list_free(search_path);
 	}
 
+	/*
+	 * Prevent creation of extensions if attempting to use a temporary
+	 * schema as this would make the extension tied with the session
+	 * context, and this is a database-wide object.
+	 */
+	if (isTempNamespace(schemaOid))
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("cannot create extensions using temporary schema")));
+
 	/*
 	 * We don't check creation rights on the target namespace here.  If the
 	 * extension script actually creates any objects there, it will fail if
diff --git a/src/test/modules/test_extensions/expected/test_extensions.out b/src/test/modules/test_extensions/expected/test_extensions.out
index 28d86c4b87..83db5a3d91 100644
--- a/src/test/modules/test_extensions/expected/test_extensions.out
+++ b/src/test/modules/test_extensions/expected/test_extensions.out
@@ -9,6 +9,28 @@ ERROR:  schema "test_ext" does not exist
 CREATE SCHEMA test_ext;
 CREATE EXTENSION test_ext1 SCHEMA test_ext;
 ERROR:  extension "test_ext1" must be installed in schema "test_ext1"
+-- creation of extension in temporary schema.  This function
+-- wrapper is useful for portability.
+-- First enforce presence of temporary schema.
+CREATE TEMP TABLE test_ext2_tab ();
+CREATE OR REPLACE FUNCTION create_extension_with_temp_schema()
+  RETURNS VOID AS $$
+  DECLARE
+    tmpschema text;
+    query text;
+  BEGIN
+    SELECT INTO tmpschema pg_my_temp_schema()::regnamespace;
+    query := 'CREATE EXTENSION test_ext2 SCHEMA ' || tmpschema || ';';
+    RAISE NOTICE 'query %', query;
+    EXECUTE query;
+  END; $$ LANGUAGE plpgsql;
+SELECT create_extension_with_temp_schema();
+NOTICE:  query CREATE EXTENSION test_ext2 SCHEMA pg_temp_3;
+ERROR:  cannot create extensions using temporary schema
+CONTEXT:  SQL statement "CREATE EXTENSION test_ext2 SCHEMA pg_temp_3;"
+PL/pgSQL function create_extension_with_temp_schema() line 9 at EXECUTE
+DROP TABLE test_ext2_tab;
+DROP FUNCTION create_extension_with_temp_schema();
 -- finally success
 CREATE EXTENSION test_ext1 SCHEMA test_ext CASCADE;
 NOTICE:  installing required extension "test_ext2"
diff --git a/src/test/modules/test_extensions/sql/test_extensions.sql b/src/test/modules/test_extensions/sql/test_extensions.sql
index 9e64503eb5..8a8079836b 100644
--- a/src/test/modules/test_extensions/sql/test_extensions.sql
+++ b/src/test/modules/test_extensions/sql/test_extensions.sql
@@ -5,6 +5,25 @@ CREATE EXTENSION test_ext1 SCHEMA test_ext;
 CREATE SCHEMA test_ext;
 CREATE EXTENSION test_ext1 SCHEMA test_ext;
 
+-- creation of extension in temporary schema.  This function
+-- wrapper is useful for portability.
+-- First enforce presence of temporary schema.
+CREATE TEMP TABLE test_ext2_tab ();
+CREATE OR REPLACE FUNCTION create_extension_with_temp_schema()
+  RETURNS VOID AS $$
+  DECLARE
+    tmpschema text;
+    query text;
+  BEGIN
+    SELECT INTO tmpschema pg_my_temp_schema()::regnamespace;
+    query := 'CREATE EXTENSION test_ext2 SCHEMA ' || tmpschema || ';';
+    RAISE NOTICE 'query %', query;
+    EXECUTE query;
+  END; $$ LANGUAGE plpgsql;
+SELECT create_extension_with_temp_schema();
+DROP TABLE test_ext2_tab;
+DROP FUNCTION create_extension_with_temp_schema();
+
 -- finally success
 CREATE EXTENSION test_ext1 SCHEMA test_ext CASCADE;
 

Attachment: signature.asc
Description: PGP signature

Reply via email to