extdepend-20160404.diff
text/x-diff
Filename: extdepend-20160404.diff
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| doc/src/sgml/catalogs.sgml | 13 | 0 |
| src/backend/catalog/dependency.c | 2 | 0 |
| src/backend/catalog/objectaddress.c | 25 | 0 |
| src/backend/commands/alter.c | 26 | 0 |
| src/backend/nodes/copyfuncs.c | 17 | 0 |
| src/backend/nodes/equalfuncs.c | 15 | 0 |
| src/backend/parser/gram.y | 84 | 2 |
| src/backend/tcop/utility.c | 27 | 0 |
| src/include/catalog/dependency.h | 8 | 1 |
| src/include/catalog/objectaddress.h | 4 | 0 |
| src/include/commands/alter.h | 1 | 0 |
| src/include/nodes/nodes.h | 1 | 0 |
| src/include/nodes/parsenodes.h | 15 | 0 |
| src/include/parser/kwlist.h | 1 | 0 |
| src/tools/pgindent/typedefs.list | 1 | 0 |
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index bb75229..3c128a0 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -2888,6 +2888,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 17f9de1..79595a9 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -589,6 +589,7 @@ findDependentObjects(const ObjectAddress *object,
{
case DEPENDENCY_NORMAL:
case DEPENDENCY_AUTO:
+ case DEPENDENCY_AUTO_EXTENSION:
/* no problem */
break;
case DEPENDENCY_INTERNAL:
@@ -788,6 +789,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/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index cb3ba85..ad65d2d 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -1016,6 +1016,31 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
}
/*
+ * Return an ObjectAddress based on a RangeVar and an object name. The
+ * name of the relation identified by the RangeVar is prepended to the
+ * list passed in as objname. This is useful to find the ObjectAddress
+ * of objects that depend on a relation. All other considerations are
+ * exactly as for get_object_address above.
+ */
+ObjectAddress
+get_object_address_rv(ObjectType objtype, RangeVar *rel, List *objname,
+ List *objargs, Relation *relp, LOCKMODE lockmode,
+ bool missing_ok)
+{
+ if (rel)
+ {
+ objname = lcons(makeString(rel->relname), objname);
+ if (rel->schemaname)
+ objname = lcons(makeString(rel->schemaname), objname);
+ if (rel->catalogname)
+ objname = lcons(makeString(rel->catalogname), objname);
+ }
+
+ return get_object_address(objtype, objname, objargs,
+ relp, lockmode, missing_ok);
+}
+
+/*
* Find an ObjectAddress for a type of object that is identified by an
* unqualified name.
*/
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 5af0f2f..4c64700 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -391,6 +391,32 @@ ExecRenameStmt(RenameStmt *stmt)
}
/*
+ * Executes an ALTER OBJECT / DEPENDS ON EXTENSION statement.
+ *
+ * Return value is the address of the altered object.
+ */
+ObjectAddress
+ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt)
+{
+ ObjectAddress address;
+ ObjectAddress extAddr;
+ Relation rel = NULL;
+
+ address =
+ get_object_address_rv(stmt->objectType, stmt->relation, stmt->objname,
+ stmt->objargs, &rel, AccessExclusiveLock, false);
+ if (rel)
+ heap_close(rel, NoLock);
+
+ extAddr = get_object_address(OBJECT_EXTENSION, stmt->extname, NULL,
+ &rel, AccessExclusiveLock, false);
+
+ recordDependencyOn(&address, &extAddr, DEPENDENCY_AUTO_EXTENSION);
+
+ return address;
+}
+
+/*
* Executes an ALTER OBJECT / SET SCHEMA statement. Based on the object
* type, the function appropriate to that type is executed.
*
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index f4e4a91..1e123d8 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3204,6 +3204,20 @@ _copyRenameStmt(const RenameStmt *from)
return newnode;
}
+static AlterObjectDependsStmt *
+_copyAlterObjectDependsStmt(const AlterObjectDependsStmt *from)
+{
+ AlterObjectDependsStmt *newnode = makeNode(AlterObjectDependsStmt);
+
+ COPY_SCALAR_FIELD(objectType);
+ COPY_NODE_FIELD(relation);
+ COPY_NODE_FIELD(objname);
+ COPY_NODE_FIELD(objargs);
+ COPY_NODE_FIELD(extname);
+
+ return newnode;
+}
+
static AlterObjectSchemaStmt *
_copyAlterObjectSchemaStmt(const AlterObjectSchemaStmt *from)
{
@@ -4682,6 +4696,9 @@ copyObject(const void *from)
case T_RenameStmt:
retval = _copyRenameStmt(from);
break;
+ case T_AlterObjectDependsStmt:
+ retval = _copyAlterObjectDependsStmt(from);
+ break;
case T_AlterObjectSchemaStmt:
retval = _copyAlterObjectSchemaStmt(from);
break;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 854c062..6c05096 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1326,6 +1326,18 @@ _equalRenameStmt(const RenameStmt *a, const RenameStmt *b)
}
static bool
+_equalAlterObjectDependsStmt(const AlterObjectDependsStmt *a, const AlterObjectDependsStmt *b)
+{
+ COMPARE_SCALAR_FIELD(objectType);
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(objname);
+ COMPARE_NODE_FIELD(objargs);
+ COMPARE_NODE_FIELD(extname);
+
+ return true;
+}
+
+static bool
_equalAlterObjectSchemaStmt(const AlterObjectSchemaStmt *a, const AlterObjectSchemaStmt *b)
{
COMPARE_SCALAR_FIELD(objectType);
@@ -3004,6 +3016,9 @@ equal(const void *a, const void *b)
case T_RenameStmt:
retval = _equalRenameStmt(a, b);
break;
+ case T_AlterObjectDependsStmt:
+ retval = _equalAlterObjectDependsStmt(a, b);
+ break;
case T_AlterObjectSchemaStmt:
retval = _equalAlterObjectSchemaStmt(a, b);
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 1273352..f7a097b 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -233,7 +233,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
AlterEventTrigStmt
AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterEnumStmt
AlterFdwStmt AlterForeignServerStmt AlterGroupStmt
- AlterObjectSchemaStmt AlterOwnerStmt AlterOperatorStmt AlterSeqStmt AlterSystemStmt AlterTableStmt
+ AlterObjectDependsStmt AlterObjectSchemaStmt AlterOwnerStmt
+ AlterOperatorStmt AlterSeqStmt AlterSystemStmt AlterTableStmt
AlterTblSpcStmt AlterExtensionStmt AlterExtensionContentsStmt AlterForeignTableStmt
AlterCompositeTypeStmt AlterUserStmt AlterUserMappingStmt AlterUserSetStmt
AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt
@@ -578,7 +579,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 DEPENDS 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
@@ -767,6 +768,7 @@ stmt :
| AlterForeignTableStmt
| AlterFunctionStmt
| AlterGroupStmt
+ | AlterObjectDependsStmt
| AlterObjectSchemaStmt
| AlterOwnerStmt
| AlterOperatorStmt
@@ -8027,6 +8029,85 @@ opt_set_data: SET DATA_P { $$ = 1; }
/*****************************************************************************
*
+ * ALTER THING name DEPENDS ON EXTENSION name
+ *
+ *****************************************************************************/
+
+AlterObjectDependsStmt:
+ ALTER FUNCTION function_with_argtypes DEPENDS ON EXTENSION name
+ {
+ AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
+ n->objectType = OBJECT_FUNCTION;
+ n->relation = NULL;
+ n->objname = $3->funcname;
+ n->objargs = $3->funcargs;
+ n->extname = list_make1(makeString($7));
+ $$ = (Node *)n;
+ }
+ | ALTER TRIGGER name ON qualified_name DEPENDS ON EXTENSION name
+ {
+ AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
+ n->objectType = OBJECT_TRIGGER;
+ n->relation = $5;
+ n->objname = list_make1(makeString($3));
+ n->objargs = NIL;
+ n->extname = list_make1(makeString($9));
+ $$ = (Node *)n;
+ }
+ | ALTER RULE name ON qualified_name DEPENDS ON EXTENSION name
+ {
+ AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
+ n->objectType = OBJECT_RULE;
+ n->relation = $5;
+ n->objname = list_make1(makeString($3));
+ n->objargs = NIL;
+ n->extname = list_make1(makeString($9));
+ $$ = (Node *)n;
+ }
+ | ALTER TABLE qualified_name DEPENDS ON EXTENSION name
+ {
+ AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
+ n->objectType = OBJECT_TABLE;
+ n->relation = $3;
+ n->objname = NIL;
+ n->objargs = NIL;
+ n->extname = list_make1(makeString($7));
+ $$ = (Node *)n;
+ }
+ | ALTER TEXT_P SEARCH CONFIGURATION any_name DEPENDS ON EXTENSION name
+ {
+ AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
+ n->objectType = OBJECT_TSCONFIGURATION;
+ n->relation = $3;
+ n->objname = NIL;
+ n->objargs = NIL;
+ n->extname = list_make1(makeString($7));
+ $$ = (Node *)n;
+ }
+ | ALTER TYPE_P any_name DEPENDS ON EXTENSION name
+ {
+ AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
+ n->objectType = OBJECT_TYPE;
+ n->relation = NULL;
+ n->objname = $3;
+ n->objargs = NIL;
+ n->extname = list_make1(makeString($7));
+ $$ = (Node *)n;
+ }
+ | ALTER OPERATOR any_operator oper_argtypes DEPENDS ON EXTENSION name
+ {
+ AlterObjectDependsStmt *n = makeNode(AlterObjectDependsStmt);
+ n->objectType = OBJECT_OPERATOR;
+ n->relation = NULL;
+ n->objname = $3;
+ n->objargs = $4;
+ n->extname = list_make1(makeString($8));
+ $$ = (Node *)n;
+ }
+ ;
+
+/*****************************************************************************
+ *
* ALTER THING name SET SCHEMA name
*
*****************************************************************************/
@@ -13726,6 +13807,7 @@ unreserved_keyword:
| DELETE_P
| DELIMITER
| DELIMITERS
+ | DEPENDS
| DICTIONARY
| DISABLE_P
| DISCARD
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 4d0aac9..321db87 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -147,6 +147,7 @@ check_xact_readonly(Node *parsetree)
case T_AlterFunctionStmt:
case T_AlterRoleStmt:
case T_AlterRoleSetStmt:
+ case T_AlterObjectDependsStmt:
case T_AlterObjectSchemaStmt:
case T_AlterOwnerStmt:
case T_AlterOperatorStmt:
@@ -836,6 +837,19 @@ standard_ProcessUtility(Node *parsetree,
}
break;
+ case T_AlterObjectDependsStmt:
+ {
+ AlterObjectDependsStmt *stmt = (AlterObjectDependsStmt *) parsetree;
+
+ if (EventTriggerSupportsObjectType(stmt->objectType))
+ ProcessUtilitySlow(parsetree, queryString,
+ context, params,
+ dest, completionTag);
+ else
+ ExecAlterObjectDependsStmt(stmt);
+ }
+ break;
+
case T_AlterObjectSchemaStmt:
{
AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
@@ -1472,6 +1486,11 @@ ProcessUtilitySlow(Node *parsetree,
address = ExecRenameStmt((RenameStmt *) parsetree);
break;
+ case T_AlterObjectDependsStmt:
+ address =
+ ExecAlterObjectDependsStmt((AlterObjectDependsStmt *) parsetree);
+ break;
+
case T_AlterObjectSchemaStmt:
address =
ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree,
@@ -2192,6 +2211,10 @@ CreateCommandTag(Node *parsetree)
tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
break;
+ case T_AlterObjectDependsStmt:
+ tag = AlterObjectTypeCommandTag(((AlterObjectDependsStmt *) parsetree)->objectType);
+ break;
+
case T_AlterObjectSchemaStmt:
tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
break;
@@ -2822,6 +2845,10 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
+ case T_AlterObjectDependsStmt:
+ lev = LOGSTMT_DDL;
+ break;
+
case T_AlterObjectSchemaStmt:
lev = LOGSTMT_DDL;
break;
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index d41abc4..107c859 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;
/*
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 640f7ff..87aa414 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -44,6 +44,10 @@ extern ObjectAddress get_object_address(ObjectType objtype, List *objname,
List *objargs, Relation *relp,
LOCKMODE lockmode, bool missing_ok);
+extern ObjectAddress get_object_address_rv(ObjectType objtype, RangeVar *rel,
+ List *objname, List *objargs, Relation *relp,
+ LOCKMODE lockmode, bool missing_ok);
+
extern void check_object_ownership(Oid roleid,
ObjectType objtype, ObjectAddress address,
List *objname, List *objargs, Relation relation);
diff --git a/src/include/commands/alter.h b/src/include/commands/alter.h
index cf92e3e..6cd1bca 100644
--- a/src/include/commands/alter.h
+++ b/src/include/commands/alter.h
@@ -21,6 +21,7 @@
extern ObjectAddress ExecRenameStmt(RenameStmt *stmt);
+extern ObjectAddress ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt);
extern ObjectAddress ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt,
ObjectAddress *oldSchemaAddr);
extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 734df77..d888b41 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -368,6 +368,7 @@ typedef enum NodeTag
T_DeclareCursorStmt,
T_CreateTableSpaceStmt,
T_DropTableSpaceStmt,
+ T_AlterObjectDependsStmt,
T_AlterObjectSchemaStmt,
T_AlterOwnerStmt,
T_AlterOperatorStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 8b958b4..744bea6 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2536,6 +2536,21 @@ typedef struct RenameStmt
} RenameStmt;
/* ----------------------
+ * ALTER object DEPENDS ON EXTENSION extname
+ * ----------------------
+ */
+
+typedef struct AlterObjectDependsStmt
+{
+ NodeTag type;
+ ObjectType objectType; /* OBJECT_TABLE, OBJECT_TYPE, etc */
+ RangeVar *relation; /* in case a table is involved */
+ List *objname; /* name of the object */
+ List *objargs; /* argument types, if applicable */
+ List *extname; /* target extension's name */
+} AlterObjectDependsStmt;
+
+/* ----------------------
* ALTER object SET SCHEMA Statement
* ----------------------
*/
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 7de3404..17ffef5 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("depends", DEPENDS, UNRESERVED_KEYWORD)
PG_KEYWORD("desc", DESC, RESERVED_KEYWORD)
PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD)
PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD)
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index c2511de..e293fc0 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -67,6 +67,7 @@ AlterExtensionStmt
AlterFdwStmt
AlterForeignServerStmt
AlterFunctionStmt
+AlterObjectDependsStmt
AlterObjectSchemaStmt
AlterOpFamilyStmt
AlterOwnerStmt