blob: 19e7bdfd5d59e2e1987ca912eccf0d7d9d7c69a6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.calcite.adapter.arrow;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.schema.Table;
import org.apache.calcite.test.CalciteAssert;
import org.apache.calcite.util.Sources;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.SQLException;
import java.util.Map;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Tests for the Apache Arrow adapter.
*/
@Execution(ExecutionMode.SAME_THREAD)
@ExtendWith(ArrowExtension.class)
class ArrowAdapterTest {
private static Map<String, String> arrow;
private static File arrowDataDirectory;
@BeforeAll
static void initializeArrowState(@TempDir Path sharedTempDir) throws IOException, SQLException {
URL modelUrl =
Objects.requireNonNull(ArrowAdapterTest.class.getResource("/arrow-model.json"), "url");
Path sourceModelFilePath = Sources.of(modelUrl).file().toPath();
Path modelFileTarget = sharedTempDir.resolve("arrow-model.json");
Files.copy(sourceModelFilePath, modelFileTarget);
Path arrowFilesDirectory = sharedTempDir.resolve("arrow");
Files.createDirectory(arrowFilesDirectory);
arrowDataDirectory = arrowFilesDirectory.toFile();
File dataLocationFile = arrowFilesDirectory.resolve("arrowdata.arrow").toFile();
ArrowData arrowDataGenerator = new ArrowData();
arrowDataGenerator.writeArrowData(dataLocationFile);
arrowDataGenerator.writeScottEmpData(arrowFilesDirectory);
arrow = ImmutableMap.of("model", modelFileTarget.toAbsolutePath().toString());
}
/** Test to read an Arrow file and check its field names. */
@Test void testArrowSchema() {
ArrowSchema arrowSchema = new ArrowSchema(arrowDataDirectory);
Map<String, Table> tableMap = arrowSchema.getTableMap();
RelDataTypeFactory typeFactory =
new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
RelDataType relDataType = tableMap.get("ARROWDATA").getRowType(typeFactory);
assertEquals(relDataType.getFieldNames(),
ImmutableList.of("intField", "stringField", "floatField", "longField"));
}
@Test void testArrowProjectAllFields() {
String sql = "select * from arrowdata\n";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=0; stringField=0; floatField=0.0; longField=0\n"
+ "intField=1; stringField=1; floatField=1.0; longField=1\n"
+ "intField=2; stringField=2; floatField=2.0; longField=2\n"
+ "intField=3; stringField=3; floatField=3.0; longField=3\n"
+ "intField=4; stringField=4; floatField=4.0; longField=4\n"
+ "intField=5; stringField=5; floatField=5.0; longField=5\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(6)
.returns(result)
.explainContains(plan);
}
@Test void testArrowProjectAllFieldsExplicitly() {
String sql = "select \"intField\", \"stringField\", \"floatField\", \"longField\" "
+ "from arrowdata\n";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=0; stringField=0; floatField=0.0; longField=0\n"
+ "intField=1; stringField=1; floatField=1.0; longField=1\n"
+ "intField=2; stringField=2; floatField=2.0; longField=2\n"
+ "intField=3; stringField=3; floatField=3.0; longField=3\n"
+ "intField=4; stringField=4; floatField=4.0; longField=4\n"
+ "intField=5; stringField=5; floatField=5.0; longField=5\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(6)
.returns(result)
.explainContains(plan);
}
@Test void testArrowProjectAllFieldsExplicitlyPermutation() {
String sql = "select \"stringField\", \"intField\", \"longField\", \"floatField\" "
+ "from arrowdata\n";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(stringField=[$1], intField=[$0], longField=[$3], floatField=[$2])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "stringField=0; intField=0; longField=0; floatField=0.0\n"
+ "stringField=1; intField=1; longField=1; floatField=1.0\n"
+ "stringField=2; intField=2; longField=2; floatField=2.0\n"
+ "stringField=3; intField=3; longField=3; floatField=3.0\n"
+ "stringField=4; intField=4; longField=4; floatField=4.0\n"
+ "stringField=5; intField=5; longField=5; floatField=5.0\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(6)
.returns(result)
.explainContains(plan);
}
@Test void testArrowProjectSingleField() {
String sql = "select \"intField\" from arrowdata\n";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=0\nintField=1\nintField=2\n"
+ "intField=3\nintField=4\nintField=5\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(6)
.returns(result)
.explainContains(plan);
}
@Test void testArrowProjectTwoFields() {
String sql = "select \"intField\", \"stringField\" from arrowdata\n";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], stringField=[$1])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=0; stringField=0\n"
+ "intField=1; stringField=1\n"
+ "intField=2; stringField=2\n"
+ "intField=3; stringField=3\n"
+ "intField=4; stringField=4\n"
+ "intField=5; stringField=5\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(6)
.returns(result)
.explainContains(plan);
}
@Test void testArrowProjectFieldsWithIntegerFilter() {
String sql = "select \"intField\", \"stringField\"\n"
+ "from arrowdata\n"
+ "where \"intField\" < 4";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], stringField=[$1])\n"
+ " ArrowFilter(condition=[<($0, 4)])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=0; stringField=0\n"
+ "intField=1; stringField=1\n"
+ "intField=2; stringField=2\n"
+ "intField=3; stringField=3\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testArrowProjectFieldsWithMultipleFilterSameField() {
String sql = "select \"intField\", \"stringField\"\n"
+ "from arrowdata\n"
+ "where \"intField\" > 1 and \"intField\" < 4";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], stringField=[$1])\n"
+ " ArrowFilter(condition=[SEARCH($0, Sarg[(1..4)])])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=2; stringField=2\n"
+ "intField=3; stringField=3\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testArrowProjectFieldsWithConjunctiveFilters() {
String sql = "select \"intField\", \"stringField\"\n"
+ "from arrowdata\n"
+ "where \"intField\"=12 and \"stringField\"='12'";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], stringField=[$1])\n"
+ " ArrowFilter(condition=[AND(=($0, 12), =($1, '12'))])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=12; stringField=12\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Disabled("OR is not supported yet")
@Test void testArrowProjectFieldsWithDisjunctiveFilter() {
String sql = "select \"intField\", \"stringField\"\n"
+ "from arrowdata\n"
+ "where \"intField\"=12 or \"stringField\"='12'";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], stringField=[$1])\n"
+ " ArrowFilter(condition=[OR(=($0, 12), =($1, '12'))])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=12; stringField=12\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Disabled("IN is not supported as OR is not supported yet")
@Test void testArrowProjectFieldsWithInFilter() {
String sql = "select \"intField\", \"stringField\"\n"
+ "from arrowdata\n"
+ "where \"intField\" in (0, 1, 2)";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], stringField=[$1])\n"
+ " ArrowFilter(condition=[OR(=($0, 0), =($0, 1), =($0, 2))])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=0; stringField=0\n"
+ "intField=1; stringField=1\n"
+ "intField=2; stringField=2\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Disabled("IS NOT NULL is not supported yet")
@Test void testArrowProjectFieldsWithIsNotNullFilter() {
String sql = "select \"intField\", \"stringField\"\n"
+ "from arrowdata\n"
+ "where \"intField\" is not null\n"
+ "order by \"intField\"\n"
+ "limit 1";
String plan = "PLAN=EnumerableLimit(fetch=[1])\n"
+ " EnumerableSort(sort0=[$0], dir0=[ASC])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], stringField=[$1])\n"
+ " ArrowFilter(condition=[IS NOT NULL($0)])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=0; stringField=0\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Disabled("IS NULL is not supported yet")
@Test void testArrowProjectFieldsWithIsNullFilter() {
String sql = "select \"intField\", \"stringField\"\n"
+ "from arrowdata\n"
+ "where \"intField\" is null";
String plan = "ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], stringField=[$1])\n"
+ " ArrowFilter(condition=[IS NOT NULL($0)])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returnsCount(0)
.explainContains(plan);
}
@Test void testArrowProjectFieldsWithFloatFilter() {
String sql = "select * from arrowdata\n"
+ " where \"floatField\"=15.0";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowFilter(condition=[=(CAST($2):DOUBLE, 15.0)])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=15; stringField=15; floatField=15.0; longField=15\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testArrowProjectFieldsWithFilterOnLaterBatch() {
String sql = "select \"intField\"\n"
+ "from arrowdata\n"
+ "where \"intField\"=25";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0])\n"
+ " ArrowFilter(condition=[=($0, 25)])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=25\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testArrowSubquery() {
String sql = "select \"intField\"\n"
+ "from (select \"intField\", \"stringField\" from arrowdata where \"stringField\" = '2')\n"
+ "where \"intField\" = 2";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0])\n"
+ " ArrowFilter(condition=[AND(=($1, '2'), =($0, 2))])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n"
+ "\n";
String result = "intField=2\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Disabled("UNION does not work")
@Test void testArrowUnion() {
String sql = "(select \"intField\"\n"
+ "from arrowdata\n"
+ "where \"intField\" = 2)\n"
+ " union \n"
+ "(select \"intField\"\n"
+ "from arrowdata\n"
+ "where \"intField\" = 1)\n";
String plan = "PLAN=EnumerableUnion(all=[false])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0])\n"
+ " ArrowFilter(condition=[=($0, 2)])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0])\n"
+ " ArrowFilter(condition=[=($0, 1)])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=1\nintField=2\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testFieldWithSpace() {
String sql = "select \"my Field\" from (select \"intField\", \"stringField\" as \"my Field\"\n"
+ "from arrowdata)\n"
+ "where \"my Field\" = '2'";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(my Field=[$1])\n"
+ " ArrowFilter(condition=[=($1, '2')])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "my Field=2\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Disabled("literal with space is not supported")
@Test void testLiteralWithSpace() {
String sql = "select \"intField\", \"stringField\" as \"my Field\"\n"
+ "from arrowdata\n"
+ "where \"stringField\" = 'literal with space'";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], my Field=[$1])\n"
+ " ArrowFilter(condition=[=($1, '2')])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testLiteralWithQuote() {
String sql = "select \"intField\", \"stringField\" as \"my Field\"\n"
+ "from arrowdata\n"
+ "where \"stringField\" = ''''";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], stringField=[$1])\n"
+ " ArrowFilter(condition=[=($1, '''')])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testTinyIntProject() {
String sql = "select DEPTNO from DEPT";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(DEPTNO=[$0])\n"
+ " ArrowTableScan(table=[[ARROW, DEPT]], fields=[[0, 1, 2]])\n\n";
String result = "DEPTNO=10\nDEPTNO=20\nDEPTNO=30\nDEPTNO=40\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testSmallIntProject() {
String sql = "select EMPNO from EMP";
String plan = "PLAN=ArrowToEnumerableConverter\n"
+ " ArrowProject(EMPNO=[$0])\n"
+ " ArrowTableScan(table=[[ARROW, EMP]], fields=[[0, 1, 2, 3, 4, 5, 6, 7]])\n\n";
String result = "EMPNO=7369\nEMPNO=7499\nEMPNO=7521\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(3)
.returns(result)
.explainContains(plan);
}
@Test void testCastDecimalToInt() {
String sql = "select CAST(LOSAL AS INT) as \"trunc\" from SALGRADE";
String plan =
"PLAN=EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t1):INTEGER], trunc=[$t3])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, SALGRADE]], fields=[[0, 1, 2]])\n\n";
String result = "trunc=700\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.typeIs("[trunc INTEGER]")
.limit(1)
.returns(result)
.explainContains(plan);
}
@Test void testCastDecimalToFloat() {
String sql = "select CAST(LOSAL AS FLOAT) as \"extra\" from SALGRADE";
String plan = "PLAN=EnumerableCalc(expr#0..2=[{inputs}],"
+ " expr#3=[CAST($t1):FLOAT], extra=[$t3])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, SALGRADE]], fields=[[0, 1, 2]])\n\n";
String result = "extra=700.0\nextra=1201.0\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.typeIs("[extra FLOAT]")
.limit(2)
.returns(result)
.explainContains(plan);
}
@Test void testCastDecimalToDouble() {
String sql = "select CAST(LOSAL AS DOUBLE) as \"extra\" from SALGRADE";
String plan =
"PLAN=EnumerableCalc(expr#0..2=[{inputs}], expr#3=[CAST($t1):DOUBLE], extra=[$t3])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, SALGRADE]], fields=[[0, 1, 2]])\n\n";
String result = "extra=700.0\nextra=1201.0\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.typeIs("[extra DOUBLE]")
.limit(2)
.returns(result)
.explainContains(plan);
}
@Test void testCastIntToDouble() {
String sql = "select CAST(\"intField\" AS DOUBLE) as \"dbl\" from arrowdata";
String plan =
"PLAN=EnumerableCalc(expr#0..3=[{inputs}], expr#4=[CAST($t0):DOUBLE], dbl=[$t4])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "dbl=0.0\ndbl=1.0\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.typeIs("[dbl DOUBLE]")
.limit(2)
.returns(result)
.explainContains(plan);
}
@Test void testStringOperation() {
String sql = "select\n"
+ " \"stringField\" || '_suffix' as \"field1\"\n"
+ "from arrowdata";
String plan = "PLAN=EnumerableCalc(expr#0..3=[{inputs}], expr#4=['_suffix'], "
+ "expr#5=[||($t1, $t4)], field1=[$t5])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "field1=0_suffix\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(1)
.returns(result)
.explainContains(plan);
}
@Disabled("join is not supported yet")
@Test void testJoin() {
String sql = "select t1.\"intField\", t2.\"intField\" "
+ "from arrowdata t1 join arrowdata t2 on t1.\"intField\" = t2.\"intField\"";
String plan = "PLAN=EnumerableJoin(condition=[=($0, $4)], joinType=[inner])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=0\nintField=1\nintField=2\nintField=3\nintField=4\nintField=5\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(1)
.returns(result)
.explainContains(plan);
}
@Test void testAggWithoutAggFunctions() {
String sql = "select DISTINCT(\"intField\") as \"dep\" from arrowdata";
String plan = "PLAN=EnumerableAggregate(group=[{0}])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "dep=0\ndep=1\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(2)
.returns(result)
.explainContains(plan);
}
@Test void testAggWithAggFunctions() {
String sql = "select JOB, SUM(SAL) as TOTAL from EMP GROUP BY JOB";
String plan = "PLAN=EnumerableAggregate(group=[{2}], TOTAL=[SUM($5)])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, EMP]], fields=[[0, 1, 2, 3, 4, 5, 6, 7]])\n\n";
String result = "JOB=SALESMAN; TOTAL=5600.00\nJOB=ANALYST; TOTAL=6000.00\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(2)
.returns(result)
.explainContains(plan);
}
@Test void testFilteredAgg() {
String sql = "select SUM(SAL) FILTER (WHERE COMM > 400) as SALESSUM from EMP";
String plan = "PLAN=EnumerableAggregate(group=[{}], SALESSUM=[SUM($0) FILTER $1])\n"
+ " EnumerableCalc(expr#0..7=[{inputs}], expr#8=[400], expr#9=[>($t6, $t8)], "
+ "expr#10=[IS TRUE($t9)], SAL=[$t5], $f1=[$t10])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, EMP]], fields=[[0, 1, 2, 3, 4, 5, 6, 7]])\n\n";
String result = "SALESSUM=2500.00\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(2)
.returns(result)
.explainContains(plan);
}
@Test void testFilteredAggGroupBy() {
String sql = "select SUM(SAL) FILTER (WHERE COMM > 400) as SALESSUM from EMP group by EMPNO";
String plan = "PLAN=EnumerableCalc(expr#0..1=[{inputs}], SALESSUM=[$t1])\n"
+ " EnumerableAggregate(group=[{0}], SALESSUM=[SUM($1) FILTER $2])\n"
+ " EnumerableCalc(expr#0..7=[{inputs}], expr#8=[400], expr#9=[>($t6, $t8)], "
+ "expr#10=[IS TRUE($t9)], EMPNO=[$t0], SAL=[$t5], $f2=[$t10])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, EMP]], fields=[[0, 1, 2, 3, 4, 5, 6, 7]])\n\n";
String result = "SALESSUM=1250.00\nSALESSUM=null\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(2)
.returns(result)
.explainContains(plan);
}
@Test void testAggGroupedByNullable() {
String sql = "select COMM, SUM(SAL) as SALESSUM from EMP GROUP BY COMM";
String plan = "PLAN=EnumerableAggregate(group=[{6}], SALESSUM=[SUM($5)])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, EMP]], fields=[[0, 1, 2, 3, 4, 5, 6, 7]])\n\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returnsUnordered("COMM=0.00; SALESSUM=1500.00",
"COMM=1400.00; SALESSUM=1250.00",
"COMM=300.00; SALESSUM=1600.00",
"COMM=500.00; SALESSUM=1250.00",
"COMM=null; SALESSUM=23425.00")
.explainContains(plan);
}
@Test void testArrowAdapterLimitNoSort() {
String sql = "select \"intField\"\n"
+ "from arrowdata\n"
+ "limit 2";
String plan = "PLAN=EnumerableCalc(expr#0..3=[{inputs}], intField=[$t0])\n"
+ " EnumerableLimit(fetch=[2])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=0\nintField=1\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testArrowLimitOffsetNoSort() {
String sql = "select \"intField\"\n"
+ "from arrowdata\n"
+ "limit 2 offset 2";
String plan = "PLAN=EnumerableCalc(expr#0..3=[{inputs}], intField=[$t0])\n"
+ " EnumerableLimit(offset=[2], fetch=[2])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=2\nintField=3\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.returns(result)
.explainContains(plan);
}
@Test void testArrowSortOnLong() {
String sql = "select \"intField\" from arrowdata order by \"longField\" desc";
String plan = "PLAN=EnumerableSort(sort0=[$1], dir0=[DESC])\n"
+ " ArrowToEnumerableConverter\n"
+ " ArrowProject(intField=[$0], longField=[$3])\n"
+ " ArrowTableScan(table=[[ARROW, ARROWDATA]], fields=[[0, 1, 2, 3]])\n\n";
String result = "intField=49\nintField=48\n";
CalciteAssert.that()
.with(arrow)
.query(sql)
.limit(2)
.returns(result)
.explainContains(plan);
}
}