[
https://issues.apache.org/jira/browse/CALCITE-7431?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Xuyang Zhong updated CALCITE-7431:
----------------------------------
Description:
Below is my test and an exception will be thrown:
{code:java}
RelBuilder b = RelBuilder.create(RelBuilderTest.config().build());
RelNode in = b
.scan("EMP")
.sort(3) // MGR asc
.project(b.field(3), b.alias(b.field(3), "MGR2")) // MGR, MGR as MGR2
.build();
// the following 3 lines will all fail
System.err.println(in.getTraitSet().getCollation());
System.err.println(in.getTraitSet().getCollations());
System.err.println((RelCollation)
in.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE));
// the exception:
java.lang.ClassCastException: org.apache.calcite.plan.RelCompositeTrait cannot
be cast to org.apache.calcite.rel.RelCollation{code}
The reason is that at `{{{}return (T) getTrait(index);{}}}` in
`RelTraitSet#getTrait`, the trait we actually get is a
`{{{}RelCompositeTrait`{}}}, but it is cast to `{{{}RelCollation`{}}}, which
leads to a Java cast error.
I’m not sure whether this is by design: Callers of
`{{{}RelTraitSet#getTrait`{}}} have to be aware that the input trait may have
multiple values (`{{{}RelMultipleTrait`{}}}), and therefore should use
`{{{}#getTraits`{}}} instead. From my perspective, relying on callers to be
aware of this is not ideal. At the very least, `{{{}#getTrait{}}}` should
validate whether the trait is a `{{{}RelMultipleTrait{}}}` and explicitly
indicate that `{{{}#getTraits`{}}} should be used instead.
I encountered this issue because for the SQL below, in older versions,
`{{{}FilterProjectTransposeRule#Line187`{}}} would throw this error. Although
it was fixed in
[https://github.com/apache/calcite/pull/4704/changes#r2644415395], I found that
there still seem to be many places that call `{{{}#getTrait`{}}}
incorrectly—for example, `{{{}#getCollation()`{}}}, `{{{}#getCollations()`{}}},
and the handling of `{{{}RelDistribution`{}}}.
{code:java}
SELECT
*
FROM (
SELECT
task_status, task_status + 1
FROM ods_htg__prod_shop_govern_task__task
WHERE
task_date >= '2026-02-01' AND task_date < '2026-02-01'
-- this will convert the source to empty value source,
-- and empty value source will output multi collations
)
WHERE
task_status > 10 {code}
was:
Below is my test and an exception will be thrown:
{code:java}
RelBuilder b = RelBuilder.create(RelBuilderTest.config().build());
RelNode in = b
.scan("EMP")
.sort(3) // MGR asc
.project(b.field(3), b.alias(b.field(3), "MGR2")) // MGR, MGR as MGR2
.build();
// the following 3 line will all fail
System.err.println(in.getTraitSet().getCollation());
System.err.println(in.getTraitSet().getCollations());
System.err.println((RelCollation)
in.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE));
// the exception:
java.lang.ClassCastException: org.apache.calcite.plan.RelCompositeTrait cannot
be cast to org.apache.calcite.rel.RelCollation{code}
The reason is that at `{{{}return (T) getTrait(index);{}}}` in
`RelTraitSet#getTrait`. The trait we actually get is a
`{{{}RelCompositeTrait`{}}}, but it is cast to `{{{}RelCollation`{}}}, which
leads to a Java cast error.
I’m not sure whether this is by design: Callers of
`{{{}RelTraitSet#getTrait`{}}} have to be aware that the input trait may have
multiple values (`{{{}RelMultipleTrait`{}}}), and therefore should use
`{{{}#getTraits`{}}} instead. From my perspective, relying on callers to be
aware of this is not ideal. At the very least, `{{{}#getTrait{}}}` should
validate whether the trait is a `{{{}RelMultipleTrait{}}}` and explicitly
indicate that `{{{}#getTraits`{}}} should be used instead.
I encountered this issue because for the SQL below, in older versions,
`{{{}FilterProjectTransposeRule#Line187`{}}} would throw this error. Although
it was fixed in
[https://github.com/apache/calcite/pull/4704/changes#r2644415395], I found that
there still seem to be many places that call `{{{}#getTrait`{}}}
incorrectly—for example, `{{{}#getCollation()`{}}}, `{{{}#getCollations()`{}}},
and the handling of `{{{}RelDistribution`{}}}.
{code:java}
SELECT
*
FROM (
SELECT
task_status, task_status + 1
FROM ods_htg__prod_shop_govern_task__task
WHERE
task_date >= '2026-02-01' AND task_date < '2026-02-01'
-- this will convert the source to empty value source,
-- and empty value source will output multi collations
)
WHERE
task_status > 10 {code}
> RelTraitSet#getTrait seems to mishandle RelCompositeTrait
> ---------------------------------------------------------
>
> Key: CALCITE-7431
> URL: https://issues.apache.org/jira/browse/CALCITE-7431
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.41.0
> Reporter: Xuyang Zhong
> Priority: Major
>
> Below is my test and an exception will be thrown:
>
> {code:java}
> RelBuilder b = RelBuilder.create(RelBuilderTest.config().build());
> RelNode in = b
> .scan("EMP")
> .sort(3) // MGR asc
> .project(b.field(3), b.alias(b.field(3), "MGR2")) // MGR, MGR as MGR2
> .build();
> // the following 3 lines will all fail
> System.err.println(in.getTraitSet().getCollation());
> System.err.println(in.getTraitSet().getCollations());
> System.err.println((RelCollation)
> in.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE));
> // the exception:
> java.lang.ClassCastException: org.apache.calcite.plan.RelCompositeTrait
> cannot be cast to org.apache.calcite.rel.RelCollation{code}
> The reason is that at `{{{}return (T) getTrait(index);{}}}` in
> `RelTraitSet#getTrait`, the trait we actually get is a
> `{{{}RelCompositeTrait`{}}}, but it is cast to `{{{}RelCollation`{}}}, which
> leads to a Java cast error.
> I’m not sure whether this is by design: Callers of
> `{{{}RelTraitSet#getTrait`{}}} have to be aware that the input trait may have
> multiple values (`{{{}RelMultipleTrait`{}}}), and therefore should use
> `{{{}#getTraits`{}}} instead. From my perspective, relying on callers to be
> aware of this is not ideal. At the very least, `{{{}#getTrait{}}}` should
> validate whether the trait is a `{{{}RelMultipleTrait{}}}` and explicitly
> indicate that `{{{}#getTraits`{}}} should be used instead.
> I encountered this issue because for the SQL below, in older versions,
> `{{{}FilterProjectTransposeRule#Line187`{}}} would throw this error. Although
> it was fixed in
> [https://github.com/apache/calcite/pull/4704/changes#r2644415395], I found
> that there still seem to be many places that call `{{{}#getTrait`{}}}
> incorrectly—for example, `{{{}#getCollation()`{}}},
> `{{{}#getCollations()`{}}}, and the handling of `{{{}RelDistribution`{}}}.
> {code:java}
> SELECT
> *
> FROM (
> SELECT
> task_status, task_status + 1
> FROM ods_htg__prod_shop_govern_task__task
> WHERE
> task_date >= '2026-02-01' AND task_date < '2026-02-01'
> -- this will convert the source to empty value source,
> -- and empty value source will output multi collations
> )
> WHERE
> task_status > 10 {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)