Search in sources :

Example 6 with RecordQueryScanPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan in project fdb-record-layer by FoundationDB.

the class ExpressionMatcherTest method nestedTypeMatchers.

@Test
public void nestedTypeMatchers() {
    BindingMatcher<RecordQueryIndexPlan> childMatcher1 = RecordQueryPlanMatchers.indexPlan();
    BindingMatcher<RecordQueryScanPlan> childMatcher2 = RecordQueryPlanMatchers.scanPlan();
    BindingMatcher<RecordQueryUnionPlan> parentMatcher = RecordQueryPlanMatchers.union(ListMatcher.exactly(QuantifierMatchers.physicalQuantifier(childMatcher1), QuantifierMatchers.physicalQuantifier(childMatcher2)));
    IndexScanParameters fullValueScan = IndexScanComparisons.byValue();
    RecordQueryIndexPlan child1 = new RecordQueryIndexPlan("an_index", fullValueScan, true);
    RecordQueryScanPlan child2 = new RecordQueryScanPlan(ScanComparisons.EMPTY, true);
    // check matches if the children are in the right order
    RelationalExpression root = // union with arbitrary comparison key
    RecordQueryUnionPlan.from(child1, child2, EmptyKeyExpression.EMPTY, false);
    Optional<PlannerBindings> possibleBindings = parentMatcher.bindMatches(PlannerBindings.empty(), root).findFirst();
    assertTrue(possibleBindings.isPresent());
    PlannerBindings allBindings = possibleBindings.get().mergedWith(getExistingBindings());
    assertExistingBindingsSurvived(allBindings);
    assertEquals(root, allBindings.get(parentMatcher));
    assertEquals(child1, allBindings.get(childMatcher1));
    assertEquals(child2, allBindings.get(childMatcher2));
    // check that we fail to match if the children are in the wrong order
    root = // union with arbitrary comparison key
    RecordQueryUnionPlan.from(child2, child1, EmptyKeyExpression.EMPTY, false);
    assertFalse(parentMatcher.bindMatches(PlannerBindings.empty(), root).findFirst().isPresent());
}
Also used : IndexScanParameters(com.apple.foundationdb.record.provider.foundationdb.IndexScanParameters) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) RecordQueryUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlan) RecordQueryScanPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) Test(org.junit.jupiter.api.Test)

Example 7 with RecordQueryScanPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan in project fdb-record-layer by FoundationDB.

the class ExpressionMatcherTest method matchChildOrder.

@Test
public void matchChildOrder() {
    BindingMatcher<RecordQueryUnionPlan> parentMatcher = RecordQueryPlanMatchers.union(ListMatcher.exactly(QuantifierMatchers.physicalQuantifier(RecordQueryPlanMatchers.indexPlan()), QuantifierMatchers.physicalQuantifier(RecordQueryPlanMatchers.scanPlan())));
    IndexScanParameters fullValueScan = IndexScanComparisons.byValue();
    RecordQueryIndexPlan child1 = new RecordQueryIndexPlan("an_index", fullValueScan, true);
    RecordQueryScanPlan child2 = new RecordQueryScanPlan(ScanComparisons.EMPTY, true);
    RelationalExpression root = // union with arbitrary comparison key
    RecordQueryUnionPlan.from(child1, child2, EmptyKeyExpression.EMPTY, false);
    assertTrue(parentMatcher.bindMatches(PlannerBindings.empty(), root).findFirst().isPresent());
    root = // union with arbitrary comparison key
    RecordQueryUnionPlan.from(child2, child1, EmptyKeyExpression.EMPTY, false);
    assertFalse(parentMatcher.bindMatches(PlannerBindings.empty(), root).findFirst().isPresent());
}
Also used : IndexScanParameters(com.apple.foundationdb.record.provider.foundationdb.IndexScanParameters) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) RecordQueryUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlan) RecordQueryScanPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) Test(org.junit.jupiter.api.Test)

Example 8 with RecordQueryScanPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan in project fdb-record-layer by FoundationDB.

the class ExpressionMatcherTest method matchChildrenAsReferences.

