use of com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planFieldWithComparison.
@Nullable
private ScoredPlan planFieldWithComparison(@Nonnull CandidateScan candidateScan, @Nonnull KeyExpression indexExpr, @Nonnull FieldWithComparison singleField, @Nullable KeyExpression sort, boolean fullKey) {
final Comparisons.Comparison comparison = singleField.getComparison();
final ScanComparisons scanComparisons = ScanComparisons.from(comparison);
if (scanComparisons == null) {
// this index, but this should be handled elsewhere by the planner.
return null;
}
if (indexExpr instanceof FieldKeyExpression) {
FieldKeyExpression field = (FieldKeyExpression) indexExpr;
if (Objects.equals(singleField.getFieldName(), field.getFieldName())) {
if (sort != null) {
if (sort instanceof FieldKeyExpression) {
FieldKeyExpression sortField = (FieldKeyExpression) sort;
if (Objects.equals(sortField.getFieldName(), field.getFieldName())) {
// everything matches, yay!! Hopefully that comparison can be for tuples
return new ScoredPlan(1, valueScan(candidateScan, scanComparisons, fullKey));
}
}
} else {
return new ScoredPlan(1, valueScan(candidateScan, scanComparisons, false));
}
}
return null;
} else if (indexExpr instanceof ThenKeyExpression) {
ThenKeyExpression then = (ThenKeyExpression) indexExpr;
if ((sort == null || sort.equals(then.getChildren().get(0))) && !then.createsDuplicates() && !(then.getChildren().get(0) instanceof RecordTypeKeyExpression)) {
// First column will do it all or not.
return planFieldWithComparison(candidateScan, then.getChildren().get(0), singleField, sort, false);
} else {
// May need second column to do sort, so handle like And, which does such cases.
return new AndWithThenPlanner(candidateScan, then, Collections.singletonList(singleField), sort).plan();
}
}
return null;
}
use of com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planThenNestedField.
private ScoredPlan planThenNestedField(@Nonnull CandidateScan candidateScan, @Nonnull ThenKeyExpression then, @Nonnull NestedField filter, @Nullable KeyExpression sort) {
if (sort instanceof ThenKeyExpression || then.createsDuplicates()) {
// Too complicated for the simple checks below.
return new AndWithThenPlanner(candidateScan, then, Collections.singletonList(filter), sort).plan();
}
ScoredPlan plan = planNestedField(candidateScan, then.getChildren().get(0), filter, sort);
if (plan == null && sort != null && sort.equals(then.getChildren().get(1))) {
ScoredPlan sortlessPlan = planNestedField(candidateScan, then.getChildren().get(0), filter, null);
ScanComparisons sortlessComparisons = getPlanComparisons(sortlessPlan);
if (sortlessComparisons != null && sortlessComparisons.isEquality()) {
// A scan for an equality filter will be sorted by the next index key.
plan = sortlessPlan;
}
}
return plan;
}
use of com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression in project fdb-record-layer by FoundationDB.
the class RecordQueryPlanner method planQueryKeyExpressionWithOneOfComparison.
@Nullable
private ScoredPlan planQueryKeyExpressionWithOneOfComparison(@Nonnull CandidateScan candidateScan, @Nonnull KeyExpression indexExpr, @Nonnull QueryKeyExpressionWithOneOfComparison queryKeyExpressionWithOneOfComparison, @Nullable KeyExpression sort) {
if (indexExpr.equals(queryKeyExpressionWithOneOfComparison.getKeyExpression()) && (sort == null || sort.equals(indexExpr))) {
final Comparisons.Comparison comparison = queryKeyExpressionWithOneOfComparison.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(queryKeyExpressionWithOneOfComparison), sort).plan();
}
return null;
}
use of com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression in project fdb-record-layer by FoundationDB.
the class ScalarTranslationVisitor method visitExpression.
@Nonnull
@Override
public Value visitExpression(@Nonnull final ThenKeyExpression thenKeyExpression) {
if (thenKeyExpression.getColumnSize() > 1) {
throw new RecordCoreException("cannot expand ThenKeyExpression in scalar expansion");
}
final ScalarVisitorState state = getCurrentState();
final KeyExpression child = Iterables.getOnlyElement(thenKeyExpression.getChildren());
return pop(child.expand(push(state)));
}
use of com.apple.foundationdb.record.metadata.expressions.ThenKeyExpression in project fdb-record-layer by FoundationDB.
the class IndexFunctionHelper method getThenSubKey.
protected static KeyExpression getThenSubKey(ThenKeyExpression then, int columnStart, int columnEnd) {
final List<KeyExpression> children = then.getChildren();
int columnPosition = 0;
int startChildPosition = -1;
int startChildStart = -1;
int startChildEnd = -1;
for (int childPosition = 0; childPosition < children.size(); childPosition++) {
final KeyExpression child = children.get(childPosition);
final int childColumns = child.getColumnSize();
if (startChildPosition < 0 && columnPosition + childColumns > columnStart) {
startChildPosition = childPosition;
startChildStart = columnStart - columnPosition;
startChildEnd = childColumns;
}
if (columnPosition + childColumns >= columnEnd) {
int endChildEnd = columnEnd - columnPosition;
if (childPosition == startChildPosition) {
// Just one child spans column start, end.
if (startChildPosition == 0 && endChildEnd == childColumns) {
return child;
} else {
return getSubKey(child, startChildStart, endChildEnd);
}
}
if (startChildStart == 0 && endChildEnd == childColumns) {
return new ThenKeyExpression(children.subList(startChildPosition, childPosition + 1));
}
final List<KeyExpression> keys = new ArrayList<>(childPosition - startChildPosition + 1);
keys.add(getSubKey(children.get(startChildPosition), startChildStart, startChildEnd));
if (childPosition > startChildPosition + 1) {
keys.addAll(children.subList(startChildPosition + 1, childPosition));
}
keys.add(getSubKey(child, 0, endChildEnd));
return new ThenKeyExpression(keys);
}
columnPosition += childColumns;
}
throw new RecordCoreException("column counts are not consistent");
}
Aggregations