use of com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression 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.ThenKeyExpression in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planVersion.
@Nullable
private ScoredPlan planVersion(@Nonnull CandidateScan candidateScan, @Nonnull KeyExpression indexExpr, @Nonnull QueryRecordFunctionWithComparison filter, @Nullable KeyExpression sort) {
if (indexExpr instanceof VersionKeyExpression) {
final Comparisons.Comparison comparison = filter.getComparison();
final ScanComparisons comparisons = ScanComparisons.from(comparison);
if (sort == null || sort.equals(VersionKeyExpression.VERSION)) {
IndexScanParameters scanParameters = IndexScanComparisons.byValue(comparisons);
RecordQueryPlan plan = new RecordQueryIndexPlan(candidateScan.index.getName(), scanParameters, candidateScan.reverse);
return new ScoredPlan(1, plan, Collections.emptyList(), false);
}
} else if (indexExpr instanceof ThenKeyExpression) {
ThenKeyExpression then = (ThenKeyExpression) indexExpr;
if (sort == null) {
// && !then.createsDuplicates()) {
return planVersion(candidateScan, then.getChildren().get(0), filter, null);
} else {
return new AndWithThenPlanner(candidateScan, then, Collections.singletonList(filter), sort).plan();
}
}
return null;
}
use of com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planQueryKeyExpressionWithComparison.
@Nullable
private ScoredPlan planQueryKeyExpressionWithComparison(@Nonnull CandidateScan candidateScan, @Nonnull KeyExpression indexExpr, @Nonnull QueryKeyExpressionWithComparison queryKeyExpressionWithComparison, @Nullable KeyExpression sort) {
if (indexExpr.equals(queryKeyExpressionWithComparison.getKeyExpression()) && (sort == null || sort.equals(indexExpr))) {
final Comparisons.Comparison comparison = queryKeyExpressionWithComparison.getComparison();
final ScanComparisons scanComparisons = ScanComparisons.from(comparison);
if (scanComparisons == null) {
return null;
}
// Must be equal.
final boolean strictlySorted = sort != null;
return new ScoredPlan(1, valueScan(candidateScan, scanComparisons, strictlySorted));
} else if (indexExpr instanceof ThenKeyExpression) {
return new AndWithThenPlanner(candidateScan, (ThenKeyExpression) indexExpr, Collections.singletonList(queryKeyExpressionWithComparison), sort).plan();
}
return null;
}
use of com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression in project fdb-record-layer by FoundationDB.
the class QueryToKeyMatcher method matches.
@Nonnull
private Match matches(@Nonnull AndComponent query, @Nonnull KeyExpression key, @Nonnull MatchingMode matchingMode, @Nullable FilterSatisfiedMask filterMask) {
final List<QueryComponent> listOfQueries = query.getChildren();
final Iterator<KeyExpression> keyChildIterator;
final int keyChildSize = key.getColumnSize();
if (key instanceof ThenKeyExpression) {
List<KeyExpression> children = ((ThenKeyExpression) key).getChildren();
keyChildIterator = children.iterator();
} else {
keyChildIterator = Iterators.singletonIterator(key);
}
// Keep a local mask so that if we can only partially fulfill queries we don't pollute the main
// one with our state
FilterSatisfiedMask localMask = FilterSatisfiedMask.of(query);
localMask.setExpression(key);
List<Comparison> comparisons = new ArrayList<>(keyChildSize);
while (keyChildIterator.hasNext()) {
KeyExpression exp = keyChildIterator.next();
// Look for a query segment that matches this expression
boolean found = false;
boolean foundInequality = false;
final Iterator<FilterSatisfiedMask> childMaskIterator = localMask.getChildren().iterator();
for (QueryComponent querySegment : listOfQueries) {
Match match = matches(querySegment, exp, matchingMode, childMaskIterator.next());
if (match.getType() != MatchType.NO_MATCH) {
found = true;
comparisons.addAll(match.getComparisons());
if (match.getType() == MatchType.INEQUALITY) {
foundInequality = true;
}
break;
}
}
if (!found) {
return Match.none();
}
// Only the last comparison in the list can be inequality.
if (localMask.allSatisfied() || foundInequality) {
break;
}
}
if (matchingMode.equals(MatchingMode.SATISFY_QUERY) && !localMask.allSatisfied() || matchingMode.equals(MatchingMode.COVER_KEY) && comparisons.size() < keyChildSize) {
// filters that have not yet been satisfied.
return Match.none();
}
if (filterMask != null) {
filterMask.mergeWith(localMask);
}
return new Match(comparisons);
}
use of com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression in project fdb-record-layer by FoundationDB.
the class ValueIndexLikeExpansionVisitor method visitExpression.
@Nonnull
@Override
public GraphExpansion visitExpression(@Nonnull final ThenKeyExpression thenKeyExpression) {
final ImmutableList.Builder<GraphExpansion> expandedPredicatesBuilder = ImmutableList.builder();
final VisitorState state = getCurrentState();
int currentOrdinal = state.getCurrentOrdinal();
for (KeyExpression child : thenKeyExpression.getChildren()) {
final GraphExpansion graphExpansion = pop(child.expand(push(state.withCurrentOrdinal(currentOrdinal))));
currentOrdinal += graphExpansion.getResultValues().size();
expandedPredicatesBuilder.add(graphExpansion);
}
return GraphExpansion.ofOthers(expandedPredicatesBuilder.build());
}
Aggregations