com.hazelcast.org.apache.calcite.interpreter.TableScanNode Maven / Gradle / Ivy
/*
* 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 com.hazelcast.org.apache.calcite.interpreter;
import com.hazelcast.org.apache.calcite.DataContext;
import com.hazelcast.org.apache.calcite.linq4j.Enumerable;
import com.hazelcast.org.apache.calcite.linq4j.Queryable;
import com.hazelcast.org.apache.calcite.linq4j.function.Function1;
import com.hazelcast.org.apache.calcite.plan.RelOptTable;
import com.hazelcast.org.apache.calcite.plan.RelOptUtil;
import com.hazelcast.org.apache.calcite.rel.core.TableScan;
import com.hazelcast.org.apache.calcite.rel.type.RelDataType;
import com.hazelcast.org.apache.calcite.rel.type.RelDataTypeFactory;
import com.hazelcast.org.apache.calcite.rel.type.RelDataTypeField;
import com.hazelcast.org.apache.calcite.rex.RexNode;
import com.hazelcast.org.apache.calcite.rex.RexUtil;
import com.hazelcast.org.apache.calcite.runtime.Enumerables;
import com.hazelcast.org.apache.calcite.schema.FilterableTable;
import com.hazelcast.org.apache.calcite.schema.ProjectableFilterableTable;
import com.hazelcast.org.apache.calcite.schema.QueryableTable;
import com.hazelcast.org.apache.calcite.schema.ScannableTable;
import com.hazelcast.org.apache.calcite.schema.SchemaPlus;
import com.hazelcast.org.apache.calcite.schema.Schemas;
import com.hazelcast.org.apache.calcite.util.ImmutableBitSet;
import com.hazelcast.org.apache.calcite.util.ImmutableIntList;
import com.hazelcast.org.apache.calcite.util.Util;
import com.hazelcast.org.apache.calcite.util.mapping.Mapping;
import com.hazelcast.org.apache.calcite.util.mapping.Mappings;
import com.hazelcast.com.google.common.collect.ImmutableList;
import com.hazelcast.com.google.common.collect.Iterables;
import com.hazelcast.com.google.common.collect.Lists;
import com.hazelcast.org.checkerframework.checker.nullness.qual.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.List;
import static com.hazelcast.org.apache.calcite.util.Static.RESOURCE;
import static java.util.Objects.requireNonNull;
/**
* Interpreter node that implements a
* {@link com.hazelcast.org.apache.calcite.rel.core.TableScan}.
*/
public class TableScanNode implements Node {
private TableScanNode(Compiler compiler, TableScan rel,
Enumerable enumerable) {
compiler.enumerable(rel, enumerable);
}
@Override public void run() {
// nothing to do
}
/** Creates a TableScanNode.
*
* Tries various table SPIs, and negotiates with the table which filters
* and projects it can implement. Adds to the Enumerable implementations of
* any filters and projects that cannot be implemented by the table. */
static TableScanNode create(Compiler compiler, TableScan rel,
ImmutableList filters, @Nullable ImmutableIntList projects) {
final RelOptTable relOptTable = rel.getTable();
final ProjectableFilterableTable pfTable =
relOptTable.unwrap(ProjectableFilterableTable.class);
if (pfTable != null) {
return createProjectableFilterable(compiler, rel, filters, projects,
pfTable);
}
final FilterableTable filterableTable =
relOptTable.unwrap(FilterableTable.class);
if (filterableTable != null) {
return createFilterable(compiler, rel, filters, projects,
filterableTable);
}
final ScannableTable scannableTable =
relOptTable.unwrap(ScannableTable.class);
if (scannableTable != null) {
return createScannable(compiler, rel, filters, projects,
scannableTable);
}
//noinspection unchecked
final Enumerable enumerable = relOptTable.unwrap(Enumerable.class);
if (enumerable != null) {
return createEnumerable(compiler, rel, enumerable, null, filters,
projects);
}
final QueryableTable queryableTable =
relOptTable.unwrap(QueryableTable.class);
if (queryableTable != null) {
return createQueryable(compiler, rel, filters, projects,
queryableTable);
}
throw new AssertionError("cannot convert table " + relOptTable
+ " to enumerable");
}
private static TableScanNode createScannable(Compiler compiler, TableScan rel,
ImmutableList filters, @Nullable ImmutableIntList projects,
ScannableTable scannableTable) {
final Enumerable rowEnumerable =
Enumerables.toRow(scannableTable.scan(compiler.getDataContext()));
return createEnumerable(compiler, rel, rowEnumerable, null, filters,
projects);
}
private static TableScanNode createQueryable(Compiler compiler,
TableScan rel, ImmutableList filters, @Nullable ImmutableIntList projects,
QueryableTable queryableTable) {
final DataContext root = compiler.getDataContext();
final RelOptTable relOptTable = rel.getTable();
final Type elementType = queryableTable.getElementType();
SchemaPlus schema = root.getRootSchema();
for (String name : Util.skipLast(relOptTable.getQualifiedName())) {
requireNonNull(schema, () ->
"schema is null while resolving " + name + " for table"
+ relOptTable.getQualifiedName());
schema = schema.getSubSchema(name);
}
final Enumerable rowEnumerable;
if (elementType instanceof Class) {
//noinspection unchecked
final Queryable