diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2016-03-25 12:33:16 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2016-03-25 12:33:16 -0400 |
commit | c94959d4110a1965472956cfd631082a96f64a84 (patch) | |
tree | 603f7821778785ae423809a2a1d7ed4b0148d68b /src/backend/commands/operatorcmds.c | |
parent | d543170f2fdd6d9845aaf91dc0f6be7a2bf0d9e7 (diff) | |
download | postgresql-c94959d4110a1965472956cfd631082a96f64a84.tar.gz postgresql-c94959d4110a1965472956cfd631082a96f64a84.zip |
Fix DROP OPERATOR to reset oprcom/oprnegate links to the dropped operator.
This avoids leaving dangling links in pg_operator; which while fairly
harmless are also unsightly.
While we're at it, simplify OperatorUpd, which went through
heap_modify_tuple for no very good reason considering it had already made
a tuple copy it could just scribble on.
Roma Sokolov, reviewed by Tomas Vondra, additional hacking by Robert Haas
and myself.
Diffstat (limited to 'src/backend/commands/operatorcmds.c')
-rw-r--r-- | src/backend/commands/operatorcmds.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 664e5d7de74..d32ba2d61f6 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -341,12 +341,32 @@ RemoveOperatorById(Oid operOid) { Relation relation; HeapTuple tup; + Form_pg_operator op; relation = heap_open(OperatorRelationId, RowExclusiveLock); tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid)); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "cache lookup failed for operator %u", operOid); + op = (Form_pg_operator) GETSTRUCT(tup); + + /* + * Reset links from commutator and negator, if any. In case of a + * self-commutator or self-negator, this means we have to re-fetch the + * updated tuple. (We could optimize away updates on the tuple we're + * about to drop, but it doesn't seem worth convoluting the logic for.) + */ + if (OidIsValid(op->oprcom) || OidIsValid(op->oprnegate)) + { + OperatorUpd(operOid, op->oprcom, op->oprnegate, true); + if (operOid == op->oprcom || operOid == op->oprnegate) + { + ReleaseSysCache(tup); + tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid)); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for operator %u", operOid); + } + } simple_heap_delete(relation, &tup->t_self); |