mirror of https://github.com/citusdata/citus.git
Fix Shard Pruning Problem With Subqueries on VARCHAR Partition Columns
Fixes #375 Prior to this change, shard pruning couldn't be done if: - Table is hash-distributed - Partition column of is VARCHAR - Query to be pruned is a subquery There were two problems: - A bug in left-side/right-side checks for the partition column - We were not considering relabeled types (VARCHAR was relabeled as TEXT)pull/426/head
parent
339e1364d5
commit
1ffc30d7f5
|
@ -3710,6 +3710,8 @@ PartitionColumnOpExpressionList(Query *query)
|
|||
Node *whereNode = (Node *) lfirst(whereClauseCell);
|
||||
Node *leftArgument = NULL;
|
||||
Node *rightArgument = NULL;
|
||||
Node *strippedLeftArgument = NULL;
|
||||
Node *strippedRightArgument = NULL;
|
||||
OpExpr *whereClause = NULL;
|
||||
List *argumentList = NIL;
|
||||
List *rangetableList = NIL;
|
||||
|
@ -3744,14 +3746,16 @@ PartitionColumnOpExpressionList(Query *query)
|
|||
|
||||
leftArgument = (Node *) linitial(argumentList);
|
||||
rightArgument = (Node *) lsecond(argumentList);
|
||||
strippedLeftArgument = strip_implicit_coercions(leftArgument);
|
||||
strippedRightArgument = strip_implicit_coercions(rightArgument);
|
||||
|
||||
if (IsA(leftArgument, Var) && IsA(rightArgument, Const))
|
||||
if (IsA(strippedLeftArgument, Var) && IsA(strippedRightArgument, Const))
|
||||
{
|
||||
candidatePartitionColumn = (Var *) leftArgument;
|
||||
candidatePartitionColumn = (Var *) strippedLeftArgument;
|
||||
}
|
||||
else if (IsA(leftArgument, Const) && IsA(leftArgument, Var))
|
||||
else if (IsA(strippedLeftArgument, Const) && IsA(strippedRightArgument, Var))
|
||||
{
|
||||
candidatePartitionColumn = (Var *) rightArgument;
|
||||
candidatePartitionColumn = (Var *) strippedRightArgument;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3798,14 +3802,16 @@ ReplaceColumnsInOpExpressionList(List *opExpressionList, Var *newColumn)
|
|||
|
||||
Node *leftArgument = (Node *) linitial(argumentList);
|
||||
Node *rightArgument = (Node *) lsecond(argumentList);
|
||||
Node *strippedLeftArgument = strip_implicit_coercions(leftArgument);
|
||||
Node *strippedRightArgument = strip_implicit_coercions(rightArgument);
|
||||
|
||||
if (IsA(leftArgument, Var))
|
||||
if (IsA(strippedLeftArgument, Var))
|
||||
{
|
||||
newArgumentList = list_make2(newColumn, rightArgument);
|
||||
newArgumentList = list_make2(newColumn, strippedRightArgument);
|
||||
}
|
||||
else if (IsA(leftArgument, Var))
|
||||
else if (IsA(strippedRightArgument, Var))
|
||||
{
|
||||
newArgumentList = list_make2(leftArgument, newColumn);
|
||||
newArgumentList = list_make2(strippedLeftArgument, newColumn);
|
||||
}
|
||||
|
||||
copyOpExpression->args = newArgumentList;
|
||||
|
|
|
@ -294,3 +294,31 @@ FROM
|
|||
l_orderkey = o_orderkey
|
||||
GROUP BY
|
||||
l_orderkey) AS unit_prices;
|
||||
|
||||
-- Check that we can prune shards in subqueries with VARCHAR partition columns
|
||||
|
||||
CREATE TABLE subquery_pruning_varchar_test_table
|
||||
(
|
||||
a varchar,
|
||||
b int
|
||||
);
|
||||
|
||||
SELECT master_create_distributed_table('subquery_pruning_varchar_test_table', 'a', 'hash');
|
||||
SELECT master_create_worker_shards('subquery_pruning_varchar_test_table', 4, 1);
|
||||
|
||||
SET citus.subquery_pushdown TO TRUE;
|
||||
SET client_min_messages TO DEBUG2;
|
||||
|
||||
SELECT * FROM
|
||||
(SELECT count(*) FROM subquery_pruning_varchar_test_table WHERE a = 'onder' GROUP BY a)
|
||||
AS foo;
|
||||
|
||||
SELECT * FROM
|
||||
(SELECT count(*) FROM subquery_pruning_varchar_test_table WHERE 'eren' = a GROUP BY a)
|
||||
AS foo;
|
||||
|
||||
SET client_min_messages TO NOTICE;
|
||||
|
||||
DROP TABLE subquery_pruning_varchar_test_table;
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 102026;
|
||||
|
|
|
@ -326,3 +326,46 @@ FROM
|
|||
l_orderkey) AS unit_prices;
|
||||
ERROR: cannot push down this subquery
|
||||
DETAIL: Shards of relations in subquery need to have 1-to-1 shard partitioning
|
||||
-- Check that we can prune shards in subqueries with VARCHAR partition columns
|
||||
CREATE TABLE subquery_pruning_varchar_test_table
|
||||
(
|
||||
a varchar,
|
||||
b int
|
||||
);
|
||||
SELECT master_create_distributed_table('subquery_pruning_varchar_test_table', 'a', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('subquery_pruning_varchar_test_table', 4, 1);
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SET citus.subquery_pushdown TO TRUE;
|
||||
SET client_min_messages TO DEBUG2;
|
||||
SELECT * FROM
|
||||
(SELECT count(*) FROM subquery_pruning_varchar_test_table WHERE a = 'onder' GROUP BY a)
|
||||
AS foo;
|
||||
DEBUG: predicate pruning for shardId 102029
|
||||
DEBUG: predicate pruning for shardId 102027
|
||||
DEBUG: predicate pruning for shardId 102026
|
||||
count
|
||||
-------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM
|
||||
(SELECT count(*) FROM subquery_pruning_varchar_test_table WHERE 'eren' = a GROUP BY a)
|
||||
AS foo;
|
||||
DEBUG: predicate pruning for shardId 102029
|
||||
DEBUG: predicate pruning for shardId 102028
|
||||
DEBUG: predicate pruning for shardId 102026
|
||||
count
|
||||
-------
|
||||
(0 rows)
|
||||
|
||||
SET client_min_messages TO NOTICE;
|
||||
DROP TABLE subquery_pruning_varchar_test_table;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 102026;
|
||||
|
|
Loading…
Reference in New Issue