|
6 | 6 |
|
7 | 7 | import io.substrait.dsl.SubstraitBuilder;
|
8 | 8 | import io.substrait.expression.Expression;
|
| 9 | +import io.substrait.expression.Expression.ScalarFunctionInvocation; |
| 10 | +import io.substrait.expression.ExpressionCreator; |
| 11 | +import io.substrait.extension.DefaultExtensionCatalog; |
9 | 12 | import io.substrait.isthmus.expression.ExpressionRexConverter;
|
10 | 13 | import io.substrait.relation.Project;
|
11 | 14 | import io.substrait.relation.Rel;
|
@@ -159,6 +162,32 @@ Rel createSubQueryRel() {
|
159 | 162 | commonTable));
|
160 | 163 | }
|
161 | 164 |
|
| 165 | + /** |
| 166 | + * Test that checks that we use the explicit return type provided in the Substrait plan instead of |
| 167 | + * relying on the return type inference by Calcite. Would throw an |
| 168 | + * java.lang.ArrayIndexOutOfBoundsException otherwise. |
| 169 | + */ |
| 170 | + @Test |
| 171 | + public void subtractDateTimeExplicitReturnTypeTest() { |
| 172 | + ScalarFunctionInvocation expr = |
| 173 | + b.scalarFn( |
| 174 | + DefaultExtensionCatalog.FUNCTIONS_DATETIME, |
| 175 | + "subtract:date_iday", |
| 176 | + TypeCreator.REQUIRED.DATE, |
| 177 | + ExpressionCreator.date(false, 10561), |
| 178 | + ExpressionCreator.intervalDay(false, 120, 0, 0, 6)); |
| 179 | + |
| 180 | + Project query = b.project(input -> List.of(expr), b.emptyScan()); |
| 181 | + |
| 182 | + SubstraitToCalcite substraitToCalcite = new SubstraitToCalcite(extensions, typeFactory); |
| 183 | + RelNode calciteRel = substraitToCalcite.convert(query); |
| 184 | + RexNode calciteExpr = ((LogicalProject) calciteRel).getProjects().get(0); |
| 185 | + |
| 186 | + assertEquals( |
| 187 | + TypeConverter.DEFAULT.toCalcite(typeFactory, TypeCreator.REQUIRED.DATE), |
| 188 | + calciteExpr.getType()); |
| 189 | + } |
| 190 | + |
162 | 191 | void assertTypeMatch(RelDataType actual, Type expected) {
|
163 | 192 | Type type = TypeConverter.DEFAULT.toSubstrait(actual);
|
164 | 193 | assertEquals(expected, type);
|
|
0 commit comments