diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index b0570c33b6..cda543a03b 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -360,53 +360,17 @@ OperatorCreate(const char *operatorName, errmsg("\"%s\" is not a valid operator name", operatorName))); - if (!(OidIsValid(leftTypeId) && OidIsValid(rightTypeId))) - { - /* If it's not a binary op, these things mustn't be set: */ - if (commutatorName) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only binary operators can have commutators"))); - if (OidIsValid(joinId)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only binary operators can have join selectivity"))); - if (canMerge) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only binary operators can merge join"))); - if (canHash) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only binary operators can hash"))); - } - operResultType = get_func_rettype(procedureId); - if (operResultType != BOOLOID) - { - /* If it's not a boolean op, these things mustn't be set: */ - if (negatorName) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only boolean operators can have negators"))); - if (OidIsValid(restrictionId)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only boolean operators can have restriction selectivity"))); - if (OidIsValid(joinId)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only boolean operators can have join selectivity"))); - if (canMerge) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only boolean operators can merge join"))); - if (canHash) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("only boolean operators can hash"))); - } + OperatorValidateParams(leftTypeId, + rightTypeId, + operResultType, + commutatorName, + negatorName, + OidIsValid(joinId), + OidIsValid(restrictionId), + canMerge, + canHash); operatorObjectId = OperatorGet(operatorName, operatorNamespace, @@ -763,6 +727,78 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete) table_close(pg_operator_desc, RowExclusiveLock); } +/* + * OperatorValidateParams + * + * This function validates that an operator with arguments of leftTypeId and + * rightTypeId returning operResultType can have the attributes that are set + * to true. If any attributes set are not compatible with the operator then this + * function will raise an error, otherwise it simply returns. + * + * This function doesn't check for missing requirements so any attribute that's + * false is considered valid by this function. As such, if you are modifying an + * operator you can set any attributes you are not modifying to false to validate + * the changes you are making. + */ + +void +OperatorValidateParams(Oid leftTypeId, + Oid rightTypeId, + Oid operResultType, + bool hasCommutator, + bool hasNegator, + bool hasJoinSelectivity, + bool hasRestrictionSelectivity, + bool canMerge, + bool canHash) +{ + if (!(OidIsValid(leftTypeId) && OidIsValid(rightTypeId))) + { + /* If it's not a binary op, these things mustn't be set: */ + if (hasCommutator) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only binary operators can have commutators"))); + if (hasJoinSelectivity) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only binary operators can have join selectivity"))); + if (canMerge) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only binary operators can merge join"))); + if (canHash) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only binary operators can hash"))); + } + + if (operResultType != BOOLOID) + { + /* If it's not a boolean op, these things mustn't be set: */ + if (hasNegator) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only boolean operators can have negators"))); + if (hasRestrictionSelectivity) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only boolean operators can have restriction selectivity"))); + if (hasJoinSelectivity) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only boolean operators can have join selectivity"))); + if (canMerge) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only boolean operators can merge join"))); + if (canHash) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("only boolean operators can hash"))); + } +} + /* * Create dependencies for an operator (either a freshly inserted * complete operator, a new shell operator, a just-updated shell, diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index aff372b4bb..a670973ab2 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -104,4 +104,14 @@ extern ObjectAddress makeOperatorDependencies(HeapTuple tuple, extern void OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete); +extern void OperatorValidateParams(Oid leftTypeId, + Oid rightTypeId, + Oid operResultType, + bool hasCommutator, + bool hasNegator, + bool hasJoinSelectivity, + bool hasRestrictionSelectivity, + bool canMerge, + bool canHash); + #endif /* PG_OPERATOR_H */