com.hazelcast.sql.impl.calcite.opt.physical.MapIndexScanPhysicalRel Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved.
*
* Licensed 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.sql.impl.calcite.opt.physical;
import com.hazelcast.sql.impl.calcite.opt.AbstractMapScanRel;
import com.hazelcast.sql.impl.calcite.opt.cost.CostUtils;
import com.hazelcast.sql.impl.calcite.opt.physical.visitor.PhysicalRelVisitor;
import com.hazelcast.sql.impl.exec.scan.index.IndexFilter;
import com.hazelcast.sql.impl.schema.map.MapTableIndex;
import com.hazelcast.sql.impl.type.QueryDataType;
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.RelNode;
import com.hazelcast.org.apache.calcite.rel.RelWriter;
import com.hazelcast.org.apache.calcite.rel.metadata.RelMdUtil;
import com.hazelcast.org.apache.calcite.rel.metadata.RelMetadataQuery;
import com.hazelcast.org.apache.calcite.rex.RexNode;
import java.util.List;
/**
* Map index scan operator.
*/
public class MapIndexScanPhysicalRel extends AbstractMapScanRel implements PhysicalRel {
private final MapTableIndex index;
private final IndexFilter indexFilter;
private final List converterTypes;
private final RexNode indexExp;
private final RexNode remainderExp;
public MapIndexScanPhysicalRel(
RelOptCluster cluster,
RelTraitSet traitSet,
RelOptTable table,
MapTableIndex index,
IndexFilter indexFilter,
List converterTypes,
RexNode indexExp,
RexNode remainderExp
) {
super(cluster, traitSet, table);
this.index = index;
this.indexFilter = indexFilter;
this.converterTypes = converterTypes;
this.indexExp = indexExp;
this.remainderExp = remainderExp;
}
public MapTableIndex getIndex() {
return index;
}
public IndexFilter getIndexFilter() {
return indexFilter;
}
public List getConverterTypes() {
return converterTypes;
}
public RexNode getRemainderExp() {
return remainderExp;
}
@Override
public RelNode copy(RelTraitSet traitSet, List inputs) {
return new MapIndexScanPhysicalRel(
getCluster(),
traitSet,
getTable(),
index,
indexFilter,
converterTypes,
indexExp,
remainderExp
);
}
@Override
public void visit(PhysicalRelVisitor visitor) {
visitor.onMapIndexScan(this);
}
@Override
public RelWriter explainTerms(RelWriter pw) {
return super.explainTerms(pw)
.item("index", index.getName())
.item("indexExp", indexExp)
.item("remainderExp", remainderExp);
}
@Override
public double estimateRowCount(RelMetadataQuery mq) {
double rowCount = table.getRowCount();
if (indexExp != null) {
rowCount = CostUtils.adjustFilteredRowCount(rowCount, RelMdUtil.guessSelectivity(indexExp));
}
if (remainderExp != null) {
rowCount = CostUtils.adjustFilteredRowCount(rowCount, RelMdUtil.guessSelectivity(remainderExp));
}
return rowCount;
}
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
// Get the number of rows being scanned. This is either the whole index (scan), or only part of the index (lookup)
double scanRowCount = table.getRowCount();
if (indexExp != null) {
scanRowCount = CostUtils.adjustFilteredRowCount(scanRowCount, RelMdUtil.guessSelectivity(indexExp));
}
// Get the number of rows that we expect after the remainder filter is applied.
boolean hasFilter = remainderExp != null;
double filterRowCount = scanRowCount;
if (hasFilter) {
filterRowCount = CostUtils.adjustFilteredRowCount(filterRowCount, RelMdUtil.guessSelectivity(remainderExp));
}
return computeSelfCost(
planner,
scanRowCount,
CostUtils.indexScanCpuMultiplier(index.getType()),
hasFilter,
filterRowCount,
getTableUnwrapped().getProjects().size()
);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy