Class ExternalSourceExec
- All Implemented Interfaces:
NamedWriteable,Writeable,DataSourceExec,EstimatesRowSize
This is the unified physical plan node for all external sources, replacing source-specific nodes. It uses generic maps for configuration and metadata to avoid leaking source-specific types (like S3Configuration) into core ESQL code.
Key design principles:
- Generic configuration: Uses
Map<String, Object>for config instead of source-specific classes like S3Configuration - Opaque metadata: Source-specific data (native schema, etc.) is stored in
sourceMetadata()and passed through without core understanding it - Coordinator plan never holds it: the coordinator
Mapperleaves the source asFragmentExec(ExternalRelation); this exec is materialized per-node byLocalMapperfromExternalRelation.toPhysicalExec()duringPlannerUtils.localPlan(), on whichever node runs the compute. It is a serializableNamedWriteable(seewriteTo(org.elasticsearch.common.io.stream.StreamOutput)/readFrom(org.elasticsearch.common.io.stream.StreamInput)) so it can ride the wire, but only its execution inputs survive that round trip; see the field categories below.
Field categories. The fields fall into three groups, and only the first is serialized:
- Execution inputs (serialized):
sourcePath,sourceType,attributes,config,sourceMetadata,estimatedRowSize,splits,datasetName. These are what a data-node operator needs to read; in the distributed path the data node reads the files via the serializedsplits. - Build-time state (not serialized):
fileList,schemaMap,unifiedSchema. These are coordinator-resolved and read off the exec by split discovery andplanExternalSource.fileListandschemaMaporiginate onExternalRelationand are coordinator-only (a data node deserializes the relation withFileList.UNRESOLVED/ an emptyschemaMap, sotoPhysicalExec()does not rebuild them there); the data node relies on the serializedsplitsinstead.unifiedSchemais the exception:toPhysicalExec()rebuilds it on every node from the serializedmetadata.schema(). - Local-execution pushdown hints (not serialized):
pushedFilter,pushedExpressions,pushedLimit,pushedTopN,deferredExtraction. These are decisions produced byLocalPhysicalPlanOptimizerrules that run after this exec is created, independently on each node. They are intentionally re-derived per-node and must not be serialized.
writeTo(org.elasticsearch.common.io.stream.StreamOutput).-
Nested Class Summary
Nested classes/interfaces inherited from class org.elasticsearch.xpack.esql.core.tree.Node
Node.NodeStringFormatNested classes/interfaces inherited from interface org.elasticsearch.xpack.esql.plan.physical.EstimatesRowSize
EstimatesRowSize.StateNested classes/interfaces inherited from interface org.elasticsearch.common.io.stream.Writeable
Writeable.Reader<V>, Writeable.Writer<V> -
Field Summary
FieldsFields inherited from class org.elasticsearch.xpack.esql.core.tree.Node
TO_STRING_MAX_LINES, TO_STRING_MAX_WIDTH -
Constructor Summary
ConstructorsConstructorDescriptionExternalSourceExec(Source source, String sourcePath, String sourceType, List<Attribute> attributes, Map<String, Object> config, Map<String, Object> sourceMetadata, Integer estimatedRowSize) Convenience ctor with no pushed filter; seeExternalSourceExec(Source, String, String, List, Map, Map, Object, Integer).ExternalSourceExec(Source source, String sourcePath, String sourceType, List<Attribute> attributes, Map<String, Object> config, Map<String, Object> sourceMetadata, Object pushedFilter, Integer estimatedRowSize) Convenience ctor (no splits/fileList/schema).ExternalSourceExec(Source source, String sourcePath, String sourceType, List<Attribute> attributes, Map<String, Object> config, Map<String, Object> sourceMetadata, Object pushedFilter, List<Expression> pushedExpressions, int pushedLimit, Integer estimatedRowSize, FileList fileList, Map<StoragePath, SchemaReconciliation.FileSchemaInfo> schemaMap, List<ExternalSplit> splits) Public 13-arg ctor used byinfo()(via constructor reference) and by tree tests.ExternalSourceExec(Source source, String sourcePath, String sourceType, List<Attribute> attributes, Map<String, Object> config, Map<String, Object> sourceMetadata, Object pushedFilter, List<Expression> pushedExpressions, int pushedLimit, Integer estimatedRowSize, FileList fileList, Map<StoragePath, SchemaReconciliation.FileSchemaInfo> schemaMap, List<ExternalSplit> splits, String datasetName, DeclaredReadSpec declaredReadSpec) Public 15-arg ctor used byinfo()(via constructor reference) and by tree tests: the 13-arg shape above plusdatasetNameanddeclaredReadSpec, so node-reflection reconstruction preserves both. -
Method Summary
Modifier and TypeMethodDescriptionconfig()Registered dataset identifier carried fromExternalRelation, ornullif this exec came from inlineEXTERNAL.The declared read-instructions (renames,_id.path), orDeclaredReadSpec.NONE.booleanWhether a pairedExternalFieldExtractExecsits downstream consuming deferred-encoded columns.The effective per-source statistics for this exec, resolved from the typed per-splitSplitStatscarried onsplits()when available, falling back to the whole-file / anchor-file stats embedded insourceMetadata()(the legacy flat_stats.*map).booleanEstimate the number of bytes that'll be loaded per position before the stream of pages is consumed.fileList()inthashCode()protected NodeInfo<? extends PhysicalPlan> info()Normally, you want to use one of the staticcreatemethods to implement this.The values of all the properties that are important to thisNode.voidnodeString(StringBuilder sb, Node.NodeStringFormat format, NodeStringMapper mapper) Append thisNode's string representation tosb.output()The ordered list of attributes (i.e.intThe Top-N grouping hint set byPushTopNIntoExternalSource, ornullif no Top-N pruning should be performed during hash aggregation.The whole-file / anchor-file statistics parsed fromsourceMetadata()'s flat_stats.*keys, ornullwhen the map carries none.splits()withAttributes(List<Attribute> newAttributes) Returns a copy of this source with the given output attribute list.withDatasetName(String newDatasetName) Returns a copy of this source carrying the given dataset name.withDeclaredReadSpec(DeclaredReadSpec newDeclaredReadSpec) Returns a copy of this source carrying the given declared read-instructions.Returns a copy of this source flagged for deferred extraction.protected ExternalSourceExecwithEstimatedRowSize(Integer newEstimatedRowSize) withFileList(FileList newFileList) Returns a copy carrying the given (coordinator-resolved)FileList.withPushedFilter(Object newFilter) withPushedFilterAndExpressions(Object newFilter, List<Expression> newPushedExpressions) withPushedLimit(int newLimit) withPushedTopN(BlockHash.TopNDef newPushedTopN) Returns a copy of this source annotated with the given Top-N grouping hint.withSplits(List<ExternalSplit> newSplits) withUnifiedSchema(ExternalSchema newUnifiedSchema) Returns a copy of this source carrying the given pre-prune Unified schema.voidwriteTo(StreamOutput out) Methods inherited from class org.elasticsearch.xpack.esql.plan.physical.LeafExec
computeReferences, replaceChildrenMethods inherited from class org.elasticsearch.xpack.esql.plan.QueryPlan
computeExpressions, expressions, forEachExpression, forEachExpression, forEachExpressionDown, forEachExpressionUp, inputSet, outputSet, references, transformExpressionsDown, transformExpressionsDown, transformExpressionsOnly, transformExpressionsOnly, transformExpressionsOnlyUp, transformExpressionsUp, transformExpressionsUpMethods 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, nodeString, propertiesToString, replaceChildrenSameSize, source, sourceLocation, sourceText, toString, toString, 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.plan.physical.DataSourceExec
source
-
Field Details
-
ENTRY
-
-
Constructor Details
-
ExternalSourceExec
public ExternalSourceExec(Source source, String sourcePath, String sourceType, List<Attribute> attributes, Map<String, Object> config, Map<String, Object> sourceMetadata, Object pushedFilter, List<Expression> pushedExpressions, int pushedLimit, Integer estimatedRowSize, FileList fileList, Map<StoragePath, SchemaReconciliation.FileSchemaInfo> schemaMap, List<ExternalSplit> splits) Public 13-arg ctor used byinfo()(via constructor reference) and by tree tests. PassesnullforunifiedSchema; callers that need to carry the Unified schema (e.g.ExternalRelation.toPhysicalExec()) apply it afterwards viawithUnifiedSchema(ExternalSchema). -
ExternalSourceExec
public ExternalSourceExec(Source source, String sourcePath, String sourceType, List<Attribute> attributes, Map<String, Object> config, Map<String, Object> sourceMetadata, Object pushedFilter, List<Expression> pushedExpressions, int pushedLimit, Integer estimatedRowSize, FileList fileList, Map<StoragePath, SchemaReconciliation.FileSchemaInfo> schemaMap, List<ExternalSplit> splits, @Nullable String datasetName, DeclaredReadSpec declaredReadSpec) Public 15-arg ctor used byinfo()(via constructor reference) and by tree tests: the 13-arg shape above plusdatasetNameanddeclaredReadSpec, so node-reflection reconstruction preserves both. LosingdatasetNameon a generic rewrite would silently null_index; losingdeclaredReadSpecwould silently drop declared renames /_id.path(the same reflection safety the renames had while riding the reflectedconfigmap). This is the longest public ctor —EsqlNodeSubclassTestskeys the requiredinfo()arity off it. PassesnullforpushedTopN/unifiedSchema; those are transient hints carried via theirwith*methods. -
ExternalSourceExec
public ExternalSourceExec(Source source, String sourcePath, String sourceType, List<Attribute> attributes, Map<String, Object> config, Map<String, Object> sourceMetadata, Object pushedFilter, Integer estimatedRowSize) Convenience ctor (no splits/fileList/schema). UsewithFileList(FileList),withSplits(List), and the otherwith*builders to attach the build-time and pushdown state. Primarily for tests and the inlineEXTERNALpath. -
ExternalSourceExec
public ExternalSourceExec(Source source, String sourcePath, String sourceType, List<Attribute> attributes, Map<String, Object> config, Map<String, Object> sourceMetadata, Integer estimatedRowSize) Convenience ctor with no pushed filter; seeExternalSourceExec(Source, String, String, List, Map, Map, Object, Integer).
-
-
Method Details
-
writeTo
- Specified by:
writeToin interfaceWriteable- Throws:
IOException
-
getWriteableName
- Specified by:
getWriteableNamein interfaceNamedWriteable
-
sourcePath
-
sourceType
-
output
Description copied from class:QueryPlanThe ordered list of attributes (i.e. columns) this plan produces when executed. Must be called only on resolved plans, otherwise may throw an exception or return wrong results.- Specified by:
outputin interfaceDataSourceExec- Specified by:
outputin classQueryPlan<PhysicalPlan>
-
config
-
sourceMetadata
-
effectiveSplitStats
The effective per-source statistics for this exec, resolved from the typed per-splitSplitStatscarried onsplits()when available, falling back to the whole-file / anchor-file stats embedded insourceMetadata()(the legacy flat_stats.*map). Returnsnullwhen no complete stats are available (e.g. a multi-file glob marked_stats.partial, or a split missing stats).Centralizes the
SplitStats.resolveEffectiveStats(splits(), sourceMetadata())call so the optimizer's push rules read statistics through one typed accessor on the plan node rather than each re-deriving them from the flat map. This is the read-side seam for migrating stats off the flat map. -
sourceMetadataStats
The whole-file / anchor-file statistics parsed fromsourceMetadata()'s flat_stats.*keys, ornullwhen the map carries none. Distinct fromeffectiveSplitStats()in that it ignores per-split stats: callers use it only in the degenerate single-/no-split branch where the split itself carries no typed stats. Centralizes theSplitStats.of(sourceMetadata())read. -
pushedFilter
-
pushedExpressions
-
pushedLimit
public int pushedLimit() -
estimatedRowSize
-
fileList
-
schemaMap
-
unifiedSchema
-
splits
-
withSplits
-
withFileList
Returns a copy carrying the given (coordinator-resolved)FileList.fileListis build-time state copied fromExternalRelation; it is read off the exec by split discovery andplanExternalSourceand is never serialized. See the class Javadoc. -
withPushedFilter
-
withPushedFilterAndExpressions
public ExternalSourceExec withPushedFilterAndExpressions(Object newFilter, List<Expression> newPushedExpressions) -
withPushedLimit
-
withAttributes
Returns a copy of this source with the given output attribute list. Used byInsertExternalFieldExtractionto narrow the source's projection (sort keys + predicate columns) and inject a synthetic_rowPositionattribute that the pairedExternalFieldExtractExecconsumes.Every other field — including pushed filter, pushed limit, splits, and the source path — is preserved. The new attribute list is not validated against the source's reader schema; the caller (the optimizer rule) is responsible for ensuring it is a valid subset plus
_rowPosition. Serialization is unaffected because attributes are part of the wire format already. -
withPushedTopN
Returns a copy of this source annotated with the given Top-N grouping hint. SeepushedTopN(). -
pushedTopN
The Top-N grouping hint set byPushTopNIntoExternalSource, ornullif no Top-N pruning should be performed during hash aggregation. This is a transient local-execution hint; it is never serialized and is re-derived independently on each node. -
withUnifiedSchema
Returns a copy of this source carrying the given pre-prune Unified schema. SeeunifiedSchema(). Applied byExternalRelation.toPhysicalExec()after construction so the Unified schema does not appear ininfo()(which would let the optimizer's attribute-rewriting rules prune it along withattributes). -
datasetName
Registered dataset identifier carried fromExternalRelation, ornullif this exec came from inlineEXTERNAL. SeeExternalRelation.datasetName(). -
deferredExtraction
public boolean deferredExtraction()Whether a pairedExternalFieldExtractExecsits downstream consuming deferred-encoded columns. See the field Javadoc for why this is its own signal rather than inferred from the projection. -
withDeferredExtraction
Returns a copy of this source flagged for deferred extraction. SeedeferredExtraction(). -
withDatasetName
Returns a copy of this source carrying the given dataset name. Applied byExternalRelation.toPhysicalExec()after construction;datasetNamealso flows throughinfo()so node-reflection reconstruction preserves it. -
declaredReadSpec
The declared read-instructions (renames,_id.path), orDeclaredReadSpec.NONE. Consumed on the data node byFileSourceFactory(physicalization) and the pushdown rules; see the field Javadoc. -
withDeclaredReadSpec
Returns a copy of this source carrying the given declared read-instructions. Applied byExternalRelation.toPhysicalExec()after construction;declaredReadSpecalso flows throughinfo()so node-reflection reconstruction preserves it. -
estimateRowSize
Description copied from interface:EstimatesRowSizeEstimate the number of bytes that'll be loaded per position before the stream of pages is consumed.- Specified by:
estimateRowSizein interfaceEstimatesRowSize
-
withEstimatedRowSize
-
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<PhysicalPlan>
-
hashCode
public int hashCode()- Specified by:
hashCodein classPhysicalPlan
-
equals
- Specified by:
equalsin classPhysicalPlan
-
nodeProperties
Description copied from class:NodeThe values of all the properties that are important to thisNode.- Overrides:
nodePropertiesin classNode<PhysicalPlan>
-
nodeString
Description copied from class:Node- Overrides:
nodeStringin classNode<PhysicalPlan>- Parameters:
sb- target for the stringformat- output-shape configuration (width / lines / property count)mapper- identifier-mapping strategy (raw viaNodeStringMapper.IDENTITY, anonymized via the failure-path anonymizer, etc.)
-