Skip to content

Commit

Permalink
feat(calcite): support reading in list and map literals (substrait-io…
Browse files Browse the repository at this point in the history
…#177)

* feat: inject ExpressionRexConverter into SubstraitRelNodeConverter
* feat: allow subclasses of ExpressionRexConverter to re-use fields
  • Loading branch information
vbarua authored Sep 12, 2023
1 parent f874241 commit 6437e90
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,32 @@ public SubstraitRelNodeConverter(
AggregateFunctionConverter aggregateFunctionConverter,
WindowFunctionConverter windowFunctionConverter,
TypeConverter typeConverter) {
this(
typeFactory,
relBuilder,
scalarFunctionConverter,
aggregateFunctionConverter,
windowFunctionConverter,
typeConverter,
new ExpressionRexConverter(
typeFactory, scalarFunctionConverter, windowFunctionConverter, typeConverter));
}

public SubstraitRelNodeConverter(
RelDataTypeFactory typeFactory,
RelBuilder relBuilder,
ScalarFunctionConverter scalarFunctionConverter,
AggregateFunctionConverter aggregateFunctionConverter,
WindowFunctionConverter windowFunctionConverter,
TypeConverter typeConverter,
ExpressionRexConverter expressionRexConverter) {
this.typeFactory = typeFactory;
this.typeConverter = typeConverter;
this.relBuilder = relBuilder;
this.rexBuilder = new RexBuilder(typeFactory);
this.scalarFunctionConverter = scalarFunctionConverter;
this.aggregateFunctionConverter = aggregateFunctionConverter;
this.expressionRexConverter =
new ExpressionRexConverter(
typeFactory, scalarFunctionConverter, windowFunctionConverter, typeConverter);
this.expressionRexConverter = expressionRexConverter;
}

public static RelNode convert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@
*/
public class ExpressionRexConverter extends AbstractExpressionVisitor<RexNode, RuntimeException>
implements FunctionArg.FuncArgVisitor<RexNode, RuntimeException> {
private final RelDataTypeFactory typeFactory;
private final TypeConverter typeConverter;
private final RexBuilder rexBuilder;
private final ScalarFunctionConverter scalarFunctionConverter;
private final WindowFunctionConverter windowFunctionConverter;
protected final RelDataTypeFactory typeFactory;
protected final TypeConverter typeConverter;
protected final RexBuilder rexBuilder;
protected final ScalarFunctionConverter scalarFunctionConverter;
protected final WindowFunctionConverter windowFunctionConverter;

private static final SqlIntervalQualifier YEAR_MONTH_INTERVAL =
new SqlIntervalQualifier(
Expand Down Expand Up @@ -218,6 +218,22 @@ public RexNode visit(Expression.DecimalLiteral expr) throws RuntimeException {
return rexBuilder.makeLiteral(decimal, typeConverter.toCalcite(typeFactory, expr.getType()));
}

@Override
public RexNode visit(Expression.ListLiteral expr) throws RuntimeException {
List<RexNode> args =
expr.values().stream().map(l -> l.accept(this)).collect(Collectors.toList());
return rexBuilder.makeCall(SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR, args);
}

@Override
public RexNode visit(Expression.MapLiteral expr) throws RuntimeException {
var args =
expr.values().entrySet().stream()
.flatMap(entry -> Stream.of(entry.getKey().accept(this), entry.getValue().accept(this)))
.collect(Collectors.toList());
return rexBuilder.makeCall(SqlStdOperatorTable.MAP_VALUE_CONSTRUCTOR, args);
}

@Override
public RexNode visit(Expression.IfThen expr) throws RuntimeException {
// In Calcite, the arguments to the CASE operator are given as:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.io.IOException;
import java.util.List;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.sql.parser.SqlParseException;
import org.junit.jupiter.api.Test;

/** Tests which test that an expression can be converted to and from Calcite expressions. */
Expand All @@ -32,6 +33,16 @@ public class ExpressionConvertabilityTest extends PlanTestBase {

final SubstraitToCalcite converter = new SubstraitToCalcite(extensions, typeFactory);

@Test
public void listLiteral() throws IOException, SqlParseException {
assertFullRoundTrip("select ARRAY[1,2,3] from ORDERS");
}

@Test
public void mapLiteral() throws IOException, SqlParseException {
assertFullRoundTrip("select MAP[1, 'hello'] from ORDERS");
}

@Test
public void singleOrList() throws IOException {
Plan.Root root =
Expand Down

0 comments on commit 6437e90

Please sign in to comment.