0001-bug-fixes-v3.patch
application/octet-stream
Filename: 0001-bug-fixes-v3.patch
Type: application/octet-stream
Part: 2
Patch
Format: unified
Series: patch v3-0001
| File | + | − |
|---|---|---|
| src/backend/catalog/pg_operator.c | 17 | 15 |
| src/test/regress/expected/create_operator.out | 36 | 0 |
| src/test/regress/sql/create_operator.sql | 36 | 0 |
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 95918a77a1..b0570c33b6 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -57,8 +57,7 @@ static Oid OperatorShellMake(const char *operatorName,
static Oid get_other_operator(List *otherOp,
Oid otherLeftTypeId, Oid otherRightTypeId,
const char *operatorName, Oid operatorNamespace,
- Oid leftTypeId, Oid rightTypeId,
- bool isCommutator);
+ Oid leftTypeId, Oid rightTypeId);
/*
@@ -442,8 +441,7 @@ OperatorCreate(const char *operatorName,
commutatorId = get_other_operator(commutatorName,
rightTypeId, leftTypeId,
operatorName, operatorNamespace,
- leftTypeId, rightTypeId,
- true);
+ leftTypeId, rightTypeId);
/* Permission check: must own other operator */
if (OidIsValid(commutatorId) &&
@@ -467,8 +465,19 @@ OperatorCreate(const char *operatorName,
negatorId = get_other_operator(negatorName,
leftTypeId, rightTypeId,
operatorName, operatorNamespace,
- leftTypeId, rightTypeId,
- false);
+ leftTypeId, rightTypeId);
+
+ /*
+ * Prevent self negation as it doesn't make sense. When self negating,
+ * get_other_operator returns InvalidOid when creating a new operator
+ * and the OID of the operator we are 'creating' when upgrading a
+ * shell operator.
+ */
+
+ if (!OidIsValid(negatorId) || operatorObjectId == negatorId)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+ errmsg("operator cannot be its own negator")));
/* Permission check: must own other operator */
if (OidIsValid(negatorId) &&
@@ -584,7 +593,7 @@ OperatorCreate(const char *operatorName,
static Oid
get_other_operator(List *otherOp, Oid otherLeftTypeId, Oid otherRightTypeId,
const char *operatorName, Oid operatorNamespace,
- Oid leftTypeId, Oid rightTypeId, bool isCommutator)
+ Oid leftTypeId, Oid rightTypeId)
{
Oid other_oid;
bool otherDefined;
@@ -611,14 +620,7 @@ get_other_operator(List *otherOp, Oid otherLeftTypeId, Oid otherRightTypeId,
otherLeftTypeId == leftTypeId &&
otherRightTypeId == rightTypeId)
{
- /*
- * self-linkage to this operator; caller will fix later. Note that
- * only self-linkage for commutation makes sense.
- */
- if (!isCommutator)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("operator cannot be its own negator or sort operator")));
+ /* self-linkage to this operator; caller will fix later. */
return InvalidOid;
}
diff --git a/src/test/regress/expected/create_operator.out b/src/test/regress/expected/create_operator.out
index f71b601f2d..49070ce90f 100644
--- a/src/test/regress/expected/create_operator.out
+++ b/src/test/regress/expected/create_operator.out
@@ -260,6 +260,42 @@ CREATE OPERATOR #*# (
);
ERROR: permission denied for type type_op6
ROLLBACK;
+-- Should fail. An operator cannot have a self negator.
+BEGIN TRANSACTION;
+CREATE FUNCTION create_op_test_fn(boolean, boolean)
+RETURNS boolean AS $$
+ SELECT NULL::BOOLEAN;
+$$ LANGUAGE sql IMMUTABLE;
+CREATE OPERATOR === (
+ leftarg = boolean,
+ rightarg = boolean,
+ procedure = create_op_test_fn,
+ negator = ===
+);
+ERROR: operator cannot be its own negator
+ROLLBACK;
+-- Should fail. An operator cannot have a self negator. Here we test that when
+-- 'creating' an existing shell operator, it checks the negator is not self.
+BEGIN TRANSACTION;
+CREATE FUNCTION create_op_test_fn(boolean, boolean)
+RETURNS boolean AS $$
+ SELECT NULL::BOOLEAN;
+$$ LANGUAGE sql IMMUTABLE;
+-- create a shell operator for ===!!! by referencing it as a commutator
+CREATE OPERATOR === (
+ leftarg = boolean,
+ rightarg = boolean,
+ procedure = create_op_test_fn,
+ commutator = ===!!!
+);
+CREATE OPERATOR ===!!! (
+ leftarg = boolean,
+ rightarg = boolean,
+ procedure = create_op_test_fn,
+ negator = ===!!!
+);
+ERROR: operator cannot be its own negator
+ROLLBACK;
-- invalid: non-lowercase quoted identifiers
CREATE OPERATOR ===
(
diff --git a/src/test/regress/sql/create_operator.sql b/src/test/regress/sql/create_operator.sql
index f53e24db3c..168cad3814 100644
--- a/src/test/regress/sql/create_operator.sql
+++ b/src/test/regress/sql/create_operator.sql
@@ -210,6 +210,42 @@ CREATE OPERATOR #*# (
);
ROLLBACK;
+-- Should fail. An operator cannot have a self negator.
+BEGIN TRANSACTION;
+CREATE FUNCTION create_op_test_fn(boolean, boolean)
+RETURNS boolean AS $$
+ SELECT NULL::BOOLEAN;
+$$ LANGUAGE sql IMMUTABLE;
+CREATE OPERATOR === (
+ leftarg = boolean,
+ rightarg = boolean,
+ procedure = create_op_test_fn,
+ negator = ===
+);
+ROLLBACK;
+
+-- Should fail. An operator cannot have a self negator. Here we test that when
+-- 'creating' an existing shell operator, it checks the negator is not self.
+BEGIN TRANSACTION;
+CREATE FUNCTION create_op_test_fn(boolean, boolean)
+RETURNS boolean AS $$
+ SELECT NULL::BOOLEAN;
+$$ LANGUAGE sql IMMUTABLE;
+-- create a shell operator for ===!!! by referencing it as a commutator
+CREATE OPERATOR === (
+ leftarg = boolean,
+ rightarg = boolean,
+ procedure = create_op_test_fn,
+ commutator = ===!!!
+);
+CREATE OPERATOR ===!!! (
+ leftarg = boolean,
+ rightarg = boolean,
+ procedure = create_op_test_fn,
+ negator = ===!!!
+);
+ROLLBACK;
+
-- invalid: non-lowercase quoted identifiers
CREATE OPERATOR ===
(