Interface VirtualAttribute

All Known Implementing Classes:
ExternalMetadataAttribute

public interface VirtualAttribute
Marker interface for Attributes whose values are synthesized by the engine and have no physical presence in the underlying source data — they are not columns in any file, document, or index segment, and cannot be evaluated by a format-level scan.

Today the only implementation is ExternalMetadataAttribute (_file.path, _file.name, _file.size, etc.), which is materialized as a per-file constant block by VirtualColumnIterator. Future synthetic attributes (Hive partition columns surfaced as virtual columns, computed table-level columns, etc.) should also implement this interface so format-level pushdown rules pick them up automatically.

Why a marker rather than a name check. The conventional _file.* prefix is a surface convention; user-facing renames (and even internal aliasing) can change the visible name. Type-based identification stays correct under any rename and survives serialization.

Why a marker rather than a base class. The single Java inheritance slot under TypedAttribute is already spent by each concrete attribute (e.g. ExternalMetadataAttribute and a hypothetical future PartitionAttribute that needs to extend FieldAttribute for Lucene type metadata). The interface composes orthogonally with whichever base each subclass needs and carries no behavior of its own — adding a base would lock the hierarchy without buying any shared state. Same idiom as SurrogateExpression, OptionalArgument, and similar capability tags in the expression tree.

Relationship to MetadataAttribute. MetadataAttribute models real Elasticsearch document metadata (_id, _index, _score, ...) — values the index actually stores or computes per-document. Format-level pushdown to external file formats (Parquet, ORC) cannot evaluate either of these, so the shared PushdownPredicates.isVirtualColumn helper treats both MetadataAttribute and any VirtualAttribute as virtual for pushdown purposes — but the two concepts stay distinct here so other consumers can disambiguate (real-but-unscanable metadata vs engine-synthesized).