Handle hash-partitioned aliased data types

When two data types have the same binary representation, PostgreSQL may
add an implicit coercion between them by wrapping a node in a relabel
type. This wrapper signals that the wrapped value is completely binary
compatible with the designated "final type" of the relabel node. As an
example, the varchar type is often relabeled to text, since functions
provided for use with text (comparisons, hashes, etc.) are completely
compatible with varchar as well.

The hash-partitioned codepath contains functions that verify queries
actually contain an equality constraint on the partition column, but
those functions expect such constraints to be comparison operations
between a Var and Const. The RelabelType wrapper node causes these
functions to always return false, which bypasses shard pruning.
pull/328/head
Jason Petersen 2016-02-10 14:58:46 -07:00
parent 136306a1fe
commit d164305929
No known key found for this signature in database
GPG Key ID: 9F1D3510D110ABA9
3 changed files with 18 additions and 10 deletions

View File

@ -2808,6 +2808,10 @@ SimpleOpExpression(Expr *clause)
return false; /* not a binary opclause */ return false; /* not a binary opclause */
} }
/* strip coercions before doing check */
leftOperand = strip_implicit_coercions(leftOperand);
rightOperand = strip_implicit_coercions(rightOperand);
if (IsA(rightOperand, Const) && IsA(leftOperand, Var)) if (IsA(rightOperand, Const) && IsA(leftOperand, Var))
{ {
constantClause = (Const *) rightOperand; constantClause = (Const *) rightOperand;
@ -2919,6 +2923,10 @@ OpExpressionContainsColumn(OpExpr *operatorExpression, Var *partitionColumn)
Node *rightOperand = get_rightop((Expr *) operatorExpression); Node *rightOperand = get_rightop((Expr *) operatorExpression);
Var *column = NULL; Var *column = NULL;
/* strip coercions before doing check */
leftOperand = strip_implicit_coercions(leftOperand);
rightOperand = strip_implicit_coercions(rightOperand);
if (IsA(leftOperand, Var)) if (IsA(leftOperand, Var))
{ {
column = (Var *) leftOperand; column = (Var *) leftOperand;

View File

@ -121,7 +121,7 @@ CREATE TABLE varchar_hash_partitioned_table
id int, id int,
name varchar name varchar
); );
SELECT master_create_distributed_table('varchar_hash_partitioned_table', 'id', 'hash'); SELECT master_create_distributed_table('varchar_hash_partitioned_table', 'name', 'hash');
master_create_distributed_table master_create_distributed_table
--------------------------------- ---------------------------------
@ -139,16 +139,16 @@ INSERT INTO varchar_hash_partitioned_table VALUES (2, 'Ozgun');
INSERT INTO varchar_hash_partitioned_table VALUES (3, 'Onder'); INSERT INTO varchar_hash_partitioned_table VALUES (3, 'Onder');
INSERT INTO varchar_hash_partitioned_table VALUES (4, 'Sumedh'); INSERT INTO varchar_hash_partitioned_table VALUES (4, 'Sumedh');
INSERT INTO varchar_hash_partitioned_table VALUES (5, 'Marco'); INSERT INTO varchar_hash_partitioned_table VALUES (5, 'Marco');
SELECT * FROM varchar_hash_partitioned_table WHERE name = 'Onder'; SELECT * FROM varchar_hash_partitioned_table WHERE id = 1;
id | name id | name
----+------- ----+-------
3 | Onder 1 | Jason
(1 row) (1 row)
UPDATE varchar_hash_partitioned_table SET name = 'Samay' WHERE id = 5; UPDATE varchar_hash_partitioned_table SET id = 6 WHERE name = 'Jason';
SELECT * FROM varchar_hash_partitioned_table WHERE name = 'Samay'; SELECT * FROM varchar_hash_partitioned_table WHERE id = 6;
id | name id | name
----+------- ----+-------
5 | Samay 6 | Jason
(1 row) (1 row)

View File

@ -104,7 +104,7 @@ CREATE TABLE varchar_hash_partitioned_table
name varchar name varchar
); );
SELECT master_create_distributed_table('varchar_hash_partitioned_table', 'id', 'hash'); SELECT master_create_distributed_table('varchar_hash_partitioned_table', 'name', 'hash');
SELECT master_create_worker_shards('varchar_hash_partitioned_table', 4, 1); SELECT master_create_worker_shards('varchar_hash_partitioned_table', 4, 1);
-- execute INSERT, SELECT and UPDATE queries on composite_type_partitioned_table -- execute INSERT, SELECT and UPDATE queries on composite_type_partitioned_table
@ -114,8 +114,8 @@ INSERT INTO varchar_hash_partitioned_table VALUES (3, 'Onder');
INSERT INTO varchar_hash_partitioned_table VALUES (4, 'Sumedh'); INSERT INTO varchar_hash_partitioned_table VALUES (4, 'Sumedh');
INSERT INTO varchar_hash_partitioned_table VALUES (5, 'Marco'); INSERT INTO varchar_hash_partitioned_table VALUES (5, 'Marco');
SELECT * FROM varchar_hash_partitioned_table WHERE name = 'Onder'; SELECT * FROM varchar_hash_partitioned_table WHERE id = 1;
UPDATE varchar_hash_partitioned_table SET name = 'Samay' WHERE id = 5; UPDATE varchar_hash_partitioned_table SET id = 6 WHERE name = 'Jason';
SELECT * FROM varchar_hash_partitioned_table WHERE name = 'Samay'; SELECT * FROM varchar_hash_partitioned_table WHERE id = 6;