Search in sources :

Example 6 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class RecordQueryPlanner method computeIndexFilters.

private ScoredPlan computeIndexFilters(@Nonnull PlanContext planContext, @Nonnull final ScoredPlan plan) {
    if (plan.plan instanceof RecordQueryPlanWithIndex) {
        final RecordQueryPlanWithIndex indexPlan = (RecordQueryPlanWithIndex) plan.plan;
        final Index index = metaData.getIndex(indexPlan.getIndexName());
        final Collection<RecordType> recordTypes = metaData.recordTypesForIndex(index);
        if (recordTypes.size() != 1) {
            return plan;
        }
        final RecordType recordType = Iterables.getOnlyElement(recordTypes);
        final List<QueryComponent> unsatisfiedFilters = new ArrayList<>(plan.unsatisfiedFilters);
        final AvailableFields availableFieldsFromIndex = AvailableFields.fromIndex(recordType, index, indexTypes, planContext.commonPrimaryKey);
        final List<QueryComponent> indexFilters = Lists.newArrayListWithCapacity(unsatisfiedFilters.size());
        final List<QueryComponent> residualFilters = Lists.newArrayListWithCapacity(unsatisfiedFilters.size());
        FilterVisitor.partitionFilters(unsatisfiedFilters, availableFieldsFromIndex, indexFilters, residualFilters, null);
        if (!indexFilters.isEmpty()) {
            return plan.withFilters(residualFilters, indexFilters);
        }
    }
    return plan;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) RecordType(com.apple.foundationdb.record.metadata.RecordType) ArrayList(java.util.ArrayList) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) RecordQueryPlanWithIndex(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlanWithIndex) Index(com.apple.foundationdb.record.metadata.Index)

Example 7 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class GroupingValidator method findGroupFieldFilter.

private static boolean findGroupFieldFilter(@Nonnull List<QueryComponent> filters, @Nonnull FieldKeyExpression groupField, @Nonnull List<QueryComponent> groupFilters, @Nonnull List<Comparisons.Comparison> groupComparisons) {
    for (QueryComponent filter : filters) {
        if (filter instanceof FieldWithComparison) {
            FieldWithComparison comparisonFilter = (FieldWithComparison) filter;
            if (comparisonFilter.getFieldName().equals(groupField.getFieldName()) && (comparisonFilter.getComparison().getType() == Comparisons.Type.EQUALS || comparisonFilter.getComparison().getType() == Comparisons.Type.IS_NULL)) {
                groupFilters.add(filter);
                groupComparisons.add(comparisonFilter.getComparison());
                return true;
            }
        }
    }
    return false;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison)

Example 8 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class InExtractor method mapClauses.

private QueryComponent mapClauses(QueryComponent filter, BiFunction<ComponentWithComparison, List<FieldKeyExpression>, QueryComponent> mapper, @Nullable List<FieldKeyExpression> fields) {
    if (filter instanceof ComponentWithComparison) {
        final ComponentWithComparison withComparison = (ComponentWithComparison) filter;
        return mapper.apply(withComparison, fields);
    } else if (filter instanceof ComponentWithChildren) {
        ComponentWithChildren componentWithChildren = (ComponentWithChildren) filter;
        return componentWithChildren.withOtherChildren(componentWithChildren.getChildren().stream().map(component -> mapClauses(component, mapper, fields)).collect(Collectors.toList()));
    } else if (filter instanceof ComponentWithSingleChild) {
        ComponentWithSingleChild componentWithSingleChild = (ComponentWithSingleChild) filter;
        List<FieldKeyExpression> nestedFields = null;
        if (fields != null && (componentWithSingleChild instanceof NestedField || componentWithSingleChild instanceof OneOfThemWithComponent)) {
            nestedFields = new ArrayList<>(fields);
            nestedFields.add(Key.Expressions.field(((BaseField) componentWithSingleChild).getFieldName(), componentWithSingleChild instanceof NestedField ? KeyExpression.FanType.None : KeyExpression.FanType.FanOut));
        }
        return componentWithSingleChild.withOtherChild(mapClauses(componentWithSingleChild.getChild(), mapper, nestedFields));
    } else if (filter instanceof ComponentWithNoChildren) {
        return filter;
    } else {
        throw new Query.InvalidExpressionException("Unsupported query type " + filter.getClass());
    }
}
Also used : BiFunction(java.util.function.BiFunction) Bindings(com.apple.foundationdb.record.Bindings) PlanOrderingKey(com.apple.foundationdb.record.query.plan.PlanOrderingKey) ComponentWithSingleChild(com.apple.foundationdb.record.query.expressions.ComponentWithSingleChild) ComponentWithComparison(com.apple.foundationdb.record.query.expressions.ComponentWithComparison) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ArrayList(java.util.ArrayList) Key(com.apple.foundationdb.record.metadata.Key) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) ImmutableList(com.google.common.collect.ImmutableList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) ComponentWithNoChildren(com.apple.foundationdb.record.query.expressions.ComponentWithNoChildren) InSource(com.apple.foundationdb.record.query.plan.plans.InSource) InValuesSource(com.apple.foundationdb.record.query.plan.plans.InValuesSource) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) Query(com.apple.foundationdb.record.query.expressions.Query) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) RecordQueryInParameterJoinPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryInParameterJoinPlan) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) List(java.util.List) NestedField(com.apple.foundationdb.record.query.expressions.NestedField) OneOfThemWithComponent(com.apple.foundationdb.record.query.expressions.OneOfThemWithComponent) BaseField(com.apple.foundationdb.record.query.expressions.BaseField) OneOfThemWithComparison(com.apple.foundationdb.record.query.expressions.OneOfThemWithComparison) RecordQueryInValuesJoinPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryInValuesJoinPlan) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) API(com.apple.foundationdb.annotation.API) InParameterSource(com.apple.foundationdb.record.query.plan.plans.InParameterSource) ComponentWithChildren(com.apple.foundationdb.record.query.expressions.ComponentWithChildren) Collections(java.util.Collections) BaseField(com.apple.foundationdb.record.query.expressions.BaseField) Query(com.apple.foundationdb.record.query.expressions.Query) ComponentWithNoChildren(com.apple.foundationdb.record.query.expressions.ComponentWithNoChildren) ComponentWithChildren(com.apple.foundationdb.record.query.expressions.ComponentWithChildren) NestedField(com.apple.foundationdb.record.query.expressions.NestedField) ComponentWithSingleChild(com.apple.foundationdb.record.query.expressions.ComponentWithSingleChild) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) ComponentWithComparison(com.apple.foundationdb.record.query.expressions.ComponentWithComparison) OneOfThemWithComponent(com.apple.foundationdb.record.query.expressions.OneOfThemWithComponent)

