com.hazelcast.org.apache.calcite.rel.core.TableScan 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.rel.core;
import com.hazelcast.org.apache.calcite.plan.RelOptCluster;
import com.hazelcast.org.apache.calcite.plan.RelOptCost;
import com.hazelcast.org.apache.calcite.plan.RelOptPlanner;
import com.hazelcast.org.apache.calcite.plan.RelOptTable;
import com.hazelcast.org.apache.calcite.plan.RelTraitSet;
import com.hazelcast.org.apache.calcite.rel.AbstractRelNode;
import com.hazelcast.org.apache.calcite.rel.RelCollation;
import com.hazelcast.org.apache.calcite.rel.RelInput;
import com.hazelcast.org.apache.calcite.rel.RelNode;
import com.hazelcast.org.apache.calcite.rel.RelShuttle;
import com.hazelcast.org.apache.calcite.rel.RelWriter;
import com.hazelcast.org.apache.calcite.rel.hint.Hintable;
import com.hazelcast.org.apache.calcite.rel.hint.RelHint;
import com.hazelcast.org.apache.calcite.rel.metadata.RelMetadataQuery;
import com.hazelcast.org.apache.calcite.rel.type.RelDataType;
import com.hazelcast.org.apache.calcite.rel.type.RelDataTypeField;
import com.hazelcast.org.apache.calcite.rex.RexBuilder;
import com.hazelcast.org.apache.calcite.rex.RexNode;
import com.hazelcast.org.apache.calcite.tools.RelBuilder;
import com.hazelcast.org.apache.calcite.util.ImmutableBitSet;
import com.hazelcast.org.apache.calcite.util.ImmutableIntList;
import com.hazelcast.com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* Relational operator that returns the contents of a table.
*/
public abstract class TableScan
extends AbstractRelNode implements Hintable {
//~ Instance fields --------------------------------------------------------
/**
* The table definition.
*/
protected final RelOptTable table;
/**
* The table hints.
*/
protected final ImmutableList hints;
//~ Constructors -----------------------------------------------------------
protected TableScan(RelOptCluster cluster, RelTraitSet traitSet,
List hints, RelOptTable table) {
super(cluster, traitSet);
this.table = table;
if (table.getRelOptSchema() != null) {
cluster.getPlanner().registerSchema(table.getRelOptSchema());
}
this.hints = ImmutableList.copyOf(hints);
}
@Deprecated // to be removed before 2.0
protected TableScan(RelOptCluster cluster, RelTraitSet traitSet,
RelOptTable table) {
this(cluster, traitSet, ImmutableList.of(), table);
}
/**
* Creates a TableScan by parsing serialized output.
*/
protected TableScan(RelInput input) {
this(input.getCluster(), input.getTraitSet(), ImmutableList.of(), input.getTable("table"));
}
//~ Methods ----------------------------------------------------------------
@Override public double estimateRowCount(RelMetadataQuery mq) {
return table.getRowCount();
}
@Override public RelOptTable getTable() {
return table;
}
@SuppressWarnings("deprecation")
@Override public List getCollationList() {
return table.getCollationList();
}
@Override public RelOptCost computeSelfCost(RelOptPlanner planner,
RelMetadataQuery mq) {
double dRows = table.getRowCount();
double dCpu = dRows + 1; // ensure non-zero cost
double dIo = 0;
return planner.getCostFactory().makeCost(dRows, dCpu, dIo);
}
@Override public RelDataType deriveRowType() {
return table.getRowType();
}
/** Returns an identity projection for the given table. */
public static ImmutableIntList identity(RelOptTable table) {
return ImmutableIntList.identity(table.getRowType().getFieldCount());
}
/** Returns an identity projection. */
public ImmutableIntList identity() {
return identity(table);
}
@Override public RelWriter explainTerms(RelWriter pw) {
return super.explainTerms(pw)
.item("table", table.getQualifiedName());
}
/**
* Projects a subset of the fields of the table, and also asks for "extra"
* fields that were not included in the table's official type.
*
* The default implementation assumes that tables cannot do either of
* these operations, therefore it adds a {@link Project} that projects
* {@code NULL} values for the extra fields, using the
* {@link RelBuilder#project(Iterable)} method.
*
*
Sub-classes, representing table types that have these capabilities,
* should override.
*
* @param fieldsUsed Bitmap of the fields desired by the consumer
* @param extraFields Extra fields, not advertised in the table's row-type,
* wanted by the consumer
* @param relBuilder Builder used to create a Project
* @return Relational expression that projects the desired fields
*/
public RelNode project(ImmutableBitSet fieldsUsed,
Set extraFields,
RelBuilder relBuilder) {
final int fieldCount = getRowType().getFieldCount();
if (fieldsUsed.equals(ImmutableBitSet.range(fieldCount))
&& extraFields.isEmpty()) {
return this;
}
int fieldSize = fieldsUsed.size() + extraFields.size();
final List exprList = new ArrayList<>(fieldSize);
final List nameList = new ArrayList<>(fieldSize);
final RexBuilder rexBuilder = getCluster().getRexBuilder();
final List fields = getRowType().getFieldList();
// Project the subset of fields.
for (int i : fieldsUsed) {
RelDataTypeField field = fields.get(i);
exprList.add(rexBuilder.makeInputRef(this, i));
nameList.add(field.getName());
}
// Project nulls for the extra fields. (Maybe a sub-class table has
// extra fields, but we don't.)
for (RelDataTypeField extraField : extraFields) {
exprList.add(rexBuilder.makeNullLiteral(extraField.getType()));
nameList.add(extraField.getName());
}
return relBuilder.push(this).project(exprList, nameList).build();
}
@Override public RelNode accept(RelShuttle shuttle) {
return shuttle.visit(this);
}
@Override public ImmutableList getHints() {
return hints;
}
}