use of com.hazelcast.sql.impl.exec.scan.index.IndexFilter in project hazelcast by hazelcast.
the class MapIndexScanPTest method test_pointLookup_hashed.
// We also don't test full hash index scan, because such plan aren't allowed to be created.
@Test
public void test_pointLookup_hashed() {
List<JetSqlRow> expected = new ArrayList<>();
for (int i = count; i > 0; i--) {
map.put(i, new Person("value-" + i, i));
}
expected.add(jetRow((5), "value-5", 5));
IndexConfig indexConfig = new IndexConfig(IndexType.HASH, "age").setName(randomName());
map.addIndex(indexConfig);
IndexFilter filter = new IndexEqualsFilter(intValue(5));
MapIndexScanMetadata metadata = metadata(indexConfig.getName(), filter, -1, false);
TestSupport.verifyProcessor(adaptSupplier(MapIndexScanP.readMapIndexSupplier(metadata))).hazelcastInstance(instance()).jobConfig(new JobConfig().setArgument(SQL_ARGUMENTS_KEY_NAME, emptyList())).outputChecker(LENIENT_SAME_ITEMS_IN_ORDER).disableSnapshots().disableProgressAssertion().expectOutput(expected);
}
use of com.hazelcast.sql.impl.exec.scan.index.IndexFilter in project hazelcast by hazelcast.
the class MapIndexScanPTest method test_whenFilterExistsWithoutSpecificProjection_sorted.
@Test
public void test_whenFilterExistsWithoutSpecificProjection_sorted() {
List<JetSqlRow> expected = new ArrayList<>();
for (int i = count; i > 0; i--) {
map.put(i, new Person("value-" + i, i));
if (i > count / 2) {
expected.add(jetRow((count - i + 1), "value-" + (count - i + 1), (count - i + 1)));
}
}
IndexConfig indexConfig = new IndexConfig(IndexType.SORTED, "age").setName(randomName());
map.addIndex(indexConfig);
IndexFilter filter = new IndexRangeFilter(intValue(0), true, intValue(count / 2), true);
MapIndexScanMetadata metadata = metadata(indexConfig.getName(), filter, 2, false);
TestSupport.verifyProcessor(adaptSupplier(MapIndexScanP.readMapIndexSupplier(metadata))).hazelcastInstance(instance()).jobConfig(new JobConfig().setArgument(SQL_ARGUMENTS_KEY_NAME, emptyList())).outputChecker(LENIENT_SAME_ITEMS_IN_ORDER).disableSnapshots().disableProgressAssertion().expectOutput(expected);
}
use of com.hazelcast.sql.impl.exec.scan.index.IndexFilter in project hazelcast by hazelcast.
the class IndexResolver method createIndexScan.
private static IndexScanMapPhysicalRel createIndexScan(FullScanLogicalRel scan, MapTableIndex index, List<RexNode> conjunctions, List<IndexComponentFilter> filterDescriptors, List<Boolean> ascs) {
// Collect filters and relevant expressions
List<IndexFilter> filters = new ArrayList<>(filterDescriptors.size());
Set<RexNode> exps = new HashSet<>();
for (IndexComponentFilter filterDescriptor : filterDescriptors) {
filters.add(filterDescriptor.getFilter());
exps.addAll(filterDescriptor.getExpressions());
}
// Construct Calcite expressions.
RexBuilder rexBuilder = scan.getCluster().getRexBuilder();
RexNode exp = RexUtil.composeConjunction(rexBuilder, exps);
List<RexNode> remainderConjunctiveExps = excludeNodes(conjunctions, exps);
RexNode remainderExp = remainderConjunctiveExps.isEmpty() ? null : RexUtil.composeConjunction(rexBuilder, remainderConjunctiveExps);
// Prepare traits
RelTraitSet traitSet = scan.getTraitSet();
// Make a collation trait
RelCollation relCollation = buildCollationTrait(scan, index, ascs);
traitSet = OptUtils.traitPlus(traitSet, relCollation);
// Prepare table
HazelcastRelOptTable originalRelTable = (HazelcastRelOptTable) scan.getTable();
HazelcastTable originalHazelcastTable = OptUtils.extractHazelcastTable(scan);
RelOptTable newRelTable = createRelTable(originalRelTable, originalHazelcastTable.withFilter(null), scan.getCluster().getTypeFactory());
// Try composing the final filter out of the isolated component filters if possible
IndexFilter filter = composeFilter(filters, index.getType(), index.getComponentsCount());
if (filter == null) {
return null;
}
// Construct the scan
return new IndexScanMapPhysicalRel(scan.getCluster(), OptUtils.toPhysicalConvention(traitSet), newRelTable, index, filter, exp, remainderExp);
}
use of com.hazelcast.sql.impl.exec.scan.index.IndexFilter in project hazelcast by hazelcast.
the class IndexResolver method composeInFilter.
/**
* Create the final IN filter from the collection of per-column filters.
* <p>
* Consider the expression {@code {a=1 AND b IN (2,3)}}. After the conversion, the composite filter will be
* {@code {a,b} IN {{1, 2}, {1, 3}}}.
*
* @param filters per-column filters
* @param lastFilter the last IN filter
* @param indexComponentsCount the number of index components
* @return composite IN filter
*/
private static IndexFilter composeInFilter(List<IndexFilter> filters, IndexInFilter lastFilter, IndexType indexType, int indexComponentsCount) {
List<IndexFilter> newFilters = new ArrayList<>(lastFilter.getFilters().size());
for (IndexFilter filter : lastFilter.getFilters()) {
assert filter instanceof IndexEqualsFilter;
IndexFilter newFilter = composeEqualsFilter(filters, (IndexEqualsFilter) filter, indexType, indexComponentsCount);
if (newFilter == null) {
// Cannot create a filter for one of the values of the IN clause. Stop.
return null;
}
newFilters.add(newFilter);
}
return new IndexInFilter(newFilters);
}
use of com.hazelcast.sql.impl.exec.scan.index.IndexFilter in project hazelcast by hazelcast.
the class IndexResolver method prepareSingleColumnCandidateIsNull.
/**
* Try creating a candidate filter for the "IS NULL" expression.
* <p>
* Returns the filter EQUALS(null) with "allowNulls-true".
*
* @param exp original expression, e.g. {col IS NULL}
* @param operand operand, e.g. {col}; CAST must be unwrapped before the method is invoked
* @return candidate or {@code null}
*/
private static IndexComponentCandidate prepareSingleColumnCandidateIsNull(RexNode exp, RexNode operand) {
if (operand.getKind() != SqlKind.INPUT_REF) {
// The operand is not a column, e.g. {'literal' IS NULL}, index cannot be used
return null;
}
int columnIndex = ((RexInputRef) operand).getIndex();
QueryDataType type = HazelcastTypeUtils.toHazelcastType(operand.getType());
// Create a value with "allowNulls=true"
IndexFilterValue filterValue = new IndexFilterValue(singletonList(ConstantExpression.create(null, type)), singletonList(true));
IndexFilter filter = new IndexEqualsFilter(filterValue);
return new IndexComponentCandidate(exp, columnIndex, filter);
}
Aggregations