Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pWAh7-00089W-89 for pgsql-hackers@arkaria.postgresql.org; Sun, 26 Feb 2023 06:39:37 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1pWAh3-00078G-TI for pgsql-hackers@arkaria.postgresql.org; Sun, 26 Feb 2023 06:39:33 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pWAh3-000786-45 for pgsql-hackers@lists.postgresql.org; Sun, 26 Feb 2023 06:39:33 +0000 Received: from mail-qv1-xf2c.google.com ([2607:f8b0:4864:20::f2c]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1pWAgx-0006Bc-9M for pgsql-hackers@postgresql.org; Sun, 26 Feb 2023 06:39:31 +0000 Received: by mail-qv1-xf2c.google.com with SMTP id op8so2417070qvb.11 for ; Sat, 25 Feb 2023 22:39:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pcorp-us.20210112.gappssmtp.com; s=20210112; h=content-language:thread-index:mime-version:message-id:date:subject :in-reply-to:references:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4csq5Figx/aNrBBSwaONb8tFPe4LMHEnkm3t7WdLfLM=; b=g58kryes90asbw3tEry2cDMzo3KpGaUShhAIZsz5cyuPzG4hbgQL/6GjEfYxcvoL0S R+E+j++j8X2Hpi8hXX4PJI9fQtINL1jCqlhDNhDBzvFP4fGVvxSWcIzK2zbR8tyYfN1U W2e03SMN8v+hWjVs/eraTW7n6tq3fyqHPvRldotWAsiAOPToVXvjpxTcyX8p7gxCAqqf nGqDhOBXSNugha2W+KyTRn6x122tGGEoemKEi9MXMX/gUnjEoQV3WzsKRqtn4ICoX9ry Zd+V2fNDV8B+oQLqw93d0DmFd7jlPujUa8JzFmtXNYfV3rjqrWIr42VHSvhq/e26fdB3 eGIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-language:thread-index:mime-version:message-id:date:subject :in-reply-to:references:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4csq5Figx/aNrBBSwaONb8tFPe4LMHEnkm3t7WdLfLM=; b=PgHm8qz9F3H+z0m0I+0+g1xMTbcJ5x0XME8kZigXssyZ7Quy1XDz7NvFA3Wf1MwHSi 3YDtrYC5+p8HwJG4QECjADWcAf01ijlkQ5zPeGef8t+YoDk6Dcq14inTBWbtWu31ymUo z0SFxBngeNM9b2rxnT16NhmZ8rSwRHwPFWF1jEMjyBPpGfgM7t+9sMgMnK7lcizIHl97 hv2pPMVAniNO/PxQxLBQR4E0aJAU7sgL6ySMtJFjruOqKNuDRWTP01OrKDgzynNhOOQV bU/G/QdAZ8A+PVWxLSryIhXYU0mAA692YnnjN2o20PscX8UILv+sI0WX6cP0wkZ6SDeu oX2Q== X-Gm-Message-State: AO0yUKWJ1sMMrXOdkP9EJC2OBt7CAhKzL8ziDDF/wyuK6l3DaYFeBBpG xCJKxZOczdbxP9WVdE2Lf6cNu0HHdUf27RME X-Google-Smtp-Source: AK7set/dWJU8iC7K606f6HiICpc6wmP7LPUdvouhbMleWcsa8d2a8KMQIpKXTaGDR+7aKtCgxEkAyQ== X-Received: by 2002:ad4:4ea7:0:b0:56e:abb8:b656 with SMTP id ed7-20020ad44ea7000000b0056eabb8b656mr10070572qvb.7.1677393565992; Sat, 25 Feb 2023 22:39:25 -0800 (PST) Received: from F (50-78-240-110-static.hfc.comcastbusiness.net. [50.78.240.110]) by smtp.gmail.com with ESMTPSA id q11-20020a37430b000000b00742a252ba06sm301631qka.135.2023.02.25.22.39.25 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 Feb 2023 22:39:25 -0800 (PST) From: "Regina Obe" To: Cc: "'Tom Lane'" , References: <003001d8f4ae$402282c0$c0678840$@pcorp.us> <79300.1668052170@sss.pgh.pa.us> <004501d8f4bf$1213fba0$363bf2e0$@pcorp.us> <175298.1668101858@sss.pgh.pa.us> <004b01d8fef3$752dbf30$5f893d90$@pcorp.us> <20221215085234.rpjzlm7hmsmbanqv@c19> <000401d93a14$8647f540$92d7dfc0$@pcorp.us> <20230223183906.6rhtybwdpe37sri7@c19> In-Reply-To: Subject: RE: Ability to reference other extensions by schema in extension scripts Date: Sun, 26 Feb 2023 01:39:24 -0500 Message-ID: <000001d949ad$1159adc0$340d0940$@pcorp.us> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0001_01D94983.2883F3E0" X-Mailer: Microsoft Outlook 15.0 Thread-Index: AQFgXZxpr0yOB+9uS1Xwc1lFBKthIAHDgsBQATMNnPQCHx2JfQJ9+hXQAio5JzEC/Q8E0gI4X7Gsr1pV+oCAAK2ooA== Content-Language: en-us List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multipart message in MIME format. ------=_NextPart_000_0001_01D94983.2883F3E0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit > So in conclusion we have 3 possible paths to go with this > > 1) Just don't allow any extensions referenced by other extensions to be > relocatable. > It will show a message something like > "SET SCHEMA not allowed because other extensions depend on it" > Given that if you don't specify relocatable in you .control file, the assume is > relocatable = false , this isn't too far off from standard protocol. > > 2) Use objsubid=1 to denote that another extension explicitly references the > schema of another extension so setting schema of other extension is not okay. > So instead of introducing another dependency, we'd update the > DEPENDENCY_NORMAL one between the two schemas with objsubid=1 > instead of 0. > > This has 2 approaches: > > a) Update the existing DEPENDENCY_NORMAL between the two extensions > setting the objsubid=1 > > or > b) Create a new DEPEDENCY_NORMAL between the two extensions with > objsubid=1 > > I'm not sure if either has implications in backup / restore . I suspect b would > be safer since I suspect objsubid might be checked and this dependency only > needs checking during SET SCHEMA time. > > 3) Create a whole new DEPENDENCY type, perhaps calling it something like > DEPENDENCY_EXTENSION_SCHEMA > > 4) Just don't allow @extschema:@ syntax to be used unless > the is marked as relocatable=false. This one I don't like > because it doesn't solve my fundamental issue of > > postgis_tiger_geocoder relying on fuzzystrmatch, which is marked as > relocatable. > > The main issue I was trying to solve is my extension references fuzzystrmatch > functions in a function used for functional indexes, and this fails restore of > table indexes because I can't schema qualify the fuzzystrmatch extension in > the backing function. > > > If no one has any opinion, I'll go with option 1 which is the one that strk had > actually proposed before and seems least programmatically invasive, but > perhaps more annoying user facing. > > My preferred would be #2 > > Thanks, > Regina Attached is my revision 3 patch, which follows the proposed #1. Don't allow schema relocation of an extension if another extension requires it. ------=_NextPart_000_0001_01D94983.2883F3E0 Content-Type: application/octet-stream; name="0003-Allow-use-of-extschema-reqextname-to-reference.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0003-Allow-use-of-extschema-reqextname-to-reference.patch" From d25ae7c6795922c82921fb9abfd29719fcc8bdc0 Mon Sep 17 00:00:00 2001=0A= From: Regina Obe =0A= Date: Sun, 5 Feb 2023 01:35:29 -0500=0A= Subject: [PATCH 3/3] Allow @extschema:@ in extension scripts=0A= =0A= Changes to extension execute logic to allow referencing required=0A= extension schemas by variable=0A= =0A= This feature is needed in cases such as=0A= when another extension packages a function=0A= which references an object from one of required extensions=0A= and this function is used to back=0A= indexes, constraints, and materialized views=0A= =0A= Without this feature, because pg_restore removes the paths,=0A= these indexes, constraints, materialized views are not restored=0A= because when the function is called, the function call fails=0A= because the dependent item is not schema qualified.=0A= =0A= - Extension tests both Makefile and meson.build=0A= - Documentation of the new feature=0A= - Prevent an extension from being relocated if=0A= another extension requires it=0A= =0A= Discussion: = https://postgr.es/m/000801d94959%2463a9f520%242afddf60%24%40pcorp.us=0A= ---=0A= doc/src/sgml/extend.sgml | 17 ++++++=0A= src/backend/commands/extension.c | 55 +++++++++++++++++++=0A= src/test/modules/test_extensions/Makefile | 9 ++-=0A= .../expected/test_extensions.out | 40 ++++++++++++++=0A= src/test/modules/test_extensions/meson.build | 7 +++=0A= .../test_extensions/sql/test_extensions.sql | 14 +++++=0A= .../test_ext_req_schema1--1.0.sql | 6 ++=0A= .../test_ext_req_schema1.control | 3 +=0A= .../test_ext_req_schema2--1.0--2.0.sql | 7 +++=0A= .../test_ext_req_schema2--1.0.sql | 9 +++=0A= .../test_ext_req_schema2.control | 4 ++=0A= .../test_ext_req_schema3--1.0.sql | 13 +++++=0A= .../test_ext_req_schema3.control | 4 ++=0A= 13 files changed, 186 insertions(+), 2 deletions(-)=0A= create mode 100644 = src/test/modules/test_extensions/test_ext_req_schema1--1.0.sql=0A= create mode 100644 = src/test/modules/test_extensions/test_ext_req_schema1.control=0A= create mode 100644 = src/test/modules/test_extensions/test_ext_req_schema2--1.0--2.0.sql=0A= create mode 100644 = src/test/modules/test_extensions/test_ext_req_schema2--1.0.sql=0A= create mode 100644 = src/test/modules/test_extensions/test_ext_req_schema2.control=0A= create mode 100644 = src/test/modules/test_extensions/test_ext_req_schema3--1.0.sql=0A= create mode 100644 = src/test/modules/test_extensions/test_ext_req_schema3.control=0A= =0A= diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml=0A= index b70cbe83ae..6c93bddb36 100644=0A= --- a/doc/src/sgml/extend.sgml=0A= +++ b/doc/src/sgml/extend.sgml=0A= @@ -908,6 +908,23 @@ RETURNS anycompatible AS ...=0A= =0A= =0A= =0A= + =0A= + =0A= + An extension might depend on other extensions.=0A= + It is useful to schema qualify calls to dependent extension to = minimize reliance on search_path.=0A= + This is critical for cases such as functions used in indexes, = materialized views, or check constraints.=0A= + To reference a required extension's schema, you must first have = requires=0A= + variable specifying the list of extensions your extension = requires.=0A= + In your extension sql scripts,=0A= + you can reference a required extension's schema with syntax=0A= + @extschema:reqextname@ where = reqextname=0A= + is the name of an extension in your requires = list.=0A= + All occurrences of this string will be=0A= + replaced by the schema the required extension is installed in = before the script is=0A= + executed.=0A= + =0A= + =0A= +=0A= =0A= =0A= If the extension does not support relocation at all, set=0A= diff --git a/src/backend/commands/extension.c = b/src/backend/commands/extension.c=0A= index b1509cc505..57a21ba41e 100644=0A= --- a/src/backend/commands/extension.c=0A= +++ b/src/backend/commands/extension.c=0A= @@ -854,6 +854,7 @@ execute_extension_script(Oid extensionOid, = ExtensionControlFile *control,=0A= const char *schemaName, Oid schemaOid)=0A= {=0A= bool switch_to_superuser =3D false;=0A= + char *origSchemaName =3D (char *) schemaName;=0A= char *filename;=0A= Oid save_userid =3D 0;=0A= int save_sec_context =3D 0;=0A= @@ -1030,6 +1031,46 @@ execute_extension_script(Oid extensionOid, = ExtensionControlFile *control,=0A= CStringGetTextDatum(qSchemaName));=0A= }=0A= =0A= + /*=0A= + * If this extension requires other extensions=0A= + * Check each required extension to see if it's schema=0A= + * is referenced by @extschema:reqextname@ syntax=0A= + */=0A= + if (control->requires)=0A= + {=0A= + foreach(lc, control->requires)=0A= + {=0A= + char *curreq;=0A= + curreq =3D (char *) lfirst(lc);=0A= + Oid reqext;=0A= + Oid reqschema;=0A= + reqext =3D get_required_extension(curreq,=0A= + control->name,=0A= + origSchemaName,=0A= + false,=0A= + NIL,=0A= + false);=0A= + reqschema =3D get_extension_schema(reqext);=0A= + char *reqname;=0A= + reqname =3D get_namespace_name(reqschema);=0A= + StringInfoData rToken;=0A= + initStringInfo(&rToken);=0A= + appendStringInfo(&rToken, "%s%s%s", "@extschema:", curreq, "@");=0A= + if (strstr(c_sql,rToken.data) !=3D NULL){=0A= + /*=0A= + * If the required extension's schema is referenced=0A= + * by variable name,=0A= + * Replace each occurence of @extschema:reqextname@=0A= + * with the required extension's schema=0A= + */=0A= + t_sql =3D DirectFunctionCall3Coll(replace_text,=0A= + C_COLLATION_OID,=0A= + t_sql,=0A= + CStringGetTextDatum(rToken.data),=0A= + CStringGetTextDatum(quote_identifier(reqname)));=0A= + }=0A= + }=0A= + }=0A= /*=0A= * If module_pathname was set in the control file, substitute its=0A= * value for occurrences of MODULE_PATHNAME.=0A= @@ -2816,6 +2857,20 @@ AlterExtensionNamespace(const char = *extensionName, const char *newschema, Oid *o=0A= ObjectAddress dep;=0A= Oid dep_oldNspOid;=0A= =0A= + /* If an extension requires this extension=0A= + * do not allow relocation */=0A= + if (pg_depend->deptype =3D=3D DEPENDENCY_NORMAL && pg_depend->classid = =3D=3D ExtensionRelationId){=0A= + dep.classId =3D pg_depend->classid;=0A= + dep.objectId =3D pg_depend->objid;=0A= + dep.objectSubId =3D pg_depend->objsubid;=0A= + ereport(ERROR,=0A= + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),=0A= + errmsg("cannot SET SCHEMA of extension %s because other = extensions require it",=0A= + NameStr(extForm->extname)),=0A= + errdetail("%s requires extension %s",=0A= + getObjectDescription(&dep, false), = NameStr(extForm->extname))));=0A= +=0A= + }=0A= /*=0A= * Ignore non-membership dependencies. (Currently, the only other=0A= * case we could see here is a normal dependency from another=0A= diff --git a/src/test/modules/test_extensions/Makefile = b/src/test/modules/test_extensions/Makefile=0A= index c3139ab0fc..c073df963c 100644=0A= --- a/src/test/modules/test_extensions/Makefile=0A= +++ b/src/test/modules/test_extensions/Makefile=0A= @@ -6,14 +6,19 @@ PGFILEDESC =3D "test_extensions - regression testing = for EXTENSION support"=0A= EXTENSION =3D test_ext1 test_ext2 test_ext3 test_ext4 test_ext5 = test_ext6 \=0A= test_ext7 test_ext8 test_ext_cine test_ext_cor \=0A= test_ext_cyclic1 test_ext_cyclic2 \=0A= - test_ext_evttrig=0A= + test_ext_evttrig \=0A= + test_ext_req_schema1 test_ext_req_schema2 = test_ext_req_schema3=0A= +=0A= DATA =3D test_ext1--1.0.sql test_ext2--1.0.sql test_ext3--1.0.sql \=0A= test_ext4--1.0.sql test_ext5--1.0.sql test_ext6--1.0.sql \=0A= test_ext7--1.0.sql test_ext7--1.0--2.0.sql test_ext8--1.0.sql \=0A= test_ext_cine--1.0.sql test_ext_cine--1.0--1.1.sql \=0A= test_ext_cor--1.0.sql \=0A= test_ext_cyclic1--1.0.sql test_ext_cyclic2--1.0.sql \=0A= - test_ext_evttrig--1.0.sql test_ext_evttrig--1.0--2.0.sql=0A= + test_ext_evttrig--1.0.sql test_ext_evttrig--1.0--2.0.sql \=0A= + test_ext_req_schema1--1.0.sql \=0A= + test_ext_req_schema2--1.0.sql test_ext_req_schema2--1.0--2.0.sql = \=0A= + test_ext_req_schema3--1.0.sql=0A= =0A= REGRESS =3D test_extensions test_extdepend=0A= =0A= diff --git = a/src/test/modules/test_extensions/expected/test_extensions.out = b/src/test/modules/test_extensions/expected/test_extensions.out=0A= index 821fed38d1..21dfd05982 100644=0A= --- a/src/test/modules/test_extensions/expected/test_extensions.out=0A= +++ b/src/test/modules/test_extensions/expected/test_extensions.out=0A= @@ -312,3 +312,43 @@ Objects in extension "test_ext_cine"=0A= table ext_cine_tab3=0A= (9 rows)=0A= =0A= +CREATE SCHEMA test_s_dep;=0A= +CREATE EXTENSION test_ext_req_schema1 SCHEMA test_s_dep;=0A= +CREATE EXTENSION test_ext_req_schema3 CASCADE;=0A= +NOTICE: installing required extension "test_ext_req_schema2"=0A= +SELECT dep_req();=0A= + dep_req =0A= +---------=0A= + 1032w=0A= +(1 row)=0A= +=0A= +SELECT dep_req2();=0A= + dep_req2 =0A= +----------=0A= + 1032w=0A= +(1 row)=0A= +=0A= +SELECT dep_req3();=0A= + dep_req3 =0A= +----------=0A= + 2032w=0A= +(1 row)=0A= +=0A= +ALTER EXTENSION test_ext_req_schema2 UPDATE TO '2.0';=0A= +CREATE SCHEMA test_s_dep2;=0A= +ALTER EXTENSION test_ext_req_schema1 SET SCHEMA test_s_dep2;=0A= +ERROR: cannot SET SCHEMA of extension test_ext_req_schema1 because = other extensions require it=0A= +DETAIL: extension test_ext_req_schema3 requires extension = test_ext_req_schema1=0A= +SELECT dep_req();=0A= + dep_req =0A= +---------=0A= + 1update=0A= +(1 row)=0A= +=0A= +DROP EXTENSION test_ext_req_schema1;=0A= +ERROR: cannot drop extension test_ext_req_schema1 because other = objects depend on it=0A= +DETAIL: extension test_ext_req_schema2 depends on extension = test_ext_req_schema1=0A= +extension test_ext_req_schema3 depends on extension test_ext_req_schema1=0A= +HINT: Use DROP ... CASCADE to drop the dependent objects too.=0A= +DROP EXTENSION test_ext_req_schema3;=0A= +DROP EXTENSION test_ext_req_schema2;=0A= diff --git a/src/test/modules/test_extensions/meson.build = b/src/test/modules/test_extensions/meson.build=0A= index 45597ddc23..7519f6e28e 100644=0A= --- a/src/test/modules/test_extensions/meson.build=0A= +++ b/src/test/modules/test_extensions/meson.build=0A= @@ -31,6 +31,13 @@ install_data(=0A= 'test_ext_evttrig--1.0--2.0.sql',=0A= 'test_ext_evttrig--1.0.sql',=0A= 'test_ext_evttrig.control',=0A= + 'test_ext_req_schema1--1.0.sql',=0A= + 'test_ext_req_schema1.control',=0A= + 'test_ext_req_schema2--1.0.sql',=0A= + 'test_ext_req_schema2.control',=0A= + 'test_ext_req_schema2--1.0--2.0.sql',=0A= + 'test_ext_req_schema3.control',=0A= + 'test_ext_req_schema3--1.0.sql',=0A= kwargs: contrib_data_args,=0A= )=0A= =0A= diff --git a/src/test/modules/test_extensions/sql/test_extensions.sql = b/src/test/modules/test_extensions/sql/test_extensions.sql=0A= index 41b6cddf0b..81ecd13736 100644=0A= --- a/src/test/modules/test_extensions/sql/test_extensions.sql=0A= +++ b/src/test/modules/test_extensions/sql/test_extensions.sql=0A= @@ -209,3 +209,17 @@ CREATE EXTENSION test_ext_cine;=0A= ALTER EXTENSION test_ext_cine UPDATE TO '1.1';=0A= =0A= \dx+ test_ext_cine=0A= +=0A= +CREATE SCHEMA test_s_dep;=0A= +CREATE EXTENSION test_ext_req_schema1 SCHEMA test_s_dep;=0A= +CREATE EXTENSION test_ext_req_schema3 CASCADE;=0A= +SELECT dep_req();=0A= +SELECT dep_req2();=0A= +SELECT dep_req3();=0A= +ALTER EXTENSION test_ext_req_schema2 UPDATE TO '2.0';=0A= +CREATE SCHEMA test_s_dep2;=0A= +ALTER EXTENSION test_ext_req_schema1 SET SCHEMA test_s_dep2;=0A= +SELECT dep_req();=0A= +DROP EXTENSION test_ext_req_schema1;=0A= +DROP EXTENSION test_ext_req_schema3;=0A= +DROP EXTENSION test_ext_req_schema2;=0A= \ No newline at end of file=0A= diff --git = a/src/test/modules/test_extensions/test_ext_req_schema1--1.0.sql = b/src/test/modules/test_extensions/test_ext_req_schema1--1.0.sql=0A= new file mode 100644=0A= index 0000000000..462fb52145=0A= --- /dev/null=0A= +++ b/src/test/modules/test_extensions/test_ext_req_schema1--1.0.sql=0A= @@ -0,0 +1,6 @@=0A= +/* src/test/modules/test_extensions/test_ext_req_schema1--1.0.sql */=0A= +-- complain if script is sourced in psql, rather than via CREATE = EXTENSION=0A= +\echo Use "CREATE EXTENSION test_ext_req_schema1" to load this file. = \quit=0A= +=0A= +CREATE DOMAIN req AS text=0A= + CONSTRAINT starts_with_1 check(pg_catalog.left(value,1) = OPERATOR(pg_catalog.=3D) '1');=0A= diff --git = a/src/test/modules/test_extensions/test_ext_req_schema1.control = b/src/test/modules/test_extensions/test_ext_req_schema1.control=0A= new file mode 100644=0A= index 0000000000..9ea4558a90=0A= --- /dev/null=0A= +++ b/src/test/modules/test_extensions/test_ext_req_schema1.control=0A= @@ -0,0 +1,3 @@=0A= +comment =3D 'Create required extension to be referenced'=0A= +default_version =3D '1.0'=0A= +relocatable =3D true=0A= diff --git = a/src/test/modules/test_extensions/test_ext_req_schema2--1.0--2.0.sql = b/src/test/modules/test_extensions/test_ext_req_schema2--1.0--2.0.sql=0A= new file mode 100644=0A= index 0000000000..73a44a25e5=0A= --- /dev/null=0A= +++ b/src/test/modules/test_extensions/test_ext_req_schema2--1.0--2.0.sql=0A= @@ -0,0 +1,7 @@=0A= +/* src/test/modules/test_extensions/test_ext_req_schema2--1.0.sql */=0A= +-- complain if script is sourced in psql, rather than via CREATE = EXTENSION=0A= +\echo Use "CREATE EXTENSION test_ext_req_schema2" to load this file. = \quit=0A= +=0A= +CREATE OR REPLACE FUNCTION dep_req() RETURNS = @extschema:test_ext_req_schema1@.req=0A= +LANGUAGE SQL IMMUTABLE PARALLEL SAFE=0A= +AS 'SELECT ''1update''::@extschema:test_ext_req_schema1@.req';=0A= diff --git = a/src/test/modules/test_extensions/test_ext_req_schema2--1.0.sql = b/src/test/modules/test_extensions/test_ext_req_schema2--1.0.sql=0A= new file mode 100644=0A= index 0000000000..9fe25d48a1=0A= --- /dev/null=0A= +++ b/src/test/modules/test_extensions/test_ext_req_schema2--1.0.sql=0A= @@ -0,0 +1,9 @@=0A= +/* src/test/modules/test_extensions/test_ext_req_schema2--1.0.sql */=0A= +-- complain if script is sourced in psql, rather than via CREATE = EXTENSION=0A= +\echo Use "CREATE EXTENSION test_ext_req_schema2" to load this file. = \quit=0A= +CREATE DOMAIN dreq AS text=0A= + CONSTRAINT starts_with_2 check(pg_catalog.left(value,1) = OPERATOR(pg_catalog.=3D) '2');=0A= +=0A= +CREATE FUNCTION dep_req() RETURNS @extschema:test_ext_req_schema1@.req=0A= +LANGUAGE SQL IMMUTABLE PARALLEL SAFE=0A= +AS 'SELECT ''1032w''::@extschema:test_ext_req_schema1@.req';=0A= diff --git = a/src/test/modules/test_extensions/test_ext_req_schema2.control = b/src/test/modules/test_extensions/test_ext_req_schema2.control=0A= new file mode 100644=0A= index 0000000000..d2ba5add97=0A= --- /dev/null=0A= +++ b/src/test/modules/test_extensions/test_ext_req_schema2.control=0A= @@ -0,0 +1,4 @@=0A= +comment =3D 'Test schema referencing of required extensions'=0A= +default_version =3D '1.0'=0A= +relocatable =3D true=0A= +requires =3D 'test_ext_req_schema1'=0A= diff --git = a/src/test/modules/test_extensions/test_ext_req_schema3--1.0.sql = b/src/test/modules/test_extensions/test_ext_req_schema3--1.0.sql=0A= new file mode 100644=0A= index 0000000000..bd05669097=0A= --- /dev/null=0A= +++ b/src/test/modules/test_extensions/test_ext_req_schema3--1.0.sql=0A= @@ -0,0 +1,13 @@=0A= +/* src/test/modules/test_extensions/test_ext_req_schema2--1.0.sql */=0A= +-- complain if script is sourced in psql, rather than via CREATE = EXTENSION=0A= +\echo Use "CREATE EXTENSION test_ext_req_schema2" to load this file. = \quit=0A= +CREATE DOMAIN req2 AS text=0A= + CONSTRAINT starts_with_2 check(pg_catalog.left(value,1) = OPERATOR(pg_catalog.=3D) '2');=0A= +=0A= +CREATE FUNCTION dep_req2() RETURNS @extschema:test_ext_req_schema1@.req=0A= +LANGUAGE SQL IMMUTABLE PARALLEL SAFE=0A= +AS 'SELECT ''1032w''::@extschema:test_ext_req_schema1@.req';=0A= +=0A= +CREATE FUNCTION dep_req3() RETURNS @extschema:test_ext_req_schema2@.dreq=0A= +LANGUAGE SQL IMMUTABLE PARALLEL SAFE=0A= +AS 'SELECT ''2032w''::@extschema:test_ext_req_schema2@.dreq';=0A= diff --git = a/src/test/modules/test_extensions/test_ext_req_schema3.control = b/src/test/modules/test_extensions/test_ext_req_schema3.control=0A= new file mode 100644=0A= index 0000000000..b052fad785=0A= --- /dev/null=0A= +++ b/src/test/modules/test_extensions/test_ext_req_schema3.control=0A= @@ -0,0 +1,4 @@=0A= +comment =3D 'Test schema referencing of 2 required extensions'=0A= +default_version =3D '1.0'=0A= +relocatable =3D true=0A= +requires =3D 'test_ext_req_schema1,test_ext_req_schema2'=0A= -- =0A= 2.21.0.windows.1=0A= =0A= ------=_NextPart_000_0001_01D94983.2883F3E0--