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