@Test
public void matchChildrenAsReferences() {
    BindingMatcher<? extends ExpressionRef<? extends RelationalExpression>> childMatcher1 = ReferenceMatchers.anyRef();
    BindingMatcher<? extends ExpressionRef<? extends RelationalExpression>> childMatcher2 = ReferenceMatchers.anyRef();
    BindingMatcher<RecordQueryUnionPlan> matcher = RecordQueryPlanMatchers.union(ListMatcher.exactly(QuantifierMatchers.physicalQuantifierOverRef(childMatcher1), QuantifierMatchers.physicalQuantifierOverRef(childMatcher2)));
    IndexScanParameters fullValueScan = IndexScanComparisons.byValue();
    RecordQueryIndexPlan child1 = new RecordQueryIndexPlan("an_index", fullValueScan, true);
    RecordQueryScanPlan child2 = new RecordQueryScanPlan(ScanComparisons.EMPTY, true);
    RelationalExpression root = // union with arbitrary comparison key
    RecordQueryUnionPlan.from(child1, child2, EmptyKeyExpression.EMPTY, false);
    Optional<PlannerBindings> possibleBindings = matcher.bindMatches(PlannerBindings.empty(), root).findFirst();
    assertTrue(possibleBindings.isPresent());
    PlannerBindings newBindings = possibleBindings.get().mergedWith(getExistingBindings());
    assertExistingBindingsSurvived(newBindings);
    // check that root matches
    assertEquals(root, newBindings.get(matcher));
    // check that children are behind references
    assertEquals(child1, newBindings.get(childMatcher1).get());
    assertEquals(child2, newBindings.get(childMatcher2).get());
}
Also used : IndexScanParameters(com.apple.foundationdb.record.provider.foundationdb.IndexScanParameters) RelationalExpression(com.apple.foundationdb.record.query.plan.temp.RelationalExpression) RecordQueryUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlan) RecordQueryScanPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) Test(org.junit.jupiter.api.Test)

Example 9 with RecordQueryScanPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan in project fdb-record-layer by FoundationDB.

the class RecordQueryPlanner method planScan.

@Nonnull
private RecordQueryPlan planScan(@Nonnull CandidateScan candidateScan, @Nonnull IndexScanComparisons indexScanComparisons, boolean strictlySorted) {
    RecordQueryPlan plan;
    Set<String> possibleTypes;
    if (candidateScan.index == null) {
        final ScanComparisons scanComparisons = indexScanComparisons.getComparisons();
        if (primaryKeyHasRecordTypePrefix && RecordTypeKeyComparison.hasRecordTypeKeyComparison(scanComparisons)) {
            possibleTypes = RecordTypeKeyComparison.recordTypeKeyComparisonTypes(scanComparisons);
        } else {
            possibleTypes = metaData.getRecordTypes().keySet();
        }
        plan = new RecordQueryScanPlan(possibleTypes, scanComparisons, candidateScan.reverse, strictlySorted);
    } else {
        plan = new RecordQueryIndexPlan(candidateScan.index.getName(), indexScanComparisons, candidateScan.reverse, strictlySorted);
        possibleTypes = getPossibleTypes(candidateScan.index);
    }
    // Add a type filter if the query plan might return records of more types than the query specified
    plan = addTypeFilterIfNeeded(candidateScan, plan, possibleTypes);
    return plan;
}
Also used : RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) TimeWindowScanComparisons(com.apple.foundationdb.record.provider.foundationdb.leaderboard.TimeWindowScanComparisons) IndexScanComparisons(com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons) RecordQueryScanPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) Nonnull(javax.annotation.Nonnull)

Example 10 with RecordQueryScanPlan

use of com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan in project fdb-record-layer by FoundationDB.

the class PlanOrderingKey method forPlan.

