From 20ba0f72a6f6580f8b1c8477dbb4e0c9ee6d3238 Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Fri, 13 May 2016 20:10:12 +0300 Subject: [PATCH] Change equality operator check for operator expressions --- .../planner/multi_logical_optimizer.c | 14 ++----- .../planner/multi_logical_planner.c | 37 ++++++++++++++----- .../planner/multi_physical_planner.c | 5 +-- .../planner/multi_router_planner.c | 7 +--- .../distributed/multi_logical_planner.h | 3 +- 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/backend/distributed/planner/multi_logical_optimizer.c b/src/backend/distributed/planner/multi_logical_optimizer.c index 03c835c4c..070d8dda9 100644 --- a/src/backend/distributed/planner/multi_logical_optimizer.c +++ b/src/backend/distributed/planner/multi_logical_optimizer.c @@ -3364,8 +3364,7 @@ SupportedLateralQuery(Query *parentQuery, Query *lateralQuery) { OpExpr *operatorExpression = NULL; List *argumentList = NIL; - char *operatorName = NULL; - int equalsOperator = 0; + bool equalsOperator = false; Expr *leftArgument = NULL; Expr *rightArgument = NULL; Expr *outerQueryExpression = NULL; @@ -3396,15 +3395,8 @@ SupportedLateralQuery(Query *parentQuery, Query *lateralQuery) continue; } - /* - * We accept all column types that can be joined with an equals sign as - * valid. These include columns that have cross-type equals operators - * (such as int48eq) and columns that can be casted at run-time (such as - * from numeric to int4). - */ - operatorName = get_opname(operatorExpression->opno); - equalsOperator = strncmp(operatorName, EQUAL_OPERATOR_STRING, NAMEDATALEN); - if (equalsOperator != 0) + equalsOperator = OperatorImplementsEquality(operatorExpression->opno); + if (!equalsOperator) { continue; } diff --git a/src/backend/distributed/planner/multi_logical_planner.c b/src/backend/distributed/planner/multi_logical_planner.c index 33acc0d46..37d3b9b9a 100644 --- a/src/backend/distributed/planner/multi_logical_planner.c +++ b/src/backend/distributed/planner/multi_logical_planner.c @@ -928,15 +928,8 @@ IsJoinClause(Node *clause) bool equiJoin = false; bool joinBetweenDifferentTables = false; - /* - * We accept all column types that can be joined with an equals sign as - * valid. These include columns that have cross-type equals operators - * (such as int48eq) and columns that can be casted at run-time (such as - * from numeric to int4). - */ - char *operatorName = get_opname(operatorExpression->opno); - int equalsOperator = strncmp(operatorName, EQUAL_OPERATOR_STRING, NAMEDATALEN); - if (equalsOperator == 0) + bool equalsOperator = OperatorImplementsEquality(operatorExpression->opno); + if (equalsOperator) { equiJoin = true; } @@ -1956,3 +1949,29 @@ MultiSubqueryPushdownTable(RangeTblEntry *subqueryRangeTableEntry) return subqueryTableNode; } + + +/* + * OperatorImplementsEquality returns true if the given opno represents an + * equality operator. The function retrieves btree interpretation list for this + * opno and check if BTEqualStrategyNumber strategy is present. + */ +bool +OperatorImplementsEquality(Oid opno) +{ + bool equalityOperator = false; + List *btreeIntepretationList = get_op_btree_interpretation(opno); + ListCell *btreeInterpretationCell = NULL; + foreach(btreeInterpretationCell, btreeIntepretationList) + { + OpBtreeInterpretation *btreeIntepretation = (OpBtreeInterpretation *) + lfirst(btreeInterpretationCell); + if (btreeIntepretation->strategy == BTEqualStrategyNumber) + { + equalityOperator = true; + break; + } + } + + return equalityOperator; +} diff --git a/src/backend/distributed/planner/multi_physical_planner.c b/src/backend/distributed/planner/multi_physical_planner.c index 22057879b..3ceca75ba 100644 --- a/src/backend/distributed/planner/multi_physical_planner.c +++ b/src/backend/distributed/planner/multi_physical_planner.c @@ -2861,9 +2861,8 @@ HashableClauseMutator(Node *originalNode, Var *partitionColumn) ScalarArrayOpExpr *arrayOperatorExpression = (ScalarArrayOpExpr *) originalNode; Node *leftOpExpression = linitial(arrayOperatorExpression->args); Node *strippedLeftOpExpression = strip_implicit_coercions(leftOpExpression); - char *operatorName = get_opname(arrayOperatorExpression->opno); - int equalsCompare = strncmp(operatorName, EQUAL_OPERATOR_STRING, NAMEDATALEN); - bool usingEqualityOperator = (equalsCompare == 0); + bool usingEqualityOperator = OperatorImplementsEquality( + arrayOperatorExpression->opno); /* * Citus cannot prune hash-distributed shards with ANY/ALL. We show a NOTICE diff --git a/src/backend/distributed/planner/multi_router_planner.c b/src/backend/distributed/planner/multi_router_planner.c index 679e302f7..bfc67e21e 100644 --- a/src/backend/distributed/planner/multi_router_planner.c +++ b/src/backend/distributed/planner/multi_router_planner.c @@ -1009,8 +1009,6 @@ ColumnMatchExpressionAtTopLevelConjunction(Node *node, Var *column) OpExpr *opExpr = (OpExpr *) node; bool simpleExpression = SimpleOpExpression((Expr *) opExpr); bool columnInExpr = false; - char *operatorName = NULL; - int operatorNameComparison = 0; bool usingEqualityOperator = false; if (!simpleExpression) @@ -1024,10 +1022,7 @@ ColumnMatchExpressionAtTopLevelConjunction(Node *node, Var *column) return false; } - operatorName = get_opname(opExpr->opno); - operatorNameComparison = strncmp(operatorName, EQUAL_OPERATOR_STRING, - NAMEDATALEN); - usingEqualityOperator = (operatorNameComparison == 0); + usingEqualityOperator = OperatorImplementsEquality(opExpr->opno); return usingEqualityOperator; } diff --git a/src/include/distributed/multi_logical_planner.h b/src/include/distributed/multi_logical_planner.h index 890d202ea..825251613 100644 --- a/src/include/distributed/multi_logical_planner.h +++ b/src/include/distributed/multi_logical_planner.h @@ -22,8 +22,6 @@ #include "nodes/pg_list.h" -/* Defines the operator string used for equi joins */ -#define EQUAL_OPERATOR_STRING "=" #define SUBQUERY_RANGE_TABLE_ID -1 #define SUBQUERY_RELATION_ID 10000 #define HEAP_ANALYTICS_SUBQUERY_RELATION_ID 10001 @@ -201,6 +199,7 @@ extern List * TableEntryList(List *rangeTableList); extern bool ExtractRangeTableRelationWalker(Node *node, List **rangeTableList); extern bool ExtractRangeTableEntryWalker(Node *node, List **rangeTableList); extern List * pull_var_clause_default(Node *node); +extern bool OperatorImplementsEquality(Oid opno); #endif /* MULTI_LOGICAL_PLANNER_H */