Search in sources :

Example 6 with NestingKeyExpression

use of com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression in project fdb-record-layer by FoundationDB.

the class RecordQueryPlanner method planOneOfThemWithComponent.

@Nullable
private ScoredPlan planOneOfThemWithComponent(@Nonnull CandidateScan candidateScan, @Nonnull KeyExpression indexExpr, @Nonnull OneOfThemWithComponent filter, @Nullable KeyExpression sort) {
    if (indexExpr instanceof FieldKeyExpression) {
        return null;
    } else if (indexExpr instanceof ThenKeyExpression) {
        ThenKeyExpression then = (ThenKeyExpression) indexExpr;
        return planOneOfThemWithComponent(candidateScan, then.getChildren().get(0), filter, sort);
    } else if (indexExpr instanceof NestingKeyExpression) {
        NestingKeyExpression indexNesting = (NestingKeyExpression) indexExpr;
        ScoredPlan plan = null;
        if (sort == null) {
            plan = planNesting(candidateScan, indexNesting, filter, null);
        } else if (sort instanceof FieldKeyExpression) {
            plan = null;
        } else if (sort instanceof ThenKeyExpression) {
            plan = null;
        } else if (sort instanceof NestingKeyExpression) {
            NestingKeyExpression sortNesting = (NestingKeyExpression) sort;
            plan = planNesting(candidateScan, indexNesting, filter, sortNesting);
        }
        if (plan != null) {
            List<QueryComponent> unsatisfied;
            if (!plan.unsatisfiedFilters.isEmpty()) {
                unsatisfied = Collections.singletonList(filter);
            } else {
                unsatisfied = Collections.emptyList();
            }
            // Right now it marks the whole nesting as unsatisfied, in theory there could be plans that handle that
            plan = new ScoredPlan(plan.score, plan.plan, unsatisfied, true);
        }
        return plan;
    }
    return null;
}
Also used : ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) Nullable(javax.annotation.Nullable)

Example 7 with NestingKeyExpression

use of com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression in project fdb-record-layer by FoundationDB.

the class RankComparisons method findComparison.

