Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import com.apple.foundationdb.record.query.plan.cascades.typing.Type;
import com.apple.foundationdb.record.query.plan.cascades.values.FieldValue;
import com.apple.foundationdb.record.query.plan.cascades.values.QuantifiedObjectValue;
import com.apple.foundationdb.record.query.plan.cascades.values.RowNumberValue;
import com.apple.foundationdb.record.query.plan.cascades.values.RowNumberTransientValue;
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
import com.apple.foundationdb.record.query.plan.plans.QueryResult;
import com.google.common.annotations.VisibleForTesting;
Expand Down Expand Up @@ -151,7 +151,7 @@ public static IndexPredicate fromQueryPredicate(@Nonnull final QueryPredicate qu

/**
* Attempts to convert a {@link com.apple.foundationdb.record.query.plan.cascades.predicates.ValuePredicate}
* wrapping a {@link RowNumberValue} with a field ordering and a constant size comparison into
* wrapping a {@link RowNumberTransientValue} with a field ordering and a constant size comparison into
* a {@link RowNumberWindowPredicate}.
*
* <p>Expected pattern: {@code ROW_NUMBER() OVER (ORDER BY field ASC) <= size}.</p>
Expand All @@ -162,10 +162,10 @@ public static IndexPredicate fromQueryPredicate(@Nonnull final QueryPredicate qu
@javax.annotation.Nullable
private static RowNumberWindowPredicate tryFromRowNumberPredicate(
@Nonnull final com.apple.foundationdb.record.query.plan.cascades.predicates.ValuePredicate valuePredicate) {
if (!(valuePredicate.getValue() instanceof RowNumberValue)) {
if (!(valuePredicate.getValue() instanceof RowNumberTransientValue)) {
return null;
}
final var rowNumberValue = (RowNumberValue)valuePredicate.getValue();
final var rowNumberValue = (RowNumberTransientValue)valuePredicate.getValue();
final var argumentValues = rowNumberValue.getArgumentValues();
if (argumentValues.size() != 1 || !(argumentValues.get(0) instanceof FieldValue)) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@
import com.apple.foundationdb.record.metadata.Key;
import com.apple.foundationdb.record.provider.foundationdb.FDBRecord;
import com.apple.foundationdb.record.query.plan.cascades.BuiltInFunction;
import com.apple.foundationdb.record.query.plan.cascades.CallSiteArguments;
import com.apple.foundationdb.record.query.plan.cascades.CatalogedFunction;
import com.apple.foundationdb.record.query.plan.cascades.KeyExpressionVisitor;
import com.apple.foundationdb.record.query.plan.cascades.values.BuiltInFunctionCatalog;
import com.apple.foundationdb.record.query.plan.cascades.values.FunctionCatalog;
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
import com.apple.foundationdb.record.util.ServiceLoaderProvider;
import com.google.common.collect.ImmutableList;
import com.google.protobuf.Descriptors;
import com.google.protobuf.Message;

Expand Down Expand Up @@ -274,11 +277,14 @@ public <S extends KeyExpressionVisitor.State, R> R expand(@Nonnull final KeyExpr
@Nonnull
protected Value resolveAndEncapsulateFunction(@Nonnull final String functionName,
@Nonnull final List<? extends Value> argumentValues) {
final BuiltInFunction<?> builtInFunction =
BuiltInFunctionCatalog.resolve(functionName, argumentValues.size())
final CatalogedFunction<?> catalogedFunction =
FunctionCatalog.resolve(functionName, argumentValues.size())
.orElseThrow(() -> new RecordCoreArgumentException("unknown function",
LogMessageKeys.FUNCTION, getName()));
return (Value)builtInFunction.encapsulate(argumentValues);
if (!(catalogedFunction instanceof final BuiltInFunction<?> builtInFunction)) {
throw new RecordCoreArgumentException("unknown function", LogMessageKeys.FUNCTION, getName());
}
return (Value)builtInFunction.encapsulate(CallSiteArguments.ofPositional(ImmutableList.copyOf(argumentValues)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import com.apple.foundationdb.record.query.plan.cascades.IndexExpansionInfo;
import com.apple.foundationdb.record.query.plan.cascades.MatchCandidate;
import com.apple.foundationdb.record.query.plan.cascades.MatchCandidateExpansion;
import com.apple.foundationdb.record.query.plan.cascades.WindowedIndexExpansionVisitor;
import com.apple.foundationdb.record.query.plan.cascades.LegacyWindowedIndexExpansionVisitor;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableList;

Expand Down Expand Up @@ -117,7 +117,7 @@ public Iterable<MatchCandidate> createMatchCandidates(@Nonnull final RecordMetaD
// For rank() we need to create at two candidates. One for BY_RANK scans and one for BY_VALUE scans.
MatchCandidateExpansion.expandValueIndexMatchCandidate(info)
.ifPresent(resultBuilder::add);
MatchCandidateExpansion.expandIndexMatchCandidate(info, true, info.getCommonPrimaryKeyForTypes(), new WindowedIndexExpansionVisitor(index, info.getIndexedRecordTypes()))
MatchCandidateExpansion.expandIndexMatchCandidate(info, true, info.getCommonPrimaryKeyForTypes(), new LegacyWindowedIndexExpansionVisitor(index, info.getIndexedRecordTypes()))
.ifPresent(resultBuilder::add);

return resultBuilder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import com.apple.foundationdb.record.query.plan.cascades.typing.PseudoField;
import com.apple.foundationdb.record.query.plan.cascades.values.FieldValue;
import com.apple.foundationdb.record.query.plan.cascades.values.QuantifiedObjectValue;
import com.apple.foundationdb.record.query.plan.cascades.values.RankValue;
import com.apple.foundationdb.record.query.plan.cascades.values.RankTransientValue;
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
import com.google.common.collect.Lists;
import com.google.protobuf.Descriptors;
Expand Down Expand Up @@ -140,7 +140,7 @@ public GraphExpansion expand(@Nonnull final Quantifier.ForEach baseQuantifier,
final var partitioningSize = groupingKeyExpression.getGroupingCount();
final var partitioningExpressions = sealedPartitioningAndArgumentExpansion.getResultValues().subList(0, partitioningSize);
final var argumentExpressions = sealedPartitioningAndArgumentExpansion.getResultValues().subList(partitioningSize, groupingKeyExpression.getColumnSize());
final var rankValue = new RankValue(partitioningExpressions, argumentExpressions);
final var rankValue = new RankTransientValue(argumentExpressions, partitioningExpressions);
final var rankPredicate = new ValuePredicate(rankValue, comparison);
final var selfJoinPredicate =
innerBaseQuantifier.getFlowedObjectValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2015-2022 Apple Inc. and the FoundationDB project authors
* Copyright 2015-2026 Apple Inc. and the FoundationDB project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -362,11 +362,14 @@ public static boolean supportsAggregateIndexType(@Nonnull String indexType) {
@Nonnull
public static Optional<AggregateValue> aggregateValue(@Nonnull final Index index, @Nonnull final Value argument) {
return Optional.of((AggregateValue)aggregateMap.get()
.get(index.getType()).encapsulate(ImmutableList.of(argument)));
.get(index.getType()).encapsulate(CallSiteArguments.ofPositional(argument)));
}

@Nonnull
private static Map<String, BuiltInFunction<? extends Value>> computeAggregateMap() {
// Aggregate functions are second-order window functions (e.g. SUM is a BuiltInWindowFunction).
// Since aggregate indexes do not support windowing semantics, we first call encapsulatePureAggregate()
// to obtain a first-order BuiltInFunction with no frame/order, then encapsulate(args) to produce the value.
final ImmutableMap.Builder<String, BuiltInFunction<? extends Value>> mapBuilder = ImmutableMap.builder();
mapBuilder.put(IndexTypes.MAX_EVER_LONG, new IndexOnlyAggregateValue.MaxEverFn());
mapBuilder.put(IndexTypes.MIN_EVER_LONG, new IndexOnlyAggregateValue.MinEverFn());
Expand All @@ -388,12 +391,15 @@ public static boolean canBeRolledUp(@Nonnull final String indexType) {
public static Optional<AggregateValue> rollUpAggregateValueMaybe(@Nonnull final String indexType, @Nonnull final Value argument) {
return Optional.ofNullable(rollUpAggregateMap.get()
.get(indexType))
.map(fn -> (AggregateValue)fn.encapsulate(ImmutableList.of(argument)));
.map(fn -> (AggregateValue)fn.encapsulate(CallSiteArguments.ofPositional(argument)));
}

@Nonnull
private static Map<String, BuiltInFunction<? extends Value>> computeRollUpAggregateMap() {
final ImmutableMap.Builder<String, BuiltInFunction<? extends Value>> mapBuilder = ImmutableMap.builder();
// Aggregate functions are second-order window functions (e.g. SUM is a BuiltInWindowFunction).
// Since aggregate indexes do not support windowing semantics, we first call encapsulatePureAggregate()
// to obtain a first-order BuiltInFunction with no frame/order, then encapsulate(args) to produce the value.
mapBuilder.put(IndexTypes.MAX_EVER_LONG, new NumericAggregationValue.MaxFn());
mapBuilder.put(IndexTypes.MIN_EVER_LONG, new NumericAggregationValue.MinFn());
mapBuilder.put(IndexTypes.MAX_EVER_TUPLE, new NumericAggregationValue.MaxFn());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2015-2024 Apple Inc. and the FoundationDB project authors
* Copyright 2015-2026 Apple Inc. and the FoundationDB project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,7 +32,7 @@
import com.apple.foundationdb.record.query.plan.cascades.predicates.Placeholder;
import com.apple.foundationdb.record.query.plan.cascades.values.ArithmeticValue;
import com.apple.foundationdb.record.query.plan.cascades.values.FieldValue;
import com.apple.foundationdb.record.query.plan.cascades.values.BuiltInFunctionCatalog;
import com.apple.foundationdb.record.query.plan.cascades.values.FunctionCatalog;
import com.apple.foundationdb.record.query.plan.cascades.values.LiteralValue;
import com.apple.foundationdb.record.query.plan.cascades.values.NumericAggregationValue;
import com.apple.foundationdb.record.query.plan.cascades.values.RecordConstructorValue;
Expand Down Expand Up @@ -88,22 +88,23 @@ protected NonnullPair<Quantifier, List<Placeholder>> constructGroupBy(@Nonnull f
throw new UnsupportedOperationException("unable to plan group by with non-field value " + groupedValue);
}

final var bitmapConstructAggFunc = BuiltInFunctionCatalog.getFunctionSingleton(NumericAggregationValue.BitmapConstructAggFn.class).orElseThrow();
final var bitmapBitPositionFunc = BuiltInFunctionCatalog.getFunctionSingleton(ArithmeticValue.BitmapBitPositionFn.class).orElseThrow();
final String sizeArgument = index.getOption(IndexOptions.BITMAP_VALUE_ENTRY_SIZE_OPTION);
final int entrySize = sizeArgument != null ? Integer.parseInt(sizeArgument) : BitmapValueIndexMaintainer.DEFAULT_ENTRY_SIZE;
final var entrySizeValue = LiteralValue.ofScalar(entrySize);
final var bitmapBitPositionFunc = FunctionCatalog.getBuiltInFunction(ArithmeticValue.BitmapBitPositionFn.class).orElseThrow();
final var bitPositionCallsite = (Value)bitmapBitPositionFunc.encapsulate(CallSiteArguments.ofPositional(ImmutableList.of(argument, entrySizeValue)));

final var aggregateValue = (Value)bitmapConstructAggFunc.encapsulate(ImmutableList.of(bitmapBitPositionFunc.encapsulate(ImmutableList.of(argument, entrySizeValue))));
final var bitmapConstructAggFunc = new NumericAggregationValue.BitmapConstructAggFn();
final var aggregateValue = (Value)bitmapConstructAggFunc.encapsulate(CallSiteArguments.ofPositional(bitPositionCallsite));
// add an RCV column representing the grouping columns as the first result set column
// also, make sure to set the field type names correctly for each field value in the grouping keys RCV.

final var groupingValues = baseExpansion.getResultColumns().subList(0, groupingKeyExpression.getGroupingCount())
.stream()
.map(Column::getValue)
.collect(ImmutableList.toImmutableList());
final var bitmapBitPosition = BuiltInFunctionCatalog.getFunctionSingleton(ArithmeticValue.BitmapBucketOffsetFn.class).orElseThrow();
final var implicitGroupingValue = (Value)bitmapBitPosition.encapsulate(ImmutableList.of(argument, entrySizeValue));
final var bitmapBitPosition = FunctionCatalog.getBuiltInFunction(ArithmeticValue.BitmapBucketOffsetFn.class).orElseThrow();
final var implicitGroupingValue = (Value)bitmapBitPosition.encapsulate(CallSiteArguments.ofPositional(ImmutableList.of(argument, entrySizeValue)));
final var placeHolder = Placeholder.newInstanceWithoutRanges(implicitGroupingValue, newParameterAlias());

final var selectQunValue = selectWhereQun.getRangesOver().get().getResultValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.apple.foundationdb.record.RecordCoreException;
import com.apple.foundationdb.record.query.plan.cascades.typing.Type;
import com.apple.foundationdb.record.query.plan.cascades.typing.Typed;
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
import com.google.common.base.Verify;

import javax.annotation.Nonnull;
Expand All @@ -40,22 +41,24 @@
* @param <T> The resulting type of the function.
*/
@SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod")
public abstract class BuiltInFunction<T extends Typed> extends CatalogedFunction {
public class BuiltInFunction<T extends Typed> extends CatalogedFunction<Value> {
@Nonnull
final EncapsulationFunction<T> encapsulationFunction;

/**
* Creates a new instance of {@link BuiltInFunction}.
*
* @param functionName The name of the function.
* @param parameterTypes The type of the parameter(s).
* @param encapsulationFunction An encapsulation of the function's runtime computation.
*/
protected BuiltInFunction(@Nonnull final String functionName, @Nonnull final List<Type> parameterTypes, @Nonnull final EncapsulationFunction<T> encapsulationFunction) {
public BuiltInFunction(@Nonnull final String functionName, @Nonnull final List<Type> parameterTypes, @Nonnull final EncapsulationFunction<T> encapsulationFunction) {
this(functionName, parameterTypes, null, encapsulationFunction);
}

/**
* Creates a new instance of {@link BuiltInFunction}.
*
* @param functionName The name of the function.
* @param parameterTypes The type of the parameter(s).
* @param variadicSuffixType The type of the function's vararg.
Expand All @@ -68,21 +71,16 @@ protected BuiltInFunction(@Nonnull final String functionName, @Nonnull final Lis

protected BuiltInFunction(@Nonnull final String functionName, @Nonnull final List<String> parameterNames,
@Nonnull final List<Type> parameterTypes,
@Nonnull final List<Optional<? extends Typed>> parameterDefaults,
@Nonnull final List<Optional<Value>> parameterDefaults,
@Nonnull final EncapsulationFunction<T> encapsulationFunction) {
super(functionName, parameterNames, parameterTypes, parameterDefaults);
this.encapsulationFunction = encapsulationFunction;
}

@Nonnull
@Override
public Typed encapsulate(@Nonnull final List<? extends Typed> arguments) {
return Verify.verifyNotNull(encapsulationFunction).encapsulate(this, arguments);
}

@Nonnull
@Override
public Typed encapsulate(@Nonnull final Map<String, ? extends Typed> namedArguments) {
throw new RecordCoreException("built-in functions do not support named argument calling conventions");
public Typed encapsulate(final @Nonnull CallSiteArguments arguments) {
return Verify.verifyNotNull(encapsulationFunction).createCallSite(this, arguments);
}
}

Loading