At 2016-01-18 11:08:19 +0530, a...@2ndquadrant.com wrote:
>
> I'm proposing to address a part of that problem by allowing extension
> dependencies to be explicitly declared for functions and objects
> created either by a user or dynamically by the extension itself—things
> that need the extension to function, but aren't a part of it.

I didn't hear any further suggestions, so here's a patch for discussion.

1. This adds the 'x'/DEPENDENCY_AUTO_EXTENSION type.
2. This adds an 'ALTER FUNCTION … ADD DEPENDENT FUNCTION …' command.

I split up the two because we may want the new dependency type without
going to the trouble of adding a new command. Maybe extension authors
should just insert an 'x' row into pg_depend directly?

I was inclined to implement it using ALTER FUNCTION, but AlterFunction()
is focused on altering the pg_proc entry for a function, so the new code
didn't fit. Ultimately, ExecAlterExtensionContentsStmt() was the closest
match, so that's where I did it.

Comments welcome. I'll add this patch to the CF.

-- Abhijit
>From 9835f0990a015431393d608c8710d9effe301c9d Mon Sep 17 00:00:00 2001
From: Abhijit Menon-Sen <a...@2ndquadrant.com>
Date: Tue, 1 Mar 2016 06:44:28 +0530
Subject: Add a DEPENDENCY_AUTO_EXTENSION dependency type

This is useful for functions that require the extension to operate, but
do not belong to the extension per se and, in particular, should not be
ignored by pg_dump.
---
 doc/src/sgml/catalogs.sgml       | 13 +++++++++++++
 src/backend/catalog/dependency.c |  2 ++
 src/include/catalog/dependency.h |  9 ++++++++-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 951f59b..189b771 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -2864,6 +2864,19 @@
       </para>
      </listitem>
     </varlistentry>