private void findComparison(@Nonnull QueryRecordFunctionWithComparison comparison, @Nonnull List<Index> indexes, @Nonnull List<QueryComponent> potentialGroupFilters, @Nonnull AtomicInteger counter) {
    RecordFunction<?> recordFunction = comparison.getFunction();
    // TODO: Should share with indexMaintainerForAggregateFunction
    // TODO: Move index-specific query planning behavior outside of planner (https://github.com/FoundationDB/fdb-record-layer/issues/17)
    List<String> requiredIndexTypes;
    if (recordFunction.getName().equals(FunctionNames.RANK)) {
        requiredIndexTypes = Arrays.asList(IndexTypes.RANK, IndexTypes.TIME_WINDOW_LEADERBOARD);
    } else if (recordFunction.getName().equals(FunctionNames.TIME_WINDOW_RANK)) {
        requiredIndexTypes = Collections.singletonList(IndexTypes.TIME_WINDOW_LEADERBOARD);
    } else {
        requiredIndexTypes = null;
    }
    if (requiredIndexTypes != null) {
        final GroupingKeyExpression operand = ((IndexRecordFunction) recordFunction).getOperand();
        Optional<Index> matchingIndex = indexes.stream().filter(index -> requiredIndexTypes.contains(index.getType()) && index.getRootExpression().equals(operand)).min(Comparator.comparing(Index::getColumnSize));
        if (matchingIndex.isPresent()) {
            final KeyExpression groupBy = operand.getGroupingSubKey();
            final List<QueryComponent> groupFilters = new ArrayList<>();
            final List<Comparisons.Comparison> groupComparisons = new ArrayList<>();
            if (!GroupingValidator.findGroupKeyFilters(potentialGroupFilters, groupBy, groupFilters, groupComparisons)) {
                return;
            }
            QueryComponent substitute = null;
            String bindingName = null;
            final Comparisons.Type comparisonType = comparison.getComparison().getType();
            if (!operand.createsDuplicates() && !comparisonType.isUnary()) {
                bindingName = Bindings.Internal.RANK.bindingName(Integer.toString(counter.getAndIncrement()));
                Comparisons.Comparison substituteComparison = new Comparisons.ParameterComparison(comparisonType, bindingName, Bindings.Internal.RANK);
                final KeyExpression grouped = operand.getGroupedSubKey();
                if (grouped instanceof FieldKeyExpression) {
                    substitute = new FieldWithComparison(((FieldKeyExpression) grouped).getFieldName(), substituteComparison);
                } else if (grouped instanceof NestingKeyExpression) {
                    NestingKeyExpression nesting = (NestingKeyExpression) grouped;
                    if (nesting.getChild() instanceof FieldKeyExpression) {
                        substitute = new NestedField(nesting.getParent().getFieldName(), new FieldWithComparison(((FieldKeyExpression) nesting.getChild()).getFieldName(), substituteComparison));
                    }
                }
                if (substitute == null) {
                    bindingName = null;
                }
            }
            comparisons.put(comparison, new RankComparison(comparison, matchingIndex.get(), groupFilters, groupComparisons, substitute, bindingName));
        }
    }
}
Also used : FunctionNames(com.apple.foundationdb.record.FunctionNames) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Arrays(java.util.Arrays) IndexAggregateFunction(com.apple.foundationdb.record.metadata.IndexAggregateFunction) Bindings(com.apple.foundationdb.record.Bindings) HashMap(java.util.HashMap) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) Function(java.util.function.Function) ArrayList(java.util.ArrayList) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) Tuple(com.apple.foundationdb.tuple.Tuple) QueryRecordFunctionWithComparison(com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) Map(java.util.Map) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) Set(java.util.Set) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) RecordQueryScoreForRankPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryScoreForRankPlan) AndComponent(com.apple.foundationdb.record.query.expressions.AndComponent) Collectors(java.util.stream.Collectors) AndOrComponent(com.apple.foundationdb.record.query.expressions.AndOrComponent) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) List(java.util.List) NestedField(com.apple.foundationdb.record.query.expressions.NestedField) Index(com.apple.foundationdb.record.metadata.Index) IndexTypes(com.apple.foundationdb.record.metadata.IndexTypes) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) RecordFunction(com.apple.foundationdb.record.RecordFunction) Comparator(java.util.Comparator) ComponentWithChildren(com.apple.foundationdb.record.query.expressions.ComponentWithChildren) Collections(java.util.Collections) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) IndexRecordFunction(com.apple.foundationdb.record.metadata.IndexRecordFunction) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) GroupingKeyExpression(com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) ArrayList(java.util.ArrayList) Index(com.apple.foundationdb.record.metadata.Index) NestedField(com.apple.foundationdb.record.query.expressions.NestedField) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) QueryRecordFunctionWithComparison(com.apple.foundationdb.record.query.expressions.QueryRecordFunctionWithComparison) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison) ScanComparisons(com.apple.foundationdb.record.query.plan.ScanComparisons) Comparisons(com.apple.foundationdb.record.query.expressions.Comparisons) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison)

Example 8 with NestingKeyExpression

use of com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression in project fdb-record-layer by FoundationDB.

the class GroupingValidator method matchNestingField.

