@API(value=EXPERIMENTAL) public abstract class FunctionKeyExpression extends BaseKeyExpression implements AtomKeyExpression, KeyExpressionWithChild
FunctionKeyExpression
is a KeyExpression
that is dynamically loaded and defined by a
String
name and a Key.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 java String.substring()
method, you could
create, say, a unique index with key of
function("subsstr", concat(field("firstname"), value(0), value(2)))Which would prevent duplicate records in which the first two characters of the
firstname
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 to
substr
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 performing
substr(content, start, end)
for each SubString
value
in substrings.
Actual implementations of FunctionKeyExpressions
are discovered by polling all available
FunctionKeyExpression.Registry
implementations. A Registry
returns a list of FunctionKeyExpression.Builder
s which, given a set of
arguments, are capable of creating an implementation of a function.
Modifier and Type | Class and Description |
---|---|
static class |
FunctionKeyExpression.BiFunctionBuilder
An implementation of a
Builder that can construct a KeyExpressionFunction
via a provided generator. |
static class |
FunctionKeyExpression.Builder
A builder is capable of producing an instance of a
FunctionKeyExpression given the arguments
to the function. |
static interface |
FunctionKeyExpression.Factory
Implementations of
FunctionKeyExpression.Factory are dynamically located by the FunctionKeyExpression.Registry
and are polled once to request a list of builders for functions that the factory is capable of producing. |
static class |
FunctionKeyExpression.Registry
The
Registry maintains a mapping from a function name to a Builder capable of
producing an instance of the function. |
BaseKeyExpression.IllegalSubKeyException, BaseKeyExpression.UnsplittableKeyExpressionException
KeyExpression.DeserializationException, KeyExpression.FanType, KeyExpression.InvalidExpressionException, KeyExpression.InvalidResultException, KeyExpression.NoSuchArgumentException, KeyExpression.SerializationException
Modifier and Type | Field and Description |
---|---|
protected KeyExpression |
arguments |
protected String |
name |
Modifier | Constructor and Description |
---|---|
protected |
FunctionKeyExpression(String name,
KeyExpression arguments) |
Modifier and Type | Method and Description |
---|---|
static FunctionKeyExpression |
create(String name,
KeyExpression arguments)
Create a function.
|
boolean |
equals(Object o) |
boolean |
equalsAtomic(AtomKeyExpression other) |
abstract <M extends Message> |
evaluateFunction(FDBRecord<M> record,
Message message,
Key.Evaluated arguments)
The
evaluateFunction method implements the function execution. |
<M extends Message> |
evaluateMessage(FDBRecord<M> record,
Message message)
Evaluate this expression against a record or a Protobuf message.
|
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() |
int |
planHash()
Return a hash similar to
hashCode , but with the additional guarantee that is is stable across JVMs. |
RecordMetaDataProto.KeyExpression |
toKeyExpression() |
RecordMetaDataProto.Function |
toProto() |
String |
toString() |
List<Descriptors.FieldDescriptor> |
validate(Descriptors.Descriptor descriptor)
Validate this expression against a given record type descriptor.
|
getSubKey, getSubKeyImpl, isPrefixKey
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
getChildren
createsDuplicates, evaluate, evaluateSingleton, fromProto, getColumnSize, getSubKey, hasProperInterfaces, hasRecordTypeKey, isPrefixKey, normalizeKeyForPositions, versionColumns
combineHashes, iterablePlanHash, objectPlanHash, objectsPlanHash, planHash, planHash, planHashUnordered, stringHashUnordered
@Nonnull protected final KeyExpression arguments
protected FunctionKeyExpression(@Nonnull String name, @Nonnull KeyExpression arguments)
public static FunctionKeyExpression create(@Nonnull String name, @Nonnull KeyExpression arguments)
name
- the name of the functionarguments
- an expression that produces the arguments to the functionInvalidExpressionException
- if the function name provided does not have an available
implementation, or the arguments provided are not suitable for the function@Nonnull public KeyExpression getChild()
getChild
in interface KeyExpressionWithChild
@Nonnull public final KeyExpression getArguments()
public abstract int getMinArguments()
public abstract int getMaxArguments()
@Nonnull public <M extends Message> List<Key.Evaluated> evaluateMessage(@Nullable FDBRecord<M> record, @Nullable Message message)
KeyExpression
evaluateMessage
.
Under ordinary circumstances, if record
is null
, then message
will be null
.
Otherwise, message
will be record.getRecord()
or some submessage of that, possibly null
if
the corresponding field is missing.evaluateMessage
in interface KeyExpression
M
- the type of recordrecord
- the recordmessage
- the Protobuf message to evaluate againstKeyExpression.evaluate(com.apple.foundationdb.record.provider.foundationdb.FDBRecord<M>)
@Nonnull public abstract <M extends Message> List<Key.Evaluated> evaluateFunction(@Nullable FDBRecord<M> record, @Nullable Message message, @Nonnull Key.Evaluated arguments)
evaluateFunction
method implements the function execution. This method is invoked once per
Key.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 of Key.Evaluated
values that
produce the final set of keys.
Note that the record
parameter might be null
. 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 of arguments
and not record
directly, then the implementor can ignore
the nullity of record
.
M
- the type of the recordsrecord
- 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 the record
public List<Descriptors.FieldDescriptor> validate(@Nonnull Descriptors.Descriptor descriptor)
KeyExpression
validate
in interface KeyExpression
descriptor
- the descriptor for the record type or submessagepublic boolean equalsAtomic(AtomKeyExpression other)
equalsAtomic
in interface AtomKeyExpression
@Nonnull public static FunctionKeyExpression fromProto(RecordMetaDataProto.Function function) throws KeyExpression.DeserializationException
function
- the protobuf definition of the functionInvalidExpressionException
- If the function name provided does not have an available
implementation, or the arguments provided are not suitable for the function.KeyExpression.DeserializationException
@Nonnull public final RecordMetaDataProto.Function toProto() throws KeyExpression.SerializationException
toProto
in interface KeyExpression
KeyExpression.SerializationException
@Nonnull public final RecordMetaDataProto.KeyExpression toKeyExpression()
toKeyExpression
in interface KeyExpression
public int planHash()
PlanHashable
hashCode
, but with the additional guarantee that is is stable across JVMs.planHash
in interface PlanHashable