Class FieldExtract
- All Implemented Interfaces:
NamedWriteable,Writeable,Resolvable,EvaluatorMapper,BlockLoaderExpression
flattened field root as keyword.
The second argument is the literal name of a flattened sub-field, that is,
exactly the dotted key as it is stored in doc values for the flattened root (for example
"host.name").
When the path is a foldable literal key on a real flattened FieldAttribute,
the call is fused into the field load via BlockLoaderExpression. The keyed sub-field's
doc values are read directly instead of materializing the whole flattened JSON and re-parsing
it per row. The path is the flat sub-field name as is (no parsing), so any path that passes
verifier-time validation is eligible for pushdown.
-
Nested Class Summary
Nested classes/interfaces inherited from class org.elasticsearch.xpack.esql.core.expression.Expression
Expression.TypeResolutionNested classes/interfaces inherited from class org.elasticsearch.xpack.esql.core.tree.Node
Node.NodeStringFormatNested classes/interfaces inherited from interface org.elasticsearch.xpack.esql.expression.function.blockloader.BlockLoaderExpression
BlockLoaderExpression.PushedBlockLoaderExpressionNested classes/interfaces inherited from interface org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper
EvaluatorMapper.ToEvaluatorNested classes/interfaces inherited from interface org.elasticsearch.common.io.stream.Writeable
Writeable.Reader<V>, Writeable.Writer<V> -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final FunctionDefinitionstatic final NamedWriteableRegistry.EntryFields inherited from class org.elasticsearch.xpack.esql.core.expression.function.scalar.ScalarFunction
MAX_BYTES_REF_RESULT_SIZEFields inherited from class org.elasticsearch.xpack.esql.core.tree.Node
TO_STRING_MAX_LINES, TO_STRING_MAX_WIDTH -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptiondataType()TheDataTypereturned by executing the tree rooted at this expression.booleanfoldable()Whether the expression can be evaluated statically, aka "folded", or not.protected NodeInfo<? extends Expression> info()Normally, you want to use one of the staticcreatemethods to implement this.static booleanWhetherfield_extractis part of the active function set for this build, matching thefn_field_extractentry emitted byEsqlFunctionRegistry.addCapabilities(org.elasticsearch.xpack.esql.action.EsqlCapabilities.Builder).static voidprocess(BytesRefBlock.Builder builder, org.apache.lucene.util.BytesRef flattenedJson, org.apache.lucene.util.BytesRef path) replaceChildren(List<Expression> newChildren) protected Expression.TypeResolutionThe implementation ofExpression.typeResolved(), which is just a caching wrapper around this method.toEvaluator(EvaluatorMapper.ToEvaluator toEvaluator) Convert this into anExpressionEvaluator.tryAsKeyedSubfieldName(LucenePushdownPredicates pushdownPredicates) If thisfield_extractcan be pushed to a Lucene query against the keyed sub-field, returns the synthetic data-node field name (e.g.tryPushToFieldLoading(SearchStats stats) The field and loading configuration that replaces this expression, effectively "fusing" the expression into the load.voidwriteTo(StreamOutput out) Methods inherited from class org.elasticsearch.xpack.esql.expression.function.scalar.EsqlScalarFunction
foldMethods inherited from class org.elasticsearch.xpack.esql.core.expression.function.Function
arguments, equals, functionName, hashCode, nodeString, nullableMethods inherited from class org.elasticsearch.xpack.esql.core.expression.Expression
canonical, canonicalize, childrenResolved, propertiesToString, references, resolved, semanticEquals, semanticHash, toString, toString, typeResolvedMethods inherited from class org.elasticsearch.xpack.esql.core.tree.Node
allMatch, anyMatch, children, collect, collect, collect, collectFirstChildren, collectLeaves, doCollectFirst, forEachDown, forEachDown, forEachDownMayReturnEarly, forEachProperty, forEachPropertyDown, forEachPropertyOnly, forEachPropertyUp, forEachUp, forEachUp, nodeName, nodeProperties, nodeString, replaceChildrenSameSize, source, sourceLocation, sourceText, toString, transformChildren, transformChildren, transformDown, transformDown, transformDown, transformDown, transformDownSkipBranch, transformNodeProps, transformPropertiesDown, transformPropertiesOnly, transformPropertiesUp, transformUp, transformUp, transformUpMethods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, waitMethods inherited from interface org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper
fold
-
Field Details
-
ENTRY
-
DEFINITION
-
-
Constructor Details
-
FieldExtract
-
-
Method Details
-
writeTo
- Specified by:
writeToin interfaceWriteable- Throws:
IOException
-
getWriteableName
- Specified by:
getWriteableNamein interfaceNamedWriteable
-
dataType
Description copied from class:ExpressionTheDataTypereturned by executing the tree rooted at this expression. IfExpression.typeResolved()returns an error then the behavior of this method is undefined. It may return a valid type. Or it may throw an exception. Or it may return a totally nonsensical type.- Specified by:
dataTypein classExpression
-
resolveType
Description copied from class:ExpressionThe implementation ofExpression.typeResolved(), which is just a caching wrapper around this method. See it's javadoc for what this method should return.Implementations will rarely interact with the
Expression.TypeResolutionclass directly, instead usually calling the utility methods onTypeResolutions.Implementations should fail if
Expression.childrenResolved()returnsfalse.- Overrides:
resolveTypein classExpression
-
foldable
public boolean foldable()Description copied from class:ExpressionWhether the expression can be evaluated statically, aka "folded", or not.- Overrides:
foldablein classExpression
-
process
public static void process(BytesRefBlock.Builder builder, org.apache.lucene.util.BytesRef flattenedJson, org.apache.lucene.util.BytesRef path) -
replaceChildren
- Specified by:
replaceChildrenin classNode<Expression>
-
info
Description copied from class:NodeNormally, you want to use one of the staticcreatemethods to implement this.For
QueryPlans, it is very important that the properties contain all of the expressions and references relevant to this node, and that all the properties are used in the provided constructor; otherwise query plan transformations likeQueryPlan#transformExpressionsOnly(Function)will not have an effect.- Specified by:
infoin classNode<Expression>
-
toEvaluator
Description copied from interface:EvaluatorMapperConvert this into anExpressionEvaluator.Note for implementors: If you are implementing this function, you should call the passed-in lambda on your children, after doing any other manipulation (casting, etc.) necessary.
Note for Callers: If you are attempting to call this method, and you have an
Expressionand aLayout, you likely want to callEvalMapper.toEvaluator(org.elasticsearch.xpack.esql.core.expression.FoldContext, org.elasticsearch.xpack.esql.core.expression.Expression, org.elasticsearch.xpack.esql.planner.Layout)instead. On the other hand, if you already have something that looks like the parameter for this method, you should call this method with that function.Build an
ExpressionEvaluator.Factoryfor the tree of expressions rooted at this node. This is only guaranteed to return a sensible evaluator if this node has a valid type. If this node is a subclass ofExpressionthen "valid type" means thatExpression.typeResolved()returns a non-error resolution. If Expression.typeResolved() returns an error then this method may throw. Or return an evaluator that produces garbage. Or return an evaluator that throws when run.- Specified by:
toEvaluatorin interfaceEvaluatorMapper
-
isFnFieldExtractCapabilityMet
public static boolean isFnFieldExtractCapabilityMet()Whetherfield_extractis part of the active function set for this build, matching thefn_field_extractentry emitted byEsqlFunctionRegistry.addCapabilities(org.elasticsearch.xpack.esql.action.EsqlCapabilities.Builder). Block-loader fusion and Lucene query pushdown use the same gate so they stay aligned with function registration (snapshot-only until the function is promoted to the main registry). -
tryPushToFieldLoading
Description copied from interface:BlockLoaderExpressionThe field and loading configuration that replaces this expression, effectively "fusing" the expression into the load. Or null if the fusion isn't possible.SearchStats.supportsLoaderConfig(org.elasticsearch.xpack.esql.core.expression.FieldAttribute.FieldName, org.elasticsearch.index.mapper.blockloader.BlockLoaderFunctionConfig, org.elasticsearch.index.mapper.MappedFieldType.FieldExtractPreference)checks that the configuration is supported by all field mappers. Callers to this method must call that to confirm that configurations returned are supported. Implementations of this method do not need to call it, though they may use methods likeSearchStats.hasDocValues(org.elasticsearch.xpack.esql.core.expression.FieldAttribute.FieldName)andSearchStats.isIndexed(org.elasticsearch.xpack.esql.core.expression.FieldAttribute.FieldName)as preflight checks. They should use those methods if it is expensive to build theBlockLoaderFunctionConfig.- Specified by:
tryPushToFieldLoadingin interfaceBlockLoaderExpression
-
tryAsKeyedSubfieldName
If thisfield_extractcan be pushed to a Lucene query against the keyed sub-field, returns the synthetic data-node field name (e.g."resource.attributes.host.name"). The data node'sFieldTypeLookupresolves this name to aKeyedFlattenedFieldTypewhich handles the key-prefix encoding inindexedValueForSearch. The caller is responsible for wrapping the produced query in aSingleValueQueryto preserve ES|QL's single-value comparison semantics.Explicitly mapped sub-fields are not pushed: for them the synthetic name resolves to the real typed field (e.g. an
iporlong), so a pushed query would apply that field's typed comparison semantics while the per-row evaluator compares the extracted value as akeyword. Keeping mapped sub-fields on the evaluator path makesfield_extract's result independent of whether the optimizer pushed the call. That rejection is delegated to the flattened field type'sMappedFieldType.supportsBlockLoaderConfig(org.elasticsearch.index.mapper.blockloader.BlockLoaderFunctionConfig, org.elasticsearch.index.mapper.MappedFieldType.FieldExtractPreference), the same hook that gates block-loader fusion, so both pushdown paths agree on which keys are pushable. The mapped/unmapped decision needs the data-node mapping, so the stats-lesscan_matchpredicates report no loader config as supported and push nothing.
-