diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 3cd1899..ab969a4 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -54,8 +54,6 @@ static Oid OperatorShellMake(const char *operatorName,
 				  Oid leftTypeId,
 				  Oid rightTypeId);
 
-static void OperatorUpd(Oid baseId, Oid commId, Oid negId);
-
 static Oid get_other_operator(List *otherOp,
 				   Oid otherLeftTypeId, Oid otherRightTypeId,
 				   const char *operatorName, Oid operatorNamespace,
@@ -566,7 +564,7 @@ OperatorCreate(const char *operatorName,
 		commutatorId = operatorObjectId;
 
 	if (OidIsValid(commutatorId) || OidIsValid(negatorId))
-		OperatorUpd(operatorObjectId, commutatorId, negatorId);
+		OperatorUpd(operatorObjectId, commutatorId, negatorId, false);
 
 	return address;
 }
@@ -643,9 +641,14 @@ get_other_operator(List *otherOp, Oid otherLeftTypeId, Oid otherRightTypeId,
  *	(respectively) are empty, then use the new operator for neg or comm.
  *	This solves a problem for users who need to insert two new operators
  *	which are the negator or commutator of each other.
+ *
+ *	If we are removing given operator, we'd like to reset links on commutator
+ *	and negator, but only if they are point to given operator (i.e. haven't
+ *	been somehow updated. This check is mostly useless, since we forbid
+ *	overwriting oprcom and oprnegate).
  */
-static void
-OperatorUpd(Oid baseId, Oid commId, Oid negId)
+void
+OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete)
 {
 	int			i;
 	Relation	pg_operator_desc;
@@ -653,6 +656,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
 	bool		nulls[Natts_pg_operator];
 	bool		replaces[Natts_pg_operator];
 	Datum		values[Natts_pg_operator];
+	Datum		target;
 
 	for (i = 0; i < Natts_pg_operator; ++i)
 	{
@@ -667,10 +671,16 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
 	 * We need a CommandCounterIncrement here in case of a self-commutator
 	 * operator: we'll need to update the tuple that we just inserted.
 	 */
-	CommandCounterIncrement();
+	if (!isDelete)
+		CommandCounterIncrement();
 
 	pg_operator_desc = heap_open(OperatorRelationId, RowExclusiveLock);
 
+	/* When deleting, reset other operator field to InvalidOid, otherwise,
+     * set it to point to operator being updated
+	 */
+	target = (isDelete ? InvalidOid : ObjectIdGetDatum(baseId));
+
 	tup = SearchSysCacheCopy1(OPEROID, ObjectIdGetDatum(commId));
 
 	/*
@@ -683,18 +693,27 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
 		if (HeapTupleIsValid(tup))
 		{
 			Form_pg_operator t = (Form_pg_operator) GETSTRUCT(tup);
-
-			if (!OidIsValid(t->oprcom) || !OidIsValid(t->oprnegate))
+			/*
+			 * When deleting, check, whether other op field points to operator
+			 * being updated. Otherwise, check, whether field is not set.
+			 */
+			bool shouldUpdateNegator = (isDelete ?
+										t->oprnegate == baseId :
+										!OidIsValid(t->oprnegate));
+			bool shouldUpdateCommutator = (isDelete ?
+										   t->oprcom == baseId :
+										   !OidIsValid(t->oprcom));
+			if (shouldUpdateNegator || shouldUpdateCommutator)
 			{
-				if (!OidIsValid(t->oprnegate))
+				if (shouldUpdateNegator)
 				{
-					values[Anum_pg_operator_oprnegate - 1] = ObjectIdGetDatum(baseId);
+					values[Anum_pg_operator_oprnegate - 1] = target;
 					replaces[Anum_pg_operator_oprnegate - 1] = true;
 				}
 
-				if (!OidIsValid(t->oprcom))
+				if (shouldUpdateCommutator)
 				{
-					values[Anum_pg_operator_oprcom - 1] = ObjectIdGetDatum(baseId);
+					values[Anum_pg_operator_oprcom - 1] = target;
 					replaces[Anum_pg_operator_oprcom - 1] = true;
 				}
 
@@ -717,45 +736,52 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
 
 	/* if commutator and negator are different, do two updates */
 
-	if (HeapTupleIsValid(tup) &&
-		!(OidIsValid(((Form_pg_operator) GETSTRUCT(tup))->oprcom)))
+	if (HeapTupleIsValid(tup))
 	{
-		values[Anum_pg_operator_oprcom - 1] = ObjectIdGetDatum(baseId);
-		replaces[Anum_pg_operator_oprcom - 1] = true;
+		Form_pg_operator t = (Form_pg_operator) GETSTRUCT(tup);
+		/* As above, check whether other operator should be updated */
+		if (isDelete ? t->oprcom == baseId : !OidIsValid(t->oprcom))
+		{
 
-		tup = heap_modify_tuple(tup,
-								RelationGetDescr(pg_operator_desc),
-								values,
-								nulls,
-								replaces);
+			values[Anum_pg_operator_oprcom - 1] = target;
+			replaces[Anum_pg_operator_oprcom - 1] =true;
 
-		simple_heap_update(pg_operator_desc, &tup->t_self, tup);
+			tup = heap_modify_tuple(tup,
+									RelationGetDescr(pg_operator_desc),
+									values,
+									nulls,
+									replaces);
+
+			simple_heap_update(pg_operator_desc, &tup->t_self, tup);
 
-		CatalogUpdateIndexes(pg_operator_desc, tup);
+			CatalogUpdateIndexes(pg_operator_desc, tup);
 
-		values[Anum_pg_operator_oprcom - 1] = (Datum) NULL;
-		replaces[Anum_pg_operator_oprcom - 1] = false;
+			values[Anum_pg_operator_oprcom - 1] = (Datum) NULL;
+			replaces[Anum_pg_operator_oprcom - 1] = false;
+		}
 	}
 
 	/* check and update the negator, if necessary */
-
 	tup = SearchSysCacheCopy1(OPEROID, ObjectIdGetDatum(negId));
 
-	if (HeapTupleIsValid(tup) &&
-		!(OidIsValid(((Form_pg_operator) GETSTRUCT(tup))->oprnegate)))
+	if (HeapTupleIsValid(tup))
 	{
-		values[Anum_pg_operator_oprnegate - 1] = ObjectIdGetDatum(baseId);
-		replaces[Anum_pg_operator_oprnegate - 1] = true;
+		Form_pg_operator t = (Form_pg_operator) GETSTRUCT(tup);
+		if (isDelete ? t->oprnegate == baseId : !OidIsValid(t->oprnegate))
+		{
+			values[Anum_pg_operator_oprnegate - 1] = target;
+			replaces[Anum_pg_operator_oprnegate - 1] = true;
 
-		tup = heap_modify_tuple(tup,
-								RelationGetDescr(pg_operator_desc),
-								values,
-								nulls,
-								replaces);
+			tup = heap_modify_tuple(tup,
+									RelationGetDescr(pg_operator_desc),
+									values,
+									nulls,
+									replaces);
 
-		simple_heap_update(pg_operator_desc, &tup->t_self, tup);
+			simple_heap_update(pg_operator_desc, &tup->t_self, tup);
 
-		CatalogUpdateIndexes(pg_operator_desc, tup);
+			CatalogUpdateIndexes(pg_operator_desc, tup);
+		}
 	}
 
 	heap_close(pg_operator_desc, RowExclusiveLock);
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index 664e5d7..b389c24 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -339,15 +339,30 @@ ValidateJoinEstimator(List *joinName)
 void
 RemoveOperatorById(Oid operOid)
 {
-	Relation	relation;
-	HeapTuple	tup;
+	Relation			relation;
+	HeapTuple			tup;
+	Form_pg_operator	op;
 
 	relation = heap_open(OperatorRelationId, RowExclusiveLock);
 
 	tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid));
+	op = (Form_pg_operator)	GETSTRUCT(tup);
 	if (!HeapTupleIsValid(tup)) /* should not happen */
 		elog(ERROR, "cache lookup failed for operator %u", operOid);
 
+	/*
+	 * Reset links on commutator and negator. Only do that if either
+	 * oprcom or oprnegate is set and given operator is	not self-commutator.
+	 * For self-commutator with	negator	prevent	meaningful updates of the
+	 * same tuple by sending InvalidOid.
+	 */
+	if (OidIsValid(op->oprnegate) ||
+		(OidIsValid(op->oprcom)	&& operOid != op->oprcom))
+		OperatorUpd(operOid,
+					operOid	== op->oprcom ?	InvalidOid : op->oprcom,
+					op->oprnegate,
+					true);
+
 	simple_heap_delete(relation, &tup->t_self);
 
 	ReleaseSysCache(tup);
diff --git a/src/include/catalog/pg_operator_fn.h b/src/include/catalog/pg_operator_fn.h
index 5315e19..3e1c7ae 100644
--- a/src/include/catalog/pg_operator_fn.h
+++ b/src/include/catalog/pg_operator_fn.h
@@ -30,5 +30,5 @@ extern ObjectAddress OperatorCreate(const char *operatorName,
 			   bool canHash);
 
 extern ObjectAddress makeOperatorDependencies(HeapTuple tuple, bool isUpdate);
-
+extern void OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete);
 #endif   /* PG_OPERATOR_FN_H */
diff --git a/src/test/regress/expected/drop_operator.out b/src/test/regress/expected/drop_operator.out
new file mode 100644
index 0000000..208ed80
--- /dev/null
+++ b/src/test/regress/expected/drop_operator.out
@@ -0,0 +1,142 @@
+CREATE OPERATOR === (
+        PROCEDURE = int8eq,
+        LEFTARG = bigint,
+        RIGHTARG = bigint
+);
+SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype
+FROM pg_depend
+WHERE classid = 'pg_operator'::regclass AND
+      objid = '===(bigint,bigint)'::regoperator
+ORDER BY 1;
+      ref      | deptype 
+---------------+---------
+ schema public | n
+(1 row)
+
+CREATE OPERATOR !== (
+        PROCEDURE = int8ne,
+        LEFTARG = bigint,
+        RIGHTARG = bigint,
+        NEGATOR = ===
+);
+SELECT po.oprname AS op, po2.oprname AS negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+ op  | negator 
+-----+---------
+ === | !==
+ !== | ===
+(2 rows)
+
+DROP OPERATOR !== (bigint, bigint);
+SELECT po.oprname AS op, po2.oprname AS negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+ op | negator 
+----+---------
+(0 rows)
+
+SELECT oprname, oprnegate FROM pg_operator WHERE oprname = '==='
+    AND oprleft = 'bigint'::regtype AND oprright = 'bigint'::regtype;
+ oprname | oprnegate 
+---------+-----------
+ ===     |         0
+(1 row)
+
+DROP OPERATOR ===(bigint,bigint);
+CREATE OPERATOR === (
+        PROCEDURE = int8eq,
+        LEFTARG = bigint,
+        RIGHTARG = bigint,
+        COMMUTATOR = ===
+);
+CREATE OPERATOR !== (
+        PROCEDURE = int8ne,
+        LEFTARG = bigint,
+        RIGHTARG = bigint,
+        NEGATOR = ===,
+        COMMUTATOR = !==
+);
+SELECT po.oprname AS op, po2.oprname AS negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+ op  | negator 
+-----+---------
+ === | !==
+ !== | ===
+(2 rows)
+
+SELECT po.oprname AS op, po2.oprname AS commutator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprcom
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype
+    ORDER BY po.oprname;
+ op  | commutator 
+-----+------------
+ !== | !==
+ === | ===
+(2 rows)
+
+DROP OPERATOR !==(bigint, bigint);
+SELECT po.oprname AS op, po2.oprname AS negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+ op | negator 
+----+---------
+(0 rows)
+
+SELECT po.oprname AS op, po2.oprname AS commutator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprcom
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+ op  | commutator 
+-----+------------
+ === | ===
+(1 row)
+
+DROP OPERATOR ===(bigint, bigint);
+CREATE OPERATOR === (
+        PROCEDURE = int8eq,
+        LEFTARG = bigint,
+        RIGHTARG = bigint
+);
+CREATE OPERATOR !== (
+        PROCEDURE = int8ne,
+        LEFTARG = bigint,
+        RIGHTARG = bigint,
+        NEGATOR = ===,
+        COMMUTATOR = ===
+);
+SELECT po.oprname AS op, po2.oprname AS commutator, po3.oprname as negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprcom
+    JOIN pg_operator AS po3 ON po.oid = po3.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprname = '===' AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+ op  | commutator | negator 
+-----+------------+---------
+ === | !==        | !==
+(1 row)
+
+DROP OPERATOR !==(bigint, bigint);
+SELECT po.oprname AS op, po2.oprname AS commutator, po3.oprname as negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprcom
+    JOIN pg_operator AS po3 ON po.oid = po3.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprname = '===' AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+ op | commutator | negator 
+----+------------+---------
+(0 rows)
+
+DROP OPERATOR ===(bigint, bigint);
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index bec0316..731677f 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -79,7 +79,7 @@ ignore: random
 # ----------
 # Another group of parallel tests
 # ----------
-test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete
+test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete drop_operator
 
 # ----------
 # Another group of parallel tests
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 7e9b319..4e2fe83 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -115,6 +115,7 @@ test: object_address
 test: tablesample
 test: alter_generic
 test: alter_operator
+test: drop_operator
 test: misc
 test: psql
 test: async
diff --git a/src/test/regress/sql/drop_operator.sql b/src/test/regress/sql/drop_operator.sql
new file mode 100644
index 0000000..05bc383
--- /dev/null
+++ b/src/test/regress/sql/drop_operator.sql
@@ -0,0 +1,113 @@
+CREATE OPERATOR === (
+        PROCEDURE = int8eq,
+        LEFTARG = bigint,
+        RIGHTARG = bigint
+);
+
+SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype
+FROM pg_depend
+WHERE classid = 'pg_operator'::regclass AND
+      objid = '===(bigint,bigint)'::regoperator
+ORDER BY 1;
+
+CREATE OPERATOR !== (
+        PROCEDURE = int8ne,
+        LEFTARG = bigint,
+        RIGHTARG = bigint,
+        NEGATOR = ===
+);
+
+SELECT po.oprname AS op, po2.oprname AS negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+
+DROP OPERATOR !== (bigint, bigint);
+
+SELECT po.oprname AS op, po2.oprname AS negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+
+SELECT oprname, oprnegate FROM pg_operator WHERE oprname = '==='
+    AND oprleft = 'bigint'::regtype AND oprright = 'bigint'::regtype;
+
+DROP OPERATOR ===(bigint,bigint);
+
+CREATE OPERATOR === (
+        PROCEDURE = int8eq,
+        LEFTARG = bigint,
+        RIGHTARG = bigint,
+        COMMUTATOR = ===
+);
+
+CREATE OPERATOR !== (
+        PROCEDURE = int8ne,
+        LEFTARG = bigint,
+        RIGHTARG = bigint,
+        NEGATOR = ===,
+        COMMUTATOR = !==
+);
+
+SELECT po.oprname AS op, po2.oprname AS negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+
+SELECT po.oprname AS op, po2.oprname AS commutator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprcom
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype
+    ORDER BY po.oprname;
+
+DROP OPERATOR !==(bigint, bigint);
+
+SELECT po.oprname AS op, po2.oprname AS negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+
+SELECT po.oprname AS op, po2.oprname AS commutator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprcom
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+
+DROP OPERATOR ===(bigint, bigint);
+
+CREATE OPERATOR === (
+        PROCEDURE = int8eq,
+        LEFTARG = bigint,
+        RIGHTARG = bigint
+);
+
+CREATE OPERATOR !== (
+        PROCEDURE = int8ne,
+        LEFTARG = bigint,
+        RIGHTARG = bigint,
+        NEGATOR = ===,
+        COMMUTATOR = ===
+);
+
+SELECT po.oprname AS op, po2.oprname AS commutator, po3.oprname as negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprcom
+    JOIN pg_operator AS po3 ON po.oid = po3.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprname = '===' AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+
+DROP OPERATOR !==(bigint, bigint);
+
+SELECT po.oprname AS op, po2.oprname AS commutator, po3.oprname as negator FROM pg_operator AS po
+    JOIN pg_operator AS po2 ON po.oid = po2.oprcom
+    JOIN pg_operator AS po3 ON po.oid = po3.oprnegate
+WHERE po.oprnamespace = (SELECT oid FROM
+        pg_namespace WHERE nspname = 'public')
+    AND po.oprname = '===' AND po.oprleft = 'bigint'::regtype AND po.oprright = 'bigint'::regtype;
+
+DROP OPERATOR ===(bigint, bigint);
