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;
}
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;
}
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());
}
}
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;
}
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);
}
Aggregations