@Nullable
public static PlanOrderingKey forPlan(@Nonnull RecordMetaData metaData, @Nonnull RecordQueryPlan queryPlan, @Nullable KeyExpression primaryKey) {
    if (primaryKey == null) {
        return null;
    }
    while (queryPlan instanceof RecordQueryFilterPlan) {
        queryPlan = ((RecordQueryFilterPlan) queryPlan).getInnerPlan();
    }
    if (queryPlan instanceof RecordQueryPlanWithIndex) {
        final RecordQueryPlanWithIndex indexPlan = (RecordQueryPlanWithIndex) queryPlan;
        final Index index = metaData.getIndex(indexPlan.getIndexName());
        final List<KeyExpression> keys = new ArrayList<>(index.getRootExpression().normalizeKeyForPositions());
        int pkeyStart = keys.size();
        int pKeyTail = pkeyStart;
        // Primary keys come after index value keys, unless they were already part of it.
        for (KeyExpression pkey : primaryKey.normalizeKeyForPositions()) {
            int pos = keys.indexOf(pkey);
            if (pos < 0) {
                keys.add(pkey);
            } else if (pkeyStart > pos) {
                pkeyStart = pos;
            }
        }
        final int prefixSize;
        if (indexPlan instanceof RecordQueryIndexPlan) {
            prefixSize = ((RecordQueryIndexPlan) indexPlan).getComparisons().getEqualitySize();
        } else if (indexPlan instanceof RecordQueryTextIndexPlan) {
            final TextScan textScan = ((RecordQueryTextIndexPlan) indexPlan).getTextScan();
            int groupingSize = textScan.getGroupingComparisons() != null ? textScan.getGroupingComparisons().getEqualitySize() : 0;
            int suffixSize = textScan.getSuffixComparisons() != null ? textScan.getSuffixComparisons().getEqualitySize() : 0;
            if (textScan.getTextComparison().getType().isEquality()) {
                // Can use the equality comparisons in the grouping columns and any columns after the text index
                // plus the text column itself.
                prefixSize = groupingSize + suffixSize + 1;
            } else {
                // by the token that the prefix scan just so happened to hit.
                return null;
            }
        } else {
            // Some unknown index plan. Maybe this should throw an error?
            return null;
        }
        return new PlanOrderingKey(keys, prefixSize, pkeyStart, pKeyTail);
    } else if (queryPlan instanceof RecordQueryScanPlan) {
        final RecordQueryScanPlan scanPlan = (RecordQueryScanPlan) queryPlan;
        return new PlanOrderingKey(primaryKey.normalizeKeyForPositions(), scanPlan.getComparisons().getEqualitySize(), 0, 0);
    } else if (queryPlan instanceof RecordQueryIntersectionPlan) {
        return forComparisonKey(((RecordQueryIntersectionPlan) queryPlan).getComparisonKey(), primaryKey);
    } else if (queryPlan instanceof RecordQueryUnionPlan) {
        return forComparisonKey(((RecordQueryUnionPlan) queryPlan).getComparisonKey(), primaryKey);
    } else {
        return null;
    }
}
Also used : RecordQueryUnionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlan) RecordQueryScanPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) ArrayList(java.util.ArrayList) RecordQueryIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) Index(com.apple.foundationdb.record.metadata.Index) RecordQueryTextIndexPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryTextIndexPlan) RecordQueryIntersectionPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryIntersectionPlan) RecordQueryFilterPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) Nullable(javax.annotation.Nullable)

Aggregations

RecordQueryScanPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryScanPlan)12 RecordQueryIndexPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryIndexPlan)7 Test (org.junit.jupiter.api.Test)6 IndexScanParameters (com.apple.foundationdb.record.provider.foundationdb.IndexScanParameters)5 RelationalExpression (com.apple.foundationdb.record.query.plan.temp.RelationalExpression)5 RecordQueryUnionPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryUnionPlan)4 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)3 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)2 RecordQueryFilterPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryFilterPlan)2 RecordQueryPlanWithIndex (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex)2 Quantifier (com.apple.foundationdb.record.query.plan.temp.Quantifier)2 LogicalFilterExpression (com.apple.foundationdb.record.query.plan.temp.expressions.LogicalFilterExpression)2 Nonnull (javax.annotation.Nonnull)2 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)1 Index (com.apple.foundationdb.record.metadata.Index)1 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)1 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)1 StoreTimer (com.apple.foundationdb.record.provider.common.StoreTimer)1 FDBStoreTimer (com.apple.foundationdb.record.provider.foundationdb.FDBStoreTimer)1 IndexScanComparisons (com.apple.foundationdb.record.provider.foundationdb.IndexScanComparisons)1