Class FunctionKeyExpression
- java.lang.Object
-
- com.apple.foundationdb.record.metadata.expressions.BaseKeyExpression
-
- com.apple.foundationdb.record.metadata.expressions.FunctionKeyExpression
-
- All Implemented Interfaces:
AtomKeyExpression
,KeyExpression
,KeyExpressionWithChild
,KeyExpressionWithChildren
,PlanHashable
,QueryHashable
- Direct Known Subclasses:
CollateFunctionKeyExpression
@API(EXPERIMENTAL) public abstract class FunctionKeyExpression extends BaseKeyExpression implements AtomKeyExpression, KeyExpressionWithChild
AFunctionKeyExpression
is aKeyExpression
that is dynamically loaded and defined by aString
name and aKey.Expression
that produces sets of arguments to which the function is to be evaluated.FunctionKeyExpressions
provide a mechanism by which indexes can be defined on arbitrarily complex logic applied to a record being inserted. For example, assuming a function called "substr
" that functions much like the javaString.substring()
method, you could create, say, a unique index with key offunction("subsstr", concat(field("firstname"), value(0), value(2)))
Which would prevent duplicate records in which the first two characters of thefirstname
are identical.Similarly, the function can be made to apply in a fan-out fashion, simply by providing a argument an expression that itself fans out into a set of arguments to
substr
. For example, given message definitions such as:message SubString { required string content = 1; required int32 start = 2; required int32 end = 3; } message SubStrings { repeated SubString substrings = 1; }
In which we want to have the arguments tosubstr
driven by data stored in the records themselves, you could define the index key expression as:function("substr", field("substrings", FanType.FanOut).nest(concatenateFields("content", "start", "end")))
This would produce the result of performingsubstr(content, start, end)
for eachSubString
value in substrings.Actual implementations of
FunctionKeyExpressions
are discovered by polling all availableFunctionKeyExpression.Registry
implementations. ARegistry
returns a list ofFunctionKeyExpression.Builder
s which, given a set of arguments, are capable of creating an implementation of a function.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
FunctionKeyExpression.BiFunctionBuilder
An implementation of aBuilder
that can construct aKeyExpressionFunction
via a provided generator.static class
FunctionKeyExpression.Builder
A builder is capable of producing an instance of aFunctionKeyExpression
given the arguments to the function.static interface
FunctionKeyExpression.Factory
Implementations ofFunctionKeyExpression.Factory
are dynamically located by theFunctionKeyExpression.Registry
and are polled once to request a list of builders for functions that the factory is capable of producing.static class
FunctionKeyExpression.Registry
TheRegistry
maintains a mapping from a function name to aBuilder
capable of producing an instance of the function.-
Nested classes/interfaces inherited from class com.apple.foundationdb.record.metadata.expressions.BaseKeyExpression
BaseKeyExpression.IllegalSubKeyException, BaseKeyExpression.UnsplittableKeyExpressionException
-
Nested classes/interfaces inherited from interface com.apple.foundationdb.record.metadata.expressions.KeyExpression
KeyExpression.DeserializationException, KeyExpression.FanType, KeyExpression.InvalidExpressionException, KeyExpression.InvalidResultException, KeyExpression.NoSuchArgumentException, KeyExpression.SerializationException
-
Nested classes/interfaces inherited from interface com.apple.foundationdb.record.PlanHashable
PlanHashable.PlanHashKind
-
Nested classes/interfaces inherited from interface com.apple.foundationdb.record.QueryHashable
QueryHashable.QueryHashKind
-
-
Field Summary
Fields Modifier and Type Field Description protected KeyExpression
arguments
protected String
name
-
Constructor Summary
Constructors Modifier Constructor Description protected
FunctionKeyExpression(String name, KeyExpression arguments)
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected int
basePlanHash(PlanHashable.PlanHashKind hashKind, ObjectPlanHash baseHash, Object... hashables)
Base implementation ofPlanHashable.planHash(com.apple.foundationdb.record.PlanHashable.PlanHashKind)
.protected int
baseQueryHash(QueryHashable.QueryHashKind hashKind, ObjectPlanHash baseHash, Object... hashables)
Base implementation ofQueryHashable.queryHash(com.apple.foundationdb.record.QueryHashable.QueryHashKind)
.static FunctionKeyExpression
create(String name, KeyExpression arguments)
Create a function.boolean
equals(Object o)
boolean
equalsAtomic(AtomKeyExpression other)
abstract <M extends Message>
List<Key.Evaluated>evaluateFunction(FDBRecord<M> record, Message message, Key.Evaluated arguments)
TheevaluateFunction
method implements the function execution.<M extends Message>
List<Key.Evaluated>evaluateMessage(FDBRecord<M> record, Message message)
Evaluate this expression against a record or a Protobuf message.<S extends KeyExpressionVisitor.State>
GraphExpansionexpand(ExpansionVisitor<S> visitor)
Expand this key expression into a data flow graph.static FunctionKeyExpression
fromProto(RecordMetaDataProto.Function function)
Create a function from its protobuf serialized form.KeyExpression
getArguments()
KeyExpression
getChild()
abstract int
getMaxArguments()
Get the maximum number of arguments supported by this function.abstract int
getMinArguments()
Get the the minimum number of arguments supported by this function.String
getName()
int
hashCode()
RecordMetaDataProto.KeyExpression
toKeyExpression()
RecordMetaDataProto.Function
toProto()
String
toString()
List<Descriptors.FieldDescriptor>
validate(Descriptors.Descriptor descriptor)
Validate this expression against a given record type descriptor.-
Methods inherited from class com.apple.foundationdb.record.metadata.expressions.BaseKeyExpression
getSubKey, getSubKeyImpl, isPrefixKey
-
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface com.apple.foundationdb.record.metadata.expressions.KeyExpression
createsDuplicates, evaluate, evaluateSingleton, getColumnSize, getSubKey, hasLosslessNormalization, hasProperInterfaces, hasRecordTypeKey, isPrefixKey, normalizeKeyForPositions, versionColumns
-
Methods inherited from interface com.apple.foundationdb.record.metadata.expressions.KeyExpressionWithChild
getChildren
-
Methods inherited from interface com.apple.foundationdb.record.PlanHashable
planHash, planHash
-
Methods inherited from interface com.apple.foundationdb.record.QueryHashable
queryHash
-
-
-
-
Field Detail
-
arguments
@Nonnull protected final KeyExpression arguments
-
-
Constructor Detail
-
FunctionKeyExpression
protected FunctionKeyExpression(@Nonnull String name, @Nonnull KeyExpression arguments)
-
-
Method Detail
-
create
public static FunctionKeyExpression create(@Nonnull String name, @Nonnull KeyExpression arguments)
Create a function.- Parameters:
name
- the name of the functionarguments
- an expression that produces the arguments to the function- Returns:
- the key expression that implements the function
- Throws:
KeyExpression.InvalidExpressionException
- if the function name provided does not have an available implementation, or the arguments provided are not suitable for the function
-
getChild
@Nonnull public KeyExpression getChild()
- Specified by:
getChild
in interfaceKeyExpressionWithChild
-
getArguments
@Nonnull public final KeyExpression getArguments()
-
getMinArguments
public abstract int getMinArguments()
Get the the minimum number of arguments supported by this function.- Returns:
- the minimum number of arguments supported by this function
-
getMaxArguments
public abstract int getMaxArguments()
Get the maximum number of arguments supported by this function.- Returns:
- the maximum number of arguments supported by this function
-
evaluateMessage
@Nonnull public <M extends Message> List<Key.Evaluated> evaluateMessage(@Nullable FDBRecord<M> record, @Nullable Message message)
Description copied from interface:KeyExpression
Evaluate this expression against a record or a Protobuf message. The message might be the Protobuf form of a record or a piece of that record. If the key expression is meaningful against a subrecord, it should evaluate against the message. Otherwise, it should evaluate against the record and ignore what part of that record is being considered. There should not be any reason to call this method outside of the implementation of anotherevaluateMessage
. Under ordinary circumstances, ifrecord
isnull
, thenmessage
will benull
. Otherwise,message
will berecord.getRecord()
or some submessage of that, possiblynull
if the corresponding field is missing.- Specified by:
evaluateMessage
in interfaceKeyExpression
- Type Parameters:
M
- the type of record- Parameters:
record
- the recordmessage
- the Protobuf message to evaluate against- Returns:
- the evaluated keys for the given record
- See Also:
KeyExpression.evaluate(com.apple.foundationdb.record.provider.foundationdb.FDBRecord<M>)
-
evaluateFunction
@Nonnull public abstract <M extends Message> List<Key.Evaluated> evaluateFunction(@Nullable FDBRecord<M> record, @Nullable Message message, @Nonnull Key.Evaluated arguments)
TheevaluateFunction
method implements the function execution. This method is invoked once perKey.Evaluated
that was produced by the evaluation of the function's argument. Put another way, the function's argument expression is evaluated and is expected to produce a set of arguments. This method is invoked once for each of these and, itself, may produce a set ofKey.Evaluated
values that produce the final set of keys.Note that the
record
parameter might benull
. Function implementors should treat this case the same way that they would treat a non-null
record that has all of its non-repeated fields unset and all of its repeated fields empty. If the function result depends only on the value ofarguments
and notrecord
directly, then the implementor can ignore the nullity ofrecord
.- Type Parameters:
M
- the type of the records- Parameters:
record
- the record against which this function will produce a keymessage
- the Protobuf message against which this function will produce a keyarguments
- the set of arguments to be applied by the function against therecord
- Returns:
- the list of keys for the given record
-
validate
public List<Descriptors.FieldDescriptor> validate(@Nonnull Descriptors.Descriptor descriptor)
Description copied from interface:KeyExpression
Validate this expression against a given record type descriptor.- Specified by:
validate
in interfaceKeyExpression
- Parameters:
descriptor
- the descriptor for the record type or submessage- Returns:
- a list of fields that this key applies to
-
equalsAtomic
public boolean equalsAtomic(AtomKeyExpression other)
- Specified by:
equalsAtomic
in interfaceAtomKeyExpression
-
fromProto
@Nonnull public static FunctionKeyExpression fromProto(RecordMetaDataProto.Function function) throws KeyExpression.DeserializationException
Create a function from its protobuf serialized form.- Parameters:
function
- the protobuf definition of the function- Returns:
- the key expression that implements the function
- Throws:
KeyExpression.InvalidExpressionException
- If the function name provided does not have an available implementation, or the arguments provided are not suitable for the function.KeyExpression.DeserializationException
-
toProto
@Nonnull public final RecordMetaDataProto.Function toProto() throws KeyExpression.SerializationException
- Specified by:
toProto
in interfaceKeyExpression
- Throws:
KeyExpression.SerializationException
-
toKeyExpression
@Nonnull public final RecordMetaDataProto.KeyExpression toKeyExpression()
- Specified by:
toKeyExpression
in interfaceKeyExpression
-
expand
@Nonnull public <S extends KeyExpressionVisitor.State> GraphExpansion expand(@Nonnull ExpansionVisitor<S> visitor)
Description copied from interface:KeyExpression
Expand this key expression into a data flow graph. The returned graph represents an adequate representation of the key expression as composition of relational expressions and operators (RelationalExpression
s). Note that implementors should defer to the visitation methods in the supplied visitor rather than encoding actual logic in an overriding method.- Specified by:
expand
in interfaceKeyExpression
- Type Parameters:
S
- a type that reflects the state thatvisitor
uses- Parameters:
visitor
- aExpansionVisitor
that is created by the caller from a data structure that reflects the specific semantics of the key expression. Normally this visitor is directly created based on an index.- Returns:
- a new
GraphExpansion
representing the query graph equivalent of this key expression using the supplied visitor - See Also:
QueryComponent.expand(com.apple.foundationdb.record.query.plan.temp.CorrelationIdentifier)
-
basePlanHash
protected int basePlanHash(@Nonnull PlanHashable.PlanHashKind hashKind, ObjectPlanHash baseHash, Object... hashables)
Base implementation ofPlanHashable.planHash(com.apple.foundationdb.record.PlanHashable.PlanHashKind)
. This implementation makes each concrete subclass implement its own version ofPlanHashable.planHash(com.apple.foundationdb.record.PlanHashable.PlanHashKind)
so that they are guided to add their own class modifier (SeeObjectPlanHash
). This implementation is meant to give subclasses common functionality for their own implementation.- Parameters:
hashKind
- the plan hash kind to usebaseHash
- the subclass' base hash (concrete identifier)hashables
- the rest of the subclass' hashable parameters (if any)- Returns:
- the plan hash value calculated
-
baseQueryHash
protected int baseQueryHash(@Nonnull QueryHashable.QueryHashKind hashKind, ObjectPlanHash baseHash, Object... hashables)
Base implementation ofQueryHashable.queryHash(com.apple.foundationdb.record.QueryHashable.QueryHashKind)
. This implementation makes each concrete subclass implement its own version ofQueryHashable.queryHash(com.apple.foundationdb.record.QueryHashable.QueryHashKind)
so that they are guided to add their own class modifier (SeeObjectPlanHash
). This implementation is meant to give subclasses common functionality for their own implementation.- Parameters:
hashKind
- the query hash kind to usebaseHash
- the subclass' base hash (concrete identifier)hashables
- the rest of the subclass' hashable parameters (if any)- Returns:
- the query hash value calculated
-
-