Merge pull request #4580 from citusdata/convert-relabeltype-into-collateexpr-in-deparser

Convert relabeltype into collateexpr in deparser
pull/4645/head
Halil Ozan Akgül 2021-02-05 13:33:02 +03:00 committed by GitHub
commit cbb95af2c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 161 additions and 27 deletions

View File

@ -5166,20 +5166,42 @@ get_rule_expr(Node *node, deparse_context *context,
case T_RelabelType:
{
RelabelType *relabel = (RelabelType *) node;
Node *arg = (Node *) relabel->arg;
if (relabel->relabelformat == COERCE_IMPLICIT_CAST &&
!showimplicit)
/*
* This is a Citus specific modification
* The planner converts CollateExpr to RelabelType
* and here we convert back.
*/
if (relabel->resultcollid != InvalidOid)
{
/* don't show the implicit cast */
get_rule_expr_paren(arg, context, false, node);
CollateExpr *collate = RelabelTypeToCollateExpr(relabel);
Node *arg = (Node *) collate->arg;
if (!PRETTY_PAREN(context))
appendStringInfoChar(buf, '(');
get_rule_expr_paren(arg, context, showimplicit, node);
appendStringInfo(buf, " COLLATE %s",
generate_collation_name(collate->collOid));
if (!PRETTY_PAREN(context))
appendStringInfoChar(buf, ')');
}
else
{
get_coercion_expr(arg, context,
relabel->resulttype,
relabel->resulttypmod,
node);
Node *arg = (Node *) relabel->arg;
if (relabel->relabelformat == COERCE_IMPLICIT_CAST &&
!showimplicit)
{
/* don't show the implicit cast */
get_rule_expr_paren(arg, context, false, node);
}
else
{
get_coercion_expr(arg, context,
relabel->resulttype,
relabel->resulttypmod,
node);
}
}
}
break;

View File

@ -5181,20 +5181,42 @@ get_rule_expr(Node *node, deparse_context *context,
case T_RelabelType:
{
RelabelType *relabel = (RelabelType *) node;
Node *arg = (Node *) relabel->arg;
if (relabel->relabelformat == COERCE_IMPLICIT_CAST &&
!showimplicit)
/*
* This is a Citus specific modification
* The planner converts CollateExpr to RelabelType
* and here we convert back.
*/
if (relabel->resultcollid != InvalidOid)
{
/* don't show the implicit cast */
get_rule_expr_paren(arg, context, false, node);
CollateExpr *collate = RelabelTypeToCollateExpr(relabel);
Node *arg = (Node *) collate->arg;
if (!PRETTY_PAREN(context))
appendStringInfoChar(buf, '(');
get_rule_expr_paren(arg, context, showimplicit, node);
appendStringInfo(buf, " COLLATE %s",
generate_collation_name(collate->collOid));
if (!PRETTY_PAREN(context))
appendStringInfoChar(buf, ')');
}
else
{
get_coercion_expr(arg, context,
relabel->resulttype,
relabel->resulttypmod,
node);
Node *arg = (Node *) relabel->arg;
if (relabel->relabelformat == COERCE_IMPLICIT_CAST &&
!showimplicit)
{
/* don't show the implicit cast */
get_rule_expr_paren(arg, context, false, node);
}
else
{
get_coercion_expr(arg, context,
relabel->resulttype,
relabel->resulttypmod,
node);
}
}
}
break;

View File

@ -5237,20 +5237,42 @@ get_rule_expr(Node *node, deparse_context *context,
case T_RelabelType:
{
RelabelType *relabel = (RelabelType *) node;
Node *arg = (Node *) relabel->arg;
if (relabel->relabelformat == COERCE_IMPLICIT_CAST &&
!showimplicit)
/*
* This is a Citus specific modification
* The planner converts CollateExpr to RelabelType
* and here we convert back.
*/
if (relabel->resultcollid != InvalidOid)
{
/* don't show the implicit cast */
get_rule_expr_paren(arg, context, false, node);
CollateExpr *collate = RelabelTypeToCollateExpr(relabel);
Node *arg = (Node *) collate->arg;
if (!PRETTY_PAREN(context))
appendStringInfoChar(buf, '(');
get_rule_expr_paren(arg, context, showimplicit, node);
appendStringInfo(buf, " COLLATE %s",
generate_collation_name(collate->collOid));
if (!PRETTY_PAREN(context))
appendStringInfoChar(buf, ')');
}
else
{
get_coercion_expr(arg, context,
relabel->resulttype,
relabel->resulttypmod,
node);
Node *arg = (Node *) relabel->arg;
if (relabel->relabelformat == COERCE_IMPLICIT_CAST &&
!showimplicit)
{
/* don't show the implicit cast */
get_rule_expr_paren(arg, context, false, node);
}
else
{
get_coercion_expr(arg, context,
relabel->resulttype,
relabel->resulttypmod,
node);
}
}
}
break;

View File

@ -2937,6 +2937,24 @@ SqlTaskList(Job *job)
}
/*
* RelabelTypeToCollateExpr converts RelabelType's into CollationExpr's.
* With that, we will be able to pushdown COLLATE's.
*/
CollateExpr *
RelabelTypeToCollateExpr(RelabelType *relabelType)
{
Assert(OidIsValid(relabelType->resultcollid));
CollateExpr *collateExpr = makeNode(CollateExpr);
collateExpr->arg = relabelType->arg;
collateExpr->collOid = relabelType->resultcollid;
collateExpr->location = relabelType->location;
return collateExpr;
}
/*
* DependsOnHashPartitionJob checks if the given job depends on a hash
* partitioning job.

View File

@ -540,6 +540,7 @@ extern Node * WrapUngroupedVarsInAnyValueAggregate(Node *expression,
List *groupClauseList,
List *targetList,
bool checkExpressionEquality);
extern CollateExpr * RelabelTypeToCollateExpr(RelabelType *relabelType);
/*
* Function declarations for building, updating constraints and simple operator

View File

@ -56,6 +56,44 @@ SELECT * FROM collation_tests.test_propagate WHERE t2 < 'b' COLLATE "C";
2 | Voẞr | Vossr
(1 row)
SELECT * FROM collation_tests.test_propagate WHERE t2 COLLATE "C" < 'b';
id | t1 | t2
---------------------------------------------------------------------
2 | Voẞr | Vossr
(1 row)
-- Test COLLATE is pushed down with aggregate function
SET citus.next_shard_id TO 20060000;
CREATE TABLE test_collate_pushed_down_aggregate (a int, b int);
SELECT create_distributed_table('test_collate_pushed_down_aggregate', 'a');
create_distributed_table
---------------------------------------------------------------------
(1 row)
SELECT alter_distributed_table('test_collate_pushed_down_aggregate', shard_count := 2, cascade_to_colocated:=false);
NOTICE: creating a new table for collation_tests.test_collate_pushed_down_aggregate
NOTICE: Moving the data of collation_tests.test_collate_pushed_down_aggregate
NOTICE: Dropping the old collation_tests.test_collate_pushed_down_aggregate
NOTICE: Renaming the new table to collation_tests.test_collate_pushed_down_aggregate
alter_distributed_table
---------------------------------------------------------------------
(1 row)
SET citus.log_remote_commands TO true;
SELECT ALL MIN((lower(CAST(test_collate_pushed_down_aggregate.a AS VARCHAR)) COLLATE "C"))
FROM ONLY test_collate_pushed_down_aggregate;
NOTICE: issuing SELECT min((lower(((a)::character varying COLLATE "default")) COLLATE "C")) AS min FROM collation_tests.test_collate_pushed_down_aggregate_20060004 test_collate_pushed_down_aggregate WHERE true
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT min((lower(((a)::character varying COLLATE "default")) COLLATE "C")) AS min FROM collation_tests.test_collate_pushed_down_aggregate_20060005 test_collate_pushed_down_aggregate WHERE true
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
min
---------------------------------------------------------------------
(1 row)
RESET citus.log_remote_commands;
-- 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');

View File

@ -34,6 +34,17 @@ SELECT create_distributed_table('test_propagate', 'id');
-- Test COLLATE is pushed down
SELECT * FROM collation_tests.test_propagate WHERE t2 < 'b';
SELECT * FROM collation_tests.test_propagate WHERE t2 < 'b' COLLATE "C";
SELECT * FROM collation_tests.test_propagate WHERE t2 COLLATE "C" < 'b';
-- Test COLLATE is pushed down with aggregate function
SET citus.next_shard_id TO 20060000;
CREATE TABLE test_collate_pushed_down_aggregate (a int, b int);
SELECT create_distributed_table('test_collate_pushed_down_aggregate', 'a');
SELECT alter_distributed_table('test_collate_pushed_down_aggregate', shard_count := 2, cascade_to_colocated:=false);
SET citus.log_remote_commands TO true;
SELECT ALL MIN((lower(CAST(test_collate_pushed_down_aggregate.a AS VARCHAR)) COLLATE "C"))
FROM ONLY test_collate_pushed_down_aggregate;
RESET citus.log_remote_commands;
-- Test range table with collated distribution column
CREATE TABLE test_range(key text COLLATE german_phonebook, val int);