private static boolean matchNestingField(@Nonnull QueryComponent filter, @Nonnull ComponentWithSingleChild nestingComponent, @Nonnull NestingKeyExpression nesting, @Nonnull List<QueryComponent> groupFilters, @Nonnull List<Comparisons.Comparison> groupComparisons) {
    if (nesting.getChild() instanceof NestingKeyExpression) {
        NestingKeyExpression childNesting = (NestingKeyExpression) nesting.getChild();
        QueryComponent childComponent = nestingComponent.getChild();
        if (childComponent instanceof NestedField || childComponent instanceof OneOfThemWithComponent) {
            if (childNesting.getParent().getFieldName().equals(((BaseField) childComponent).getFieldName()) && matchNestingField(filter, (ComponentWithSingleChild) childComponent, childNesting, groupFilters, groupComparisons)) {
                return true;
            }
        }
    } else if (nesting.getChild() instanceof FieldKeyExpression) {
        FieldKeyExpression childField = (FieldKeyExpression) nesting.getChild();
        if (nestingComponent.getChild() instanceof FieldWithComparison) {
            FieldWithComparison comparisonFilter = (FieldWithComparison) nestingComponent.getChild();
            if (comparisonFilter.getFieldName().equals(childField.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 : NestedField(com.apple.foundationdb.record.query.expressions.NestedField) QueryComponent(com.apple.foundationdb.record.query.expressions.QueryComponent) BaseField(com.apple.foundationdb.record.query.expressions.BaseField) ComponentWithSingleChild(com.apple.foundationdb.record.query.expressions.ComponentWithSingleChild) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) OneOfThemWithComponent(com.apple.foundationdb.record.query.expressions.OneOfThemWithComponent) FieldWithComparison(com.apple.foundationdb.record.query.expressions.FieldWithComparison)

Example 9 with NestingKeyExpression

use of com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression in project fdb-record-layer by FoundationDB.

the class AvailableFields method addCoveringField.

public static boolean addCoveringField(@Nonnull KeyExpression requiredExpr, @Nonnull FieldData fieldData, @Nonnull IndexKeyValueToPartialRecord.Builder builder) {
    while (requiredExpr instanceof NestingKeyExpression) {
        NestingKeyExpression nesting = (NestingKeyExpression) requiredExpr;
        String fieldName = nesting.getParent().getFieldName();
        requiredExpr = nesting.getChild();
        builder = builder.getFieldBuilder(fieldName);
    }
    if (requiredExpr instanceof FieldKeyExpression) {
        FieldKeyExpression fieldKeyExpression = (FieldKeyExpression) requiredExpr;
        // (e.g., a default value).
        if (fieldKeyExpression.getNullStandin().equals(Key.Evaluated.NullStandin.NOT_NULL) || fieldKeyExpression.getFanType().equals(KeyExpression.FanType.FanOut)) {
            return false;
        }
        if (!builder.hasField(fieldKeyExpression.getFieldName())) {
            builder.addField(fieldKeyExpression.getFieldName(), fieldData.source, fieldData.index);
        }
        return true;
    } else {
        return false;
    }
}
Also used : NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)

Example 10 with NestingKeyExpression

use of com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression in project fdb-record-layer by FoundationDB.

the class ValueIndexLikeExpansionVisitor method visitExpression.

@Nonnull
@Override
public GraphExpansion visitExpression(@Nonnull final NestingKeyExpression nestingKeyExpression) {
    final VisitorState state = getCurrentState();
    final List<String> fieldNamePrefix = state.getFieldNamePrefix();
    final CorrelationIdentifier baseAlias = state.getBaseAlias();
    final FieldKeyExpression parent = nestingKeyExpression.getParent();
    final KeyExpression child = nestingKeyExpression.getChild();
    switch(parent.getFanType()) {
        case None:
            List<String> newPrefix = ImmutableList.<String>builder().addAll(fieldNamePrefix).add(parent.getFieldName()).build();
            return pop(child.expand(push(state.withFieldNamePrefix(newPrefix))));
        case FanOut:
            // explode the parent field(s) also depending on the prefix
            final Quantifier childBase = parent.explodeField(baseAlias, fieldNamePrefix);
            // expand the children of the key expression and then unify them into an expansion of this expression
            final GraphExpansion.Sealed sealedChildExpansion = pop(child.expand(push(state.withBaseAlias(childBase.getAlias()).withFieldNamePrefix(ImmutableList.of())))).seal();
            final SelectExpression selectExpression = sealedChildExpansion.buildSelectWithBase(childBase);
            final Quantifier childQuantifier = Quantifier.forEach(GroupExpressionRef.of(selectExpression));
            return sealedChildExpansion.derivedWithQuantifier(childQuantifier);
        case Concatenate:
        default:
            throw new RecordCoreException("unsupported fan type");
    }
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) VisitorState(com.apple.foundationdb.record.query.plan.temp.ValueIndexLikeExpansionVisitor.VisitorState) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) FieldKeyExpression(com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression) NestingKeyExpression(com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression) ThenKeyExpression(com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression) EmptyKeyExpression(com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression) SelectExpression(com.apple.foundationdb.record.query.plan.temp.expressions.SelectExpression) Nonnull(javax.annotation.Nonnull)

Aggregations

NestingKeyExpression (com.apple.foundationdb.record.metadata.expressions.NestingKeyExpression)10 FieldKeyExpression (com.apple.foundationdb.record.metadata.expressions.FieldKeyExpression)9 ThenKeyExpression (com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression)6 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)5 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)5 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)3 QueryComponent (com.apple.foundationdb.record.query.expressions.QueryComponent)3 Nonnull (javax.annotation.Nonnull)3 Nullable (javax.annotation.Nullable)3 EmptyKeyExpression (com.apple.foundationdb.record.metadata.expressions.EmptyKeyExpression)2 Comparisons (com.apple.foundationdb.record.query.expressions.Comparisons)2 FieldWithComparison (com.apple.foundationdb.record.query.expressions.FieldWithComparison)2 NestedField (com.apple.foundationdb.record.query.expressions.NestedField)2 Tuple (com.apple.foundationdb.tuple.Tuple)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 API (com.apple.foundationdb.annotation.API)1 Bindings (com.apple.foundationdb.record.Bindings)1