blob: 7bb65e6d0bc918da210c7af185f7824a21646ebd [file]
/*
* 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.datafusion.proto;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.arrow.memory.BufferAllocator;
import org.apache.arrow.memory.RootAllocator;
import org.apache.arrow.vector.BigIntVector;
import org.apache.arrow.vector.IntVector;
import org.apache.arrow.vector.VectorSchemaRoot;
import org.apache.arrow.vector.ipc.ArrowReader;
import org.apache.arrow.vector.types.DateUnit;
import org.apache.arrow.vector.types.pojo.ArrowType;
import org.apache.arrow.vector.types.pojo.Schema;
import org.apache.datafusion.DataFrame;
import org.apache.datafusion.SessionContext;
import org.apache.datafusion.protobuf.BareTableReference;
import org.apache.datafusion.protobuf.EmptyRelationNode;
import org.apache.datafusion.protobuf.ListingTableScanNode;
import org.apache.datafusion.protobuf.LogicalExprNode;
import org.apache.datafusion.protobuf.LogicalPlanNode;
import org.apache.datafusion.protobuf.ProjectionColumns;
import org.apache.datafusion.protobuf.ProjectionNode;
import org.apache.datafusion.protobuf.SortExprNode;
import org.apache.datafusion.protobuf.SortNode;
import org.apache.datafusion.protobuf.TableReference;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import datafusion_common.DatafusionCommon;
class SessionContextProtoTest {
@Test
void fromProtoExecutesProjectionOverEmptyRelation() throws Exception {
LogicalPlanNode plan =
LogicalPlanNode.newBuilder()
.setProjection(
ProjectionNode.newBuilder()
.setInput(
LogicalPlanNode.newBuilder()
.setEmptyRelation(
EmptyRelationNode.newBuilder().setProduceOneRow(true).build())
.build())
.addExpr(
LogicalExprNode.newBuilder()
.setLiteral(
DatafusionCommon.ScalarValue.newBuilder().setInt32Value(1).build())
.build())
.build())
.build();
try (BufferAllocator allocator = new RootAllocator();
SessionContext ctx = new SessionContext();
DataFrame df = ctx.fromProto(plan.toByteArray());
ArrowReader reader = df.collect(allocator)) {
assertTrue(reader.loadNextBatch());
VectorSchemaRoot root = reader.getVectorSchemaRoot();
assertEquals(1, root.getRowCount());
IntVector col = (IntVector) root.getVector(0);
assertEquals(1, col.get(0));
}
}
@Test
void tableSchemaReturnsExpectedLineitemFields() {
Path lineitem = Path.of("tpch-data/sf1/lineitem.parquet");
Assumptions.assumeTrue(
Files.exists(lineitem), "TPC-H SF1 data not found; run `make tpch-data` first");
try (SessionContext ctx = new SessionContext()) {
ctx.registerParquet("lineitem", lineitem.toAbsolutePath().toString());
Schema schema = ctx.tableSchema("lineitem");
assertEquals(16, schema.getFields().size());
assertEquals("l_orderkey", schema.getFields().get(0).getName());
assertTrue(schema.getFields().get(0).getType() instanceof ArrowType.Int);
// l_extendedprice = Decimal128(15, 2)
ArrowType.Decimal price = (ArrowType.Decimal) schema.findField("l_extendedprice").getType();
assertEquals(15, price.getPrecision());
assertEquals(2, price.getScale());
// l_shipdate = Date(DAY)
ArrowType.Date ship = (ArrowType.Date) schema.findField("l_shipdate").getType();
assertEquals(DateUnit.DAY, ship.getUnit());
}
}
@Test
void fromProtoListingScanMatchesSql() throws Exception {
Path lineitem = Path.of("tpch-data/sf1/lineitem.parquet");
Assumptions.assumeTrue(
Files.exists(lineitem), "TPC-H SF1 data not found; run `make tpch-data` first");
String absPath = lineitem.toAbsolutePath().toString();
try (BufferAllocator allocator = new RootAllocator();
SessionContext ctx = new SessionContext()) {
ctx.registerParquet("lineitem", absPath);
Schema arrow = ctx.tableSchema("lineitem");
DatafusionCommon.Schema schemaProto = SchemaConverter.toProto(arrow);
LogicalExprNode orderKeyExpr =
LogicalExprNode.newBuilder()
.setColumn(DatafusionCommon.Column.newBuilder().setName("l_orderkey").build())
.build();
LogicalPlanNode plan =
LogicalPlanNode.newBuilder()
.setSort(
SortNode.newBuilder()
.setInput(
LogicalPlanNode.newBuilder()
.setListingScan(
ListingTableScanNode.newBuilder()
.setTableName(
TableReference.newBuilder()
.setBare(
BareTableReference.newBuilder()
.setTable("lineitem")
.build())
.build())
.addPaths(absPath)
.setFileExtension(".parquet")
.setSchema(schemaProto)
.setProjection(
ProjectionColumns.newBuilder()
.addColumns("l_orderkey")
.build())
.setParquet(
DatafusionCommon.ParquetFormat.getDefaultInstance())
.setTargetPartitions(1)
.build())
.build())
.addExpr(
SortExprNode.newBuilder()
.setExpr(orderKeyExpr)
.setAsc(true)
.setNullsFirst(false)
.build())
.setFetch(1)
.build())
.build();
long protoValue;
try (DataFrame df = ctx.fromProto(plan.toByteArray());
ArrowReader reader = df.collect(allocator)) {
assertTrue(reader.loadNextBatch());
VectorSchemaRoot root = reader.getVectorSchemaRoot();
assertEquals(1, root.getRowCount());
protoValue = ((BigIntVector) root.getVector(0)).get(0);
}
long sqlValue;
try (DataFrame df = ctx.sql("SELECT l_orderkey FROM lineitem ORDER BY l_orderkey LIMIT 1");
ArrowReader reader = df.collect(allocator)) {
assertTrue(reader.loadNextBatch());
VectorSchemaRoot root = reader.getVectorSchemaRoot();
assertEquals(1, root.getRowCount());
sqlValue = ((BigIntVector) root.getVector(0)).get(0);
}
assertEquals(sqlValue, protoValue);
}
}
}