Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/backend/distributed/planner/multi_physical_planner.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ static bool QueryTreeHasImproperForDeparseNodes(Node *inputNode, void *context);
static Node * AdjustImproperForDeparseNodes(Node *inputNode, void *context);
static bool IsImproperForDeparseRelabelTypeNode(Node *inputNode);
static bool IsImproperForDeparseCoerceViaIONode(Node *inputNode);
static CollateExpr * RelabelTypeToCollateExpr(RelabelType *relabelType);
static Node * RelabelTypeToCollateExpr(RelabelType *relabelType);


/*
Expand Down Expand Up @@ -2878,7 +2878,7 @@ SqlTaskList(Job *job)
* RelabelTypeToCollateExpr converts RelabelType's into CollationExpr's.
* With that, we will be able to pushdown COLLATE's.
*/
static CollateExpr *
static Node *
RelabelTypeToCollateExpr(RelabelType *relabelType)
{
Assert(OidIsValid(relabelType->resultcollid));
Expand All @@ -2888,7 +2888,21 @@ RelabelTypeToCollateExpr(RelabelType *relabelType)
collateExpr->collOid = relabelType->resultcollid;
collateExpr->location = relabelType->location;

return collateExpr;
Oid argType = exprType((Node *) relabelType->arg);
if (relabelType->resulttype != argType)
{
RelabelType *castRelabel = makeNode(RelabelType);
castRelabel->arg = (Expr *) collateExpr;
castRelabel->resulttype = relabelType->resulttype;
castRelabel->resulttypmod = relabelType->resulttypmod;
castRelabel->resultcollid = DEFAULT_COLLATION_OID;
castRelabel->relabelformat = relabelType->relabelformat;
castRelabel->location = relabelType->location;

return (Node *) castRelabel;
}

return (Node *) collateExpr;
}


Expand Down
29 changes: 29 additions & 0 deletions src/test/regress/expected/distributed_collations.out
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,35 @@ DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
(1 row)

RESET citus.log_remote_commands;
-- Test COLLATE with type cast does not cause type mismatch (issue #8469)
-- When a GROUP BY expression uses both ::VARCHAR and COLLATE, the type cast
-- must be preserved in the query sent to workers.
SET citus.next_shard_id TO 20070000;
CREATE TABLE test_collate_cast (c0 inet, c1 inet);
SELECT create_distributed_table('test_collate_cast', 'c0');
create_distributed_table
---------------------------------------------------------------------

(1 row)

INSERT INTO test_collate_cast(c1, c0) VALUES
('144.150.228.243', '230.194.119.117'),
('22.171.214.19', '138.53.199.60'),
('14.25.58.22', '103.167.89.59');
-- This used to fail with: "attribute 2 of type record has wrong type"
-- "Table has type text, but query expects character varying"
SELECT SUM(agg0)
FROM (
SELECT ALL SUM(0.5) as agg0
FROM ONLY test_collate_cast
GROUP BY
(((('fooText')||(test_collate_cast.c1)))::VARCHAR COLLATE "C")
) as asdf;
sum
---------------------------------------------------------------------
1.5
(1 row)

-- Test range table with collated distribution column
CREATE TABLE test_range(key text COLLATE german_phonebook, val int);
SELECT create_distributed_table('test_range', 'key', 'range');
Expand Down
21 changes: 21 additions & 0 deletions src/test/regress/sql/distributed_collations.sql
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,27 @@ SELECT ALL MIN((lower(CAST(test_collate_pushed_down_aggregate.a AS VARCHAR)) COL
FROM ONLY test_collate_pushed_down_aggregate;
RESET citus.log_remote_commands;

-- Test COLLATE with type cast does not cause type mismatch (issue #8469)
-- When a GROUP BY expression uses both ::VARCHAR and COLLATE, the type cast
-- must be preserved in the query sent to workers.
SET citus.next_shard_id TO 20070000;
CREATE TABLE test_collate_cast (c0 inet, c1 inet);
SELECT create_distributed_table('test_collate_cast', 'c0');
INSERT INTO test_collate_cast(c1, c0) VALUES
('144.150.228.243', '230.194.119.117'),
('22.171.214.19', '138.53.199.60'),
('14.25.58.22', '103.167.89.59');

-- This used to fail with: "attribute 2 of type record has wrong type"
-- "Table has type text, but query expects character varying"
SELECT SUM(agg0)
FROM (
SELECT ALL SUM(0.5) as agg0
FROM ONLY test_collate_cast
GROUP BY
(((('fooText')||(test_collate_cast.c1)))::VARCHAR COLLATE "C")
) as asdf;

-- Test range table with collated distribution column
CREATE TABLE test_range(key text COLLATE german_phonebook, val int);
SELECT create_distributed_table('test_range', 'key', 'range');
Expand Down