From e786cbed0f5d834e6c6a9527b453a189b01fed1a Mon Sep 17 00:00:00 2001 From: eren Date: Thu, 7 Apr 2016 15:16:04 +0300 Subject: [PATCH] Fix Join Problem With VARCHAR Partition Columns This change fixes the problem with joins with VARCHAR columns. Prior to this change, when we tried to do large table joins on varchar columns, we got an error of the form: ERROR: cannot perform local joins that involve expressions DETAIL: local joins can be performed between columns only. This is because we have a check in CheckJoinBetweenColumns() which requires the join clause to have only 'Var' nodes (i.e. columns). Postgres adds a relabel t ype cast to cast the varchar to text; hence the type of the node is not T_Var and the join fails. The fix involves calling strip_implicit_coercions() to the left and right arguments so that RELABELTYPE is stripped to VAR. Fixes #76. --- .../distributed/planner/multi_physical_planner.c | 6 ++++-- src/test/regress/expected/multi_join_pruning.out | 14 ++++++++------ src/test/regress/sql/multi_join_pruning.sql | 5 +---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/backend/distributed/planner/multi_physical_planner.c b/src/backend/distributed/planner/multi_physical_planner.c index 1488d1e94..9323a163a 100644 --- a/src/backend/distributed/planner/multi_physical_planner.c +++ b/src/backend/distributed/planner/multi_physical_planner.c @@ -3500,9 +3500,11 @@ CheckJoinBetweenColumns(OpExpr *joinClause) List *argumentList = joinClause->args; Node *leftArgument = (Node *) linitial(argumentList); Node *rightArgument = (Node *) lsecond(argumentList); + Node *strippedLeftArgument = strip_implicit_coercions(leftArgument); + Node *strippedRightArgument = strip_implicit_coercions(rightArgument); - NodeTag leftArgumentType = nodeTag(leftArgument); - NodeTag rightArgumentType = nodeTag(rightArgument); + NodeTag leftArgumentType = nodeTag(strippedLeftArgument); + NodeTag rightArgumentType = nodeTag(strippedRightArgument); if (leftArgumentType != T_Var || rightArgumentType != T_Var) { diff --git a/src/test/regress/expected/multi_join_pruning.out b/src/test/regress/expected/multi_join_pruning.out index 578964ac5..9627df180 100644 --- a/src/test/regress/expected/multi_join_pruning.out +++ b/src/test/regress/expected/multi_join_pruning.out @@ -89,13 +89,15 @@ DEBUG: join prunable for intervals [(a,3,b),(b,4,c)] and [(c,5,d),(d,6,e)] explain statements for distributed queries are currently unsupported (1 row) --- Large table joins between varchar columns do not work because of a bug we --- have. Currently, we require joins to be only on columns. Postgres adds a --- relabel to typecast varchars to text due to which our check fails and we --- error out. +-- Test that large table joins on partition varchar columns work EXPLAIN SELECT count(*) FROM varchar_partitioned_table table1, varchar_partitioned_table table2 WHERE table1.varchar_column = table2.varchar_column; -ERROR: cannot perform local joins that involve expressions -DETAIL: local joins can be performed between columns only +DEBUG: join prunable for intervals [BA1000U2AMO4ZGX,BZZXSP27F21T6] and [AA1000U2AMO4ZGX,AZZXSP27F21T6] +DEBUG: join prunable for intervals [AA1000U2AMO4ZGX,AZZXSP27F21T6] and [BA1000U2AMO4ZGX,BZZXSP27F21T6] + QUERY PLAN +---------------------------------------------------------------------- + explain statements for distributed queries are currently unsupported +(1 row) + SET client_min_messages TO NOTICE; diff --git a/src/test/regress/sql/multi_join_pruning.sql b/src/test/regress/sql/multi_join_pruning.sql index 293b05f4c..f2794d8d9 100644 --- a/src/test/regress/sql/multi_join_pruning.sql +++ b/src/test/regress/sql/multi_join_pruning.sql @@ -44,10 +44,7 @@ EXPLAIN SELECT count(*) FROM composite_partitioned_table table1, composite_partitioned_table table2 WHERE table1.composite_column = table2.composite_column; --- Large table joins between varchar columns do not work because of a bug we --- have. Currently, we require joins to be only on columns. Postgres adds a --- relabel to typecast varchars to text due to which our check fails and we --- error out. +-- Test that large table joins on partition varchar columns work EXPLAIN SELECT count(*) FROM varchar_partitioned_table table1, varchar_partitioned_table table2