From f77cff3fb6ed9b222f9f8c61bbe9b5d0dcac0cfd Mon Sep 17 00:00:00 2001 From: eren Date: Fri, 8 Apr 2016 11:51:37 +0300 Subject: [PATCH] Fix JOINs on varchar columns with subquery pushdown Fixes #379 Varchar VAR struct is wrapped in RELABELTYPE struct inside PostgreSQL code and IsPartitionColumnRecursive function considers only VAR types so returning false for varchar. This change adds strip_implicit_coercions() call to the columnExpression in IsPartitionColumnRecursive function so that we get rid of implicit coercions like RELABELTYPE are stripped to VAR. --- .../planner/multi_logical_optimizer.c | 9 +++--- src/test/regress/input/multi_subquery.source | 30 +++++++++++++++++ src/test/regress/output/multi_subquery.source | 32 +++++++++++++++++++ 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/backend/distributed/planner/multi_logical_optimizer.c b/src/backend/distributed/planner/multi_logical_optimizer.c index 59c5c4ee0..75a869b60 100644 --- a/src/backend/distributed/planner/multi_logical_optimizer.c +++ b/src/backend/distributed/planner/multi_logical_optimizer.c @@ -2907,14 +2907,15 @@ IsPartitionColumnRecursive(Expr *columnExpression, Query *query) List *rangetableList = query->rtable; Index rangeTableEntryIndex = 0; RangeTblEntry *rangeTableEntry = NULL; + Expr *strippedColumnExpression = strip_implicit_coercions(columnExpression); - if (IsA(columnExpression, Var)) + if (IsA(strippedColumnExpression, Var)) { - candidateColumn = (Var *) columnExpression; + candidateColumn = (Var *) strippedColumnExpression; } - else if (IsA(columnExpression, FieldSelect)) + else if (IsA(strippedColumnExpression, FieldSelect)) { - FieldSelect *compositeField = (FieldSelect *) columnExpression; + FieldSelect *compositeField = (FieldSelect *) strippedColumnExpression; Expr *fieldExpression = compositeField->arg; if (IsA(fieldExpression, Var)) diff --git a/src/test/regress/input/multi_subquery.source b/src/test/regress/input/multi_subquery.source index cee05ac3d..032b044cf 100644 --- a/src/test/regress/input/multi_subquery.source +++ b/src/test/regress/input/multi_subquery.source @@ -319,6 +319,36 @@ AS foo; SET client_min_messages TO NOTICE; +-- test subquery join on VARCHAR partition column +SELECT * FROM + (SELECT + a_inner AS a + FROM + (SELECT + subquery_pruning_varchar_test_table.a AS a_inner + FROM + subquery_pruning_varchar_test_table + GROUP BY + subquery_pruning_varchar_test_table.a + HAVING + count(subquery_pruning_varchar_test_table.a) < 3) + AS f1, + + (SELECT + subquery_pruning_varchar_test_table.a + FROM + subquery_pruning_varchar_test_table + GROUP BY + subquery_pruning_varchar_test_table.a + HAVING + sum(coalesce(subquery_pruning_varchar_test_table.b,0)) > 20.0) + AS f2 + WHERE + f1.a_inner = f2.a + GROUP BY + a_inner) +AS foo; + DROP TABLE subquery_pruning_varchar_test_table; ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 102026; diff --git a/src/test/regress/output/multi_subquery.source b/src/test/regress/output/multi_subquery.source index 8f5f30c22..0d8492e9b 100644 --- a/src/test/regress/output/multi_subquery.source +++ b/src/test/regress/output/multi_subquery.source @@ -367,5 +367,37 @@ DEBUG: predicate pruning for shardId 102026 (0 rows) SET client_min_messages TO NOTICE; +-- test subquery join on VARCHAR partition column +SELECT * FROM + (SELECT + a_inner AS a + FROM + (SELECT + subquery_pruning_varchar_test_table.a AS a_inner + FROM + subquery_pruning_varchar_test_table + GROUP BY + subquery_pruning_varchar_test_table.a + HAVING + count(subquery_pruning_varchar_test_table.a) < 3) + AS f1, + (SELECT + subquery_pruning_varchar_test_table.a + FROM + subquery_pruning_varchar_test_table + GROUP BY + subquery_pruning_varchar_test_table.a + HAVING + sum(coalesce(subquery_pruning_varchar_test_table.b,0)) > 20.0) + AS f2 + WHERE + f1.a_inner = f2.a + GROUP BY + a_inner) +AS foo; + a +--- +(0 rows) + DROP TABLE subquery_pruning_varchar_test_table; ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 102026;