Example 9 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class RecordQueryPlanner method planFilter.

/**
 * Plan the given filter, which can be the whole query or a branch of an {@code OR}.
 * @param planContext the plan context for the query
 * @param filter the filter to plan
 * @param needOrdering whether to populate {@link ScoredPlan#planOrderingKey} to facilitate combining sub-plans
 * @return the best plan or {@code null} if no suitable index exists
 */
@Nullable
private ScoredPlan planFilter(@Nonnull PlanContext planContext, @Nonnull QueryComponent filter, boolean needOrdering) {
    final InExtractor inExtractor = new InExtractor(filter);
    ScoredPlan withInAsOrUnion = null;
    if (planContext.query.getSort() != null) {
        final InExtractor savedExtractor = new InExtractor(inExtractor);
        boolean canSort = inExtractor.setSort(planContext.query.getSort(), planContext.query.isSortReverse());
        if (!canSort) {
            if (getConfiguration().shouldAttemptFailedInJoinAsUnion()) {
                withInAsOrUnion = planFilterWithInUnion(planContext, savedExtractor);
            } else if (getConfiguration().shouldAttemptFailedInJoinAsOr()) {
                // Can't implement as an IN join because of the sort order. Try as an OR instead.
                QueryComponent asOr = normalizeAndOrForInAsOr(inExtractor.asOr());
                if (!filter.equals(asOr)) {
                    withInAsOrUnion = planFilter(planContext, asOr);
                }
            }
        }
    } else if (needOrdering) {
        inExtractor.sortByClauses();
    }
    final ScoredPlan withInJoin = planFilterWithInJoin(planContext, inExtractor, needOrdering);
    if (withInAsOrUnion != null) {
        if (withInJoin == null || withInAsOrUnion.score > withInJoin.score || FieldWithComparisonCountProperty.evaluate(withInAsOrUnion.plan) < FieldWithComparisonCountProperty.evaluate(withInJoin.plan)) {
            return withInAsOrUnion;
        }
    }
    return withInJoin;
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) InExtractor(com.apple.foundationdb.record.query.plan.planning.InExtractor) Nullable(javax.annotation.Nullable)

Example 10 with QueryComponent

use of com.apple.foundationdb.record.query.expressions.QueryComponent in project fdb-record-layer by FoundationDB.

the class FDBRecordStore method mergeRecordTypeAndComponent.

@Nonnull
protected static QueryComponent mergeRecordTypeAndComponent(@Nonnull String recordType, @Nullable QueryComponent component) {
    if (component == null) {
        return new RecordTypeKeyComparison(recordType);
    }
    List<QueryComponent> components = new ArrayList<>();
    components.add(new RecordTypeKeyComparison(recordType));
    if (component instanceof AndComponent) {
        components.addAll(((AndComponent) component).getChildren());
    } else {
        components.add(component);
    }
    return Query.and(components);
}
Also used : QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) ArrayList(java.util.ArrayList) RecordTypeKeyComparison(com.apple.foundationdb.record.query.expressions.RecordTypeKeyComparison) Nonnull(javax.annotation.Nonnull)

Aggregations

QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)96 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)58 RecordQuery (com.apple.foundationdb.record.query.RecordQuery)44 Test (org.junit.jupiter.api.Test)41 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)37 ArrayList (java.util.ArrayList)30 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)29 FDBQueriedRecord (com.apple.foundationdb.record.provider.foundationdb.FDBQueriedRecord)25 Index (com.apple.foundationdb.record.metadata.Index)24 Nonnull (javax.annotation.Nonnull)23 Comparisons (com.apple.foundationdb.record.query.expressions.Comparisons)22 Message (com.google.protobuf.Message)22 Query (com.apple.foundationdb.record.query.expressions.Query)20 RecordQueryPlanner (com.apple.foundationdb.record.query.plan.RecordQueryPlanner)20 List (java.util.List)20 Collections (java.util.Collections)19 Nullable (javax.annotation.Nullable)18 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)18 PlanHashable (com.apple.foundationdb.record.PlanHashable)17 Expressions.field (com.apple.foundationdb.record.metadata.Key.Expressions.field)17