Interface KeyExpression
-
- All Superinterfaces:
PlanHashable
- All Known Subinterfaces:
AtomKeyExpression
,KeyExpressionWithChild
,KeyExpressionWithChildren
,KeyExpressionWithoutChildren
,QueryableKeyExpression
- All Known Implementing Classes:
BaseKeyExpression
,CollateFunctionKeyExpression
,CollateFunctionKeyExpressionFactoryJRE.CollateFunctionKeyExpressionJRE
,ElementKeyExpression
,EmptyKeyExpression
,FieldKeyExpression
,FunctionKeyExpression
,GroupingKeyExpression
,KeyWithValueExpression
,ListKeyExpression
,LiteralKeyExpression
,NestingKeyExpression
,RecordTypeKeyExpression
,SplitKeyExpression
,ThenKeyExpression
,VersionKeyExpression
@API(MAINTAINED) public interface KeyExpression extends PlanHashable
Interface for expressions that evaluate to keys. While Java will let you extend this class, you probably shouldn't because the planner does lots of instanceof calls to figure out what query to use. If you're ok with always just doing a scan of all records, and evaluating the expression on that, I guess that's ok. When implementing a new key expression, care should be taken to implement at least one (and possibly both) of the interfaces Key.AtomExpression and Key.ExpressionWithChildren.
-
-
Nested Class Summary
Nested Classes Modifier and Type Interface Description static class
KeyExpression.DeserializationException
Exception thrown when there is a problem deserializing a key expression.static class
KeyExpression.FanType
How should repeated fields be handled.static class
KeyExpression.InvalidExpressionException
Exception thrown when there is a problem with using a key expression in a certain context.static class
KeyExpression.InvalidResultException
This is a runtime exception (i.e.static class
KeyExpression.NoSuchArgumentException
Exception thrown when a function key expression does not have an argument.static class
KeyExpression.SerializationException
Exception thrown when there is a problem serializing a key expression.
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description boolean
createsDuplicates()
This states whether the given expression type is capable of evaluating more to more than one value when applied to a single record.default <M extends Message>
List<Key.Evaluated>evaluate(FDBRecord<M> record)
Evaluate against a given record producing a list of evaluated keys.<M extends Message>
List<Key.Evaluated>evaluateMessage(FDBRecord<M> record, Message message)
Evaluate this expression against a record or a Protobuf message.default <M extends Message>
Key.EvaluatedevaluateSingleton(FDBRecord<M> record)
Evaluate this expression with the expectation of getting exactly one result.default List<Element>
flattenForPlanner()
Flatten this key expression into a list ofElement
s, much likenormalizeKeyForPositions()
.static KeyExpression
fromProto(RecordMetaDataProto.KeyExpression expression)
int
getColumnSize()
Returns the number of items in each KeyValue that will be returned.static List<KeyExpression>
getKeyFields(KeyExpression rootExpression)
Return the key fields for an expression.KeyExpression
getSubKey(int start, int end)
Returns a sub-set of the key expression.static List<KeyExpression>
getValueFields(KeyExpression rootExpression)
Return the value fields for an expression.default boolean
hasProperInterfaces()
default boolean
hasRecordTypeKey()
Check whether a key expression uses record type key in some way.boolean
isPrefixKey(KeyExpression key)
Check whether a key is a prefix of another key.KeyExpression
normalizeForPlanner(Source source, List<String> fieldNamePrefix)
Normalize this key expression into another key expression that pushes all nesting and fan-out toElementKeyExpression
s at the leaves.default List<KeyExpression>
normalizeKeyForPositions()
Get key in normalized form for comparing field-by-field.RecordMetaDataProto.KeyExpression
toKeyExpression()
Message
toProto()
List<Descriptors.FieldDescriptor>
validate(Descriptors.Descriptor descriptor)
Validate this expression against a given record type descriptor.default int
versionColumns()
Returns the number of version columns produced by this key expression.-
Methods inherited from interface com.apple.foundationdb.record.PlanHashable
planHash
-
-
-
-
Method Detail
-
evaluate
@Nonnull default <M extends Message> List<Key.Evaluated> evaluate(@Nullable FDBRecord<M> record)
Evaluate against a given record producing a list of evaluated keys. These are extracted from the fields within the record according to the rules of each implementing class. Implementations should overrideevaluateMessage(com.apple.foundationdb.record.provider.foundationdb.FDBRecord<M>, com.google.protobuf.Message)
instead of this one, even if they do not deal with Protobuf messages, so that they interact properly with expressions that do.- Type Parameters:
M
- the type of record- Parameters:
record
- the record- Returns:
- the list of evaluated keys for the given record
- Throws:
KeyExpression.InvalidResultException
- if any returned result has some number of columns other than the return value ofgetColumnSize()
-
evaluateSingleton
@Nonnull default <M extends Message> Key.Evaluated evaluateSingleton(@Nullable FDBRecord<M> record)
Evaluate this expression with the expectation of getting exactly one result.- Type Parameters:
M
- the type of record- Parameters:
record
- the record- Returns:
- the evaluated keys for the given record
-
evaluateMessage
@Nonnull <M extends Message> List<Key.Evaluated> evaluateMessage(@Nullable FDBRecord<M> record, @Nullable Message message)
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.- 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:
evaluate(com.apple.foundationdb.record.provider.foundationdb.FDBRecord<M>)
-
createsDuplicates
boolean createsDuplicates()
This states whether the given expression type is capable of evaluating more to more than one value when applied to a single record. In practice, this can happen if this expression is evaluated on a repeated field withFanType.FanOut
set (either directly or indirectly).- Returns:
true
if this expression can evaluate to multiple values andfalse
otherwise
-
validate
List<Descriptors.FieldDescriptor> validate(@Nonnull Descriptors.Descriptor descriptor)
Validate this expression against a given record type descriptor.- Parameters:
descriptor
- the descriptor for the record type or submessage- Returns:
- a list of fields that this key applies to
- Throws:
KeyExpression.InvalidExpressionException
- if the expression is not valid for the given descriptor
-
getColumnSize
int getColumnSize()
Returns the number of items in each KeyValue that will be returned. For key expressions that supportKeyExpression.FanType.Concatenate
, this will the count of non-nested lists, i.e. this will be value of evaluate(r).get(i).toList().size() for any i or r.- Returns:
- the number of elements that will be produced for every key
-
toProto
@Nonnull Message toProto() throws KeyExpression.SerializationException
-
toKeyExpression
@Nonnull RecordMetaDataProto.KeyExpression toKeyExpression()
-
normalizeKeyForPositions
@Nonnull default List<KeyExpression> normalizeKeyForPositions()
Get key in normalized form for comparing field-by-field. Does not take account of fan-type, so only valid when this has already been taken care of, such as individual index entries.- Returns:
- a list of key expressions in order
-
flattenForPlanner
@API(EXPERIMENTAL) @Nonnull default List<Element> flattenForPlanner()
Flatten this key expression into a list ofElement
s, much likenormalizeKeyForPositions()
. By default, this method throws an exception because most key expressions cannot be flattened to a list of elements without prior adjustment. This method is only overriden by key expressions that can be flattened.- Returns:
- a list of elements representing this key expression in unnested form
- See Also:
ElementKeyExpression.flattenForPlanner()
,ThenKeyExpression.flattenForPlanner()
-
normalizeForPlanner
@API(EXPERIMENTAL) @Nonnull KeyExpression normalizeForPlanner(@Nonnull Source source, @Nonnull List<String> fieldNamePrefix)
Normalize this key expression into another key expression that pushes all nesting and fan-out toElementKeyExpression
s at the leaves.By default, a key expression is a complicated nested structure that can be difficult to work with. This method pushes much of the complexity, including nested structures and fan-out of repeated fields, to special key expressions that track these relationship using the
Source
abstraction. This pre-processing makes planning nested and repeated structures much simpler.This normalization process requires tracking some state since the name of a nested field is available only at the relevant
FieldKeyExpression
, but that information is necessary to construct theElementKeyExpression
at the leaves of the sub-tree rooted at theNestingKeyExpression
. This extra information is tracked in thefieldNamePrefix
.- Parameters:
source
- the source representing the input stream of the key expressionfieldNamePrefix
- the (non-repeated) field names on the path from the most recent source to this part of the key expression- Returns:
- a new key expression that has only
ElementKeyExpression
s at its leaves
-
getKeyFields
@API(EXPERIMENTAL) static List<KeyExpression> getKeyFields(@Nonnull KeyExpression rootExpression)
Return the key fields for an expression.- Parameters:
rootExpression
- a key expression- Returns:
- the parts of the key expression that are in the key
-
getValueFields
@API(EXPERIMENTAL) static List<KeyExpression> getValueFields(@Nonnull KeyExpression rootExpression)
Return the value fields for an expression.- Parameters:
rootExpression
- a key expression- Returns:
- the parts of the key expression that are in the value
-
versionColumns
default int versionColumns()
Returns the number of version columns produced by this key expression.- Returns:
- the number of version columns
-
hasRecordTypeKey
default boolean hasRecordTypeKey()
Check whether a key expression uses record type key in some way.- Returns:
true
if record type key is used
-
getSubKey
@Nonnull KeyExpression getSubKey(int start, int end)
Returns a sub-set of the key expression.- Parameters:
start
- starting positionend
- ending position- Returns:
- a key expression for the subkey between
start
andend
-
isPrefixKey
boolean isPrefixKey(@Nonnull KeyExpression key)
Check whether a key is a prefix of another key.- Parameters:
key
- the whole key to check- Returns:
true
ifprefix
is a left subset ofkey
-
hasProperInterfaces
default boolean hasProperInterfaces()
-
fromProto
@Nonnull static KeyExpression fromProto(RecordMetaDataProto.KeyExpression expression) throws KeyExpression.DeserializationException
-
-