diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/pg_depend.c | 49 | ||||
-rw-r--r-- | src/backend/commands/alter.c | 24 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 36 |
5 files changed, 91 insertions, 20 deletions
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c index 596dafe19c8..fa38ee94777 100644 --- a/src/backend/catalog/pg_depend.c +++ b/src/backend/catalog/pg_depend.c @@ -279,6 +279,55 @@ deleteDependencyRecordsForClass(Oid classId, Oid objectId, } /* + * 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 * * classId/objectId specify the referencing object. diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 11db9bfe922..951690b2b8d 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 @@ -433,7 +433,6 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre ObjectAddress address; ObjectAddress refAddr; Relation rel; - List *currexts; address = get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object, @@ -463,11 +462,22 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre if (refAddress) *refAddress = refAddr; - /* Avoid duplicates */ - currexts = getAutoExtensionsOfObject(address.classId, - address.objectId); - if (!list_member_oid(currexts, refAddr.objectId)) - recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION); + if (stmt->remove) + { + deleteDependencyRecordsForSpecific(address.classId, address.objectId, + DEPENDENCY_AUTO_EXTENSION, + refAddr.classId, refAddr.objectId); + } + else + { + List *currexts; + + /* Avoid duplicates */ + currexts = getAutoExtensionsOfObject(address.classId, + address.objectId); + if (!list_member_oid(currexts, refAddr.objectId)) + recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION); + } return address; } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 1525c0de725..491452ae2d4 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -3638,6 +3638,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.c index 4f34189ab5c..8408c28ec69 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1449,6 +1449,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.y index 1219ac8c264..3c78f2d1b51 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -320,7 +320,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 @@ -9053,57 +9053,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 |