sql_cli/execution/
config.rs

1//! Execution configuration for controlling statement execution behavior
2//!
3//! This module defines configuration options that control how SQL statements
4//! are preprocessed and executed.
5
6use crate::query_plan::TransformerConfig;
7
8/// Configuration for statement execution
9///
10/// Controls preprocessing, case sensitivity, and other execution behaviors
11#[derive(Clone, Debug)]
12pub struct ExecutionConfig {
13    /// Whether to show preprocessing transformations (debug output)
14    pub show_preprocessing: bool,
15
16    /// Whether to show SQL before/after each transformation (formatted SQL output)
17    pub show_sql_transformations: bool,
18
19    /// Whether to use case-insensitive comparison
20    pub case_insensitive: bool,
21
22    /// Whether to automatically hide empty columns
23    pub auto_hide_empty: bool,
24
25    /// Configuration for AST transformers (preprocessing pipeline)
26    pub transformer_config: TransformerConfig,
27
28    /// Whether to enable debug tracing during execution
29    pub debug_trace: bool,
30}
31
32impl Default for ExecutionConfig {
33    fn default() -> Self {
34        Self {
35            show_preprocessing: false,
36            show_sql_transformations: false,
37            case_insensitive: false,
38            auto_hide_empty: false,
39            transformer_config: TransformerConfig::default(),
40            debug_trace: false,
41        }
42    }
43}
44
45impl ExecutionConfig {
46    /// Create a new execution config with default values
47    pub fn new() -> Self {
48        Self::default()
49    }
50
51    /// Enable preprocessing debug output
52    pub fn with_show_preprocessing(mut self, show: bool) -> Self {
53        self.show_preprocessing = show;
54        self
55    }
56
57    /// Enable SQL transformation output (show before/after SQL for each transformer)
58    pub fn with_show_sql_transformations(mut self, show: bool) -> Self {
59        self.show_sql_transformations = show;
60        self
61    }
62
63    /// Enable case-insensitive comparison
64    pub fn with_case_insensitive(mut self, insensitive: bool) -> Self {
65        self.case_insensitive = insensitive;
66        self
67    }
68
69    /// Enable automatic hiding of empty columns
70    pub fn with_auto_hide_empty(mut self, hide: bool) -> Self {
71        self.auto_hide_empty = hide;
72        self
73    }
74
75    /// Set transformer configuration
76    pub fn with_transformer_config(mut self, config: TransformerConfig) -> Self {
77        self.transformer_config = config;
78        self
79    }
80
81    /// Enable debug tracing
82    pub fn with_debug_trace(mut self, trace: bool) -> Self {
83        self.debug_trace = trace;
84        self
85    }
86
87    /// Disable all preprocessing transformers
88    pub fn without_preprocessing(mut self) -> Self {
89        self.transformer_config.enable_expression_lifter = false;
90        self.transformer_config.enable_where_expansion = false;
91        self.transformer_config.enable_group_by_expansion = false;
92        self.transformer_config.enable_having_expansion = false;
93        self.transformer_config.enable_qualify_to_where = false;
94        self.transformer_config.enable_cte_hoister = false;
95        self.transformer_config.enable_in_lifter = false;
96        self
97    }
98
99    /// Create config from command-line flags (helper for non_interactive.rs)
100    pub fn from_cli_flags(
101        show_preprocessing: bool,
102        show_sql_transformations: bool,
103        case_insensitive: bool,
104        auto_hide_empty: bool,
105        no_expression_lifter: bool,
106        no_where_expansion: bool,
107        no_group_by_expansion: bool,
108        no_having_expansion: bool,
109        no_order_by_expansion: bool,
110        no_qualify_to_where: bool,
111        no_cte_hoister: bool,
112        no_in_lifter: bool,
113        debug_trace: bool,
114    ) -> Self {
115        let config = Self {
116            show_preprocessing,
117            show_sql_transformations,
118            case_insensitive,
119            auto_hide_empty,
120            transformer_config: TransformerConfig {
121                enable_expression_lifter: !no_expression_lifter,
122                enable_where_expansion: !no_where_expansion,
123                enable_group_by_expansion: !no_group_by_expansion,
124                enable_having_expansion: !no_having_expansion,
125                enable_order_by_expansion: !no_order_by_expansion,
126                enable_qualify_to_where: !no_qualify_to_where,
127                enable_ilike_to_like: true, // Always enabled by default
128                enable_cte_hoister: !no_cte_hoister,
129                enable_in_lifter: !no_in_lifter,
130            },
131            debug_trace,
132        };
133
134        config
135    }
136}
137
138#[cfg(test)]
139mod tests {
140    use super::*;
141
142    #[test]
143    fn test_default_config() {
144        let config = ExecutionConfig::default();
145
146        assert!(!config.show_preprocessing);
147        assert!(!config.case_insensitive);
148        assert!(!config.auto_hide_empty);
149        assert!(!config.debug_trace);
150
151        // All transformers enabled by default
152        assert!(config.transformer_config.enable_expression_lifter);
153        assert!(config.transformer_config.enable_where_expansion);
154        assert!(config.transformer_config.enable_group_by_expansion);
155        assert!(config.transformer_config.enable_having_expansion);
156        assert!(config.transformer_config.enable_qualify_to_where);
157        assert!(config.transformer_config.enable_cte_hoister);
158        assert!(config.transformer_config.enable_in_lifter);
159    }
160
161    #[test]
162    fn test_builder_pattern() {
163        let config = ExecutionConfig::new()
164            .with_show_preprocessing(true)
165            .with_case_insensitive(true)
166            .with_auto_hide_empty(true)
167            .with_debug_trace(true);
168
169        assert!(config.show_preprocessing);
170        assert!(config.case_insensitive);
171        assert!(config.auto_hide_empty);
172        assert!(config.debug_trace);
173    }
174
175    #[test]
176    fn test_without_preprocessing() {
177        let config = ExecutionConfig::new().without_preprocessing();
178
179        assert!(!config.transformer_config.enable_expression_lifter);
180        assert!(!config.transformer_config.enable_where_expansion);
181        assert!(!config.transformer_config.enable_group_by_expansion);
182        assert!(!config.transformer_config.enable_having_expansion);
183        assert!(!config.transformer_config.enable_qualify_to_where);
184        assert!(!config.transformer_config.enable_cte_hoister);
185        assert!(!config.transformer_config.enable_in_lifter);
186    }
187
188    #[test]
189    fn test_from_cli_flags_all_disabled() {
190        let config = ExecutionConfig::from_cli_flags(
191            false, // show_preprocessing
192            false, // show_sql_transformations
193            false, // case_insensitive
194            false, // auto_hide_empty
195            true,  // no_expression_lifter
196            true,  // no_where_expansion
197            true,  // no_group_by_expansion
198            true,  // no_having_expansion
199            true,  // no_order_by_expansion
200            true,  // no_qualify_to_where
201            true,  // no_cte_hoister
202            true,  // no_in_lifter
203            false, // debug_trace
204        );
205
206        assert!(!config.show_preprocessing);
207        assert!(!config.show_sql_transformations);
208        assert!(!config.case_insensitive);
209        assert!(!config.transformer_config.enable_expression_lifter);
210        assert!(!config.transformer_config.enable_where_expansion);
211        assert!(!config.transformer_config.enable_group_by_expansion);
212        assert!(!config.transformer_config.enable_having_expansion);
213        assert!(!config.transformer_config.enable_qualify_to_where);
214        assert!(!config.transformer_config.enable_cte_hoister);
215        assert!(!config.transformer_config.enable_in_lifter);
216    }
217
218    #[test]
219    fn test_from_cli_flags_all_enabled() {
220        let config = ExecutionConfig::from_cli_flags(
221            true,  // show_preprocessing
222            true,  // show_sql_transformations
223            true,  // case_insensitive
224            true,  // auto_hide_empty
225            false, // no_expression_lifter
226            false, // no_where_expansion
227            false, // no_group_by_expansion
228            false, // no_having_expansion
229            false, // no_order_by_expansion
230            false, // no_qualify_to_where
231            false, // no_cte_hoister
232            false, // no_in_lifter
233            true,  // debug_trace
234        );
235
236        assert!(config.show_preprocessing);
237        assert!(config.show_sql_transformations);
238        assert!(config.case_insensitive);
239        assert!(config.auto_hide_empty);
240        assert!(config.debug_trace);
241        assert!(config.transformer_config.enable_expression_lifter);
242        assert!(config.transformer_config.enable_where_expansion);
243        assert!(config.transformer_config.enable_group_by_expansion);
244        assert!(config.transformer_config.enable_having_expansion);
245        assert!(config.transformer_config.enable_qualify_to_where);
246        assert!(config.transformer_config.enable_cte_hoister);
247        assert!(config.transformer_config.enable_in_lifter);
248    }
249
250    #[test]
251    fn test_custom_transformer_config() {
252        let custom_transformer = TransformerConfig {
253            enable_expression_lifter: true,
254            enable_where_expansion: false,
255            enable_group_by_expansion: true,
256            enable_having_expansion: false,
257            enable_order_by_expansion: true,
258            enable_qualify_to_where: false,
259            enable_ilike_to_like: true,
260            enable_cte_hoister: true,
261            enable_in_lifter: false,
262        };
263
264        let config = ExecutionConfig::new().with_transformer_config(custom_transformer.clone());
265
266        assert!(config.transformer_config.enable_expression_lifter);
267        assert!(!config.transformer_config.enable_where_expansion);
268        assert!(config.transformer_config.enable_group_by_expansion);
269        assert!(!config.transformer_config.enable_having_expansion);
270        assert!(!config.transformer_config.enable_qualify_to_where);
271        assert!(config.transformer_config.enable_cte_hoister);
272        assert!(!config.transformer_config.enable_in_lifter);
273    }
274}