|
20 | 20 | import org.apache.calcite.rel.RelCollation; |
21 | 21 | import org.apache.calcite.rel.RelCollationTraitDef; |
22 | 22 | import org.apache.calcite.rel.RelCollations; |
| 23 | +import org.apache.calcite.rel.RelNode; |
| 24 | +import org.apache.calcite.tools.FrameworkConfig; |
| 25 | +import org.apache.calcite.tools.RelBuilder; |
| 26 | +import org.apache.calcite.test.RelBuilderTest; |
23 | 27 |
|
24 | 28 | import com.google.common.collect.ImmutableList; |
25 | 29 |
|
|
33 | 37 | import static org.hamcrest.Matchers.hasSize; |
34 | 38 | import static org.junit.jupiter.api.Assertions.assertFalse; |
35 | 39 | import static org.junit.jupiter.api.Assertions.assertNotEquals; |
| 40 | +import static org.junit.jupiter.api.Assertions.assertThrows; |
36 | 41 | import static org.junit.jupiter.api.Assertions.assertTrue; |
37 | 42 |
|
38 | 43 | import static java.lang.Integer.toHexString; |
@@ -98,4 +103,34 @@ private void assertCanonical(String message, Supplier<List<RelCollation>> collat |
98 | 103 | RelTraitSet traits3 = traits2.replace(RelCollations.of(1)); |
99 | 104 | assertFalse(traits3.equalsSansConvention(traits2)); |
100 | 105 | } |
| 106 | + |
| 107 | + /** Test for |
| 108 | + * <a href="https://issues.apache.org/jira/browse/CALCITE-7431">[CALCITE-7431] |
| 109 | + * RelTraitSet#getTrait seems to mishandle RelCompositeTrait</a>. */ |
| 110 | + @Test void testRelCompositeTrait() { |
| 111 | + // Build: EMP -> Sort(MGR asc) -> Project(MGR, MGR as MGR2) |
| 112 | + // The project maps both output columns 0 and 1 back to input column 3 |
| 113 | + // (MGR), so the planner derives two collations: [0 ASC] and [1 ASC], which |
| 114 | + // are stored as a RelCompositeTrait in the output trait set. |
| 115 | + final FrameworkConfig config = RelBuilderTest.config().build(); |
| 116 | + final RelBuilder b = RelBuilder.create(config); |
| 117 | + final RelNode in = b |
| 118 | + .scan("EMP") |
| 119 | + .sort(3) // MGR asc |
| 120 | + .project(b.field(3), b.alias(b.field(3), "MGR2")) // MGR, MGR as MGR2 |
| 121 | + .build(); |
| 122 | + |
| 123 | + final RelTraitSet traitSet = in.getTraitSet(); |
| 124 | + |
| 125 | + final List<RelCollation> collations = traitSet.getCollations(); |
| 126 | + assertTrue(collations.size() >= 2, |
| 127 | + "getCollations() should expose all composite collations"); |
| 128 | + |
| 129 | + assertThrows(IllegalStateException.class, traitSet::getCollation, |
| 130 | + "getCollation() should throw when a RelCompositeTrait is present"); |
| 131 | + |
| 132 | + assertThrows(IllegalStateException.class, |
| 133 | + () -> traitSet.getTrait(RelCollationTraitDef.INSTANCE), |
| 134 | + "getTrait() should throw when a RelCompositeTrait is present"); |
| 135 | + } |
101 | 136 | } |
0 commit comments