+
+    <varlistentry>
+     <term><symbol>DEPENDENCY_AUTO_EXTENSION</> (<literal>x</>)</term>
+     <listitem>
+      <para>
+       The dependent object is not a member of the extension that is the
+       referenced object (and so should not be ignored by pg_dump), but
+       cannot function without it and should be dropped when the
+       extension itself is. The dependent object may be dropped on its
+       own as well.
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
 
    Other dependency flavors might be needed in future.
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index c48e37b..a284bed 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -587,6 +587,7 @@ findDependentObjects(const ObjectAddress *object,
 		{
 			case DEPENDENCY_NORMAL:
 			case DEPENDENCY_AUTO:
+			case DEPENDENCY_AUTO_EXTENSION:
 				/* no problem */
 				break;
 			case DEPENDENCY_INTERNAL:
@@ -786,6 +787,7 @@ findDependentObjects(const ObjectAddress *object,
 				subflags = DEPFLAG_NORMAL;
 				break;
 			case DEPENDENCY_AUTO:
+			case DEPENDENCY_AUTO_EXTENSION:
 				subflags = DEPFLAG_AUTO;
 				break;
 			case DEPENDENCY_INTERNAL:
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 049bf9f..380f74a 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -61,6 +61,12 @@
  * created only during initdb.  The fields for the dependent object
  * contain zeroes.
  *
+ * DEPENDENCY_AUTO_EXTENSION ('x'): the dependent object is not a member
+ * of the extension that is the referenced object (and so should not be
+ * ignored by pg_dump), but cannot function without it and should be
+ * dropped when the extension itself is. The dependent object may be
+ * dropped on its own as well.
+ *
  * Other dependency flavors may be needed in future.
  */
 
@@ -70,7 +76,8 @@ typedef enum DependencyType
 	DEPENDENCY_AUTO = 'a',
 	DEPENDENCY_INTERNAL = 'i',
 	DEPENDENCY_EXTENSION = 'e',
-	DEPENDENCY_PIN = 'p'
+	DEPENDENCY_PIN = 'p',
+	DEPENDENCY_AUTO_EXTENSION = 'x'
 } DependencyType;
 
 /*
-- 
2.1.4

>From f06f59e8f7f25406510178fbf62b59dcfd59428c Mon Sep 17 00:00:00 2001
From: Abhijit Menon-Sen <a...@2ndquadrant.com>
Date: Tue, 1 Mar 2016 06:46:11 +0530
Subject: =?UTF-8?q?Add=20experimental=20'ALTER=20EXTENSION=20=E2=80=A6=20A?=
 =?UTF-8?q?DD=20DEPENDENT=20FUNCTION=20=E2=80=A6'=20command?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This uses the new 'x' dependency type.
---
 src/backend/commands/extension.c |  7 +++++--
 src/backend/nodes/copyfuncs.c    |  1 +
 src/backend/nodes/equalfuncs.c   |  1 +
 src/backend/parser/gram.y        | 39 ++++++++++++++++++++++++++++++++++++++-
 src/include/nodes/parsenodes.h   |  1 +
 src/include/parser/kwlist.h      |  1 +
 6 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 9d84b79..c33dca6 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -2985,6 +2985,7 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt,
 	ObjectAddress object;
 	Relation	relation;
 	Oid			oldExtension;
+	DependencyType deptype;
 
 	extension.classId = ExtensionRelationId;
 	extension.objectId = get_extension_oid(stmt->extname, false);
@@ -3017,6 +3018,8 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt,
 	 */
 	oldExtension = getExtensionOfObject(object.classId, object.objectId);
 
+	deptype = stmt->deptype;
+
 	if (stmt->action > 0)
 	{
 		/*
@@ -3045,7 +3048,7 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt,
 		/*
 		 * OK, add the dependency.
 		 */
-		recordDependencyOn(&object, &extension, DEPENDENCY_EXTENSION);
+		recordDependencyOn(&object, &extension, deptype);
 	}
 	else
 	{
@@ -3064,7 +3067,7 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt,
 		 */
 		if (deleteDependencyRecordsForClass(object.classId, object.objectId,
 											ExtensionRelationId,
-											DEPENDENCY_EXTENSION) != 1)
+											deptype) != 1)
 			elog(ERROR, "unexpected number of extension dependency records");
 
 		/*
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index a9e9cc3..43fc249 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3695,6 +3695,7 @@ _copyAlterExtensionContentsStmt(const AlterExtensionContentsStmt *from)
 	COPY_SCALAR_FIELD(objtype);
 	COPY_NODE_FIELD(objname);
 	COPY_NODE_FIELD(objargs);
+	COPY_SCALAR_FIELD(deptype);
 
 	return newnode;
 }
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index b9c3959..50646bd 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1740,6 +1740,7 @@ _equalAlterExtensionContentsStmt(const AlterExtensionContentsStmt *a, const Alte
 	COMPARE_SCALAR_FIELD(objtype);
 	COMPARE_NODE_FIELD(objname);
 	COMPARE_NODE_FIELD(objargs);
+	COMPARE_SCALAR_FIELD(deptype);
 
 	return true;
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b307b48..4a887d0 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -577,7 +577,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 	CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
 
 	DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
-	DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC
+	DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDENT DESC
 	DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
 
 	EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EVENT EXCEPT
@@ -3935,6 +3935,7 @@ AlterExtensionContentsStmt:
 					n->objtype = OBJECT_AGGREGATE;
 					n->objname = $6;
 					n->objargs = extractAggrArgTypes($7);
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop CAST '(' Typename AS Typename ')'
@@ -3945,6 +3946,7 @@ AlterExtensionContentsStmt:
 					n->objtype = OBJECT_CAST;
 					n->objname = list_make1($7);
 					n->objargs = list_make1($9);
+					n->deptype = 'e';
 					$$ = (Node *) n;
 				}
 			| ALTER EXTENSION name add_drop COLLATION any_name
@@ -3954,6 +3956,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_COLLATION;
 					n->objname = $6;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop CONVERSION_P any_name
@@ -3963,6 +3966,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_CONVERSION;
 					n->objname = $6;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop DOMAIN_P Typename
@@ -3972,6 +3976,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_DOMAIN;
 					n->objname = list_make1($6);
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop FUNCTION function_with_argtypes
@@ -3982,6 +3987,7 @@ AlterExtensionContentsStmt:
 					n->objtype = OBJECT_FUNCTION;
 					n->objname = $6->funcname;
 					n->objargs = $6->funcargs;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop opt_procedural LANGUAGE name
@@ -3991,6 +3997,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_LANGUAGE;
 					n->objname = list_make1(makeString($7));
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop OPERATOR any_operator oper_argtypes
@@ -4001,6 +4008,7 @@ AlterExtensionContentsStmt:
 					n->objtype = OBJECT_OPERATOR;
 					n->objname = $6;
 					n->objargs = $7;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING access_method
@@ -4010,6 +4018,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_OPCLASS;
 					n->objname = lcons(makeString($9), $7);
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING access_method
@@ -4019,6 +4028,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_OPFAMILY;
 					n->objname = lcons(makeString($9), $7);
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop SCHEMA name
@@ -4028,6 +4038,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_SCHEMA;
 					n->objname = list_make1(makeString($6));
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop EVENT TRIGGER name
@@ -4037,6 +4048,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_EVENT_TRIGGER;
 					n->objname = list_make1(makeString($7));
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop TABLE any_name
@@ -4046,6 +4058,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_TABLE;
 					n->objname = $6;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop TEXT_P SEARCH PARSER any_name
@@ -4055,6 +4068,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_TSPARSER;
 					n->objname = $8;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop TEXT_P SEARCH DICTIONARY any_name
@@ -4064,6 +4078,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_TSDICTIONARY;
 					n->objname = $8;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop TEXT_P SEARCH TEMPLATE any_name
@@ -4073,6 +4088,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_TSTEMPLATE;
 					n->objname = $8;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop TEXT_P SEARCH CONFIGURATION any_name
@@ -4082,6 +4098,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_TSCONFIGURATION;
 					n->objname = $8;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop SEQUENCE any_name
@@ -4091,6 +4108,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_SEQUENCE;
 					n->objname = $6;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop VIEW any_name
@@ -4100,6 +4118,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_VIEW;
 					n->objname = $6;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop MATERIALIZED VIEW any_name
@@ -4109,6 +4128,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_MATVIEW;
 					n->objname = $7;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop FOREIGN TABLE any_name
@@ -4118,6 +4138,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_FOREIGN_TABLE;
 					n->objname = $7;
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop FOREIGN DATA_P WRAPPER name
@@ -4127,6 +4148,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_FDW;
 					n->objname = list_make1(makeString($8));
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop SERVER name
@@ -4136,6 +4158,7 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_FOREIGN_SERVER;
 					n->objname = list_make1(makeString($6));
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop TRANSFORM FOR Typename LANGUAGE name
@@ -4146,6 +4169,7 @@ AlterExtensionContentsStmt:
 					n->objtype = OBJECT_TRANSFORM;
 					n->objname = list_make1($7);
 					n->objargs = list_make1(makeString($9));
+					n->deptype = 'e';
 					$$ = (Node *)n;
 				}
 			| ALTER EXTENSION name add_drop TYPE_P Typename
@@ -4155,6 +4179,18 @@ AlterExtensionContentsStmt:
 					n->action = $4;
 					n->objtype = OBJECT_TYPE;
 					n->objname = list_make1($6);
+					n->deptype = 'e';
+					$$ = (Node *)n;
+				}
+			| ALTER EXTENSION name add_drop DEPENDENT FUNCTION function_with_argtypes
+				{
+					AlterExtensionContentsStmt *n = makeNode(AlterExtensionContentsStmt);
+					n->extname = $3;
+					n->action = $4;
+					n->objtype = OBJECT_FUNCTION;
+					n->objname = $7->funcname;
+					n->objargs = $7->funcargs;
+					n->deptype = 'x';
 					$$ = (Node *)n;
 				}
 		;
@@ -13706,6 +13742,7 @@ unreserved_keyword:
 			| DELETE_P
 			| DELIMITER
 			| DELIMITERS
+			| DEPENDENT
 			| DICTIONARY
 			| DISABLE_P
 			| DISCARD
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 2fd0629..7305559 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1930,6 +1930,7 @@ typedef struct AlterExtensionContentsStmt
 	ObjectType	objtype;		/* Object's type */
 	List	   *objname;		/* Qualified name of the object */
 	List	   *objargs;		/* Arguments if needed (eg, for functions) */
+	char		deptype;		/* Dependency type: 'e' or 'x' */
 } AlterExtensionContentsStmt;
 
 /* ----------------------
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 6e1e820..5b84d34 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -125,6 +125,7 @@ PG_KEYWORD("definer", DEFINER, UNRESERVED_KEYWORD)
 PG_KEYWORD("delete", DELETE_P, UNRESERVED_KEYWORD)
 PG_KEYWORD("delimiter", DELIMITER, UNRESERVED_KEYWORD)
 PG_KEYWORD("delimiters", DELIMITERS, UNRESERVED_KEYWORD)
+PG_KEYWORD("dependent", DEPENDENT, UNRESERVED_KEYWORD)
 PG_KEYWORD("desc", DESC, RESERVED_KEYWORD)
 PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD)
 PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD)
-- 
2.1.4

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to