@@ -21,6 +21,7 @@ use databend_common_ast::ast::SampleConfig;
2121use databend_common_exception:: Result ;
2222use databend_common_expression:: ColumnId ;
2323use databend_common_expression:: DataSchema ;
24+ use databend_common_expression:: Expr ;
2425use databend_common_expression:: FunctionRegistry ;
2526use databend_common_expression:: RemoteExpr ;
2627use databend_common_expression:: SEARCH_MATCHED_COL_NAME ;
@@ -57,9 +58,11 @@ pub struct VirtualColumnField {
5758 pub source_column_id : u32 ,
5859 /// The source column name.
5960 pub source_name : String ,
60- /// The virtual column id
61- pub column_id : u32 ,
62- /// The virtual column name.
61+ /// Query-time temporary column id. This is not a persisted segment-local
62+ /// virtual column id; each segment may assign a different real column id
63+ /// for the same path, so readers must map this id through the segment schema.
64+ pub query_column_id : u32 ,
65+ /// Full query field name, including the source column, e.g. `v.user.name` or `v[0].id`.
6366 pub name : String ,
6467 /// Paths to generate virtual column from source column.
6568 pub key_paths : OwnedKeyPaths ,
@@ -69,6 +72,21 @@ pub struct VirtualColumnField {
6972 pub data_type : Box < TableDataType > ,
7073}
7174
75+ /// Query-time identity of a virtual column referenced by a pushed-down filter
76+ /// or ordering expression. It bridges the query column id to the persisted
77+ /// source-column/canonical-path identity used to locate segment-local stats.
78+ #[ derive( Clone , Debug ) ]
79+ pub struct VirtualPredicateRef {
80+ /// Full query/pipeline field name used by expression column references.
81+ pub name : String ,
82+ /// Id of the authoritative source Variant column.
83+ pub source_column_id : u32 ,
84+ /// Query-time temporary column id used by runtime filters and readers.
85+ pub query_column_id : u32 ,
86+ /// Compact canonical JSON path relative to the source column.
87+ pub encoded_path : String ,
88+ }
89+
7290/// Information about prewhere optimization.
7391///
7492/// Prewhere steps:
@@ -207,6 +225,30 @@ pub struct PushDownInfo {
207225}
208226
209227impl PushDownInfo {
228+ pub fn virtual_predicate_refs (
229+ & self ,
230+ filter_expr : Option < & Expr < String > > ,
231+ ) -> Vec < VirtualPredicateRef > {
232+ let Some ( virtual_column) = & self . virtual_column else {
233+ return Vec :: new ( ) ;
234+ } ;
235+ let mut referenced_columns = filter_expr. map ( Expr :: column_refs) . unwrap_or_default ( ) ;
236+ for ( expr, _, _) in & self . order_by {
237+ referenced_columns. extend ( expr. column_refs ( ) ) ;
238+ }
239+ virtual_column
240+ . virtual_column_fields
241+ . iter ( )
242+ . filter ( |field| referenced_columns. contains_key ( & field. name ) )
243+ . map ( |field| VirtualPredicateRef {
244+ name : field. name . clone ( ) ,
245+ source_column_id : field. source_column_id ,
246+ query_column_id : field. query_column_id ,
247+ encoded_path : field. key_paths . to_canonical_path ( ) ,
248+ } )
249+ . collect ( )
250+ }
251+
210252 pub fn add_internal_column_dependencies < ' a > (
211253 & mut self ,
212254 schema : & TableSchema ,
0 commit comments