@@ -17,8 +17,6 @@ use std::sync::Arc;
1717
1818use databend_common_base:: base:: OrderedFloat ;
1919use databend_common_catalog:: catalog:: CatalogManager ;
20- use databend_common_catalog:: BasicColumnStatistics ;
21- use databend_common_catalog:: TableStatistics ;
2220use databend_common_exception:: Result ;
2321use databend_common_expression:: types:: DataType ;
2422use databend_common_expression:: types:: NumberScalar ;
@@ -44,181 +42,15 @@ use databend_common_sql::plans::RelOperator;
4442use databend_common_sql:: plans:: ScalarExpr ;
4543use databend_common_sql:: plans:: ScalarItem ;
4644use databend_common_sql:: plans:: Scan ;
47- use databend_common_sql:: plans:: Statistics ;
48- use databend_common_sql:: BaseTableColumn ;
4945use databend_common_sql:: ColumnBinding ;
50- use databend_common_sql:: ColumnEntry ;
5146use databend_common_sql:: ColumnSet ;
5247use databend_common_sql:: IndexType ;
53- use databend_common_sql:: MetadataRef ;
5448use databend_common_sql:: NameResolutionContext ;
5549use databend_common_sql:: Planner ;
5650use databend_common_sql:: Visibility ;
5751use databend_query:: interpreters:: InterpreterFactory ;
5852use databend_query:: sessions:: QueryContext ;
5953
60- /// A builder for setting test statistics on plans
61- #[ derive( Clone , Debug , Default ) ]
62- pub struct TestStatisticsBuilder {
63- // Map of table name to table statistics
64- table_stats : HashMap < String , Option < TableStatistics > > ,
65- // Map of (table name, column name) to column statistics
66- column_stats : HashMap < ( String , String ) , Option < BasicColumnStatistics > > ,
67- }
68-
69- impl TestStatisticsBuilder {
70- /// Create a new TestStatisticsBuilder
71- pub fn new ( ) -> Self {
72- Self {
73- table_stats : HashMap :: new ( ) ,
74- column_stats : HashMap :: new ( ) ,
75- }
76- }
77-
78- /// Set statistics for a specific table
79- pub fn set_table_statistics (
80- & mut self ,
81- table_name : & str ,
82- stats : Option < TableStatistics > ,
83- ) -> & mut Self {
84- self . table_stats . insert ( table_name. to_string ( ) , stats) ;
85- self
86- }
87-
88- /// Set statistics for a specific column in a table
89- pub fn set_column_statistics (
90- & mut self ,
91- table_name : & str ,
92- column_name : & str ,
93- stats : Option < BasicColumnStatistics > ,
94- ) -> & mut Self {
95- self . column_stats
96- . insert ( ( table_name. to_string ( ) , column_name. to_string ( ) ) , stats) ;
97- self
98- }
99-
100- /// Apply the statistics to a plan
101- pub fn apply_to_plan ( & self , plan : & mut Plan ) -> Result < ( ) > {
102- if let Plan :: Query {
103- s_expr, metadata, ..
104- } = plan
105- {
106- let new_s_expr = self . apply_to_sexpr ( s_expr, metadata) ?;
107- * s_expr = Box :: new ( new_s_expr) ;
108- }
109- Ok ( ( ) )
110- }
111-
112- /// Internal helper to apply statistics to an SExpr
113- fn apply_to_sexpr ( & self , s_expr : & SExpr , metadata : & MetadataRef ) -> Result < SExpr > {
114- let mut result = s_expr. clone ( ) ;
115-
116- if let RelOperator :: Scan ( scan) = s_expr. plan . as_ref ( ) {
117- let table_index = scan. table_index ;
118- let metadata_guard = metadata. read ( ) ;
119- let table = metadata_guard. table ( table_index) ;
120- let table_name = table. name ( ) ;
121-
122- // Check if we have statistics for this table
123- let should_update = self . table_stats . contains_key ( table_name)
124- || self . column_stats . iter ( ) . any ( |( ( t, _) , _) | t == table_name) ;
125-
126- if should_update {
127- let mut new_scan = scan. clone ( ) ;
128-
129- // Create a mutable copy of the statistics
130- let mut stats = Statistics {
131- table_stats : None ,
132- column_stats : HashMap :: new ( ) ,
133- histograms : HashMap :: new ( ) ,
134- } ;
135-
136- // Update table statistics if specified
137- if let Some ( table_stats) = self . table_stats . get ( table_name) {
138- stats. table_stats = * table_stats;
139- }
140-
141- // Update column statistics if specified
142- let metadata_guard = metadata. read ( ) ;
143- let columns = metadata_guard. columns_by_table_index ( table_index) ;
144- for ( idx, column) in columns. iter ( ) . enumerate ( ) {
145- if let ColumnEntry :: BaseTableColumn ( BaseTableColumn { column_name, .. } ) =
146- column
147- {
148- if let Some ( col_stats_option) = self
149- . column_stats
150- . get ( & ( table_name. to_string ( ) , column_name. clone ( ) ) )
151- {
152- stats
153- . column_stats
154- . insert ( idx as IndexType , col_stats_option. clone ( ) ) ;
155- }
156- }
157- }
158-
159- // Replace the statistics
160- new_scan. statistics = Arc :: new ( stats) ;
161- result = result. replace_plan ( Arc :: new ( RelOperator :: Scan ( new_scan) ) ) ;
162- }
163- }
164-
165- // Recursively process children
166- let mut new_children = Vec :: new ( ) ;
167- for child in s_expr. children ( ) {
168- new_children. push ( Arc :: new ( self . apply_to_sexpr ( child, metadata) ?) ) ;
169- }
170-
171- if !new_children. is_empty ( ) {
172- result = result. replace_children ( new_children) ;
173- }
174-
175- Ok ( result)
176- }
177- }
178-
179- // Extension trait for Plan to make it easier to set statistics
180- pub trait PlanStatisticsExt {
181- /// Set statistics for a specific table
182- fn set_table_statistics (
183- & mut self ,
184- table_name : & str ,
185- stats : Option < TableStatistics > ,
186- ) -> Result < & mut Self > ;
187-
188- /// Set statistics for a specific column in a table
189- fn set_column_statistics (
190- & mut self ,
191- table_name : & str ,
192- column_name : & str ,
193- stats : Option < BasicColumnStatistics > ,
194- ) -> Result < & mut Self > ;
195- }
196-
197- impl PlanStatisticsExt for Plan {
198- fn set_table_statistics (
199- & mut self ,
200- table_name : & str ,
201- stats : Option < TableStatistics > ,
202- ) -> Result < & mut Self > {
203- let mut builder = TestStatisticsBuilder :: new ( ) ;
204- builder. set_table_statistics ( table_name, stats) ;
205- builder. apply_to_plan ( self ) ?;
206- Ok ( self )
207- }
208-
209- fn set_column_statistics (
210- & mut self ,
211- table_name : & str ,
212- column_name : & str ,
213- stats : Option < BasicColumnStatistics > ,
214- ) -> Result < & mut Self > {
215- let mut builder = TestStatisticsBuilder :: new ( ) ;
216- builder. set_column_statistics ( table_name, column_name, stats) ;
217- builder. apply_to_plan ( self ) ?;
218- Ok ( self )
219- }
220- }
221-
22254// TPC-DS Test Utilities
22355
22456/// Plan SQL query to get a Plan object
@@ -271,15 +103,6 @@ pub async fn optimize_plan(ctx: &Arc<QueryContext>, plan: Plan) -> Result<Plan>
271103 optimize ( opt_ctx, plan) . await
272104}
273105
274- /// Test case structure for optimizer tests
275- pub struct TestCase {
276- pub name : & ' static str ,
277- pub sql : & ' static str ,
278- pub stats_setup : fn ( & mut Plan ) -> Result < ( ) > ,
279- pub raw_plan : & ' static str , // Expected raw plan string
280- pub expected_plan : & ' static str , // Expected optimized plan string
281- }
282-
283106// ===== Helper Functions =====
284107
285108/// Creates a column reference with the given index, name, data type, table name and table index
0 commit comments