aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/pg_depend.c49
-rw-r--r--src/backend/commands/alter.c24
-rw-r--r--src/backend/nodes/copyfuncs.c1
-rw-r--r--src/backend/nodes/equalfuncs.c1
-rw-r--r--src/backend/parser/gram.y36
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