sql_cli/sql/parser/
ast.rs

1//! Abstract Syntax Tree (AST) definitions for SQL queries
2//!
3//! This module contains all the data structures that represent
4//! the parsed SQL query structure.
5
6// ===== Expression Types =====
7
8#[derive(Debug, Clone)]
9pub enum SqlExpression {
10    Column(String),
11    StringLiteral(String),
12    NumberLiteral(String),
13    BooleanLiteral(bool),
14    Null, // NULL literal
15    DateTimeConstructor {
16        year: i32,
17        month: u32,
18        day: u32,
19        hour: Option<u32>,
20        minute: Option<u32>,
21        second: Option<u32>,
22    },
23    DateTimeToday {
24        hour: Option<u32>,
25        minute: Option<u32>,
26        second: Option<u32>,
27    },
28    MethodCall {
29        object: String,
30        method: String,
31        args: Vec<SqlExpression>,
32    },
33    ChainedMethodCall {
34        base: Box<SqlExpression>,
35        method: String,
36        args: Vec<SqlExpression>,
37    },
38    FunctionCall {
39        name: String,
40        args: Vec<SqlExpression>,
41        distinct: bool, // For COUNT(DISTINCT col), SUM(DISTINCT col), etc.
42    },
43    WindowFunction {
44        name: String,
45        args: Vec<SqlExpression>,
46        window_spec: WindowSpec,
47    },
48    BinaryOp {
49        left: Box<SqlExpression>,
50        op: String,
51        right: Box<SqlExpression>,
52    },
53    InList {
54        expr: Box<SqlExpression>,
55        values: Vec<SqlExpression>,
56    },
57    NotInList {
58        expr: Box<SqlExpression>,
59        values: Vec<SqlExpression>,
60    },
61    Between {
62        expr: Box<SqlExpression>,
63        lower: Box<SqlExpression>,
64        upper: Box<SqlExpression>,
65    },
66    Not {
67        expr: Box<SqlExpression>,
68    },
69    CaseExpression {
70        when_branches: Vec<WhenBranch>,
71        else_branch: Option<Box<SqlExpression>>,
72    },
73    /// Scalar subquery that returns a single value
74    /// Used in expressions like: WHERE col = (SELECT MAX(id) FROM table)
75    ScalarSubquery {
76        query: Box<SelectStatement>,
77    },
78    /// IN subquery that returns multiple values  
79    /// Used in expressions like: WHERE col IN (SELECT id FROM table WHERE ...)
80    InSubquery {
81        expr: Box<SqlExpression>,
82        subquery: Box<SelectStatement>,
83    },
84    /// NOT IN subquery
85    /// Used in expressions like: WHERE col NOT IN (SELECT id FROM table WHERE ...)
86    NotInSubquery {
87        expr: Box<SqlExpression>,
88        subquery: Box<SelectStatement>,
89    },
90}
91
92#[derive(Debug, Clone)]
93pub struct WhenBranch {
94    pub condition: Box<SqlExpression>,
95    pub result: Box<SqlExpression>,
96}
97
98// ===== WHERE Clause Types =====
99
100#[derive(Debug, Clone)]
101pub struct WhereClause {
102    pub conditions: Vec<Condition>,
103}
104
105#[derive(Debug, Clone)]
106pub struct Condition {
107    pub expr: SqlExpression,
108    pub connector: Option<LogicalOp>, // AND/OR connecting to next condition
109}
110
111#[derive(Debug, Clone)]
112pub enum LogicalOp {
113    And,
114    Or,
115}
116
117// ===== ORDER BY Types =====
118
119#[derive(Debug, Clone, PartialEq)]
120pub enum SortDirection {
121    Asc,
122    Desc,
123}
124
125#[derive(Debug, Clone)]
126pub struct OrderByColumn {
127    pub column: String,
128    pub direction: SortDirection,
129}
130
131// ===== Window Function Types =====
132
133#[derive(Debug, Clone)]
134pub struct WindowSpec {
135    pub partition_by: Vec<String>,
136    pub order_by: Vec<OrderByColumn>,
137}
138
139// ===== SELECT Statement Types =====
140
141/// Represents a SELECT item - either a simple column or a computed expression with alias
142#[derive(Debug, Clone)]
143pub enum SelectItem {
144    /// Simple column reference: "`column_name`"
145    Column(String),
146    /// Computed expression with alias: "expr AS alias"
147    Expression { expr: SqlExpression, alias: String },
148    /// Star selector: "*"
149    Star,
150}
151
152#[derive(Debug, Clone)]
153pub struct SelectStatement {
154    pub distinct: bool,                // SELECT DISTINCT flag
155    pub columns: Vec<String>,          // Keep for backward compatibility, will be deprecated
156    pub select_items: Vec<SelectItem>, // New field for computed expressions
157    pub from_table: Option<String>,
158    pub from_subquery: Option<Box<SelectStatement>>, // Subquery in FROM clause
159    pub from_function: Option<TableFunction>,        // Table function like RANGE() in FROM clause
160    pub from_alias: Option<String>,                  // Alias for subquery (AS name)
161    pub joins: Vec<JoinClause>,                      // JOIN clauses
162    pub where_clause: Option<WhereClause>,
163    pub order_by: Option<Vec<OrderByColumn>>,
164    pub group_by: Option<Vec<SqlExpression>>, // Changed from Vec<String> to support expressions
165    pub having: Option<SqlExpression>,        // HAVING clause for post-aggregation filtering
166    pub limit: Option<usize>,
167    pub offset: Option<usize>,
168    pub ctes: Vec<CTE>, // Common Table Expressions (WITH clause)
169}
170
171// ===== Table and Join Types =====
172
173/// Table function that generates virtual tables
174#[derive(Debug, Clone)]
175pub enum TableFunction {
176    Range {
177        start: SqlExpression,
178        end: SqlExpression,
179        step: Option<SqlExpression>,
180    },
181}
182
183/// Common Table Expression (CTE) structure
184#[derive(Debug, Clone)]
185pub struct CTE {
186    pub name: String,
187    pub column_list: Option<Vec<String>>, // Optional column list: WITH t(col1, col2) AS ...
188    pub cte_type: CTEType,
189}
190
191/// Type of CTE - standard SQL or WEB fetch
192#[derive(Debug, Clone)]
193pub enum CTEType {
194    Standard(SelectStatement),
195    Web(WebCTESpec),
196}
197
198/// Specification for WEB CTEs
199#[derive(Debug, Clone)]
200pub struct WebCTESpec {
201    pub url: String,
202    pub format: Option<DataFormat>,     // CSV, JSON, or auto-detect
203    pub headers: Vec<(String, String)>, // HTTP headers
204    pub cache_seconds: Option<u64>,     // Cache duration
205}
206
207/// Data format for WEB CTEs
208#[derive(Debug, Clone)]
209pub enum DataFormat {
210    CSV,
211    JSON,
212    Auto, // Auto-detect from Content-Type or extension
213}
214
215/// Table source - either a file/table name or a derived table (subquery/CTE)
216#[derive(Debug, Clone)]
217pub enum TableSource {
218    Table(String), // Regular table from CSV/JSON
219    DerivedTable {
220        // Both CTE and subquery
221        query: Box<SelectStatement>,
222        alias: String, // Required alias for subqueries
223    },
224}
225
226/// Join type enumeration
227#[derive(Debug, Clone, PartialEq)]
228pub enum JoinType {
229    Inner,
230    Left,
231    Right,
232    Full,
233    Cross,
234}
235
236/// Join operator for join conditions
237#[derive(Debug, Clone, PartialEq)]
238pub enum JoinOperator {
239    Equal,
240    NotEqual,
241    LessThan,
242    GreaterThan,
243    LessThanOrEqual,
244    GreaterThanOrEqual,
245}
246
247/// Join condition - initially just column equality
248#[derive(Debug, Clone)]
249pub struct JoinCondition {
250    pub left_column: String, // Column from left table (can include table prefix)
251    pub operator: JoinOperator, // Join operator (initially just Equal)
252    pub right_column: String, // Column from right table (can include table prefix)
253}
254
255/// Join clause structure
256#[derive(Debug, Clone)]
257pub struct JoinClause {
258    pub join_type: JoinType,
259    pub table: TableSource,       // The table being joined
260    pub alias: Option<String>,    // Optional alias for the joined table
261    pub condition: JoinCondition, // ON condition
262}