From: Alvaro Herrera <alvherre@2ndquadrant.com>
To: Pg Hackers <pgsql-hackers@lists.postgresql.org>
Subject: Re: more ALTER .. DEPENDS ON EXTENSION fixes
Date: Mon, 17 Feb 2020 20:56:03 -0300
Message-ID: <20200217235603.GA32740@alvherre.pgsql> (raw)
In-Reply-To: <20200217225333.GA30974@alvherre.pgsql>
On 2020-Feb-17, Alvaro Herrera wrote:
> * More than one 'x' dependencies are allowed for the same object on the
> same extension. That's useless and polluting, so should be prevented.
>
> * There's no way to remove an 'x' dependency.
Here's these two patches. There's an "if (true)" in 0002 which is a
little weird -- that's there just to avoid reindenting those lines in
0003.
In principle, I would think that these are all backpatchable bugfixes.
Maybe 0002 could pass as not backpatchable since it disallows a command
that works today. OTOH the feature is rarely used, so maybe a backpatch
is not welcome anyhow.
--
Álvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Attachments:download all (2 files, .tar.gz)0002-Avoid-duplicates-in-ALTER-.-DEPENDS-ON-EXTENSION.patch (text/x-diff, 3.4K) download
From 586899b994e45a2b2bf217a25198ba4bdbc6ee82 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Mon, 17 Feb 2020 19:42:57 -0300
Subject: [PATCH 2/3] Avoid duplicates in ALTER ... DEPENDS ON EXTENSION
If the command is attempted on an extension that the object already
depends on, raise an error.
---
src/backend/catalog/pg_depend.c | 43 ++++++++++++++++++++++++++++++++
src/backend/commands/alter.c | 17 ++++++++++++-
src/include/catalog/dependency.h | 1 +
3 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.cindex f9af245eec..596dafe19c 100644--- a/src/backend/catalog/pg_depend.c+++ b/src/backend/catalog/pg_depend.c@@ -648,6 +648,49 @@ getExtensionOfObject(Oid classId, Oid objectId)
return result;
}
+/*+ * Return (possibly NIL) list of extensions that the given object depends on+ * in DEPENDENCY_AUTO_EXTENSION mode.+ */+List *+getAutoExtensionsOfObject(Oid classId, Oid objectId)+{+ List *result = NIL;+ Relation depRel;+ ScanKeyData key[2];+ SysScanDesc scan;+ HeapTuple tup;++ depRel = table_open(DependRelationId, AccessShareLock);++ ScanKeyInit(&key[0],+ Anum_pg_depend_classid,+ BTEqualStrategyNumber, F_OIDEQ,+ ObjectIdGetDatum(classId));+ ScanKeyInit(&key[1],+ Anum_pg_depend_objid,+ BTEqualStrategyNumber, F_OIDEQ,+ ObjectIdGetDatum(objectId));++ scan = systable_beginscan(depRel, DependDependerIndexId, true,+ NULL, 2, key);++ while (HeapTupleIsValid((tup = systable_getnext(scan))))+ {+ Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);++ if (depform->refclassid == ExtensionRelationId &&+ depform->deptype == DEPENDENCY_AUTO_EXTENSION)+ result = lappend_oid(result, depform->refobjid);+ }++ systable_endscan(scan);++ table_close(depRel, AccessShareLock);++ return result;+}+
/*
* Detect whether a sequence is marked as "owned" by a column
*
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.cindex 1cb84182b0..28e32f2fb5 100644--- a/src/backend/commands/alter.c+++ b/src/backend/commands/alter.c@@ -462,7 +462,22 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre
if (refAddress)
*refAddress = refAddr;
- recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION);+ if (true)+ {+ List *currexts;++ /* Avoid duplicates */+ currexts = getAutoExtensionsOfObject(address.classId,+ address.objectId);+ if (list_member_oid(currexts, refAddr.objectId))+ ereport(ERROR,+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),+ errmsg("%s already depends on extension \"%s\"",+ getObjectDescription(&address),+ get_extension_name(refAddr.objectId))));++ recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION);+ }
return address;
}
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.hindex 0cd6fcf027..ab5e92bdc6 100644--- a/src/include/catalog/dependency.h+++ b/src/include/catalog/dependency.h@@ -207,6 +207,7 @@ extern long changeDependenciesOn(Oid refClassId, Oid oldRefObjectId,
Oid newRefObjectId);
extern Oid getExtensionOfObject(Oid classId, Oid objectId);
+extern List *getAutoExtensionsOfObject(Oid classId, Oid objectId);
extern bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId);
extern List *getOwnedSequences(Oid relid);
--
2.20.1
0003-Add-ALTER-.-NO-DEPENDS-ON.patch (text/x-diff, 18.2K) download
From 540941aa2d8a3bd84518dbd49600dc013771c275 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Wed, 30 Oct 2019 16:57:29 -0300
Subject: [PATCH 3/3] Add ALTER .. NO DEPENDS ON
This new command removes any previously added dependency mark; necessary
for completeness.
---
doc/src/sgml/ref/alter_function.sgml | 10 ++--
doc/src/sgml/ref/alter_index.sgml | 9 ++--
doc/src/sgml/ref/alter_materialized_view.sgml | 11 ++---
doc/src/sgml/ref/alter_trigger.sgml | 7 ++-
src/backend/catalog/pg_depend.c | 49 +++++++++++++++++++
src/backend/commands/alter.c | 17 ++++++-
src/backend/nodes/copyfuncs.c | 1 +
src/backend/nodes/equalfuncs.c | 1 +
src/backend/parser/gram.y | 36 +++++++++-----
src/include/catalog/dependency.h | 4 ++
src/include/nodes/parsenodes.h | 1 +
.../expected/test_extdepend.out | 39 ++++++++++++++-
.../test_extensions/sql/test_extdepend.sql | 18 ++++++-
13 files changed, 169 insertions(+), 34 deletions(-)
diff --git a/doc/src/sgml/ref/alter_function.sgml b/doc/src/sgml/ref/alter_function.sgmlindex 03ffa5945a..70b1f24bc0 100644--- a/doc/src/sgml/ref/alter_function.sgml+++ b/doc/src/sgml/ref/alter_function.sgml@@ -30,7 +30,7 @@ ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="param
ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
SET SCHEMA <replaceable>new_schema</replaceable>
ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
- DEPENDS ON EXTENSION <replaceable>extension_name</replaceable>+ [ NO ] DEPENDS ON EXTENSION <replaceable>extension_name</replaceable>
<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
@@ -153,10 +153,14 @@ ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="param
</varlistentry>
<varlistentry>
- <term><replaceable class="parameter">extension_name</replaceable></term>+ <term><literal>DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable></literal></term>+ <term><literal>NO DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable></literal></term>
<listitem>
<para>
- The name of the extension that the function is to depend on.+ This form marks the function as dependent on the extension, or no longer+ dependent on that extension if <literal>NO</literal> is specified.+ A function that's marked as dependent on an extension is automatically+ dropped when the extension is dropped.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/alter_index.sgml b/doc/src/sgml/ref/alter_index.sgmlindex 6d34dbb74e..de6f89d458 100644--- a/doc/src/sgml/ref/alter_index.sgml+++ b/doc/src/sgml/ref/alter_index.sgml@@ -100,11 +100,14 @@ ALTER INDEX ALL IN TABLESPACE <replaceable class="parameter">name</replaceable>
</varlistentry>
<varlistentry>
- <term><literal>DEPENDS ON EXTENSION</literal></term>+ <term><literal>DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable></literal></term>+ <term><literal>NO DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable></literal></term>
<listitem>
<para>
- This form marks the index as dependent on the extension, such that if the- extension is dropped, the index will automatically be dropped as well.+ This form marks the index as dependent on the extension, or no longer+ dependent on that extension if <literal>NO</literal> is specified.+ An index that's marked as dependent on an extension is automatically+ dropped when the extension is dropped.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/alter_materialized_view.sgml b/doc/src/sgml/ref/alter_materialized_view.sgmlindex 03e3df1ffd..9df8a79977 100644--- a/doc/src/sgml/ref/alter_materialized_view.sgml+++ b/doc/src/sgml/ref/alter_materialized_view.sgml@@ -68,12 +68,6 @@ ALTER MATERIALIZED VIEW ALL IN TABLESPACE <replaceable class="parameter">name</r
anyway.)
</para>
- <para>- The <literal>DEPENDS ON EXTENSION</literal> form marks the materialized view- as dependent on an extension, such that the materialized view will- automatically be dropped if the extension is dropped.- </para>-
<para>
The statement subforms and actions available for
<command>ALTER MATERIALIZED VIEW</command> are a subset of those available
@@ -110,7 +104,10 @@ ALTER MATERIALIZED VIEW ALL IN TABLESPACE <replaceable class="parameter">name</r
<term><replaceable class="parameter">extension_name</replaceable></term>
<listitem>
<para>
- The name of the extension that the materialized view is to depend on.+ The name of the extension that the materialized view is to depend on (or no longer+ dependent on, if <literal>NO</literal> is specified). A materialized view+ that's marked as dependent on an extension is automatically dropped when+ the extension is dropped.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/alter_trigger.sgml b/doc/src/sgml/ref/alter_trigger.sgmlindex 6cf789a67a..6d4784c82f 100644--- a/doc/src/sgml/ref/alter_trigger.sgml+++ b/doc/src/sgml/ref/alter_trigger.sgml@@ -22,7 +22,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
ALTER TRIGGER <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
-ALTER TRIGGER <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable>+ALTER TRIGGER <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> [ NO ] DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable>
</synopsis>
</refsynopsisdiv>
@@ -78,7 +78,10 @@ ALTER TRIGGER <replaceable class="parameter">name</replaceable> ON <replaceable
<term><replaceable class="parameter">extension_name</replaceable></term>
<listitem>
<para>
- The name of the extension that the trigger is to depend on.+ The name of the extension that the trigger is to depend on (or no longer+ dependent on, if <literal>NO</literal> is specified). A trigger+ that's marked as dependent on an extension is automatically dropped when+ the extension is dropped.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.cindex 596dafe19c..fa38ee9477 100644--- a/src/backend/catalog/pg_depend.c+++ b/src/backend/catalog/pg_depend.c@@ -278,6 +278,55 @@ deleteDependencyRecordsForClass(Oid classId, Oid objectId,
return count;
}
+/*+ * deleteDependencyRecordsForSpecific -- delete all records with given depender+ * classId/objectId, dependee classId/objectId, of the given deptype.+ * Returns the number of records deleted.+ */+long+deleteDependencyRecordsForSpecific(Oid classId, Oid objectId, char deptype,+ Oid refclassId, Oid refobjectId)+{+ long count = 0;+ Relation depRel;+ ScanKeyData key[2];+ SysScanDesc scan;+ HeapTuple tup;++ depRel = table_open(DependRelationId, RowExclusiveLock);++ ScanKeyInit(&key[0],+ Anum_pg_depend_classid,+ BTEqualStrategyNumber, F_OIDEQ,+ ObjectIdGetDatum(classId));+ ScanKeyInit(&key[1],+ Anum_pg_depend_objid,+ BTEqualStrategyNumber, F_OIDEQ,+ ObjectIdGetDatum(objectId));++ scan = systable_beginscan(depRel, DependDependerIndexId, true,+ NULL, 2, key);++ while (HeapTupleIsValid(tup = systable_getnext(scan)))+ {+ Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);++ if (depform->refclassid == refclassId &&+ depform->refobjid == refobjectId &&+ depform->deptype == deptype)+ {+ CatalogTupleDelete(depRel, &tup->t_self);+ count++;+ }+ }++ systable_endscan(scan);++ table_close(depRel, RowExclusiveLock);++ return count;+}+
/*
* Adjust dependency record(s) to point to a different object of the same type
*
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.cindex 28e32f2fb5..4a98e11efe 100644--- a/src/backend/commands/alter.c+++ b/src/backend/commands/alter.c@@ -421,7 +421,7 @@ ExecRenameStmt(RenameStmt *stmt)
}
/*
- * Executes an ALTER OBJECT / DEPENDS ON [EXTENSION] statement.+ * Executes an ALTER OBJECT / [NO] DEPENDS ON EXTENSION statement.
*
* Return value is the address of the altered object. refAddress is an output
* argument which, if not null, receives the address of the object that the
@@ -462,10 +462,23 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre
if (refAddress)
*refAddress = refAddr;
- if (true)+ if (stmt->remove)+ deleteDependencyRecordsForSpecific(address.classId, address.objectId,+ DEPENDENCY_AUTO_EXTENSION,+ refAddr.classId, refAddr.objectId);+ else
{
+ Oid currextoid;
List *currexts;
+ /* Fail if object is part of an extension */+ currextoid = getExtensionOfObject(address.classId, address.objectId);+ if (OidIsValid(currextoid))+ ereport(ERROR,+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),+ errmsg("%s is already part of extension \"%s\"",+ getObjectDescription(&address),+ get_extension_name(currextoid))));
/* Avoid duplicates */
currexts = getAutoExtensionsOfObject(address.classId,
address.objectId);
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.cindex 54ad62bb7f..851e0b0c4a 100644--- a/src/backend/nodes/copyfuncs.c+++ b/src/backend/nodes/copyfuncs.c@@ -3593,6 +3593,7 @@ _copyAlterObjectDependsStmt(const AlterObjectDependsStmt *from)
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(object);
COPY_NODE_FIELD(extname);
+ COPY_SCALAR_FIELD(remove);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.cindex 5b1ba143b1..8c734045a8 100644--- a/src/backend/nodes/equalfuncs.c+++ b/src/backend/nodes/equalfuncs.c@@ -1445,6 +1445,7 @@ _equalAlterObjectDependsStmt(const AlterObjectDependsStmt *a, const AlterObjectD
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(object);
COMPARE_NODE_FIELD(extname);
+ COMPARE_SCALAR_FIELD(remove);
return true;
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.yindex 1b0edf5d3d..d99156194d 100644--- a/src/backend/parser/gram.y+++ b/src/backend/parser/gram.y@@ -311,7 +311,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <list> vac_analyze_option_list
%type <node> vac_analyze_option_arg
%type <defelt> drop_option
-%type <boolean> opt_or_replace+%type <boolean> opt_or_replace opt_no
opt_grant_grant_option opt_grant_admin_option
opt_nowait opt_if_exists opt_with_data
opt_transaction_chain
@@ -9024,57 +9024,67 @@ opt_set_data: SET DATA_P { $$ = 1; }
*****************************************************************************/
AlterObjectDependsStmt:
- ALTER FUNCTION function_with_argtypes DEPENDS ON EXTENSION name+ ALTER FUNCTION function_with_argtypes opt_no DEPENDS ON EXTENSION name
{
AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
n->objectType = OBJECT_FUNCTION;
n->object = (Node *) $3;
- n->extname = makeString($7);+ n->extname = makeString($8);+ n->remove = $4;
$$ = (Node *)n;
}
- | ALTER PROCEDURE function_with_argtypes DEPENDS ON EXTENSION name+ | ALTER PROCEDURE function_with_argtypes opt_no DEPENDS ON EXTENSION name
{
AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
n->objectType = OBJECT_PROCEDURE;
n->object = (Node *) $3;
- n->extname = makeString($7);+ n->extname = makeString($8);+ n->remove = $4;
$$ = (Node *)n;
}
- | ALTER ROUTINE function_with_argtypes DEPENDS ON EXTENSION name+ | ALTER ROUTINE function_with_argtypes opt_no DEPENDS ON EXTENSION name
{
AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
n->objectType = OBJECT_ROUTINE;
n->object = (Node *) $3;
- n->extname = makeString($7);+ n->extname = makeString($8);+ n->remove = $4;
$$ = (Node *)n;
}
- | ALTER TRIGGER name ON qualified_name DEPENDS ON EXTENSION name+ | ALTER TRIGGER name ON qualified_name opt_no DEPENDS ON EXTENSION name
{
AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
n->objectType = OBJECT_TRIGGER;
n->relation = $5;
n->object = (Node *) list_make1(makeString($3));
- n->extname = makeString($9);+ n->extname = makeString($10);+ n->remove = $6;
$$ = (Node *)n;
}
- | ALTER MATERIALIZED VIEW qualified_name DEPENDS ON EXTENSION name+ | ALTER MATERIALIZED VIEW qualified_name opt_no DEPENDS ON EXTENSION name
{
AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
n->objectType = OBJECT_MATVIEW;
n->relation = $4;
- n->extname = makeString($8);+ n->extname = makeString($9);+ n->remove = $5;
$$ = (Node *)n;
}
- | ALTER INDEX qualified_name DEPENDS ON EXTENSION name+ | ALTER INDEX qualified_name opt_no DEPENDS ON EXTENSION name
{
AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
n->objectType = OBJECT_INDEX;
n->relation = $3;
- n->extname = makeString($7);+ n->extname = makeString($8);+ n->remove = $4;
$$ = (Node *)n;
}
;
+opt_no: NO { $$ = true; }+ | /* EMPTY */ { $$ = false; }+ ;+
/*****************************************************************************
*
* ALTER THING name SET SCHEMA name
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.hindex ab5e92bdc6..2c6abe26a5 100644--- a/src/include/catalog/dependency.h+++ b/src/include/catalog/dependency.h@@ -196,6 +196,10 @@ extern long deleteDependencyRecordsFor(Oid classId, Oid objectId,
extern long deleteDependencyRecordsForClass(Oid classId, Oid objectId,
Oid refclassId, char deptype);
+extern long deleteDependencyRecordsForSpecific(Oid classId, Oid objectId,+ char deptype,+ Oid refclassId, Oid refobjectId);+
extern long changeDependencyFor(Oid classId, Oid objectId,
Oid refClassId, Oid oldRefObjectId,
Oid newRefObjectId);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.hindex da0706add5..dad344f137 100644--- a/src/include/nodes/parsenodes.h+++ b/src/include/nodes/parsenodes.h@@ -2930,6 +2930,7 @@ typedef struct AlterObjectDependsStmt
RangeVar *relation; /* in case a table is involved */
Node *object; /* name of the object */
Value *extname; /* extension name */
+ bool remove; /* set true to remove dep rather than add */
} AlterObjectDependsStmt;
/* ----------------------
diff --git a/src/test/modules/test_extensions/expected/test_extdepend.out b/src/test/modules/test_extensions/expected/test_extdepend.outindex 11e441ddd3..7bb1d8f362 100644--- a/src/test/modules/test_extensions/expected/test_extdepend.out+++ b/src/test/modules/test_extensions/expected/test_extdepend.out@@ -147,6 +147,41 @@ SELECT deptype, i.*
---------+------+--------+------+----------
(0 rows)
-DROP TABLE a;+RESET search_path;
DROP SCHEMA test_ext CASCADE;
-NOTICE: drop cascades to extension test_ext5+NOTICE: drop cascades to 2 other objects+DETAIL: drop cascades to extension test_ext5+drop cascades to table test_ext.a+-- Fourth test: we can mark the objects as dependent, then unmark; then the+-- drop of the extension does nothing+SELECT * FROM test_extdep_commands \gexec+ CREATE SCHEMA test_ext+ CREATE EXTENSION test_ext5 SCHEMA test_ext+ SET search_path TO test_ext+ CREATE TABLE a (a1 int)++ CREATE FUNCTION b() RETURNS TRIGGER LANGUAGE plpgsql AS+ $$ BEGIN NEW.a1 := NEW.a1 + 42; RETURN NEW; END; $$+ ALTER FUNCTION b() DEPENDS ON EXTENSION test_ext5++ CREATE TRIGGER c BEFORE INSERT ON a FOR EACH ROW EXECUTE PROCEDURE b()+ ALTER TRIGGER c ON a DEPENDS ON EXTENSION test_ext5++ CREATE MATERIALIZED VIEW d AS SELECT * FROM a+ ALTER MATERIALIZED VIEW d DEPENDS ON EXTENSION test_ext5++ CREATE INDEX e ON a (a1)+ ALTER INDEX e DEPENDS ON EXTENSION test_ext5+ RESET search_path+SET search_path TO test_ext;+ALTER FUNCTION b() NO DEPENDS ON EXTENSION test_ext5;+ALTER TRIGGER c ON a NO DEPENDS ON EXTENSION test_ext5;+ALTER MATERIALIZED VIEW d NO DEPENDS ON EXTENSION test_ext5;+ALTER INDEX e NO DEPENDS ON EXTENSION test_ext5;+DROP EXTENSION test_ext5;+DROP TRIGGER c ON a;+DROP FUNCTION b();+DROP MATERIALIZED VIEW d;+DROP INDEX e;+DROP SCHEMA test_ext CASCADE;+NOTICE: drop cascades to table adiff --git a/src/test/modules/test_extensions/sql/test_extdepend.sql b/src/test/modules/test_extensions/sql/test_extdepend.sqlindex cf44145dcb..b709d71e96 100644--- a/src/test/modules/test_extensions/sql/test_extdepend.sql+++ b/src/test/modules/test_extensions/sql/test_extdepend.sql@@ -68,6 +68,20 @@ SELECT deptype, i.*
refobjid=(SELECT oid FROM pg_extension WHERE extname='test_ext5'))
OR (refclassid='pg_class'::regclass AND refobjid='test_ext.a'::regclass)
AND NOT deptype IN ('i', 'a');
--DROP TABLE a;+RESET search_path;+DROP SCHEMA test_ext CASCADE;++-- Fourth test: we can mark the objects as dependent, then unmark; then the+-- drop of the extension does nothing+SELECT * FROM test_extdep_commands \gexec+SET search_path TO test_ext;+ALTER FUNCTION b() NO DEPENDS ON EXTENSION test_ext5;+ALTER TRIGGER c ON a NO DEPENDS ON EXTENSION test_ext5;+ALTER MATERIALIZED VIEW d NO DEPENDS ON EXTENSION test_ext5;+ALTER INDEX e NO DEPENDS ON EXTENSION test_ext5;+DROP EXTENSION test_ext5;+DROP TRIGGER c ON a;+DROP FUNCTION b();+DROP MATERIALIZED VIEW d;+DROP INDEX e;
DROP SCHEMA test_ext CASCADE;
--
2.20.1
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: alvherre@2ndquadrant.com, pgsql-hackers@lists.postgresql.org
Subject: Re: more ALTER .. DEPENDS ON EXTENSION fixes
In-Reply-To: <20200217235603.GA32740@alvherre.pgsql>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox