Skip to main content

polyglot_sql/
expressions.rs

1//! SQL Expression AST (Abstract Syntax Tree).
2//!
3//! This module defines all the AST node types used to represent parsed SQL
4//! statements and expressions. The design follows Python sqlglot's expression
5//! hierarchy, ported to a Rust enum-based AST.
6//!
7//! # Architecture
8//!
9//! The central type is [`Expression`], a large tagged enum with one variant per
10//! SQL construct. Inner structs carry the fields for each variant. Most
11//! heap-allocated variants are wrapped in `Box` to keep the enum size small.
12//!
13//! # Variant Groups
14//!
15//! | Group | Examples | Purpose |
16//! |---|---|---|
17//! | **Queries** | `Select`, `Union`, `Intersect`, `Except`, `Subquery` | Top-level query structures |
18//! | **DML** | `Insert`, `Update`, `Delete`, `Merge`, `Copy` | Data manipulation |
19//! | **DDL** | `CreateTable`, `AlterTable`, `DropView`, `CreateIndex` | Schema definition |
20//! | **Clauses** | `From`, `Join`, `Where`, `GroupBy`, `OrderBy`, `With` | Query clauses |
21//! | **Operators** | `And`, `Or`, `Add`, `Eq`, `Like`, `Not` | Binary and unary operations |
22//! | **Functions** | `Function`, `AggregateFunction`, `WindowFunction`, `Count`, `Sum` | Scalar, aggregate, and window functions |
23//! | **Literals** | `Literal`, `Boolean`, `Null`, `Interval` | Constant values |
24//! | **Types** | `DataType`, `Cast`, `TryCast`, `SafeCast` | Data types and casts |
25//! | **Identifiers** | `Identifier`, `Column`, `Table`, `Star` | Name references |
26//!
27//! # SQL Generation
28//!
29//! Every `Expression` can be rendered back to SQL via [`Expression::sql()`]
30//! (generic dialect) or [`Expression::sql_for()`] (specific dialect). The
31//! actual generation logic lives in the `generator` module.
32
33use crate::tokens::Span;
34use serde::{Deserialize, Serialize};
35use std::fmt;
36#[cfg(feature = "bindings")]
37use ts_rs::TS;
38
39/// Helper function for serde default value
40fn default_true() -> bool {
41    true
42}
43
44fn is_true(v: &bool) -> bool {
45    *v
46}
47
48/// Represent any SQL expression or statement as a single, recursive AST node.
49///
50/// `Expression` is the root type of the polyglot AST. Every parsed SQL
51/// construct -- from a simple integer literal to a multi-CTE query with
52/// window functions -- is represented as a variant of this enum.
53///
54/// Variants are organized into logical groups (see the module-level docs).
55/// Most non-trivial variants box their payload so that `size_of::<Expression>()`
56/// stays small (currently two words: tag + pointer).
57///
58/// # Constructing Expressions
59///
60/// Use the convenience constructors on `impl Expression` for common cases:
61///
62/// ```rust,ignore
63/// use polyglot_sql::expressions::Expression;
64///
65/// let col  = Expression::column("id");
66/// let lit  = Expression::number(42);
67/// let star = Expression::star();
68/// ```
69///
70/// # Generating SQL
71///
72/// ```rust,ignore
73/// let expr = Expression::column("name");
74/// assert_eq!(expr.sql(), "name");
75/// ```
76#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
77#[cfg_attr(feature = "bindings", derive(TS))]
78#[serde(rename_all = "snake_case")]
79#[cfg_attr(feature = "bindings", ts(export))]
80pub enum Expression {
81    // Literals
82    Literal(Box<Literal>),
83    Boolean(BooleanLiteral),
84    Null(Null),
85
86    // Identifiers
87    Identifier(Identifier),
88    Column(Box<Column>),
89    Table(Box<TableRef>),
90    Star(Star),
91    /// Snowflake braced wildcard syntax: {*}, {tbl.*}, {* EXCLUDE (...)}, {* ILIKE '...'}
92    BracedWildcard(Box<Expression>),
93
94    // Queries
95    Select(Box<Select>),
96    Union(Box<Union>),
97    Intersect(Box<Intersect>),
98    Except(Box<Except>),
99    Subquery(Box<Subquery>),
100    PipeOperator(Box<PipeOperator>),
101    Pivot(Box<Pivot>),
102    PivotAlias(Box<PivotAlias>),
103    Unpivot(Box<Unpivot>),
104    Values(Box<Values>),
105    PreWhere(Box<PreWhere>),
106    Stream(Box<Stream>),
107    UsingData(Box<UsingData>),
108    XmlNamespace(Box<XmlNamespace>),
109
110    // DML
111    Insert(Box<Insert>),
112    Update(Box<Update>),
113    Delete(Box<Delete>),
114    Copy(Box<CopyStmt>),
115    Put(Box<PutStmt>),
116    StageReference(Box<StageReference>),
117    TryCatch(Box<TryCatch>),
118
119    // Expressions
120    Alias(Box<Alias>),
121    Cast(Box<Cast>),
122    Collation(Box<CollationExpr>),
123    Case(Box<Case>),
124
125    // Binary operations
126    And(Box<BinaryOp>),
127    Or(Box<BinaryOp>),
128    Add(Box<BinaryOp>),
129    Sub(Box<BinaryOp>),
130    Mul(Box<BinaryOp>),
131    Div(Box<BinaryOp>),
132    Mod(Box<BinaryOp>),
133    Eq(Box<BinaryOp>),
134    Neq(Box<BinaryOp>),
135    Lt(Box<BinaryOp>),
136    Lte(Box<BinaryOp>),
137    Gt(Box<BinaryOp>),
138    Gte(Box<BinaryOp>),
139    Like(Box<LikeOp>),
140    ILike(Box<LikeOp>),
141    /// SQLite MATCH operator (FTS)
142    Match(Box<BinaryOp>),
143    BitwiseAnd(Box<BinaryOp>),
144    BitwiseOr(Box<BinaryOp>),
145    BitwiseXor(Box<BinaryOp>),
146    Concat(Box<BinaryOp>),
147    Adjacent(Box<BinaryOp>),   // PostgreSQL range adjacency operator (-|-)
148    TsMatch(Box<BinaryOp>),    // PostgreSQL text search match operator (@@)
149    PropertyEQ(Box<BinaryOp>), // := assignment operator (MySQL @var := val, DuckDB named args)
150
151    // PostgreSQL array/JSONB operators
152    ArrayContainsAll(Box<BinaryOp>), // @> operator (array contains all)
153    ArrayContainedBy(Box<BinaryOp>), // <@ operator (array contained by)
154    ArrayOverlaps(Box<BinaryOp>),    // && operator (array overlaps)
155    JSONBContainsAllTopKeys(Box<BinaryOp>), // ?& operator (JSONB contains all keys)
156    JSONBContainsAnyTopKeys(Box<BinaryOp>), // ?| operator (JSONB contains any key)
157    JSONBDeleteAtPath(Box<BinaryOp>), // #- operator (JSONB delete at path)
158    ExtendsLeft(Box<BinaryOp>),      // &< operator (PostgreSQL range extends left)
159    ExtendsRight(Box<BinaryOp>),     // &> operator (PostgreSQL range extends right)
160
161    // Unary operations
162    Not(Box<UnaryOp>),
163    Neg(Box<UnaryOp>),
164    BitwiseNot(Box<UnaryOp>),
165
166    // Predicates
167    In(Box<In>),
168    Between(Box<Between>),
169    IsNull(Box<IsNull>),
170    IsTrue(Box<IsTrueFalse>),
171    IsFalse(Box<IsTrueFalse>),
172    IsJson(Box<IsJson>),
173    Is(Box<BinaryOp>), // General IS expression (e.g., a IS ?)
174    Exists(Box<Exists>),
175    /// MySQL MEMBER OF operator: expr MEMBER OF(json_array)
176    MemberOf(Box<BinaryOp>),
177
178    // Functions
179    Function(Box<Function>),
180    AggregateFunction(Box<AggregateFunction>),
181    WindowFunction(Box<WindowFunction>),
182
183    // Clauses
184    From(Box<From>),
185    Join(Box<Join>),
186    JoinedTable(Box<JoinedTable>),
187    Where(Box<Where>),
188    GroupBy(Box<GroupBy>),
189    Having(Box<Having>),
190    OrderBy(Box<OrderBy>),
191    Limit(Box<Limit>),
192    Offset(Box<Offset>),
193    Qualify(Box<Qualify>),
194    With(Box<With>),
195    Cte(Box<Cte>),
196    DistributeBy(Box<DistributeBy>),
197    ClusterBy(Box<ClusterBy>),
198    SortBy(Box<SortBy>),
199    LateralView(Box<LateralView>),
200    Hint(Box<Hint>),
201    Pseudocolumn(Pseudocolumn),
202
203    // Oracle hierarchical queries (CONNECT BY)
204    Connect(Box<Connect>),
205    Prior(Box<Prior>),
206    ConnectByRoot(Box<ConnectByRoot>),
207
208    // Pattern matching (MATCH_RECOGNIZE)
209    MatchRecognize(Box<MatchRecognize>),
210
211    // Order expressions
212    Ordered(Box<Ordered>),
213
214    // Window specifications
215    Window(Box<WindowSpec>),
216    Over(Box<Over>),
217    WithinGroup(Box<WithinGroup>),
218
219    // Data types
220    DataType(DataType),
221
222    // Arrays and structs
223    Array(Box<Array>),
224    Struct(Box<Struct>),
225    Tuple(Box<Tuple>),
226
227    // Interval
228    Interval(Box<Interval>),
229
230    // String functions
231    ConcatWs(Box<ConcatWs>),
232    Substring(Box<SubstringFunc>),
233    Upper(Box<UnaryFunc>),
234    Lower(Box<UnaryFunc>),
235    Length(Box<UnaryFunc>),
236    Trim(Box<TrimFunc>),
237    LTrim(Box<UnaryFunc>),
238    RTrim(Box<UnaryFunc>),
239    Replace(Box<ReplaceFunc>),
240    Reverse(Box<UnaryFunc>),
241    Left(Box<LeftRightFunc>),
242    Right(Box<LeftRightFunc>),
243    Repeat(Box<RepeatFunc>),
244    Lpad(Box<PadFunc>),
245    Rpad(Box<PadFunc>),
246    Split(Box<SplitFunc>),
247    RegexpLike(Box<RegexpFunc>),
248    RegexpReplace(Box<RegexpReplaceFunc>),
249    RegexpExtract(Box<RegexpExtractFunc>),
250    Overlay(Box<OverlayFunc>),
251
252    // Math functions
253    Abs(Box<UnaryFunc>),
254    Round(Box<RoundFunc>),
255    Floor(Box<FloorFunc>),
256    Ceil(Box<CeilFunc>),
257    Power(Box<BinaryFunc>),
258    Sqrt(Box<UnaryFunc>),
259    Cbrt(Box<UnaryFunc>),
260    Ln(Box<UnaryFunc>),
261    Log(Box<LogFunc>),
262    Exp(Box<UnaryFunc>),
263    Sign(Box<UnaryFunc>),
264    Greatest(Box<VarArgFunc>),
265    Least(Box<VarArgFunc>),
266
267    // Date/time functions
268    CurrentDate(CurrentDate),
269    CurrentTime(CurrentTime),
270    CurrentTimestamp(CurrentTimestamp),
271    CurrentTimestampLTZ(CurrentTimestampLTZ),
272    AtTimeZone(Box<AtTimeZone>),
273    DateAdd(Box<DateAddFunc>),
274    DateSub(Box<DateAddFunc>),
275    DateDiff(Box<DateDiffFunc>),
276    DateTrunc(Box<DateTruncFunc>),
277    Extract(Box<ExtractFunc>),
278    ToDate(Box<ToDateFunc>),
279    ToTimestamp(Box<ToTimestampFunc>),
280    Date(Box<UnaryFunc>),
281    Time(Box<UnaryFunc>),
282    DateFromUnixDate(Box<UnaryFunc>),
283    UnixDate(Box<UnaryFunc>),
284    UnixSeconds(Box<UnaryFunc>),
285    UnixMillis(Box<UnaryFunc>),
286    UnixMicros(Box<UnaryFunc>),
287    UnixToTimeStr(Box<BinaryFunc>),
288    TimeStrToDate(Box<UnaryFunc>),
289    DateToDi(Box<UnaryFunc>),
290    DiToDate(Box<UnaryFunc>),
291    TsOrDiToDi(Box<UnaryFunc>),
292    TsOrDsToDatetime(Box<UnaryFunc>),
293    TsOrDsToTimestamp(Box<UnaryFunc>),
294    YearOfWeek(Box<UnaryFunc>),
295    YearOfWeekIso(Box<UnaryFunc>),
296
297    // Control flow functions
298    Coalesce(Box<VarArgFunc>),
299    NullIf(Box<BinaryFunc>),
300    IfFunc(Box<IfFunc>),
301    IfNull(Box<BinaryFunc>),
302    Nvl(Box<BinaryFunc>),
303    Nvl2(Box<Nvl2Func>),
304
305    // Type conversion
306    TryCast(Box<Cast>),
307    SafeCast(Box<Cast>),
308
309    // Typed aggregate functions
310    Count(Box<CountFunc>),
311    Sum(Box<AggFunc>),
312    Avg(Box<AggFunc>),
313    Min(Box<AggFunc>),
314    Max(Box<AggFunc>),
315    GroupConcat(Box<GroupConcatFunc>),
316    StringAgg(Box<StringAggFunc>),
317    ListAgg(Box<ListAggFunc>),
318    ArrayAgg(Box<AggFunc>),
319    CountIf(Box<AggFunc>),
320    SumIf(Box<SumIfFunc>),
321    Stddev(Box<AggFunc>),
322    StddevPop(Box<AggFunc>),
323    StddevSamp(Box<AggFunc>),
324    Variance(Box<AggFunc>),
325    VarPop(Box<AggFunc>),
326    VarSamp(Box<AggFunc>),
327    Median(Box<AggFunc>),
328    Mode(Box<AggFunc>),
329    First(Box<AggFunc>),
330    Last(Box<AggFunc>),
331    AnyValue(Box<AggFunc>),
332    ApproxDistinct(Box<AggFunc>),
333    ApproxCountDistinct(Box<AggFunc>),
334    ApproxPercentile(Box<ApproxPercentileFunc>),
335    Percentile(Box<PercentileFunc>),
336    LogicalAnd(Box<AggFunc>),
337    LogicalOr(Box<AggFunc>),
338    Skewness(Box<AggFunc>),
339    BitwiseCount(Box<UnaryFunc>),
340    ArrayConcatAgg(Box<AggFunc>),
341    ArrayUniqueAgg(Box<AggFunc>),
342    BoolXorAgg(Box<AggFunc>),
343
344    // Typed window functions
345    RowNumber(RowNumber),
346    Rank(Rank),
347    DenseRank(DenseRank),
348    NTile(Box<NTileFunc>),
349    Lead(Box<LeadLagFunc>),
350    Lag(Box<LeadLagFunc>),
351    FirstValue(Box<ValueFunc>),
352    LastValue(Box<ValueFunc>),
353    NthValue(Box<NthValueFunc>),
354    PercentRank(PercentRank),
355    CumeDist(CumeDist),
356    PercentileCont(Box<PercentileFunc>),
357    PercentileDisc(Box<PercentileFunc>),
358
359    // Additional string functions
360    Contains(Box<BinaryFunc>),
361    StartsWith(Box<BinaryFunc>),
362    EndsWith(Box<BinaryFunc>),
363    Position(Box<PositionFunc>),
364    Initcap(Box<UnaryFunc>),
365    Ascii(Box<UnaryFunc>),
366    Chr(Box<UnaryFunc>),
367    /// MySQL CHAR function with multiple args and optional USING charset
368    CharFunc(Box<CharFunc>),
369    Soundex(Box<UnaryFunc>),
370    Levenshtein(Box<BinaryFunc>),
371    ByteLength(Box<UnaryFunc>),
372    Hex(Box<UnaryFunc>),
373    LowerHex(Box<UnaryFunc>),
374    Unicode(Box<UnaryFunc>),
375
376    // Additional math functions
377    ModFunc(Box<BinaryFunc>),
378    Random(Random),
379    Rand(Box<Rand>),
380    TruncFunc(Box<TruncateFunc>),
381    Pi(Pi),
382    Radians(Box<UnaryFunc>),
383    Degrees(Box<UnaryFunc>),
384    Sin(Box<UnaryFunc>),
385    Cos(Box<UnaryFunc>),
386    Tan(Box<UnaryFunc>),
387    Asin(Box<UnaryFunc>),
388    Acos(Box<UnaryFunc>),
389    Atan(Box<UnaryFunc>),
390    Atan2(Box<BinaryFunc>),
391    IsNan(Box<UnaryFunc>),
392    IsInf(Box<UnaryFunc>),
393    IntDiv(Box<BinaryFunc>),
394
395    // Control flow
396    Decode(Box<DecodeFunc>),
397
398    // Additional date/time functions
399    DateFormat(Box<DateFormatFunc>),
400    FormatDate(Box<DateFormatFunc>),
401    Year(Box<UnaryFunc>),
402    Month(Box<UnaryFunc>),
403    Day(Box<UnaryFunc>),
404    Hour(Box<UnaryFunc>),
405    Minute(Box<UnaryFunc>),
406    Second(Box<UnaryFunc>),
407    DayOfWeek(Box<UnaryFunc>),
408    DayOfWeekIso(Box<UnaryFunc>),
409    DayOfMonth(Box<UnaryFunc>),
410    DayOfYear(Box<UnaryFunc>),
411    WeekOfYear(Box<UnaryFunc>),
412    Quarter(Box<UnaryFunc>),
413    AddMonths(Box<BinaryFunc>),
414    MonthsBetween(Box<BinaryFunc>),
415    LastDay(Box<LastDayFunc>),
416    NextDay(Box<BinaryFunc>),
417    Epoch(Box<UnaryFunc>),
418    EpochMs(Box<UnaryFunc>),
419    FromUnixtime(Box<FromUnixtimeFunc>),
420    UnixTimestamp(Box<UnixTimestampFunc>),
421    MakeDate(Box<MakeDateFunc>),
422    MakeTimestamp(Box<MakeTimestampFunc>),
423    TimestampTrunc(Box<DateTruncFunc>),
424    TimeStrToUnix(Box<UnaryFunc>),
425
426    // Session/User functions
427    SessionUser(SessionUser),
428
429    // Hash/Crypto functions
430    SHA(Box<UnaryFunc>),
431    SHA1Digest(Box<UnaryFunc>),
432
433    // Time conversion functions
434    TimeToUnix(Box<UnaryFunc>),
435
436    // Array functions
437    ArrayFunc(Box<ArrayConstructor>),
438    ArrayLength(Box<UnaryFunc>),
439    ArraySize(Box<UnaryFunc>),
440    Cardinality(Box<UnaryFunc>),
441    ArrayContains(Box<BinaryFunc>),
442    ArrayPosition(Box<BinaryFunc>),
443    ArrayAppend(Box<BinaryFunc>),
444    ArrayPrepend(Box<BinaryFunc>),
445    ArrayConcat(Box<VarArgFunc>),
446    ArraySort(Box<ArraySortFunc>),
447    ArrayReverse(Box<UnaryFunc>),
448    ArrayDistinct(Box<UnaryFunc>),
449    ArrayJoin(Box<ArrayJoinFunc>),
450    ArrayToString(Box<ArrayJoinFunc>),
451    Unnest(Box<UnnestFunc>),
452    Explode(Box<UnaryFunc>),
453    ExplodeOuter(Box<UnaryFunc>),
454    ArrayFilter(Box<ArrayFilterFunc>),
455    ArrayTransform(Box<ArrayTransformFunc>),
456    ArrayFlatten(Box<UnaryFunc>),
457    ArrayCompact(Box<UnaryFunc>),
458    ArrayIntersect(Box<VarArgFunc>),
459    ArrayUnion(Box<BinaryFunc>),
460    ArrayExcept(Box<BinaryFunc>),
461    ArrayRemove(Box<BinaryFunc>),
462    ArrayZip(Box<VarArgFunc>),
463    Sequence(Box<SequenceFunc>),
464    Generate(Box<SequenceFunc>),
465    ExplodingGenerateSeries(Box<SequenceFunc>),
466    ToArray(Box<UnaryFunc>),
467    StarMap(Box<BinaryFunc>),
468
469    // Struct functions
470    StructFunc(Box<StructConstructor>),
471    StructExtract(Box<StructExtractFunc>),
472    NamedStruct(Box<NamedStructFunc>),
473
474    // Map functions
475    MapFunc(Box<MapConstructor>),
476    MapFromEntries(Box<UnaryFunc>),
477    MapFromArrays(Box<BinaryFunc>),
478    MapKeys(Box<UnaryFunc>),
479    MapValues(Box<UnaryFunc>),
480    MapContainsKey(Box<BinaryFunc>),
481    MapConcat(Box<VarArgFunc>),
482    ElementAt(Box<BinaryFunc>),
483    TransformKeys(Box<TransformFunc>),
484    TransformValues(Box<TransformFunc>),
485
486    // Exasol: function call with EMITS clause
487    FunctionEmits(Box<FunctionEmits>),
488
489    // JSON functions
490    JsonExtract(Box<JsonExtractFunc>),
491    JsonExtractScalar(Box<JsonExtractFunc>),
492    JsonExtractPath(Box<JsonPathFunc>),
493    JsonArray(Box<VarArgFunc>),
494    JsonObject(Box<JsonObjectFunc>),
495    JsonQuery(Box<JsonExtractFunc>),
496    JsonValue(Box<JsonExtractFunc>),
497    JsonArrayLength(Box<UnaryFunc>),
498    JsonKeys(Box<UnaryFunc>),
499    JsonType(Box<UnaryFunc>),
500    ParseJson(Box<UnaryFunc>),
501    ToJson(Box<UnaryFunc>),
502    JsonSet(Box<JsonModifyFunc>),
503    JsonInsert(Box<JsonModifyFunc>),
504    JsonRemove(Box<JsonPathFunc>),
505    JsonMergePatch(Box<BinaryFunc>),
506    JsonArrayAgg(Box<JsonArrayAggFunc>),
507    JsonObjectAgg(Box<JsonObjectAggFunc>),
508
509    // Type casting/conversion
510    Convert(Box<ConvertFunc>),
511    Typeof(Box<UnaryFunc>),
512
513    // Additional expressions
514    Lambda(Box<LambdaExpr>),
515    Parameter(Box<Parameter>),
516    Placeholder(Placeholder),
517    NamedArgument(Box<NamedArgument>),
518    /// TABLE ref or MODEL ref used as a function argument (BigQuery)
519    /// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
520    TableArgument(Box<TableArgument>),
521    SqlComment(Box<SqlComment>),
522
523    // Additional predicates
524    NullSafeEq(Box<BinaryOp>),
525    NullSafeNeq(Box<BinaryOp>),
526    Glob(Box<BinaryOp>),
527    SimilarTo(Box<SimilarToExpr>),
528    Any(Box<QuantifiedExpr>),
529    All(Box<QuantifiedExpr>),
530    Overlaps(Box<OverlapsExpr>),
531
532    // Bitwise operations
533    BitwiseLeftShift(Box<BinaryOp>),
534    BitwiseRightShift(Box<BinaryOp>),
535    BitwiseAndAgg(Box<AggFunc>),
536    BitwiseOrAgg(Box<AggFunc>),
537    BitwiseXorAgg(Box<AggFunc>),
538
539    // Array/struct/map access
540    Subscript(Box<Subscript>),
541    Dot(Box<DotAccess>),
542    MethodCall(Box<MethodCall>),
543    ArraySlice(Box<ArraySlice>),
544
545    // DDL statements
546    CreateTable(Box<CreateTable>),
547    DropTable(Box<DropTable>),
548    Undrop(Box<Undrop>),
549    AlterTable(Box<AlterTable>),
550    SplitTable(Box<SplitTable>),
551    FlashbackTable(Box<FlashbackTable>),
552    CreateIndex(Box<CreateIndex>),
553    DropIndex(Box<DropIndex>),
554    CreateView(Box<CreateView>),
555    DropView(Box<DropView>),
556    AlterView(Box<AlterView>),
557    AlterIndex(Box<AlterIndex>),
558    Truncate(Box<Truncate>),
559    Use(Box<Use>),
560    Cache(Box<Cache>),
561    Uncache(Box<Uncache>),
562    LoadData(Box<LoadData>),
563    Pragma(Box<Pragma>),
564    Grant(Box<Grant>),
565    Revoke(Box<Revoke>),
566    Comment(Box<Comment>),
567    SetStatement(Box<SetStatement>),
568    // Phase 4: Additional DDL statements
569    CreateSchema(Box<CreateSchema>),
570    DropSchema(Box<DropSchema>),
571    DropNamespace(Box<DropNamespace>),
572    CreateDatabase(Box<CreateDatabase>),
573    DropDatabase(Box<DropDatabase>),
574    CreateFunction(Box<CreateFunction>),
575    DropFunction(Box<DropFunction>),
576    CreateProcedure(Box<CreateProcedure>),
577    DropProcedure(Box<DropProcedure>),
578    CreateSequence(Box<CreateSequence>),
579    CreateSynonym(Box<CreateSynonym>),
580    DropSequence(Box<DropSequence>),
581    AlterSequence(Box<AlterSequence>),
582    CreateTrigger(Box<CreateTrigger>),
583    DropTrigger(Box<DropTrigger>),
584    CreateType(Box<CreateType>),
585    DropType(Box<DropType>),
586    Describe(Box<Describe>),
587    Show(Box<Show>),
588
589    // Transaction and other commands
590    Command(Box<Command>),
591    Kill(Box<Kill>),
592    /// PREPARE statement (PostgreSQL/generic prepared statement definition)
593    Prepare(Box<PrepareStatement>),
594    /// EXEC/EXECUTE statement (TSQL stored procedure call)
595    Execute(Box<ExecuteStatement>),
596
597    /// Snowflake CREATE TASK statement
598    CreateTask(Box<CreateTask>),
599
600    // Placeholder for unparsed/raw SQL
601    Raw(Raw),
602
603    // Paren for grouping
604    Paren(Box<Paren>),
605
606    // Expression with trailing comments (for round-trip preservation)
607    Annotated(Box<Annotated>),
608
609    // === BATCH GENERATED EXPRESSION TYPES ===
610    // Generated from Python sqlglot expressions.py
611    Refresh(Box<Refresh>),
612    LockingStatement(Box<LockingStatement>),
613    SequenceProperties(Box<SequenceProperties>),
614    TruncateTable(Box<TruncateTable>),
615    Clone(Box<Clone>),
616    Attach(Box<Attach>),
617    Detach(Box<Detach>),
618    Install(Box<Install>),
619    Summarize(Box<Summarize>),
620    Declare(Box<Declare>),
621    DeclareItem(Box<DeclareItem>),
622    Set(Box<Set>),
623    Heredoc(Box<Heredoc>),
624    SetItem(Box<SetItem>),
625    QueryBand(Box<QueryBand>),
626    UserDefinedFunction(Box<UserDefinedFunction>),
627    RecursiveWithSearch(Box<RecursiveWithSearch>),
628    ProjectionDef(Box<ProjectionDef>),
629    TableAlias(Box<TableAlias>),
630    ByteString(Box<ByteString>),
631    HexStringExpr(Box<HexStringExpr>),
632    UnicodeString(Box<UnicodeString>),
633    ColumnPosition(Box<ColumnPosition>),
634    ColumnDef(Box<ColumnDef>),
635    AlterColumn(Box<AlterColumn>),
636    AlterSortKey(Box<AlterSortKey>),
637    AlterSet(Box<AlterSet>),
638    RenameColumn(Box<RenameColumn>),
639    Comprehension(Box<Comprehension>),
640    MergeTreeTTLAction(Box<MergeTreeTTLAction>),
641    MergeTreeTTL(Box<MergeTreeTTL>),
642    IndexConstraintOption(Box<IndexConstraintOption>),
643    ColumnConstraint(Box<ColumnConstraint>),
644    PeriodForSystemTimeConstraint(Box<PeriodForSystemTimeConstraint>),
645    CaseSpecificColumnConstraint(Box<CaseSpecificColumnConstraint>),
646    CharacterSetColumnConstraint(Box<CharacterSetColumnConstraint>),
647    CheckColumnConstraint(Box<CheckColumnConstraint>),
648    AssumeColumnConstraint(Box<AssumeColumnConstraint>),
649    CompressColumnConstraint(Box<CompressColumnConstraint>),
650    DateFormatColumnConstraint(Box<DateFormatColumnConstraint>),
651    EphemeralColumnConstraint(Box<EphemeralColumnConstraint>),
652    WithOperator(Box<WithOperator>),
653    GeneratedAsIdentityColumnConstraint(Box<GeneratedAsIdentityColumnConstraint>),
654    AutoIncrementColumnConstraint(AutoIncrementColumnConstraint),
655    CommentColumnConstraint(CommentColumnConstraint),
656    GeneratedAsRowColumnConstraint(Box<GeneratedAsRowColumnConstraint>),
657    IndexColumnConstraint(Box<IndexColumnConstraint>),
658    MaskingPolicyColumnConstraint(Box<MaskingPolicyColumnConstraint>),
659    NotNullColumnConstraint(Box<NotNullColumnConstraint>),
660    PrimaryKeyColumnConstraint(Box<PrimaryKeyColumnConstraint>),
661    UniqueColumnConstraint(Box<UniqueColumnConstraint>),
662    WatermarkColumnConstraint(Box<WatermarkColumnConstraint>),
663    ComputedColumnConstraint(Box<ComputedColumnConstraint>),
664    InOutColumnConstraint(Box<InOutColumnConstraint>),
665    DefaultColumnConstraint(Box<DefaultColumnConstraint>),
666    PathColumnConstraint(Box<PathColumnConstraint>),
667    Constraint(Box<Constraint>),
668    Export(Box<Export>),
669    Filter(Box<Filter>),
670    Changes(Box<Changes>),
671    CopyParameter(Box<CopyParameter>),
672    Credentials(Box<Credentials>),
673    Directory(Box<Directory>),
674    ForeignKey(Box<ForeignKey>),
675    ColumnPrefix(Box<ColumnPrefix>),
676    PrimaryKey(Box<PrimaryKey>),
677    IntoClause(Box<IntoClause>),
678    JoinHint(Box<JoinHint>),
679    Opclass(Box<Opclass>),
680    Index(Box<Index>),
681    IndexParameters(Box<IndexParameters>),
682    ConditionalInsert(Box<ConditionalInsert>),
683    MultitableInserts(Box<MultitableInserts>),
684    OnConflict(Box<OnConflict>),
685    OnCondition(Box<OnCondition>),
686    Returning(Box<Returning>),
687    Introducer(Box<Introducer>),
688    PartitionRange(Box<PartitionRange>),
689    Fetch(Box<Fetch>),
690    Group(Box<Group>),
691    Cube(Box<Cube>),
692    Rollup(Box<Rollup>),
693    GroupingSets(Box<GroupingSets>),
694    LimitOptions(Box<LimitOptions>),
695    Lateral(Box<Lateral>),
696    TableFromRows(Box<TableFromRows>),
697    RowsFrom(Box<RowsFrom>),
698    MatchRecognizeMeasure(Box<MatchRecognizeMeasure>),
699    WithFill(Box<WithFill>),
700    Property(Box<Property>),
701    GrantPrivilege(Box<GrantPrivilege>),
702    GrantPrincipal(Box<GrantPrincipal>),
703    AllowedValuesProperty(Box<AllowedValuesProperty>),
704    AlgorithmProperty(Box<AlgorithmProperty>),
705    AutoIncrementProperty(Box<AutoIncrementProperty>),
706    AutoRefreshProperty(Box<AutoRefreshProperty>),
707    BackupProperty(Box<BackupProperty>),
708    BuildProperty(Box<BuildProperty>),
709    BlockCompressionProperty(Box<BlockCompressionProperty>),
710    CharacterSetProperty(Box<CharacterSetProperty>),
711    ChecksumProperty(Box<ChecksumProperty>),
712    CollateProperty(Box<CollateProperty>),
713    DataBlocksizeProperty(Box<DataBlocksizeProperty>),
714    DataDeletionProperty(Box<DataDeletionProperty>),
715    DefinerProperty(Box<DefinerProperty>),
716    DistKeyProperty(Box<DistKeyProperty>),
717    DistributedByProperty(Box<DistributedByProperty>),
718    DistStyleProperty(Box<DistStyleProperty>),
719    DuplicateKeyProperty(Box<DuplicateKeyProperty>),
720    EngineProperty(Box<EngineProperty>),
721    ToTableProperty(Box<ToTableProperty>),
722    ExecuteAsProperty(Box<ExecuteAsProperty>),
723    ExternalProperty(Box<ExternalProperty>),
724    FallbackProperty(Box<FallbackProperty>),
725    FileFormatProperty(Box<FileFormatProperty>),
726    CredentialsProperty(Box<CredentialsProperty>),
727    FreespaceProperty(Box<FreespaceProperty>),
728    InheritsProperty(Box<InheritsProperty>),
729    InputModelProperty(Box<InputModelProperty>),
730    OutputModelProperty(Box<OutputModelProperty>),
731    IsolatedLoadingProperty(Box<IsolatedLoadingProperty>),
732    JournalProperty(Box<JournalProperty>),
733    LanguageProperty(Box<LanguageProperty>),
734    EnviromentProperty(Box<EnviromentProperty>),
735    ClusteredByProperty(Box<ClusteredByProperty>),
736    DictProperty(Box<DictProperty>),
737    DictRange(Box<DictRange>),
738    OnCluster(Box<OnCluster>),
739    LikeProperty(Box<LikeProperty>),
740    LocationProperty(Box<LocationProperty>),
741    LockProperty(Box<LockProperty>),
742    LockingProperty(Box<LockingProperty>),
743    LogProperty(Box<LogProperty>),
744    MaterializedProperty(Box<MaterializedProperty>),
745    MergeBlockRatioProperty(Box<MergeBlockRatioProperty>),
746    OnProperty(Box<OnProperty>),
747    OnCommitProperty(Box<OnCommitProperty>),
748    PartitionedByProperty(Box<PartitionedByProperty>),
749    PartitionByProperty(Box<PartitionByProperty>),
750    PartitionedByBucket(Box<PartitionedByBucket>),
751    ClusterByColumnsProperty(Box<ClusterByColumnsProperty>),
752    PartitionByTruncate(Box<PartitionByTruncate>),
753    PartitionByRangeProperty(Box<PartitionByRangeProperty>),
754    PartitionByRangePropertyDynamic(Box<PartitionByRangePropertyDynamic>),
755    PartitionByListProperty(Box<PartitionByListProperty>),
756    PartitionList(Box<PartitionList>),
757    Partition(Box<Partition>),
758    RefreshTriggerProperty(Box<RefreshTriggerProperty>),
759    UniqueKeyProperty(Box<UniqueKeyProperty>),
760    RollupProperty(Box<RollupProperty>),
761    PartitionBoundSpec(Box<PartitionBoundSpec>),
762    PartitionedOfProperty(Box<PartitionedOfProperty>),
763    RemoteWithConnectionModelProperty(Box<RemoteWithConnectionModelProperty>),
764    ReturnsProperty(Box<ReturnsProperty>),
765    RowFormatProperty(Box<RowFormatProperty>),
766    RowFormatDelimitedProperty(Box<RowFormatDelimitedProperty>),
767    RowFormatSerdeProperty(Box<RowFormatSerdeProperty>),
768    QueryTransform(Box<QueryTransform>),
769    SampleProperty(Box<SampleProperty>),
770    SecurityProperty(Box<SecurityProperty>),
771    SchemaCommentProperty(Box<SchemaCommentProperty>),
772    SemanticView(Box<SemanticView>),
773    SerdeProperties(Box<SerdeProperties>),
774    SetProperty(Box<SetProperty>),
775    SharingProperty(Box<SharingProperty>),
776    SetConfigProperty(Box<SetConfigProperty>),
777    SettingsProperty(Box<SettingsProperty>),
778    SortKeyProperty(Box<SortKeyProperty>),
779    SqlReadWriteProperty(Box<SqlReadWriteProperty>),
780    SqlSecurityProperty(Box<SqlSecurityProperty>),
781    StabilityProperty(Box<StabilityProperty>),
782    StorageHandlerProperty(Box<StorageHandlerProperty>),
783    TemporaryProperty(Box<TemporaryProperty>),
784    Tags(Box<Tags>),
785    TransformModelProperty(Box<TransformModelProperty>),
786    TransientProperty(Box<TransientProperty>),
787    UsingTemplateProperty(Box<UsingTemplateProperty>),
788    ViewAttributeProperty(Box<ViewAttributeProperty>),
789    VolatileProperty(Box<VolatileProperty>),
790    WithDataProperty(Box<WithDataProperty>),
791    WithJournalTableProperty(Box<WithJournalTableProperty>),
792    WithSchemaBindingProperty(Box<WithSchemaBindingProperty>),
793    WithSystemVersioningProperty(Box<WithSystemVersioningProperty>),
794    WithProcedureOptions(Box<WithProcedureOptions>),
795    EncodeProperty(Box<EncodeProperty>),
796    IncludeProperty(Box<IncludeProperty>),
797    Properties(Box<Properties>),
798    OptionsProperty(Box<OptionsProperty>),
799    InputOutputFormat(Box<InputOutputFormat>),
800    Reference(Box<Reference>),
801    QueryOption(Box<QueryOption>),
802    WithTableHint(Box<WithTableHint>),
803    IndexTableHint(Box<IndexTableHint>),
804    HistoricalData(Box<HistoricalData>),
805    Get(Box<Get>),
806    SetOperation(Box<SetOperation>),
807    Var(Box<Var>),
808    Variadic(Box<Variadic>),
809    Version(Box<Version>),
810    Schema(Box<Schema>),
811    Lock(Box<Lock>),
812    TableSample(Box<TableSample>),
813    Tag(Box<Tag>),
814    UnpivotColumns(Box<UnpivotColumns>),
815    WindowSpec(Box<WindowSpec>),
816    SessionParameter(Box<SessionParameter>),
817    PseudoType(Box<PseudoType>),
818    ObjectIdentifier(Box<ObjectIdentifier>),
819    Transaction(Box<Transaction>),
820    Commit(Box<Commit>),
821    Rollback(Box<Rollback>),
822    AlterSession(Box<AlterSession>),
823    Analyze(Box<Analyze>),
824    AnalyzeStatistics(Box<AnalyzeStatistics>),
825    AnalyzeHistogram(Box<AnalyzeHistogram>),
826    AnalyzeSample(Box<AnalyzeSample>),
827    AnalyzeListChainedRows(Box<AnalyzeListChainedRows>),
828    AnalyzeDelete(Box<AnalyzeDelete>),
829    AnalyzeWith(Box<AnalyzeWith>),
830    AnalyzeValidate(Box<AnalyzeValidate>),
831    AddPartition(Box<AddPartition>),
832    AttachOption(Box<AttachOption>),
833    DropPartition(Box<DropPartition>),
834    ReplacePartition(Box<ReplacePartition>),
835    DPipe(Box<DPipe>),
836    Operator(Box<Operator>),
837    PivotAny(Box<PivotAny>),
838    Aliases(Box<Aliases>),
839    AtIndex(Box<AtIndex>),
840    FromTimeZone(Box<FromTimeZone>),
841    FormatPhrase(Box<FormatPhrase>),
842    ForIn(Box<ForIn>),
843    TimeUnit(Box<TimeUnit>),
844    IntervalOp(Box<IntervalOp>),
845    IntervalSpan(Box<IntervalSpan>),
846    HavingMax(Box<HavingMax>),
847    CosineDistance(Box<CosineDistance>),
848    DotProduct(Box<DotProduct>),
849    EuclideanDistance(Box<EuclideanDistance>),
850    ManhattanDistance(Box<ManhattanDistance>),
851    JarowinklerSimilarity(Box<JarowinklerSimilarity>),
852    Booland(Box<Booland>),
853    Boolor(Box<Boolor>),
854    ParameterizedAgg(Box<ParameterizedAgg>),
855    ArgMax(Box<ArgMax>),
856    ArgMin(Box<ArgMin>),
857    ApproxTopK(Box<ApproxTopK>),
858    ApproxTopKAccumulate(Box<ApproxTopKAccumulate>),
859    ApproxTopKCombine(Box<ApproxTopKCombine>),
860    ApproxTopKEstimate(Box<ApproxTopKEstimate>),
861    ApproxTopSum(Box<ApproxTopSum>),
862    ApproxQuantiles(Box<ApproxQuantiles>),
863    Minhash(Box<Minhash>),
864    FarmFingerprint(Box<FarmFingerprint>),
865    Float64(Box<Float64>),
866    Transform(Box<Transform>),
867    Translate(Box<Translate>),
868    Grouping(Box<Grouping>),
869    GroupingId(Box<GroupingId>),
870    Anonymous(Box<Anonymous>),
871    AnonymousAggFunc(Box<AnonymousAggFunc>),
872    CombinedAggFunc(Box<CombinedAggFunc>),
873    CombinedParameterizedAgg(Box<CombinedParameterizedAgg>),
874    HashAgg(Box<HashAgg>),
875    Hll(Box<Hll>),
876    Apply(Box<Apply>),
877    ToBoolean(Box<ToBoolean>),
878    List(Box<List>),
879    ToMap(Box<ToMap>),
880    Pad(Box<Pad>),
881    ToChar(Box<ToChar>),
882    ToNumber(Box<ToNumber>),
883    ToDouble(Box<ToDouble>),
884    Int64(Box<UnaryFunc>),
885    StringFunc(Box<StringFunc>),
886    ToDecfloat(Box<ToDecfloat>),
887    TryToDecfloat(Box<TryToDecfloat>),
888    ToFile(Box<ToFile>),
889    Columns(Box<Columns>),
890    ConvertToCharset(Box<ConvertToCharset>),
891    ConvertTimezone(Box<ConvertTimezone>),
892    GenerateSeries(Box<GenerateSeries>),
893    AIAgg(Box<AIAgg>),
894    AIClassify(Box<AIClassify>),
895    ArrayAll(Box<ArrayAll>),
896    ArrayAny(Box<ArrayAny>),
897    ArrayConstructCompact(Box<ArrayConstructCompact>),
898    StPoint(Box<StPoint>),
899    StDistance(Box<StDistance>),
900    StringToArray(Box<StringToArray>),
901    ArraySum(Box<ArraySum>),
902    ObjectAgg(Box<ObjectAgg>),
903    CastToStrType(Box<CastToStrType>),
904    CheckJson(Box<CheckJson>),
905    CheckXml(Box<CheckXml>),
906    TranslateCharacters(Box<TranslateCharacters>),
907    CurrentSchemas(Box<CurrentSchemas>),
908    CurrentDatetime(Box<CurrentDatetime>),
909    Localtime(Box<Localtime>),
910    Localtimestamp(Box<Localtimestamp>),
911    Systimestamp(Box<Systimestamp>),
912    CurrentSchema(Box<CurrentSchema>),
913    CurrentUser(Box<CurrentUser>),
914    UtcTime(Box<UtcTime>),
915    UtcTimestamp(Box<UtcTimestamp>),
916    Timestamp(Box<TimestampFunc>),
917    DateBin(Box<DateBin>),
918    Datetime(Box<Datetime>),
919    DatetimeAdd(Box<DatetimeAdd>),
920    DatetimeSub(Box<DatetimeSub>),
921    DatetimeDiff(Box<DatetimeDiff>),
922    DatetimeTrunc(Box<DatetimeTrunc>),
923    Dayname(Box<Dayname>),
924    MakeInterval(Box<MakeInterval>),
925    PreviousDay(Box<PreviousDay>),
926    Elt(Box<Elt>),
927    TimestampAdd(Box<TimestampAdd>),
928    TimestampSub(Box<TimestampSub>),
929    TimestampDiff(Box<TimestampDiff>),
930    TimeSlice(Box<TimeSlice>),
931    TimeAdd(Box<TimeAdd>),
932    TimeSub(Box<TimeSub>),
933    TimeDiff(Box<TimeDiff>),
934    TimeTrunc(Box<TimeTrunc>),
935    DateFromParts(Box<DateFromParts>),
936    TimeFromParts(Box<TimeFromParts>),
937    DecodeCase(Box<DecodeCase>),
938    Decrypt(Box<Decrypt>),
939    DecryptRaw(Box<DecryptRaw>),
940    Encode(Box<Encode>),
941    Encrypt(Box<Encrypt>),
942    EncryptRaw(Box<EncryptRaw>),
943    EqualNull(Box<EqualNull>),
944    ToBinary(Box<ToBinary>),
945    Base64DecodeBinary(Box<Base64DecodeBinary>),
946    Base64DecodeString(Box<Base64DecodeString>),
947    Base64Encode(Box<Base64Encode>),
948    TryBase64DecodeBinary(Box<TryBase64DecodeBinary>),
949    TryBase64DecodeString(Box<TryBase64DecodeString>),
950    GapFill(Box<GapFill>),
951    GenerateDateArray(Box<GenerateDateArray>),
952    GenerateTimestampArray(Box<GenerateTimestampArray>),
953    GetExtract(Box<GetExtract>),
954    Getbit(Box<Getbit>),
955    OverflowTruncateBehavior(Box<OverflowTruncateBehavior>),
956    HexEncode(Box<HexEncode>),
957    Compress(Box<Compress>),
958    DecompressBinary(Box<DecompressBinary>),
959    DecompressString(Box<DecompressString>),
960    Xor(Box<Xor>),
961    Nullif(Box<Nullif>),
962    JSON(Box<JSON>),
963    JSONPath(Box<JSONPath>),
964    JSONPathFilter(Box<JSONPathFilter>),
965    JSONPathKey(Box<JSONPathKey>),
966    JSONPathRecursive(Box<JSONPathRecursive>),
967    JSONPathScript(Box<JSONPathScript>),
968    JSONPathSlice(Box<JSONPathSlice>),
969    JSONPathSelector(Box<JSONPathSelector>),
970    JSONPathSubscript(Box<JSONPathSubscript>),
971    JSONPathUnion(Box<JSONPathUnion>),
972    Format(Box<Format>),
973    JSONKeys(Box<JSONKeys>),
974    JSONKeyValue(Box<JSONKeyValue>),
975    JSONKeysAtDepth(Box<JSONKeysAtDepth>),
976    JSONObject(Box<JSONObject>),
977    JSONObjectAgg(Box<JSONObjectAgg>),
978    JSONBObjectAgg(Box<JSONBObjectAgg>),
979    JSONArray(Box<JSONArray>),
980    JSONArrayAgg(Box<JSONArrayAgg>),
981    JSONExists(Box<JSONExists>),
982    JSONColumnDef(Box<JSONColumnDef>),
983    JSONSchema(Box<JSONSchema>),
984    JSONSet(Box<JSONSet>),
985    JSONStripNulls(Box<JSONStripNulls>),
986    JSONValue(Box<JSONValue>),
987    JSONValueArray(Box<JSONValueArray>),
988    JSONRemove(Box<JSONRemove>),
989    JSONTable(Box<JSONTable>),
990    JSONType(Box<JSONType>),
991    ObjectInsert(Box<ObjectInsert>),
992    OpenJSONColumnDef(Box<OpenJSONColumnDef>),
993    OpenJSON(Box<OpenJSON>),
994    JSONBExists(Box<JSONBExists>),
995    JSONBContains(Box<BinaryFunc>),
996    JSONBExtract(Box<BinaryFunc>),
997    JSONCast(Box<JSONCast>),
998    JSONExtract(Box<JSONExtract>),
999    JSONExtractQuote(Box<JSONExtractQuote>),
1000    JSONExtractArray(Box<JSONExtractArray>),
1001    JSONExtractScalar(Box<JSONExtractScalar>),
1002    JSONBExtractScalar(Box<JSONBExtractScalar>),
1003    JSONFormat(Box<JSONFormat>),
1004    JSONBool(Box<UnaryFunc>),
1005    JSONPathRoot(JSONPathRoot),
1006    JSONArrayAppend(Box<JSONArrayAppend>),
1007    JSONArrayContains(Box<JSONArrayContains>),
1008    JSONArrayInsert(Box<JSONArrayInsert>),
1009    ParseJSON(Box<ParseJSON>),
1010    ParseUrl(Box<ParseUrl>),
1011    ParseIp(Box<ParseIp>),
1012    ParseTime(Box<ParseTime>),
1013    ParseDatetime(Box<ParseDatetime>),
1014    Map(Box<Map>),
1015    MapCat(Box<MapCat>),
1016    MapDelete(Box<MapDelete>),
1017    MapInsert(Box<MapInsert>),
1018    MapPick(Box<MapPick>),
1019    ScopeResolution(Box<ScopeResolution>),
1020    Slice(Box<Slice>),
1021    VarMap(Box<VarMap>),
1022    MatchAgainst(Box<MatchAgainst>),
1023    MD5Digest(Box<MD5Digest>),
1024    MD5NumberLower64(Box<UnaryFunc>),
1025    MD5NumberUpper64(Box<UnaryFunc>),
1026    Monthname(Box<Monthname>),
1027    Ntile(Box<Ntile>),
1028    Normalize(Box<Normalize>),
1029    Normal(Box<Normal>),
1030    Predict(Box<Predict>),
1031    MLTranslate(Box<MLTranslate>),
1032    FeaturesAtTime(Box<FeaturesAtTime>),
1033    GenerateEmbedding(Box<GenerateEmbedding>),
1034    MLForecast(Box<MLForecast>),
1035    ModelAttribute(Box<ModelAttribute>),
1036    VectorSearch(Box<VectorSearch>),
1037    Quantile(Box<Quantile>),
1038    ApproxQuantile(Box<ApproxQuantile>),
1039    ApproxPercentileEstimate(Box<ApproxPercentileEstimate>),
1040    Randn(Box<Randn>),
1041    Randstr(Box<Randstr>),
1042    RangeN(Box<RangeN>),
1043    RangeBucket(Box<RangeBucket>),
1044    ReadCSV(Box<ReadCSV>),
1045    ReadParquet(Box<ReadParquet>),
1046    Reduce(Box<Reduce>),
1047    RegexpExtractAll(Box<RegexpExtractAll>),
1048    RegexpILike(Box<RegexpILike>),
1049    RegexpFullMatch(Box<RegexpFullMatch>),
1050    RegexpInstr(Box<RegexpInstr>),
1051    RegexpSplit(Box<RegexpSplit>),
1052    RegexpCount(Box<RegexpCount>),
1053    RegrValx(Box<RegrValx>),
1054    RegrValy(Box<RegrValy>),
1055    RegrAvgy(Box<RegrAvgy>),
1056    RegrAvgx(Box<RegrAvgx>),
1057    RegrCount(Box<RegrCount>),
1058    RegrIntercept(Box<RegrIntercept>),
1059    RegrR2(Box<RegrR2>),
1060    RegrSxx(Box<RegrSxx>),
1061    RegrSxy(Box<RegrSxy>),
1062    RegrSyy(Box<RegrSyy>),
1063    RegrSlope(Box<RegrSlope>),
1064    SafeAdd(Box<SafeAdd>),
1065    SafeDivide(Box<SafeDivide>),
1066    SafeMultiply(Box<SafeMultiply>),
1067    SafeSubtract(Box<SafeSubtract>),
1068    SHA2(Box<SHA2>),
1069    SHA2Digest(Box<SHA2Digest>),
1070    SortArray(Box<SortArray>),
1071    SplitPart(Box<SplitPart>),
1072    SubstringIndex(Box<SubstringIndex>),
1073    StandardHash(Box<StandardHash>),
1074    StrPosition(Box<StrPosition>),
1075    Search(Box<Search>),
1076    SearchIp(Box<SearchIp>),
1077    StrToDate(Box<StrToDate>),
1078    DateStrToDate(Box<UnaryFunc>),
1079    DateToDateStr(Box<UnaryFunc>),
1080    StrToTime(Box<StrToTime>),
1081    StrToUnix(Box<StrToUnix>),
1082    StrToMap(Box<StrToMap>),
1083    NumberToStr(Box<NumberToStr>),
1084    FromBase(Box<FromBase>),
1085    Stuff(Box<Stuff>),
1086    TimeToStr(Box<TimeToStr>),
1087    TimeStrToTime(Box<TimeStrToTime>),
1088    TsOrDsAdd(Box<TsOrDsAdd>),
1089    TsOrDsDiff(Box<TsOrDsDiff>),
1090    TsOrDsToDate(Box<TsOrDsToDate>),
1091    TsOrDsToTime(Box<TsOrDsToTime>),
1092    Unhex(Box<Unhex>),
1093    Uniform(Box<Uniform>),
1094    UnixToStr(Box<UnixToStr>),
1095    UnixToTime(Box<UnixToTime>),
1096    Uuid(Box<Uuid>),
1097    TimestampFromParts(Box<TimestampFromParts>),
1098    TimestampTzFromParts(Box<TimestampTzFromParts>),
1099    Corr(Box<Corr>),
1100    WidthBucket(Box<WidthBucket>),
1101    CovarSamp(Box<CovarSamp>),
1102    CovarPop(Box<CovarPop>),
1103    Week(Box<Week>),
1104    XMLElement(Box<XMLElement>),
1105    XMLGet(Box<XMLGet>),
1106    XMLTable(Box<XMLTable>),
1107    XMLKeyValueOption(Box<XMLKeyValueOption>),
1108    Zipf(Box<Zipf>),
1109    Merge(Box<Merge>),
1110    When(Box<When>),
1111    Whens(Box<Whens>),
1112    NextValueFor(Box<NextValueFor>),
1113    /// RETURN statement (DuckDB stored procedures)
1114    ReturnStmt(Box<Expression>),
1115}
1116
1117impl Expression {
1118    /// Create a `Column` variant, boxing the value automatically.
1119    #[inline]
1120    pub fn boxed_column(col: Column) -> Self {
1121        Expression::Column(Box::new(col))
1122    }
1123
1124    /// Create a `Table` variant, boxing the value automatically.
1125    #[inline]
1126    pub fn boxed_table(t: TableRef) -> Self {
1127        Expression::Table(Box::new(t))
1128    }
1129
1130    /// Returns `true` if this expression is a valid top-level SQL statement.
1131    ///
1132    /// Bare expressions like identifiers, literals, and function calls are not
1133    /// valid statements. This is used by `validate()` to reject inputs like
1134    /// `SELECT scooby dooby doo` which the parser splits into `SELECT scooby AS dooby`
1135    /// plus the bare identifier `doo`.
1136    pub fn is_statement(&self) -> bool {
1137        match self {
1138            // Queries
1139            Expression::Select(_)
1140            | Expression::Union(_)
1141            | Expression::Intersect(_)
1142            | Expression::Except(_)
1143            | Expression::Subquery(_)
1144            | Expression::Values(_)
1145            | Expression::PipeOperator(_)
1146
1147            // DML
1148            | Expression::Insert(_)
1149            | Expression::Update(_)
1150            | Expression::Delete(_)
1151            | Expression::Copy(_)
1152            | Expression::Put(_)
1153            | Expression::Merge(_)
1154            | Expression::TryCatch(_)
1155
1156            // DDL
1157            | Expression::CreateTable(_)
1158            | Expression::DropTable(_)
1159            | Expression::Undrop(_)
1160            | Expression::AlterTable(_)
1161            | Expression::SplitTable(_)
1162            | Expression::FlashbackTable(_)
1163            | Expression::CreateIndex(_)
1164            | Expression::DropIndex(_)
1165            | Expression::CreateView(_)
1166            | Expression::DropView(_)
1167            | Expression::AlterView(_)
1168            | Expression::AlterIndex(_)
1169            | Expression::Truncate(_)
1170            | Expression::TruncateTable(_)
1171            | Expression::CreateSchema(_)
1172            | Expression::DropSchema(_)
1173            | Expression::DropNamespace(_)
1174            | Expression::CreateDatabase(_)
1175            | Expression::DropDatabase(_)
1176            | Expression::CreateFunction(_)
1177            | Expression::DropFunction(_)
1178            | Expression::CreateProcedure(_)
1179            | Expression::DropProcedure(_)
1180            | Expression::CreateSequence(_)
1181            | Expression::CreateSynonym(_)
1182            | Expression::DropSequence(_)
1183            | Expression::AlterSequence(_)
1184            | Expression::CreateTrigger(_)
1185            | Expression::DropTrigger(_)
1186            | Expression::CreateType(_)
1187            | Expression::DropType(_)
1188            | Expression::Comment(_)
1189
1190            // Session/Transaction/Control
1191            | Expression::Use(_)
1192            | Expression::Set(_)
1193            | Expression::SetStatement(_)
1194            | Expression::Transaction(_)
1195            | Expression::Commit(_)
1196            | Expression::Rollback(_)
1197            | Expression::Grant(_)
1198            | Expression::Revoke(_)
1199            | Expression::Cache(_)
1200            | Expression::Uncache(_)
1201            | Expression::LoadData(_)
1202            | Expression::Pragma(_)
1203            | Expression::Describe(_)
1204            | Expression::Show(_)
1205            | Expression::Kill(_)
1206            | Expression::Prepare(_)
1207            | Expression::Execute(_)
1208            | Expression::Declare(_)
1209            | Expression::Refresh(_)
1210            | Expression::AlterSession(_)
1211            | Expression::LockingStatement(_)
1212
1213            // Analyze
1214            | Expression::Analyze(_)
1215            | Expression::AnalyzeStatistics(_)
1216            | Expression::AnalyzeHistogram(_)
1217            | Expression::AnalyzeSample(_)
1218            | Expression::AnalyzeListChainedRows(_)
1219            | Expression::AnalyzeDelete(_)
1220
1221            // Attach/Detach/Install/Summarize
1222            | Expression::Attach(_)
1223            | Expression::Detach(_)
1224            | Expression::Install(_)
1225            | Expression::Summarize(_)
1226
1227            // Pivot at statement level
1228            | Expression::Pivot(_)
1229            | Expression::Unpivot(_)
1230
1231            // Command (raw/unparsed statements)
1232            | Expression::Command(_)
1233            | Expression::Raw(_)
1234            | Expression::CreateTask(_)
1235
1236            // Return statement
1237            | Expression::ReturnStmt(_) => true,
1238
1239            // Annotated wraps another expression with comments — check inner
1240            Expression::Annotated(a) => a.this.is_statement(),
1241
1242            // Alias at top level can wrap a statement (e.g., parenthesized subquery with alias)
1243            Expression::Alias(a) => a.this.is_statement(),
1244
1245            // Everything else (identifiers, literals, operators, functions, etc.)
1246            _ => false,
1247        }
1248    }
1249
1250    /// Create a literal number expression from an integer.
1251    pub fn number(n: i64) -> Self {
1252        Expression::Literal(Box::new(Literal::Number(n.to_string())))
1253    }
1254
1255    /// Create a single-quoted literal string expression.
1256    pub fn string(s: impl Into<String>) -> Self {
1257        Expression::Literal(Box::new(Literal::String(s.into())))
1258    }
1259
1260    /// Create a literal number expression from a float.
1261    pub fn float(f: f64) -> Self {
1262        Expression::Literal(Box::new(Literal::Number(f.to_string())))
1263    }
1264
1265    /// Get the inferred type annotation, if present.
1266    ///
1267    /// For value-producing expressions with an `inferred_type` field, returns
1268    /// the stored type. For literals and boolean constants, computes the type
1269    /// on the fly from the variant. For DDL/clause expressions, returns `None`.
1270    pub fn inferred_type(&self) -> Option<&DataType> {
1271        match self {
1272            // Structs with inferred_type field
1273            Expression::And(op)
1274            | Expression::Or(op)
1275            | Expression::Add(op)
1276            | Expression::Sub(op)
1277            | Expression::Mul(op)
1278            | Expression::Div(op)
1279            | Expression::Mod(op)
1280            | Expression::Eq(op)
1281            | Expression::Neq(op)
1282            | Expression::Lt(op)
1283            | Expression::Lte(op)
1284            | Expression::Gt(op)
1285            | Expression::Gte(op)
1286            | Expression::Concat(op)
1287            | Expression::BitwiseAnd(op)
1288            | Expression::BitwiseOr(op)
1289            | Expression::BitwiseXor(op)
1290            | Expression::Adjacent(op)
1291            | Expression::TsMatch(op)
1292            | Expression::PropertyEQ(op)
1293            | Expression::ArrayContainsAll(op)
1294            | Expression::ArrayContainedBy(op)
1295            | Expression::ArrayOverlaps(op)
1296            | Expression::JSONBContainsAllTopKeys(op)
1297            | Expression::JSONBContainsAnyTopKeys(op)
1298            | Expression::JSONBDeleteAtPath(op)
1299            | Expression::ExtendsLeft(op)
1300            | Expression::ExtendsRight(op)
1301            | Expression::Is(op)
1302            | Expression::MemberOf(op)
1303            | Expression::Match(op)
1304            | Expression::NullSafeEq(op)
1305            | Expression::NullSafeNeq(op)
1306            | Expression::Glob(op)
1307            | Expression::BitwiseLeftShift(op)
1308            | Expression::BitwiseRightShift(op) => op.inferred_type.as_ref(),
1309
1310            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1311                op.inferred_type.as_ref()
1312            }
1313
1314            Expression::Like(op) | Expression::ILike(op) => op.inferred_type.as_ref(),
1315
1316            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1317                c.inferred_type.as_ref()
1318            }
1319
1320            Expression::Column(c) => c.inferred_type.as_ref(),
1321            Expression::Dot(dot) => dot.inferred_type.as_ref(),
1322            Expression::Function(f) => f.inferred_type.as_ref(),
1323            Expression::AggregateFunction(f) => f.inferred_type.as_ref(),
1324            Expression::WindowFunction(f) => f.inferred_type.as_ref(),
1325            Expression::Case(c) => c.inferred_type.as_ref(),
1326            Expression::Array(a) => a.inferred_type.as_ref(),
1327            Expression::ArrayFunc(a) => a.inferred_type.as_ref(),
1328            Expression::Paren(p) => p.this.inferred_type(),
1329            Expression::Annotated(a) => a.this.inferred_type(),
1330            Expression::Subquery(s) => s.inferred_type.as_ref(),
1331            Expression::Alias(a) => a.inferred_type.as_ref(),
1332            Expression::Unnest(u) => u.inferred_type.as_ref(),
1333            Expression::IfFunc(f) => f.inferred_type.as_ref(),
1334            Expression::Nvl2(f) => f.inferred_type.as_ref(),
1335            Expression::Count(f) => f.inferred_type.as_ref(),
1336            Expression::GroupConcat(f) => f.inferred_type.as_ref(),
1337            Expression::StringAgg(f) => f.inferred_type.as_ref(),
1338            Expression::ListAgg(f) => f.inferred_type.as_ref(),
1339            Expression::SumIf(f) => f.inferred_type.as_ref(),
1340            Expression::Trim(f) => f.inferred_type.as_ref(),
1341
1342            // UnaryFunc variants
1343            Expression::Upper(f)
1344            | Expression::Lower(f)
1345            | Expression::Length(f)
1346            | Expression::LTrim(f)
1347            | Expression::RTrim(f)
1348            | Expression::Reverse(f)
1349            | Expression::Abs(f)
1350            | Expression::Sqrt(f)
1351            | Expression::Cbrt(f)
1352            | Expression::Ln(f)
1353            | Expression::Exp(f)
1354            | Expression::Sign(f)
1355            | Expression::Date(f)
1356            | Expression::Time(f)
1357            | Expression::Initcap(f)
1358            | Expression::Ascii(f)
1359            | Expression::Chr(f)
1360            | Expression::Soundex(f)
1361            | Expression::ByteLength(f)
1362            | Expression::Hex(f)
1363            | Expression::LowerHex(f)
1364            | Expression::Unicode(f)
1365            | Expression::Typeof(f)
1366            | Expression::Explode(f)
1367            | Expression::ExplodeOuter(f)
1368            | Expression::MapFromEntries(f)
1369            | Expression::MapKeys(f)
1370            | Expression::MapValues(f)
1371            | Expression::ArrayLength(f)
1372            | Expression::ArraySize(f)
1373            | Expression::Cardinality(f)
1374            | Expression::ArrayReverse(f)
1375            | Expression::ArrayDistinct(f)
1376            | Expression::ArrayFlatten(f)
1377            | Expression::ArrayCompact(f)
1378            | Expression::ToArray(f)
1379            | Expression::JsonArrayLength(f)
1380            | Expression::JsonKeys(f)
1381            | Expression::JsonType(f)
1382            | Expression::ParseJson(f)
1383            | Expression::ToJson(f)
1384            | Expression::Radians(f)
1385            | Expression::Degrees(f)
1386            | Expression::Sin(f)
1387            | Expression::Cos(f)
1388            | Expression::Tan(f)
1389            | Expression::Asin(f)
1390            | Expression::Acos(f)
1391            | Expression::Atan(f)
1392            | Expression::IsNan(f)
1393            | Expression::IsInf(f)
1394            | Expression::Year(f)
1395            | Expression::Month(f)
1396            | Expression::Day(f)
1397            | Expression::Hour(f)
1398            | Expression::Minute(f)
1399            | Expression::Second(f)
1400            | Expression::DayOfWeek(f)
1401            | Expression::DayOfWeekIso(f)
1402            | Expression::DayOfMonth(f)
1403            | Expression::DayOfYear(f)
1404            | Expression::WeekOfYear(f)
1405            | Expression::Quarter(f)
1406            | Expression::Epoch(f)
1407            | Expression::EpochMs(f)
1408            | Expression::BitwiseCount(f)
1409            | Expression::DateFromUnixDate(f)
1410            | Expression::UnixDate(f)
1411            | Expression::UnixSeconds(f)
1412            | Expression::UnixMillis(f)
1413            | Expression::UnixMicros(f)
1414            | Expression::TimeStrToDate(f)
1415            | Expression::DateToDi(f)
1416            | Expression::DiToDate(f)
1417            | Expression::TsOrDiToDi(f)
1418            | Expression::TsOrDsToDatetime(f)
1419            | Expression::TsOrDsToTimestamp(f)
1420            | Expression::YearOfWeek(f)
1421            | Expression::YearOfWeekIso(f)
1422            | Expression::SHA(f)
1423            | Expression::SHA1Digest(f)
1424            | Expression::TimeToUnix(f)
1425            | Expression::TimeStrToUnix(f) => f.inferred_type.as_ref(),
1426
1427            // BinaryFunc variants
1428            Expression::Power(f)
1429            | Expression::NullIf(f)
1430            | Expression::IfNull(f)
1431            | Expression::Nvl(f)
1432            | Expression::Contains(f)
1433            | Expression::StartsWith(f)
1434            | Expression::EndsWith(f)
1435            | Expression::Levenshtein(f)
1436            | Expression::ModFunc(f)
1437            | Expression::IntDiv(f)
1438            | Expression::Atan2(f)
1439            | Expression::AddMonths(f)
1440            | Expression::MonthsBetween(f)
1441            | Expression::NextDay(f)
1442            | Expression::UnixToTimeStr(f)
1443            | Expression::ArrayContains(f)
1444            | Expression::ArrayPosition(f)
1445            | Expression::ArrayAppend(f)
1446            | Expression::ArrayPrepend(f)
1447            | Expression::ArrayUnion(f)
1448            | Expression::ArrayExcept(f)
1449            | Expression::ArrayRemove(f)
1450            | Expression::StarMap(f)
1451            | Expression::MapFromArrays(f)
1452            | Expression::MapContainsKey(f)
1453            | Expression::ElementAt(f)
1454            | Expression::JsonMergePatch(f) => f.inferred_type.as_ref(),
1455
1456            // VarArgFunc variants
1457            Expression::Coalesce(f)
1458            | Expression::Greatest(f)
1459            | Expression::Least(f)
1460            | Expression::ArrayConcat(f)
1461            | Expression::ArrayIntersect(f)
1462            | Expression::ArrayZip(f)
1463            | Expression::MapConcat(f)
1464            | Expression::JsonArray(f) => f.inferred_type.as_ref(),
1465
1466            // AggFunc variants
1467            Expression::Sum(f)
1468            | Expression::Avg(f)
1469            | Expression::Min(f)
1470            | Expression::Max(f)
1471            | Expression::ArrayAgg(f)
1472            | Expression::CountIf(f)
1473            | Expression::Stddev(f)
1474            | Expression::StddevPop(f)
1475            | Expression::StddevSamp(f)
1476            | Expression::Variance(f)
1477            | Expression::VarPop(f)
1478            | Expression::VarSamp(f)
1479            | Expression::Median(f)
1480            | Expression::Mode(f)
1481            | Expression::First(f)
1482            | Expression::Last(f)
1483            | Expression::AnyValue(f)
1484            | Expression::ApproxDistinct(f)
1485            | Expression::ApproxCountDistinct(f)
1486            | Expression::LogicalAnd(f)
1487            | Expression::LogicalOr(f)
1488            | Expression::Skewness(f)
1489            | Expression::ArrayConcatAgg(f)
1490            | Expression::ArrayUniqueAgg(f)
1491            | Expression::BoolXorAgg(f)
1492            | Expression::BitwiseAndAgg(f)
1493            | Expression::BitwiseOrAgg(f)
1494            | Expression::BitwiseXorAgg(f) => f.inferred_type.as_ref(),
1495
1496            // Everything else: no inferred_type field
1497            _ => None,
1498        }
1499    }
1500
1501    /// Set the inferred type annotation on this expression.
1502    ///
1503    /// Only has an effect on value-producing expressions with an `inferred_type`
1504    /// field. For other expression types, this is a no-op.
1505    pub fn set_inferred_type(&mut self, dt: DataType) {
1506        match self {
1507            Expression::And(op)
1508            | Expression::Or(op)
1509            | Expression::Add(op)
1510            | Expression::Sub(op)
1511            | Expression::Mul(op)
1512            | Expression::Div(op)
1513            | Expression::Mod(op)
1514            | Expression::Eq(op)
1515            | Expression::Neq(op)
1516            | Expression::Lt(op)
1517            | Expression::Lte(op)
1518            | Expression::Gt(op)
1519            | Expression::Gte(op)
1520            | Expression::Concat(op)
1521            | Expression::BitwiseAnd(op)
1522            | Expression::BitwiseOr(op)
1523            | Expression::BitwiseXor(op)
1524            | Expression::Adjacent(op)
1525            | Expression::TsMatch(op)
1526            | Expression::PropertyEQ(op)
1527            | Expression::ArrayContainsAll(op)
1528            | Expression::ArrayContainedBy(op)
1529            | Expression::ArrayOverlaps(op)
1530            | Expression::JSONBContainsAllTopKeys(op)
1531            | Expression::JSONBContainsAnyTopKeys(op)
1532            | Expression::JSONBDeleteAtPath(op)
1533            | Expression::ExtendsLeft(op)
1534            | Expression::ExtendsRight(op)
1535            | Expression::Is(op)
1536            | Expression::MemberOf(op)
1537            | Expression::Match(op)
1538            | Expression::NullSafeEq(op)
1539            | Expression::NullSafeNeq(op)
1540            | Expression::Glob(op)
1541            | Expression::BitwiseLeftShift(op)
1542            | Expression::BitwiseRightShift(op) => op.inferred_type = Some(dt),
1543
1544            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1545                op.inferred_type = Some(dt)
1546            }
1547
1548            Expression::Like(op) | Expression::ILike(op) => op.inferred_type = Some(dt),
1549
1550            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1551                c.inferred_type = Some(dt)
1552            }
1553
1554            Expression::Column(c) => c.inferred_type = Some(dt),
1555            Expression::Dot(dot) => dot.inferred_type = Some(dt),
1556            Expression::Function(f) => f.inferred_type = Some(dt),
1557            Expression::AggregateFunction(f) => f.inferred_type = Some(dt),
1558            Expression::WindowFunction(f) => f.inferred_type = Some(dt),
1559            Expression::Case(c) => c.inferred_type = Some(dt),
1560            Expression::Array(a) => a.inferred_type = Some(dt),
1561            Expression::ArrayFunc(a) => a.inferred_type = Some(dt),
1562            Expression::Paren(p) => p.this.set_inferred_type(dt),
1563            Expression::Annotated(a) => a.this.set_inferred_type(dt),
1564            Expression::Subquery(s) => s.inferred_type = Some(dt),
1565            Expression::Alias(a) => a.inferred_type = Some(dt),
1566            Expression::Unnest(u) => u.inferred_type = Some(dt),
1567            Expression::IfFunc(f) => f.inferred_type = Some(dt),
1568            Expression::Nvl2(f) => f.inferred_type = Some(dt),
1569            Expression::Count(f) => f.inferred_type = Some(dt),
1570            Expression::GroupConcat(f) => f.inferred_type = Some(dt),
1571            Expression::StringAgg(f) => f.inferred_type = Some(dt),
1572            Expression::ListAgg(f) => f.inferred_type = Some(dt),
1573            Expression::SumIf(f) => f.inferred_type = Some(dt),
1574            Expression::Trim(f) => f.inferred_type = Some(dt),
1575
1576            // UnaryFunc variants
1577            Expression::Upper(f)
1578            | Expression::Lower(f)
1579            | Expression::Length(f)
1580            | Expression::LTrim(f)
1581            | Expression::RTrim(f)
1582            | Expression::Reverse(f)
1583            | Expression::Abs(f)
1584            | Expression::Sqrt(f)
1585            | Expression::Cbrt(f)
1586            | Expression::Ln(f)
1587            | Expression::Exp(f)
1588            | Expression::Sign(f)
1589            | Expression::Date(f)
1590            | Expression::Time(f)
1591            | Expression::Initcap(f)
1592            | Expression::Ascii(f)
1593            | Expression::Chr(f)
1594            | Expression::Soundex(f)
1595            | Expression::ByteLength(f)
1596            | Expression::Hex(f)
1597            | Expression::LowerHex(f)
1598            | Expression::Unicode(f)
1599            | Expression::Typeof(f)
1600            | Expression::Explode(f)
1601            | Expression::ExplodeOuter(f)
1602            | Expression::MapFromEntries(f)
1603            | Expression::MapKeys(f)
1604            | Expression::MapValues(f)
1605            | Expression::ArrayLength(f)
1606            | Expression::ArraySize(f)
1607            | Expression::Cardinality(f)
1608            | Expression::ArrayReverse(f)
1609            | Expression::ArrayDistinct(f)
1610            | Expression::ArrayFlatten(f)
1611            | Expression::ArrayCompact(f)
1612            | Expression::ToArray(f)
1613            | Expression::JsonArrayLength(f)
1614            | Expression::JsonKeys(f)
1615            | Expression::JsonType(f)
1616            | Expression::ParseJson(f)
1617            | Expression::ToJson(f)
1618            | Expression::Radians(f)
1619            | Expression::Degrees(f)
1620            | Expression::Sin(f)
1621            | Expression::Cos(f)
1622            | Expression::Tan(f)
1623            | Expression::Asin(f)
1624            | Expression::Acos(f)
1625            | Expression::Atan(f)
1626            | Expression::IsNan(f)
1627            | Expression::IsInf(f)
1628            | Expression::Year(f)
1629            | Expression::Month(f)
1630            | Expression::Day(f)
1631            | Expression::Hour(f)
1632            | Expression::Minute(f)
1633            | Expression::Second(f)
1634            | Expression::DayOfWeek(f)
1635            | Expression::DayOfWeekIso(f)
1636            | Expression::DayOfMonth(f)
1637            | Expression::DayOfYear(f)
1638            | Expression::WeekOfYear(f)
1639            | Expression::Quarter(f)
1640            | Expression::Epoch(f)
1641            | Expression::EpochMs(f)
1642            | Expression::BitwiseCount(f)
1643            | Expression::DateFromUnixDate(f)
1644            | Expression::UnixDate(f)
1645            | Expression::UnixSeconds(f)
1646            | Expression::UnixMillis(f)
1647            | Expression::UnixMicros(f)
1648            | Expression::TimeStrToDate(f)
1649            | Expression::DateToDi(f)
1650            | Expression::DiToDate(f)
1651            | Expression::TsOrDiToDi(f)
1652            | Expression::TsOrDsToDatetime(f)
1653            | Expression::TsOrDsToTimestamp(f)
1654            | Expression::YearOfWeek(f)
1655            | Expression::YearOfWeekIso(f)
1656            | Expression::SHA(f)
1657            | Expression::SHA1Digest(f)
1658            | Expression::TimeToUnix(f)
1659            | Expression::TimeStrToUnix(f) => f.inferred_type = Some(dt),
1660
1661            // BinaryFunc variants
1662            Expression::Power(f)
1663            | Expression::NullIf(f)
1664            | Expression::IfNull(f)
1665            | Expression::Nvl(f)
1666            | Expression::Contains(f)
1667            | Expression::StartsWith(f)
1668            | Expression::EndsWith(f)
1669            | Expression::Levenshtein(f)
1670            | Expression::ModFunc(f)
1671            | Expression::IntDiv(f)
1672            | Expression::Atan2(f)
1673            | Expression::AddMonths(f)
1674            | Expression::MonthsBetween(f)
1675            | Expression::NextDay(f)
1676            | Expression::UnixToTimeStr(f)
1677            | Expression::ArrayContains(f)
1678            | Expression::ArrayPosition(f)
1679            | Expression::ArrayAppend(f)
1680            | Expression::ArrayPrepend(f)
1681            | Expression::ArrayUnion(f)
1682            | Expression::ArrayExcept(f)
1683            | Expression::ArrayRemove(f)
1684            | Expression::StarMap(f)
1685            | Expression::MapFromArrays(f)
1686            | Expression::MapContainsKey(f)
1687            | Expression::ElementAt(f)
1688            | Expression::JsonMergePatch(f) => f.inferred_type = Some(dt),
1689
1690            // VarArgFunc variants
1691            Expression::Coalesce(f)
1692            | Expression::Greatest(f)
1693            | Expression::Least(f)
1694            | Expression::ArrayConcat(f)
1695            | Expression::ArrayIntersect(f)
1696            | Expression::ArrayZip(f)
1697            | Expression::MapConcat(f)
1698            | Expression::JsonArray(f) => f.inferred_type = Some(dt),
1699
1700            // AggFunc variants
1701            Expression::Sum(f)
1702            | Expression::Avg(f)
1703            | Expression::Min(f)
1704            | Expression::Max(f)
1705            | Expression::ArrayAgg(f)
1706            | Expression::CountIf(f)
1707            | Expression::Stddev(f)
1708            | Expression::StddevPop(f)
1709            | Expression::StddevSamp(f)
1710            | Expression::Variance(f)
1711            | Expression::VarPop(f)
1712            | Expression::VarSamp(f)
1713            | Expression::Median(f)
1714            | Expression::Mode(f)
1715            | Expression::First(f)
1716            | Expression::Last(f)
1717            | Expression::AnyValue(f)
1718            | Expression::ApproxDistinct(f)
1719            | Expression::ApproxCountDistinct(f)
1720            | Expression::LogicalAnd(f)
1721            | Expression::LogicalOr(f)
1722            | Expression::Skewness(f)
1723            | Expression::ArrayConcatAgg(f)
1724            | Expression::ArrayUniqueAgg(f)
1725            | Expression::BoolXorAgg(f)
1726            | Expression::BitwiseAndAgg(f)
1727            | Expression::BitwiseOrAgg(f)
1728            | Expression::BitwiseXorAgg(f) => f.inferred_type = Some(dt),
1729
1730            // Expressions without inferred_type field - no-op
1731            _ => {}
1732        }
1733    }
1734
1735    /// Create an unqualified column reference (e.g. `name`).
1736    pub fn column(name: impl Into<String>) -> Self {
1737        Expression::Column(Box::new(Column {
1738            name: Identifier::new(name),
1739            table: None,
1740            join_mark: false,
1741            trailing_comments: Vec::new(),
1742            span: None,
1743            inferred_type: None,
1744        }))
1745    }
1746
1747    /// Create a qualified column reference (`table.column`).
1748    pub fn qualified_column(table: impl Into<String>, column: impl Into<String>) -> Self {
1749        Expression::Column(Box::new(Column {
1750            name: Identifier::new(column),
1751            table: Some(Identifier::new(table)),
1752            join_mark: false,
1753            trailing_comments: Vec::new(),
1754            span: None,
1755            inferred_type: None,
1756        }))
1757    }
1758
1759    /// Create a bare identifier expression (not a column reference).
1760    pub fn identifier(name: impl Into<String>) -> Self {
1761        Expression::Identifier(Identifier::new(name))
1762    }
1763
1764    /// Create a NULL expression
1765    pub fn null() -> Self {
1766        Expression::Null(Null)
1767    }
1768
1769    /// Create a TRUE expression
1770    pub fn true_() -> Self {
1771        Expression::Boolean(BooleanLiteral { value: true })
1772    }
1773
1774    /// Create a FALSE expression
1775    pub fn false_() -> Self {
1776        Expression::Boolean(BooleanLiteral { value: false })
1777    }
1778
1779    /// Create a wildcard star (`*`) expression with no EXCEPT/REPLACE/RENAME modifiers.
1780    pub fn star() -> Self {
1781        Expression::Star(Star {
1782            table: None,
1783            except: None,
1784            replace: None,
1785            rename: None,
1786            trailing_comments: Vec::new(),
1787            span: None,
1788        })
1789    }
1790
1791    /// Wrap this expression in an `AS` alias (e.g. `expr AS name`).
1792    pub fn alias(self, name: impl Into<String>) -> Self {
1793        Expression::Alias(Box::new(Alias::new(self, Identifier::new(name))))
1794    }
1795
1796    /// Check if this is a SELECT expression
1797    pub fn is_select(&self) -> bool {
1798        matches!(self, Expression::Select(_))
1799    }
1800
1801    /// Try to get as a Select
1802    pub fn as_select(&self) -> Option<&Select> {
1803        match self {
1804            Expression::Select(s) => Some(s),
1805            _ => None,
1806        }
1807    }
1808
1809    /// Try to get as a mutable Select
1810    pub fn as_select_mut(&mut self) -> Option<&mut Select> {
1811        match self {
1812            Expression::Select(s) => Some(s),
1813            _ => None,
1814        }
1815    }
1816
1817    /// Generate a SQL string for this expression using the generic (dialect-agnostic) generator.
1818    ///
1819    /// Returns an empty string if generation fails. For dialect-specific output,
1820    /// use [`sql_for()`](Self::sql_for) instead.
1821    #[cfg(feature = "generate")]
1822    pub fn sql(&self) -> String {
1823        crate::generator::Generator::sql(self).unwrap_or_default()
1824    }
1825
1826    /// Generate a SQL string for this expression targeting a specific dialect.
1827    ///
1828    /// Dialect-specific rules (identifier quoting, function names, type mappings,
1829    /// syntax variations) are applied automatically.  Returns an empty string if
1830    /// generation fails.
1831    #[cfg(feature = "generate")]
1832    pub fn sql_for(&self, dialect: crate::dialects::DialectType) -> String {
1833        crate::generate(self, dialect).unwrap_or_default()
1834    }
1835}
1836
1837// === Python API accessor methods ===
1838
1839impl Expression {
1840    /// Returns the serde-compatible snake_case variant name without serialization.
1841    /// This is much faster than serializing to JSON and extracting the key.
1842    pub fn variant_name(&self) -> &'static str {
1843        match self {
1844            Expression::Literal(_) => "literal",
1845            Expression::Boolean(_) => "boolean",
1846            Expression::Null(_) => "null",
1847            Expression::Identifier(_) => "identifier",
1848            Expression::Column(_) => "column",
1849            Expression::Table(_) => "table",
1850            Expression::Star(_) => "star",
1851            Expression::BracedWildcard(_) => "braced_wildcard",
1852            Expression::Select(_) => "select",
1853            Expression::Union(_) => "union",
1854            Expression::Intersect(_) => "intersect",
1855            Expression::Except(_) => "except",
1856            Expression::Subquery(_) => "subquery",
1857            Expression::PipeOperator(_) => "pipe_operator",
1858            Expression::Pivot(_) => "pivot",
1859            Expression::PivotAlias(_) => "pivot_alias",
1860            Expression::Unpivot(_) => "unpivot",
1861            Expression::Values(_) => "values",
1862            Expression::PreWhere(_) => "pre_where",
1863            Expression::Stream(_) => "stream",
1864            Expression::UsingData(_) => "using_data",
1865            Expression::XmlNamespace(_) => "xml_namespace",
1866            Expression::Insert(_) => "insert",
1867            Expression::Update(_) => "update",
1868            Expression::Delete(_) => "delete",
1869            Expression::Copy(_) => "copy",
1870            Expression::Put(_) => "put",
1871            Expression::StageReference(_) => "stage_reference",
1872            Expression::Alias(_) => "alias",
1873            Expression::Cast(_) => "cast",
1874            Expression::Collation(_) => "collation",
1875            Expression::Case(_) => "case",
1876            Expression::And(_) => "and",
1877            Expression::Or(_) => "or",
1878            Expression::Add(_) => "add",
1879            Expression::Sub(_) => "sub",
1880            Expression::Mul(_) => "mul",
1881            Expression::Div(_) => "div",
1882            Expression::Mod(_) => "mod",
1883            Expression::Eq(_) => "eq",
1884            Expression::Neq(_) => "neq",
1885            Expression::Lt(_) => "lt",
1886            Expression::Lte(_) => "lte",
1887            Expression::Gt(_) => "gt",
1888            Expression::Gte(_) => "gte",
1889            Expression::Like(_) => "like",
1890            Expression::ILike(_) => "i_like",
1891            Expression::Match(_) => "match",
1892            Expression::BitwiseAnd(_) => "bitwise_and",
1893            Expression::BitwiseOr(_) => "bitwise_or",
1894            Expression::BitwiseXor(_) => "bitwise_xor",
1895            Expression::Concat(_) => "concat",
1896            Expression::Adjacent(_) => "adjacent",
1897            Expression::TsMatch(_) => "ts_match",
1898            Expression::PropertyEQ(_) => "property_e_q",
1899            Expression::ArrayContainsAll(_) => "array_contains_all",
1900            Expression::ArrayContainedBy(_) => "array_contained_by",
1901            Expression::ArrayOverlaps(_) => "array_overlaps",
1902            Expression::JSONBContainsAllTopKeys(_) => "j_s_o_n_b_contains_all_top_keys",
1903            Expression::JSONBContainsAnyTopKeys(_) => "j_s_o_n_b_contains_any_top_keys",
1904            Expression::JSONBDeleteAtPath(_) => "j_s_o_n_b_delete_at_path",
1905            Expression::ExtendsLeft(_) => "extends_left",
1906            Expression::ExtendsRight(_) => "extends_right",
1907            Expression::Not(_) => "not",
1908            Expression::Neg(_) => "neg",
1909            Expression::BitwiseNot(_) => "bitwise_not",
1910            Expression::In(_) => "in",
1911            Expression::Between(_) => "between",
1912            Expression::IsNull(_) => "is_null",
1913            Expression::IsTrue(_) => "is_true",
1914            Expression::IsFalse(_) => "is_false",
1915            Expression::IsJson(_) => "is_json",
1916            Expression::Is(_) => "is",
1917            Expression::Exists(_) => "exists",
1918            Expression::MemberOf(_) => "member_of",
1919            Expression::Function(_) => "function",
1920            Expression::AggregateFunction(_) => "aggregate_function",
1921            Expression::WindowFunction(_) => "window_function",
1922            Expression::From(_) => "from",
1923            Expression::Join(_) => "join",
1924            Expression::JoinedTable(_) => "joined_table",
1925            Expression::Where(_) => "where",
1926            Expression::GroupBy(_) => "group_by",
1927            Expression::Having(_) => "having",
1928            Expression::OrderBy(_) => "order_by",
1929            Expression::Limit(_) => "limit",
1930            Expression::Offset(_) => "offset",
1931            Expression::Qualify(_) => "qualify",
1932            Expression::With(_) => "with",
1933            Expression::Cte(_) => "cte",
1934            Expression::DistributeBy(_) => "distribute_by",
1935            Expression::ClusterBy(_) => "cluster_by",
1936            Expression::SortBy(_) => "sort_by",
1937            Expression::LateralView(_) => "lateral_view",
1938            Expression::Hint(_) => "hint",
1939            Expression::Pseudocolumn(_) => "pseudocolumn",
1940            Expression::Connect(_) => "connect",
1941            Expression::Prior(_) => "prior",
1942            Expression::ConnectByRoot(_) => "connect_by_root",
1943            Expression::MatchRecognize(_) => "match_recognize",
1944            Expression::Ordered(_) => "ordered",
1945            Expression::Window(_) => "window",
1946            Expression::Over(_) => "over",
1947            Expression::WithinGroup(_) => "within_group",
1948            Expression::DataType(_) => "data_type",
1949            Expression::Array(_) => "array",
1950            Expression::Struct(_) => "struct",
1951            Expression::Tuple(_) => "tuple",
1952            Expression::Interval(_) => "interval",
1953            Expression::ConcatWs(_) => "concat_ws",
1954            Expression::Substring(_) => "substring",
1955            Expression::Upper(_) => "upper",
1956            Expression::Lower(_) => "lower",
1957            Expression::Length(_) => "length",
1958            Expression::Trim(_) => "trim",
1959            Expression::LTrim(_) => "l_trim",
1960            Expression::RTrim(_) => "r_trim",
1961            Expression::Replace(_) => "replace",
1962            Expression::Reverse(_) => "reverse",
1963            Expression::Left(_) => "left",
1964            Expression::Right(_) => "right",
1965            Expression::Repeat(_) => "repeat",
1966            Expression::Lpad(_) => "lpad",
1967            Expression::Rpad(_) => "rpad",
1968            Expression::Split(_) => "split",
1969            Expression::RegexpLike(_) => "regexp_like",
1970            Expression::RegexpReplace(_) => "regexp_replace",
1971            Expression::RegexpExtract(_) => "regexp_extract",
1972            Expression::Overlay(_) => "overlay",
1973            Expression::Abs(_) => "abs",
1974            Expression::Round(_) => "round",
1975            Expression::Floor(_) => "floor",
1976            Expression::Ceil(_) => "ceil",
1977            Expression::Power(_) => "power",
1978            Expression::Sqrt(_) => "sqrt",
1979            Expression::Cbrt(_) => "cbrt",
1980            Expression::Ln(_) => "ln",
1981            Expression::Log(_) => "log",
1982            Expression::Exp(_) => "exp",
1983            Expression::Sign(_) => "sign",
1984            Expression::Greatest(_) => "greatest",
1985            Expression::Least(_) => "least",
1986            Expression::CurrentDate(_) => "current_date",
1987            Expression::CurrentTime(_) => "current_time",
1988            Expression::CurrentTimestamp(_) => "current_timestamp",
1989            Expression::CurrentTimestampLTZ(_) => "current_timestamp_l_t_z",
1990            Expression::AtTimeZone(_) => "at_time_zone",
1991            Expression::DateAdd(_) => "date_add",
1992            Expression::DateSub(_) => "date_sub",
1993            Expression::DateDiff(_) => "date_diff",
1994            Expression::DateTrunc(_) => "date_trunc",
1995            Expression::Extract(_) => "extract",
1996            Expression::ToDate(_) => "to_date",
1997            Expression::ToTimestamp(_) => "to_timestamp",
1998            Expression::Date(_) => "date",
1999            Expression::Time(_) => "time",
2000            Expression::DateFromUnixDate(_) => "date_from_unix_date",
2001            Expression::UnixDate(_) => "unix_date",
2002            Expression::UnixSeconds(_) => "unix_seconds",
2003            Expression::UnixMillis(_) => "unix_millis",
2004            Expression::UnixMicros(_) => "unix_micros",
2005            Expression::UnixToTimeStr(_) => "unix_to_time_str",
2006            Expression::TimeStrToDate(_) => "time_str_to_date",
2007            Expression::DateToDi(_) => "date_to_di",
2008            Expression::DiToDate(_) => "di_to_date",
2009            Expression::TsOrDiToDi(_) => "ts_or_di_to_di",
2010            Expression::TsOrDsToDatetime(_) => "ts_or_ds_to_datetime",
2011            Expression::TsOrDsToTimestamp(_) => "ts_or_ds_to_timestamp",
2012            Expression::YearOfWeek(_) => "year_of_week",
2013            Expression::YearOfWeekIso(_) => "year_of_week_iso",
2014            Expression::Coalesce(_) => "coalesce",
2015            Expression::NullIf(_) => "null_if",
2016            Expression::IfFunc(_) => "if_func",
2017            Expression::IfNull(_) => "if_null",
2018            Expression::Nvl(_) => "nvl",
2019            Expression::Nvl2(_) => "nvl2",
2020            Expression::TryCast(_) => "try_cast",
2021            Expression::SafeCast(_) => "safe_cast",
2022            Expression::Count(_) => "count",
2023            Expression::Sum(_) => "sum",
2024            Expression::Avg(_) => "avg",
2025            Expression::Min(_) => "min",
2026            Expression::Max(_) => "max",
2027            Expression::GroupConcat(_) => "group_concat",
2028            Expression::StringAgg(_) => "string_agg",
2029            Expression::ListAgg(_) => "list_agg",
2030            Expression::ArrayAgg(_) => "array_agg",
2031            Expression::CountIf(_) => "count_if",
2032            Expression::SumIf(_) => "sum_if",
2033            Expression::Stddev(_) => "stddev",
2034            Expression::StddevPop(_) => "stddev_pop",
2035            Expression::StddevSamp(_) => "stddev_samp",
2036            Expression::Variance(_) => "variance",
2037            Expression::VarPop(_) => "var_pop",
2038            Expression::VarSamp(_) => "var_samp",
2039            Expression::Median(_) => "median",
2040            Expression::Mode(_) => "mode",
2041            Expression::First(_) => "first",
2042            Expression::Last(_) => "last",
2043            Expression::AnyValue(_) => "any_value",
2044            Expression::ApproxDistinct(_) => "approx_distinct",
2045            Expression::ApproxCountDistinct(_) => "approx_count_distinct",
2046            Expression::ApproxPercentile(_) => "approx_percentile",
2047            Expression::Percentile(_) => "percentile",
2048            Expression::LogicalAnd(_) => "logical_and",
2049            Expression::LogicalOr(_) => "logical_or",
2050            Expression::Skewness(_) => "skewness",
2051            Expression::BitwiseCount(_) => "bitwise_count",
2052            Expression::ArrayConcatAgg(_) => "array_concat_agg",
2053            Expression::ArrayUniqueAgg(_) => "array_unique_agg",
2054            Expression::BoolXorAgg(_) => "bool_xor_agg",
2055            Expression::RowNumber(_) => "row_number",
2056            Expression::Rank(_) => "rank",
2057            Expression::DenseRank(_) => "dense_rank",
2058            Expression::NTile(_) => "n_tile",
2059            Expression::Lead(_) => "lead",
2060            Expression::Lag(_) => "lag",
2061            Expression::FirstValue(_) => "first_value",
2062            Expression::LastValue(_) => "last_value",
2063            Expression::NthValue(_) => "nth_value",
2064            Expression::PercentRank(_) => "percent_rank",
2065            Expression::CumeDist(_) => "cume_dist",
2066            Expression::PercentileCont(_) => "percentile_cont",
2067            Expression::PercentileDisc(_) => "percentile_disc",
2068            Expression::Contains(_) => "contains",
2069            Expression::StartsWith(_) => "starts_with",
2070            Expression::EndsWith(_) => "ends_with",
2071            Expression::Position(_) => "position",
2072            Expression::Initcap(_) => "initcap",
2073            Expression::Ascii(_) => "ascii",
2074            Expression::Chr(_) => "chr",
2075            Expression::CharFunc(_) => "char_func",
2076            Expression::Soundex(_) => "soundex",
2077            Expression::Levenshtein(_) => "levenshtein",
2078            Expression::ByteLength(_) => "byte_length",
2079            Expression::Hex(_) => "hex",
2080            Expression::LowerHex(_) => "lower_hex",
2081            Expression::Unicode(_) => "unicode",
2082            Expression::ModFunc(_) => "mod_func",
2083            Expression::Random(_) => "random",
2084            Expression::Rand(_) => "rand",
2085            Expression::TruncFunc(_) => "trunc_func",
2086            Expression::Pi(_) => "pi",
2087            Expression::Radians(_) => "radians",
2088            Expression::Degrees(_) => "degrees",
2089            Expression::Sin(_) => "sin",
2090            Expression::Cos(_) => "cos",
2091            Expression::Tan(_) => "tan",
2092            Expression::Asin(_) => "asin",
2093            Expression::Acos(_) => "acos",
2094            Expression::Atan(_) => "atan",
2095            Expression::Atan2(_) => "atan2",
2096            Expression::IsNan(_) => "is_nan",
2097            Expression::IsInf(_) => "is_inf",
2098            Expression::IntDiv(_) => "int_div",
2099            Expression::Decode(_) => "decode",
2100            Expression::DateFormat(_) => "date_format",
2101            Expression::FormatDate(_) => "format_date",
2102            Expression::Year(_) => "year",
2103            Expression::Month(_) => "month",
2104            Expression::Day(_) => "day",
2105            Expression::Hour(_) => "hour",
2106            Expression::Minute(_) => "minute",
2107            Expression::Second(_) => "second",
2108            Expression::DayOfWeek(_) => "day_of_week",
2109            Expression::DayOfWeekIso(_) => "day_of_week_iso",
2110            Expression::DayOfMonth(_) => "day_of_month",
2111            Expression::DayOfYear(_) => "day_of_year",
2112            Expression::WeekOfYear(_) => "week_of_year",
2113            Expression::Quarter(_) => "quarter",
2114            Expression::AddMonths(_) => "add_months",
2115            Expression::MonthsBetween(_) => "months_between",
2116            Expression::LastDay(_) => "last_day",
2117            Expression::NextDay(_) => "next_day",
2118            Expression::Epoch(_) => "epoch",
2119            Expression::EpochMs(_) => "epoch_ms",
2120            Expression::FromUnixtime(_) => "from_unixtime",
2121            Expression::UnixTimestamp(_) => "unix_timestamp",
2122            Expression::MakeDate(_) => "make_date",
2123            Expression::MakeTimestamp(_) => "make_timestamp",
2124            Expression::TimestampTrunc(_) => "timestamp_trunc",
2125            Expression::TimeStrToUnix(_) => "time_str_to_unix",
2126            Expression::SessionUser(_) => "session_user",
2127            Expression::SHA(_) => "s_h_a",
2128            Expression::SHA1Digest(_) => "s_h_a1_digest",
2129            Expression::TimeToUnix(_) => "time_to_unix",
2130            Expression::ArrayFunc(_) => "array_func",
2131            Expression::ArrayLength(_) => "array_length",
2132            Expression::ArraySize(_) => "array_size",
2133            Expression::Cardinality(_) => "cardinality",
2134            Expression::ArrayContains(_) => "array_contains",
2135            Expression::ArrayPosition(_) => "array_position",
2136            Expression::ArrayAppend(_) => "array_append",
2137            Expression::ArrayPrepend(_) => "array_prepend",
2138            Expression::ArrayConcat(_) => "array_concat",
2139            Expression::ArraySort(_) => "array_sort",
2140            Expression::ArrayReverse(_) => "array_reverse",
2141            Expression::ArrayDistinct(_) => "array_distinct",
2142            Expression::ArrayJoin(_) => "array_join",
2143            Expression::ArrayToString(_) => "array_to_string",
2144            Expression::Unnest(_) => "unnest",
2145            Expression::Explode(_) => "explode",
2146            Expression::ExplodeOuter(_) => "explode_outer",
2147            Expression::ArrayFilter(_) => "array_filter",
2148            Expression::ArrayTransform(_) => "array_transform",
2149            Expression::ArrayFlatten(_) => "array_flatten",
2150            Expression::ArrayCompact(_) => "array_compact",
2151            Expression::ArrayIntersect(_) => "array_intersect",
2152            Expression::ArrayUnion(_) => "array_union",
2153            Expression::ArrayExcept(_) => "array_except",
2154            Expression::ArrayRemove(_) => "array_remove",
2155            Expression::ArrayZip(_) => "array_zip",
2156            Expression::Sequence(_) => "sequence",
2157            Expression::Generate(_) => "generate",
2158            Expression::ExplodingGenerateSeries(_) => "exploding_generate_series",
2159            Expression::ToArray(_) => "to_array",
2160            Expression::StarMap(_) => "star_map",
2161            Expression::StructFunc(_) => "struct_func",
2162            Expression::StructExtract(_) => "struct_extract",
2163            Expression::NamedStruct(_) => "named_struct",
2164            Expression::MapFunc(_) => "map_func",
2165            Expression::MapFromEntries(_) => "map_from_entries",
2166            Expression::MapFromArrays(_) => "map_from_arrays",
2167            Expression::MapKeys(_) => "map_keys",
2168            Expression::MapValues(_) => "map_values",
2169            Expression::MapContainsKey(_) => "map_contains_key",
2170            Expression::MapConcat(_) => "map_concat",
2171            Expression::ElementAt(_) => "element_at",
2172            Expression::TransformKeys(_) => "transform_keys",
2173            Expression::TransformValues(_) => "transform_values",
2174            Expression::FunctionEmits(_) => "function_emits",
2175            Expression::JsonExtract(_) => "json_extract",
2176            Expression::JsonExtractScalar(_) => "json_extract_scalar",
2177            Expression::JsonExtractPath(_) => "json_extract_path",
2178            Expression::JsonArray(_) => "json_array",
2179            Expression::JsonObject(_) => "json_object",
2180            Expression::JsonQuery(_) => "json_query",
2181            Expression::JsonValue(_) => "json_value",
2182            Expression::JsonArrayLength(_) => "json_array_length",
2183            Expression::JsonKeys(_) => "json_keys",
2184            Expression::JsonType(_) => "json_type",
2185            Expression::ParseJson(_) => "parse_json",
2186            Expression::ToJson(_) => "to_json",
2187            Expression::JsonSet(_) => "json_set",
2188            Expression::JsonInsert(_) => "json_insert",
2189            Expression::JsonRemove(_) => "json_remove",
2190            Expression::JsonMergePatch(_) => "json_merge_patch",
2191            Expression::JsonArrayAgg(_) => "json_array_agg",
2192            Expression::JsonObjectAgg(_) => "json_object_agg",
2193            Expression::Convert(_) => "convert",
2194            Expression::Typeof(_) => "typeof",
2195            Expression::Lambda(_) => "lambda",
2196            Expression::Parameter(_) => "parameter",
2197            Expression::Placeholder(_) => "placeholder",
2198            Expression::NamedArgument(_) => "named_argument",
2199            Expression::TableArgument(_) => "table_argument",
2200            Expression::SqlComment(_) => "sql_comment",
2201            Expression::NullSafeEq(_) => "null_safe_eq",
2202            Expression::NullSafeNeq(_) => "null_safe_neq",
2203            Expression::Glob(_) => "glob",
2204            Expression::SimilarTo(_) => "similar_to",
2205            Expression::Any(_) => "any",
2206            Expression::All(_) => "all",
2207            Expression::Overlaps(_) => "overlaps",
2208            Expression::BitwiseLeftShift(_) => "bitwise_left_shift",
2209            Expression::BitwiseRightShift(_) => "bitwise_right_shift",
2210            Expression::BitwiseAndAgg(_) => "bitwise_and_agg",
2211            Expression::BitwiseOrAgg(_) => "bitwise_or_agg",
2212            Expression::BitwiseXorAgg(_) => "bitwise_xor_agg",
2213            Expression::Subscript(_) => "subscript",
2214            Expression::Dot(_) => "dot",
2215            Expression::MethodCall(_) => "method_call",
2216            Expression::ArraySlice(_) => "array_slice",
2217            Expression::CreateTable(_) => "create_table",
2218            Expression::DropTable(_) => "drop_table",
2219            Expression::Undrop(_) => "undrop",
2220            Expression::AlterTable(_) => "alter_table",
2221            Expression::SplitTable(_) => "split_table",
2222            Expression::FlashbackTable(_) => "flashback_table",
2223            Expression::CreateIndex(_) => "create_index",
2224            Expression::DropIndex(_) => "drop_index",
2225            Expression::CreateView(_) => "create_view",
2226            Expression::DropView(_) => "drop_view",
2227            Expression::AlterView(_) => "alter_view",
2228            Expression::AlterIndex(_) => "alter_index",
2229            Expression::Truncate(_) => "truncate",
2230            Expression::Use(_) => "use",
2231            Expression::Cache(_) => "cache",
2232            Expression::Uncache(_) => "uncache",
2233            Expression::LoadData(_) => "load_data",
2234            Expression::Pragma(_) => "pragma",
2235            Expression::Grant(_) => "grant",
2236            Expression::Revoke(_) => "revoke",
2237            Expression::Comment(_) => "comment",
2238            Expression::SetStatement(_) => "set_statement",
2239            Expression::CreateSchema(_) => "create_schema",
2240            Expression::DropSchema(_) => "drop_schema",
2241            Expression::DropNamespace(_) => "drop_namespace",
2242            Expression::CreateDatabase(_) => "create_database",
2243            Expression::DropDatabase(_) => "drop_database",
2244            Expression::CreateFunction(_) => "create_function",
2245            Expression::DropFunction(_) => "drop_function",
2246            Expression::CreateProcedure(_) => "create_procedure",
2247            Expression::DropProcedure(_) => "drop_procedure",
2248            Expression::CreateSequence(_) => "create_sequence",
2249            Expression::CreateSynonym(_) => "create_synonym",
2250            Expression::DropSequence(_) => "drop_sequence",
2251            Expression::AlterSequence(_) => "alter_sequence",
2252            Expression::CreateTrigger(_) => "create_trigger",
2253            Expression::DropTrigger(_) => "drop_trigger",
2254            Expression::CreateType(_) => "create_type",
2255            Expression::DropType(_) => "drop_type",
2256            Expression::Describe(_) => "describe",
2257            Expression::Show(_) => "show",
2258            Expression::Command(_) => "command",
2259            Expression::TryCatch(_) => "try_catch",
2260            Expression::Kill(_) => "kill",
2261            Expression::Prepare(_) => "prepare",
2262            Expression::Execute(_) => "execute",
2263            Expression::Raw(_) => "raw",
2264            Expression::CreateTask(_) => "create_task",
2265            Expression::Paren(_) => "paren",
2266            Expression::Annotated(_) => "annotated",
2267            Expression::Refresh(_) => "refresh",
2268            Expression::LockingStatement(_) => "locking_statement",
2269            Expression::SequenceProperties(_) => "sequence_properties",
2270            Expression::TruncateTable(_) => "truncate_table",
2271            Expression::Clone(_) => "clone",
2272            Expression::Attach(_) => "attach",
2273            Expression::Detach(_) => "detach",
2274            Expression::Install(_) => "install",
2275            Expression::Summarize(_) => "summarize",
2276            Expression::Declare(_) => "declare",
2277            Expression::DeclareItem(_) => "declare_item",
2278            Expression::Set(_) => "set",
2279            Expression::Heredoc(_) => "heredoc",
2280            Expression::SetItem(_) => "set_item",
2281            Expression::QueryBand(_) => "query_band",
2282            Expression::UserDefinedFunction(_) => "user_defined_function",
2283            Expression::RecursiveWithSearch(_) => "recursive_with_search",
2284            Expression::ProjectionDef(_) => "projection_def",
2285            Expression::TableAlias(_) => "table_alias",
2286            Expression::ByteString(_) => "byte_string",
2287            Expression::HexStringExpr(_) => "hex_string_expr",
2288            Expression::UnicodeString(_) => "unicode_string",
2289            Expression::ColumnPosition(_) => "column_position",
2290            Expression::ColumnDef(_) => "column_def",
2291            Expression::AlterColumn(_) => "alter_column",
2292            Expression::AlterSortKey(_) => "alter_sort_key",
2293            Expression::AlterSet(_) => "alter_set",
2294            Expression::RenameColumn(_) => "rename_column",
2295            Expression::Comprehension(_) => "comprehension",
2296            Expression::MergeTreeTTLAction(_) => "merge_tree_t_t_l_action",
2297            Expression::MergeTreeTTL(_) => "merge_tree_t_t_l",
2298            Expression::IndexConstraintOption(_) => "index_constraint_option",
2299            Expression::ColumnConstraint(_) => "column_constraint",
2300            Expression::PeriodForSystemTimeConstraint(_) => "period_for_system_time_constraint",
2301            Expression::CaseSpecificColumnConstraint(_) => "case_specific_column_constraint",
2302            Expression::CharacterSetColumnConstraint(_) => "character_set_column_constraint",
2303            Expression::CheckColumnConstraint(_) => "check_column_constraint",
2304            Expression::AssumeColumnConstraint(_) => "assume_column_constraint",
2305            Expression::CompressColumnConstraint(_) => "compress_column_constraint",
2306            Expression::DateFormatColumnConstraint(_) => "date_format_column_constraint",
2307            Expression::EphemeralColumnConstraint(_) => "ephemeral_column_constraint",
2308            Expression::WithOperator(_) => "with_operator",
2309            Expression::GeneratedAsIdentityColumnConstraint(_) => {
2310                "generated_as_identity_column_constraint"
2311            }
2312            Expression::AutoIncrementColumnConstraint(_) => "auto_increment_column_constraint",
2313            Expression::CommentColumnConstraint(_) => "comment_column_constraint",
2314            Expression::GeneratedAsRowColumnConstraint(_) => "generated_as_row_column_constraint",
2315            Expression::IndexColumnConstraint(_) => "index_column_constraint",
2316            Expression::MaskingPolicyColumnConstraint(_) => "masking_policy_column_constraint",
2317            Expression::NotNullColumnConstraint(_) => "not_null_column_constraint",
2318            Expression::PrimaryKeyColumnConstraint(_) => "primary_key_column_constraint",
2319            Expression::UniqueColumnConstraint(_) => "unique_column_constraint",
2320            Expression::WatermarkColumnConstraint(_) => "watermark_column_constraint",
2321            Expression::ComputedColumnConstraint(_) => "computed_column_constraint",
2322            Expression::InOutColumnConstraint(_) => "in_out_column_constraint",
2323            Expression::DefaultColumnConstraint(_) => "default_column_constraint",
2324            Expression::PathColumnConstraint(_) => "path_column_constraint",
2325            Expression::Constraint(_) => "constraint",
2326            Expression::Export(_) => "export",
2327            Expression::Filter(_) => "filter",
2328            Expression::Changes(_) => "changes",
2329            Expression::CopyParameter(_) => "copy_parameter",
2330            Expression::Credentials(_) => "credentials",
2331            Expression::Directory(_) => "directory",
2332            Expression::ForeignKey(_) => "foreign_key",
2333            Expression::ColumnPrefix(_) => "column_prefix",
2334            Expression::PrimaryKey(_) => "primary_key",
2335            Expression::IntoClause(_) => "into_clause",
2336            Expression::JoinHint(_) => "join_hint",
2337            Expression::Opclass(_) => "opclass",
2338            Expression::Index(_) => "index",
2339            Expression::IndexParameters(_) => "index_parameters",
2340            Expression::ConditionalInsert(_) => "conditional_insert",
2341            Expression::MultitableInserts(_) => "multitable_inserts",
2342            Expression::OnConflict(_) => "on_conflict",
2343            Expression::OnCondition(_) => "on_condition",
2344            Expression::Returning(_) => "returning",
2345            Expression::Introducer(_) => "introducer",
2346            Expression::PartitionRange(_) => "partition_range",
2347            Expression::Fetch(_) => "fetch",
2348            Expression::Group(_) => "group",
2349            Expression::Cube(_) => "cube",
2350            Expression::Rollup(_) => "rollup",
2351            Expression::GroupingSets(_) => "grouping_sets",
2352            Expression::LimitOptions(_) => "limit_options",
2353            Expression::Lateral(_) => "lateral",
2354            Expression::TableFromRows(_) => "table_from_rows",
2355            Expression::RowsFrom(_) => "rows_from",
2356            Expression::MatchRecognizeMeasure(_) => "match_recognize_measure",
2357            Expression::WithFill(_) => "with_fill",
2358            Expression::Property(_) => "property",
2359            Expression::GrantPrivilege(_) => "grant_privilege",
2360            Expression::GrantPrincipal(_) => "grant_principal",
2361            Expression::AllowedValuesProperty(_) => "allowed_values_property",
2362            Expression::AlgorithmProperty(_) => "algorithm_property",
2363            Expression::AutoIncrementProperty(_) => "auto_increment_property",
2364            Expression::AutoRefreshProperty(_) => "auto_refresh_property",
2365            Expression::BackupProperty(_) => "backup_property",
2366            Expression::BuildProperty(_) => "build_property",
2367            Expression::BlockCompressionProperty(_) => "block_compression_property",
2368            Expression::CharacterSetProperty(_) => "character_set_property",
2369            Expression::ChecksumProperty(_) => "checksum_property",
2370            Expression::CollateProperty(_) => "collate_property",
2371            Expression::DataBlocksizeProperty(_) => "data_blocksize_property",
2372            Expression::DataDeletionProperty(_) => "data_deletion_property",
2373            Expression::DefinerProperty(_) => "definer_property",
2374            Expression::DistKeyProperty(_) => "dist_key_property",
2375            Expression::DistributedByProperty(_) => "distributed_by_property",
2376            Expression::DistStyleProperty(_) => "dist_style_property",
2377            Expression::DuplicateKeyProperty(_) => "duplicate_key_property",
2378            Expression::EngineProperty(_) => "engine_property",
2379            Expression::ToTableProperty(_) => "to_table_property",
2380            Expression::ExecuteAsProperty(_) => "execute_as_property",
2381            Expression::ExternalProperty(_) => "external_property",
2382            Expression::FallbackProperty(_) => "fallback_property",
2383            Expression::FileFormatProperty(_) => "file_format_property",
2384            Expression::CredentialsProperty(_) => "credentials_property",
2385            Expression::FreespaceProperty(_) => "freespace_property",
2386            Expression::InheritsProperty(_) => "inherits_property",
2387            Expression::InputModelProperty(_) => "input_model_property",
2388            Expression::OutputModelProperty(_) => "output_model_property",
2389            Expression::IsolatedLoadingProperty(_) => "isolated_loading_property",
2390            Expression::JournalProperty(_) => "journal_property",
2391            Expression::LanguageProperty(_) => "language_property",
2392            Expression::EnviromentProperty(_) => "enviroment_property",
2393            Expression::ClusteredByProperty(_) => "clustered_by_property",
2394            Expression::DictProperty(_) => "dict_property",
2395            Expression::DictRange(_) => "dict_range",
2396            Expression::OnCluster(_) => "on_cluster",
2397            Expression::LikeProperty(_) => "like_property",
2398            Expression::LocationProperty(_) => "location_property",
2399            Expression::LockProperty(_) => "lock_property",
2400            Expression::LockingProperty(_) => "locking_property",
2401            Expression::LogProperty(_) => "log_property",
2402            Expression::MaterializedProperty(_) => "materialized_property",
2403            Expression::MergeBlockRatioProperty(_) => "merge_block_ratio_property",
2404            Expression::OnProperty(_) => "on_property",
2405            Expression::OnCommitProperty(_) => "on_commit_property",
2406            Expression::PartitionedByProperty(_) => "partitioned_by_property",
2407            Expression::PartitionByProperty(_) => "partition_by_property",
2408            Expression::PartitionedByBucket(_) => "partitioned_by_bucket",
2409            Expression::ClusterByColumnsProperty(_) => "cluster_by_columns_property",
2410            Expression::PartitionByTruncate(_) => "partition_by_truncate",
2411            Expression::PartitionByRangeProperty(_) => "partition_by_range_property",
2412            Expression::PartitionByRangePropertyDynamic(_) => "partition_by_range_property_dynamic",
2413            Expression::PartitionByListProperty(_) => "partition_by_list_property",
2414            Expression::PartitionList(_) => "partition_list",
2415            Expression::Partition(_) => "partition",
2416            Expression::RefreshTriggerProperty(_) => "refresh_trigger_property",
2417            Expression::UniqueKeyProperty(_) => "unique_key_property",
2418            Expression::RollupProperty(_) => "rollup_property",
2419            Expression::PartitionBoundSpec(_) => "partition_bound_spec",
2420            Expression::PartitionedOfProperty(_) => "partitioned_of_property",
2421            Expression::RemoteWithConnectionModelProperty(_) => {
2422                "remote_with_connection_model_property"
2423            }
2424            Expression::ReturnsProperty(_) => "returns_property",
2425            Expression::RowFormatProperty(_) => "row_format_property",
2426            Expression::RowFormatDelimitedProperty(_) => "row_format_delimited_property",
2427            Expression::RowFormatSerdeProperty(_) => "row_format_serde_property",
2428            Expression::QueryTransform(_) => "query_transform",
2429            Expression::SampleProperty(_) => "sample_property",
2430            Expression::SecurityProperty(_) => "security_property",
2431            Expression::SchemaCommentProperty(_) => "schema_comment_property",
2432            Expression::SemanticView(_) => "semantic_view",
2433            Expression::SerdeProperties(_) => "serde_properties",
2434            Expression::SetProperty(_) => "set_property",
2435            Expression::SharingProperty(_) => "sharing_property",
2436            Expression::SetConfigProperty(_) => "set_config_property",
2437            Expression::SettingsProperty(_) => "settings_property",
2438            Expression::SortKeyProperty(_) => "sort_key_property",
2439            Expression::SqlReadWriteProperty(_) => "sql_read_write_property",
2440            Expression::SqlSecurityProperty(_) => "sql_security_property",
2441            Expression::StabilityProperty(_) => "stability_property",
2442            Expression::StorageHandlerProperty(_) => "storage_handler_property",
2443            Expression::TemporaryProperty(_) => "temporary_property",
2444            Expression::Tags(_) => "tags",
2445            Expression::TransformModelProperty(_) => "transform_model_property",
2446            Expression::TransientProperty(_) => "transient_property",
2447            Expression::UsingTemplateProperty(_) => "using_template_property",
2448            Expression::ViewAttributeProperty(_) => "view_attribute_property",
2449            Expression::VolatileProperty(_) => "volatile_property",
2450            Expression::WithDataProperty(_) => "with_data_property",
2451            Expression::WithJournalTableProperty(_) => "with_journal_table_property",
2452            Expression::WithSchemaBindingProperty(_) => "with_schema_binding_property",
2453            Expression::WithSystemVersioningProperty(_) => "with_system_versioning_property",
2454            Expression::WithProcedureOptions(_) => "with_procedure_options",
2455            Expression::EncodeProperty(_) => "encode_property",
2456            Expression::IncludeProperty(_) => "include_property",
2457            Expression::Properties(_) => "properties",
2458            Expression::OptionsProperty(_) => "options_property",
2459            Expression::InputOutputFormat(_) => "input_output_format",
2460            Expression::Reference(_) => "reference",
2461            Expression::QueryOption(_) => "query_option",
2462            Expression::WithTableHint(_) => "with_table_hint",
2463            Expression::IndexTableHint(_) => "index_table_hint",
2464            Expression::HistoricalData(_) => "historical_data",
2465            Expression::Get(_) => "get",
2466            Expression::SetOperation(_) => "set_operation",
2467            Expression::Var(_) => "var",
2468            Expression::Variadic(_) => "variadic",
2469            Expression::Version(_) => "version",
2470            Expression::Schema(_) => "schema",
2471            Expression::Lock(_) => "lock",
2472            Expression::TableSample(_) => "table_sample",
2473            Expression::Tag(_) => "tag",
2474            Expression::UnpivotColumns(_) => "unpivot_columns",
2475            Expression::WindowSpec(_) => "window_spec",
2476            Expression::SessionParameter(_) => "session_parameter",
2477            Expression::PseudoType(_) => "pseudo_type",
2478            Expression::ObjectIdentifier(_) => "object_identifier",
2479            Expression::Transaction(_) => "transaction",
2480            Expression::Commit(_) => "commit",
2481            Expression::Rollback(_) => "rollback",
2482            Expression::AlterSession(_) => "alter_session",
2483            Expression::Analyze(_) => "analyze",
2484            Expression::AnalyzeStatistics(_) => "analyze_statistics",
2485            Expression::AnalyzeHistogram(_) => "analyze_histogram",
2486            Expression::AnalyzeSample(_) => "analyze_sample",
2487            Expression::AnalyzeListChainedRows(_) => "analyze_list_chained_rows",
2488            Expression::AnalyzeDelete(_) => "analyze_delete",
2489            Expression::AnalyzeWith(_) => "analyze_with",
2490            Expression::AnalyzeValidate(_) => "analyze_validate",
2491            Expression::AddPartition(_) => "add_partition",
2492            Expression::AttachOption(_) => "attach_option",
2493            Expression::DropPartition(_) => "drop_partition",
2494            Expression::ReplacePartition(_) => "replace_partition",
2495            Expression::DPipe(_) => "d_pipe",
2496            Expression::Operator(_) => "operator",
2497            Expression::PivotAny(_) => "pivot_any",
2498            Expression::Aliases(_) => "aliases",
2499            Expression::AtIndex(_) => "at_index",
2500            Expression::FromTimeZone(_) => "from_time_zone",
2501            Expression::FormatPhrase(_) => "format_phrase",
2502            Expression::ForIn(_) => "for_in",
2503            Expression::TimeUnit(_) => "time_unit",
2504            Expression::IntervalOp(_) => "interval_op",
2505            Expression::IntervalSpan(_) => "interval_span",
2506            Expression::HavingMax(_) => "having_max",
2507            Expression::CosineDistance(_) => "cosine_distance",
2508            Expression::DotProduct(_) => "dot_product",
2509            Expression::EuclideanDistance(_) => "euclidean_distance",
2510            Expression::ManhattanDistance(_) => "manhattan_distance",
2511            Expression::JarowinklerSimilarity(_) => "jarowinkler_similarity",
2512            Expression::Booland(_) => "booland",
2513            Expression::Boolor(_) => "boolor",
2514            Expression::ParameterizedAgg(_) => "parameterized_agg",
2515            Expression::ArgMax(_) => "arg_max",
2516            Expression::ArgMin(_) => "arg_min",
2517            Expression::ApproxTopK(_) => "approx_top_k",
2518            Expression::ApproxTopKAccumulate(_) => "approx_top_k_accumulate",
2519            Expression::ApproxTopKCombine(_) => "approx_top_k_combine",
2520            Expression::ApproxTopKEstimate(_) => "approx_top_k_estimate",
2521            Expression::ApproxTopSum(_) => "approx_top_sum",
2522            Expression::ApproxQuantiles(_) => "approx_quantiles",
2523            Expression::Minhash(_) => "minhash",
2524            Expression::FarmFingerprint(_) => "farm_fingerprint",
2525            Expression::Float64(_) => "float64",
2526            Expression::Transform(_) => "transform",
2527            Expression::Translate(_) => "translate",
2528            Expression::Grouping(_) => "grouping",
2529            Expression::GroupingId(_) => "grouping_id",
2530            Expression::Anonymous(_) => "anonymous",
2531            Expression::AnonymousAggFunc(_) => "anonymous_agg_func",
2532            Expression::CombinedAggFunc(_) => "combined_agg_func",
2533            Expression::CombinedParameterizedAgg(_) => "combined_parameterized_agg",
2534            Expression::HashAgg(_) => "hash_agg",
2535            Expression::Hll(_) => "hll",
2536            Expression::Apply(_) => "apply",
2537            Expression::ToBoolean(_) => "to_boolean",
2538            Expression::List(_) => "list",
2539            Expression::ToMap(_) => "to_map",
2540            Expression::Pad(_) => "pad",
2541            Expression::ToChar(_) => "to_char",
2542            Expression::ToNumber(_) => "to_number",
2543            Expression::ToDouble(_) => "to_double",
2544            Expression::Int64(_) => "int64",
2545            Expression::StringFunc(_) => "string_func",
2546            Expression::ToDecfloat(_) => "to_decfloat",
2547            Expression::TryToDecfloat(_) => "try_to_decfloat",
2548            Expression::ToFile(_) => "to_file",
2549            Expression::Columns(_) => "columns",
2550            Expression::ConvertToCharset(_) => "convert_to_charset",
2551            Expression::ConvertTimezone(_) => "convert_timezone",
2552            Expression::GenerateSeries(_) => "generate_series",
2553            Expression::AIAgg(_) => "a_i_agg",
2554            Expression::AIClassify(_) => "a_i_classify",
2555            Expression::ArrayAll(_) => "array_all",
2556            Expression::ArrayAny(_) => "array_any",
2557            Expression::ArrayConstructCompact(_) => "array_construct_compact",
2558            Expression::StPoint(_) => "st_point",
2559            Expression::StDistance(_) => "st_distance",
2560            Expression::StringToArray(_) => "string_to_array",
2561            Expression::ArraySum(_) => "array_sum",
2562            Expression::ObjectAgg(_) => "object_agg",
2563            Expression::CastToStrType(_) => "cast_to_str_type",
2564            Expression::CheckJson(_) => "check_json",
2565            Expression::CheckXml(_) => "check_xml",
2566            Expression::TranslateCharacters(_) => "translate_characters",
2567            Expression::CurrentSchemas(_) => "current_schemas",
2568            Expression::CurrentDatetime(_) => "current_datetime",
2569            Expression::Localtime(_) => "localtime",
2570            Expression::Localtimestamp(_) => "localtimestamp",
2571            Expression::Systimestamp(_) => "systimestamp",
2572            Expression::CurrentSchema(_) => "current_schema",
2573            Expression::CurrentUser(_) => "current_user",
2574            Expression::UtcTime(_) => "utc_time",
2575            Expression::UtcTimestamp(_) => "utc_timestamp",
2576            Expression::Timestamp(_) => "timestamp",
2577            Expression::DateBin(_) => "date_bin",
2578            Expression::Datetime(_) => "datetime",
2579            Expression::DatetimeAdd(_) => "datetime_add",
2580            Expression::DatetimeSub(_) => "datetime_sub",
2581            Expression::DatetimeDiff(_) => "datetime_diff",
2582            Expression::DatetimeTrunc(_) => "datetime_trunc",
2583            Expression::Dayname(_) => "dayname",
2584            Expression::MakeInterval(_) => "make_interval",
2585            Expression::PreviousDay(_) => "previous_day",
2586            Expression::Elt(_) => "elt",
2587            Expression::TimestampAdd(_) => "timestamp_add",
2588            Expression::TimestampSub(_) => "timestamp_sub",
2589            Expression::TimestampDiff(_) => "timestamp_diff",
2590            Expression::TimeSlice(_) => "time_slice",
2591            Expression::TimeAdd(_) => "time_add",
2592            Expression::TimeSub(_) => "time_sub",
2593            Expression::TimeDiff(_) => "time_diff",
2594            Expression::TimeTrunc(_) => "time_trunc",
2595            Expression::DateFromParts(_) => "date_from_parts",
2596            Expression::TimeFromParts(_) => "time_from_parts",
2597            Expression::DecodeCase(_) => "decode_case",
2598            Expression::Decrypt(_) => "decrypt",
2599            Expression::DecryptRaw(_) => "decrypt_raw",
2600            Expression::Encode(_) => "encode",
2601            Expression::Encrypt(_) => "encrypt",
2602            Expression::EncryptRaw(_) => "encrypt_raw",
2603            Expression::EqualNull(_) => "equal_null",
2604            Expression::ToBinary(_) => "to_binary",
2605            Expression::Base64DecodeBinary(_) => "base64_decode_binary",
2606            Expression::Base64DecodeString(_) => "base64_decode_string",
2607            Expression::Base64Encode(_) => "base64_encode",
2608            Expression::TryBase64DecodeBinary(_) => "try_base64_decode_binary",
2609            Expression::TryBase64DecodeString(_) => "try_base64_decode_string",
2610            Expression::GapFill(_) => "gap_fill",
2611            Expression::GenerateDateArray(_) => "generate_date_array",
2612            Expression::GenerateTimestampArray(_) => "generate_timestamp_array",
2613            Expression::GetExtract(_) => "get_extract",
2614            Expression::Getbit(_) => "getbit",
2615            Expression::OverflowTruncateBehavior(_) => "overflow_truncate_behavior",
2616            Expression::HexEncode(_) => "hex_encode",
2617            Expression::Compress(_) => "compress",
2618            Expression::DecompressBinary(_) => "decompress_binary",
2619            Expression::DecompressString(_) => "decompress_string",
2620            Expression::Xor(_) => "xor",
2621            Expression::Nullif(_) => "nullif",
2622            Expression::JSON(_) => "j_s_o_n",
2623            Expression::JSONPath(_) => "j_s_o_n_path",
2624            Expression::JSONPathFilter(_) => "j_s_o_n_path_filter",
2625            Expression::JSONPathKey(_) => "j_s_o_n_path_key",
2626            Expression::JSONPathRecursive(_) => "j_s_o_n_path_recursive",
2627            Expression::JSONPathScript(_) => "j_s_o_n_path_script",
2628            Expression::JSONPathSlice(_) => "j_s_o_n_path_slice",
2629            Expression::JSONPathSelector(_) => "j_s_o_n_path_selector",
2630            Expression::JSONPathSubscript(_) => "j_s_o_n_path_subscript",
2631            Expression::JSONPathUnion(_) => "j_s_o_n_path_union",
2632            Expression::Format(_) => "format",
2633            Expression::JSONKeys(_) => "j_s_o_n_keys",
2634            Expression::JSONKeyValue(_) => "j_s_o_n_key_value",
2635            Expression::JSONKeysAtDepth(_) => "j_s_o_n_keys_at_depth",
2636            Expression::JSONObject(_) => "j_s_o_n_object",
2637            Expression::JSONObjectAgg(_) => "j_s_o_n_object_agg",
2638            Expression::JSONBObjectAgg(_) => "j_s_o_n_b_object_agg",
2639            Expression::JSONArray(_) => "j_s_o_n_array",
2640            Expression::JSONArrayAgg(_) => "j_s_o_n_array_agg",
2641            Expression::JSONExists(_) => "j_s_o_n_exists",
2642            Expression::JSONColumnDef(_) => "j_s_o_n_column_def",
2643            Expression::JSONSchema(_) => "j_s_o_n_schema",
2644            Expression::JSONSet(_) => "j_s_o_n_set",
2645            Expression::JSONStripNulls(_) => "j_s_o_n_strip_nulls",
2646            Expression::JSONValue(_) => "j_s_o_n_value",
2647            Expression::JSONValueArray(_) => "j_s_o_n_value_array",
2648            Expression::JSONRemove(_) => "j_s_o_n_remove",
2649            Expression::JSONTable(_) => "j_s_o_n_table",
2650            Expression::JSONType(_) => "j_s_o_n_type",
2651            Expression::ObjectInsert(_) => "object_insert",
2652            Expression::OpenJSONColumnDef(_) => "open_j_s_o_n_column_def",
2653            Expression::OpenJSON(_) => "open_j_s_o_n",
2654            Expression::JSONBExists(_) => "j_s_o_n_b_exists",
2655            Expression::JSONBContains(_) => "j_s_o_n_b_contains",
2656            Expression::JSONBExtract(_) => "j_s_o_n_b_extract",
2657            Expression::JSONCast(_) => "j_s_o_n_cast",
2658            Expression::JSONExtract(_) => "j_s_o_n_extract",
2659            Expression::JSONExtractQuote(_) => "j_s_o_n_extract_quote",
2660            Expression::JSONExtractArray(_) => "j_s_o_n_extract_array",
2661            Expression::JSONExtractScalar(_) => "j_s_o_n_extract_scalar",
2662            Expression::JSONBExtractScalar(_) => "j_s_o_n_b_extract_scalar",
2663            Expression::JSONFormat(_) => "j_s_o_n_format",
2664            Expression::JSONBool(_) => "j_s_o_n_bool",
2665            Expression::JSONPathRoot(_) => "j_s_o_n_path_root",
2666            Expression::JSONArrayAppend(_) => "j_s_o_n_array_append",
2667            Expression::JSONArrayContains(_) => "j_s_o_n_array_contains",
2668            Expression::JSONArrayInsert(_) => "j_s_o_n_array_insert",
2669            Expression::ParseJSON(_) => "parse_j_s_o_n",
2670            Expression::ParseUrl(_) => "parse_url",
2671            Expression::ParseIp(_) => "parse_ip",
2672            Expression::ParseTime(_) => "parse_time",
2673            Expression::ParseDatetime(_) => "parse_datetime",
2674            Expression::Map(_) => "map",
2675            Expression::MapCat(_) => "map_cat",
2676            Expression::MapDelete(_) => "map_delete",
2677            Expression::MapInsert(_) => "map_insert",
2678            Expression::MapPick(_) => "map_pick",
2679            Expression::ScopeResolution(_) => "scope_resolution",
2680            Expression::Slice(_) => "slice",
2681            Expression::VarMap(_) => "var_map",
2682            Expression::MatchAgainst(_) => "match_against",
2683            Expression::MD5Digest(_) => "m_d5_digest",
2684            Expression::MD5NumberLower64(_) => "m_d5_number_lower64",
2685            Expression::MD5NumberUpper64(_) => "m_d5_number_upper64",
2686            Expression::Monthname(_) => "monthname",
2687            Expression::Ntile(_) => "ntile",
2688            Expression::Normalize(_) => "normalize",
2689            Expression::Normal(_) => "normal",
2690            Expression::Predict(_) => "predict",
2691            Expression::MLTranslate(_) => "m_l_translate",
2692            Expression::FeaturesAtTime(_) => "features_at_time",
2693            Expression::GenerateEmbedding(_) => "generate_embedding",
2694            Expression::MLForecast(_) => "m_l_forecast",
2695            Expression::ModelAttribute(_) => "model_attribute",
2696            Expression::VectorSearch(_) => "vector_search",
2697            Expression::Quantile(_) => "quantile",
2698            Expression::ApproxQuantile(_) => "approx_quantile",
2699            Expression::ApproxPercentileEstimate(_) => "approx_percentile_estimate",
2700            Expression::Randn(_) => "randn",
2701            Expression::Randstr(_) => "randstr",
2702            Expression::RangeN(_) => "range_n",
2703            Expression::RangeBucket(_) => "range_bucket",
2704            Expression::ReadCSV(_) => "read_c_s_v",
2705            Expression::ReadParquet(_) => "read_parquet",
2706            Expression::Reduce(_) => "reduce",
2707            Expression::RegexpExtractAll(_) => "regexp_extract_all",
2708            Expression::RegexpILike(_) => "regexp_i_like",
2709            Expression::RegexpFullMatch(_) => "regexp_full_match",
2710            Expression::RegexpInstr(_) => "regexp_instr",
2711            Expression::RegexpSplit(_) => "regexp_split",
2712            Expression::RegexpCount(_) => "regexp_count",
2713            Expression::RegrValx(_) => "regr_valx",
2714            Expression::RegrValy(_) => "regr_valy",
2715            Expression::RegrAvgy(_) => "regr_avgy",
2716            Expression::RegrAvgx(_) => "regr_avgx",
2717            Expression::RegrCount(_) => "regr_count",
2718            Expression::RegrIntercept(_) => "regr_intercept",
2719            Expression::RegrR2(_) => "regr_r2",
2720            Expression::RegrSxx(_) => "regr_sxx",
2721            Expression::RegrSxy(_) => "regr_sxy",
2722            Expression::RegrSyy(_) => "regr_syy",
2723            Expression::RegrSlope(_) => "regr_slope",
2724            Expression::SafeAdd(_) => "safe_add",
2725            Expression::SafeDivide(_) => "safe_divide",
2726            Expression::SafeMultiply(_) => "safe_multiply",
2727            Expression::SafeSubtract(_) => "safe_subtract",
2728            Expression::SHA2(_) => "s_h_a2",
2729            Expression::SHA2Digest(_) => "s_h_a2_digest",
2730            Expression::SortArray(_) => "sort_array",
2731            Expression::SplitPart(_) => "split_part",
2732            Expression::SubstringIndex(_) => "substring_index",
2733            Expression::StandardHash(_) => "standard_hash",
2734            Expression::StrPosition(_) => "str_position",
2735            Expression::Search(_) => "search",
2736            Expression::SearchIp(_) => "search_ip",
2737            Expression::StrToDate(_) => "str_to_date",
2738            Expression::DateStrToDate(_) => "date_str_to_date",
2739            Expression::DateToDateStr(_) => "date_to_date_str",
2740            Expression::StrToTime(_) => "str_to_time",
2741            Expression::StrToUnix(_) => "str_to_unix",
2742            Expression::StrToMap(_) => "str_to_map",
2743            Expression::NumberToStr(_) => "number_to_str",
2744            Expression::FromBase(_) => "from_base",
2745            Expression::Stuff(_) => "stuff",
2746            Expression::TimeToStr(_) => "time_to_str",
2747            Expression::TimeStrToTime(_) => "time_str_to_time",
2748            Expression::TsOrDsAdd(_) => "ts_or_ds_add",
2749            Expression::TsOrDsDiff(_) => "ts_or_ds_diff",
2750            Expression::TsOrDsToDate(_) => "ts_or_ds_to_date",
2751            Expression::TsOrDsToTime(_) => "ts_or_ds_to_time",
2752            Expression::Unhex(_) => "unhex",
2753            Expression::Uniform(_) => "uniform",
2754            Expression::UnixToStr(_) => "unix_to_str",
2755            Expression::UnixToTime(_) => "unix_to_time",
2756            Expression::Uuid(_) => "uuid",
2757            Expression::TimestampFromParts(_) => "timestamp_from_parts",
2758            Expression::TimestampTzFromParts(_) => "timestamp_tz_from_parts",
2759            Expression::Corr(_) => "corr",
2760            Expression::WidthBucket(_) => "width_bucket",
2761            Expression::CovarSamp(_) => "covar_samp",
2762            Expression::CovarPop(_) => "covar_pop",
2763            Expression::Week(_) => "week",
2764            Expression::XMLElement(_) => "x_m_l_element",
2765            Expression::XMLGet(_) => "x_m_l_get",
2766            Expression::XMLTable(_) => "x_m_l_table",
2767            Expression::XMLKeyValueOption(_) => "x_m_l_key_value_option",
2768            Expression::Zipf(_) => "zipf",
2769            Expression::Merge(_) => "merge",
2770            Expression::When(_) => "when",
2771            Expression::Whens(_) => "whens",
2772            Expression::NextValueFor(_) => "next_value_for",
2773            Expression::ReturnStmt(_) => "return_stmt",
2774        }
2775    }
2776
2777    /// Returns the primary child expression (".this" in sqlglot).
2778    pub fn get_this(&self) -> Option<&Expression> {
2779        match self {
2780            // Unary ops
2781            Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this),
2782            // UnaryFunc variants
2783            Expression::Upper(f)
2784            | Expression::Lower(f)
2785            | Expression::Length(f)
2786            | Expression::LTrim(f)
2787            | Expression::RTrim(f)
2788            | Expression::Reverse(f)
2789            | Expression::Abs(f)
2790            | Expression::Sqrt(f)
2791            | Expression::Cbrt(f)
2792            | Expression::Ln(f)
2793            | Expression::Exp(f)
2794            | Expression::Sign(f)
2795            | Expression::Date(f)
2796            | Expression::Time(f)
2797            | Expression::Initcap(f)
2798            | Expression::Ascii(f)
2799            | Expression::Chr(f)
2800            | Expression::Soundex(f)
2801            | Expression::ByteLength(f)
2802            | Expression::Hex(f)
2803            | Expression::LowerHex(f)
2804            | Expression::Unicode(f)
2805            | Expression::Typeof(f)
2806            | Expression::Explode(f)
2807            | Expression::ExplodeOuter(f)
2808            | Expression::MapFromEntries(f)
2809            | Expression::MapKeys(f)
2810            | Expression::MapValues(f)
2811            | Expression::ArrayLength(f)
2812            | Expression::ArraySize(f)
2813            | Expression::Cardinality(f)
2814            | Expression::ArrayReverse(f)
2815            | Expression::ArrayDistinct(f)
2816            | Expression::ArrayFlatten(f)
2817            | Expression::ArrayCompact(f)
2818            | Expression::ToArray(f)
2819            | Expression::JsonArrayLength(f)
2820            | Expression::JsonKeys(f)
2821            | Expression::JsonType(f)
2822            | Expression::ParseJson(f)
2823            | Expression::ToJson(f)
2824            | Expression::Radians(f)
2825            | Expression::Degrees(f)
2826            | Expression::Sin(f)
2827            | Expression::Cos(f)
2828            | Expression::Tan(f)
2829            | Expression::Asin(f)
2830            | Expression::Acos(f)
2831            | Expression::Atan(f)
2832            | Expression::IsNan(f)
2833            | Expression::IsInf(f)
2834            | Expression::Year(f)
2835            | Expression::Month(f)
2836            | Expression::Day(f)
2837            | Expression::Hour(f)
2838            | Expression::Minute(f)
2839            | Expression::Second(f)
2840            | Expression::DayOfWeek(f)
2841            | Expression::DayOfWeekIso(f)
2842            | Expression::DayOfMonth(f)
2843            | Expression::DayOfYear(f)
2844            | Expression::WeekOfYear(f)
2845            | Expression::Quarter(f)
2846            | Expression::Epoch(f)
2847            | Expression::EpochMs(f)
2848            | Expression::BitwiseCount(f)
2849            | Expression::DateFromUnixDate(f)
2850            | Expression::UnixDate(f)
2851            | Expression::UnixSeconds(f)
2852            | Expression::UnixMillis(f)
2853            | Expression::UnixMicros(f)
2854            | Expression::TimeStrToDate(f)
2855            | Expression::DateToDi(f)
2856            | Expression::DiToDate(f)
2857            | Expression::TsOrDiToDi(f)
2858            | Expression::TsOrDsToDatetime(f)
2859            | Expression::TsOrDsToTimestamp(f)
2860            | Expression::YearOfWeek(f)
2861            | Expression::YearOfWeekIso(f)
2862            | Expression::SHA(f)
2863            | Expression::SHA1Digest(f)
2864            | Expression::TimeToUnix(f)
2865            | Expression::TimeStrToUnix(f)
2866            | Expression::Int64(f)
2867            | Expression::JSONBool(f)
2868            | Expression::MD5NumberLower64(f)
2869            | Expression::MD5NumberUpper64(f)
2870            | Expression::DateStrToDate(f)
2871            | Expression::DateToDateStr(f) => Some(&f.this),
2872            // BinaryFunc - this is the primary child
2873            Expression::Power(f)
2874            | Expression::NullIf(f)
2875            | Expression::IfNull(f)
2876            | Expression::Nvl(f)
2877            | Expression::Contains(f)
2878            | Expression::StartsWith(f)
2879            | Expression::EndsWith(f)
2880            | Expression::Levenshtein(f)
2881            | Expression::ModFunc(f)
2882            | Expression::IntDiv(f)
2883            | Expression::Atan2(f)
2884            | Expression::AddMonths(f)
2885            | Expression::MonthsBetween(f)
2886            | Expression::NextDay(f)
2887            | Expression::UnixToTimeStr(f)
2888            | Expression::ArrayContains(f)
2889            | Expression::ArrayPosition(f)
2890            | Expression::ArrayAppend(f)
2891            | Expression::ArrayPrepend(f)
2892            | Expression::ArrayUnion(f)
2893            | Expression::ArrayExcept(f)
2894            | Expression::ArrayRemove(f)
2895            | Expression::StarMap(f)
2896            | Expression::MapFromArrays(f)
2897            | Expression::MapContainsKey(f)
2898            | Expression::ElementAt(f)
2899            | Expression::JsonMergePatch(f)
2900            | Expression::JSONBContains(f)
2901            | Expression::JSONBExtract(f) => Some(&f.this),
2902            // AggFunc - this is the primary child
2903            Expression::Sum(af)
2904            | Expression::Avg(af)
2905            | Expression::Min(af)
2906            | Expression::Max(af)
2907            | Expression::ArrayAgg(af)
2908            | Expression::CountIf(af)
2909            | Expression::Stddev(af)
2910            | Expression::StddevPop(af)
2911            | Expression::StddevSamp(af)
2912            | Expression::Variance(af)
2913            | Expression::VarPop(af)
2914            | Expression::VarSamp(af)
2915            | Expression::Median(af)
2916            | Expression::Mode(af)
2917            | Expression::First(af)
2918            | Expression::Last(af)
2919            | Expression::AnyValue(af)
2920            | Expression::ApproxDistinct(af)
2921            | Expression::ApproxCountDistinct(af)
2922            | Expression::LogicalAnd(af)
2923            | Expression::LogicalOr(af)
2924            | Expression::Skewness(af)
2925            | Expression::ArrayConcatAgg(af)
2926            | Expression::ArrayUniqueAgg(af)
2927            | Expression::BoolXorAgg(af)
2928            | Expression::BitwiseAndAgg(af)
2929            | Expression::BitwiseOrAgg(af)
2930            | Expression::BitwiseXorAgg(af) => Some(&af.this),
2931            // Binary operations - left is "this" in sqlglot
2932            Expression::And(op)
2933            | Expression::Or(op)
2934            | Expression::Add(op)
2935            | Expression::Sub(op)
2936            | Expression::Mul(op)
2937            | Expression::Div(op)
2938            | Expression::Mod(op)
2939            | Expression::Eq(op)
2940            | Expression::Neq(op)
2941            | Expression::Lt(op)
2942            | Expression::Lte(op)
2943            | Expression::Gt(op)
2944            | Expression::Gte(op)
2945            | Expression::BitwiseAnd(op)
2946            | Expression::BitwiseOr(op)
2947            | Expression::BitwiseXor(op)
2948            | Expression::Concat(op)
2949            | Expression::Adjacent(op)
2950            | Expression::TsMatch(op)
2951            | Expression::PropertyEQ(op)
2952            | Expression::ArrayContainsAll(op)
2953            | Expression::ArrayContainedBy(op)
2954            | Expression::ArrayOverlaps(op)
2955            | Expression::JSONBContainsAllTopKeys(op)
2956            | Expression::JSONBContainsAnyTopKeys(op)
2957            | Expression::JSONBDeleteAtPath(op)
2958            | Expression::ExtendsLeft(op)
2959            | Expression::ExtendsRight(op)
2960            | Expression::Is(op)
2961            | Expression::MemberOf(op)
2962            | Expression::Match(op)
2963            | Expression::NullSafeEq(op)
2964            | Expression::NullSafeNeq(op)
2965            | Expression::Glob(op)
2966            | Expression::BitwiseLeftShift(op)
2967            | Expression::BitwiseRightShift(op) => Some(&op.left),
2968            // Like operations - left is "this"
2969            Expression::Like(op) | Expression::ILike(op) => Some(&op.left),
2970            // Structural types with .this
2971            Expression::Alias(a) => Some(&a.this),
2972            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => Some(&c.this),
2973            Expression::Paren(p) => Some(&p.this),
2974            Expression::Annotated(a) => Some(&a.this),
2975            Expression::Subquery(s) => Some(&s.this),
2976            Expression::Where(w) => Some(&w.this),
2977            Expression::Having(h) => Some(&h.this),
2978            Expression::Qualify(q) => Some(&q.this),
2979            Expression::IsNull(i) => Some(&i.this),
2980            Expression::Exists(e) => Some(&e.this),
2981            Expression::Ordered(o) => Some(&o.this),
2982            Expression::WindowFunction(wf) => Some(&wf.this),
2983            Expression::Cte(cte) => Some(&cte.this),
2984            Expression::Between(b) => Some(&b.this),
2985            Expression::In(i) => Some(&i.this),
2986            Expression::ReturnStmt(e) => Some(e),
2987            _ => None,
2988        }
2989    }
2990
2991    /// Returns the secondary child expression (".expression" in sqlglot).
2992    pub fn get_expression(&self) -> Option<&Expression> {
2993        match self {
2994            // Binary operations - right is "expression"
2995            Expression::And(op)
2996            | Expression::Or(op)
2997            | Expression::Add(op)
2998            | Expression::Sub(op)
2999            | Expression::Mul(op)
3000            | Expression::Div(op)
3001            | Expression::Mod(op)
3002            | Expression::Eq(op)
3003            | Expression::Neq(op)
3004            | Expression::Lt(op)
3005            | Expression::Lte(op)
3006            | Expression::Gt(op)
3007            | Expression::Gte(op)
3008            | Expression::BitwiseAnd(op)
3009            | Expression::BitwiseOr(op)
3010            | Expression::BitwiseXor(op)
3011            | Expression::Concat(op)
3012            | Expression::Adjacent(op)
3013            | Expression::TsMatch(op)
3014            | Expression::PropertyEQ(op)
3015            | Expression::ArrayContainsAll(op)
3016            | Expression::ArrayContainedBy(op)
3017            | Expression::ArrayOverlaps(op)
3018            | Expression::JSONBContainsAllTopKeys(op)
3019            | Expression::JSONBContainsAnyTopKeys(op)
3020            | Expression::JSONBDeleteAtPath(op)
3021            | Expression::ExtendsLeft(op)
3022            | Expression::ExtendsRight(op)
3023            | Expression::Is(op)
3024            | Expression::MemberOf(op)
3025            | Expression::Match(op)
3026            | Expression::NullSafeEq(op)
3027            | Expression::NullSafeNeq(op)
3028            | Expression::Glob(op)
3029            | Expression::BitwiseLeftShift(op)
3030            | Expression::BitwiseRightShift(op) => Some(&op.right),
3031            // Like operations - right is "expression"
3032            Expression::Like(op) | Expression::ILike(op) => Some(&op.right),
3033            // BinaryFunc - expression is the secondary
3034            Expression::Power(f)
3035            | Expression::NullIf(f)
3036            | Expression::IfNull(f)
3037            | Expression::Nvl(f)
3038            | Expression::Contains(f)
3039            | Expression::StartsWith(f)
3040            | Expression::EndsWith(f)
3041            | Expression::Levenshtein(f)
3042            | Expression::ModFunc(f)
3043            | Expression::IntDiv(f)
3044            | Expression::Atan2(f)
3045            | Expression::AddMonths(f)
3046            | Expression::MonthsBetween(f)
3047            | Expression::NextDay(f)
3048            | Expression::UnixToTimeStr(f)
3049            | Expression::ArrayContains(f)
3050            | Expression::ArrayPosition(f)
3051            | Expression::ArrayAppend(f)
3052            | Expression::ArrayPrepend(f)
3053            | Expression::ArrayUnion(f)
3054            | Expression::ArrayExcept(f)
3055            | Expression::ArrayRemove(f)
3056            | Expression::StarMap(f)
3057            | Expression::MapFromArrays(f)
3058            | Expression::MapContainsKey(f)
3059            | Expression::ElementAt(f)
3060            | Expression::JsonMergePatch(f)
3061            | Expression::JSONBContains(f)
3062            | Expression::JSONBExtract(f) => Some(&f.expression),
3063            _ => None,
3064        }
3065    }
3066
3067    /// Returns the list of child expressions (".expressions" in sqlglot).
3068    pub fn get_expressions(&self) -> &[Expression] {
3069        match self {
3070            Expression::Select(s) => &s.expressions,
3071            Expression::Function(f) => &f.args,
3072            Expression::AggregateFunction(f) => &f.args,
3073            Expression::From(f) => &f.expressions,
3074            Expression::GroupBy(g) => &g.expressions,
3075            Expression::In(i) => &i.expressions,
3076            Expression::Array(a) => &a.expressions,
3077            Expression::ArrayFunc(a) => &a.expressions,
3078            Expression::Tuple(t) => &t.expressions,
3079            Expression::Coalesce(f)
3080            | Expression::Greatest(f)
3081            | Expression::Least(f)
3082            | Expression::ArrayConcat(f)
3083            | Expression::ArrayIntersect(f)
3084            | Expression::ArrayZip(f)
3085            | Expression::MapConcat(f)
3086            | Expression::JsonArray(f) => &f.expressions,
3087            _ => &[],
3088        }
3089    }
3090
3091    /// Returns the name of this expression as a string slice.
3092    pub fn get_name(&self) -> &str {
3093        match self {
3094            Expression::Identifier(id) => &id.name,
3095            Expression::Column(col) => &col.name.name,
3096            Expression::Table(t) => &t.name.name,
3097            Expression::Literal(lit) => lit.value_str(),
3098            Expression::Star(_) => "*",
3099            Expression::Function(f) => &f.name,
3100            Expression::AggregateFunction(f) => &f.name,
3101            Expression::Alias(a) => a.this.get_name(),
3102            Expression::Boolean(b) => {
3103                if b.value {
3104                    "TRUE"
3105                } else {
3106                    "FALSE"
3107                }
3108            }
3109            Expression::Null(_) => "NULL",
3110            _ => "",
3111        }
3112    }
3113
3114    /// Returns the alias name if this expression has one.
3115    pub fn get_alias(&self) -> &str {
3116        match self {
3117            Expression::Alias(a) => &a.alias.name,
3118            Expression::Table(t) => t.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3119            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3120            _ => "",
3121        }
3122    }
3123
3124    /// Returns the output name of this expression (what it shows up as in a SELECT).
3125    pub fn get_output_name(&self) -> &str {
3126        match self {
3127            Expression::Alias(a) => &a.alias.name,
3128            Expression::Column(c) => &c.name.name,
3129            Expression::Identifier(id) => &id.name,
3130            Expression::Literal(lit) => lit.value_str(),
3131            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3132            Expression::Star(_) => "*",
3133            _ => "",
3134        }
3135    }
3136
3137    /// Returns comments attached to this expression.
3138    pub fn get_comments(&self) -> Vec<&str> {
3139        match self {
3140            Expression::Identifier(id) => id.trailing_comments.iter().map(|s| s.as_str()).collect(),
3141            Expression::Column(c) => c.trailing_comments.iter().map(|s| s.as_str()).collect(),
3142            Expression::Star(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3143            Expression::Paren(p) => p.trailing_comments.iter().map(|s| s.as_str()).collect(),
3144            Expression::Annotated(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3145            Expression::Alias(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3146            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
3147                c.trailing_comments.iter().map(|s| s.as_str()).collect()
3148            }
3149            Expression::And(op)
3150            | Expression::Or(op)
3151            | Expression::Add(op)
3152            | Expression::Sub(op)
3153            | Expression::Mul(op)
3154            | Expression::Div(op)
3155            | Expression::Mod(op)
3156            | Expression::Eq(op)
3157            | Expression::Neq(op)
3158            | Expression::Lt(op)
3159            | Expression::Lte(op)
3160            | Expression::Gt(op)
3161            | Expression::Gte(op)
3162            | Expression::Concat(op)
3163            | Expression::BitwiseAnd(op)
3164            | Expression::BitwiseOr(op)
3165            | Expression::BitwiseXor(op) => {
3166                op.trailing_comments.iter().map(|s| s.as_str()).collect()
3167            }
3168            Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(),
3169            Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3170            _ => Vec::new(),
3171        }
3172    }
3173}
3174
3175impl fmt::Display for Expression {
3176    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3177        // Basic display - full SQL generation is in generator module
3178        match self {
3179            Expression::Literal(lit) => write!(f, "{}", lit),
3180            Expression::Identifier(id) => write!(f, "{}", id),
3181            Expression::Column(col) => write!(f, "{}", col),
3182            Expression::Star(_) => write!(f, "*"),
3183            Expression::Null(_) => write!(f, "NULL"),
3184            Expression::Boolean(b) => write!(f, "{}", if b.value { "TRUE" } else { "FALSE" }),
3185            Expression::Select(_) => write!(f, "SELECT ..."),
3186            _ => write!(f, "{:?}", self),
3187        }
3188    }
3189}
3190
3191/// Represent a SQL literal value.
3192///
3193/// Numeric values are stored as their original text representation (not parsed
3194/// to `i64`/`f64`) so that precision, trailing zeros, and hex notation are
3195/// preserved across round-trips.
3196///
3197/// Dialect-specific literal forms (triple-quoted strings, dollar-quoted
3198/// strings, raw strings, etc.) each have a dedicated variant so that the
3199/// generator can emit them with the correct syntax.
3200#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3201#[cfg_attr(feature = "bindings", derive(TS))]
3202#[serde(tag = "literal_type", content = "value", rename_all = "snake_case")]
3203pub enum Literal {
3204    /// Single-quoted string literal: `'hello'`
3205    String(String),
3206    /// Numeric literal, stored as the original text: `42`, `3.14`, `1e10`
3207    Number(String),
3208    /// Hex string literal: `X'FF'`
3209    HexString(String),
3210    /// Hex number: 0xA, 0xFF (BigQuery, SQLite style) - represents an integer in hex notation
3211    HexNumber(String),
3212    BitString(String),
3213    /// Byte string: b"..." (BigQuery style)
3214    ByteString(String),
3215    /// National string: N'abc'
3216    NationalString(String),
3217    /// DATE literal: DATE '2024-01-15'
3218    Date(String),
3219    /// TIME literal: TIME '10:30:00'
3220    Time(String),
3221    /// TIMESTAMP literal: TIMESTAMP '2024-01-15 10:30:00'
3222    Timestamp(String),
3223    /// DATETIME literal: DATETIME '2024-01-15 10:30:00' (BigQuery)
3224    Datetime(String),
3225    /// Triple-quoted string: """...""" or '''...'''
3226    /// Contains (content, quote_char) where quote_char is '"' or '\''
3227    TripleQuotedString(String, char),
3228    /// Escape string: E'...' (PostgreSQL)
3229    EscapeString(String),
3230    /// Dollar-quoted string: $$...$$  (PostgreSQL)
3231    DollarString(String),
3232    /// Raw string: r"..." or r'...' (BigQuery, Spark, Databricks)
3233    /// In raw strings, backslashes are literal and not escape characters.
3234    /// When converting to a regular string, backslashes must be doubled.
3235    RawString(String),
3236}
3237
3238impl Literal {
3239    /// Returns the inner value as a string slice, regardless of literal type.
3240    pub fn value_str(&self) -> &str {
3241        match self {
3242            Literal::String(s)
3243            | Literal::Number(s)
3244            | Literal::HexString(s)
3245            | Literal::HexNumber(s)
3246            | Literal::BitString(s)
3247            | Literal::ByteString(s)
3248            | Literal::NationalString(s)
3249            | Literal::Date(s)
3250            | Literal::Time(s)
3251            | Literal::Timestamp(s)
3252            | Literal::Datetime(s)
3253            | Literal::EscapeString(s)
3254            | Literal::DollarString(s)
3255            | Literal::RawString(s) => s.as_str(),
3256            Literal::TripleQuotedString(s, _) => s.as_str(),
3257        }
3258    }
3259
3260    /// Returns `true` if this is a string-type literal.
3261    pub fn is_string(&self) -> bool {
3262        matches!(
3263            self,
3264            Literal::String(_)
3265                | Literal::NationalString(_)
3266                | Literal::EscapeString(_)
3267                | Literal::DollarString(_)
3268                | Literal::RawString(_)
3269                | Literal::TripleQuotedString(_, _)
3270        )
3271    }
3272
3273    /// Returns `true` if this is a numeric literal.
3274    pub fn is_number(&self) -> bool {
3275        matches!(self, Literal::Number(_) | Literal::HexNumber(_))
3276    }
3277}
3278
3279impl fmt::Display for Literal {
3280    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3281        match self {
3282            Literal::String(s) => write!(f, "'{}'", s),
3283            Literal::Number(n) => write!(f, "{}", n),
3284            Literal::HexString(h) => write!(f, "X'{}'", h),
3285            Literal::HexNumber(h) => write!(f, "0x{}", h),
3286            Literal::BitString(b) => write!(f, "B'{}'", b),
3287            Literal::ByteString(b) => write!(f, "b'{}'", b),
3288            Literal::NationalString(s) => write!(f, "N'{}'", s),
3289            Literal::Date(d) => write!(f, "DATE '{}'", d),
3290            Literal::Time(t) => write!(f, "TIME '{}'", t),
3291            Literal::Timestamp(ts) => write!(f, "TIMESTAMP '{}'", ts),
3292            Literal::Datetime(dt) => write!(f, "DATETIME '{}'", dt),
3293            Literal::TripleQuotedString(s, q) => {
3294                write!(f, "{0}{0}{0}{1}{0}{0}{0}", q, s)
3295            }
3296            Literal::EscapeString(s) => write!(f, "E'{}'", s),
3297            Literal::DollarString(s) => write!(f, "$${}$$", s),
3298            Literal::RawString(s) => write!(f, "r'{}'", s),
3299        }
3300    }
3301}
3302
3303/// Boolean literal
3304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3305#[cfg_attr(feature = "bindings", derive(TS))]
3306pub struct BooleanLiteral {
3307    pub value: bool,
3308}
3309
3310/// NULL literal
3311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3312#[cfg_attr(feature = "bindings", derive(TS))]
3313pub struct Null;
3314
3315/// Represent a SQL identifier (table name, column name, alias, keyword-as-name, etc.).
3316///
3317/// The `quoted` flag indicates whether the identifier was originally delimited
3318/// (double-quoted, backtick-quoted, or bracket-quoted depending on the
3319/// dialect). The generator uses this flag to decide whether to emit quoting
3320/// characters.
3321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, Serialize, Deserialize)]
3322#[cfg_attr(feature = "bindings", derive(TS))]
3323pub struct Identifier {
3324    /// The raw text of the identifier, without any quoting characters.
3325    pub name: String,
3326    /// Whether the identifier was quoted in the source SQL.
3327    pub quoted: bool,
3328    #[serde(default)]
3329    pub trailing_comments: Vec<String>,
3330    /// Original source range, including quoting delimiters. Absent for synthetic
3331    /// or programmatically constructed identifiers. Not part of structural equality.
3332    #[serde(default, skip_serializing_if = "Option::is_none")]
3333    pub span: Option<Span>,
3334}
3335
3336impl PartialEq for Identifier {
3337    fn eq(&self, other: &Self) -> bool {
3338        self.name == other.name
3339            && self.quoted == other.quoted
3340            && self.trailing_comments == other.trailing_comments
3341    }
3342}
3343
3344impl Identifier {
3345    pub fn new(name: impl Into<String>) -> Self {
3346        Self {
3347            name: name.into(),
3348            quoted: false,
3349            trailing_comments: Vec::new(),
3350            span: None,
3351        }
3352    }
3353
3354    pub fn quoted(name: impl Into<String>) -> Self {
3355        Self {
3356            name: name.into(),
3357            quoted: true,
3358            trailing_comments: Vec::new(),
3359            span: None,
3360        }
3361    }
3362
3363    pub fn empty() -> Self {
3364        Self {
3365            name: String::new(),
3366            quoted: false,
3367            trailing_comments: Vec::new(),
3368            span: None,
3369        }
3370    }
3371
3372    pub fn is_empty(&self) -> bool {
3373        self.name.is_empty()
3374    }
3375
3376    /// Set the source span on this identifier
3377    pub fn with_span(mut self, span: Span) -> Self {
3378        self.span = Some(span);
3379        self
3380    }
3381}
3382
3383impl fmt::Display for Identifier {
3384    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3385        if self.quoted {
3386            write!(f, "\"{}\"", self.name)
3387        } else {
3388            write!(f, "{}", self.name)
3389        }
3390    }
3391}
3392
3393/// Represent a column reference, optionally qualified by a table name.
3394///
3395/// Renders as `name` when unqualified, or `table.name` when qualified.
3396/// Use [`Expression::column()`] or [`Expression::qualified_column()`] for
3397/// convenient construction.
3398#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, Serialize, Deserialize)]
3399#[cfg_attr(feature = "bindings", derive(TS))]
3400pub struct Column {
3401    /// The column name.
3402    pub name: Identifier,
3403    /// Optional table qualifier (e.g. `t` in `t.col`).
3404    pub table: Option<Identifier>,
3405    /// Oracle-style join marker (+) for outer joins
3406    #[serde(default)]
3407    pub join_mark: bool,
3408    /// Trailing comments that appeared after this column reference
3409    #[serde(default)]
3410    pub trailing_comments: Vec<String>,
3411    /// Original column-reference range, including its qualifier when present.
3412    /// Absent for synthetic references. Not part of structural equality.
3413    #[serde(default, skip_serializing_if = "Option::is_none")]
3414    pub span: Option<Span>,
3415    /// Inferred data type from type annotation
3416    #[serde(default, skip_serializing_if = "Option::is_none")]
3417    #[ast(skip)]
3418    pub inferred_type: Option<DataType>,
3419}
3420
3421impl PartialEq for Column {
3422    fn eq(&self, other: &Self) -> bool {
3423        self.name == other.name
3424            && self.table == other.table
3425            && self.join_mark == other.join_mark
3426            && self.trailing_comments == other.trailing_comments
3427            && self.inferred_type == other.inferred_type
3428    }
3429}
3430
3431impl fmt::Display for Column {
3432    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3433        if let Some(table) = &self.table {
3434            write!(f, "{}.{}", table, self.name)
3435        } else {
3436            write!(f, "{}", self.name)
3437        }
3438    }
3439}
3440
3441/// Represent a table reference with optional schema and catalog qualifiers.
3442///
3443/// Renders as `name`, `schema.name`, or `catalog.schema.name` depending on
3444/// which qualifiers are present. Supports aliases, column alias lists,
3445/// time-travel clauses (Snowflake, BigQuery), table hints (TSQL), and
3446/// several other dialect-specific extensions.
3447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3448#[cfg_attr(feature = "bindings", derive(TS))]
3449pub struct TableRef {
3450    /// The unqualified table name.
3451    pub name: Identifier,
3452    /// Optional schema qualifier (e.g. `public` in `public.users`).
3453    pub schema: Option<Identifier>,
3454    /// Optional catalog qualifier (e.g. `mydb` in `mydb.public.users`).
3455    pub catalog: Option<Identifier>,
3456    /// Optional table alias (e.g. `t` in `FROM users AS t`).
3457    pub alias: Option<Identifier>,
3458    /// Whether AS keyword was explicitly used for the alias
3459    #[serde(default)]
3460    pub alias_explicit_as: bool,
3461    /// Column aliases for table alias: AS t(c1, c2)
3462    #[serde(default)]
3463    pub column_aliases: Vec<Identifier>,
3464    /// Leading comments that appeared before this table reference in a FROM clause
3465    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3466    pub leading_comments: Vec<String>,
3467    /// Trailing comments that appeared after this table reference
3468    #[serde(default)]
3469    pub trailing_comments: Vec<String>,
3470    /// Snowflake time travel: BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
3471    #[serde(default)]
3472    pub when: Option<Box<HistoricalData>>,
3473    /// PostgreSQL ONLY modifier: prevents scanning child tables in inheritance hierarchy
3474    #[serde(default)]
3475    pub only: bool,
3476    /// ClickHouse FINAL modifier: forces final aggregation for MergeTree tables
3477    #[serde(default)]
3478    pub final_: bool,
3479    /// TABLESAMPLE clause attached to this table reference (DuckDB, BigQuery)
3480    #[serde(default, skip_serializing_if = "Option::is_none")]
3481    pub table_sample: Option<Box<Sample>>,
3482    /// TSQL table hints: WITH (TABLOCK, INDEX(myindex), ...)
3483    #[serde(default)]
3484    pub hints: Vec<Expression>,
3485    /// TSQL: FOR SYSTEM_TIME temporal clause
3486    /// Contains the full clause text, e.g., "FOR SYSTEM_TIME BETWEEN c AND d"
3487    #[serde(default, skip_serializing_if = "Option::is_none")]
3488    pub system_time: Option<String>,
3489    /// MySQL: PARTITION(p0, p1, ...) hint for reading from specific partitions
3490    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3491    pub partitions: Vec<Identifier>,
3492    /// Snowflake IDENTIFIER() function: dynamic table name from string/variable
3493    /// When set, this is used instead of the name field
3494    #[serde(default, skip_serializing_if = "Option::is_none")]
3495    pub identifier_func: Option<Box<Expression>>,
3496    /// Snowflake CHANGES clause: CHANGES (INFORMATION => ...) AT (...) END (...)
3497    #[serde(default, skip_serializing_if = "Option::is_none")]
3498    pub changes: Option<Box<Changes>>,
3499    /// Time travel version clause: FOR VERSION AS OF / FOR TIMESTAMP AS OF (Presto/Trino, BigQuery, Databricks)
3500    #[serde(default, skip_serializing_if = "Option::is_none")]
3501    pub version: Option<Box<Version>>,
3502    /// Source position span
3503    #[serde(default, skip_serializing_if = "Option::is_none")]
3504    pub span: Option<Span>,
3505}
3506
3507impl TableRef {
3508    pub fn new(name: impl Into<String>) -> Self {
3509        Self {
3510            name: Identifier::new(name),
3511            schema: None,
3512            catalog: None,
3513            alias: None,
3514            alias_explicit_as: false,
3515            column_aliases: Vec::new(),
3516            leading_comments: Vec::new(),
3517            trailing_comments: Vec::new(),
3518            when: None,
3519            only: false,
3520            final_: false,
3521            table_sample: None,
3522            hints: Vec::new(),
3523            system_time: None,
3524            partitions: Vec::new(),
3525            identifier_func: None,
3526            changes: None,
3527            version: None,
3528            span: None,
3529        }
3530    }
3531
3532    /// Create with a schema qualifier.
3533    pub fn new_with_schema(name: impl Into<String>, schema: impl Into<String>) -> Self {
3534        let mut t = Self::new(name);
3535        t.schema = Some(Identifier::new(schema));
3536        t
3537    }
3538
3539    /// Create with catalog and schema qualifiers.
3540    pub fn new_with_catalog(
3541        name: impl Into<String>,
3542        schema: impl Into<String>,
3543        catalog: impl Into<String>,
3544    ) -> Self {
3545        let mut t = Self::new(name);
3546        t.schema = Some(Identifier::new(schema));
3547        t.catalog = Some(Identifier::new(catalog));
3548        t
3549    }
3550
3551    /// Create from an Identifier, preserving the quoted flag
3552    pub fn from_identifier(name: Identifier) -> Self {
3553        Self {
3554            name,
3555            schema: None,
3556            catalog: None,
3557            alias: None,
3558            alias_explicit_as: false,
3559            column_aliases: Vec::new(),
3560            leading_comments: Vec::new(),
3561            trailing_comments: Vec::new(),
3562            when: None,
3563            only: false,
3564            final_: false,
3565            table_sample: None,
3566            hints: Vec::new(),
3567            system_time: None,
3568            partitions: Vec::new(),
3569            identifier_func: None,
3570            changes: None,
3571            version: None,
3572            span: None,
3573        }
3574    }
3575
3576    pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
3577        self.alias = Some(Identifier::new(alias));
3578        self
3579    }
3580
3581    pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
3582        self.schema = Some(Identifier::new(schema));
3583        self
3584    }
3585}
3586
3587/// Represent a wildcard star expression (`*`, `table.*`).
3588///
3589/// Supports the EXCEPT/EXCLUDE, REPLACE, and RENAME modifiers found in
3590/// DuckDB, BigQuery, and Snowflake (e.g. `SELECT * EXCEPT (id) FROM t`).
3591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3592#[cfg_attr(feature = "bindings", derive(TS))]
3593pub struct Star {
3594    /// Optional table qualifier (e.g. `t` in `t.*`).
3595    pub table: Option<Identifier>,
3596    /// EXCLUDE / EXCEPT columns (DuckDB, BigQuery, Snowflake)
3597    pub except: Option<Vec<Identifier>>,
3598    /// REPLACE expressions (BigQuery, Snowflake)
3599    pub replace: Option<Vec<Alias>>,
3600    /// RENAME columns (Snowflake)
3601    pub rename: Option<Vec<(Identifier, Identifier)>>,
3602    /// Trailing comments that appeared after the star
3603    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3604    pub trailing_comments: Vec<String>,
3605    /// Source position span
3606    #[serde(default, skip_serializing_if = "Option::is_none")]
3607    pub span: Option<Span>,
3608}
3609
3610/// Represent a complete SELECT statement.
3611///
3612/// This is the most feature-rich AST node, covering the full surface area of
3613/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3614/// `Vec` are omitted from the generated SQL when absent.
3615///
3616/// # Key Fields
3617///
3618/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3619/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3620/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3621/// - `where_clause` -- the WHERE predicate.
3622/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3623/// - `having` -- HAVING predicate.
3624/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3625/// - `limit` / `offset` / `fetch` -- result set limiting.
3626/// - `with` -- Common Table Expressions (CTEs).
3627/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3628/// - `windows` -- named window definitions (WINDOW w AS ...).
3629///
3630/// Dialect-specific extensions are supported via fields like `prewhere`
3631/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3632/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3633#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3634#[cfg_attr(feature = "bindings", derive(TS))]
3635pub struct Select {
3636    /// The select-list: columns, expressions, aliases, and wildcards.
3637    pub expressions: Vec<Expression>,
3638    /// The FROM clause, containing one or more table sources.
3639    pub from: Option<From>,
3640    /// JOIN clauses applied after the FROM source.
3641    pub joins: Vec<Join>,
3642    pub lateral_views: Vec<LateralView>,
3643    /// ClickHouse PREWHERE clause
3644    #[serde(default, skip_serializing_if = "Option::is_none")]
3645    pub prewhere: Option<Expression>,
3646    pub where_clause: Option<Where>,
3647    pub group_by: Option<GroupBy>,
3648    pub having: Option<Having>,
3649    pub qualify: Option<Qualify>,
3650    pub order_by: Option<OrderBy>,
3651    pub distribute_by: Option<DistributeBy>,
3652    pub cluster_by: Option<ClusterBy>,
3653    pub sort_by: Option<SortBy>,
3654    pub limit: Option<Limit>,
3655    pub offset: Option<Offset>,
3656    /// ClickHouse LIMIT BY clause expressions
3657    #[serde(default, skip_serializing_if = "Option::is_none")]
3658    pub limit_by: Option<Vec<Expression>>,
3659    pub fetch: Option<Fetch>,
3660    pub distinct: bool,
3661    pub distinct_on: Option<Vec<Expression>>,
3662    pub top: Option<Top>,
3663    pub with: Option<With>,
3664    pub sample: Option<Sample>,
3665    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3666    #[serde(default, skip_serializing_if = "Option::is_none")]
3667    pub settings: Option<Vec<Expression>>,
3668    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3669    #[serde(default, skip_serializing_if = "Option::is_none")]
3670    pub format: Option<Expression>,
3671    pub windows: Option<Vec<NamedWindow>>,
3672    pub hint: Option<Hint>,
3673    /// Oracle CONNECT BY clause for hierarchical queries
3674    pub connect: Option<Connect>,
3675    /// SELECT ... INTO table_name for creating tables
3676    pub into: Option<SelectInto>,
3677    /// FOR UPDATE/SHARE locking clauses
3678    #[serde(default)]
3679    pub locks: Vec<Lock>,
3680    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3681    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3682    pub for_xml: Vec<Expression>,
3683    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3684    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3685    pub for_json: Vec<Expression>,
3686    /// Leading comments before the statement
3687    #[serde(default)]
3688    pub leading_comments: Vec<String>,
3689    /// Comments that appear after SELECT keyword (before expressions)
3690    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3691    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3692    pub post_select_comments: Vec<String>,
3693    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3694    #[serde(default, skip_serializing_if = "Option::is_none")]
3695    pub kind: Option<String>,
3696    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3697    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3698    pub operation_modifiers: Vec<String>,
3699    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3700    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3701    pub qualify_after_window: bool,
3702    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3703    #[serde(default, skip_serializing_if = "Option::is_none")]
3704    pub option: Option<String>,
3705    /// Redshift-style EXCLUDE clause at the end of the projection list
3706    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3707    #[serde(default, skip_serializing_if = "Option::is_none")]
3708    pub exclude: Option<Vec<Expression>>,
3709}
3710
3711impl Select {
3712    pub fn new() -> Self {
3713        Self {
3714            expressions: Vec::new(),
3715            from: None,
3716            joins: Vec::new(),
3717            lateral_views: Vec::new(),
3718            prewhere: None,
3719            where_clause: None,
3720            group_by: None,
3721            having: None,
3722            qualify: None,
3723            order_by: None,
3724            distribute_by: None,
3725            cluster_by: None,
3726            sort_by: None,
3727            limit: None,
3728            offset: None,
3729            limit_by: None,
3730            fetch: None,
3731            distinct: false,
3732            distinct_on: None,
3733            top: None,
3734            with: None,
3735            sample: None,
3736            settings: None,
3737            format: None,
3738            windows: None,
3739            hint: None,
3740            connect: None,
3741            into: None,
3742            locks: Vec::new(),
3743            for_xml: Vec::new(),
3744            for_json: Vec::new(),
3745            leading_comments: Vec::new(),
3746            post_select_comments: Vec::new(),
3747            kind: None,
3748            operation_modifiers: Vec::new(),
3749            qualify_after_window: false,
3750            option: None,
3751            exclude: None,
3752        }
3753    }
3754
3755    /// Add a column to select
3756    pub fn column(mut self, expr: Expression) -> Self {
3757        self.expressions.push(expr);
3758        self
3759    }
3760
3761    /// Set the FROM clause
3762    pub fn from(mut self, table: Expression) -> Self {
3763        self.from = Some(From {
3764            expressions: vec![table],
3765        });
3766        self
3767    }
3768
3769    /// Add a WHERE clause
3770    pub fn where_(mut self, condition: Expression) -> Self {
3771        self.where_clause = Some(Where { this: condition });
3772        self
3773    }
3774
3775    /// Set DISTINCT
3776    pub fn distinct(mut self) -> Self {
3777        self.distinct = true;
3778        self
3779    }
3780
3781    /// Add a JOIN
3782    pub fn join(mut self, join: Join) -> Self {
3783        self.joins.push(join);
3784        self
3785    }
3786
3787    /// Set ORDER BY
3788    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
3789        self.order_by = Some(OrderBy {
3790            expressions,
3791            siblings: false,
3792            comments: Vec::new(),
3793        });
3794        self
3795    }
3796
3797    /// Set LIMIT
3798    pub fn limit(mut self, n: Expression) -> Self {
3799        self.limit = Some(Limit {
3800            this: n,
3801            percent: false,
3802            comments: Vec::new(),
3803        });
3804        self
3805    }
3806
3807    /// Set OFFSET
3808    pub fn offset(mut self, n: Expression) -> Self {
3809        self.offset = Some(Offset {
3810            this: n,
3811            rows: None,
3812        });
3813        self
3814    }
3815}
3816
3817impl Default for Select {
3818    fn default() -> Self {
3819        Self::new()
3820    }
3821}
3822
3823/// Represent a UNION set operation between two query expressions.
3824///
3825/// When `all` is true, duplicate rows are preserved (UNION ALL).
3826/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
3827/// Supports DuckDB/Snowflake BY NAME and BigQuery BY NAME/CORRESPONDING modifiers.
3828#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3829#[cfg_attr(feature = "bindings", derive(TS))]
3830pub struct Union {
3831    /// The left-hand query operand.
3832    pub left: Expression,
3833    /// The right-hand query operand.
3834    pub right: Expression,
3835    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
3836    pub all: bool,
3837    /// Whether DISTINCT was explicitly specified
3838    #[serde(default)]
3839    pub distinct: bool,
3840    /// Optional WITH clause
3841    pub with: Option<With>,
3842    /// ORDER BY applied to entire UNION result
3843    pub order_by: Option<OrderBy>,
3844    /// LIMIT applied to entire UNION result
3845    pub limit: Option<Box<Expression>>,
3846    /// OFFSET applied to entire UNION result
3847    pub offset: Option<Box<Expression>>,
3848    /// DISTRIBUTE BY clause (Hive/Spark)
3849    #[serde(default, skip_serializing_if = "Option::is_none")]
3850    pub distribute_by: Option<DistributeBy>,
3851    /// SORT BY clause (Hive/Spark)
3852    #[serde(default, skip_serializing_if = "Option::is_none")]
3853    pub sort_by: Option<SortBy>,
3854    /// CLUSTER BY clause (Hive/Spark)
3855    #[serde(default, skip_serializing_if = "Option::is_none")]
3856    pub cluster_by: Option<ClusterBy>,
3857    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3858    #[serde(default)]
3859    pub by_name: bool,
3860    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3861    #[serde(default, skip_serializing_if = "Option::is_none")]
3862    pub side: Option<String>,
3863    /// BigQuery: Set operation kind (INNER)
3864    #[serde(default, skip_serializing_if = "Option::is_none")]
3865    pub kind: Option<String>,
3866    /// BigQuery: CORRESPONDING modifier
3867    #[serde(default)]
3868    pub corresponding: bool,
3869    /// BigQuery: STRICT modifier (before CORRESPONDING)
3870    #[serde(default)]
3871    pub strict: bool,
3872    /// BigQuery: BY (columns) after CORRESPONDING
3873    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3874    pub on_columns: Vec<Expression>,
3875}
3876
3877/// Iteratively flatten the left-recursive chain to prevent stack overflow
3878/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3879impl Drop for Union {
3880    fn drop(&mut self) {
3881        loop {
3882            if let Expression::Union(ref mut inner) = self.left {
3883                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3884                let old_left = std::mem::replace(&mut self.left, next_left);
3885                drop(old_left);
3886            } else {
3887                break;
3888            }
3889        }
3890    }
3891}
3892
3893/// Represent an INTERSECT set operation between two query expressions.
3894///
3895/// Returns only rows that appear in both operands. When `all` is true,
3896/// duplicates are preserved according to their multiplicity.
3897#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3898#[cfg_attr(feature = "bindings", derive(TS))]
3899pub struct Intersect {
3900    /// The left-hand query operand.
3901    pub left: Expression,
3902    /// The right-hand query operand.
3903    pub right: Expression,
3904    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
3905    pub all: bool,
3906    /// Whether DISTINCT was explicitly specified
3907    #[serde(default)]
3908    pub distinct: bool,
3909    /// Optional WITH clause
3910    pub with: Option<With>,
3911    /// ORDER BY applied to entire INTERSECT result
3912    pub order_by: Option<OrderBy>,
3913    /// LIMIT applied to entire INTERSECT result
3914    pub limit: Option<Box<Expression>>,
3915    /// OFFSET applied to entire INTERSECT result
3916    pub offset: Option<Box<Expression>>,
3917    /// DISTRIBUTE BY clause (Hive/Spark)
3918    #[serde(default, skip_serializing_if = "Option::is_none")]
3919    pub distribute_by: Option<DistributeBy>,
3920    /// SORT BY clause (Hive/Spark)
3921    #[serde(default, skip_serializing_if = "Option::is_none")]
3922    pub sort_by: Option<SortBy>,
3923    /// CLUSTER BY clause (Hive/Spark)
3924    #[serde(default, skip_serializing_if = "Option::is_none")]
3925    pub cluster_by: Option<ClusterBy>,
3926    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3927    #[serde(default)]
3928    pub by_name: bool,
3929    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3930    #[serde(default, skip_serializing_if = "Option::is_none")]
3931    pub side: Option<String>,
3932    /// BigQuery: Set operation kind (INNER)
3933    #[serde(default, skip_serializing_if = "Option::is_none")]
3934    pub kind: Option<String>,
3935    /// BigQuery: CORRESPONDING modifier
3936    #[serde(default)]
3937    pub corresponding: bool,
3938    /// BigQuery: STRICT modifier (before CORRESPONDING)
3939    #[serde(default)]
3940    pub strict: bool,
3941    /// BigQuery: BY (columns) after CORRESPONDING
3942    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3943    pub on_columns: Vec<Expression>,
3944}
3945
3946impl Drop for Intersect {
3947    fn drop(&mut self) {
3948        loop {
3949            if let Expression::Intersect(ref mut inner) = self.left {
3950                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3951                let old_left = std::mem::replace(&mut self.left, next_left);
3952                drop(old_left);
3953            } else {
3954                break;
3955            }
3956        }
3957    }
3958}
3959
3960/// Represent an EXCEPT (MINUS) set operation between two query expressions.
3961///
3962/// Returns rows from the left operand that do not appear in the right operand.
3963/// When `all` is true, duplicates are subtracted according to their multiplicity.
3964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3965#[cfg_attr(feature = "bindings", derive(TS))]
3966pub struct Except {
3967    /// The left-hand query operand.
3968    pub left: Expression,
3969    /// The right-hand query operand (rows to subtract).
3970    pub right: Expression,
3971    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
3972    pub all: bool,
3973    /// Whether DISTINCT was explicitly specified
3974    #[serde(default)]
3975    pub distinct: bool,
3976    /// Optional WITH clause
3977    pub with: Option<With>,
3978    /// ORDER BY applied to entire EXCEPT result
3979    pub order_by: Option<OrderBy>,
3980    /// LIMIT applied to entire EXCEPT result
3981    pub limit: Option<Box<Expression>>,
3982    /// OFFSET applied to entire EXCEPT result
3983    pub offset: Option<Box<Expression>>,
3984    /// DISTRIBUTE BY clause (Hive/Spark)
3985    #[serde(default, skip_serializing_if = "Option::is_none")]
3986    pub distribute_by: Option<DistributeBy>,
3987    /// SORT BY clause (Hive/Spark)
3988    #[serde(default, skip_serializing_if = "Option::is_none")]
3989    pub sort_by: Option<SortBy>,
3990    /// CLUSTER BY clause (Hive/Spark)
3991    #[serde(default, skip_serializing_if = "Option::is_none")]
3992    pub cluster_by: Option<ClusterBy>,
3993    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3994    #[serde(default)]
3995    pub by_name: bool,
3996    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3997    #[serde(default, skip_serializing_if = "Option::is_none")]
3998    pub side: Option<String>,
3999    /// BigQuery: Set operation kind (INNER)
4000    #[serde(default, skip_serializing_if = "Option::is_none")]
4001    pub kind: Option<String>,
4002    /// BigQuery: CORRESPONDING modifier
4003    #[serde(default)]
4004    pub corresponding: bool,
4005    /// BigQuery: STRICT modifier (before CORRESPONDING)
4006    #[serde(default)]
4007    pub strict: bool,
4008    /// BigQuery: BY (columns) after CORRESPONDING
4009    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4010    pub on_columns: Vec<Expression>,
4011}
4012
4013impl Drop for Except {
4014    fn drop(&mut self) {
4015        loop {
4016            if let Expression::Except(ref mut inner) = self.left {
4017                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4018                let old_left = std::mem::replace(&mut self.left, next_left);
4019                drop(old_left);
4020            } else {
4021                break;
4022            }
4023        }
4024    }
4025}
4026
4027/// INTO clause for SELECT INTO statements
4028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4029#[cfg_attr(feature = "bindings", derive(TS))]
4030pub struct SelectInto {
4031    /// Target table or variable (used when single target)
4032    pub this: Expression,
4033    /// Whether TEMPORARY keyword was used
4034    #[serde(default)]
4035    pub temporary: bool,
4036    /// Whether UNLOGGED keyword was used (PostgreSQL)
4037    #[serde(default)]
4038    pub unlogged: bool,
4039    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4040    #[serde(default)]
4041    pub bulk_collect: bool,
4042    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4043    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4044    pub expressions: Vec<Expression>,
4045}
4046
4047/// Represent a parenthesized subquery expression.
4048///
4049/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4050/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4051/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4052/// modifiers are rendered inside or outside the parentheses.
4053///
4054/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4055/// scalar subqueries in select-lists, and derived tables.
4056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4057#[cfg_attr(feature = "bindings", derive(TS))]
4058pub struct Subquery {
4059    /// The inner query expression.
4060    pub this: Expression,
4061    /// Optional alias for the derived table.
4062    pub alias: Option<Identifier>,
4063    /// Optional column aliases: AS t(c1, c2)
4064    pub column_aliases: Vec<Identifier>,
4065    /// Whether AS keyword was explicitly used for the alias.
4066    #[serde(default)]
4067    pub alias_explicit_as: bool,
4068    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4069    #[serde(skip_serializing_if = "Option::is_none", default)]
4070    pub alias_keyword: Option<String>,
4071    /// ORDER BY clause (for parenthesized queries)
4072    pub order_by: Option<OrderBy>,
4073    /// LIMIT clause
4074    pub limit: Option<Limit>,
4075    /// OFFSET clause
4076    pub offset: Option<Offset>,
4077    /// DISTRIBUTE BY clause (Hive/Spark)
4078    #[serde(default, skip_serializing_if = "Option::is_none")]
4079    pub distribute_by: Option<DistributeBy>,
4080    /// SORT BY clause (Hive/Spark)
4081    #[serde(default, skip_serializing_if = "Option::is_none")]
4082    pub sort_by: Option<SortBy>,
4083    /// CLUSTER BY clause (Hive/Spark)
4084    #[serde(default, skip_serializing_if = "Option::is_none")]
4085    pub cluster_by: Option<ClusterBy>,
4086    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4087    #[serde(default)]
4088    pub lateral: bool,
4089    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4090    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4091    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4092    #[serde(default)]
4093    pub modifiers_inside: bool,
4094    /// Trailing comments after the closing paren
4095    #[serde(default)]
4096    pub trailing_comments: Vec<String>,
4097    /// Inferred data type from type annotation
4098    #[serde(default, skip_serializing_if = "Option::is_none")]
4099    #[ast(skip)]
4100    pub inferred_type: Option<DataType>,
4101}
4102
4103/// Pipe operator expression: query |> transform
4104///
4105/// Used in DataFusion and BigQuery pipe syntax:
4106///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4107#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4108#[cfg_attr(feature = "bindings", derive(TS))]
4109pub struct PipeOperator {
4110    /// The input query/expression (left side of |>)
4111    pub this: Expression,
4112    /// The piped operation (right side of |>)
4113    pub expression: Expression,
4114}
4115
4116/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4118#[cfg_attr(feature = "bindings", derive(TS))]
4119pub struct Values {
4120    /// The rows of values
4121    pub expressions: Vec<Tuple>,
4122    /// Optional alias for the table
4123    pub alias: Option<Identifier>,
4124    /// Optional column aliases: AS t(c1, c2)
4125    pub column_aliases: Vec<Identifier>,
4126}
4127
4128/// PIVOT operation - supports both standard and DuckDB simplified syntax
4129///
4130/// Standard syntax (in FROM clause):
4131///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4132///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4133///
4134/// DuckDB simplified syntax (statement-level):
4135///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4136///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4137#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4138#[cfg_attr(feature = "bindings", derive(TS))]
4139pub struct Pivot {
4140    /// Source table/expression
4141    pub this: Expression,
4142    /// For standard PIVOT: the aggregation function(s) (first is primary)
4143    /// For DuckDB simplified: unused (use `using` instead)
4144    #[serde(default)]
4145    pub expressions: Vec<Expression>,
4146    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4147    #[serde(default)]
4148    pub fields: Vec<Expression>,
4149    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4150    #[serde(default)]
4151    pub using: Vec<Expression>,
4152    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4153    #[serde(default)]
4154    pub group: Option<Box<Expression>>,
4155    /// Whether this is an UNPIVOT (vs PIVOT)
4156    #[serde(default)]
4157    pub unpivot: bool,
4158    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4159    #[serde(default)]
4160    pub into: Option<Box<Expression>>,
4161    /// Optional alias
4162    #[serde(default)]
4163    pub alias: Option<Identifier>,
4164    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4165    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4166    pub alias_columns: Vec<Identifier>,
4167    /// Include/exclude nulls (for UNPIVOT)
4168    #[serde(default)]
4169    pub include_nulls: Option<bool>,
4170    /// Default on null value (Snowflake)
4171    #[serde(default)]
4172    pub default_on_null: Option<Box<Expression>>,
4173    /// WITH clause (CTEs)
4174    #[serde(default, skip_serializing_if = "Option::is_none")]
4175    pub with: Option<With>,
4176}
4177
4178/// UNPIVOT operation
4179#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4180#[cfg_attr(feature = "bindings", derive(TS))]
4181pub struct Unpivot {
4182    pub this: Expression,
4183    pub value_column: Identifier,
4184    pub name_column: Identifier,
4185    pub columns: Vec<Expression>,
4186    pub alias: Option<Identifier>,
4187    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4188    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4189    pub alias_columns: Vec<Identifier>,
4190    /// Whether the value_column was parenthesized in the original SQL
4191    #[serde(default)]
4192    pub value_column_parenthesized: bool,
4193    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4194    #[serde(default)]
4195    pub include_nulls: Option<bool>,
4196    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4197    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4198    pub extra_value_columns: Vec<Identifier>,
4199}
4200
4201/// PIVOT alias for aliasing pivot expressions
4202/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4203#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4204#[cfg_attr(feature = "bindings", derive(TS))]
4205pub struct PivotAlias {
4206    pub this: Expression,
4207    pub alias: Expression,
4208}
4209
4210/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4212#[cfg_attr(feature = "bindings", derive(TS))]
4213pub struct PreWhere {
4214    pub this: Expression,
4215}
4216
4217/// STREAM definition (Snowflake) - for change data capture
4218#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4219#[cfg_attr(feature = "bindings", derive(TS))]
4220pub struct Stream {
4221    pub this: Expression,
4222    #[serde(skip_serializing_if = "Option::is_none")]
4223    pub on: Option<Expression>,
4224    #[serde(skip_serializing_if = "Option::is_none")]
4225    pub show_initial_rows: Option<bool>,
4226}
4227
4228/// USING DATA clause for data import statements
4229#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4230#[cfg_attr(feature = "bindings", derive(TS))]
4231pub struct UsingData {
4232    pub this: Expression,
4233}
4234
4235/// XML Namespace declaration
4236#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4237#[cfg_attr(feature = "bindings", derive(TS))]
4238pub struct XmlNamespace {
4239    pub this: Expression,
4240    #[serde(skip_serializing_if = "Option::is_none")]
4241    pub alias: Option<Identifier>,
4242}
4243
4244/// ROW FORMAT clause for Hive/Spark
4245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4246#[cfg_attr(feature = "bindings", derive(TS))]
4247pub struct RowFormat {
4248    pub delimited: bool,
4249    pub fields_terminated_by: Option<String>,
4250    pub collection_items_terminated_by: Option<String>,
4251    pub map_keys_terminated_by: Option<String>,
4252    pub lines_terminated_by: Option<String>,
4253    pub null_defined_as: Option<String>,
4254}
4255
4256/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4258#[cfg_attr(feature = "bindings", derive(TS))]
4259pub struct DirectoryInsert {
4260    pub local: bool,
4261    pub path: String,
4262    pub row_format: Option<RowFormat>,
4263    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4264    #[serde(default)]
4265    pub stored_as: Option<String>,
4266}
4267
4268/// INSERT statement
4269#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4270#[cfg_attr(feature = "bindings", derive(TS))]
4271pub struct Insert {
4272    pub table: TableRef,
4273    pub columns: Vec<Identifier>,
4274    pub values: Vec<Vec<Expression>>,
4275    pub query: Option<Expression>,
4276    /// INSERT OVERWRITE for Hive/Spark
4277    pub overwrite: bool,
4278    /// PARTITION clause for Hive/Spark
4279    pub partition: Vec<(Identifier, Option<Expression>)>,
4280    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4281    #[serde(default)]
4282    pub directory: Option<DirectoryInsert>,
4283    /// RETURNING clause (PostgreSQL, SQLite)
4284    #[serde(default)]
4285    pub returning: Vec<Expression>,
4286    /// OUTPUT clause (TSQL)
4287    #[serde(default)]
4288    pub output: Option<OutputClause>,
4289    /// ON CONFLICT clause (PostgreSQL, SQLite)
4290    #[serde(default)]
4291    pub on_conflict: Option<Box<Expression>>,
4292    /// Leading comments before the statement
4293    #[serde(default)]
4294    pub leading_comments: Vec<String>,
4295    /// IF EXISTS clause (Hive)
4296    #[serde(default)]
4297    pub if_exists: bool,
4298    /// WITH clause (CTEs)
4299    #[serde(default)]
4300    pub with: Option<With>,
4301    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4302    #[serde(default)]
4303    pub ignore: bool,
4304    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4305    #[serde(default)]
4306    pub source_alias: Option<Identifier>,
4307    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4308    #[serde(default)]
4309    pub alias: Option<Identifier>,
4310    /// Whether the alias uses explicit AS keyword
4311    #[serde(default)]
4312    pub alias_explicit_as: bool,
4313    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4314    #[serde(default)]
4315    pub default_values: bool,
4316    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4317    #[serde(default)]
4318    pub by_name: bool,
4319    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4320    #[serde(default, skip_serializing_if = "Option::is_none")]
4321    pub conflict_action: Option<String>,
4322    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4323    #[serde(default)]
4324    pub is_replace: bool,
4325    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4326    #[serde(default, skip_serializing_if = "Option::is_none")]
4327    pub hint: Option<Hint>,
4328    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4329    #[serde(default)]
4330    pub replace_where: Option<Box<Expression>>,
4331    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4332    #[serde(default)]
4333    pub source: Option<Box<Expression>>,
4334    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4335    #[serde(default, skip_serializing_if = "Option::is_none")]
4336    pub function_target: Option<Box<Expression>>,
4337    /// ClickHouse: PARTITION BY expr
4338    #[serde(default, skip_serializing_if = "Option::is_none")]
4339    pub partition_by: Option<Box<Expression>>,
4340    /// ClickHouse: SETTINGS key = val, ...
4341    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4342    pub settings: Vec<Expression>,
4343}
4344
4345/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4346#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4347#[cfg_attr(feature = "bindings", derive(TS))]
4348pub struct OutputClause {
4349    /// Columns/expressions to output
4350    pub columns: Vec<Expression>,
4351    /// Optional INTO target table or table variable
4352    #[serde(default)]
4353    pub into_table: Option<Expression>,
4354}
4355
4356/// UPDATE statement
4357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4358#[cfg_attr(feature = "bindings", derive(TS))]
4359pub struct Update {
4360    pub table: TableRef,
4361    #[serde(default)]
4362    pub hint: Option<Hint>,
4363    /// Additional tables for multi-table UPDATE (MySQL syntax)
4364    #[serde(default)]
4365    pub extra_tables: Vec<TableRef>,
4366    /// JOINs attached to the table list (MySQL multi-table syntax)
4367    #[serde(default)]
4368    pub table_joins: Vec<Join>,
4369    pub set: Vec<(Identifier, Expression)>,
4370    pub from_clause: Option<From>,
4371    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4372    #[serde(default)]
4373    pub from_joins: Vec<Join>,
4374    pub where_clause: Option<Where>,
4375    /// RETURNING clause (PostgreSQL, SQLite)
4376    #[serde(default)]
4377    pub returning: Vec<Expression>,
4378    /// OUTPUT clause (TSQL)
4379    #[serde(default)]
4380    pub output: Option<OutputClause>,
4381    /// WITH clause (CTEs)
4382    #[serde(default)]
4383    pub with: Option<With>,
4384    /// Leading comments before the statement
4385    #[serde(default)]
4386    pub leading_comments: Vec<String>,
4387    /// LIMIT clause (MySQL)
4388    #[serde(default)]
4389    pub limit: Option<Expression>,
4390    /// ORDER BY clause (MySQL)
4391    #[serde(default)]
4392    pub order_by: Option<OrderBy>,
4393    /// Whether FROM clause appears before SET (Snowflake syntax)
4394    #[serde(default)]
4395    pub from_before_set: bool,
4396}
4397
4398/// DELETE statement
4399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4400#[cfg_attr(feature = "bindings", derive(TS))]
4401pub struct Delete {
4402    pub table: TableRef,
4403    #[serde(default)]
4404    pub hint: Option<Hint>,
4405    /// ClickHouse: ON CLUSTER clause for distributed DDL
4406    #[serde(default, skip_serializing_if = "Option::is_none")]
4407    pub on_cluster: Option<OnCluster>,
4408    /// Optional alias for the table
4409    pub alias: Option<Identifier>,
4410    /// Whether the alias was declared with explicit AS keyword
4411    #[serde(default)]
4412    pub alias_explicit_as: bool,
4413    /// PostgreSQL/DuckDB USING clause - additional tables to join
4414    pub using: Vec<TableRef>,
4415    pub where_clause: Option<Where>,
4416    /// OUTPUT clause (TSQL)
4417    #[serde(default)]
4418    pub output: Option<OutputClause>,
4419    /// Leading comments before the statement
4420    #[serde(default)]
4421    pub leading_comments: Vec<String>,
4422    /// WITH clause (CTEs)
4423    #[serde(default)]
4424    pub with: Option<With>,
4425    /// LIMIT clause (MySQL)
4426    #[serde(default)]
4427    pub limit: Option<Expression>,
4428    /// ORDER BY clause (MySQL)
4429    #[serde(default)]
4430    pub order_by: Option<OrderBy>,
4431    /// RETURNING clause (PostgreSQL)
4432    #[serde(default)]
4433    pub returning: Vec<Expression>,
4434    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4435    /// These are the target tables to delete from
4436    #[serde(default)]
4437    pub tables: Vec<TableRef>,
4438    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4439    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4440    #[serde(default)]
4441    pub tables_from_using: bool,
4442    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4443    #[serde(default)]
4444    pub joins: Vec<Join>,
4445    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4446    #[serde(default)]
4447    pub force_index: Option<String>,
4448    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4449    #[serde(default)]
4450    pub no_from: bool,
4451}
4452
4453/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4454#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4455#[cfg_attr(feature = "bindings", derive(TS))]
4456pub struct CopyStmt {
4457    /// Target table or query
4458    pub this: Expression,
4459    /// True for FROM (loading into table), false for TO (exporting)
4460    pub kind: bool,
4461    /// Source/destination file(s) or stage
4462    pub files: Vec<Expression>,
4463    /// Copy parameters
4464    #[serde(default)]
4465    pub params: Vec<CopyParameter>,
4466    /// Credentials for external access
4467    #[serde(default)]
4468    pub credentials: Option<Box<Credentials>>,
4469    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4470    #[serde(default)]
4471    pub is_into: bool,
4472    /// Whether parameters are wrapped in WITH (...) syntax
4473    #[serde(default)]
4474    pub with_wrapped: bool,
4475}
4476
4477/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4479#[cfg_attr(feature = "bindings", derive(TS))]
4480pub struct CopyParameter {
4481    pub name: String,
4482    pub value: Option<Expression>,
4483    pub values: Vec<Expression>,
4484    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4485    #[serde(default)]
4486    pub eq: bool,
4487}
4488
4489/// Credentials for external access (S3, Azure, etc.)
4490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4491#[cfg_attr(feature = "bindings", derive(TS))]
4492pub struct Credentials {
4493    pub credentials: Vec<(String, String)>,
4494    pub encryption: Option<String>,
4495    pub storage: Option<String>,
4496}
4497
4498/// PUT statement (Snowflake)
4499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4500#[cfg_attr(feature = "bindings", derive(TS))]
4501pub struct PutStmt {
4502    /// Source file path
4503    pub source: String,
4504    /// Whether source was quoted in the original SQL
4505    #[serde(default)]
4506    pub source_quoted: bool,
4507    /// Target stage
4508    pub target: Expression,
4509    /// PUT parameters
4510    #[serde(default)]
4511    pub params: Vec<CopyParameter>,
4512}
4513
4514/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4516#[cfg_attr(feature = "bindings", derive(TS))]
4517pub struct StageReference {
4518    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4519    pub name: String,
4520    /// Optional path within the stage (e.g., "/path/to/file.csv")
4521    #[serde(default)]
4522    pub path: Option<String>,
4523    /// Optional FILE_FORMAT parameter
4524    #[serde(default)]
4525    pub file_format: Option<Expression>,
4526    /// Optional PATTERN parameter
4527    #[serde(default)]
4528    pub pattern: Option<String>,
4529    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4530    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4531    pub quoted: bool,
4532}
4533
4534/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4535#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4536#[cfg_attr(feature = "bindings", derive(TS))]
4537pub struct HistoricalData {
4538    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4539    pub this: Box<Expression>,
4540    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4541    pub kind: String,
4542    /// The expression value (e.g., the statement ID or timestamp)
4543    pub expression: Box<Expression>,
4544}
4545
4546/// Represent an aliased expression (`expr AS name`).
4547///
4548/// Used for column aliases in select-lists, table aliases on subqueries,
4549/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4550#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4551#[cfg_attr(feature = "bindings", derive(TS))]
4552pub struct Alias {
4553    /// The expression being aliased.
4554    pub this: Expression,
4555    /// The alias name (required for simple aliases, optional when only column aliases provided)
4556    pub alias: Identifier,
4557    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4558    #[serde(default)]
4559    pub column_aliases: Vec<Identifier>,
4560    /// Whether AS keyword was explicitly used for the alias.
4561    #[serde(default)]
4562    pub alias_explicit_as: bool,
4563    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4564    #[serde(skip_serializing_if = "Option::is_none", default)]
4565    pub alias_keyword: Option<String>,
4566    /// Comments that appeared between the expression and AS keyword
4567    #[serde(default)]
4568    pub pre_alias_comments: Vec<String>,
4569    /// Trailing comments that appeared after the alias
4570    #[serde(default)]
4571    pub trailing_comments: Vec<String>,
4572    /// Inferred data type from type annotation
4573    #[serde(default, skip_serializing_if = "Option::is_none")]
4574    #[ast(skip)]
4575    pub inferred_type: Option<DataType>,
4576}
4577
4578impl Alias {
4579    /// Create a simple alias
4580    pub fn new(this: Expression, alias: Identifier) -> Self {
4581        Self {
4582            this,
4583            alias,
4584            column_aliases: Vec::new(),
4585            alias_explicit_as: false,
4586            alias_keyword: None,
4587            pre_alias_comments: Vec::new(),
4588            trailing_comments: Vec::new(),
4589            inferred_type: None,
4590        }
4591    }
4592
4593    /// Create an alias with column aliases only (no table alias name)
4594    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4595        Self {
4596            this,
4597            alias: Identifier::empty(),
4598            column_aliases,
4599            alias_explicit_as: false,
4600            alias_keyword: None,
4601            pre_alias_comments: Vec::new(),
4602            trailing_comments: Vec::new(),
4603            inferred_type: None,
4604        }
4605    }
4606}
4607
4608/// Represent a type cast expression.
4609///
4610/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4611/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4612/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4613/// CONVERSION ERROR (Oracle) clauses.
4614#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4615#[cfg_attr(feature = "bindings", derive(TS))]
4616pub struct Cast {
4617    /// The expression being cast.
4618    pub this: Expression,
4619    /// The target data type.
4620    pub to: DataType,
4621    #[serde(default)]
4622    pub trailing_comments: Vec<String>,
4623    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4624    #[serde(default)]
4625    pub double_colon_syntax: bool,
4626    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4627    #[serde(skip_serializing_if = "Option::is_none", default)]
4628    pub format: Option<Box<Expression>>,
4629    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4630    #[serde(skip_serializing_if = "Option::is_none", default)]
4631    pub default: Option<Box<Expression>>,
4632    /// Inferred data type from type annotation
4633    #[serde(default, skip_serializing_if = "Option::is_none")]
4634    #[ast(skip)]
4635    pub inferred_type: Option<DataType>,
4636}
4637
4638///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4639#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4640#[cfg_attr(feature = "bindings", derive(TS))]
4641pub struct CollationExpr {
4642    pub this: Expression,
4643    pub collation: String,
4644    /// True if the collation was single-quoted in the original SQL (string literal)
4645    #[serde(default)]
4646    pub quoted: bool,
4647    /// True if the collation was double-quoted in the original SQL (identifier)
4648    #[serde(default)]
4649    pub double_quoted: bool,
4650}
4651
4652/// Represent a CASE expression (both simple and searched forms).
4653///
4654/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4655/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4656/// Each entry in `whens` is a `(condition, result)` pair.
4657#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4658#[cfg_attr(feature = "bindings", derive(TS))]
4659pub struct Case {
4660    /// The operand for simple CASE, or `None` for searched CASE.
4661    pub operand: Option<Expression>,
4662    /// Pairs of (WHEN condition, THEN result).
4663    pub whens: Vec<(Expression, Expression)>,
4664    /// Optional ELSE result.
4665    pub else_: Option<Expression>,
4666    /// Comments from the CASE keyword (emitted after END)
4667    #[serde(default)]
4668    #[serde(skip_serializing_if = "Vec::is_empty")]
4669    pub comments: Vec<String>,
4670    /// Inferred data type from type annotation
4671    #[serde(default, skip_serializing_if = "Option::is_none")]
4672    #[ast(skip)]
4673    pub inferred_type: Option<DataType>,
4674}
4675
4676/// Represent a binary operation (two operands separated by an operator).
4677///
4678/// This is the shared payload struct for all binary operator variants in the
4679/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4680/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4681/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4682/// preservation of inline comments around operators.
4683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4684#[cfg_attr(feature = "bindings", derive(TS))]
4685pub struct BinaryOp {
4686    pub left: Expression,
4687    pub right: Expression,
4688    /// Comments after the left operand (before the operator)
4689    #[serde(default)]
4690    pub left_comments: Vec<String>,
4691    /// Comments after the operator (before the right operand)
4692    #[serde(default)]
4693    pub operator_comments: Vec<String>,
4694    /// Comments after the right operand
4695    #[serde(default)]
4696    pub trailing_comments: Vec<String>,
4697    /// Inferred data type from type annotation
4698    #[serde(default, skip_serializing_if = "Option::is_none")]
4699    #[ast(skip)]
4700    pub inferred_type: Option<DataType>,
4701}
4702
4703impl BinaryOp {
4704    pub fn new(left: Expression, right: Expression) -> Self {
4705        Self {
4706            left,
4707            right,
4708            left_comments: Vec::new(),
4709            operator_comments: Vec::new(),
4710            trailing_comments: Vec::new(),
4711            inferred_type: None,
4712        }
4713    }
4714}
4715
4716/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4717#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4718#[cfg_attr(feature = "bindings", derive(TS))]
4719pub struct LikeOp {
4720    pub left: Expression,
4721    pub right: Expression,
4722    /// ESCAPE character/expression
4723    #[serde(default)]
4724    pub escape: Option<Expression>,
4725    /// Quantifier: ANY, ALL, or SOME
4726    #[serde(default)]
4727    pub quantifier: Option<String>,
4728    /// Inferred data type from type annotation
4729    #[serde(default, skip_serializing_if = "Option::is_none")]
4730    #[ast(skip)]
4731    pub inferred_type: Option<DataType>,
4732}
4733
4734impl LikeOp {
4735    pub fn new(left: Expression, right: Expression) -> Self {
4736        Self {
4737            left,
4738            right,
4739            escape: None,
4740            quantifier: None,
4741            inferred_type: None,
4742        }
4743    }
4744
4745    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4746        Self {
4747            left,
4748            right,
4749            escape: Some(escape),
4750            quantifier: None,
4751            inferred_type: None,
4752        }
4753    }
4754}
4755
4756/// Represent a unary operation (single operand with a prefix operator).
4757///
4758/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4759#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4760#[cfg_attr(feature = "bindings", derive(TS))]
4761pub struct UnaryOp {
4762    /// The operand expression.
4763    pub this: Expression,
4764    /// Inferred data type from type annotation
4765    #[serde(default, skip_serializing_if = "Option::is_none")]
4766    #[ast(skip)]
4767    pub inferred_type: Option<DataType>,
4768}
4769
4770impl UnaryOp {
4771    pub fn new(this: Expression) -> Self {
4772        Self {
4773            this,
4774            inferred_type: None,
4775        }
4776    }
4777}
4778
4779/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4780///
4781/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4782/// but not both. When `not` is true, the predicate is `NOT IN`.
4783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4784#[cfg_attr(feature = "bindings", derive(TS))]
4785pub struct In {
4786    /// The expression being tested.
4787    pub this: Expression,
4788    /// The value list (mutually exclusive with `query`).
4789    pub expressions: Vec<Expression>,
4790    /// A subquery (mutually exclusive with `expressions`).
4791    pub query: Option<Expression>,
4792    /// Whether this is NOT IN.
4793    pub not: bool,
4794    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4795    pub global: bool,
4796    /// BigQuery: IN UNNEST(expr)
4797    #[serde(default, skip_serializing_if = "Option::is_none")]
4798    pub unnest: Option<Box<Expression>>,
4799    /// Whether the right side is a bare field reference (no parentheses).
4800    /// Matches Python sqlglot's `field` attribute on `In` expression.
4801    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4802    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4803    pub is_field: bool,
4804}
4805
4806/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4808#[cfg_attr(feature = "bindings", derive(TS))]
4809pub struct Between {
4810    /// The expression being tested.
4811    pub this: Expression,
4812    /// The lower bound.
4813    pub low: Expression,
4814    /// The upper bound.
4815    pub high: Expression,
4816    /// Whether this is NOT BETWEEN.
4817    pub not: bool,
4818    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4819    #[serde(default)]
4820    pub symmetric: Option<bool>,
4821}
4822
4823/// IS NULL predicate
4824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4825#[cfg_attr(feature = "bindings", derive(TS))]
4826pub struct IsNull {
4827    pub this: Expression,
4828    pub not: bool,
4829    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4830    #[serde(default)]
4831    pub postfix_form: bool,
4832}
4833
4834/// IS TRUE / IS FALSE predicate
4835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4836#[cfg_attr(feature = "bindings", derive(TS))]
4837pub struct IsTrueFalse {
4838    pub this: Expression,
4839    pub not: bool,
4840}
4841
4842/// IS JSON predicate (SQL standard)
4843/// Checks if a value is valid JSON
4844#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4845#[cfg_attr(feature = "bindings", derive(TS))]
4846pub struct IsJson {
4847    pub this: Expression,
4848    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4849    pub json_type: Option<String>,
4850    /// Key uniqueness constraint
4851    pub unique_keys: Option<JsonUniqueKeys>,
4852    /// Whether IS NOT JSON
4853    pub negated: bool,
4854}
4855
4856/// JSON unique keys constraint variants
4857#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4858#[cfg_attr(feature = "bindings", derive(TS))]
4859pub enum JsonUniqueKeys {
4860    /// WITH UNIQUE KEYS
4861    With,
4862    /// WITHOUT UNIQUE KEYS
4863    Without,
4864    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4865    Shorthand,
4866}
4867
4868/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4869#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4870#[cfg_attr(feature = "bindings", derive(TS))]
4871pub struct Exists {
4872    /// The subquery expression.
4873    pub this: Expression,
4874    /// Whether this is NOT EXISTS.
4875    pub not: bool,
4876}
4877
4878/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
4879///
4880/// This is the generic function node. Well-known aggregates, window functions,
4881/// and built-in functions each have their own dedicated `Expression` variants
4882/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
4883/// not recognize as built-ins are represented with this struct.
4884#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4885#[cfg_attr(feature = "bindings", derive(TS))]
4886pub struct Function {
4887    /// The function name, as originally written (may be schema-qualified).
4888    pub name: String,
4889    /// Positional arguments to the function.
4890    pub args: Vec<Expression>,
4891    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
4892    pub distinct: bool,
4893    #[serde(default)]
4894    pub trailing_comments: Vec<String>,
4895    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
4896    #[serde(default)]
4897    pub use_bracket_syntax: bool,
4898    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
4899    #[serde(default)]
4900    pub no_parens: bool,
4901    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
4902    #[serde(default)]
4903    pub quoted: bool,
4904    /// Source position span
4905    #[serde(default, skip_serializing_if = "Option::is_none")]
4906    pub span: Option<Span>,
4907    /// Inferred data type from type annotation
4908    #[serde(default, skip_serializing_if = "Option::is_none")]
4909    #[ast(skip)]
4910    pub inferred_type: Option<DataType>,
4911}
4912
4913impl Default for Function {
4914    fn default() -> Self {
4915        Self {
4916            name: String::new(),
4917            args: Vec::new(),
4918            distinct: false,
4919            trailing_comments: Vec::new(),
4920            use_bracket_syntax: false,
4921            no_parens: false,
4922            quoted: false,
4923            span: None,
4924            inferred_type: None,
4925        }
4926    }
4927}
4928
4929impl Function {
4930    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
4931        Self {
4932            name: name.into(),
4933            args,
4934            distinct: false,
4935            trailing_comments: Vec::new(),
4936            use_bracket_syntax: false,
4937            no_parens: false,
4938            quoted: false,
4939            span: None,
4940            inferred_type: None,
4941        }
4942    }
4943}
4944
4945/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
4946///
4947/// This struct is used for aggregate function calls that are not covered by
4948/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
4949/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
4950/// IGNORE NULLS / RESPECT NULLS modifiers.
4951#[derive(
4952    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
4953)]
4954#[cfg_attr(feature = "bindings", derive(TS))]
4955pub struct AggregateFunction {
4956    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
4957    pub name: String,
4958    /// Positional arguments.
4959    pub args: Vec<Expression>,
4960    /// Whether DISTINCT was specified.
4961    pub distinct: bool,
4962    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
4963    pub filter: Option<Expression>,
4964    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
4965    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4966    pub order_by: Vec<Ordered>,
4967    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
4968    #[serde(default, skip_serializing_if = "Option::is_none")]
4969    pub limit: Option<Box<Expression>>,
4970    /// IGNORE NULLS / RESPECT NULLS
4971    #[serde(default, skip_serializing_if = "Option::is_none")]
4972    pub ignore_nulls: Option<bool>,
4973    /// Inferred data type from type annotation
4974    #[serde(default, skip_serializing_if = "Option::is_none")]
4975    #[ast(skip)]
4976    pub inferred_type: Option<DataType>,
4977}
4978
4979/// Represent a window function call with its OVER clause.
4980///
4981/// The inner `this` expression is typically a window-specific expression
4982/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
4983/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
4984/// frame specification.
4985#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4986#[cfg_attr(feature = "bindings", derive(TS))]
4987pub struct WindowFunction {
4988    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
4989    pub this: Expression,
4990    /// The OVER clause defining the window partitioning, ordering, and frame.
4991    pub over: Over,
4992    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
4993    #[serde(default, skip_serializing_if = "Option::is_none")]
4994    pub keep: Option<Keep>,
4995    /// Inferred data type from type annotation
4996    #[serde(default, skip_serializing_if = "Option::is_none")]
4997    #[ast(skip)]
4998    pub inferred_type: Option<DataType>,
4999}
5000
5001/// Oracle KEEP clause for aggregate functions
5002/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
5003#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5004#[cfg_attr(feature = "bindings", derive(TS))]
5005pub struct Keep {
5006    /// true = FIRST, false = LAST
5007    pub first: bool,
5008    /// ORDER BY clause inside KEEP
5009    pub order_by: Vec<Ordered>,
5010}
5011
5012/// WITHIN GROUP clause (for ordered-set aggregate functions)
5013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5014#[cfg_attr(feature = "bindings", derive(TS))]
5015pub struct WithinGroup {
5016    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
5017    pub this: Expression,
5018    /// The ORDER BY clause within the group
5019    pub order_by: Vec<Ordered>,
5020}
5021
5022/// Represent the FROM clause of a SELECT statement.
5023///
5024/// Contains one or more table sources (tables, subqueries, table-valued
5025/// functions, etc.). Multiple entries represent comma-separated implicit joins.
5026#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5027#[cfg_attr(feature = "bindings", derive(TS))]
5028pub struct From {
5029    /// The table source expressions.
5030    pub expressions: Vec<Expression>,
5031}
5032
5033/// Represent a JOIN clause between two table sources.
5034///
5035/// The join condition can be specified via `on` (ON predicate) or `using`
5036/// (USING column list), but not both. The `kind` field determines the join
5037/// type (INNER, LEFT, CROSS, etc.).
5038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5039#[cfg_attr(feature = "bindings", derive(TS))]
5040pub struct Join {
5041    /// The right-hand table expression being joined.
5042    pub this: Expression,
5043    /// The ON condition (mutually exclusive with `using`).
5044    pub on: Option<Expression>,
5045    /// The USING column list (mutually exclusive with `on`).
5046    pub using: Vec<Identifier>,
5047    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5048    pub kind: JoinKind,
5049    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5050    pub use_inner_keyword: bool,
5051    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5052    pub use_outer_keyword: bool,
5053    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5054    pub deferred_condition: bool,
5055    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5056    #[serde(default, skip_serializing_if = "Option::is_none")]
5057    pub join_hint: Option<String>,
5058    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5059    #[serde(default, skip_serializing_if = "Option::is_none")]
5060    pub match_condition: Option<Expression>,
5061    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5062    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5063    pub pivots: Vec<Expression>,
5064    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5065    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5066    pub comments: Vec<String>,
5067    /// Nesting group identifier for nested join pretty-printing.
5068    /// Joins in the same group were parsed together; group boundaries come from
5069    /// deferred condition resolution phases.
5070    #[serde(default)]
5071    pub nesting_group: usize,
5072    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5073    #[serde(default)]
5074    pub directed: bool,
5075}
5076
5077/// Enumerate all supported SQL join types.
5078///
5079/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5080/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5081/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5082/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5083#[derive(
5084    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5085)]
5086#[cfg_attr(feature = "bindings", derive(TS))]
5087pub enum JoinKind {
5088    Inner,
5089    Left,
5090    Right,
5091    Full,
5092    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5093    Cross,
5094    Natural,
5095    NaturalLeft,
5096    NaturalRight,
5097    NaturalFull,
5098    Semi,
5099    Anti,
5100    // Directional SEMI/ANTI joins
5101    LeftSemi,
5102    LeftAnti,
5103    RightSemi,
5104    RightAnti,
5105    // SQL Server specific
5106    CrossApply,
5107    OuterApply,
5108    // Time-series specific
5109    AsOf,
5110    AsOfLeft,
5111    AsOfRight,
5112    // Lateral join
5113    Lateral,
5114    LeftLateral,
5115    // MySQL specific
5116    Straight,
5117    // Implicit join (comma-separated tables: FROM a, b)
5118    Implicit,
5119    // ClickHouse ARRAY JOIN
5120    Array,
5121    LeftArray,
5122    // ClickHouse PASTE JOIN (positional join)
5123    Paste,
5124    // DuckDB POSITIONAL JOIN
5125    Positional,
5126}
5127
5128impl Default for JoinKind {
5129    fn default() -> Self {
5130        JoinKind::Inner
5131    }
5132}
5133
5134/// Parenthesized table expression with joins
5135/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5137#[cfg_attr(feature = "bindings", derive(TS))]
5138pub struct JoinedTable {
5139    /// The left-hand side table expression
5140    pub left: Expression,
5141    /// The joins applied to the left table
5142    pub joins: Vec<Join>,
5143    /// LATERAL VIEW clauses (Hive/Spark)
5144    pub lateral_views: Vec<LateralView>,
5145    /// Optional alias for the joined table expression
5146    pub alias: Option<Identifier>,
5147}
5148
5149/// Represent a WHERE clause containing a boolean filter predicate.
5150#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5151#[cfg_attr(feature = "bindings", derive(TS))]
5152pub struct Where {
5153    /// The filter predicate expression.
5154    pub this: Expression,
5155}
5156
5157/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5158///
5159/// The `expressions` list may contain plain columns, ordinal positions,
5160/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5161#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5162#[cfg_attr(feature = "bindings", derive(TS))]
5163pub struct GroupBy {
5164    /// The grouping expressions.
5165    pub expressions: Vec<Expression>,
5166    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5167    #[serde(default)]
5168    pub all: Option<bool>,
5169    /// ClickHouse: WITH TOTALS modifier
5170    #[serde(default)]
5171    pub totals: bool,
5172    /// Leading comments that appeared before the GROUP BY keyword
5173    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5174    pub comments: Vec<String>,
5175}
5176
5177/// Represent a HAVING clause containing a predicate over aggregate results.
5178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5179#[cfg_attr(feature = "bindings", derive(TS))]
5180pub struct Having {
5181    /// The filter predicate, typically involving aggregate functions.
5182    pub this: Expression,
5183    /// Leading comments that appeared before the HAVING keyword
5184    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5185    pub comments: Vec<String>,
5186}
5187
5188/// Represent an ORDER BY clause containing one or more sort specifications.
5189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5190#[cfg_attr(feature = "bindings", derive(TS))]
5191pub struct OrderBy {
5192    /// The sort specifications, each with direction and null ordering.
5193    pub expressions: Vec<Ordered>,
5194    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5195    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5196    pub siblings: bool,
5197    /// Leading comments that appeared before the ORDER BY keyword
5198    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5199    pub comments: Vec<String>,
5200}
5201
5202/// Represent an expression with sort direction and null ordering.
5203///
5204/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5205/// When `desc` is false the sort is ascending. The `nulls_first` field
5206/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5207/// (database default).
5208#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5209#[cfg_attr(feature = "bindings", derive(TS))]
5210pub struct Ordered {
5211    /// The expression to sort by.
5212    pub this: Expression,
5213    /// Whether the sort direction is descending (true) or ascending (false).
5214    pub desc: bool,
5215    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5216    pub nulls_first: Option<bool>,
5217    /// Whether ASC was explicitly written (not just implied)
5218    #[serde(default)]
5219    pub explicit_asc: bool,
5220    /// ClickHouse WITH FILL clause
5221    #[serde(default, skip_serializing_if = "Option::is_none")]
5222    pub with_fill: Option<Box<WithFill>>,
5223}
5224
5225impl Ordered {
5226    pub fn asc(expr: Expression) -> Self {
5227        Self {
5228            this: expr,
5229            desc: false,
5230            nulls_first: None,
5231            explicit_asc: false,
5232            with_fill: None,
5233        }
5234    }
5235
5236    pub fn desc(expr: Expression) -> Self {
5237        Self {
5238            this: expr,
5239            desc: true,
5240            nulls_first: None,
5241            explicit_asc: false,
5242            with_fill: None,
5243        }
5244    }
5245}
5246
5247/// DISTRIBUTE BY clause (Hive/Spark)
5248/// Controls how rows are distributed across reducers
5249#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5250#[cfg_attr(feature = "bindings", derive(TS))]
5251#[cfg_attr(feature = "bindings", ts(export))]
5252pub struct DistributeBy {
5253    pub expressions: Vec<Expression>,
5254}
5255
5256/// CLUSTER BY clause (Hive/Spark)
5257/// Combines DISTRIBUTE BY and SORT BY on the same columns
5258#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5259#[cfg_attr(feature = "bindings", derive(TS))]
5260#[cfg_attr(feature = "bindings", ts(export))]
5261pub struct ClusterBy {
5262    pub expressions: Vec<Ordered>,
5263}
5264
5265/// SORT BY clause (Hive/Spark)
5266/// Sorts data within each reducer (local sort, not global)
5267#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5268#[cfg_attr(feature = "bindings", derive(TS))]
5269#[cfg_attr(feature = "bindings", ts(export))]
5270pub struct SortBy {
5271    pub expressions: Vec<Ordered>,
5272}
5273
5274/// LATERAL VIEW clause (Hive/Spark)
5275/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5276#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5277#[cfg_attr(feature = "bindings", derive(TS))]
5278#[cfg_attr(feature = "bindings", ts(export))]
5279pub struct LateralView {
5280    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5281    pub this: Expression,
5282    /// Table alias for the generated table
5283    pub table_alias: Option<Identifier>,
5284    /// Column aliases for the generated columns
5285    pub column_aliases: Vec<Identifier>,
5286    /// OUTER keyword - preserve nulls when input is empty/null
5287    pub outer: bool,
5288}
5289
5290/// Query hint
5291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5292#[cfg_attr(feature = "bindings", derive(TS))]
5293#[cfg_attr(feature = "bindings", ts(export))]
5294pub struct Hint {
5295    pub expressions: Vec<HintExpression>,
5296}
5297
5298/// Individual hint expression
5299#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5300#[cfg_attr(feature = "bindings", derive(TS))]
5301#[cfg_attr(feature = "bindings", ts(export))]
5302pub enum HintExpression {
5303    /// Function-style hint: USE_HASH(table)
5304    Function { name: String, args: Vec<Expression> },
5305    /// Simple identifier hint: PARALLEL
5306    Identifier(String),
5307    /// Raw hint text (unparsed)
5308    Raw(String),
5309}
5310
5311/// Pseudocolumn type
5312#[derive(
5313    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5314)]
5315#[cfg_attr(feature = "bindings", derive(TS))]
5316#[cfg_attr(feature = "bindings", ts(export))]
5317pub enum PseudocolumnType {
5318    Rownum,      // Oracle ROWNUM
5319    Rowid,       // Oracle ROWID
5320    Level,       // Oracle LEVEL (for CONNECT BY)
5321    Sysdate,     // Oracle SYSDATE
5322    ObjectId,    // Oracle OBJECT_ID
5323    ObjectValue, // Oracle OBJECT_VALUE
5324}
5325
5326impl PseudocolumnType {
5327    pub fn as_str(&self) -> &'static str {
5328        match self {
5329            PseudocolumnType::Rownum => "ROWNUM",
5330            PseudocolumnType::Rowid => "ROWID",
5331            PseudocolumnType::Level => "LEVEL",
5332            PseudocolumnType::Sysdate => "SYSDATE",
5333            PseudocolumnType::ObjectId => "OBJECT_ID",
5334            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5335        }
5336    }
5337
5338    pub fn from_str(s: &str) -> Option<Self> {
5339        match s.to_uppercase().as_str() {
5340            "ROWNUM" => Some(PseudocolumnType::Rownum),
5341            "ROWID" => Some(PseudocolumnType::Rowid),
5342            "LEVEL" => Some(PseudocolumnType::Level),
5343            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5344            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5345            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5346            _ => None,
5347        }
5348    }
5349}
5350
5351/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5352/// These are special identifiers that should not be quoted
5353#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5354#[cfg_attr(feature = "bindings", derive(TS))]
5355#[cfg_attr(feature = "bindings", ts(export))]
5356pub struct Pseudocolumn {
5357    pub kind: PseudocolumnType,
5358}
5359
5360impl Pseudocolumn {
5361    pub fn rownum() -> Self {
5362        Self {
5363            kind: PseudocolumnType::Rownum,
5364        }
5365    }
5366
5367    pub fn rowid() -> Self {
5368        Self {
5369            kind: PseudocolumnType::Rowid,
5370        }
5371    }
5372
5373    pub fn level() -> Self {
5374        Self {
5375            kind: PseudocolumnType::Level,
5376        }
5377    }
5378}
5379
5380/// Oracle CONNECT BY clause for hierarchical queries
5381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5382#[cfg_attr(feature = "bindings", derive(TS))]
5383#[cfg_attr(feature = "bindings", ts(export))]
5384pub struct Connect {
5385    /// START WITH condition (optional, can come before or after CONNECT BY)
5386    pub start: Option<Expression>,
5387    /// CONNECT BY condition (required, contains PRIOR references)
5388    pub connect: Expression,
5389    /// NOCYCLE keyword to prevent infinite loops
5390    pub nocycle: bool,
5391}
5392
5393/// Oracle PRIOR expression - references parent row's value in CONNECT BY
5394#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5395#[cfg_attr(feature = "bindings", derive(TS))]
5396#[cfg_attr(feature = "bindings", ts(export))]
5397pub struct Prior {
5398    pub this: Expression,
5399}
5400
5401/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5402#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5403#[cfg_attr(feature = "bindings", derive(TS))]
5404#[cfg_attr(feature = "bindings", ts(export))]
5405pub struct ConnectByRoot {
5406    pub this: Expression,
5407}
5408
5409/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5410#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5411#[cfg_attr(feature = "bindings", derive(TS))]
5412#[cfg_attr(feature = "bindings", ts(export))]
5413pub struct MatchRecognize {
5414    /// Source table/expression
5415    pub this: Option<Box<Expression>>,
5416    /// PARTITION BY expressions
5417    pub partition_by: Option<Vec<Expression>>,
5418    /// ORDER BY expressions
5419    pub order_by: Option<Vec<Ordered>>,
5420    /// MEASURES definitions
5421    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5422    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5423    pub rows: Option<MatchRecognizeRows>,
5424    /// AFTER MATCH SKIP behavior
5425    pub after: Option<MatchRecognizeAfter>,
5426    /// PATTERN definition (stored as raw string for complex regex patterns)
5427    pub pattern: Option<String>,
5428    /// DEFINE clauses (pattern variable definitions)
5429    pub define: Option<Vec<(Identifier, Expression)>>,
5430    /// Optional alias for the result
5431    pub alias: Option<Identifier>,
5432    /// Whether AS keyword was explicitly present before alias
5433    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5434    pub alias_explicit_as: bool,
5435}
5436
5437/// MEASURES expression with optional RUNNING/FINAL semantics
5438#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5439#[cfg_attr(feature = "bindings", derive(TS))]
5440#[cfg_attr(feature = "bindings", ts(export))]
5441pub struct MatchRecognizeMeasure {
5442    /// The measure expression
5443    pub this: Expression,
5444    /// RUNNING or FINAL semantics (Snowflake-specific)
5445    pub window_frame: Option<MatchRecognizeSemantics>,
5446}
5447
5448/// Semantics for MEASURES in MATCH_RECOGNIZE
5449#[derive(
5450    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5451)]
5452#[cfg_attr(feature = "bindings", derive(TS))]
5453#[cfg_attr(feature = "bindings", ts(export))]
5454pub enum MatchRecognizeSemantics {
5455    Running,
5456    Final,
5457}
5458
5459/// Row output semantics for MATCH_RECOGNIZE
5460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5461#[cfg_attr(feature = "bindings", derive(TS))]
5462#[cfg_attr(feature = "bindings", ts(export))]
5463pub enum MatchRecognizeRows {
5464    OneRowPerMatch,
5465    AllRowsPerMatch,
5466    AllRowsPerMatchShowEmptyMatches,
5467    AllRowsPerMatchOmitEmptyMatches,
5468    AllRowsPerMatchWithUnmatchedRows,
5469}
5470
5471/// AFTER MATCH SKIP behavior
5472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5473#[cfg_attr(feature = "bindings", derive(TS))]
5474#[cfg_attr(feature = "bindings", ts(export))]
5475pub enum MatchRecognizeAfter {
5476    PastLastRow,
5477    ToNextRow,
5478    ToFirst(Identifier),
5479    ToLast(Identifier),
5480}
5481
5482/// Represent a LIMIT clause that restricts the number of returned rows.
5483#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5484#[cfg_attr(feature = "bindings", derive(TS))]
5485pub struct Limit {
5486    /// The limit count expression.
5487    pub this: Expression,
5488    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5489    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5490    pub percent: bool,
5491    /// Comments from before the LIMIT keyword (emitted after the limit value)
5492    #[serde(default)]
5493    #[serde(skip_serializing_if = "Vec::is_empty")]
5494    pub comments: Vec<String>,
5495}
5496
5497/// OFFSET clause
5498#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5499#[cfg_attr(feature = "bindings", derive(TS))]
5500pub struct Offset {
5501    pub this: Expression,
5502    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5503    #[serde(skip_serializing_if = "Option::is_none", default)]
5504    pub rows: Option<bool>,
5505}
5506
5507/// TOP clause (SQL Server)
5508#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5509#[cfg_attr(feature = "bindings", derive(TS))]
5510pub struct Top {
5511    pub this: Expression,
5512    pub percent: bool,
5513    pub with_ties: bool,
5514    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5515    #[serde(default)]
5516    pub parenthesized: bool,
5517}
5518
5519/// FETCH FIRST/NEXT clause (SQL standard)
5520#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5521#[cfg_attr(feature = "bindings", derive(TS))]
5522pub struct Fetch {
5523    /// FIRST or NEXT
5524    pub direction: String,
5525    /// Count expression (optional)
5526    pub count: Option<Expression>,
5527    /// PERCENT modifier
5528    pub percent: bool,
5529    /// ROWS or ROW keyword present
5530    pub rows: bool,
5531    /// WITH TIES modifier
5532    pub with_ties: bool,
5533}
5534
5535/// Represent a QUALIFY clause for filtering on window function results.
5536///
5537/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5538/// typically references a window function (e.g.
5539/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5541#[cfg_attr(feature = "bindings", derive(TS))]
5542pub struct Qualify {
5543    /// The filter predicate over window function results.
5544    pub this: Expression,
5545}
5546
5547/// SAMPLE / TABLESAMPLE clause
5548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5549#[cfg_attr(feature = "bindings", derive(TS))]
5550pub struct Sample {
5551    pub method: SampleMethod,
5552    pub size: Expression,
5553    pub seed: Option<Expression>,
5554    /// ClickHouse OFFSET expression after SAMPLE size
5555    #[serde(default)]
5556    pub offset: Option<Expression>,
5557    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5558    pub unit_after_size: bool,
5559    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5560    #[serde(default)]
5561    pub use_sample_keyword: bool,
5562    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5563    #[serde(default)]
5564    pub explicit_method: bool,
5565    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5566    #[serde(default)]
5567    pub method_before_size: bool,
5568    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5569    #[serde(default)]
5570    pub use_seed_keyword: bool,
5571    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5572    pub bucket_numerator: Option<Box<Expression>>,
5573    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5574    pub bucket_denominator: Option<Box<Expression>>,
5575    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5576    pub bucket_field: Option<Box<Expression>>,
5577    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5578    #[serde(default)]
5579    pub is_using_sample: bool,
5580    /// Whether the unit was explicitly PERCENT (vs ROWS)
5581    #[serde(default)]
5582    pub is_percent: bool,
5583    /// Whether to suppress method output (for cross-dialect transpilation)
5584    #[serde(default)]
5585    pub suppress_method_output: bool,
5586}
5587
5588/// Sample method
5589#[derive(
5590    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5591)]
5592#[cfg_attr(feature = "bindings", derive(TS))]
5593pub enum SampleMethod {
5594    Bernoulli,
5595    System,
5596    Block,
5597    Row,
5598    Percent,
5599    /// Hive bucket sampling
5600    Bucket,
5601    /// DuckDB reservoir sampling
5602    Reservoir,
5603}
5604
5605/// Named window definition (WINDOW w AS (...))
5606#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5607#[cfg_attr(feature = "bindings", derive(TS))]
5608pub struct NamedWindow {
5609    pub name: Identifier,
5610    pub spec: Over,
5611}
5612
5613/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5614///
5615/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5616/// that reference themselves. Each CTE is defined in the `ctes` vector and
5617/// can be referenced by name in subsequent CTEs and in the main query body.
5618#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5619#[cfg_attr(feature = "bindings", derive(TS))]
5620pub struct With {
5621    /// The list of CTE definitions, in order.
5622    pub ctes: Vec<Cte>,
5623    /// Whether the WITH RECURSIVE keyword was used.
5624    pub recursive: bool,
5625    /// Leading comments before the statement
5626    #[serde(default)]
5627    pub leading_comments: Vec<String>,
5628    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5629    #[serde(default, skip_serializing_if = "Option::is_none")]
5630    pub search: Option<Box<Expression>>,
5631}
5632
5633/// Represent a single Common Table Expression definition.
5634///
5635/// A CTE has a name (`alias`), an optional column list, and a body query.
5636/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5637/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5638/// the expression comes before the alias (`alias_first`).
5639#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5640#[cfg_attr(feature = "bindings", derive(TS))]
5641pub struct Cte {
5642    /// The CTE name.
5643    pub alias: Identifier,
5644    /// The CTE body (typically a SELECT, UNION, etc.).
5645    pub this: Expression,
5646    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5647    pub columns: Vec<Identifier>,
5648    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5649    pub materialized: Option<bool>,
5650    /// USING KEY (columns) for DuckDB recursive CTEs
5651    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5652    pub key_expressions: Vec<Identifier>,
5653    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5654    #[serde(default)]
5655    pub alias_first: bool,
5656    /// Comments associated with this CTE (placed after alias name, before AS)
5657    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5658    pub comments: Vec<String>,
5659}
5660
5661/// Window specification
5662#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5663#[cfg_attr(feature = "bindings", derive(TS))]
5664pub struct WindowSpec {
5665    pub partition_by: Vec<Expression>,
5666    pub order_by: Vec<Ordered>,
5667    pub frame: Option<WindowFrame>,
5668}
5669
5670/// OVER clause
5671#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5672#[cfg_attr(feature = "bindings", derive(TS))]
5673pub struct Over {
5674    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
5675    pub window_name: Option<Identifier>,
5676    pub partition_by: Vec<Expression>,
5677    pub order_by: Vec<Ordered>,
5678    pub frame: Option<WindowFrame>,
5679    pub alias: Option<Identifier>,
5680}
5681
5682/// Window frame
5683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5684#[cfg_attr(feature = "bindings", derive(TS))]
5685pub struct WindowFrame {
5686    pub kind: WindowFrameKind,
5687    pub start: WindowFrameBound,
5688    pub end: Option<WindowFrameBound>,
5689    pub exclude: Option<WindowFrameExclude>,
5690    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
5691    #[serde(default, skip_serializing_if = "Option::is_none")]
5692    pub kind_text: Option<String>,
5693    /// Original text of the start bound side keyword (e.g. "preceding")
5694    #[serde(default, skip_serializing_if = "Option::is_none")]
5695    pub start_side_text: Option<String>,
5696    /// Original text of the end bound side keyword
5697    #[serde(default, skip_serializing_if = "Option::is_none")]
5698    pub end_side_text: Option<String>,
5699}
5700
5701#[derive(
5702    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5703)]
5704#[cfg_attr(feature = "bindings", derive(TS))]
5705pub enum WindowFrameKind {
5706    Rows,
5707    Range,
5708    Groups,
5709}
5710
5711/// EXCLUDE clause for window frames
5712#[derive(
5713    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5714)]
5715#[cfg_attr(feature = "bindings", derive(TS))]
5716pub enum WindowFrameExclude {
5717    CurrentRow,
5718    Group,
5719    Ties,
5720    NoOthers,
5721}
5722
5723#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5724#[cfg_attr(feature = "bindings", derive(TS))]
5725pub enum WindowFrameBound {
5726    CurrentRow,
5727    UnboundedPreceding,
5728    UnboundedFollowing,
5729    Preceding(Box<Expression>),
5730    Following(Box<Expression>),
5731    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
5732    BarePreceding,
5733    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
5734    BareFollowing,
5735    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
5736    Value(Box<Expression>),
5737}
5738
5739/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
5740#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5741#[cfg_attr(feature = "bindings", derive(TS))]
5742pub struct StructField {
5743    pub name: String,
5744    pub data_type: DataType,
5745    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5746    pub options: Vec<Expression>,
5747    #[serde(default, skip_serializing_if = "Option::is_none")]
5748    pub comment: Option<String>,
5749}
5750
5751impl StructField {
5752    /// Create a new struct field without options
5753    pub fn new(name: String, data_type: DataType) -> Self {
5754        Self {
5755            name,
5756            data_type,
5757            options: Vec::new(),
5758            comment: None,
5759        }
5760    }
5761
5762    /// Create a new struct field with options
5763    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
5764        Self {
5765            name,
5766            data_type,
5767            options,
5768            comment: None,
5769        }
5770    }
5771
5772    /// Create a new struct field with options and comment
5773    pub fn with_options_and_comment(
5774        name: String,
5775        data_type: DataType,
5776        options: Vec<Expression>,
5777        comment: Option<String>,
5778    ) -> Self {
5779        Self {
5780            name,
5781            data_type,
5782            options,
5783            comment,
5784        }
5785    }
5786}
5787
5788/// Oracle-specific data types whose semantics cannot be represented losslessly by the
5789/// generic [`DataType`] variants.
5790///
5791/// Keeping these types structured allows the Oracle parser to retain details such as a
5792/// negative `NUMBER` scale, `BYTE`/`CHAR` length semantics, interval precisions, and
5793/// `TIMESTAMP WITH LOCAL TIME ZONE` until the target dialect is known.
5794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5795#[cfg_attr(feature = "bindings", derive(TS))]
5796#[serde(tag = "oracle_data_type", rename_all = "snake_case")]
5797pub enum OracleDataType {
5798    Number {
5799        precision: Option<u32>,
5800        scale: Option<i32>,
5801    },
5802    BinaryFloat,
5803    BinaryDouble,
5804    Float {
5805        precision: Option<u32>,
5806    },
5807    Character {
5808        kind: OracleCharacterKind,
5809        length: Option<u32>,
5810        semantics: Option<OracleCharacterLengthSemantics>,
5811    },
5812    Date,
5813    Timestamp {
5814        precision: Option<u32>,
5815        timezone: OracleTimestampTimeZone,
5816    },
5817    IntervalYearToMonth {
5818        year_precision: Option<u32>,
5819    },
5820    IntervalDayToSecond {
5821        day_precision: Option<u32>,
5822        fractional_seconds_precision: Option<u32>,
5823    },
5824    Clob {
5825        national: bool,
5826    },
5827    Blob,
5828    Raw {
5829        length: Option<u32>,
5830    },
5831    Long {
5832        raw: bool,
5833    },
5834    RowId,
5835}
5836
5837#[derive(
5838    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5839)]
5840#[cfg_attr(feature = "bindings", derive(TS))]
5841#[serde(rename_all = "snake_case")]
5842pub enum OracleCharacterKind {
5843    Char,
5844    VarChar,
5845    NChar,
5846    NVarChar,
5847}
5848
5849#[derive(
5850    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5851)]
5852#[cfg_attr(feature = "bindings", derive(TS))]
5853#[serde(rename_all = "snake_case")]
5854pub enum OracleCharacterLengthSemantics {
5855    Byte,
5856    Char,
5857}
5858
5859#[derive(
5860    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5861)]
5862#[cfg_attr(feature = "bindings", derive(TS))]
5863#[serde(rename_all = "snake_case")]
5864pub enum OracleTimestampTimeZone {
5865    None,
5866    WithTimeZone,
5867    WithLocalTimeZone,
5868}
5869
5870/// Enumerate all SQL data types recognized by the parser.
5871///
5872/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
5873/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
5874/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
5875///
5876/// This enum is used in CAST expressions, column definitions, function return
5877/// types, and anywhere a data type specification appears in SQL.
5878///
5879/// Types that do not match any known variant fall through to `Custom { name }`,
5880/// preserving the original type name for round-trip fidelity.
5881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5882#[cfg_attr(feature = "bindings", derive(TS))]
5883#[serde(tag = "data_type", rename_all = "snake_case")]
5884pub enum DataType {
5885    // Numeric
5886    Boolean,
5887    TinyInt {
5888        length: Option<u32>,
5889    },
5890    SmallInt {
5891        length: Option<u32>,
5892    },
5893    /// Int type with optional length. `integer_spelling` indicates whether the original
5894    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
5895    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
5896    Int {
5897        length: Option<u32>,
5898        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5899        integer_spelling: bool,
5900    },
5901    BigInt {
5902        length: Option<u32>,
5903    },
5904    /// Signed 128-bit integer (DuckDB HUGEINT, ClickHouse Int128, StarRocks LARGEINT).
5905    Int128,
5906    /// Unsigned 8-bit integer (DuckDB UTINYINT, ClickHouse UInt8).
5907    #[serde(rename = "uint8")]
5908    UInt8,
5909    /// Unsigned 16-bit integer (DuckDB USMALLINT, ClickHouse UInt16).
5910    #[serde(rename = "uint16")]
5911    UInt16,
5912    /// Unsigned 32-bit integer (DuckDB UINTEGER, ClickHouse UInt32).
5913    #[serde(rename = "uint32")]
5914    UInt32,
5915    /// Unsigned 64-bit integer (DuckDB UBIGINT, ClickHouse UInt64).
5916    #[serde(rename = "uint64")]
5917    UInt64,
5918    /// Unsigned 128-bit integer (DuckDB UHUGEINT, ClickHouse UInt128).
5919    #[serde(rename = "uint128")]
5920    UInt128,
5921    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
5922    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
5923    /// preserve the original spelling.
5924    Float {
5925        precision: Option<u32>,
5926        scale: Option<u32>,
5927        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5928        real_spelling: bool,
5929    },
5930    Double {
5931        precision: Option<u32>,
5932        scale: Option<u32>,
5933    },
5934    Decimal {
5935        precision: Option<u32>,
5936        scale: Option<u32>,
5937    },
5938    /// Structured Oracle data type retained until the target dialect is known.
5939    Oracle {
5940        oracle_type: OracleDataType,
5941    },
5942
5943    // String
5944    Char {
5945        length: Option<u32>,
5946    },
5947    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
5948    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
5949    VarChar {
5950        length: Option<u32>,
5951        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5952        parenthesized_length: bool,
5953    },
5954    /// String type with optional max length (BigQuery STRING(n))
5955    String {
5956        length: Option<u32>,
5957    },
5958    Text,
5959    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
5960    TextWithLength {
5961        length: u32,
5962    },
5963
5964    // Binary
5965    Binary {
5966        length: Option<u32>,
5967    },
5968    VarBinary {
5969        length: Option<u32>,
5970    },
5971    Blob,
5972
5973    // Bit
5974    Bit {
5975        length: Option<u32>,
5976    },
5977    VarBit {
5978        length: Option<u32>,
5979    },
5980
5981    // Date/Time
5982    Date,
5983    Time {
5984        precision: Option<u32>,
5985        #[serde(default)]
5986        timezone: bool,
5987    },
5988    Timestamp {
5989        precision: Option<u32>,
5990        timezone: bool,
5991    },
5992    Interval {
5993        unit: Option<String>,
5994        /// For range intervals like INTERVAL DAY TO HOUR
5995        #[serde(default, skip_serializing_if = "Option::is_none")]
5996        to: Option<String>,
5997    },
5998
5999    // JSON
6000    Json,
6001    JsonB,
6002
6003    // UUID
6004    Uuid,
6005
6006    // Array
6007    Array {
6008        element_type: Box<DataType>,
6009        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
6010        #[serde(default, skip_serializing_if = "Option::is_none")]
6011        dimension: Option<u32>,
6012    },
6013
6014    /// List type (Materialize): INT LIST, TEXT LIST LIST
6015    /// Uses postfix LIST syntax instead of ARRAY<T>
6016    List {
6017        element_type: Box<DataType>,
6018    },
6019
6020    // Struct/Map
6021    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
6022    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
6023    Struct {
6024        fields: Vec<StructField>,
6025        nested: bool,
6026    },
6027    Map {
6028        key_type: Box<DataType>,
6029        value_type: Box<DataType>,
6030    },
6031
6032    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
6033    Enum {
6034        values: Vec<String>,
6035        #[serde(default, skip_serializing_if = "Vec::is_empty")]
6036        assignments: Vec<Option<String>>,
6037    },
6038
6039    // Set type (MySQL): SET('a', 'b', 'c')
6040    Set {
6041        values: Vec<String>,
6042    },
6043
6044    // Union type (DuckDB): UNION(num INT, str TEXT)
6045    Union {
6046        fields: Vec<(String, DataType)>,
6047    },
6048
6049    // Vector (Snowflake / SingleStore)
6050    Vector {
6051        #[serde(default)]
6052        element_type: Option<Box<DataType>>,
6053        dimension: Option<u32>,
6054    },
6055
6056    // Object (Snowflake structured type)
6057    // fields: Vec of (field_name, field_type, not_null)
6058    Object {
6059        fields: Vec<(String, DataType, bool)>,
6060        modifier: Option<String>,
6061    },
6062
6063    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
6064    Nullable {
6065        inner: Box<DataType>,
6066    },
6067
6068    // Custom/User-defined
6069    Custom {
6070        name: String,
6071    },
6072
6073    // Spatial types
6074    Geometry {
6075        subtype: Option<String>,
6076        srid: Option<u32>,
6077    },
6078    Geography {
6079        subtype: Option<String>,
6080        srid: Option<u32>,
6081    },
6082
6083    // Character Set (for CONVERT USING in MySQL)
6084    // Renders as CHAR CHARACTER SET {name} in cast target
6085    CharacterSet {
6086        name: String,
6087    },
6088
6089    // Unknown
6090    Unknown,
6091}
6092
6093impl DataType {
6094    /// Canonical unsigned names and their bit-width aliases. Parser entry points
6095    /// and legacy Custom-type normalization share this mapping.
6096    pub(crate) fn from_unsigned_name(name: &str) -> Option<Self> {
6097        match name.to_ascii_uppercase().as_str() {
6098            "UTINYINT" | "UINT8" => Some(Self::UInt8),
6099            "USMALLINT" | "UINT16" => Some(Self::UInt16),
6100            "UINTEGER" | "UINT32" => Some(Self::UInt32),
6101            "UBIGINT" | "UINT64" => Some(Self::UInt64),
6102            "UHUGEINT" | "UINT128" => Some(Self::UInt128),
6103            _ => None,
6104        }
6105    }
6106}
6107
6108/// Array expression
6109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6110#[cfg_attr(feature = "bindings", derive(TS))]
6111#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
6112pub struct Array {
6113    pub expressions: Vec<Expression>,
6114    /// Inferred array data type from type annotation
6115    #[serde(default, skip_serializing_if = "Option::is_none")]
6116    #[ast(skip)]
6117    pub inferred_type: Option<DataType>,
6118}
6119
6120/// Struct expression
6121#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6122#[cfg_attr(feature = "bindings", derive(TS))]
6123pub struct Struct {
6124    pub fields: Vec<(Option<String>, Expression)>,
6125}
6126
6127/// Tuple expression
6128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6129#[cfg_attr(feature = "bindings", derive(TS))]
6130pub struct Tuple {
6131    pub expressions: Vec<Expression>,
6132}
6133
6134/// Interval expression
6135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6136#[cfg_attr(feature = "bindings", derive(TS))]
6137pub struct Interval {
6138    /// The value expression (e.g., '1', 5, column_ref)
6139    pub this: Option<Expression>,
6140    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
6141    pub unit: Option<IntervalUnitSpec>,
6142}
6143
6144/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
6145#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6146#[cfg_attr(feature = "bindings", derive(TS))]
6147#[serde(tag = "type", rename_all = "snake_case")]
6148pub enum IntervalUnitSpec {
6149    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
6150    Simple {
6151        unit: IntervalUnit,
6152        /// Whether to use plural form (e.g., DAYS vs DAY)
6153        use_plural: bool,
6154    },
6155    /// Interval span (e.g., HOUR TO SECOND)
6156    Span(IntervalSpan),
6157    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6158    /// The start and end can be expressions like function calls with precision
6159    ExprSpan(IntervalSpanExpr),
6160    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6161    Expr(Box<Expression>),
6162}
6163
6164/// Interval span for ranges like HOUR TO SECOND
6165#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6166#[cfg_attr(feature = "bindings", derive(TS))]
6167pub struct IntervalSpan {
6168    /// Start unit (e.g., HOUR)
6169    pub this: IntervalUnit,
6170    /// End unit (e.g., SECOND)
6171    pub expression: IntervalUnit,
6172}
6173
6174/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6175/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6176#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6177#[cfg_attr(feature = "bindings", derive(TS))]
6178pub struct IntervalSpanExpr {
6179    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6180    pub this: Box<Expression>,
6181    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6182    pub expression: Box<Expression>,
6183}
6184
6185#[derive(
6186    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6187)]
6188#[cfg_attr(feature = "bindings", derive(TS))]
6189pub enum IntervalUnit {
6190    Year,
6191    Quarter,
6192    Month,
6193    Week,
6194    Day,
6195    Hour,
6196    Minute,
6197    Second,
6198    Millisecond,
6199    Microsecond,
6200    Nanosecond,
6201}
6202
6203/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6204#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6205#[cfg_attr(feature = "bindings", derive(TS))]
6206pub struct Command {
6207    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6208    pub this: String,
6209}
6210
6211/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6212/// Syntax: PREPARE name [(type, ...)] AS statement
6213#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6214#[cfg_attr(feature = "bindings", derive(TS))]
6215pub struct PrepareStatement {
6216    /// The prepared statement name.
6217    pub name: Identifier,
6218    /// Optional PostgreSQL parameter type list.
6219    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6220    pub parameter_types: Vec<DataType>,
6221    /// The statement to execute when the prepared statement is invoked.
6222    pub statement: Expression,
6223}
6224
6225/// T-SQL TRY/CATCH block.
6226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6227#[cfg_attr(feature = "bindings", derive(TS))]
6228pub struct TryCatch {
6229    /// Statements inside BEGIN TRY ... END TRY.
6230    #[serde(default)]
6231    pub try_body: Vec<Expression>,
6232    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6233    #[serde(default, skip_serializing_if = "Option::is_none")]
6234    pub catch_body: Option<Vec<Expression>>,
6235}
6236
6237/// EXEC/EXECUTE statement (TSQL stored procedure call)
6238/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6240#[cfg_attr(feature = "bindings", derive(TS))]
6241pub struct ExecuteStatement {
6242    /// The procedure name (can be qualified: schema.proc_name)
6243    pub this: Expression,
6244    /// Optional T-SQL return-status variable (`EXECUTE @status = procedure`).
6245    #[serde(default, skip_serializing_if = "Option::is_none")]
6246    pub return_status: Option<String>,
6247    /// Named parameters: @param=value pairs
6248    #[serde(default)]
6249    pub parameters: Vec<ExecuteParameter>,
6250    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6251    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6252    pub arguments: Vec<Expression>,
6253    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6254    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6255    pub prepared: bool,
6256    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6257    #[serde(default, skip_serializing_if = "Option::is_none")]
6258    pub suffix: Option<String>,
6259}
6260
6261/// Named parameter in EXEC statement: @name=value
6262#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6263#[cfg_attr(feature = "bindings", derive(TS))]
6264pub struct ExecuteParameter {
6265    /// Parameter name (including @)
6266    pub name: String,
6267    /// Parameter value
6268    pub value: Expression,
6269    /// Whether this is a positional parameter (no = sign)
6270    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6271    pub positional: bool,
6272    /// TSQL OUTPUT modifier on parameter
6273    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6274    pub output: bool,
6275}
6276
6277/// KILL statement (MySQL/MariaDB)
6278/// KILL [CONNECTION | QUERY] <id>
6279#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6280#[cfg_attr(feature = "bindings", derive(TS))]
6281pub struct Kill {
6282    /// The target (process ID or connection ID)
6283    pub this: Expression,
6284    /// Optional kind: "CONNECTION" or "QUERY"
6285    pub kind: Option<String>,
6286}
6287
6288/// Snowflake CREATE TASK statement
6289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6290#[cfg_attr(feature = "bindings", derive(TS))]
6291pub struct CreateTask {
6292    pub or_replace: bool,
6293    pub if_not_exists: bool,
6294    /// Task name (possibly qualified: db.schema.task)
6295    pub name: String,
6296    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6297    pub properties: String,
6298    /// The SQL statement body after AS
6299    pub body: Expression,
6300}
6301
6302/// Raw/unparsed SQL
6303#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6304#[cfg_attr(feature = "bindings", derive(TS))]
6305pub struct Raw {
6306    pub sql: String,
6307}
6308
6309// ============================================================================
6310// Function expression types
6311// ============================================================================
6312
6313/// Generic unary function (takes a single argument)
6314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6315#[cfg_attr(feature = "bindings", derive(TS))]
6316pub struct UnaryFunc {
6317    pub this: Expression,
6318    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6319    #[serde(skip_serializing_if = "Option::is_none", default)]
6320    pub original_name: Option<String>,
6321    /// Inferred data type from type annotation
6322    #[serde(default, skip_serializing_if = "Option::is_none")]
6323    #[ast(skip)]
6324    pub inferred_type: Option<DataType>,
6325}
6326
6327impl UnaryFunc {
6328    /// Create a new UnaryFunc with no original_name
6329    pub fn new(this: Expression) -> Self {
6330        Self {
6331            this,
6332            original_name: None,
6333            inferred_type: None,
6334        }
6335    }
6336
6337    /// Create a new UnaryFunc with an original name for round-trip preservation
6338    pub fn with_name(this: Expression, name: String) -> Self {
6339        Self {
6340            this,
6341            original_name: Some(name),
6342            inferred_type: None,
6343        }
6344    }
6345}
6346
6347/// CHAR/CHR function with multiple args and optional USING charset
6348/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6349/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6350#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6351#[cfg_attr(feature = "bindings", derive(TS))]
6352pub struct CharFunc {
6353    pub args: Vec<Expression>,
6354    #[serde(skip_serializing_if = "Option::is_none", default)]
6355    pub charset: Option<String>,
6356    /// Original function name (CHAR or CHR), defaults to CHAR
6357    #[serde(skip_serializing_if = "Option::is_none", default)]
6358    pub name: Option<String>,
6359}
6360
6361/// Generic binary function (takes two arguments)
6362#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6363#[cfg_attr(feature = "bindings", derive(TS))]
6364pub struct BinaryFunc {
6365    pub this: Expression,
6366    pub expression: Expression,
6367    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6368    #[serde(skip_serializing_if = "Option::is_none", default)]
6369    pub original_name: Option<String>,
6370    /// Inferred data type from type annotation
6371    #[serde(default, skip_serializing_if = "Option::is_none")]
6372    #[ast(skip)]
6373    pub inferred_type: Option<DataType>,
6374}
6375
6376/// Variable argument function
6377#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6378#[cfg_attr(feature = "bindings", derive(TS))]
6379pub struct VarArgFunc {
6380    pub expressions: Vec<Expression>,
6381    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6382    #[serde(skip_serializing_if = "Option::is_none", default)]
6383    pub original_name: Option<String>,
6384    /// Inferred data type from type annotation
6385    #[serde(default, skip_serializing_if = "Option::is_none")]
6386    #[ast(skip)]
6387    pub inferred_type: Option<DataType>,
6388}
6389
6390/// CONCAT_WS function
6391#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6392#[cfg_attr(feature = "bindings", derive(TS))]
6393pub struct ConcatWs {
6394    pub separator: Expression,
6395    pub expressions: Vec<Expression>,
6396}
6397
6398/// SUBSTRING function
6399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6400#[cfg_attr(feature = "bindings", derive(TS))]
6401pub struct SubstringFunc {
6402    pub this: Expression,
6403    pub start: Expression,
6404    pub length: Option<Expression>,
6405    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6406    #[serde(default)]
6407    pub from_for_syntax: bool,
6408}
6409
6410/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6412#[cfg_attr(feature = "bindings", derive(TS))]
6413pub struct OverlayFunc {
6414    pub this: Expression,
6415    pub replacement: Expression,
6416    pub from: Expression,
6417    pub length: Option<Expression>,
6418}
6419
6420/// TRIM function
6421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6422#[cfg_attr(feature = "bindings", derive(TS))]
6423pub struct TrimFunc {
6424    pub this: Expression,
6425    pub characters: Option<Expression>,
6426    pub position: TrimPosition,
6427    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6428    #[serde(default)]
6429    pub sql_standard_syntax: bool,
6430    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6431    #[serde(default)]
6432    pub position_explicit: bool,
6433    /// Inferred data type from type annotation
6434    #[serde(default, skip_serializing_if = "Option::is_none")]
6435    #[ast(skip)]
6436    pub inferred_type: Option<DataType>,
6437}
6438
6439#[derive(
6440    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6441)]
6442#[cfg_attr(feature = "bindings", derive(TS))]
6443pub enum TrimPosition {
6444    Both,
6445    Leading,
6446    Trailing,
6447}
6448
6449/// REPLACE function
6450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6451#[cfg_attr(feature = "bindings", derive(TS))]
6452pub struct ReplaceFunc {
6453    pub this: Expression,
6454    pub old: Expression,
6455    pub new: Expression,
6456}
6457
6458/// LEFT/RIGHT function
6459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6460#[cfg_attr(feature = "bindings", derive(TS))]
6461pub struct LeftRightFunc {
6462    pub this: Expression,
6463    pub length: Expression,
6464}
6465
6466/// REPEAT function
6467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6468#[cfg_attr(feature = "bindings", derive(TS))]
6469pub struct RepeatFunc {
6470    pub this: Expression,
6471    pub times: Expression,
6472}
6473
6474/// LPAD/RPAD function
6475#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6476#[cfg_attr(feature = "bindings", derive(TS))]
6477pub struct PadFunc {
6478    pub this: Expression,
6479    pub length: Expression,
6480    pub fill: Option<Expression>,
6481}
6482
6483/// SPLIT function
6484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6485#[cfg_attr(feature = "bindings", derive(TS))]
6486pub struct SplitFunc {
6487    pub this: Expression,
6488    pub delimiter: Expression,
6489}
6490
6491/// REGEXP_LIKE function
6492#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6493#[cfg_attr(feature = "bindings", derive(TS))]
6494pub struct RegexpFunc {
6495    pub this: Expression,
6496    pub pattern: Expression,
6497    pub flags: Option<Expression>,
6498}
6499
6500/// REGEXP_REPLACE function
6501#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6502#[cfg_attr(feature = "bindings", derive(TS))]
6503pub struct RegexpReplaceFunc {
6504    pub this: Expression,
6505    pub pattern: Expression,
6506    pub replacement: Expression,
6507    pub flags: Option<Expression>,
6508}
6509
6510/// REGEXP_EXTRACT function
6511#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6512#[cfg_attr(feature = "bindings", derive(TS))]
6513pub struct RegexpExtractFunc {
6514    pub this: Expression,
6515    pub pattern: Expression,
6516    pub group: Option<Expression>,
6517}
6518
6519/// ROUND function
6520#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6521#[cfg_attr(feature = "bindings", derive(TS))]
6522pub struct RoundFunc {
6523    pub this: Expression,
6524    pub decimals: Option<Expression>,
6525}
6526
6527/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6528#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6529#[cfg_attr(feature = "bindings", derive(TS))]
6530pub struct FloorFunc {
6531    pub this: Expression,
6532    pub scale: Option<Expression>,
6533    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6534    #[serde(skip_serializing_if = "Option::is_none", default)]
6535    pub to: Option<Expression>,
6536}
6537
6538/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6539#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6540#[cfg_attr(feature = "bindings", derive(TS))]
6541pub struct CeilFunc {
6542    pub this: Expression,
6543    #[serde(skip_serializing_if = "Option::is_none", default)]
6544    pub decimals: Option<Expression>,
6545    /// Time unit for Druid-style CEIL(time TO unit) syntax
6546    #[serde(skip_serializing_if = "Option::is_none", default)]
6547    pub to: Option<Expression>,
6548}
6549
6550/// LOG function
6551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6552#[cfg_attr(feature = "bindings", derive(TS))]
6553pub struct LogFunc {
6554    pub this: Expression,
6555    pub base: Option<Expression>,
6556}
6557
6558/// CURRENT_DATE (no arguments)
6559#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6560#[cfg_attr(feature = "bindings", derive(TS))]
6561pub struct CurrentDate;
6562
6563/// CURRENT_TIME
6564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6565#[cfg_attr(feature = "bindings", derive(TS))]
6566pub struct CurrentTime {
6567    pub precision: Option<u32>,
6568}
6569
6570/// CURRENT_TIMESTAMP
6571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6572#[cfg_attr(feature = "bindings", derive(TS))]
6573pub struct CurrentTimestamp {
6574    pub precision: Option<u32>,
6575    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6576    #[serde(default)]
6577    pub sysdate: bool,
6578}
6579
6580/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6582#[cfg_attr(feature = "bindings", derive(TS))]
6583pub struct CurrentTimestampLTZ {
6584    pub precision: Option<u32>,
6585}
6586
6587/// AT TIME ZONE expression for timezone conversion
6588#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6589#[cfg_attr(feature = "bindings", derive(TS))]
6590pub struct AtTimeZone {
6591    /// The expression to convert
6592    pub this: Expression,
6593    /// The target timezone
6594    pub zone: Expression,
6595}
6596
6597/// DATE_ADD / DATE_SUB function
6598#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6599#[cfg_attr(feature = "bindings", derive(TS))]
6600pub struct DateAddFunc {
6601    pub this: Expression,
6602    pub interval: Expression,
6603    pub unit: IntervalUnit,
6604}
6605
6606/// DATEDIFF function
6607#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6608#[cfg_attr(feature = "bindings", derive(TS))]
6609pub struct DateDiffFunc {
6610    pub this: Expression,
6611    pub expression: Expression,
6612    pub unit: Option<IntervalUnit>,
6613}
6614
6615/// DATE_TRUNC function
6616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6617#[cfg_attr(feature = "bindings", derive(TS))]
6618pub struct DateTruncFunc {
6619    pub this: Expression,
6620    pub unit: DateTimeField,
6621}
6622
6623/// EXTRACT function
6624#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6625#[cfg_attr(feature = "bindings", derive(TS))]
6626pub struct ExtractFunc {
6627    pub this: Expression,
6628    pub field: DateTimeField,
6629}
6630
6631#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6632#[cfg_attr(feature = "bindings", derive(TS))]
6633pub enum DateTimeField {
6634    Year,
6635    Month,
6636    Day,
6637    Hour,
6638    Minute,
6639    Second,
6640    Millisecond,
6641    Microsecond,
6642    DayOfWeek,
6643    DayOfYear,
6644    Week,
6645    /// Week with a modifier like WEEK(monday), WEEK(sunday)
6646    WeekWithModifier(String),
6647    Quarter,
6648    Epoch,
6649    Timezone,
6650    TimezoneHour,
6651    TimezoneMinute,
6652    Date,
6653    Time,
6654    /// Custom datetime field for dialect-specific or arbitrary fields
6655    Custom(String),
6656}
6657
6658/// TO_DATE function
6659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6660#[cfg_attr(feature = "bindings", derive(TS))]
6661pub struct ToDateFunc {
6662    pub this: Expression,
6663    pub format: Option<Expression>,
6664}
6665
6666/// TO_TIMESTAMP function
6667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6668#[cfg_attr(feature = "bindings", derive(TS))]
6669pub struct ToTimestampFunc {
6670    pub this: Expression,
6671    pub format: Option<Expression>,
6672}
6673
6674/// IF function
6675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6676#[cfg_attr(feature = "bindings", derive(TS))]
6677pub struct IfFunc {
6678    pub condition: Expression,
6679    pub true_value: Expression,
6680    pub false_value: Option<Expression>,
6681    /// Original function name (IF, IFF, IIF) for round-trip preservation
6682    #[serde(skip_serializing_if = "Option::is_none", default)]
6683    pub original_name: Option<String>,
6684    /// Inferred data type from type annotation
6685    #[serde(default, skip_serializing_if = "Option::is_none")]
6686    #[ast(skip)]
6687    pub inferred_type: Option<DataType>,
6688}
6689
6690/// NVL2 function
6691#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6692#[cfg_attr(feature = "bindings", derive(TS))]
6693pub struct Nvl2Func {
6694    pub this: Expression,
6695    pub true_value: Expression,
6696    pub false_value: Expression,
6697    /// Inferred data type from type annotation
6698    #[serde(default, skip_serializing_if = "Option::is_none")]
6699    #[ast(skip)]
6700    pub inferred_type: Option<DataType>,
6701}
6702
6703// ============================================================================
6704// Typed Aggregate Function types
6705// ============================================================================
6706
6707/// Generic aggregate function base type
6708#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6709#[cfg_attr(feature = "bindings", derive(TS))]
6710pub struct AggFunc {
6711    pub this: Expression,
6712    pub distinct: bool,
6713    pub filter: Option<Expression>,
6714    pub order_by: Vec<Ordered>,
6715    /// Original function name (case-preserving) when parsed from SQL
6716    #[serde(skip_serializing_if = "Option::is_none", default)]
6717    pub name: Option<String>,
6718    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
6719    #[serde(skip_serializing_if = "Option::is_none", default)]
6720    pub ignore_nulls: Option<bool>,
6721    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
6722    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
6723    #[serde(skip_serializing_if = "Option::is_none", default)]
6724    pub having_max: Option<(Box<Expression>, bool)>,
6725    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
6726    #[serde(skip_serializing_if = "Option::is_none", default)]
6727    pub limit: Option<Box<Expression>>,
6728    /// Inferred data type from type annotation
6729    #[serde(default, skip_serializing_if = "Option::is_none")]
6730    #[ast(skip)]
6731    pub inferred_type: Option<DataType>,
6732}
6733
6734/// COUNT function with optional star
6735#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6736#[cfg_attr(feature = "bindings", derive(TS))]
6737pub struct CountFunc {
6738    pub this: Option<Expression>,
6739    pub star: bool,
6740    pub distinct: bool,
6741    pub filter: Option<Expression>,
6742    /// IGNORE NULLS (true) or RESPECT NULLS (false)
6743    #[serde(default, skip_serializing_if = "Option::is_none")]
6744    pub ignore_nulls: Option<bool>,
6745    /// Original function name for case preservation (e.g., "count" or "COUNT")
6746    #[serde(default, skip_serializing_if = "Option::is_none")]
6747    pub original_name: Option<String>,
6748    /// Inferred data type from type annotation
6749    #[serde(default, skip_serializing_if = "Option::is_none")]
6750    #[ast(skip)]
6751    pub inferred_type: Option<DataType>,
6752}
6753
6754/// GROUP_CONCAT function (MySQL style)
6755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6756#[cfg_attr(feature = "bindings", derive(TS))]
6757pub struct GroupConcatFunc {
6758    pub this: Expression,
6759    pub separator: Option<Expression>,
6760    pub order_by: Option<Vec<Ordered>>,
6761    pub distinct: bool,
6762    pub filter: Option<Expression>,
6763    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
6764    #[serde(default, skip_serializing_if = "Option::is_none")]
6765    pub limit: Option<Box<Expression>>,
6766    /// Inferred data type from type annotation
6767    #[serde(default, skip_serializing_if = "Option::is_none")]
6768    #[ast(skip)]
6769    pub inferred_type: Option<DataType>,
6770}
6771
6772/// STRING_AGG function (PostgreSQL/Standard SQL)
6773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6774#[cfg_attr(feature = "bindings", derive(TS))]
6775pub struct StringAggFunc {
6776    pub this: Expression,
6777    #[serde(default)]
6778    pub separator: Option<Expression>,
6779    #[serde(default)]
6780    pub order_by: Option<Vec<Ordered>>,
6781    #[serde(default)]
6782    pub distinct: bool,
6783    #[serde(default)]
6784    pub filter: Option<Expression>,
6785    /// BigQuery LIMIT inside STRING_AGG
6786    #[serde(default, skip_serializing_if = "Option::is_none")]
6787    pub limit: Option<Box<Expression>>,
6788    /// Inferred data type from type annotation
6789    #[serde(default, skip_serializing_if = "Option::is_none")]
6790    #[ast(skip)]
6791    pub inferred_type: Option<DataType>,
6792}
6793
6794/// LISTAGG function (Oracle style)
6795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6796#[cfg_attr(feature = "bindings", derive(TS))]
6797pub struct ListAggFunc {
6798    pub this: Expression,
6799    pub separator: Option<Expression>,
6800    pub on_overflow: Option<ListAggOverflow>,
6801    pub order_by: Option<Vec<Ordered>>,
6802    pub distinct: bool,
6803    pub filter: Option<Expression>,
6804    /// Inferred data type from type annotation
6805    #[serde(default, skip_serializing_if = "Option::is_none")]
6806    #[ast(skip)]
6807    pub inferred_type: Option<DataType>,
6808}
6809
6810/// LISTAGG ON OVERFLOW behavior
6811#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6812#[cfg_attr(feature = "bindings", derive(TS))]
6813pub enum ListAggOverflow {
6814    Error,
6815    Truncate {
6816        filler: Option<Expression>,
6817        with_count: bool,
6818    },
6819}
6820
6821/// SUM_IF / COUNT_IF function
6822#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6823#[cfg_attr(feature = "bindings", derive(TS))]
6824pub struct SumIfFunc {
6825    pub this: Expression,
6826    pub condition: Expression,
6827    pub filter: Option<Expression>,
6828    /// Inferred data type from type annotation
6829    #[serde(default, skip_serializing_if = "Option::is_none")]
6830    #[ast(skip)]
6831    pub inferred_type: Option<DataType>,
6832}
6833
6834/// APPROX_PERCENTILE function
6835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6836#[cfg_attr(feature = "bindings", derive(TS))]
6837pub struct ApproxPercentileFunc {
6838    pub this: Expression,
6839    pub percentile: Expression,
6840    pub accuracy: Option<Expression>,
6841    pub filter: Option<Expression>,
6842}
6843
6844/// PERCENTILE_CONT / PERCENTILE_DISC function
6845#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6846#[cfg_attr(feature = "bindings", derive(TS))]
6847pub struct PercentileFunc {
6848    pub this: Expression,
6849    pub percentile: Expression,
6850    pub order_by: Option<Vec<Ordered>>,
6851    pub filter: Option<Expression>,
6852}
6853
6854// ============================================================================
6855// Typed Window Function types
6856// ============================================================================
6857
6858/// ROW_NUMBER function (no arguments)
6859#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6860#[cfg_attr(feature = "bindings", derive(TS))]
6861pub struct RowNumber;
6862
6863/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6865#[cfg_attr(feature = "bindings", derive(TS))]
6866pub struct Rank {
6867    /// DuckDB: RANK(ORDER BY col) - order by inside function
6868    #[serde(default, skip_serializing_if = "Option::is_none")]
6869    pub order_by: Option<Vec<Ordered>>,
6870    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6871    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6872    pub args: Vec<Expression>,
6873}
6874
6875/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
6876#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6877#[cfg_attr(feature = "bindings", derive(TS))]
6878pub struct DenseRank {
6879    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6880    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6881    pub args: Vec<Expression>,
6882}
6883
6884/// NTILE function (DuckDB allows ORDER BY inside)
6885#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6886#[cfg_attr(feature = "bindings", derive(TS))]
6887pub struct NTileFunc {
6888    /// num_buckets is optional to support Databricks NTILE() without arguments
6889    #[serde(default, skip_serializing_if = "Option::is_none")]
6890    pub num_buckets: Option<Expression>,
6891    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
6892    #[serde(default, skip_serializing_if = "Option::is_none")]
6893    pub order_by: Option<Vec<Ordered>>,
6894}
6895
6896/// LEAD / LAG function
6897#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6898#[cfg_attr(feature = "bindings", derive(TS))]
6899pub struct LeadLagFunc {
6900    pub this: Expression,
6901    pub offset: Option<Expression>,
6902    pub default: Option<Expression>,
6903    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6904    #[serde(default, skip_serializing_if = "Option::is_none")]
6905    pub ignore_nulls: Option<bool>,
6906}
6907
6908/// FIRST_VALUE / LAST_VALUE function
6909#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6910#[cfg_attr(feature = "bindings", derive(TS))]
6911pub struct ValueFunc {
6912    pub this: Expression,
6913    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6914    #[serde(default, skip_serializing_if = "Option::is_none")]
6915    pub ignore_nulls: Option<bool>,
6916    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
6917    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6918    pub order_by: Vec<Ordered>,
6919}
6920
6921/// NTH_VALUE function
6922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6923#[cfg_attr(feature = "bindings", derive(TS))]
6924pub struct NthValueFunc {
6925    pub this: Expression,
6926    pub offset: Expression,
6927    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6928    #[serde(default, skip_serializing_if = "Option::is_none")]
6929    pub ignore_nulls: Option<bool>,
6930    /// Snowflake FROM FIRST / FROM LAST clause
6931    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
6932    #[serde(default, skip_serializing_if = "Option::is_none")]
6933    pub from_first: Option<bool>,
6934}
6935
6936/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6938#[cfg_attr(feature = "bindings", derive(TS))]
6939pub struct PercentRank {
6940    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
6941    #[serde(default, skip_serializing_if = "Option::is_none")]
6942    pub order_by: Option<Vec<Ordered>>,
6943    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6944    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6945    pub args: Vec<Expression>,
6946}
6947
6948/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6949#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6950#[cfg_attr(feature = "bindings", derive(TS))]
6951pub struct CumeDist {
6952    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
6953    #[serde(default, skip_serializing_if = "Option::is_none")]
6954    pub order_by: Option<Vec<Ordered>>,
6955    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6956    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6957    pub args: Vec<Expression>,
6958}
6959
6960// ============================================================================
6961// Additional String Function types
6962// ============================================================================
6963
6964/// POSITION/INSTR function
6965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6966#[cfg_attr(feature = "bindings", derive(TS))]
6967pub struct PositionFunc {
6968    pub substring: Expression,
6969    pub string: Expression,
6970    pub start: Option<Expression>,
6971}
6972
6973// ============================================================================
6974// Additional Math Function types
6975// ============================================================================
6976
6977/// RANDOM function (no arguments)
6978#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6979#[cfg_attr(feature = "bindings", derive(TS))]
6980pub struct Random;
6981
6982/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
6983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6984#[cfg_attr(feature = "bindings", derive(TS))]
6985pub struct Rand {
6986    pub seed: Option<Box<Expression>>,
6987    /// Teradata RANDOM lower bound
6988    #[serde(default)]
6989    pub lower: Option<Box<Expression>>,
6990    /// Teradata RANDOM upper bound
6991    #[serde(default)]
6992    pub upper: Option<Box<Expression>>,
6993}
6994
6995/// TRUNCATE / TRUNC function
6996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6997#[cfg_attr(feature = "bindings", derive(TS))]
6998pub struct TruncateFunc {
6999    pub this: Expression,
7000    pub decimals: Option<Expression>,
7001}
7002
7003/// PI function (no arguments)
7004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7005#[cfg_attr(feature = "bindings", derive(TS))]
7006pub struct Pi;
7007
7008// ============================================================================
7009// Control Flow Function types
7010// ============================================================================
7011
7012/// DECODE function (Oracle style)
7013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7014#[cfg_attr(feature = "bindings", derive(TS))]
7015pub struct DecodeFunc {
7016    pub this: Expression,
7017    pub search_results: Vec<(Expression, Expression)>,
7018    pub default: Option<Expression>,
7019}
7020
7021// ============================================================================
7022// Additional Date/Time Function types
7023// ============================================================================
7024
7025/// DATE_FORMAT / FORMAT_DATE function
7026#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7027#[cfg_attr(feature = "bindings", derive(TS))]
7028pub struct DateFormatFunc {
7029    pub this: Expression,
7030    pub format: Expression,
7031}
7032
7033/// FROM_UNIXTIME function
7034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7035#[cfg_attr(feature = "bindings", derive(TS))]
7036pub struct FromUnixtimeFunc {
7037    pub this: Expression,
7038    pub format: Option<Expression>,
7039}
7040
7041/// UNIX_TIMESTAMP function
7042#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7043#[cfg_attr(feature = "bindings", derive(TS))]
7044pub struct UnixTimestampFunc {
7045    pub this: Option<Expression>,
7046    pub format: Option<Expression>,
7047}
7048
7049/// MAKE_DATE function
7050#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7051#[cfg_attr(feature = "bindings", derive(TS))]
7052pub struct MakeDateFunc {
7053    pub year: Expression,
7054    pub month: Expression,
7055    pub day: Expression,
7056}
7057
7058/// MAKE_TIMESTAMP function
7059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7060#[cfg_attr(feature = "bindings", derive(TS))]
7061pub struct MakeTimestampFunc {
7062    pub year: Expression,
7063    pub month: Expression,
7064    pub day: Expression,
7065    pub hour: Expression,
7066    pub minute: Expression,
7067    pub second: Expression,
7068    pub timezone: Option<Expression>,
7069}
7070
7071/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
7072#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7073#[cfg_attr(feature = "bindings", derive(TS))]
7074pub struct LastDayFunc {
7075    pub this: Expression,
7076    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
7077    #[serde(skip_serializing_if = "Option::is_none", default)]
7078    pub unit: Option<DateTimeField>,
7079}
7080
7081// ============================================================================
7082// Array Function types
7083// ============================================================================
7084
7085/// ARRAY constructor
7086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7087#[cfg_attr(feature = "bindings", derive(TS))]
7088pub struct ArrayConstructor {
7089    pub expressions: Vec<Expression>,
7090    pub bracket_notation: bool,
7091    /// True if LIST keyword was used instead of ARRAY (DuckDB)
7092    pub use_list_keyword: bool,
7093    /// Inferred array data type from type annotation
7094    #[serde(default, skip_serializing_if = "Option::is_none")]
7095    #[ast(skip)]
7096    pub inferred_type: Option<DataType>,
7097}
7098
7099/// ARRAY_SORT function
7100#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7101#[cfg_attr(feature = "bindings", derive(TS))]
7102pub struct ArraySortFunc {
7103    pub this: Expression,
7104    pub comparator: Option<Expression>,
7105    pub desc: bool,
7106    pub nulls_first: Option<bool>,
7107}
7108
7109/// ARRAY_JOIN / ARRAY_TO_STRING function
7110#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7111#[cfg_attr(feature = "bindings", derive(TS))]
7112pub struct ArrayJoinFunc {
7113    pub this: Expression,
7114    pub separator: Expression,
7115    pub null_replacement: Option<Expression>,
7116}
7117
7118/// UNNEST function
7119#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7120#[cfg_attr(feature = "bindings", derive(TS))]
7121pub struct UnnestFunc {
7122    pub this: Expression,
7123    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
7124    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7125    pub expressions: Vec<Expression>,
7126    pub with_ordinality: bool,
7127    pub alias: Option<Identifier>,
7128    /// BigQuery: offset alias for WITH OFFSET AS <name>
7129    #[serde(default, skip_serializing_if = "Option::is_none")]
7130    pub offset_alias: Option<Identifier>,
7131    /// Inferred type of the first UNNEST output column.
7132    #[serde(default, skip_serializing_if = "Option::is_none")]
7133    #[ast(skip)]
7134    pub inferred_type: Option<DataType>,
7135}
7136
7137/// ARRAY_FILTER function (with lambda)
7138#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7139#[cfg_attr(feature = "bindings", derive(TS))]
7140pub struct ArrayFilterFunc {
7141    pub this: Expression,
7142    pub filter: Expression,
7143}
7144
7145/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
7146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7147#[cfg_attr(feature = "bindings", derive(TS))]
7148pub struct ArrayTransformFunc {
7149    pub this: Expression,
7150    pub transform: Expression,
7151}
7152
7153/// SEQUENCE / GENERATE_SERIES function
7154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7155#[cfg_attr(feature = "bindings", derive(TS))]
7156pub struct SequenceFunc {
7157    pub start: Expression,
7158    pub stop: Expression,
7159    pub step: Option<Expression>,
7160}
7161
7162// ============================================================================
7163// Struct Function types
7164// ============================================================================
7165
7166/// STRUCT constructor
7167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7168#[cfg_attr(feature = "bindings", derive(TS))]
7169pub struct StructConstructor {
7170    pub fields: Vec<(Option<Identifier>, Expression)>,
7171}
7172
7173/// STRUCT_EXTRACT function
7174#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7175#[cfg_attr(feature = "bindings", derive(TS))]
7176pub struct StructExtractFunc {
7177    pub this: Expression,
7178    pub field: Identifier,
7179}
7180
7181/// NAMED_STRUCT function
7182#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7183#[cfg_attr(feature = "bindings", derive(TS))]
7184pub struct NamedStructFunc {
7185    pub pairs: Vec<(Expression, Expression)>,
7186}
7187
7188// ============================================================================
7189// Map Function types
7190// ============================================================================
7191
7192/// MAP constructor
7193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7194#[cfg_attr(feature = "bindings", derive(TS))]
7195pub struct MapConstructor {
7196    pub keys: Vec<Expression>,
7197    pub values: Vec<Expression>,
7198    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7199    #[serde(default)]
7200    pub curly_brace_syntax: bool,
7201    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7202    #[serde(default)]
7203    pub with_map_keyword: bool,
7204}
7205
7206/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7207#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7208#[cfg_attr(feature = "bindings", derive(TS))]
7209pub struct TransformFunc {
7210    pub this: Expression,
7211    pub transform: Expression,
7212}
7213
7214/// Function call with EMITS clause (Exasol)
7215/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7217#[cfg_attr(feature = "bindings", derive(TS))]
7218pub struct FunctionEmits {
7219    /// The function call expression
7220    pub this: Expression,
7221    /// The EMITS schema definition
7222    pub emits: Expression,
7223}
7224
7225// ============================================================================
7226// JSON Function types
7227// ============================================================================
7228
7229/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7230#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7231#[cfg_attr(feature = "bindings", derive(TS))]
7232pub struct JsonExtractFunc {
7233    pub this: Expression,
7234    pub path: Expression,
7235    pub returning: Option<DataType>,
7236    /// True if parsed from -> or ->> operator syntax
7237    #[serde(default)]
7238    pub arrow_syntax: bool,
7239    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7240    #[serde(default)]
7241    pub hash_arrow_syntax: bool,
7242    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7243    #[serde(default)]
7244    pub wrapper_option: Option<String>,
7245    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7246    #[serde(default)]
7247    pub quotes_option: Option<String>,
7248    /// ON SCALAR STRING flag
7249    #[serde(default)]
7250    pub on_scalar_string: bool,
7251    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7252    #[serde(default)]
7253    pub on_error: Option<String>,
7254}
7255
7256/// JSON path extraction
7257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7258#[cfg_attr(feature = "bindings", derive(TS))]
7259pub struct JsonPathFunc {
7260    pub this: Expression,
7261    pub paths: Vec<Expression>,
7262}
7263
7264/// JSON_OBJECT function
7265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7266#[cfg_attr(feature = "bindings", derive(TS))]
7267pub struct JsonObjectFunc {
7268    pub pairs: Vec<(Expression, Expression)>,
7269    pub null_handling: Option<JsonNullHandling>,
7270    #[serde(default)]
7271    pub with_unique_keys: bool,
7272    #[serde(default)]
7273    pub returning_type: Option<DataType>,
7274    #[serde(default)]
7275    pub format_json: bool,
7276    #[serde(default)]
7277    pub encoding: Option<String>,
7278    /// For JSON_OBJECT(*) syntax
7279    #[serde(default)]
7280    pub star: bool,
7281}
7282
7283/// JSON null handling options
7284#[derive(
7285    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7286)]
7287#[cfg_attr(feature = "bindings", derive(TS))]
7288pub enum JsonNullHandling {
7289    NullOnNull,
7290    AbsentOnNull,
7291}
7292
7293/// JSON_SET / JSON_INSERT function
7294#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7295#[cfg_attr(feature = "bindings", derive(TS))]
7296pub struct JsonModifyFunc {
7297    pub this: Expression,
7298    pub path_values: Vec<(Expression, Expression)>,
7299}
7300
7301/// JSON_ARRAYAGG function
7302#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7303#[cfg_attr(feature = "bindings", derive(TS))]
7304pub struct JsonArrayAggFunc {
7305    pub this: Expression,
7306    pub order_by: Option<Vec<Ordered>>,
7307    pub null_handling: Option<JsonNullHandling>,
7308    pub filter: Option<Expression>,
7309}
7310
7311/// JSON_OBJECTAGG function
7312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7313#[cfg_attr(feature = "bindings", derive(TS))]
7314pub struct JsonObjectAggFunc {
7315    pub key: Expression,
7316    pub value: Expression,
7317    pub null_handling: Option<JsonNullHandling>,
7318    pub filter: Option<Expression>,
7319}
7320
7321// ============================================================================
7322// Type Casting Function types
7323// ============================================================================
7324
7325/// CONVERT function (SQL Server style)
7326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7327#[cfg_attr(feature = "bindings", derive(TS))]
7328pub struct ConvertFunc {
7329    pub this: Expression,
7330    pub to: DataType,
7331    pub style: Option<Expression>,
7332}
7333
7334// ============================================================================
7335// Additional Expression types
7336// ============================================================================
7337
7338/// Lambda expression
7339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7340#[cfg_attr(feature = "bindings", derive(TS))]
7341pub struct LambdaExpr {
7342    pub parameters: Vec<Identifier>,
7343    pub body: Expression,
7344    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7345    #[serde(default)]
7346    pub colon: bool,
7347    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7348    /// Maps parameter index to data type
7349    #[serde(default)]
7350    pub parameter_types: Vec<Option<DataType>>,
7351}
7352
7353/// Parameter (parameterized queries)
7354#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7355#[cfg_attr(feature = "bindings", derive(TS))]
7356pub struct Parameter {
7357    pub name: Option<String>,
7358    pub index: Option<u32>,
7359    pub style: ParameterStyle,
7360    /// Whether the name was quoted (e.g., @"x" vs @x)
7361    #[serde(default)]
7362    pub quoted: bool,
7363    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7364    #[serde(default)]
7365    pub string_quoted: bool,
7366    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7367    #[serde(default)]
7368    pub expression: Option<String>,
7369}
7370
7371/// Parameter placeholder styles
7372#[derive(
7373    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7374)]
7375#[cfg_attr(feature = "bindings", derive(TS))]
7376pub enum ParameterStyle {
7377    Question,     // ?
7378    Dollar,       // $1, $2
7379    DollarBrace,  // ${name} (Databricks, Hive template variables)
7380    Brace,        // {name} (Spark/Databricks widget/template variables)
7381    Colon,        // :name
7382    At,           // @name
7383    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7384    DoubleDollar, // $$name
7385    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7386}
7387
7388/// Placeholder expression
7389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7390#[cfg_attr(feature = "bindings", derive(TS))]
7391pub struct Placeholder {
7392    pub index: Option<u32>,
7393}
7394
7395/// Named argument in function call: name => value or name := value
7396#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7397#[cfg_attr(feature = "bindings", derive(TS))]
7398pub struct NamedArgument {
7399    pub name: Identifier,
7400    pub value: Expression,
7401    /// The separator used: `=>`, `:=`, or `=`
7402    pub separator: NamedArgSeparator,
7403}
7404
7405/// Separator style for named arguments
7406#[derive(
7407    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7408)]
7409#[cfg_attr(feature = "bindings", derive(TS))]
7410pub enum NamedArgSeparator {
7411    /// `=>` (standard SQL, Snowflake, BigQuery)
7412    DArrow,
7413    /// `:=` (Oracle, MySQL)
7414    ColonEq,
7415    /// `=` (simple equals, some dialects)
7416    Eq,
7417}
7418
7419/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7420/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7422#[cfg_attr(feature = "bindings", derive(TS))]
7423pub struct TableArgument {
7424    /// The keyword prefix: "TABLE" or "MODEL"
7425    pub prefix: String,
7426    /// The table/model reference expression
7427    pub this: Expression,
7428}
7429
7430/// SQL Comment preservation
7431#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7432#[cfg_attr(feature = "bindings", derive(TS))]
7433pub struct SqlComment {
7434    pub text: String,
7435    pub is_block: bool,
7436}
7437
7438// ============================================================================
7439// Additional Predicate types
7440// ============================================================================
7441
7442/// SIMILAR TO expression
7443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7444#[cfg_attr(feature = "bindings", derive(TS))]
7445pub struct SimilarToExpr {
7446    pub this: Expression,
7447    pub pattern: Expression,
7448    pub escape: Option<Expression>,
7449    pub not: bool,
7450}
7451
7452/// ANY / ALL quantified expression
7453#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7454#[cfg_attr(feature = "bindings", derive(TS))]
7455pub struct QuantifiedExpr {
7456    pub this: Expression,
7457    pub subquery: Expression,
7458    pub op: Option<QuantifiedOp>,
7459}
7460
7461/// Comparison operator for quantified expressions
7462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7463#[cfg_attr(feature = "bindings", derive(TS))]
7464pub enum QuantifiedOp {
7465    Eq,
7466    Neq,
7467    Lt,
7468    Lte,
7469    Gt,
7470    Gte,
7471}
7472
7473/// OVERLAPS expression
7474/// Supports two forms:
7475/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7476/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7478#[cfg_attr(feature = "bindings", derive(TS))]
7479pub struct OverlapsExpr {
7480    /// Left operand for simple binary form
7481    #[serde(skip_serializing_if = "Option::is_none")]
7482    pub this: Option<Expression>,
7483    /// Right operand for simple binary form
7484    #[serde(skip_serializing_if = "Option::is_none")]
7485    pub expression: Option<Expression>,
7486    /// Left range start for full ANSI form
7487    #[serde(skip_serializing_if = "Option::is_none")]
7488    pub left_start: Option<Expression>,
7489    /// Left range end for full ANSI form
7490    #[serde(skip_serializing_if = "Option::is_none")]
7491    pub left_end: Option<Expression>,
7492    /// Right range start for full ANSI form
7493    #[serde(skip_serializing_if = "Option::is_none")]
7494    pub right_start: Option<Expression>,
7495    /// Right range end for full ANSI form
7496    #[serde(skip_serializing_if = "Option::is_none")]
7497    pub right_end: Option<Expression>,
7498}
7499
7500// ============================================================================
7501// Array/Struct/Map access
7502// ============================================================================
7503
7504/// Subscript access (array[index] or map[key])
7505#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7506#[cfg_attr(feature = "bindings", derive(TS))]
7507pub struct Subscript {
7508    pub this: Expression,
7509    pub index: Expression,
7510}
7511
7512/// Dot access (struct.field)
7513#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7514#[cfg_attr(feature = "bindings", derive(TS))]
7515pub struct DotAccess {
7516    pub this: Expression,
7517    pub field: Identifier,
7518    #[serde(default, skip_serializing_if = "Option::is_none")]
7519    pub inferred_type: Option<DataType>,
7520}
7521
7522/// Method call (expr.method(args))
7523#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7524#[cfg_attr(feature = "bindings", derive(TS))]
7525pub struct MethodCall {
7526    pub this: Expression,
7527    pub method: Identifier,
7528    pub args: Vec<Expression>,
7529}
7530
7531/// Array slice (array[start:end])
7532#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7533#[cfg_attr(feature = "bindings", derive(TS))]
7534pub struct ArraySlice {
7535    pub this: Expression,
7536    pub start: Option<Expression>,
7537    pub end: Option<Expression>,
7538}
7539
7540// ============================================================================
7541// DDL (Data Definition Language) Statements
7542// ============================================================================
7543
7544/// ON COMMIT behavior for temporary tables
7545#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7546#[cfg_attr(feature = "bindings", derive(TS))]
7547pub enum OnCommit {
7548    /// ON COMMIT PRESERVE ROWS
7549    PreserveRows,
7550    /// ON COMMIT DELETE ROWS
7551    DeleteRows,
7552}
7553
7554/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
7555#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7556#[cfg_attr(feature = "bindings", derive(TS))]
7557pub struct TiDBAutoRandom {
7558    #[serde(default, skip_serializing_if = "Option::is_none")]
7559    pub shard_bits: Option<u64>,
7560    #[serde(default, skip_serializing_if = "Option::is_none")]
7561    pub range_bits: Option<u64>,
7562    /// Whether the attribute was wrapped in a TiDB executable comment.
7563    #[serde(default)]
7564    pub executable_comment: bool,
7565}
7566
7567/// A TiDB-specific table option and its source syntax.
7568#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7569#[cfg_attr(feature = "bindings", derive(TS))]
7570pub struct TiDBTableOption {
7571    pub kind: TiDBTableOptionKind,
7572    /// Whether the option was wrapped in a TiDB executable comment.
7573    #[serde(default)]
7574    pub executable_comment: bool,
7575}
7576
7577/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
7578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7579#[cfg_attr(feature = "bindings", derive(TS))]
7580#[serde(tag = "type", rename_all = "snake_case")]
7581pub enum TiDBTableOptionKind {
7582    ShardRowIdBits {
7583        bits: u64,
7584    },
7585    PreSplitRegions {
7586        regions: u64,
7587    },
7588    AutoRandomBase {
7589        value: u64,
7590    },
7591    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
7592    PlacementPolicy {
7593        policy: Option<Identifier>,
7594    },
7595    Ttl {
7596        column: Identifier,
7597        interval: Interval,
7598        #[serde(default, skip_serializing_if = "Option::is_none")]
7599        enabled: Option<bool>,
7600    },
7601    TtlEnable {
7602        enabled: bool,
7603    },
7604    TtlJobInterval {
7605        interval: String,
7606    },
7607}
7608
7609/// CREATE TABLE statement
7610#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7611#[cfg_attr(feature = "bindings", derive(TS))]
7612pub struct CreateTable {
7613    pub name: TableRef,
7614    /// ClickHouse: ON CLUSTER clause for distributed DDL
7615    #[serde(default, skip_serializing_if = "Option::is_none")]
7616    pub on_cluster: Option<OnCluster>,
7617    pub columns: Vec<ColumnDef>,
7618    pub constraints: Vec<TableConstraint>,
7619    pub if_not_exists: bool,
7620    pub temporary: bool,
7621    pub or_replace: bool,
7622    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
7623    #[serde(default, skip_serializing_if = "Option::is_none")]
7624    pub table_modifier: Option<String>,
7625    pub as_select: Option<Expression>,
7626    /// Whether the AS SELECT was wrapped in parentheses
7627    #[serde(default)]
7628    pub as_select_parenthesized: bool,
7629    /// ON COMMIT behavior for temporary tables
7630    #[serde(default)]
7631    pub on_commit: Option<OnCommit>,
7632    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
7633    #[serde(default)]
7634    pub clone_source: Option<TableRef>,
7635    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
7636    #[serde(default, skip_serializing_if = "Option::is_none")]
7637    pub clone_at_clause: Option<Expression>,
7638    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
7639    #[serde(default)]
7640    pub is_copy: bool,
7641    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
7642    #[serde(default)]
7643    pub shallow_clone: bool,
7644    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
7645    #[serde(default)]
7646    pub deep_clone: bool,
7647    /// Leading comments before the statement
7648    #[serde(default)]
7649    pub leading_comments: Vec<String>,
7650    /// WITH properties (e.g., WITH (FORMAT='parquet'))
7651    #[serde(default)]
7652    pub with_properties: Vec<(String, String)>,
7653    /// Teradata: table options after name before columns (comma-separated)
7654    #[serde(default)]
7655    pub teradata_post_name_options: Vec<String>,
7656    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
7657    #[serde(default)]
7658    pub with_data: Option<bool>,
7659    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
7660    #[serde(default)]
7661    pub with_statistics: Option<bool>,
7662    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
7663    #[serde(default)]
7664    pub teradata_indexes: Vec<TeradataIndex>,
7665    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
7666    #[serde(default)]
7667    pub with_cte: Option<With>,
7668    /// Table properties like DEFAULT COLLATE (BigQuery)
7669    #[serde(default)]
7670    pub properties: Vec<Expression>,
7671    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
7672    #[serde(default, skip_serializing_if = "Option::is_none")]
7673    pub partition_of: Option<Expression>,
7674    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
7675    #[serde(default)]
7676    pub post_table_properties: Vec<Expression>,
7677    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
7678    #[serde(default)]
7679    pub mysql_table_options: Vec<(String, String)>,
7680    /// TiDB-specific table options after column definitions.
7681    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7682    pub tidb_table_options: Vec<TiDBTableOption>,
7683    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
7684    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7685    pub inherits: Vec<TableRef>,
7686    /// TSQL ON filegroup or ON filegroup (partition_column) clause
7687    #[serde(default, skip_serializing_if = "Option::is_none")]
7688    pub on_property: Option<OnProperty>,
7689    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
7690    #[serde(default)]
7691    pub copy_grants: bool,
7692    /// Snowflake: USING TEMPLATE expression for schema inference
7693    #[serde(default, skip_serializing_if = "Option::is_none")]
7694    pub using_template: Option<Box<Expression>>,
7695    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
7696    #[serde(default, skip_serializing_if = "Option::is_none")]
7697    pub rollup: Option<RollupProperty>,
7698    /// ClickHouse: UUID 'xxx' clause after table name
7699    #[serde(default, skip_serializing_if = "Option::is_none")]
7700    pub uuid: Option<String>,
7701    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
7702    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
7703    /// could appear in other engines.
7704    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7705    pub with_partition_columns: Vec<ColumnDef>,
7706    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
7707    /// for external tables that reference a Cloud Resource connection.
7708    #[serde(default, skip_serializing_if = "Option::is_none")]
7709    pub with_connection: Option<TableRef>,
7710}
7711
7712/// Teradata index specification for CREATE TABLE
7713#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7714#[cfg_attr(feature = "bindings", derive(TS))]
7715pub struct TeradataIndex {
7716    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
7717    pub kind: TeradataIndexKind,
7718    /// Optional index name
7719    pub name: Option<String>,
7720    /// Optional column list
7721    pub columns: Vec<String>,
7722}
7723
7724/// Kind of Teradata index
7725#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7726#[cfg_attr(feature = "bindings", derive(TS))]
7727pub enum TeradataIndexKind {
7728    /// NO PRIMARY INDEX
7729    NoPrimary,
7730    /// PRIMARY INDEX
7731    Primary,
7732    /// PRIMARY AMP INDEX
7733    PrimaryAmp,
7734    /// UNIQUE INDEX
7735    Unique,
7736    /// UNIQUE PRIMARY INDEX
7737    UniquePrimary,
7738    /// INDEX (secondary, non-primary)
7739    Secondary,
7740}
7741
7742impl CreateTable {
7743    pub fn new(name: impl Into<String>) -> Self {
7744        Self {
7745            name: TableRef::new(name),
7746            on_cluster: None,
7747            columns: Vec::new(),
7748            constraints: Vec::new(),
7749            if_not_exists: false,
7750            temporary: false,
7751            or_replace: false,
7752            table_modifier: None,
7753            as_select: None,
7754            as_select_parenthesized: false,
7755            on_commit: None,
7756            clone_source: None,
7757            clone_at_clause: None,
7758            shallow_clone: false,
7759            deep_clone: false,
7760            is_copy: false,
7761            leading_comments: Vec::new(),
7762            with_properties: Vec::new(),
7763            teradata_post_name_options: Vec::new(),
7764            with_data: None,
7765            with_statistics: None,
7766            teradata_indexes: Vec::new(),
7767            with_cte: None,
7768            properties: Vec::new(),
7769            partition_of: None,
7770            post_table_properties: Vec::new(),
7771            mysql_table_options: Vec::new(),
7772            tidb_table_options: Vec::new(),
7773            inherits: Vec::new(),
7774            on_property: None,
7775            copy_grants: false,
7776            using_template: None,
7777            rollup: None,
7778            uuid: None,
7779            with_partition_columns: Vec::new(),
7780            with_connection: None,
7781        }
7782    }
7783}
7784
7785/// Sort order for PRIMARY KEY ASC/DESC
7786#[derive(
7787    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
7788)]
7789#[cfg_attr(feature = "bindings", derive(TS))]
7790pub enum SortOrder {
7791    Asc,
7792    Desc,
7793}
7794
7795/// Type of column constraint for tracking order
7796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7797#[cfg_attr(feature = "bindings", derive(TS))]
7798pub enum ConstraintType {
7799    NotNull,
7800    Null,
7801    PrimaryKey,
7802    Unique,
7803    Default,
7804    AutoIncrement,
7805    AutoRandom,
7806    Collate,
7807    Comment,
7808    References,
7809    Check,
7810    GeneratedAsIdentity,
7811    /// Snowflake: TAG (key='value', ...)
7812    Tags,
7813    /// Computed/generated column
7814    ComputedColumn,
7815    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
7816    GeneratedAsRow,
7817    /// MySQL: ON UPDATE expression
7818    OnUpdate,
7819    /// PATH constraint for XMLTABLE/JSON_TABLE columns
7820    Path,
7821    /// Redshift: ENCODE encoding_type
7822    Encode,
7823}
7824
7825/// Column definition in CREATE TABLE
7826#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7827#[cfg_attr(feature = "bindings", derive(TS))]
7828pub struct ColumnDef {
7829    pub name: Identifier,
7830    pub data_type: DataType,
7831    pub nullable: Option<bool>,
7832    pub default: Option<Expression>,
7833    pub primary_key: bool,
7834    /// Sort order for PRIMARY KEY (ASC/DESC)
7835    #[serde(default)]
7836    pub primary_key_order: Option<SortOrder>,
7837    pub unique: bool,
7838    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
7839    #[serde(default)]
7840    pub unique_nulls_not_distinct: bool,
7841    pub auto_increment: bool,
7842    /// TiDB distributed primary-key allocation attribute.
7843    #[serde(default, skip_serializing_if = "Option::is_none")]
7844    pub auto_random: Option<TiDBAutoRandom>,
7845    pub comment: Option<String>,
7846    pub constraints: Vec<ColumnConstraint>,
7847    /// Track original order of constraints for accurate regeneration
7848    #[serde(default)]
7849    pub constraint_order: Vec<ConstraintType>,
7850    /// Teradata: FORMAT 'pattern'
7851    #[serde(default)]
7852    pub format: Option<String>,
7853    /// Teradata: TITLE 'title'
7854    #[serde(default)]
7855    pub title: Option<String>,
7856    /// Teradata: INLINE LENGTH n
7857    #[serde(default)]
7858    pub inline_length: Option<u64>,
7859    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
7860    #[serde(default)]
7861    pub compress: Option<Vec<Expression>>,
7862    /// Teradata: CHARACTER SET name
7863    #[serde(default)]
7864    pub character_set: Option<String>,
7865    /// Teradata: UPPERCASE
7866    #[serde(default)]
7867    pub uppercase: bool,
7868    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
7869    #[serde(default)]
7870    pub casespecific: Option<bool>,
7871    /// Snowflake: AUTOINCREMENT START value
7872    #[serde(default)]
7873    pub auto_increment_start: Option<Box<Expression>>,
7874    /// Snowflake: AUTOINCREMENT INCREMENT value
7875    #[serde(default)]
7876    pub auto_increment_increment: Option<Box<Expression>>,
7877    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
7878    #[serde(default)]
7879    pub auto_increment_order: Option<bool>,
7880    /// MySQL: UNSIGNED modifier
7881    #[serde(default)]
7882    pub unsigned: bool,
7883    /// MySQL: ZEROFILL modifier
7884    #[serde(default)]
7885    pub zerofill: bool,
7886    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
7887    #[serde(default, skip_serializing_if = "Option::is_none")]
7888    pub on_update: Option<Expression>,
7889    /// MySQL: column VISIBLE/INVISIBLE modifier.
7890    #[serde(default, skip_serializing_if = "Option::is_none")]
7891    pub visible: Option<bool>,
7892    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
7893    #[serde(default, skip_serializing_if = "Option::is_none")]
7894    pub unique_constraint_name: Option<String>,
7895    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
7896    #[serde(default, skip_serializing_if = "Option::is_none")]
7897    pub not_null_constraint_name: Option<String>,
7898    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
7899    #[serde(default, skip_serializing_if = "Option::is_none")]
7900    pub primary_key_constraint_name: Option<String>,
7901    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
7902    #[serde(default, skip_serializing_if = "Option::is_none")]
7903    pub check_constraint_name: Option<String>,
7904    /// BigQuery: OPTIONS (key=value, ...) on column
7905    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7906    pub options: Vec<Expression>,
7907    /// SQLite: Column definition without explicit type
7908    #[serde(default)]
7909    pub no_type: bool,
7910    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
7911    #[serde(default, skip_serializing_if = "Option::is_none")]
7912    pub encoding: Option<String>,
7913    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
7914    #[serde(default, skip_serializing_if = "Option::is_none")]
7915    pub codec: Option<String>,
7916    /// ClickHouse: EPHEMERAL [expr] modifier
7917    #[serde(default, skip_serializing_if = "Option::is_none")]
7918    pub ephemeral: Option<Option<Box<Expression>>>,
7919    /// ClickHouse: MATERIALIZED expr modifier
7920    #[serde(default, skip_serializing_if = "Option::is_none")]
7921    pub materialized_expr: Option<Box<Expression>>,
7922    /// ClickHouse: ALIAS expr modifier
7923    #[serde(default, skip_serializing_if = "Option::is_none")]
7924    pub alias_expr: Option<Box<Expression>>,
7925    /// ClickHouse: TTL expr modifier on columns
7926    #[serde(default, skip_serializing_if = "Option::is_none")]
7927    pub ttl_expr: Option<Box<Expression>>,
7928    /// TSQL: NOT FOR REPLICATION
7929    #[serde(default)]
7930    pub not_for_replication: bool,
7931}
7932
7933impl ColumnDef {
7934    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
7935        Self {
7936            name: Identifier::new(name),
7937            data_type,
7938            nullable: None,
7939            default: None,
7940            primary_key: false,
7941            primary_key_order: None,
7942            unique: false,
7943            unique_nulls_not_distinct: false,
7944            auto_increment: false,
7945            auto_random: None,
7946            comment: None,
7947            constraints: Vec::new(),
7948            constraint_order: Vec::new(),
7949            format: None,
7950            title: None,
7951            inline_length: None,
7952            compress: None,
7953            character_set: None,
7954            uppercase: false,
7955            casespecific: None,
7956            auto_increment_start: None,
7957            auto_increment_increment: None,
7958            auto_increment_order: None,
7959            unsigned: false,
7960            zerofill: false,
7961            on_update: None,
7962            visible: None,
7963            unique_constraint_name: None,
7964            not_null_constraint_name: None,
7965            primary_key_constraint_name: None,
7966            check_constraint_name: None,
7967            options: Vec::new(),
7968            no_type: false,
7969            encoding: None,
7970            codec: None,
7971            ephemeral: None,
7972            materialized_expr: None,
7973            alias_expr: None,
7974            ttl_expr: None,
7975            not_for_replication: false,
7976        }
7977    }
7978}
7979
7980/// Column-level constraint
7981#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7982#[cfg_attr(feature = "bindings", derive(TS))]
7983pub enum ColumnConstraint {
7984    NotNull,
7985    Null,
7986    Unique,
7987    PrimaryKey,
7988    Default(Expression),
7989    Check(Expression),
7990    References(ForeignKeyRef),
7991    GeneratedAsIdentity(GeneratedAsIdentity),
7992    Collate(Identifier),
7993    Comment(String),
7994    /// Snowflake: TAG (key='value', ...)
7995    Tags(Tags),
7996    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
7997    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
7998    ComputedColumn(ComputedColumn),
7999    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8000    GeneratedAsRow(GeneratedAsRow),
8001    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
8002    Path(Expression),
8003}
8004
8005/// Computed/generated column constraint
8006#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8007#[cfg_attr(feature = "bindings", derive(TS))]
8008pub struct ComputedColumn {
8009    /// The expression that computes the column value
8010    pub expression: Box<Expression>,
8011    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
8012    #[serde(default)]
8013    pub persisted: bool,
8014    /// NOT NULL (TSQL computed columns)
8015    #[serde(default)]
8016    pub not_null: bool,
8017    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
8018    /// When None, defaults to dialect-appropriate output
8019    #[serde(default)]
8020    pub persistence_kind: Option<String>,
8021    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
8022    #[serde(default, skip_serializing_if = "Option::is_none")]
8023    pub data_type: Option<DataType>,
8024}
8025
8026/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8028#[cfg_attr(feature = "bindings", derive(TS))]
8029pub struct GeneratedAsRow {
8030    /// true = ROW START, false = ROW END
8031    pub start: bool,
8032    /// HIDDEN modifier
8033    #[serde(default)]
8034    pub hidden: bool,
8035}
8036
8037/// Generated identity column constraint
8038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8039#[cfg_attr(feature = "bindings", derive(TS))]
8040pub struct GeneratedAsIdentity {
8041    /// True for ALWAYS, False for BY DEFAULT
8042    pub always: bool,
8043    /// ON NULL (only valid with BY DEFAULT)
8044    pub on_null: bool,
8045    /// START WITH value
8046    pub start: Option<Box<Expression>>,
8047    /// INCREMENT BY value
8048    pub increment: Option<Box<Expression>>,
8049    /// MINVALUE
8050    pub minvalue: Option<Box<Expression>>,
8051    /// MAXVALUE
8052    pub maxvalue: Option<Box<Expression>>,
8053    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
8054    pub cycle: Option<bool>,
8055}
8056
8057/// Constraint modifiers (shared between table-level constraints)
8058#[derive(
8059    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
8060)]
8061#[cfg_attr(feature = "bindings", derive(TS))]
8062pub struct ConstraintModifiers {
8063    /// ENFORCED / NOT ENFORCED
8064    pub enforced: Option<bool>,
8065    /// DEFERRABLE / NOT DEFERRABLE
8066    pub deferrable: Option<bool>,
8067    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
8068    pub initially_deferred: Option<bool>,
8069    /// NORELY (Oracle)
8070    pub norely: bool,
8071    /// RELY (Oracle)
8072    pub rely: bool,
8073    /// USING index type (MySQL): BTREE or HASH
8074    #[serde(default)]
8075    pub using: Option<String>,
8076    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
8077    #[serde(default)]
8078    pub using_before_columns: bool,
8079    /// MySQL index COMMENT 'text'
8080    #[serde(default, skip_serializing_if = "Option::is_none")]
8081    pub comment: Option<String>,
8082    /// MySQL index VISIBLE/INVISIBLE
8083    #[serde(default, skip_serializing_if = "Option::is_none")]
8084    pub visible: Option<bool>,
8085    /// MySQL ENGINE_ATTRIBUTE = 'value'
8086    #[serde(default, skip_serializing_if = "Option::is_none")]
8087    pub engine_attribute: Option<String>,
8088    /// MySQL WITH PARSER name
8089    #[serde(default, skip_serializing_if = "Option::is_none")]
8090    pub with_parser: Option<String>,
8091    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
8092    #[serde(default)]
8093    pub not_valid: bool,
8094    /// TSQL CLUSTERED/NONCLUSTERED modifier
8095    #[serde(default, skip_serializing_if = "Option::is_none")]
8096    pub clustered: Option<String>,
8097    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
8098    #[serde(default, skip_serializing_if = "Option::is_none")]
8099    pub on_conflict: Option<String>,
8100    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
8101    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8102    pub with_options: Vec<(String, String)>,
8103    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
8104    #[serde(default, skip_serializing_if = "Option::is_none")]
8105    pub on_filegroup: Option<Identifier>,
8106}
8107
8108/// Table-level constraint
8109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8110#[cfg_attr(feature = "bindings", derive(TS))]
8111pub enum TableConstraint {
8112    PrimaryKey {
8113        name: Option<Identifier>,
8114        columns: Vec<Identifier>,
8115        /// Databricks primary-key columns marked with the TIMESERIES attribute.
8116        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8117        timeseries_columns: Vec<Identifier>,
8118        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
8119        #[serde(default)]
8120        include_columns: Vec<Identifier>,
8121        #[serde(default)]
8122        modifiers: ConstraintModifiers,
8123        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
8124        #[serde(default)]
8125        has_constraint_keyword: bool,
8126    },
8127    Unique {
8128        name: Option<Identifier>,
8129        columns: Vec<Identifier>,
8130        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
8131        #[serde(default)]
8132        columns_parenthesized: bool,
8133        #[serde(default)]
8134        modifiers: ConstraintModifiers,
8135        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
8136        #[serde(default)]
8137        has_constraint_keyword: bool,
8138        /// PostgreSQL 15+: NULLS NOT DISTINCT
8139        #[serde(default)]
8140        nulls_not_distinct: bool,
8141    },
8142    ForeignKey {
8143        name: Option<Identifier>,
8144        columns: Vec<Identifier>,
8145        #[serde(default)]
8146        references: Option<ForeignKeyRef>,
8147        /// ON DELETE action when REFERENCES is absent
8148        #[serde(default)]
8149        on_delete: Option<ReferentialAction>,
8150        /// ON UPDATE action when REFERENCES is absent
8151        #[serde(default)]
8152        on_update: Option<ReferentialAction>,
8153        #[serde(default)]
8154        modifiers: ConstraintModifiers,
8155    },
8156    Check {
8157        name: Option<Identifier>,
8158        expression: Expression,
8159        #[serde(default)]
8160        modifiers: ConstraintModifiers,
8161    },
8162    /// ClickHouse ASSUME constraint (query optimization assumption)
8163    Assume {
8164        name: Option<Identifier>,
8165        expression: Expression,
8166    },
8167    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
8168    Default {
8169        name: Option<Identifier>,
8170        expression: Expression,
8171        column: Identifier,
8172    },
8173    /// INDEX / KEY constraint (MySQL)
8174    Index {
8175        name: Option<Identifier>,
8176        columns: Vec<Identifier>,
8177        /// Expression-capable index key parts. This is used when an index contains
8178        /// functional key parts that cannot be represented by `columns`.
8179        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8180        key_parts: Vec<IndexKeyPart>,
8181        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8182        #[serde(default)]
8183        kind: Option<String>,
8184        #[serde(default)]
8185        modifiers: ConstraintModifiers,
8186        /// True if KEY keyword was used instead of INDEX
8187        #[serde(default)]
8188        use_key_keyword: bool,
8189        /// ClickHouse: indexed expression (instead of columns)
8190        #[serde(default, skip_serializing_if = "Option::is_none")]
8191        expression: Option<Box<Expression>>,
8192        /// ClickHouse: TYPE type_func(args)
8193        #[serde(default, skip_serializing_if = "Option::is_none")]
8194        index_type: Option<Box<Expression>>,
8195        /// ClickHouse: GRANULARITY n
8196        #[serde(default, skip_serializing_if = "Option::is_none")]
8197        granularity: Option<Box<Expression>>,
8198    },
8199    /// ClickHouse PROJECTION definition
8200    Projection {
8201        name: Identifier,
8202        expression: Expression,
8203    },
8204    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8205    Like {
8206        source: TableRef,
8207        /// Options as (INCLUDING|EXCLUDING, property) pairs
8208        options: Vec<(LikeOptionAction, String)>,
8209    },
8210    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8211    PeriodForSystemTime {
8212        start_col: Identifier,
8213        end_col: Identifier,
8214    },
8215    /// PostgreSQL EXCLUDE constraint
8216    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8217    Exclude {
8218        name: Option<Identifier>,
8219        /// Index access method (gist, btree, etc.)
8220        #[serde(default)]
8221        using: Option<String>,
8222        /// Elements: (expression, operator) pairs
8223        elements: Vec<ExcludeElement>,
8224        /// INCLUDE columns
8225        #[serde(default)]
8226        include_columns: Vec<Identifier>,
8227        /// WHERE predicate
8228        #[serde(default)]
8229        where_clause: Option<Box<Expression>>,
8230        /// WITH (storage_parameters)
8231        #[serde(default)]
8232        with_params: Vec<(String, String)>,
8233        /// USING INDEX TABLESPACE tablespace_name
8234        #[serde(default)]
8235        using_index_tablespace: Option<String>,
8236        #[serde(default)]
8237        modifiers: ConstraintModifiers,
8238    },
8239    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8240    Tags(Tags),
8241    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8242    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8243    /// for all deferrable constraints in the table
8244    InitiallyDeferred {
8245        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8246        deferred: bool,
8247    },
8248}
8249
8250/// Element in an EXCLUDE constraint: expression WITH operator
8251#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8252#[cfg_attr(feature = "bindings", derive(TS))]
8253pub struct ExcludeElement {
8254    /// The column expression (may include operator class, ordering, nulls)
8255    pub expression: String,
8256    /// The operator (e.g., &&, =)
8257    pub operator: String,
8258}
8259
8260/// Action for LIKE clause options
8261#[derive(
8262    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8263)]
8264#[cfg_attr(feature = "bindings", derive(TS))]
8265pub enum LikeOptionAction {
8266    Including,
8267    Excluding,
8268}
8269
8270/// MATCH type for foreign keys
8271#[derive(
8272    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8273)]
8274#[cfg_attr(feature = "bindings", derive(TS))]
8275pub enum MatchType {
8276    Full,
8277    Partial,
8278    Simple,
8279}
8280
8281/// Foreign key reference
8282#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8283#[cfg_attr(feature = "bindings", derive(TS))]
8284pub struct ForeignKeyRef {
8285    pub table: TableRef,
8286    pub columns: Vec<Identifier>,
8287    pub on_delete: Option<ReferentialAction>,
8288    pub on_update: Option<ReferentialAction>,
8289    /// True if ON UPDATE appears before ON DELETE in the original SQL
8290    #[serde(default)]
8291    pub on_update_first: bool,
8292    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8293    #[serde(default)]
8294    pub match_type: Option<MatchType>,
8295    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8296    #[serde(default)]
8297    pub match_after_actions: bool,
8298    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8299    #[serde(default)]
8300    pub constraint_name: Option<String>,
8301    /// DEFERRABLE / NOT DEFERRABLE
8302    #[serde(default)]
8303    pub deferrable: Option<bool>,
8304    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8305    #[serde(default)]
8306    pub has_foreign_key_keywords: bool,
8307}
8308
8309/// Referential action for foreign keys
8310#[derive(
8311    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8312)]
8313#[cfg_attr(feature = "bindings", derive(TS))]
8314pub enum ReferentialAction {
8315    Cascade,
8316    SetNull,
8317    SetDefault,
8318    Restrict,
8319    NoAction,
8320}
8321
8322/// DROP TABLE statement
8323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8324#[cfg_attr(feature = "bindings", derive(TS))]
8325pub struct DropTable {
8326    pub names: Vec<TableRef>,
8327    pub if_exists: bool,
8328    pub cascade: bool,
8329    /// Oracle: CASCADE CONSTRAINTS
8330    #[serde(default)]
8331    pub cascade_constraints: bool,
8332    /// Oracle: PURGE
8333    #[serde(default)]
8334    pub purge: bool,
8335    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8336    #[serde(default)]
8337    pub leading_comments: Vec<String>,
8338    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8339    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8340    #[serde(default, skip_serializing_if = "Option::is_none")]
8341    pub object_id_args: Option<String>,
8342    /// ClickHouse: SYNC modifier
8343    #[serde(default)]
8344    pub sync: bool,
8345    /// Snowflake: DROP ICEBERG TABLE
8346    #[serde(default)]
8347    pub iceberg: bool,
8348    /// RESTRICT modifier (opposite of CASCADE)
8349    #[serde(default)]
8350    pub restrict: bool,
8351}
8352
8353impl DropTable {
8354    pub fn new(name: impl Into<String>) -> Self {
8355        Self {
8356            names: vec![TableRef::new(name)],
8357            if_exists: false,
8358            cascade: false,
8359            cascade_constraints: false,
8360            purge: false,
8361            leading_comments: Vec::new(),
8362            object_id_args: None,
8363            sync: false,
8364            iceberg: false,
8365            restrict: false,
8366        }
8367    }
8368}
8369
8370/// UNDROP object statement (Snowflake, ClickHouse)
8371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8372#[cfg_attr(feature = "bindings", derive(TS))]
8373pub struct Undrop {
8374    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8375    pub kind: String,
8376    /// The object name
8377    pub name: TableRef,
8378    /// IF EXISTS clause
8379    #[serde(default)]
8380    pub if_exists: bool,
8381    /// Snowflake: optional RENAME TO target
8382    #[serde(default, skip_serializing_if = "Option::is_none")]
8383    pub rename_to: Option<TableRef>,
8384}
8385
8386/// Partition scope for a TiDB `SPLIT TABLE` statement.
8387#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8388#[cfg_attr(feature = "bindings", derive(TS))]
8389#[serde(tag = "type", rename_all = "snake_case")]
8390pub enum SplitTablePartitionScope {
8391    Table,
8392    AllPartitions,
8393    Partitions { names: Vec<Identifier> },
8394}
8395
8396/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8397#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8398#[cfg_attr(feature = "bindings", derive(TS))]
8399#[serde(tag = "type", rename_all = "snake_case")]
8400pub enum SplitTableMode {
8401    Between {
8402        lower: Vec<Expression>,
8403        upper: Vec<Expression>,
8404        regions: u64,
8405    },
8406    By {
8407        points: Vec<Vec<Expression>>,
8408    },
8409}
8410
8411/// TiDB `SPLIT [PARTITION] TABLE` statement.
8412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8413#[cfg_attr(feature = "bindings", derive(TS))]
8414pub struct SplitTable {
8415    pub table: TableRef,
8416    pub partition_scope: SplitTablePartitionScope,
8417    #[serde(default, skip_serializing_if = "Option::is_none")]
8418    pub index: Option<Identifier>,
8419    pub mode: SplitTableMode,
8420}
8421
8422/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
8423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8424#[cfg_attr(feature = "bindings", derive(TS))]
8425pub struct FlashbackTable {
8426    pub table: TableRef,
8427    #[serde(default, skip_serializing_if = "Option::is_none")]
8428    pub rename_to: Option<Identifier>,
8429}
8430
8431/// ALTER TABLE statement
8432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8433#[cfg_attr(feature = "bindings", derive(TS))]
8434pub struct AlterTable {
8435    pub name: TableRef,
8436    pub actions: Vec<AlterTableAction>,
8437    /// IF EXISTS clause
8438    #[serde(default)]
8439    pub if_exists: bool,
8440    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8441    #[serde(default, skip_serializing_if = "Option::is_none")]
8442    pub algorithm: Option<String>,
8443    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8444    #[serde(default, skip_serializing_if = "Option::is_none")]
8445    pub lock: Option<String>,
8446    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8447    #[serde(default, skip_serializing_if = "Option::is_none")]
8448    pub with_check: Option<String>,
8449    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8450    #[serde(default, skip_serializing_if = "Option::is_none")]
8451    pub partition: Option<Vec<(Identifier, Expression)>>,
8452    /// ClickHouse: ON CLUSTER clause for distributed DDL
8453    #[serde(default, skip_serializing_if = "Option::is_none")]
8454    pub on_cluster: Option<OnCluster>,
8455    /// Snowflake: ALTER ICEBERG TABLE
8456    #[serde(default, skip_serializing_if = "Option::is_none")]
8457    pub table_modifier: Option<String>,
8458}
8459
8460impl AlterTable {
8461    pub fn new(name: impl Into<String>) -> Self {
8462        Self {
8463            name: TableRef::new(name),
8464            actions: Vec::new(),
8465            if_exists: false,
8466            algorithm: None,
8467            lock: None,
8468            with_check: None,
8469            partition: None,
8470            on_cluster: None,
8471            table_modifier: None,
8472        }
8473    }
8474}
8475
8476/// Column position for ADD COLUMN (MySQL/MariaDB)
8477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8478#[cfg_attr(feature = "bindings", derive(TS))]
8479pub enum ColumnPosition {
8480    First,
8481    After(Identifier),
8482}
8483
8484/// Actions for ALTER TABLE
8485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8486#[cfg_attr(feature = "bindings", derive(TS))]
8487pub enum AlterTableAction {
8488    AddColumn {
8489        column: ColumnDef,
8490        if_not_exists: bool,
8491        position: Option<ColumnPosition>,
8492    },
8493    DropColumn {
8494        name: Identifier,
8495        if_exists: bool,
8496        cascade: bool,
8497    },
8498    RenameColumn {
8499        old_name: Identifier,
8500        new_name: Identifier,
8501        if_exists: bool,
8502    },
8503    AlterColumn {
8504        name: Identifier,
8505        action: AlterColumnAction,
8506        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8507        #[serde(default)]
8508        use_modify_keyword: bool,
8509    },
8510    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
8511    ModifyColumn {
8512        column: ColumnDef,
8513        if_exists: bool,
8514        position: Option<ColumnPosition>,
8515    },
8516    RenameTable(TableRef),
8517    AddConstraint(TableConstraint),
8518    DropConstraint {
8519        name: Identifier,
8520        if_exists: bool,
8521    },
8522    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8523    DropForeignKey {
8524        name: Identifier,
8525    },
8526    /// DROP PARTITION action (Hive/BigQuery)
8527    DropPartition {
8528        /// List of partitions to drop (each partition is a list of key=value pairs)
8529        partitions: Vec<Vec<(Identifier, Expression)>>,
8530        if_exists: bool,
8531    },
8532    /// ADD PARTITION action (Hive/Spark)
8533    AddPartition {
8534        /// The partition expression
8535        partition: Expression,
8536        if_not_exists: bool,
8537        location: Option<Expression>,
8538    },
8539    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8540    Delete {
8541        where_clause: Expression,
8542    },
8543    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8544    SwapWith(TableRef),
8545    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8546    SetProperty {
8547        properties: Vec<(String, Expression)>,
8548    },
8549    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8550    UnsetProperty {
8551        properties: Vec<String>,
8552    },
8553    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8554    ClusterBy {
8555        expressions: Vec<Expression>,
8556    },
8557    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8558    SetTag {
8559        expressions: Vec<(String, Expression)>,
8560    },
8561    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8562    UnsetTag {
8563        names: Vec<String>,
8564    },
8565    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8566    SetOptions {
8567        expressions: Vec<Expression>,
8568    },
8569    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8570    AlterIndex {
8571        name: Identifier,
8572        visible: bool,
8573    },
8574    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8575    SetAttribute {
8576        attribute: String,
8577    },
8578    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8579    SetStageFileFormat {
8580        options: Option<Expression>,
8581    },
8582    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8583    SetStageCopyOptions {
8584        options: Option<Expression>,
8585    },
8586    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8587    AddColumns {
8588        columns: Vec<ColumnDef>,
8589        cascade: bool,
8590    },
8591    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8592    DropColumns {
8593        names: Vec<Identifier>,
8594    },
8595    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8596    /// In SingleStore, data_type can be omitted for simple column renames
8597    ChangeColumn {
8598        old_name: Identifier,
8599        new_name: Identifier,
8600        #[serde(default, skip_serializing_if = "Option::is_none")]
8601        data_type: Option<DataType>,
8602        comment: Option<String>,
8603        #[serde(default)]
8604        cascade: bool,
8605    },
8606    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
8607    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
8608    AlterSortKey {
8609        /// AUTO or NONE keyword
8610        this: Option<String>,
8611        /// Column list for (col1, col2) syntax
8612        expressions: Vec<Expression>,
8613        /// Whether COMPOUND keyword was present
8614        compound: bool,
8615    },
8616    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
8617    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
8618    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
8619    AlterDistStyle {
8620        /// Distribution style: ALL, EVEN, AUTO, or KEY
8621        style: String,
8622        /// DISTKEY column (only when style is KEY)
8623        distkey: Option<Identifier>,
8624    },
8625    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
8626    SetTableProperties {
8627        properties: Vec<(Expression, Expression)>,
8628    },
8629    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
8630    SetLocation {
8631        location: String,
8632    },
8633    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
8634    SetFileFormat {
8635        format: String,
8636    },
8637    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
8638    ReplacePartition {
8639        partition: Expression,
8640        source: Option<Box<Expression>>,
8641    },
8642    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
8643    SetTiDBTableOption {
8644        option: TiDBTableOption,
8645        #[serde(default)]
8646        force: bool,
8647    },
8648    /// TiDB `REMOVE TTL`.
8649    RemoveTiDBTtl {
8650        #[serde(default)]
8651        executable_comment: bool,
8652    },
8653    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
8654    Raw {
8655        sql: String,
8656    },
8657}
8658
8659/// Actions for ALTER COLUMN
8660#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8661#[cfg_attr(feature = "bindings", derive(TS))]
8662pub enum AlterColumnAction {
8663    SetDataType {
8664        data_type: DataType,
8665        /// USING expression for type conversion (PostgreSQL)
8666        using: Option<Expression>,
8667        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
8668        #[serde(default, skip_serializing_if = "Option::is_none")]
8669        collate: Option<String>,
8670    },
8671    SetDefault(Expression),
8672    DropDefault,
8673    SetNotNull,
8674    DropNotNull,
8675    /// Set column comment
8676    Comment(String),
8677    /// MySQL: SET VISIBLE
8678    SetVisible,
8679    /// MySQL: SET INVISIBLE
8680    SetInvisible,
8681}
8682
8683/// CREATE INDEX statement
8684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8685#[cfg_attr(feature = "bindings", derive(TS))]
8686pub struct CreateIndex {
8687    pub name: Identifier,
8688    pub table: TableRef,
8689    pub columns: Vec<IndexColumn>,
8690    /// Expression-capable index key parts. This is used when an index contains
8691    /// functional key parts that cannot be represented by `columns`.
8692    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8693    pub key_parts: Vec<IndexKeyPart>,
8694    pub unique: bool,
8695    pub if_not_exists: bool,
8696    pub using: Option<String>,
8697    /// TSQL CLUSTERED/NONCLUSTERED modifier
8698    #[serde(default)]
8699    pub clustered: Option<String>,
8700    /// PostgreSQL CONCURRENTLY modifier
8701    #[serde(default)]
8702    pub concurrently: bool,
8703    /// PostgreSQL WHERE clause for partial indexes
8704    #[serde(default)]
8705    pub where_clause: Option<Box<Expression>>,
8706    /// PostgreSQL INCLUDE columns
8707    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8708    pub include_columns: Vec<Identifier>,
8709    /// TSQL WITH options (e.g., allow_page_locks=on)
8710    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8711    pub with_options: Vec<(String, String)>,
8712    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
8713    #[serde(default)]
8714    pub on_filegroup: Option<String>,
8715}
8716
8717impl CreateIndex {
8718    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
8719        Self {
8720            name: Identifier::new(name),
8721            table: TableRef::new(table),
8722            columns: Vec::new(),
8723            key_parts: Vec::new(),
8724            unique: false,
8725            if_not_exists: false,
8726            using: None,
8727            clustered: None,
8728            concurrently: false,
8729            where_clause: None,
8730            include_columns: Vec::new(),
8731            with_options: Vec::new(),
8732            on_filegroup: None,
8733        }
8734    }
8735}
8736
8737/// Index column specification
8738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8739#[cfg_attr(feature = "bindings", derive(TS))]
8740pub struct IndexColumn {
8741    pub column: Identifier,
8742    pub desc: bool,
8743    /// Explicit ASC keyword was present
8744    #[serde(default)]
8745    pub asc: bool,
8746    pub nulls_first: Option<bool>,
8747    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
8748    #[serde(default, skip_serializing_if = "Option::is_none")]
8749    pub opclass: Option<String>,
8750}
8751
8752/// An expression-capable index key part.
8753#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8754#[cfg_attr(feature = "bindings", derive(TS))]
8755pub struct IndexKeyPart {
8756    pub expression: Box<Expression>,
8757    /// MySQL column prefix length, for example the `16` in `name(16)`.
8758    #[serde(default, skip_serializing_if = "Option::is_none")]
8759    pub prefix_length: Option<String>,
8760    pub desc: bool,
8761    /// Explicit ASC keyword was present.
8762    #[serde(default)]
8763    pub asc: bool,
8764    pub nulls_first: Option<bool>,
8765    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops).
8766    #[serde(default, skip_serializing_if = "Option::is_none")]
8767    pub opclass: Option<String>,
8768}
8769
8770/// DROP INDEX statement
8771#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8772#[cfg_attr(feature = "bindings", derive(TS))]
8773pub struct DropIndex {
8774    pub name: TableRef,
8775    pub table: Option<TableRef>,
8776    pub if_exists: bool,
8777    /// PostgreSQL CONCURRENTLY modifier
8778    #[serde(default)]
8779    pub concurrently: bool,
8780}
8781
8782impl DropIndex {
8783    pub fn new(name: impl Into<String>) -> Self {
8784        Self {
8785            name: TableRef::new(name),
8786            table: None,
8787            if_exists: false,
8788            concurrently: false,
8789        }
8790    }
8791}
8792
8793/// View column definition with optional COMMENT and OPTIONS (BigQuery)
8794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8795#[cfg_attr(feature = "bindings", derive(TS))]
8796pub struct ViewColumn {
8797    pub name: Identifier,
8798    pub comment: Option<String>,
8799    /// BigQuery: OPTIONS (key=value, ...) on column
8800    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8801    pub options: Vec<Expression>,
8802}
8803
8804impl ViewColumn {
8805    pub fn new(name: impl Into<String>) -> Self {
8806        Self {
8807            name: Identifier::new(name),
8808            comment: None,
8809            options: Vec::new(),
8810        }
8811    }
8812
8813    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
8814        Self {
8815            name: Identifier::new(name),
8816            comment: Some(comment.into()),
8817            options: Vec::new(),
8818        }
8819    }
8820}
8821
8822/// CREATE VIEW statement
8823#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8824#[cfg_attr(feature = "bindings", derive(TS))]
8825pub struct CreateView {
8826    pub name: TableRef,
8827    pub columns: Vec<ViewColumn>,
8828    pub query: Expression,
8829    pub or_replace: bool,
8830    /// TSQL: CREATE OR ALTER
8831    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
8832    pub or_alter: bool,
8833    pub if_not_exists: bool,
8834    pub materialized: bool,
8835    pub temporary: bool,
8836    /// Snowflake: SECURE VIEW
8837    #[serde(default)]
8838    pub secure: bool,
8839    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
8840    #[serde(skip_serializing_if = "Option::is_none")]
8841    pub algorithm: Option<String>,
8842    /// MySQL: DEFINER=user@host
8843    #[serde(skip_serializing_if = "Option::is_none")]
8844    pub definer: Option<String>,
8845    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
8846    #[serde(skip_serializing_if = "Option::is_none")]
8847    pub security: Option<FunctionSecurity>,
8848    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
8849    #[serde(default = "default_true")]
8850    pub security_sql_style: bool,
8851    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
8852    #[serde(default)]
8853    pub security_after_name: bool,
8854    /// Whether the query was parenthesized: AS (SELECT ...)
8855    #[serde(default)]
8856    pub query_parenthesized: bool,
8857    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
8858    #[serde(skip_serializing_if = "Option::is_none")]
8859    pub locking_mode: Option<String>,
8860    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
8861    #[serde(skip_serializing_if = "Option::is_none")]
8862    pub locking_access: Option<String>,
8863    /// Snowflake: COPY GRANTS
8864    #[serde(default)]
8865    pub copy_grants: bool,
8866    /// Snowflake: COMMENT = 'text'
8867    #[serde(skip_serializing_if = "Option::is_none", default)]
8868    pub comment: Option<String>,
8869    /// Snowflake: WITH ROW ACCESS POLICY ... clause
8870    #[serde(skip_serializing_if = "Option::is_none", default)]
8871    pub row_access_policy: Option<String>,
8872    /// Snowflake: TAG (name='value', ...)
8873    #[serde(default)]
8874    pub tags: Vec<(String, String)>,
8875    /// BigQuery: OPTIONS (key=value, ...)
8876    #[serde(default)]
8877    pub options: Vec<Expression>,
8878    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
8879    #[serde(skip_serializing_if = "Option::is_none", default)]
8880    pub build: Option<String>,
8881    /// Doris: REFRESH property for materialized views
8882    #[serde(skip_serializing_if = "Option::is_none", default)]
8883    pub refresh: Option<Box<RefreshTriggerProperty>>,
8884    /// Doris: Schema with typed column definitions for materialized views
8885    /// This is used instead of `columns` when the view has typed column definitions
8886    #[serde(skip_serializing_if = "Option::is_none", default)]
8887    pub schema: Option<Box<Schema>>,
8888    /// Doris: KEY (columns) for materialized views
8889    #[serde(skip_serializing_if = "Option::is_none", default)]
8890    pub unique_key: Option<Box<UniqueKeyProperty>>,
8891    /// Redshift: WITH NO SCHEMA BINDING
8892    #[serde(default)]
8893    pub no_schema_binding: bool,
8894    /// Redshift: AUTO REFRESH YES|NO for materialized views
8895    #[serde(skip_serializing_if = "Option::is_none", default)]
8896    pub auto_refresh: Option<bool>,
8897    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
8898    #[serde(skip_serializing_if = "Option::is_none", default)]
8899    pub clickhouse_population: Option<String>,
8900    /// ClickHouse: ON CLUSTER clause
8901    #[serde(default, skip_serializing_if = "Option::is_none")]
8902    pub on_cluster: Option<OnCluster>,
8903    /// ClickHouse: TO destination_table
8904    #[serde(default, skip_serializing_if = "Option::is_none")]
8905    pub to_table: Option<TableRef>,
8906    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
8907    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8908    pub table_properties: Vec<Expression>,
8909}
8910
8911impl CreateView {
8912    pub fn new(name: impl Into<String>, query: Expression) -> Self {
8913        Self {
8914            name: TableRef::new(name),
8915            columns: Vec::new(),
8916            query,
8917            or_replace: false,
8918            or_alter: false,
8919            if_not_exists: false,
8920            materialized: false,
8921            temporary: false,
8922            secure: false,
8923            algorithm: None,
8924            definer: None,
8925            security: None,
8926            security_sql_style: true,
8927            security_after_name: false,
8928            query_parenthesized: false,
8929            locking_mode: None,
8930            locking_access: None,
8931            copy_grants: false,
8932            comment: None,
8933            row_access_policy: None,
8934            tags: Vec::new(),
8935            options: Vec::new(),
8936            build: None,
8937            refresh: None,
8938            schema: None,
8939            unique_key: None,
8940            no_schema_binding: false,
8941            auto_refresh: None,
8942            clickhouse_population: None,
8943            on_cluster: None,
8944            to_table: None,
8945            table_properties: Vec::new(),
8946        }
8947    }
8948}
8949
8950/// DROP VIEW statement
8951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8952#[cfg_attr(feature = "bindings", derive(TS))]
8953pub struct DropView {
8954    pub name: TableRef,
8955    pub if_exists: bool,
8956    pub materialized: bool,
8957}
8958
8959impl DropView {
8960    pub fn new(name: impl Into<String>) -> Self {
8961        Self {
8962            name: TableRef::new(name),
8963            if_exists: false,
8964            materialized: false,
8965        }
8966    }
8967}
8968
8969/// TRUNCATE TABLE statement
8970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8971#[cfg_attr(feature = "bindings", derive(TS))]
8972pub struct Truncate {
8973    /// Target of TRUNCATE (TABLE vs DATABASE)
8974    #[serde(default)]
8975    pub target: TruncateTarget,
8976    /// IF EXISTS clause
8977    #[serde(default)]
8978    pub if_exists: bool,
8979    pub table: TableRef,
8980    /// ClickHouse: ON CLUSTER clause for distributed DDL
8981    #[serde(default, skip_serializing_if = "Option::is_none")]
8982    pub on_cluster: Option<OnCluster>,
8983    pub cascade: bool,
8984    /// Additional tables for multi-table TRUNCATE
8985    #[serde(default)]
8986    pub extra_tables: Vec<TruncateTableEntry>,
8987    /// RESTART IDENTITY or CONTINUE IDENTITY
8988    #[serde(default)]
8989    pub identity: Option<TruncateIdentity>,
8990    /// RESTRICT option (alternative to CASCADE)
8991    #[serde(default)]
8992    pub restrict: bool,
8993    /// Hive PARTITION clause: PARTITION(key=value, ...)
8994    #[serde(default, skip_serializing_if = "Option::is_none")]
8995    pub partition: Option<Box<Expression>>,
8996}
8997
8998/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
8999#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9000#[cfg_attr(feature = "bindings", derive(TS))]
9001pub struct TruncateTableEntry {
9002    pub table: TableRef,
9003    /// Whether the table has a * suffix (inherit children)
9004    #[serde(default)]
9005    pub star: bool,
9006}
9007
9008/// TRUNCATE target type
9009#[derive(
9010    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9011)]
9012#[cfg_attr(feature = "bindings", derive(TS))]
9013pub enum TruncateTarget {
9014    Table,
9015    Database,
9016}
9017
9018impl Default for TruncateTarget {
9019    fn default() -> Self {
9020        TruncateTarget::Table
9021    }
9022}
9023
9024/// TRUNCATE identity option
9025#[derive(
9026    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9027)]
9028#[cfg_attr(feature = "bindings", derive(TS))]
9029pub enum TruncateIdentity {
9030    Restart,
9031    Continue,
9032}
9033
9034impl Truncate {
9035    pub fn new(table: impl Into<String>) -> Self {
9036        Self {
9037            target: TruncateTarget::Table,
9038            if_exists: false,
9039            table: TableRef::new(table),
9040            on_cluster: None,
9041            cascade: false,
9042            extra_tables: Vec::new(),
9043            identity: None,
9044            restrict: false,
9045            partition: None,
9046        }
9047    }
9048}
9049
9050/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
9051#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9052#[cfg_attr(feature = "bindings", derive(TS))]
9053pub struct Use {
9054    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
9055    pub kind: Option<UseKind>,
9056    /// The name of the object
9057    pub this: Identifier,
9058}
9059
9060/// Kind of USE statement
9061#[derive(
9062    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9063)]
9064#[cfg_attr(feature = "bindings", derive(TS))]
9065pub enum UseKind {
9066    Database,
9067    Schema,
9068    Role,
9069    Warehouse,
9070    Catalog,
9071    /// Snowflake: USE SECONDARY ROLES ALL|NONE
9072    SecondaryRoles,
9073}
9074
9075/// SET variable statement
9076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9077#[cfg_attr(feature = "bindings", derive(TS))]
9078pub struct SetStatement {
9079    /// The items being set
9080    pub items: Vec<SetItem>,
9081}
9082
9083/// A single SET item (variable assignment)
9084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9085#[cfg_attr(feature = "bindings", derive(TS))]
9086pub struct SetItem {
9087    /// The variable name
9088    pub name: Expression,
9089    /// The value to set
9090    pub value: Expression,
9091    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
9092    pub kind: Option<String>,
9093    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
9094    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9095    pub no_equals: bool,
9096}
9097
9098/// CACHE TABLE statement (Spark)
9099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9100#[cfg_attr(feature = "bindings", derive(TS))]
9101pub struct Cache {
9102    /// The table to cache
9103    pub table: Identifier,
9104    /// LAZY keyword - defer caching until first use
9105    pub lazy: bool,
9106    /// Optional OPTIONS clause (key-value pairs)
9107    pub options: Vec<(Expression, Expression)>,
9108    /// Optional AS clause with query
9109    pub query: Option<Expression>,
9110}
9111
9112/// UNCACHE TABLE statement (Spark)
9113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9114#[cfg_attr(feature = "bindings", derive(TS))]
9115pub struct Uncache {
9116    /// The table to uncache
9117    pub table: Identifier,
9118    /// IF EXISTS clause
9119    pub if_exists: bool,
9120}
9121
9122/// LOAD DATA statement (Hive)
9123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9124#[cfg_attr(feature = "bindings", derive(TS))]
9125pub struct LoadData {
9126    /// LOCAL keyword - load from local filesystem
9127    pub local: bool,
9128    /// The path to load data from (INPATH value)
9129    pub inpath: String,
9130    /// Whether to overwrite existing data
9131    pub overwrite: bool,
9132    /// The target table
9133    pub table: Expression,
9134    /// Optional PARTITION clause with key-value pairs
9135    pub partition: Vec<(Identifier, Expression)>,
9136    /// Optional INPUTFORMAT clause
9137    pub input_format: Option<String>,
9138    /// Optional SERDE clause
9139    pub serde: Option<String>,
9140}
9141
9142/// PRAGMA statement (SQLite)
9143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9144#[cfg_attr(feature = "bindings", derive(TS))]
9145pub struct Pragma {
9146    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
9147    pub schema: Option<Identifier>,
9148    /// The pragma name
9149    pub name: Identifier,
9150    /// Optional value for assignment (PRAGMA name = value)
9151    pub value: Option<Expression>,
9152    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
9153    pub args: Vec<Expression>,
9154    /// Whether this pragma should be generated using assignment syntax.
9155    #[serde(default)]
9156    pub use_assignment_syntax: bool,
9157}
9158
9159/// A privilege with optional column list for GRANT/REVOKE
9160/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
9161#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9162#[cfg_attr(feature = "bindings", derive(TS))]
9163pub struct Privilege {
9164    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
9165    pub name: String,
9166    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
9167    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9168    pub columns: Vec<String>,
9169}
9170
9171/// Principal in GRANT/REVOKE (user, role, etc.)
9172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9173#[cfg_attr(feature = "bindings", derive(TS))]
9174pub struct GrantPrincipal {
9175    /// The name of the principal
9176    pub name: Identifier,
9177    /// Whether prefixed with ROLE keyword
9178    pub is_role: bool,
9179    /// Whether prefixed with GROUP keyword (Redshift)
9180    #[serde(default)]
9181    pub is_group: bool,
9182    /// Whether prefixed with SHARE keyword (Snowflake)
9183    #[serde(default)]
9184    pub is_share: bool,
9185}
9186
9187/// GRANT statement
9188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9189#[cfg_attr(feature = "bindings", derive(TS))]
9190pub struct Grant {
9191    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
9192    pub privileges: Vec<Privilege>,
9193    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9194    pub kind: Option<String>,
9195    /// The object to grant on
9196    pub securable: Identifier,
9197    /// Function parameter types (for FUNCTION kind)
9198    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9199    pub function_params: Vec<String>,
9200    /// The grantees
9201    pub principals: Vec<GrantPrincipal>,
9202    /// WITH GRANT OPTION
9203    pub grant_option: bool,
9204    /// TSQL: AS principal (the grantor role)
9205    #[serde(default, skip_serializing_if = "Option::is_none")]
9206    pub as_principal: Option<Identifier>,
9207}
9208
9209/// REVOKE statement
9210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9211#[cfg_attr(feature = "bindings", derive(TS))]
9212pub struct Revoke {
9213    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9214    pub privileges: Vec<Privilege>,
9215    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9216    pub kind: Option<String>,
9217    /// The object to revoke from
9218    pub securable: Identifier,
9219    /// Function parameter types (for FUNCTION kind)
9220    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9221    pub function_params: Vec<String>,
9222    /// The grantees
9223    pub principals: Vec<GrantPrincipal>,
9224    /// GRANT OPTION FOR
9225    pub grant_option: bool,
9226    /// CASCADE
9227    pub cascade: bool,
9228    /// RESTRICT
9229    #[serde(default)]
9230    pub restrict: bool,
9231}
9232
9233/// COMMENT ON statement
9234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9235#[cfg_attr(feature = "bindings", derive(TS))]
9236pub struct Comment {
9237    /// The object being commented on
9238    pub this: Expression,
9239    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9240    pub kind: String,
9241    /// The comment text expression
9242    pub expression: Expression,
9243    /// IF EXISTS clause
9244    pub exists: bool,
9245    /// MATERIALIZED keyword
9246    pub materialized: bool,
9247}
9248
9249// ============================================================================
9250// Phase 4: Additional DDL Statements
9251// ============================================================================
9252
9253/// ALTER VIEW statement
9254#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9255#[cfg_attr(feature = "bindings", derive(TS))]
9256pub struct AlterView {
9257    pub name: TableRef,
9258    pub actions: Vec<AlterViewAction>,
9259    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9260    #[serde(default, skip_serializing_if = "Option::is_none")]
9261    pub algorithm: Option<String>,
9262    /// MySQL: DEFINER = 'user'@'host'
9263    #[serde(default, skip_serializing_if = "Option::is_none")]
9264    pub definer: Option<String>,
9265    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9266    #[serde(default, skip_serializing_if = "Option::is_none")]
9267    pub sql_security: Option<String>,
9268    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9269    #[serde(default, skip_serializing_if = "Option::is_none")]
9270    pub with_option: Option<String>,
9271    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9272    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9273    pub columns: Vec<ViewColumn>,
9274}
9275
9276/// Actions for ALTER VIEW
9277#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9278#[cfg_attr(feature = "bindings", derive(TS))]
9279pub enum AlterViewAction {
9280    /// Rename the view
9281    Rename(TableRef),
9282    /// Change owner
9283    OwnerTo(Identifier),
9284    /// Set schema
9285    SetSchema(Identifier),
9286    /// Set authorization (Trino/Presto)
9287    SetAuthorization(String),
9288    /// Alter column
9289    AlterColumn {
9290        name: Identifier,
9291        action: AlterColumnAction,
9292    },
9293    /// Redefine view as query (SELECT, UNION, etc.)
9294    AsSelect(Box<Expression>),
9295    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9296    SetTblproperties(Vec<(String, String)>),
9297    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9298    UnsetTblproperties(Vec<String>),
9299}
9300
9301impl AlterView {
9302    pub fn new(name: impl Into<String>) -> Self {
9303        Self {
9304            name: TableRef::new(name),
9305            actions: Vec::new(),
9306            algorithm: None,
9307            definer: None,
9308            sql_security: None,
9309            with_option: None,
9310            columns: Vec::new(),
9311        }
9312    }
9313}
9314
9315/// ALTER INDEX statement
9316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9317#[cfg_attr(feature = "bindings", derive(TS))]
9318pub struct AlterIndex {
9319    pub name: Identifier,
9320    pub table: Option<TableRef>,
9321    pub actions: Vec<AlterIndexAction>,
9322}
9323
9324/// Actions for ALTER INDEX
9325#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9326#[cfg_attr(feature = "bindings", derive(TS))]
9327pub enum AlterIndexAction {
9328    /// Rename the index
9329    Rename(Identifier),
9330    /// Set tablespace
9331    SetTablespace(Identifier),
9332    /// Set visibility (MySQL)
9333    Visible(bool),
9334}
9335
9336impl AlterIndex {
9337    pub fn new(name: impl Into<String>) -> Self {
9338        Self {
9339            name: Identifier::new(name),
9340            table: None,
9341            actions: Vec::new(),
9342        }
9343    }
9344}
9345
9346/// CREATE SCHEMA statement
9347#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9348#[cfg_attr(feature = "bindings", derive(TS))]
9349pub struct CreateSchema {
9350    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9351    pub name: Vec<Identifier>,
9352    pub if_not_exists: bool,
9353    pub authorization: Option<Identifier>,
9354    /// CLONE source parts, possibly dot-qualified
9355    #[serde(default)]
9356    pub clone_from: Option<Vec<Identifier>>,
9357    /// AT/BEFORE clause for time travel (Snowflake)
9358    #[serde(default)]
9359    pub at_clause: Option<Expression>,
9360    /// Schema properties like DEFAULT COLLATE
9361    #[serde(default)]
9362    pub properties: Vec<Expression>,
9363    /// Leading comments before the statement
9364    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9365    pub leading_comments: Vec<String>,
9366}
9367
9368impl CreateSchema {
9369    pub fn new(name: impl Into<String>) -> Self {
9370        Self {
9371            name: vec![Identifier::new(name)],
9372            if_not_exists: false,
9373            authorization: None,
9374            clone_from: None,
9375            at_clause: None,
9376            properties: Vec::new(),
9377            leading_comments: Vec::new(),
9378        }
9379    }
9380}
9381
9382/// DROP SCHEMA statement
9383#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9384#[cfg_attr(feature = "bindings", derive(TS))]
9385pub struct DropSchema {
9386    pub name: Identifier,
9387    pub if_exists: bool,
9388    pub cascade: bool,
9389}
9390
9391impl DropSchema {
9392    pub fn new(name: impl Into<String>) -> Self {
9393        Self {
9394            name: Identifier::new(name),
9395            if_exists: false,
9396            cascade: false,
9397        }
9398    }
9399}
9400
9401/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9402#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9403#[cfg_attr(feature = "bindings", derive(TS))]
9404pub struct DropNamespace {
9405    pub name: Identifier,
9406    pub if_exists: bool,
9407    pub cascade: bool,
9408}
9409
9410impl DropNamespace {
9411    pub fn new(name: impl Into<String>) -> Self {
9412        Self {
9413            name: Identifier::new(name),
9414            if_exists: false,
9415            cascade: false,
9416        }
9417    }
9418}
9419
9420/// CREATE DATABASE statement
9421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9422#[cfg_attr(feature = "bindings", derive(TS))]
9423pub struct CreateDatabase {
9424    pub name: Identifier,
9425    pub if_not_exists: bool,
9426    pub options: Vec<DatabaseOption>,
9427    /// Snowflake CLONE source
9428    #[serde(default)]
9429    pub clone_from: Option<Identifier>,
9430    /// AT/BEFORE clause for time travel (Snowflake)
9431    #[serde(default)]
9432    pub at_clause: Option<Expression>,
9433}
9434
9435/// Database option
9436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9437#[cfg_attr(feature = "bindings", derive(TS))]
9438pub enum DatabaseOption {
9439    CharacterSet(String),
9440    Collate(String),
9441    Owner(Identifier),
9442    Template(Identifier),
9443    Encoding(String),
9444    Location(String),
9445}
9446
9447impl CreateDatabase {
9448    pub fn new(name: impl Into<String>) -> Self {
9449        Self {
9450            name: Identifier::new(name),
9451            if_not_exists: false,
9452            options: Vec::new(),
9453            clone_from: None,
9454            at_clause: None,
9455        }
9456    }
9457}
9458
9459/// DROP DATABASE statement
9460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9461#[cfg_attr(feature = "bindings", derive(TS))]
9462pub struct DropDatabase {
9463    pub name: Identifier,
9464    pub if_exists: bool,
9465    /// ClickHouse: SYNC modifier
9466    #[serde(default)]
9467    pub sync: bool,
9468}
9469
9470impl DropDatabase {
9471    pub fn new(name: impl Into<String>) -> Self {
9472        Self {
9473            name: Identifier::new(name),
9474            if_exists: false,
9475            sync: false,
9476        }
9477    }
9478}
9479
9480/// CREATE FUNCTION statement
9481#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9482#[cfg_attr(feature = "bindings", derive(TS))]
9483pub struct CreateFunction {
9484    pub name: TableRef,
9485    pub parameters: Vec<FunctionParameter>,
9486    pub return_type: Option<DataType>,
9487    pub body: Option<FunctionBody>,
9488    pub or_replace: bool,
9489    /// TSQL: CREATE OR ALTER
9490    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9491    pub or_alter: bool,
9492    pub if_not_exists: bool,
9493    pub temporary: bool,
9494    pub language: Option<String>,
9495    pub deterministic: Option<bool>,
9496    pub returns_null_on_null_input: Option<bool>,
9497    pub security: Option<FunctionSecurity>,
9498    /// Whether parentheses were present in the original syntax
9499    #[serde(default = "default_true")]
9500    pub has_parens: bool,
9501    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9502    #[serde(default)]
9503    pub sql_data_access: Option<SqlDataAccess>,
9504    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9505    #[serde(default, skip_serializing_if = "Option::is_none")]
9506    pub returns_table_body: Option<String>,
9507    /// True if LANGUAGE clause appears before RETURNS clause
9508    #[serde(default)]
9509    pub language_first: bool,
9510    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9511    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9512    pub set_options: Vec<FunctionSetOption>,
9513    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9514    #[serde(default)]
9515    pub strict: bool,
9516    /// BigQuery: OPTIONS (key=value, ...)
9517    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9518    pub options: Vec<Expression>,
9519    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9520    #[serde(default)]
9521    pub is_table_function: bool,
9522    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9523    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9524    pub property_order: Vec<FunctionPropertyKind>,
9525    /// Hive: USING JAR|FILE|ARCHIVE '...'
9526    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9527    pub using_resources: Vec<FunctionUsingResource>,
9528    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9529    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9530    pub environment: Vec<Expression>,
9531    /// HANDLER 'handler_function' clause (Databricks)
9532    #[serde(default, skip_serializing_if = "Option::is_none")]
9533    pub handler: Option<String>,
9534    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9535    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9536    pub handler_uses_eq: bool,
9537    /// Snowflake: RUNTIME_VERSION='3.11'
9538    #[serde(default, skip_serializing_if = "Option::is_none")]
9539    pub runtime_version: Option<String>,
9540    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9541    #[serde(default, skip_serializing_if = "Option::is_none")]
9542    pub packages: Option<Vec<String>>,
9543    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9544    #[serde(default, skip_serializing_if = "Option::is_none")]
9545    pub parameter_style: Option<String>,
9546}
9547
9548/// A SET option in CREATE FUNCTION (PostgreSQL)
9549#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9550#[cfg_attr(feature = "bindings", derive(TS))]
9551pub struct FunctionSetOption {
9552    pub name: String,
9553    pub value: FunctionSetValue,
9554}
9555
9556/// The value of a SET option
9557#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9558#[cfg_attr(feature = "bindings", derive(TS))]
9559pub enum FunctionSetValue {
9560    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9561    Value { value: String, use_to: bool },
9562    /// SET key FROM CURRENT
9563    FromCurrent,
9564}
9565
9566/// SQL data access characteristics for functions
9567#[derive(
9568    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9569)]
9570#[cfg_attr(feature = "bindings", derive(TS))]
9571pub enum SqlDataAccess {
9572    /// NO SQL
9573    NoSql,
9574    /// CONTAINS SQL
9575    ContainsSql,
9576    /// READS SQL DATA
9577    ReadsSqlData,
9578    /// MODIFIES SQL DATA
9579    ModifiesSqlData,
9580}
9581
9582/// Types of properties in CREATE FUNCTION for tracking their original order
9583#[derive(
9584    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9585)]
9586#[cfg_attr(feature = "bindings", derive(TS))]
9587pub enum FunctionPropertyKind {
9588    /// SET option
9589    Set,
9590    /// AS body
9591    As,
9592    /// Hive: USING JAR|FILE|ARCHIVE ...
9593    Using,
9594    /// LANGUAGE clause
9595    Language,
9596    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9597    Determinism,
9598    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
9599    NullInput,
9600    /// SECURITY DEFINER/INVOKER
9601    Security,
9602    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
9603    SqlDataAccess,
9604    /// OPTIONS clause (BigQuery)
9605    Options,
9606    /// ENVIRONMENT clause (Databricks)
9607    Environment,
9608    /// HANDLER clause (Databricks)
9609    Handler,
9610    /// Snowflake: RUNTIME_VERSION='...'
9611    RuntimeVersion,
9612    /// Snowflake: PACKAGES=(...)
9613    Packages,
9614    /// PARAMETER STYLE clause (Databricks)
9615    ParameterStyle,
9616}
9617
9618/// Hive CREATE FUNCTION resource in a USING clause
9619#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9620#[cfg_attr(feature = "bindings", derive(TS))]
9621pub struct FunctionUsingResource {
9622    pub kind: String,
9623    pub uri: String,
9624}
9625
9626/// Function parameter
9627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9628#[cfg_attr(feature = "bindings", derive(TS))]
9629pub struct FunctionParameter {
9630    pub name: Option<Identifier>,
9631    pub data_type: DataType,
9632    pub mode: Option<ParameterMode>,
9633    pub default: Option<Expression>,
9634    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
9635    #[serde(default, skip_serializing_if = "Option::is_none")]
9636    pub mode_text: Option<String>,
9637}
9638
9639/// Parameter mode (IN, OUT, INOUT, VARIADIC)
9640#[derive(
9641    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9642)]
9643#[cfg_attr(feature = "bindings", derive(TS))]
9644pub enum ParameterMode {
9645    In,
9646    Out,
9647    InOut,
9648    Variadic,
9649}
9650
9651/// Function body
9652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9653#[cfg_attr(feature = "bindings", derive(TS))]
9654pub enum FunctionBody {
9655    /// AS $$ ... $$ (dollar-quoted)
9656    Block(String),
9657    /// AS 'string' (single-quoted string literal body)
9658    StringLiteral(String),
9659    /// AS 'expression'
9660    Expression(Expression),
9661    /// EXTERNAL NAME 'library'
9662    External(String),
9663    /// RETURN expression
9664    Return(Expression),
9665    /// BEGIN ... END block with parsed statements
9666    Statements(Vec<Expression>),
9667    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
9668    /// Stores (content, optional_tag)
9669    DollarQuoted {
9670        content: String,
9671        tag: Option<String>,
9672    },
9673    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
9674    RawBlock(String),
9675}
9676
9677/// Function security (DEFINER, INVOKER, or NONE)
9678#[derive(
9679    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9680)]
9681#[cfg_attr(feature = "bindings", derive(TS))]
9682pub enum FunctionSecurity {
9683    Definer,
9684    Invoker,
9685    /// StarRocks/MySQL: SECURITY NONE
9686    None,
9687}
9688
9689impl CreateFunction {
9690    pub fn new(name: impl Into<String>) -> Self {
9691        Self {
9692            name: TableRef::new(name),
9693            parameters: Vec::new(),
9694            return_type: None,
9695            body: None,
9696            or_replace: false,
9697            or_alter: false,
9698            if_not_exists: false,
9699            temporary: false,
9700            language: None,
9701            deterministic: None,
9702            returns_null_on_null_input: None,
9703            security: None,
9704            has_parens: true,
9705            sql_data_access: None,
9706            returns_table_body: None,
9707            language_first: false,
9708            set_options: Vec::new(),
9709            strict: false,
9710            options: Vec::new(),
9711            is_table_function: false,
9712            property_order: Vec::new(),
9713            using_resources: Vec::new(),
9714            environment: Vec::new(),
9715            handler: None,
9716            handler_uses_eq: false,
9717            runtime_version: None,
9718            packages: None,
9719            parameter_style: None,
9720        }
9721    }
9722}
9723
9724/// DROP FUNCTION statement
9725#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9726#[cfg_attr(feature = "bindings", derive(TS))]
9727pub struct DropFunction {
9728    pub name: TableRef,
9729    pub parameters: Option<Vec<DataType>>,
9730    pub if_exists: bool,
9731    pub cascade: bool,
9732}
9733
9734impl DropFunction {
9735    pub fn new(name: impl Into<String>) -> Self {
9736        Self {
9737            name: TableRef::new(name),
9738            parameters: None,
9739            if_exists: false,
9740            cascade: false,
9741        }
9742    }
9743}
9744
9745/// CREATE PROCEDURE statement
9746#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9747#[cfg_attr(feature = "bindings", derive(TS))]
9748pub struct CreateProcedure {
9749    pub name: TableRef,
9750    pub parameters: Vec<FunctionParameter>,
9751    pub body: Option<FunctionBody>,
9752    pub or_replace: bool,
9753    /// TSQL: CREATE OR ALTER
9754    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9755    pub or_alter: bool,
9756    pub if_not_exists: bool,
9757    pub language: Option<String>,
9758    pub security: Option<FunctionSecurity>,
9759    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
9760    #[serde(default)]
9761    pub return_type: Option<DataType>,
9762    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
9763    #[serde(default)]
9764    pub execute_as: Option<String>,
9765    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
9766    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9767    pub with_options: Vec<String>,
9768    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
9769    #[serde(default = "default_true", skip_serializing_if = "is_true")]
9770    pub has_parens: bool,
9771    /// Whether the short form PROC was used (instead of PROCEDURE)
9772    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9773    pub use_proc_keyword: bool,
9774}
9775
9776impl CreateProcedure {
9777    pub fn new(name: impl Into<String>) -> Self {
9778        Self {
9779            name: TableRef::new(name),
9780            parameters: Vec::new(),
9781            body: None,
9782            or_replace: false,
9783            or_alter: false,
9784            if_not_exists: false,
9785            language: None,
9786            security: None,
9787            return_type: None,
9788            execute_as: None,
9789            with_options: Vec::new(),
9790            has_parens: true,
9791            use_proc_keyword: false,
9792        }
9793    }
9794}
9795
9796/// DROP PROCEDURE statement
9797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9798#[cfg_attr(feature = "bindings", derive(TS))]
9799pub struct DropProcedure {
9800    pub name: TableRef,
9801    pub parameters: Option<Vec<DataType>>,
9802    pub if_exists: bool,
9803    pub cascade: bool,
9804}
9805
9806impl DropProcedure {
9807    pub fn new(name: impl Into<String>) -> Self {
9808        Self {
9809            name: TableRef::new(name),
9810            parameters: None,
9811            if_exists: false,
9812            cascade: false,
9813        }
9814    }
9815}
9816
9817/// Sequence property tag for ordering
9818#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9819#[cfg_attr(feature = "bindings", derive(TS))]
9820pub enum SeqPropKind {
9821    Start,
9822    Increment,
9823    Minvalue,
9824    Maxvalue,
9825    Cache,
9826    NoCache,
9827    Cycle,
9828    NoCycle,
9829    OwnedBy,
9830    Order,
9831    NoOrder,
9832    Comment,
9833    /// SHARING=<value> (Oracle)
9834    Sharing,
9835    /// KEEP (Oracle)
9836    Keep,
9837    /// NOKEEP (Oracle)
9838    NoKeep,
9839    /// SCALE [EXTEND|NOEXTEND] (Oracle)
9840    Scale,
9841    /// NOSCALE (Oracle)
9842    NoScale,
9843    /// SHARD [EXTEND|NOEXTEND] (Oracle)
9844    Shard,
9845    /// NOSHARD (Oracle)
9846    NoShard,
9847    /// SESSION (Oracle)
9848    Session,
9849    /// GLOBAL (Oracle)
9850    Global,
9851    /// NOCACHE (single word, Oracle)
9852    NoCacheWord,
9853    /// NOCYCLE (single word, Oracle)
9854    NoCycleWord,
9855    /// NOMINVALUE (single word, Oracle)
9856    NoMinvalueWord,
9857    /// NOMAXVALUE (single word, Oracle)
9858    NoMaxvalueWord,
9859}
9860
9861/// CREATE SYNONYM statement (TSQL)
9862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9863#[cfg_attr(feature = "bindings", derive(TS))]
9864pub struct CreateSynonym {
9865    /// The synonym name (can be qualified: schema.synonym_name)
9866    pub name: TableRef,
9867    /// The target object the synonym refers to
9868    pub target: TableRef,
9869}
9870
9871/// CREATE SEQUENCE statement
9872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9873#[cfg_attr(feature = "bindings", derive(TS))]
9874pub struct CreateSequence {
9875    pub name: TableRef,
9876    pub if_not_exists: bool,
9877    pub temporary: bool,
9878    #[serde(default)]
9879    pub or_replace: bool,
9880    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
9881    #[serde(default, skip_serializing_if = "Option::is_none")]
9882    pub as_type: Option<DataType>,
9883    pub increment: Option<i64>,
9884    pub minvalue: Option<SequenceBound>,
9885    pub maxvalue: Option<SequenceBound>,
9886    pub start: Option<i64>,
9887    pub cache: Option<i64>,
9888    pub cycle: bool,
9889    pub owned_by: Option<TableRef>,
9890    /// Whether OWNED BY NONE was specified
9891    #[serde(default)]
9892    pub owned_by_none: bool,
9893    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
9894    #[serde(default)]
9895    pub order: Option<bool>,
9896    /// Snowflake: COMMENT = 'value'
9897    #[serde(default)]
9898    pub comment: Option<String>,
9899    /// SHARING=<value> (Oracle)
9900    #[serde(default, skip_serializing_if = "Option::is_none")]
9901    pub sharing: Option<String>,
9902    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
9903    #[serde(default, skip_serializing_if = "Option::is_none")]
9904    pub scale_modifier: Option<String>,
9905    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
9906    #[serde(default, skip_serializing_if = "Option::is_none")]
9907    pub shard_modifier: Option<String>,
9908    /// Tracks the order in which properties appeared in the source
9909    #[serde(default)]
9910    pub property_order: Vec<SeqPropKind>,
9911}
9912
9913/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
9914#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9915#[cfg_attr(feature = "bindings", derive(TS))]
9916pub enum SequenceBound {
9917    Value(i64),
9918    None,
9919}
9920
9921impl CreateSequence {
9922    pub fn new(name: impl Into<String>) -> Self {
9923        Self {
9924            name: TableRef::new(name),
9925            if_not_exists: false,
9926            temporary: false,
9927            or_replace: false,
9928            as_type: None,
9929            increment: None,
9930            minvalue: None,
9931            maxvalue: None,
9932            start: None,
9933            cache: None,
9934            cycle: false,
9935            owned_by: None,
9936            owned_by_none: false,
9937            order: None,
9938            comment: None,
9939            sharing: None,
9940            scale_modifier: None,
9941            shard_modifier: None,
9942            property_order: Vec::new(),
9943        }
9944    }
9945}
9946
9947/// DROP SEQUENCE statement
9948#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9949#[cfg_attr(feature = "bindings", derive(TS))]
9950pub struct DropSequence {
9951    pub name: TableRef,
9952    pub if_exists: bool,
9953    pub cascade: bool,
9954}
9955
9956impl DropSequence {
9957    pub fn new(name: impl Into<String>) -> Self {
9958        Self {
9959            name: TableRef::new(name),
9960            if_exists: false,
9961            cascade: false,
9962        }
9963    }
9964}
9965
9966/// ALTER SEQUENCE statement
9967#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9968#[cfg_attr(feature = "bindings", derive(TS))]
9969pub struct AlterSequence {
9970    pub name: TableRef,
9971    pub if_exists: bool,
9972    pub increment: Option<i64>,
9973    pub minvalue: Option<SequenceBound>,
9974    pub maxvalue: Option<SequenceBound>,
9975    pub start: Option<i64>,
9976    pub restart: Option<Option<i64>>,
9977    pub cache: Option<i64>,
9978    pub cycle: Option<bool>,
9979    pub owned_by: Option<Option<TableRef>>,
9980}
9981
9982impl AlterSequence {
9983    pub fn new(name: impl Into<String>) -> Self {
9984        Self {
9985            name: TableRef::new(name),
9986            if_exists: false,
9987            increment: None,
9988            minvalue: None,
9989            maxvalue: None,
9990            start: None,
9991            restart: None,
9992            cache: None,
9993            cycle: None,
9994            owned_by: None,
9995        }
9996    }
9997}
9998
9999/// CREATE TRIGGER statement
10000#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10001#[cfg_attr(feature = "bindings", derive(TS))]
10002pub struct CreateTrigger {
10003    pub name: Identifier,
10004    pub table: TableRef,
10005    pub timing: TriggerTiming,
10006    pub events: Vec<TriggerEvent>,
10007    #[serde(default, skip_serializing_if = "Option::is_none")]
10008    pub for_each: Option<TriggerForEach>,
10009    pub when: Option<Expression>,
10010    /// Whether the WHEN clause was parenthesized in the original SQL
10011    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10012    pub when_paren: bool,
10013    pub body: TriggerBody,
10014    pub or_replace: bool,
10015    /// TSQL: CREATE OR ALTER
10016    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10017    pub or_alter: bool,
10018    pub constraint: bool,
10019    pub deferrable: Option<bool>,
10020    pub initially_deferred: Option<bool>,
10021    pub referencing: Option<TriggerReferencing>,
10022}
10023
10024/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
10025#[derive(
10026    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10027)]
10028#[cfg_attr(feature = "bindings", derive(TS))]
10029pub enum TriggerTiming {
10030    Before,
10031    After,
10032    InsteadOf,
10033}
10034
10035/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
10036#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10037#[cfg_attr(feature = "bindings", derive(TS))]
10038pub enum TriggerEvent {
10039    Insert,
10040    Update(Option<Vec<Identifier>>),
10041    Delete,
10042    Truncate,
10043}
10044
10045/// Trigger FOR EACH clause
10046#[derive(
10047    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10048)]
10049#[cfg_attr(feature = "bindings", derive(TS))]
10050pub enum TriggerForEach {
10051    Row,
10052    Statement,
10053}
10054
10055/// Trigger body
10056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10057#[cfg_attr(feature = "bindings", derive(TS))]
10058pub enum TriggerBody {
10059    /// EXECUTE FUNCTION/PROCEDURE name(args)
10060    Execute {
10061        function: TableRef,
10062        args: Vec<Expression>,
10063    },
10064    /// BEGIN ... END block
10065    Block(String),
10066}
10067
10068/// Trigger REFERENCING clause
10069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10070#[cfg_attr(feature = "bindings", derive(TS))]
10071pub struct TriggerReferencing {
10072    pub old_table: Option<Identifier>,
10073    pub new_table: Option<Identifier>,
10074    pub old_row: Option<Identifier>,
10075    pub new_row: Option<Identifier>,
10076}
10077
10078impl CreateTrigger {
10079    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
10080        Self {
10081            name: Identifier::new(name),
10082            table: TableRef::new(table),
10083            timing: TriggerTiming::Before,
10084            events: Vec::new(),
10085            for_each: Some(TriggerForEach::Row),
10086            when: None,
10087            when_paren: false,
10088            body: TriggerBody::Execute {
10089                function: TableRef::new(""),
10090                args: Vec::new(),
10091            },
10092            or_replace: false,
10093            or_alter: false,
10094            constraint: false,
10095            deferrable: None,
10096            initially_deferred: None,
10097            referencing: None,
10098        }
10099    }
10100}
10101
10102/// DROP TRIGGER statement
10103#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10104#[cfg_attr(feature = "bindings", derive(TS))]
10105pub struct DropTrigger {
10106    pub name: Identifier,
10107    pub table: Option<TableRef>,
10108    pub if_exists: bool,
10109    pub cascade: bool,
10110}
10111
10112impl DropTrigger {
10113    pub fn new(name: impl Into<String>) -> Self {
10114        Self {
10115            name: Identifier::new(name),
10116            table: None,
10117            if_exists: false,
10118            cascade: false,
10119        }
10120    }
10121}
10122
10123/// CREATE TYPE statement
10124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10125#[cfg_attr(feature = "bindings", derive(TS))]
10126pub struct CreateType {
10127    pub name: TableRef,
10128    pub definition: TypeDefinition,
10129    pub if_not_exists: bool,
10130}
10131
10132/// Type definition
10133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10134#[cfg_attr(feature = "bindings", derive(TS))]
10135pub enum TypeDefinition {
10136    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
10137    Enum(Vec<String>),
10138    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
10139    Composite(Vec<TypeAttribute>),
10140    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
10141    Range {
10142        subtype: DataType,
10143        subtype_diff: Option<String>,
10144        canonical: Option<String>,
10145    },
10146    /// Base type (for advanced usage)
10147    Base {
10148        input: String,
10149        output: String,
10150        internallength: Option<i32>,
10151    },
10152    /// Domain type
10153    Domain {
10154        base_type: DataType,
10155        default: Option<Expression>,
10156        constraints: Vec<DomainConstraint>,
10157    },
10158}
10159
10160/// Type attribute for composite types
10161#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10162#[cfg_attr(feature = "bindings", derive(TS))]
10163pub struct TypeAttribute {
10164    pub name: Identifier,
10165    pub data_type: DataType,
10166    pub collate: Option<Identifier>,
10167}
10168
10169/// Domain constraint
10170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10171#[cfg_attr(feature = "bindings", derive(TS))]
10172pub struct DomainConstraint {
10173    pub name: Option<Identifier>,
10174    pub check: Expression,
10175}
10176
10177impl CreateType {
10178    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
10179        Self {
10180            name: TableRef::new(name),
10181            definition: TypeDefinition::Enum(values),
10182            if_not_exists: false,
10183        }
10184    }
10185
10186    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
10187        Self {
10188            name: TableRef::new(name),
10189            definition: TypeDefinition::Composite(attributes),
10190            if_not_exists: false,
10191        }
10192    }
10193}
10194
10195/// DROP TYPE statement
10196#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10197#[cfg_attr(feature = "bindings", derive(TS))]
10198pub struct DropType {
10199    pub name: TableRef,
10200    pub if_exists: bool,
10201    pub cascade: bool,
10202}
10203
10204impl DropType {
10205    pub fn new(name: impl Into<String>) -> Self {
10206        Self {
10207            name: TableRef::new(name),
10208            if_exists: false,
10209            cascade: false,
10210        }
10211    }
10212}
10213
10214/// DESCRIBE statement - shows table structure or query plan
10215#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10216#[cfg_attr(feature = "bindings", derive(TS))]
10217pub struct Describe {
10218    /// The target to describe (table name or query)
10219    pub target: Expression,
10220    /// EXTENDED format
10221    pub extended: bool,
10222    /// FORMATTED format
10223    pub formatted: bool,
10224    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10225    #[serde(default)]
10226    pub kind: Option<String>,
10227    /// Properties like type=stage
10228    #[serde(default)]
10229    pub properties: Vec<(String, String)>,
10230    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10231    #[serde(default, skip_serializing_if = "Option::is_none")]
10232    pub style: Option<String>,
10233    /// Partition specification for DESCRIBE PARTITION
10234    #[serde(default)]
10235    pub partition: Option<Box<Expression>>,
10236    /// Leading comments before the statement
10237    #[serde(default)]
10238    pub leading_comments: Vec<String>,
10239    /// AS JSON suffix (Databricks)
10240    #[serde(default)]
10241    pub as_json: bool,
10242    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10243    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10244    pub params: Vec<String>,
10245}
10246
10247impl Describe {
10248    pub fn new(target: Expression) -> Self {
10249        Self {
10250            target,
10251            extended: false,
10252            formatted: false,
10253            kind: None,
10254            properties: Vec::new(),
10255            style: None,
10256            partition: None,
10257            leading_comments: Vec::new(),
10258            as_json: false,
10259            params: Vec::new(),
10260        }
10261    }
10262}
10263
10264/// SHOW statement - displays database objects
10265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10266#[cfg_attr(feature = "bindings", derive(TS))]
10267pub struct Show {
10268    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10269    pub this: String,
10270    /// Whether TERSE was specified
10271    #[serde(default)]
10272    pub terse: bool,
10273    /// Whether HISTORY was specified
10274    #[serde(default)]
10275    pub history: bool,
10276    /// LIKE pattern
10277    pub like: Option<Expression>,
10278    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10279    pub scope_kind: Option<String>,
10280    /// IN scope object
10281    pub scope: Option<Expression>,
10282    /// STARTS WITH pattern
10283    pub starts_with: Option<Expression>,
10284    /// LIMIT clause
10285    pub limit: Option<Box<Limit>>,
10286    /// FROM clause (for specific object)
10287    pub from: Option<Expression>,
10288    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10289    #[serde(default, skip_serializing_if = "Option::is_none")]
10290    pub where_clause: Option<Expression>,
10291    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10292    #[serde(default, skip_serializing_if = "Option::is_none")]
10293    pub for_target: Option<Expression>,
10294    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10295    #[serde(default, skip_serializing_if = "Option::is_none")]
10296    pub db: Option<Expression>,
10297    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10298    #[serde(default, skip_serializing_if = "Option::is_none")]
10299    pub target: Option<Expression>,
10300    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10301    #[serde(default, skip_serializing_if = "Option::is_none")]
10302    pub mutex: Option<bool>,
10303    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10304    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10305    pub privileges: Vec<String>,
10306}
10307
10308impl Show {
10309    pub fn new(this: impl Into<String>) -> Self {
10310        Self {
10311            this: this.into(),
10312            terse: false,
10313            history: false,
10314            like: None,
10315            scope_kind: None,
10316            scope: None,
10317            starts_with: None,
10318            limit: None,
10319            from: None,
10320            where_clause: None,
10321            for_target: None,
10322            db: None,
10323            target: None,
10324            mutex: None,
10325            privileges: Vec::new(),
10326        }
10327    }
10328}
10329
10330/// Represent an explicit parenthesized expression for grouping precedence.
10331///
10332/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10333/// correctly instead of being flattened to `a + b * c`.
10334#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10335#[cfg_attr(feature = "bindings", derive(TS))]
10336pub struct Paren {
10337    /// The inner expression wrapped by parentheses.
10338    pub this: Expression,
10339    #[serde(default)]
10340    pub trailing_comments: Vec<String>,
10341}
10342
10343/// Expression annotated with trailing comments (for round-trip preservation)
10344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10345#[cfg_attr(feature = "bindings", derive(TS))]
10346pub struct Annotated {
10347    pub this: Expression,
10348    pub trailing_comments: Vec<String>,
10349}
10350
10351// === BATCH GENERATED STRUCT DEFINITIONS ===
10352// Generated from Python sqlglot expressions.py
10353
10354/// Refresh
10355#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10356#[cfg_attr(feature = "bindings", derive(TS))]
10357pub struct Refresh {
10358    pub this: Box<Expression>,
10359    pub kind: String,
10360}
10361
10362/// LockingStatement
10363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10364#[cfg_attr(feature = "bindings", derive(TS))]
10365pub struct LockingStatement {
10366    pub this: Box<Expression>,
10367    pub expression: Box<Expression>,
10368}
10369
10370/// SequenceProperties
10371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10372#[cfg_attr(feature = "bindings", derive(TS))]
10373pub struct SequenceProperties {
10374    #[serde(default)]
10375    pub increment: Option<Box<Expression>>,
10376    #[serde(default)]
10377    pub minvalue: Option<Box<Expression>>,
10378    #[serde(default)]
10379    pub maxvalue: Option<Box<Expression>>,
10380    #[serde(default)]
10381    pub cache: Option<Box<Expression>>,
10382    #[serde(default)]
10383    pub start: Option<Box<Expression>>,
10384    #[serde(default)]
10385    pub owned: Option<Box<Expression>>,
10386    #[serde(default)]
10387    pub options: Vec<Expression>,
10388}
10389
10390/// TruncateTable
10391#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10392#[cfg_attr(feature = "bindings", derive(TS))]
10393pub struct TruncateTable {
10394    #[serde(default)]
10395    pub expressions: Vec<Expression>,
10396    #[serde(default)]
10397    pub is_database: Option<Box<Expression>>,
10398    #[serde(default)]
10399    pub exists: bool,
10400    #[serde(default)]
10401    pub only: Option<Box<Expression>>,
10402    #[serde(default)]
10403    pub cluster: Option<Box<Expression>>,
10404    #[serde(default)]
10405    pub identity: Option<Box<Expression>>,
10406    #[serde(default)]
10407    pub option: Option<Box<Expression>>,
10408    #[serde(default)]
10409    pub partition: Option<Box<Expression>>,
10410}
10411
10412/// Clone
10413#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10414#[cfg_attr(feature = "bindings", derive(TS))]
10415pub struct Clone {
10416    pub this: Box<Expression>,
10417    #[serde(default)]
10418    pub shallow: Option<Box<Expression>>,
10419    #[serde(default)]
10420    pub copy: Option<Box<Expression>>,
10421}
10422
10423/// Attach
10424#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10425#[cfg_attr(feature = "bindings", derive(TS))]
10426pub struct Attach {
10427    pub this: Box<Expression>,
10428    #[serde(default)]
10429    pub exists: bool,
10430    #[serde(default)]
10431    pub expressions: Vec<Expression>,
10432}
10433
10434/// Detach
10435#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10436#[cfg_attr(feature = "bindings", derive(TS))]
10437pub struct Detach {
10438    pub this: Box<Expression>,
10439    #[serde(default)]
10440    pub exists: bool,
10441}
10442
10443/// Install
10444#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10445#[cfg_attr(feature = "bindings", derive(TS))]
10446pub struct Install {
10447    pub this: Box<Expression>,
10448    #[serde(default)]
10449    pub from_: Option<Box<Expression>>,
10450    #[serde(default)]
10451    pub force: Option<Box<Expression>>,
10452}
10453
10454/// Summarize
10455#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10456#[cfg_attr(feature = "bindings", derive(TS))]
10457pub struct Summarize {
10458    pub this: Box<Expression>,
10459    #[serde(default)]
10460    pub table: Option<Box<Expression>>,
10461}
10462
10463/// Declare
10464#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10465#[cfg_attr(feature = "bindings", derive(TS))]
10466pub struct Declare {
10467    #[serde(default)]
10468    pub expressions: Vec<Expression>,
10469    #[serde(default)]
10470    pub replace: bool,
10471}
10472
10473/// DeclareItem
10474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10475#[cfg_attr(feature = "bindings", derive(TS))]
10476pub struct DeclareItem {
10477    pub this: Box<Expression>,
10478    #[serde(default)]
10479    pub kind: Option<String>,
10480    #[serde(default)]
10481    pub default: Option<Box<Expression>>,
10482    #[serde(default)]
10483    pub has_as: bool,
10484    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10485    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10486    pub additional_names: Vec<Expression>,
10487}
10488
10489/// Set
10490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10491#[cfg_attr(feature = "bindings", derive(TS))]
10492pub struct Set {
10493    #[serde(default)]
10494    pub expressions: Vec<Expression>,
10495    #[serde(default)]
10496    pub unset: Option<Box<Expression>>,
10497    #[serde(default)]
10498    pub tag: Option<Box<Expression>>,
10499}
10500
10501/// Heredoc
10502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10503#[cfg_attr(feature = "bindings", derive(TS))]
10504pub struct Heredoc {
10505    pub this: Box<Expression>,
10506    #[serde(default)]
10507    pub tag: Option<Box<Expression>>,
10508}
10509
10510/// QueryBand
10511#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10512#[cfg_attr(feature = "bindings", derive(TS))]
10513pub struct QueryBand {
10514    pub this: Box<Expression>,
10515    #[serde(default)]
10516    pub scope: Option<Box<Expression>>,
10517    #[serde(default)]
10518    pub update: Option<Box<Expression>>,
10519}
10520
10521/// UserDefinedFunction
10522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10523#[cfg_attr(feature = "bindings", derive(TS))]
10524pub struct UserDefinedFunction {
10525    pub this: Box<Expression>,
10526    #[serde(default)]
10527    pub expressions: Vec<Expression>,
10528    #[serde(default)]
10529    pub wrapped: Option<Box<Expression>>,
10530}
10531
10532/// RecursiveWithSearch
10533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10534#[cfg_attr(feature = "bindings", derive(TS))]
10535pub struct RecursiveWithSearch {
10536    pub kind: String,
10537    pub this: Box<Expression>,
10538    pub expression: Box<Expression>,
10539    #[serde(default)]
10540    pub using: Option<Box<Expression>>,
10541}
10542
10543/// ProjectionDef
10544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10545#[cfg_attr(feature = "bindings", derive(TS))]
10546pub struct ProjectionDef {
10547    pub this: Box<Expression>,
10548    pub expression: Box<Expression>,
10549}
10550
10551/// TableAlias
10552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10553#[cfg_attr(feature = "bindings", derive(TS))]
10554pub struct TableAlias {
10555    #[serde(default)]
10556    pub this: Option<Box<Expression>>,
10557    #[serde(default)]
10558    pub columns: Vec<Expression>,
10559}
10560
10561/// ByteString
10562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10563#[cfg_attr(feature = "bindings", derive(TS))]
10564pub struct ByteString {
10565    pub this: Box<Expression>,
10566    #[serde(default)]
10567    pub is_bytes: Option<Box<Expression>>,
10568}
10569
10570/// HexStringExpr - Hex string expression (not literal)
10571/// BigQuery: converts to FROM_HEX(this)
10572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10573#[cfg_attr(feature = "bindings", derive(TS))]
10574pub struct HexStringExpr {
10575    pub this: Box<Expression>,
10576    #[serde(default)]
10577    pub is_integer: Option<bool>,
10578}
10579
10580/// UnicodeString
10581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10582#[cfg_attr(feature = "bindings", derive(TS))]
10583pub struct UnicodeString {
10584    pub this: Box<Expression>,
10585    #[serde(default)]
10586    pub escape: Option<Box<Expression>>,
10587}
10588
10589/// AlterColumn
10590#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10591#[cfg_attr(feature = "bindings", derive(TS))]
10592pub struct AlterColumn {
10593    pub this: Box<Expression>,
10594    #[serde(default)]
10595    pub dtype: Option<Box<Expression>>,
10596    #[serde(default)]
10597    pub collate: Option<Box<Expression>>,
10598    #[serde(default)]
10599    pub using: Option<Box<Expression>>,
10600    #[serde(default)]
10601    pub default: Option<Box<Expression>>,
10602    #[serde(default)]
10603    pub drop: Option<Box<Expression>>,
10604    #[serde(default)]
10605    pub comment: Option<Box<Expression>>,
10606    #[serde(default)]
10607    pub allow_null: Option<Box<Expression>>,
10608    #[serde(default)]
10609    pub visible: Option<Box<Expression>>,
10610    #[serde(default)]
10611    pub rename_to: Option<Box<Expression>>,
10612}
10613
10614/// AlterSortKey
10615#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10616#[cfg_attr(feature = "bindings", derive(TS))]
10617pub struct AlterSortKey {
10618    #[serde(default)]
10619    pub this: Option<Box<Expression>>,
10620    #[serde(default)]
10621    pub expressions: Vec<Expression>,
10622    #[serde(default)]
10623    pub compound: Option<Box<Expression>>,
10624}
10625
10626/// AlterSet
10627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10628#[cfg_attr(feature = "bindings", derive(TS))]
10629pub struct AlterSet {
10630    #[serde(default)]
10631    pub expressions: Vec<Expression>,
10632    #[serde(default)]
10633    pub option: Option<Box<Expression>>,
10634    #[serde(default)]
10635    pub tablespace: Option<Box<Expression>>,
10636    #[serde(default)]
10637    pub access_method: Option<Box<Expression>>,
10638    #[serde(default)]
10639    pub file_format: Option<Box<Expression>>,
10640    #[serde(default)]
10641    pub copy_options: Option<Box<Expression>>,
10642    #[serde(default)]
10643    pub tag: Option<Box<Expression>>,
10644    #[serde(default)]
10645    pub location: Option<Box<Expression>>,
10646    #[serde(default)]
10647    pub serde: Option<Box<Expression>>,
10648}
10649
10650/// RenameColumn
10651#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10652#[cfg_attr(feature = "bindings", derive(TS))]
10653pub struct RenameColumn {
10654    pub this: Box<Expression>,
10655    #[serde(default)]
10656    pub to: Option<Box<Expression>>,
10657    #[serde(default)]
10658    pub exists: bool,
10659}
10660
10661/// Comprehension
10662#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10663#[cfg_attr(feature = "bindings", derive(TS))]
10664pub struct Comprehension {
10665    pub this: Box<Expression>,
10666    pub expression: Box<Expression>,
10667    #[serde(default)]
10668    pub position: Option<Box<Expression>>,
10669    #[serde(default)]
10670    pub iterator: Option<Box<Expression>>,
10671    #[serde(default)]
10672    pub condition: Option<Box<Expression>>,
10673}
10674
10675/// MergeTreeTTLAction
10676#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10677#[cfg_attr(feature = "bindings", derive(TS))]
10678pub struct MergeTreeTTLAction {
10679    pub this: Box<Expression>,
10680    #[serde(default)]
10681    pub delete: Option<Box<Expression>>,
10682    #[serde(default)]
10683    pub recompress: Option<Box<Expression>>,
10684    #[serde(default)]
10685    pub to_disk: Option<Box<Expression>>,
10686    #[serde(default)]
10687    pub to_volume: Option<Box<Expression>>,
10688}
10689
10690/// MergeTreeTTL
10691#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10692#[cfg_attr(feature = "bindings", derive(TS))]
10693pub struct MergeTreeTTL {
10694    #[serde(default)]
10695    pub expressions: Vec<Expression>,
10696    #[serde(default)]
10697    pub where_: Option<Box<Expression>>,
10698    #[serde(default)]
10699    pub group: Option<Box<Expression>>,
10700    #[serde(default)]
10701    pub aggregates: Option<Box<Expression>>,
10702}
10703
10704/// IndexConstraintOption
10705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10706#[cfg_attr(feature = "bindings", derive(TS))]
10707pub struct IndexConstraintOption {
10708    #[serde(default)]
10709    pub key_block_size: Option<Box<Expression>>,
10710    #[serde(default)]
10711    pub using: Option<Box<Expression>>,
10712    #[serde(default)]
10713    pub parser: Option<Box<Expression>>,
10714    #[serde(default)]
10715    pub comment: Option<Box<Expression>>,
10716    #[serde(default)]
10717    pub visible: Option<Box<Expression>>,
10718    #[serde(default)]
10719    pub engine_attr: Option<Box<Expression>>,
10720    #[serde(default)]
10721    pub secondary_engine_attr: Option<Box<Expression>>,
10722}
10723
10724/// PeriodForSystemTimeConstraint
10725#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10726#[cfg_attr(feature = "bindings", derive(TS))]
10727pub struct PeriodForSystemTimeConstraint {
10728    pub this: Box<Expression>,
10729    pub expression: Box<Expression>,
10730}
10731
10732/// CaseSpecificColumnConstraint
10733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10734#[cfg_attr(feature = "bindings", derive(TS))]
10735pub struct CaseSpecificColumnConstraint {
10736    #[serde(default)]
10737    pub not_: Option<Box<Expression>>,
10738}
10739
10740/// CharacterSetColumnConstraint
10741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10742#[cfg_attr(feature = "bindings", derive(TS))]
10743pub struct CharacterSetColumnConstraint {
10744    pub this: Box<Expression>,
10745}
10746
10747/// CheckColumnConstraint
10748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10749#[cfg_attr(feature = "bindings", derive(TS))]
10750pub struct CheckColumnConstraint {
10751    pub this: Box<Expression>,
10752    #[serde(default)]
10753    pub enforced: Option<Box<Expression>>,
10754}
10755
10756/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
10757#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10758#[cfg_attr(feature = "bindings", derive(TS))]
10759pub struct AssumeColumnConstraint {
10760    pub this: Box<Expression>,
10761}
10762
10763/// CompressColumnConstraint
10764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10765#[cfg_attr(feature = "bindings", derive(TS))]
10766pub struct CompressColumnConstraint {
10767    #[serde(default)]
10768    pub this: Option<Box<Expression>>,
10769}
10770
10771/// DateFormatColumnConstraint
10772#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10773#[cfg_attr(feature = "bindings", derive(TS))]
10774pub struct DateFormatColumnConstraint {
10775    pub this: Box<Expression>,
10776}
10777
10778/// EphemeralColumnConstraint
10779#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10780#[cfg_attr(feature = "bindings", derive(TS))]
10781pub struct EphemeralColumnConstraint {
10782    #[serde(default)]
10783    pub this: Option<Box<Expression>>,
10784}
10785
10786/// WithOperator
10787#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10788#[cfg_attr(feature = "bindings", derive(TS))]
10789pub struct WithOperator {
10790    pub this: Box<Expression>,
10791    pub op: String,
10792}
10793
10794/// GeneratedAsIdentityColumnConstraint
10795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10796#[cfg_attr(feature = "bindings", derive(TS))]
10797pub struct GeneratedAsIdentityColumnConstraint {
10798    #[serde(default)]
10799    pub this: Option<Box<Expression>>,
10800    #[serde(default)]
10801    pub expression: Option<Box<Expression>>,
10802    #[serde(default)]
10803    pub on_null: Option<Box<Expression>>,
10804    #[serde(default)]
10805    pub start: Option<Box<Expression>>,
10806    #[serde(default)]
10807    pub increment: Option<Box<Expression>>,
10808    #[serde(default)]
10809    pub minvalue: Option<Box<Expression>>,
10810    #[serde(default)]
10811    pub maxvalue: Option<Box<Expression>>,
10812    #[serde(default)]
10813    pub cycle: Option<Box<Expression>>,
10814    #[serde(default)]
10815    pub order: Option<Box<Expression>>,
10816}
10817
10818/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
10819/// TSQL: outputs "IDENTITY"
10820#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10821#[cfg_attr(feature = "bindings", derive(TS))]
10822pub struct AutoIncrementColumnConstraint;
10823
10824/// CommentColumnConstraint - Column comment marker
10825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10826#[cfg_attr(feature = "bindings", derive(TS))]
10827pub struct CommentColumnConstraint;
10828
10829/// GeneratedAsRowColumnConstraint
10830#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10831#[cfg_attr(feature = "bindings", derive(TS))]
10832pub struct GeneratedAsRowColumnConstraint {
10833    #[serde(default)]
10834    pub start: Option<Box<Expression>>,
10835    #[serde(default)]
10836    pub hidden: Option<Box<Expression>>,
10837}
10838
10839/// IndexColumnConstraint
10840#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10841#[cfg_attr(feature = "bindings", derive(TS))]
10842pub struct IndexColumnConstraint {
10843    #[serde(default)]
10844    pub this: Option<Box<Expression>>,
10845    #[serde(default)]
10846    pub expressions: Vec<Expression>,
10847    #[serde(default)]
10848    pub kind: Option<String>,
10849    #[serde(default)]
10850    pub index_type: Option<Box<Expression>>,
10851    #[serde(default)]
10852    pub options: Vec<Expression>,
10853    #[serde(default)]
10854    pub expression: Option<Box<Expression>>,
10855    #[serde(default)]
10856    pub granularity: Option<Box<Expression>>,
10857}
10858
10859/// MaskingPolicyColumnConstraint
10860#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10861#[cfg_attr(feature = "bindings", derive(TS))]
10862pub struct MaskingPolicyColumnConstraint {
10863    pub this: Box<Expression>,
10864    #[serde(default)]
10865    pub expressions: Vec<Expression>,
10866}
10867
10868/// NotNullColumnConstraint
10869#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10870#[cfg_attr(feature = "bindings", derive(TS))]
10871pub struct NotNullColumnConstraint {
10872    #[serde(default)]
10873    pub allow_null: Option<Box<Expression>>,
10874}
10875
10876/// DefaultColumnConstraint - DEFAULT value for a column
10877#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10878#[cfg_attr(feature = "bindings", derive(TS))]
10879pub struct DefaultColumnConstraint {
10880    pub this: Box<Expression>,
10881    /// TSQL: DEFAULT value FOR column (table-level default constraint)
10882    #[serde(default, skip_serializing_if = "Option::is_none")]
10883    pub for_column: Option<Identifier>,
10884}
10885
10886/// PrimaryKeyColumnConstraint
10887#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10888#[cfg_attr(feature = "bindings", derive(TS))]
10889pub struct PrimaryKeyColumnConstraint {
10890    #[serde(default)]
10891    pub desc: Option<Box<Expression>>,
10892    #[serde(default)]
10893    pub options: Vec<Expression>,
10894}
10895
10896/// UniqueColumnConstraint
10897#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10898#[cfg_attr(feature = "bindings", derive(TS))]
10899pub struct UniqueColumnConstraint {
10900    #[serde(default)]
10901    pub this: Option<Box<Expression>>,
10902    #[serde(default)]
10903    pub index_type: Option<Box<Expression>>,
10904    #[serde(default)]
10905    pub on_conflict: Option<Box<Expression>>,
10906    #[serde(default)]
10907    pub nulls: Option<Box<Expression>>,
10908    #[serde(default)]
10909    pub options: Vec<Expression>,
10910}
10911
10912/// WatermarkColumnConstraint
10913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10914#[cfg_attr(feature = "bindings", derive(TS))]
10915pub struct WatermarkColumnConstraint {
10916    pub this: Box<Expression>,
10917    pub expression: Box<Expression>,
10918}
10919
10920/// ComputedColumnConstraint
10921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10922#[cfg_attr(feature = "bindings", derive(TS))]
10923pub struct ComputedColumnConstraint {
10924    pub this: Box<Expression>,
10925    #[serde(default)]
10926    pub persisted: Option<Box<Expression>>,
10927    #[serde(default)]
10928    pub not_null: Option<Box<Expression>>,
10929    #[serde(default)]
10930    pub data_type: Option<Box<Expression>>,
10931}
10932
10933/// InOutColumnConstraint
10934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10935#[cfg_attr(feature = "bindings", derive(TS))]
10936pub struct InOutColumnConstraint {
10937    #[serde(default)]
10938    pub input_: Option<Box<Expression>>,
10939    #[serde(default)]
10940    pub output: Option<Box<Expression>>,
10941}
10942
10943/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
10944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10945#[cfg_attr(feature = "bindings", derive(TS))]
10946pub struct PathColumnConstraint {
10947    pub this: Box<Expression>,
10948}
10949
10950/// Constraint
10951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10952#[cfg_attr(feature = "bindings", derive(TS))]
10953pub struct Constraint {
10954    pub this: Box<Expression>,
10955    #[serde(default)]
10956    pub expressions: Vec<Expression>,
10957}
10958
10959/// Export
10960#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10961#[cfg_attr(feature = "bindings", derive(TS))]
10962pub struct Export {
10963    pub this: Box<Expression>,
10964    #[serde(default)]
10965    pub connection: Option<Box<Expression>>,
10966    #[serde(default)]
10967    pub options: Vec<Expression>,
10968}
10969
10970/// Filter
10971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10972#[cfg_attr(feature = "bindings", derive(TS))]
10973pub struct Filter {
10974    pub this: Box<Expression>,
10975    pub expression: Box<Expression>,
10976}
10977
10978/// Changes
10979#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10980#[cfg_attr(feature = "bindings", derive(TS))]
10981pub struct Changes {
10982    #[serde(default)]
10983    pub information: Option<Box<Expression>>,
10984    #[serde(default)]
10985    pub at_before: Option<Box<Expression>>,
10986    #[serde(default)]
10987    pub end: Option<Box<Expression>>,
10988}
10989
10990/// Directory
10991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10992#[cfg_attr(feature = "bindings", derive(TS))]
10993pub struct Directory {
10994    pub this: Box<Expression>,
10995    #[serde(default)]
10996    pub local: Option<Box<Expression>>,
10997    #[serde(default)]
10998    pub row_format: Option<Box<Expression>>,
10999}
11000
11001/// ForeignKey
11002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11003#[cfg_attr(feature = "bindings", derive(TS))]
11004pub struct ForeignKey {
11005    #[serde(default)]
11006    pub expressions: Vec<Expression>,
11007    #[serde(default)]
11008    pub reference: Option<Box<Expression>>,
11009    #[serde(default)]
11010    pub delete: Option<Box<Expression>>,
11011    #[serde(default)]
11012    pub update: Option<Box<Expression>>,
11013    #[serde(default)]
11014    pub options: Vec<Expression>,
11015}
11016
11017/// ColumnPrefix
11018#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11019#[cfg_attr(feature = "bindings", derive(TS))]
11020pub struct ColumnPrefix {
11021    pub this: Box<Expression>,
11022    pub expression: Box<Expression>,
11023}
11024
11025/// PrimaryKey
11026#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11027#[cfg_attr(feature = "bindings", derive(TS))]
11028pub struct PrimaryKey {
11029    #[serde(default)]
11030    pub this: Option<Box<Expression>>,
11031    #[serde(default)]
11032    pub expressions: Vec<Expression>,
11033    #[serde(default)]
11034    pub options: Vec<Expression>,
11035    #[serde(default)]
11036    pub include: Option<Box<Expression>>,
11037}
11038
11039/// Into
11040#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11041#[cfg_attr(feature = "bindings", derive(TS))]
11042pub struct IntoClause {
11043    #[serde(default)]
11044    pub this: Option<Box<Expression>>,
11045    #[serde(default)]
11046    pub temporary: bool,
11047    #[serde(default)]
11048    pub unlogged: Option<Box<Expression>>,
11049    #[serde(default)]
11050    pub bulk_collect: Option<Box<Expression>>,
11051    #[serde(default)]
11052    pub expressions: Vec<Expression>,
11053}
11054
11055/// JoinHint
11056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11057#[cfg_attr(feature = "bindings", derive(TS))]
11058pub struct JoinHint {
11059    pub this: Box<Expression>,
11060    #[serde(default)]
11061    pub expressions: Vec<Expression>,
11062}
11063
11064/// Opclass
11065#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11066#[cfg_attr(feature = "bindings", derive(TS))]
11067pub struct Opclass {
11068    pub this: Box<Expression>,
11069    pub expression: Box<Expression>,
11070}
11071
11072/// Index
11073#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11074#[cfg_attr(feature = "bindings", derive(TS))]
11075pub struct Index {
11076    #[serde(default)]
11077    pub this: Option<Box<Expression>>,
11078    #[serde(default)]
11079    pub table: Option<Box<Expression>>,
11080    #[serde(default)]
11081    pub unique: bool,
11082    #[serde(default)]
11083    pub primary: Option<Box<Expression>>,
11084    #[serde(default)]
11085    pub amp: Option<Box<Expression>>,
11086    #[serde(default)]
11087    pub params: Vec<Expression>,
11088}
11089
11090/// IndexParameters
11091#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11092#[cfg_attr(feature = "bindings", derive(TS))]
11093pub struct IndexParameters {
11094    #[serde(default)]
11095    pub using: Option<Box<Expression>>,
11096    #[serde(default)]
11097    pub include: Option<Box<Expression>>,
11098    #[serde(default)]
11099    pub columns: Vec<Expression>,
11100    #[serde(default)]
11101    pub with_storage: Option<Box<Expression>>,
11102    #[serde(default)]
11103    pub partition_by: Option<Box<Expression>>,
11104    #[serde(default)]
11105    pub tablespace: Option<Box<Expression>>,
11106    #[serde(default)]
11107    pub where_: Option<Box<Expression>>,
11108    #[serde(default)]
11109    pub on: Option<Box<Expression>>,
11110}
11111
11112/// ConditionalInsert
11113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11114#[cfg_attr(feature = "bindings", derive(TS))]
11115pub struct ConditionalInsert {
11116    pub this: Box<Expression>,
11117    #[serde(default)]
11118    pub expression: Option<Box<Expression>>,
11119    #[serde(default)]
11120    pub else_: Option<Box<Expression>>,
11121}
11122
11123/// MultitableInserts
11124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11125#[cfg_attr(feature = "bindings", derive(TS))]
11126pub struct MultitableInserts {
11127    #[serde(default)]
11128    pub expressions: Vec<Expression>,
11129    pub kind: String,
11130    #[serde(default)]
11131    pub source: Option<Box<Expression>>,
11132    /// Leading comments before the statement
11133    #[serde(default)]
11134    pub leading_comments: Vec<String>,
11135    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
11136    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11137    pub overwrite: bool,
11138}
11139
11140/// OnConflict
11141#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11142#[cfg_attr(feature = "bindings", derive(TS))]
11143pub struct OnConflict {
11144    #[serde(default)]
11145    pub duplicate: Option<Box<Expression>>,
11146    #[serde(default)]
11147    pub expressions: Vec<Expression>,
11148    #[serde(default)]
11149    pub action: Option<Box<Expression>>,
11150    #[serde(default)]
11151    pub conflict_keys: Option<Box<Expression>>,
11152    #[serde(default)]
11153    pub index_predicate: Option<Box<Expression>>,
11154    #[serde(default)]
11155    pub constraint: Option<Box<Expression>>,
11156    #[serde(default)]
11157    pub where_: Option<Box<Expression>>,
11158}
11159
11160/// OnCondition
11161#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11162#[cfg_attr(feature = "bindings", derive(TS))]
11163pub struct OnCondition {
11164    #[serde(default)]
11165    pub error: Option<Box<Expression>>,
11166    #[serde(default)]
11167    pub empty: Option<Box<Expression>>,
11168    #[serde(default)]
11169    pub null: Option<Box<Expression>>,
11170}
11171
11172/// Returning
11173#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11174#[cfg_attr(feature = "bindings", derive(TS))]
11175pub struct Returning {
11176    #[serde(default)]
11177    pub expressions: Vec<Expression>,
11178    #[serde(default)]
11179    pub into: Option<Box<Expression>>,
11180}
11181
11182/// Introducer
11183#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11184#[cfg_attr(feature = "bindings", derive(TS))]
11185pub struct Introducer {
11186    pub this: Box<Expression>,
11187    pub expression: Box<Expression>,
11188}
11189
11190/// PartitionRange
11191#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11192#[cfg_attr(feature = "bindings", derive(TS))]
11193pub struct PartitionRange {
11194    pub this: Box<Expression>,
11195    #[serde(default)]
11196    pub expression: Option<Box<Expression>>,
11197    #[serde(default)]
11198    pub expressions: Vec<Expression>,
11199}
11200
11201/// Group
11202#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11203#[cfg_attr(feature = "bindings", derive(TS))]
11204pub struct Group {
11205    #[serde(default)]
11206    pub expressions: Vec<Expression>,
11207    #[serde(default)]
11208    pub grouping_sets: Option<Box<Expression>>,
11209    #[serde(default)]
11210    pub cube: Option<Box<Expression>>,
11211    #[serde(default)]
11212    pub rollup: Option<Box<Expression>>,
11213    #[serde(default)]
11214    pub totals: Option<Box<Expression>>,
11215    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11216    #[serde(default)]
11217    pub all: Option<bool>,
11218}
11219
11220/// Cube
11221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11222#[cfg_attr(feature = "bindings", derive(TS))]
11223pub struct Cube {
11224    #[serde(default)]
11225    pub expressions: Vec<Expression>,
11226}
11227
11228/// Rollup
11229#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11230#[cfg_attr(feature = "bindings", derive(TS))]
11231pub struct Rollup {
11232    #[serde(default)]
11233    pub expressions: Vec<Expression>,
11234}
11235
11236/// GroupingSets
11237#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11238#[cfg_attr(feature = "bindings", derive(TS))]
11239pub struct GroupingSets {
11240    #[serde(default)]
11241    pub expressions: Vec<Expression>,
11242}
11243
11244/// LimitOptions
11245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11246#[cfg_attr(feature = "bindings", derive(TS))]
11247pub struct LimitOptions {
11248    #[serde(default)]
11249    pub percent: Option<Box<Expression>>,
11250    #[serde(default)]
11251    pub rows: Option<Box<Expression>>,
11252    #[serde(default)]
11253    pub with_ties: Option<Box<Expression>>,
11254}
11255
11256/// Lateral
11257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11258#[cfg_attr(feature = "bindings", derive(TS))]
11259pub struct Lateral {
11260    pub this: Box<Expression>,
11261    #[serde(default)]
11262    pub view: Option<Box<Expression>>,
11263    #[serde(default)]
11264    pub outer: Option<Box<Expression>>,
11265    #[serde(default)]
11266    pub alias: Option<String>,
11267    /// Whether the alias was originally quoted (backtick/double-quote)
11268    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11269    pub alias_quoted: bool,
11270    #[serde(default)]
11271    pub cross_apply: Option<Box<Expression>>,
11272    #[serde(default)]
11273    pub ordinality: Option<Box<Expression>>,
11274    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11275    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11276    pub column_aliases: Vec<String>,
11277}
11278
11279/// TableFromRows
11280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11281#[cfg_attr(feature = "bindings", derive(TS))]
11282pub struct TableFromRows {
11283    pub this: Box<Expression>,
11284    #[serde(default)]
11285    pub alias: Option<String>,
11286    #[serde(default)]
11287    pub joins: Vec<Expression>,
11288    #[serde(default)]
11289    pub pivots: Option<Box<Expression>>,
11290    #[serde(default)]
11291    pub sample: Option<Box<Expression>>,
11292}
11293
11294/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11295/// Used for set-returning functions with typed column definitions
11296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11297#[cfg_attr(feature = "bindings", derive(TS))]
11298pub struct RowsFrom {
11299    /// List of function expressions, each potentially with an alias and typed columns
11300    pub expressions: Vec<Expression>,
11301    /// WITH ORDINALITY modifier
11302    #[serde(default)]
11303    pub ordinality: bool,
11304    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11305    #[serde(default)]
11306    pub alias: Option<Box<Expression>>,
11307}
11308
11309/// WithFill
11310#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11311#[cfg_attr(feature = "bindings", derive(TS))]
11312pub struct WithFill {
11313    #[serde(default)]
11314    pub from_: Option<Box<Expression>>,
11315    #[serde(default)]
11316    pub to: Option<Box<Expression>>,
11317    #[serde(default)]
11318    pub step: Option<Box<Expression>>,
11319    #[serde(default)]
11320    pub staleness: Option<Box<Expression>>,
11321    #[serde(default)]
11322    pub interpolate: Option<Box<Expression>>,
11323}
11324
11325/// Property
11326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11327#[cfg_attr(feature = "bindings", derive(TS))]
11328pub struct Property {
11329    pub this: Box<Expression>,
11330    #[serde(default)]
11331    pub value: Option<Box<Expression>>,
11332}
11333
11334/// GrantPrivilege
11335#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11336#[cfg_attr(feature = "bindings", derive(TS))]
11337pub struct GrantPrivilege {
11338    pub this: Box<Expression>,
11339    #[serde(default)]
11340    pub expressions: Vec<Expression>,
11341}
11342
11343/// AllowedValuesProperty
11344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11345#[cfg_attr(feature = "bindings", derive(TS))]
11346pub struct AllowedValuesProperty {
11347    #[serde(default)]
11348    pub expressions: Vec<Expression>,
11349}
11350
11351/// AlgorithmProperty
11352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11353#[cfg_attr(feature = "bindings", derive(TS))]
11354pub struct AlgorithmProperty {
11355    pub this: Box<Expression>,
11356}
11357
11358/// AutoIncrementProperty
11359#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11360#[cfg_attr(feature = "bindings", derive(TS))]
11361pub struct AutoIncrementProperty {
11362    pub this: Box<Expression>,
11363}
11364
11365/// AutoRefreshProperty
11366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11367#[cfg_attr(feature = "bindings", derive(TS))]
11368pub struct AutoRefreshProperty {
11369    pub this: Box<Expression>,
11370}
11371
11372/// BackupProperty
11373#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11374#[cfg_attr(feature = "bindings", derive(TS))]
11375pub struct BackupProperty {
11376    pub this: Box<Expression>,
11377}
11378
11379/// BuildProperty
11380#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11381#[cfg_attr(feature = "bindings", derive(TS))]
11382pub struct BuildProperty {
11383    pub this: Box<Expression>,
11384}
11385
11386/// BlockCompressionProperty
11387#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11388#[cfg_attr(feature = "bindings", derive(TS))]
11389pub struct BlockCompressionProperty {
11390    #[serde(default)]
11391    pub autotemp: Option<Box<Expression>>,
11392    #[serde(default)]
11393    pub always: Option<Box<Expression>>,
11394    #[serde(default)]
11395    pub default: Option<Box<Expression>>,
11396    #[serde(default)]
11397    pub manual: Option<Box<Expression>>,
11398    #[serde(default)]
11399    pub never: Option<Box<Expression>>,
11400}
11401
11402/// CharacterSetProperty
11403#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11404#[cfg_attr(feature = "bindings", derive(TS))]
11405pub struct CharacterSetProperty {
11406    pub this: Box<Expression>,
11407    #[serde(default)]
11408    pub default: Option<Box<Expression>>,
11409}
11410
11411/// ChecksumProperty
11412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11413#[cfg_attr(feature = "bindings", derive(TS))]
11414pub struct ChecksumProperty {
11415    #[serde(default)]
11416    pub on: Option<Box<Expression>>,
11417    #[serde(default)]
11418    pub default: Option<Box<Expression>>,
11419}
11420
11421/// CollateProperty
11422#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11423#[cfg_attr(feature = "bindings", derive(TS))]
11424pub struct CollateProperty {
11425    pub this: Box<Expression>,
11426    #[serde(default)]
11427    pub default: Option<Box<Expression>>,
11428}
11429
11430/// DataBlocksizeProperty
11431#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11432#[cfg_attr(feature = "bindings", derive(TS))]
11433pub struct DataBlocksizeProperty {
11434    #[serde(default)]
11435    pub size: Option<i64>,
11436    #[serde(default)]
11437    pub units: Option<Box<Expression>>,
11438    #[serde(default)]
11439    pub minimum: Option<Box<Expression>>,
11440    #[serde(default)]
11441    pub maximum: Option<Box<Expression>>,
11442    #[serde(default)]
11443    pub default: Option<Box<Expression>>,
11444}
11445
11446/// DataDeletionProperty
11447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11448#[cfg_attr(feature = "bindings", derive(TS))]
11449pub struct DataDeletionProperty {
11450    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11451    #[ast(skip)]
11452    pub on: Box<Expression>,
11453    #[serde(default)]
11454    pub filter_column: Option<Box<Expression>>,
11455    #[serde(default)]
11456    pub retention_period: Option<Box<Expression>>,
11457}
11458
11459/// DefinerProperty
11460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11461#[cfg_attr(feature = "bindings", derive(TS))]
11462pub struct DefinerProperty {
11463    pub this: Box<Expression>,
11464}
11465
11466/// DistKeyProperty
11467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11468#[cfg_attr(feature = "bindings", derive(TS))]
11469pub struct DistKeyProperty {
11470    pub this: Box<Expression>,
11471}
11472
11473/// DistributedByProperty
11474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11475#[cfg_attr(feature = "bindings", derive(TS))]
11476pub struct DistributedByProperty {
11477    #[serde(default)]
11478    pub expressions: Vec<Expression>,
11479    pub kind: String,
11480    #[serde(default)]
11481    pub buckets: Option<Box<Expression>>,
11482    #[serde(default)]
11483    pub order: Option<Box<Expression>>,
11484}
11485
11486/// DistStyleProperty
11487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11488#[cfg_attr(feature = "bindings", derive(TS))]
11489pub struct DistStyleProperty {
11490    pub this: Box<Expression>,
11491}
11492
11493/// DuplicateKeyProperty
11494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11495#[cfg_attr(feature = "bindings", derive(TS))]
11496pub struct DuplicateKeyProperty {
11497    #[serde(default)]
11498    pub expressions: Vec<Expression>,
11499}
11500
11501/// EngineProperty
11502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11503#[cfg_attr(feature = "bindings", derive(TS))]
11504pub struct EngineProperty {
11505    pub this: Box<Expression>,
11506}
11507
11508/// ToTableProperty
11509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11510#[cfg_attr(feature = "bindings", derive(TS))]
11511pub struct ToTableProperty {
11512    pub this: Box<Expression>,
11513}
11514
11515/// ExecuteAsProperty
11516#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11517#[cfg_attr(feature = "bindings", derive(TS))]
11518pub struct ExecuteAsProperty {
11519    pub this: Box<Expression>,
11520}
11521
11522/// ExternalProperty
11523#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11524#[cfg_attr(feature = "bindings", derive(TS))]
11525pub struct ExternalProperty {
11526    #[serde(default)]
11527    pub this: Option<Box<Expression>>,
11528}
11529
11530/// FallbackProperty
11531#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11532#[cfg_attr(feature = "bindings", derive(TS))]
11533pub struct FallbackProperty {
11534    #[serde(default)]
11535    pub no: Option<Box<Expression>>,
11536    #[serde(default)]
11537    pub protection: Option<Box<Expression>>,
11538}
11539
11540/// FileFormatProperty
11541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11542#[cfg_attr(feature = "bindings", derive(TS))]
11543pub struct FileFormatProperty {
11544    #[serde(default)]
11545    pub this: Option<Box<Expression>>,
11546    #[serde(default)]
11547    pub expressions: Vec<Expression>,
11548    #[serde(default)]
11549    pub hive_format: Option<Box<Expression>>,
11550}
11551
11552/// CredentialsProperty
11553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11554#[cfg_attr(feature = "bindings", derive(TS))]
11555pub struct CredentialsProperty {
11556    #[serde(default)]
11557    pub expressions: Vec<Expression>,
11558}
11559
11560/// FreespaceProperty
11561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11562#[cfg_attr(feature = "bindings", derive(TS))]
11563pub struct FreespaceProperty {
11564    pub this: Box<Expression>,
11565    #[serde(default)]
11566    pub percent: Option<Box<Expression>>,
11567}
11568
11569/// InheritsProperty
11570#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11571#[cfg_attr(feature = "bindings", derive(TS))]
11572pub struct InheritsProperty {
11573    #[serde(default)]
11574    pub expressions: Vec<Expression>,
11575}
11576
11577/// InputModelProperty
11578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11579#[cfg_attr(feature = "bindings", derive(TS))]
11580pub struct InputModelProperty {
11581    pub this: Box<Expression>,
11582}
11583
11584/// OutputModelProperty
11585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11586#[cfg_attr(feature = "bindings", derive(TS))]
11587pub struct OutputModelProperty {
11588    pub this: Box<Expression>,
11589}
11590
11591/// IsolatedLoadingProperty
11592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11593#[cfg_attr(feature = "bindings", derive(TS))]
11594pub struct IsolatedLoadingProperty {
11595    #[serde(default)]
11596    pub no: Option<Box<Expression>>,
11597    #[serde(default)]
11598    pub concurrent: Option<Box<Expression>>,
11599    #[serde(default)]
11600    pub target: Option<Box<Expression>>,
11601}
11602
11603/// JournalProperty
11604#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11605#[cfg_attr(feature = "bindings", derive(TS))]
11606pub struct JournalProperty {
11607    #[serde(default)]
11608    pub no: Option<Box<Expression>>,
11609    #[serde(default)]
11610    pub dual: Option<Box<Expression>>,
11611    #[serde(default)]
11612    pub before: Option<Box<Expression>>,
11613    #[serde(default)]
11614    pub local: Option<Box<Expression>>,
11615    #[serde(default)]
11616    pub after: Option<Box<Expression>>,
11617}
11618
11619/// LanguageProperty
11620#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11621#[cfg_attr(feature = "bindings", derive(TS))]
11622pub struct LanguageProperty {
11623    pub this: Box<Expression>,
11624}
11625
11626/// EnviromentProperty
11627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11628#[cfg_attr(feature = "bindings", derive(TS))]
11629pub struct EnviromentProperty {
11630    #[serde(default)]
11631    pub expressions: Vec<Expression>,
11632}
11633
11634/// ClusteredByProperty
11635#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11636#[cfg_attr(feature = "bindings", derive(TS))]
11637pub struct ClusteredByProperty {
11638    #[serde(default)]
11639    pub expressions: Vec<Expression>,
11640    #[serde(default)]
11641    pub sorted_by: Option<Box<Expression>>,
11642    #[serde(default)]
11643    pub buckets: Option<Box<Expression>>,
11644}
11645
11646/// DictProperty
11647#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11648#[cfg_attr(feature = "bindings", derive(TS))]
11649pub struct DictProperty {
11650    pub this: Box<Expression>,
11651    pub kind: String,
11652    #[serde(default)]
11653    pub settings: Option<Box<Expression>>,
11654}
11655
11656/// DictRange
11657#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11658#[cfg_attr(feature = "bindings", derive(TS))]
11659pub struct DictRange {
11660    pub this: Box<Expression>,
11661    #[serde(default)]
11662    pub min: Option<Box<Expression>>,
11663    #[serde(default)]
11664    pub max: Option<Box<Expression>>,
11665}
11666
11667/// OnCluster
11668#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11669#[cfg_attr(feature = "bindings", derive(TS))]
11670pub struct OnCluster {
11671    pub this: Box<Expression>,
11672}
11673
11674/// LikeProperty
11675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11676#[cfg_attr(feature = "bindings", derive(TS))]
11677pub struct LikeProperty {
11678    pub this: Box<Expression>,
11679    #[serde(default)]
11680    pub expressions: Vec<Expression>,
11681}
11682
11683/// LocationProperty
11684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11685#[cfg_attr(feature = "bindings", derive(TS))]
11686pub struct LocationProperty {
11687    pub this: Box<Expression>,
11688}
11689
11690/// LockProperty
11691#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11692#[cfg_attr(feature = "bindings", derive(TS))]
11693pub struct LockProperty {
11694    pub this: Box<Expression>,
11695}
11696
11697/// LockingProperty
11698#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11699#[cfg_attr(feature = "bindings", derive(TS))]
11700pub struct LockingProperty {
11701    #[serde(default)]
11702    pub this: Option<Box<Expression>>,
11703    pub kind: String,
11704    #[serde(default)]
11705    pub for_or_in: Option<Box<Expression>>,
11706    #[serde(default)]
11707    pub lock_type: Option<Box<Expression>>,
11708    #[serde(default)]
11709    pub override_: Option<Box<Expression>>,
11710}
11711
11712/// LogProperty
11713#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11714#[cfg_attr(feature = "bindings", derive(TS))]
11715pub struct LogProperty {
11716    #[serde(default)]
11717    pub no: Option<Box<Expression>>,
11718}
11719
11720/// MaterializedProperty
11721#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11722#[cfg_attr(feature = "bindings", derive(TS))]
11723pub struct MaterializedProperty {
11724    #[serde(default)]
11725    pub this: Option<Box<Expression>>,
11726}
11727
11728/// MergeBlockRatioProperty
11729#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11730#[cfg_attr(feature = "bindings", derive(TS))]
11731pub struct MergeBlockRatioProperty {
11732    #[serde(default)]
11733    pub this: Option<Box<Expression>>,
11734    #[serde(default)]
11735    pub no: Option<Box<Expression>>,
11736    #[serde(default)]
11737    pub default: Option<Box<Expression>>,
11738    #[serde(default)]
11739    pub percent: Option<Box<Expression>>,
11740}
11741
11742/// OnProperty
11743#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11744#[cfg_attr(feature = "bindings", derive(TS))]
11745pub struct OnProperty {
11746    pub this: Box<Expression>,
11747}
11748
11749/// OnCommitProperty
11750#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11751#[cfg_attr(feature = "bindings", derive(TS))]
11752pub struct OnCommitProperty {
11753    #[serde(default)]
11754    pub delete: Option<Box<Expression>>,
11755}
11756
11757/// PartitionedByProperty
11758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11759#[cfg_attr(feature = "bindings", derive(TS))]
11760pub struct PartitionedByProperty {
11761    pub this: Box<Expression>,
11762}
11763
11764/// BigQuery PARTITION BY property in CREATE TABLE statements.
11765#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11766#[cfg_attr(feature = "bindings", derive(TS))]
11767pub struct PartitionByProperty {
11768    #[serde(default)]
11769    pub expressions: Vec<Expression>,
11770}
11771
11772/// PartitionedByBucket
11773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11774#[cfg_attr(feature = "bindings", derive(TS))]
11775pub struct PartitionedByBucket {
11776    pub this: Box<Expression>,
11777    pub expression: Box<Expression>,
11778}
11779
11780/// BigQuery CLUSTER BY property in CREATE TABLE statements.
11781#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11782#[cfg_attr(feature = "bindings", derive(TS))]
11783pub struct ClusterByColumnsProperty {
11784    #[serde(default)]
11785    pub columns: Vec<Identifier>,
11786}
11787
11788/// PartitionByTruncate
11789#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11790#[cfg_attr(feature = "bindings", derive(TS))]
11791pub struct PartitionByTruncate {
11792    pub this: Box<Expression>,
11793    pub expression: Box<Expression>,
11794}
11795
11796/// PartitionByRangeProperty
11797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11798#[cfg_attr(feature = "bindings", derive(TS))]
11799pub struct PartitionByRangeProperty {
11800    #[serde(default)]
11801    pub partition_expressions: Option<Box<Expression>>,
11802    #[serde(default)]
11803    pub create_expressions: Option<Box<Expression>>,
11804}
11805
11806/// PartitionByRangePropertyDynamic
11807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11808#[cfg_attr(feature = "bindings", derive(TS))]
11809pub struct PartitionByRangePropertyDynamic {
11810    #[serde(default)]
11811    pub this: Option<Box<Expression>>,
11812    #[serde(default)]
11813    pub start: Option<Box<Expression>>,
11814    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
11815    #[serde(default)]
11816    pub use_start_end: bool,
11817    #[serde(default)]
11818    pub end: Option<Box<Expression>>,
11819    #[serde(default)]
11820    pub every: Option<Box<Expression>>,
11821}
11822
11823/// PartitionByListProperty
11824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11825#[cfg_attr(feature = "bindings", derive(TS))]
11826pub struct PartitionByListProperty {
11827    #[serde(default)]
11828    pub partition_expressions: Option<Box<Expression>>,
11829    #[serde(default)]
11830    pub create_expressions: Option<Box<Expression>>,
11831}
11832
11833/// PartitionList
11834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11835#[cfg_attr(feature = "bindings", derive(TS))]
11836pub struct PartitionList {
11837    pub this: Box<Expression>,
11838    #[serde(default)]
11839    pub expressions: Vec<Expression>,
11840}
11841
11842/// Partition - represents PARTITION/SUBPARTITION clause
11843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11844#[cfg_attr(feature = "bindings", derive(TS))]
11845pub struct Partition {
11846    pub expressions: Vec<Expression>,
11847    #[serde(default)]
11848    pub subpartition: bool,
11849}
11850
11851/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
11852/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
11853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11854#[cfg_attr(feature = "bindings", derive(TS))]
11855pub struct RefreshTriggerProperty {
11856    /// Method: COMPLETE or AUTO
11857    pub method: String,
11858    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
11859    #[serde(default)]
11860    pub kind: Option<String>,
11861    /// For SCHEDULE: EVERY n (the number)
11862    #[serde(default)]
11863    pub every: Option<Box<Expression>>,
11864    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
11865    #[serde(default)]
11866    pub unit: Option<String>,
11867    /// For SCHEDULE: STARTS 'datetime'
11868    #[serde(default)]
11869    pub starts: Option<Box<Expression>>,
11870}
11871
11872/// UniqueKeyProperty
11873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11874#[cfg_attr(feature = "bindings", derive(TS))]
11875pub struct UniqueKeyProperty {
11876    #[serde(default)]
11877    pub expressions: Vec<Expression>,
11878}
11879
11880/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
11881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11882#[cfg_attr(feature = "bindings", derive(TS))]
11883pub struct RollupProperty {
11884    pub expressions: Vec<RollupIndex>,
11885}
11886
11887/// RollupIndex - A single rollup index: name(col1, col2)
11888#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11889#[cfg_attr(feature = "bindings", derive(TS))]
11890pub struct RollupIndex {
11891    pub name: Identifier,
11892    pub expressions: Vec<Identifier>,
11893}
11894
11895/// PartitionBoundSpec
11896#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11897#[cfg_attr(feature = "bindings", derive(TS))]
11898pub struct PartitionBoundSpec {
11899    #[serde(default)]
11900    pub this: Option<Box<Expression>>,
11901    #[serde(default)]
11902    pub expression: Option<Box<Expression>>,
11903    #[serde(default)]
11904    pub from_expressions: Option<Box<Expression>>,
11905    #[serde(default)]
11906    pub to_expressions: Option<Box<Expression>>,
11907}
11908
11909/// PartitionedOfProperty
11910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11911#[cfg_attr(feature = "bindings", derive(TS))]
11912pub struct PartitionedOfProperty {
11913    pub this: Box<Expression>,
11914    pub expression: Box<Expression>,
11915}
11916
11917/// RemoteWithConnectionModelProperty
11918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11919#[cfg_attr(feature = "bindings", derive(TS))]
11920pub struct RemoteWithConnectionModelProperty {
11921    pub this: Box<Expression>,
11922}
11923
11924/// ReturnsProperty
11925#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11926#[cfg_attr(feature = "bindings", derive(TS))]
11927pub struct ReturnsProperty {
11928    #[serde(default)]
11929    pub this: Option<Box<Expression>>,
11930    #[serde(default)]
11931    pub is_table: Option<Box<Expression>>,
11932    #[serde(default)]
11933    pub table: Option<Box<Expression>>,
11934    #[serde(default)]
11935    pub null: Option<Box<Expression>>,
11936}
11937
11938/// RowFormatProperty
11939#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11940#[cfg_attr(feature = "bindings", derive(TS))]
11941pub struct RowFormatProperty {
11942    pub this: Box<Expression>,
11943}
11944
11945/// RowFormatDelimitedProperty
11946#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11947#[cfg_attr(feature = "bindings", derive(TS))]
11948pub struct RowFormatDelimitedProperty {
11949    #[serde(default)]
11950    pub fields: Option<Box<Expression>>,
11951    #[serde(default)]
11952    pub escaped: Option<Box<Expression>>,
11953    #[serde(default)]
11954    pub collection_items: Option<Box<Expression>>,
11955    #[serde(default)]
11956    pub map_keys: Option<Box<Expression>>,
11957    #[serde(default)]
11958    pub lines: Option<Box<Expression>>,
11959    #[serde(default)]
11960    pub null: Option<Box<Expression>>,
11961    #[serde(default)]
11962    pub serde: Option<Box<Expression>>,
11963}
11964
11965/// RowFormatSerdeProperty
11966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11967#[cfg_attr(feature = "bindings", derive(TS))]
11968pub struct RowFormatSerdeProperty {
11969    pub this: Box<Expression>,
11970    #[serde(default)]
11971    pub serde_properties: Option<Box<Expression>>,
11972}
11973
11974/// QueryTransform
11975#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11976#[cfg_attr(feature = "bindings", derive(TS))]
11977pub struct QueryTransform {
11978    #[serde(default)]
11979    pub expressions: Vec<Expression>,
11980    #[serde(default)]
11981    pub command_script: Option<Box<Expression>>,
11982    #[serde(default)]
11983    pub schema: Option<Box<Expression>>,
11984    #[serde(default)]
11985    pub row_format_before: Option<Box<Expression>>,
11986    #[serde(default)]
11987    pub record_writer: Option<Box<Expression>>,
11988    #[serde(default)]
11989    pub row_format_after: Option<Box<Expression>>,
11990    #[serde(default)]
11991    pub record_reader: Option<Box<Expression>>,
11992}
11993
11994/// SampleProperty
11995#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11996#[cfg_attr(feature = "bindings", derive(TS))]
11997pub struct SampleProperty {
11998    pub this: Box<Expression>,
11999}
12000
12001/// SecurityProperty
12002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12003#[cfg_attr(feature = "bindings", derive(TS))]
12004pub struct SecurityProperty {
12005    pub this: Box<Expression>,
12006}
12007
12008/// SchemaCommentProperty
12009#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12010#[cfg_attr(feature = "bindings", derive(TS))]
12011pub struct SchemaCommentProperty {
12012    pub this: Box<Expression>,
12013}
12014
12015/// SemanticView
12016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12017#[cfg_attr(feature = "bindings", derive(TS))]
12018pub struct SemanticView {
12019    pub this: Box<Expression>,
12020    #[serde(default)]
12021    pub metrics: Option<Box<Expression>>,
12022    #[serde(default)]
12023    pub dimensions: Option<Box<Expression>>,
12024    #[serde(default)]
12025    pub facts: Option<Box<Expression>>,
12026    #[serde(default)]
12027    pub where_: Option<Box<Expression>>,
12028}
12029
12030/// SerdeProperties
12031#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12032#[cfg_attr(feature = "bindings", derive(TS))]
12033pub struct SerdeProperties {
12034    #[serde(default)]
12035    pub expressions: Vec<Expression>,
12036    #[serde(default)]
12037    pub with_: Option<Box<Expression>>,
12038}
12039
12040/// SetProperty
12041#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12042#[cfg_attr(feature = "bindings", derive(TS))]
12043pub struct SetProperty {
12044    #[serde(default)]
12045    pub multi: Option<Box<Expression>>,
12046}
12047
12048/// SharingProperty
12049#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12050#[cfg_attr(feature = "bindings", derive(TS))]
12051pub struct SharingProperty {
12052    #[serde(default)]
12053    pub this: Option<Box<Expression>>,
12054}
12055
12056/// SetConfigProperty
12057#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12058#[cfg_attr(feature = "bindings", derive(TS))]
12059pub struct SetConfigProperty {
12060    pub this: Box<Expression>,
12061}
12062
12063/// SettingsProperty
12064#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12065#[cfg_attr(feature = "bindings", derive(TS))]
12066pub struct SettingsProperty {
12067    #[serde(default)]
12068    pub expressions: Vec<Expression>,
12069}
12070
12071/// SortKeyProperty
12072#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12073#[cfg_attr(feature = "bindings", derive(TS))]
12074pub struct SortKeyProperty {
12075    pub this: Box<Expression>,
12076    #[serde(default)]
12077    pub compound: Option<Box<Expression>>,
12078}
12079
12080/// SqlReadWriteProperty
12081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12082#[cfg_attr(feature = "bindings", derive(TS))]
12083pub struct SqlReadWriteProperty {
12084    pub this: Box<Expression>,
12085}
12086
12087/// SqlSecurityProperty
12088#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12089#[cfg_attr(feature = "bindings", derive(TS))]
12090pub struct SqlSecurityProperty {
12091    pub this: Box<Expression>,
12092}
12093
12094/// StabilityProperty
12095#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12096#[cfg_attr(feature = "bindings", derive(TS))]
12097pub struct StabilityProperty {
12098    pub this: Box<Expression>,
12099}
12100
12101/// StorageHandlerProperty
12102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12103#[cfg_attr(feature = "bindings", derive(TS))]
12104pub struct StorageHandlerProperty {
12105    pub this: Box<Expression>,
12106}
12107
12108/// TemporaryProperty
12109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12110#[cfg_attr(feature = "bindings", derive(TS))]
12111pub struct TemporaryProperty {
12112    #[serde(default)]
12113    pub this: Option<Box<Expression>>,
12114}
12115
12116/// Tags
12117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12118#[cfg_attr(feature = "bindings", derive(TS))]
12119pub struct Tags {
12120    #[serde(default)]
12121    pub expressions: Vec<Expression>,
12122}
12123
12124/// TransformModelProperty
12125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12126#[cfg_attr(feature = "bindings", derive(TS))]
12127pub struct TransformModelProperty {
12128    #[serde(default)]
12129    pub expressions: Vec<Expression>,
12130}
12131
12132/// TransientProperty
12133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12134#[cfg_attr(feature = "bindings", derive(TS))]
12135pub struct TransientProperty {
12136    #[serde(default)]
12137    pub this: Option<Box<Expression>>,
12138}
12139
12140/// UsingTemplateProperty
12141#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12142#[cfg_attr(feature = "bindings", derive(TS))]
12143pub struct UsingTemplateProperty {
12144    pub this: Box<Expression>,
12145}
12146
12147/// ViewAttributeProperty
12148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12149#[cfg_attr(feature = "bindings", derive(TS))]
12150pub struct ViewAttributeProperty {
12151    pub this: Box<Expression>,
12152}
12153
12154/// VolatileProperty
12155#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12156#[cfg_attr(feature = "bindings", derive(TS))]
12157pub struct VolatileProperty {
12158    #[serde(default)]
12159    pub this: Option<Box<Expression>>,
12160}
12161
12162/// WithDataProperty
12163#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12164#[cfg_attr(feature = "bindings", derive(TS))]
12165pub struct WithDataProperty {
12166    #[serde(default)]
12167    pub no: Option<Box<Expression>>,
12168    #[serde(default)]
12169    pub statistics: Option<Box<Expression>>,
12170}
12171
12172/// WithJournalTableProperty
12173#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12174#[cfg_attr(feature = "bindings", derive(TS))]
12175pub struct WithJournalTableProperty {
12176    pub this: Box<Expression>,
12177}
12178
12179/// WithSchemaBindingProperty
12180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12181#[cfg_attr(feature = "bindings", derive(TS))]
12182pub struct WithSchemaBindingProperty {
12183    pub this: Box<Expression>,
12184}
12185
12186/// WithSystemVersioningProperty
12187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12188#[cfg_attr(feature = "bindings", derive(TS))]
12189pub struct WithSystemVersioningProperty {
12190    #[serde(default)]
12191    pub on: Option<Box<Expression>>,
12192    #[serde(default)]
12193    pub this: Option<Box<Expression>>,
12194    #[serde(default)]
12195    pub data_consistency: Option<Box<Expression>>,
12196    #[serde(default)]
12197    pub retention_period: Option<Box<Expression>>,
12198    #[serde(default)]
12199    pub with_: Option<Box<Expression>>,
12200}
12201
12202/// WithProcedureOptions
12203#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12204#[cfg_attr(feature = "bindings", derive(TS))]
12205pub struct WithProcedureOptions {
12206    #[serde(default)]
12207    pub expressions: Vec<Expression>,
12208}
12209
12210/// EncodeProperty
12211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12212#[cfg_attr(feature = "bindings", derive(TS))]
12213pub struct EncodeProperty {
12214    pub this: Box<Expression>,
12215    #[serde(default)]
12216    pub properties: Vec<Expression>,
12217    #[serde(default)]
12218    pub key: Option<Box<Expression>>,
12219}
12220
12221/// IncludeProperty
12222#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12223#[cfg_attr(feature = "bindings", derive(TS))]
12224pub struct IncludeProperty {
12225    pub this: Box<Expression>,
12226    #[serde(default)]
12227    pub alias: Option<String>,
12228    #[serde(default)]
12229    pub column_def: Option<Box<Expression>>,
12230}
12231
12232/// Properties
12233#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12234#[cfg_attr(feature = "bindings", derive(TS))]
12235pub struct Properties {
12236    #[serde(default)]
12237    pub expressions: Vec<Expression>,
12238}
12239
12240/// Key/value pair in a BigQuery OPTIONS (...) clause.
12241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12242#[cfg_attr(feature = "bindings", derive(TS))]
12243pub struct OptionEntry {
12244    pub key: Identifier,
12245    pub value: Expression,
12246}
12247
12248/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12249#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12250#[cfg_attr(feature = "bindings", derive(TS))]
12251pub struct OptionsProperty {
12252    #[serde(default)]
12253    pub entries: Vec<OptionEntry>,
12254}
12255
12256/// InputOutputFormat
12257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12258#[cfg_attr(feature = "bindings", derive(TS))]
12259pub struct InputOutputFormat {
12260    #[serde(default)]
12261    pub input_format: Option<Box<Expression>>,
12262    #[serde(default)]
12263    pub output_format: Option<Box<Expression>>,
12264}
12265
12266/// Reference
12267#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12268#[cfg_attr(feature = "bindings", derive(TS))]
12269pub struct Reference {
12270    pub this: Box<Expression>,
12271    #[serde(default)]
12272    pub expressions: Vec<Expression>,
12273    #[serde(default)]
12274    pub options: Vec<Expression>,
12275}
12276
12277/// QueryOption
12278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12279#[cfg_attr(feature = "bindings", derive(TS))]
12280pub struct QueryOption {
12281    pub this: Box<Expression>,
12282    #[serde(default)]
12283    pub expression: Option<Box<Expression>>,
12284}
12285
12286/// WithTableHint
12287#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12288#[cfg_attr(feature = "bindings", derive(TS))]
12289pub struct WithTableHint {
12290    #[serde(default)]
12291    pub expressions: Vec<Expression>,
12292}
12293
12294/// IndexTableHint
12295#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12296#[cfg_attr(feature = "bindings", derive(TS))]
12297pub struct IndexTableHint {
12298    pub this: Box<Expression>,
12299    #[serde(default)]
12300    pub expressions: Vec<Expression>,
12301    #[serde(default)]
12302    pub target: Option<Box<Expression>>,
12303}
12304
12305/// Get
12306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12307#[cfg_attr(feature = "bindings", derive(TS))]
12308pub struct Get {
12309    pub this: Box<Expression>,
12310    #[serde(default)]
12311    pub target: Option<Box<Expression>>,
12312    #[serde(default)]
12313    pub properties: Vec<Expression>,
12314}
12315
12316/// SetOperation
12317#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12318#[cfg_attr(feature = "bindings", derive(TS))]
12319pub struct SetOperation {
12320    #[serde(default)]
12321    pub with_: Option<Box<Expression>>,
12322    pub this: Box<Expression>,
12323    pub expression: Box<Expression>,
12324    #[serde(default)]
12325    pub distinct: bool,
12326    #[serde(default)]
12327    pub by_name: Option<Box<Expression>>,
12328    #[serde(default)]
12329    pub side: Option<Box<Expression>>,
12330    #[serde(default)]
12331    pub kind: Option<String>,
12332    #[serde(default)]
12333    pub on: Option<Box<Expression>>,
12334}
12335
12336/// Var - Simple variable reference (for SQL variables, keywords as values)
12337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12338#[cfg_attr(feature = "bindings", derive(TS))]
12339pub struct Var {
12340    pub this: String,
12341}
12342
12343/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12345#[cfg_attr(feature = "bindings", derive(TS))]
12346pub struct Variadic {
12347    pub this: Box<Expression>,
12348}
12349
12350/// Version
12351#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12352#[cfg_attr(feature = "bindings", derive(TS))]
12353pub struct Version {
12354    pub this: Box<Expression>,
12355    pub kind: String,
12356    #[serde(default)]
12357    pub expression: Option<Box<Expression>>,
12358}
12359
12360/// Schema
12361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12362#[cfg_attr(feature = "bindings", derive(TS))]
12363pub struct Schema {
12364    #[serde(default)]
12365    pub this: Option<Box<Expression>>,
12366    #[serde(default)]
12367    pub expressions: Vec<Expression>,
12368}
12369
12370/// Lock
12371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12372#[cfg_attr(feature = "bindings", derive(TS))]
12373pub struct Lock {
12374    #[serde(default)]
12375    pub update: Option<Box<Expression>>,
12376    #[serde(default)]
12377    pub expressions: Vec<Expression>,
12378    #[serde(default)]
12379    pub wait: Option<Box<Expression>>,
12380    #[serde(default)]
12381    pub key: Option<Box<Expression>>,
12382}
12383
12384/// TableSample - wraps an expression with a TABLESAMPLE clause
12385/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12386#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12387#[cfg_attr(feature = "bindings", derive(TS))]
12388pub struct TableSample {
12389    /// The expression being sampled (subquery, function, etc.)
12390    #[serde(default, skip_serializing_if = "Option::is_none")]
12391    pub this: Option<Box<Expression>>,
12392    /// The sample specification
12393    #[serde(default, skip_serializing_if = "Option::is_none")]
12394    pub sample: Option<Box<Sample>>,
12395    #[serde(default)]
12396    pub expressions: Vec<Expression>,
12397    #[serde(default)]
12398    pub method: Option<String>,
12399    #[serde(default)]
12400    pub bucket_numerator: Option<Box<Expression>>,
12401    #[serde(default)]
12402    pub bucket_denominator: Option<Box<Expression>>,
12403    #[serde(default)]
12404    pub bucket_field: Option<Box<Expression>>,
12405    #[serde(default)]
12406    pub percent: Option<Box<Expression>>,
12407    #[serde(default)]
12408    pub rows: Option<Box<Expression>>,
12409    #[serde(default)]
12410    pub size: Option<i64>,
12411    #[serde(default)]
12412    pub seed: Option<Box<Expression>>,
12413}
12414
12415/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12416#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12417#[cfg_attr(feature = "bindings", derive(TS))]
12418pub struct Tag {
12419    #[serde(default)]
12420    pub this: Option<Box<Expression>>,
12421    #[serde(default)]
12422    pub prefix: Option<Box<Expression>>,
12423    #[serde(default)]
12424    pub postfix: Option<Box<Expression>>,
12425}
12426
12427/// UnpivotColumns
12428#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12429#[cfg_attr(feature = "bindings", derive(TS))]
12430pub struct UnpivotColumns {
12431    pub this: Box<Expression>,
12432    #[serde(default)]
12433    pub expressions: Vec<Expression>,
12434}
12435
12436/// SessionParameter
12437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12438#[cfg_attr(feature = "bindings", derive(TS))]
12439pub struct SessionParameter {
12440    pub this: Box<Expression>,
12441    #[serde(default)]
12442    pub kind: Option<String>,
12443}
12444
12445/// PseudoType
12446#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12447#[cfg_attr(feature = "bindings", derive(TS))]
12448pub struct PseudoType {
12449    pub this: Box<Expression>,
12450}
12451
12452/// ObjectIdentifier
12453#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12454#[cfg_attr(feature = "bindings", derive(TS))]
12455pub struct ObjectIdentifier {
12456    pub this: Box<Expression>,
12457}
12458
12459/// Transaction
12460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12461#[cfg_attr(feature = "bindings", derive(TS))]
12462pub struct Transaction {
12463    #[serde(default)]
12464    pub this: Option<Box<Expression>>,
12465    #[serde(default)]
12466    pub modes: Option<Box<Expression>>,
12467    #[serde(default)]
12468    pub mark: Option<Box<Expression>>,
12469}
12470
12471/// Commit
12472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12473#[cfg_attr(feature = "bindings", derive(TS))]
12474pub struct Commit {
12475    #[serde(default)]
12476    pub chain: Option<Box<Expression>>,
12477    #[serde(default)]
12478    pub this: Option<Box<Expression>>,
12479    #[serde(default)]
12480    pub durability: Option<Box<Expression>>,
12481}
12482
12483/// Rollback
12484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12485#[cfg_attr(feature = "bindings", derive(TS))]
12486pub struct Rollback {
12487    #[serde(default)]
12488    pub savepoint: Option<Box<Expression>>,
12489    #[serde(default)]
12490    pub this: Option<Box<Expression>>,
12491}
12492
12493/// AlterSession
12494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12495#[cfg_attr(feature = "bindings", derive(TS))]
12496pub struct AlterSession {
12497    #[serde(default)]
12498    pub expressions: Vec<Expression>,
12499    #[serde(default)]
12500    pub unset: Option<Box<Expression>>,
12501}
12502
12503/// Analyze
12504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12505#[cfg_attr(feature = "bindings", derive(TS))]
12506pub struct Analyze {
12507    #[serde(default)]
12508    pub kind: Option<String>,
12509    #[serde(default)]
12510    pub this: Option<Box<Expression>>,
12511    #[serde(default)]
12512    pub options: Vec<Expression>,
12513    #[serde(default)]
12514    pub mode: Option<Box<Expression>>,
12515    #[serde(default)]
12516    pub partition: Option<Box<Expression>>,
12517    #[serde(default)]
12518    pub expression: Option<Box<Expression>>,
12519    #[serde(default)]
12520    pub properties: Vec<Expression>,
12521    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12522    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12523    pub columns: Vec<String>,
12524}
12525
12526/// AnalyzeStatistics
12527#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12528#[cfg_attr(feature = "bindings", derive(TS))]
12529pub struct AnalyzeStatistics {
12530    pub kind: String,
12531    #[serde(default)]
12532    pub option: Option<Box<Expression>>,
12533    #[serde(default)]
12534    pub this: Option<Box<Expression>>,
12535    #[serde(default)]
12536    pub expressions: Vec<Expression>,
12537}
12538
12539/// AnalyzeHistogram
12540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12541#[cfg_attr(feature = "bindings", derive(TS))]
12542pub struct AnalyzeHistogram {
12543    pub this: Box<Expression>,
12544    #[serde(default)]
12545    pub expressions: Vec<Expression>,
12546    #[serde(default)]
12547    pub expression: Option<Box<Expression>>,
12548    #[serde(default)]
12549    pub update_options: Option<Box<Expression>>,
12550}
12551
12552/// AnalyzeSample
12553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12554#[cfg_attr(feature = "bindings", derive(TS))]
12555pub struct AnalyzeSample {
12556    pub kind: String,
12557    #[serde(default)]
12558    pub sample: Option<Box<Expression>>,
12559}
12560
12561/// AnalyzeListChainedRows
12562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12563#[cfg_attr(feature = "bindings", derive(TS))]
12564pub struct AnalyzeListChainedRows {
12565    #[serde(default)]
12566    pub expression: Option<Box<Expression>>,
12567}
12568
12569/// AnalyzeDelete
12570#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12571#[cfg_attr(feature = "bindings", derive(TS))]
12572pub struct AnalyzeDelete {
12573    #[serde(default)]
12574    pub kind: Option<String>,
12575}
12576
12577/// AnalyzeWith
12578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12579#[cfg_attr(feature = "bindings", derive(TS))]
12580pub struct AnalyzeWith {
12581    #[serde(default)]
12582    pub expressions: Vec<Expression>,
12583}
12584
12585/// AnalyzeValidate
12586#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12587#[cfg_attr(feature = "bindings", derive(TS))]
12588pub struct AnalyzeValidate {
12589    pub kind: String,
12590    #[serde(default)]
12591    pub this: Option<Box<Expression>>,
12592    #[serde(default)]
12593    pub expression: Option<Box<Expression>>,
12594}
12595
12596/// AddPartition
12597#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12598#[cfg_attr(feature = "bindings", derive(TS))]
12599pub struct AddPartition {
12600    pub this: Box<Expression>,
12601    #[serde(default)]
12602    pub exists: bool,
12603    #[serde(default)]
12604    pub location: Option<Box<Expression>>,
12605}
12606
12607/// AttachOption
12608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12609#[cfg_attr(feature = "bindings", derive(TS))]
12610pub struct AttachOption {
12611    pub this: Box<Expression>,
12612    #[serde(default)]
12613    pub expression: Option<Box<Expression>>,
12614}
12615
12616/// DropPartition
12617#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12618#[cfg_attr(feature = "bindings", derive(TS))]
12619pub struct DropPartition {
12620    #[serde(default)]
12621    pub expressions: Vec<Expression>,
12622    #[serde(default)]
12623    pub exists: bool,
12624}
12625
12626/// ReplacePartition
12627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12628#[cfg_attr(feature = "bindings", derive(TS))]
12629pub struct ReplacePartition {
12630    pub expression: Box<Expression>,
12631    #[serde(default)]
12632    pub source: Option<Box<Expression>>,
12633}
12634
12635/// DPipe
12636#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12637#[cfg_attr(feature = "bindings", derive(TS))]
12638pub struct DPipe {
12639    pub this: Box<Expression>,
12640    pub expression: Box<Expression>,
12641    #[serde(default)]
12642    pub safe: Option<Box<Expression>>,
12643}
12644
12645/// Operator
12646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12647#[cfg_attr(feature = "bindings", derive(TS))]
12648pub struct Operator {
12649    pub this: Box<Expression>,
12650    #[serde(default)]
12651    pub operator: Option<Box<Expression>>,
12652    pub expression: Box<Expression>,
12653    /// Comments between OPERATOR() and the RHS expression
12654    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12655    pub comments: Vec<String>,
12656}
12657
12658/// PivotAny
12659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12660#[cfg_attr(feature = "bindings", derive(TS))]
12661pub struct PivotAny {
12662    #[serde(default)]
12663    pub this: Option<Box<Expression>>,
12664}
12665
12666/// Aliases
12667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12668#[cfg_attr(feature = "bindings", derive(TS))]
12669pub struct Aliases {
12670    pub this: Box<Expression>,
12671    #[serde(default)]
12672    pub expressions: Vec<Expression>,
12673}
12674
12675/// AtIndex
12676#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12677#[cfg_attr(feature = "bindings", derive(TS))]
12678pub struct AtIndex {
12679    pub this: Box<Expression>,
12680    pub expression: Box<Expression>,
12681}
12682
12683/// FromTimeZone
12684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12685#[cfg_attr(feature = "bindings", derive(TS))]
12686pub struct FromTimeZone {
12687    pub this: Box<Expression>,
12688    #[serde(default)]
12689    pub zone: Option<Box<Expression>>,
12690}
12691
12692/// Format override for a column in Teradata
12693#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12694#[cfg_attr(feature = "bindings", derive(TS))]
12695pub struct FormatPhrase {
12696    pub this: Box<Expression>,
12697    pub format: String,
12698}
12699
12700/// ForIn
12701#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12702#[cfg_attr(feature = "bindings", derive(TS))]
12703pub struct ForIn {
12704    pub this: Box<Expression>,
12705    pub expression: Box<Expression>,
12706}
12707
12708/// Automatically converts unit arg into a var.
12709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12710#[cfg_attr(feature = "bindings", derive(TS))]
12711pub struct TimeUnit {
12712    #[serde(default)]
12713    pub unit: Option<String>,
12714}
12715
12716/// IntervalOp
12717#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12718#[cfg_attr(feature = "bindings", derive(TS))]
12719pub struct IntervalOp {
12720    #[serde(default)]
12721    pub unit: Option<String>,
12722    pub expression: Box<Expression>,
12723}
12724
12725/// HavingMax
12726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12727#[cfg_attr(feature = "bindings", derive(TS))]
12728pub struct HavingMax {
12729    pub this: Box<Expression>,
12730    pub expression: Box<Expression>,
12731    #[serde(default)]
12732    pub max: Option<Box<Expression>>,
12733}
12734
12735/// CosineDistance
12736#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12737#[cfg_attr(feature = "bindings", derive(TS))]
12738pub struct CosineDistance {
12739    pub this: Box<Expression>,
12740    pub expression: Box<Expression>,
12741}
12742
12743/// DotProduct
12744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12745#[cfg_attr(feature = "bindings", derive(TS))]
12746pub struct DotProduct {
12747    pub this: Box<Expression>,
12748    pub expression: Box<Expression>,
12749}
12750
12751/// EuclideanDistance
12752#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12753#[cfg_attr(feature = "bindings", derive(TS))]
12754pub struct EuclideanDistance {
12755    pub this: Box<Expression>,
12756    pub expression: Box<Expression>,
12757}
12758
12759/// ManhattanDistance
12760#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12761#[cfg_attr(feature = "bindings", derive(TS))]
12762pub struct ManhattanDistance {
12763    pub this: Box<Expression>,
12764    pub expression: Box<Expression>,
12765}
12766
12767/// JarowinklerSimilarity
12768#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12769#[cfg_attr(feature = "bindings", derive(TS))]
12770pub struct JarowinklerSimilarity {
12771    pub this: Box<Expression>,
12772    pub expression: Box<Expression>,
12773}
12774
12775/// Booland
12776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12777#[cfg_attr(feature = "bindings", derive(TS))]
12778pub struct Booland {
12779    pub this: Box<Expression>,
12780    pub expression: Box<Expression>,
12781}
12782
12783/// Boolor
12784#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12785#[cfg_attr(feature = "bindings", derive(TS))]
12786pub struct Boolor {
12787    pub this: Box<Expression>,
12788    pub expression: Box<Expression>,
12789}
12790
12791/// ParameterizedAgg
12792#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12793#[cfg_attr(feature = "bindings", derive(TS))]
12794pub struct ParameterizedAgg {
12795    pub this: Box<Expression>,
12796    #[serde(default)]
12797    pub expressions: Vec<Expression>,
12798    #[serde(default)]
12799    pub params: Vec<Expression>,
12800}
12801
12802/// ArgMax
12803#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12804#[cfg_attr(feature = "bindings", derive(TS))]
12805pub struct ArgMax {
12806    pub this: Box<Expression>,
12807    pub expression: Box<Expression>,
12808    #[serde(default)]
12809    pub count: Option<Box<Expression>>,
12810}
12811
12812/// ArgMin
12813#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12814#[cfg_attr(feature = "bindings", derive(TS))]
12815pub struct ArgMin {
12816    pub this: Box<Expression>,
12817    pub expression: Box<Expression>,
12818    #[serde(default)]
12819    pub count: Option<Box<Expression>>,
12820}
12821
12822/// ApproxTopK
12823#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12824#[cfg_attr(feature = "bindings", derive(TS))]
12825pub struct ApproxTopK {
12826    pub this: Box<Expression>,
12827    #[serde(default)]
12828    pub expression: Option<Box<Expression>>,
12829    #[serde(default)]
12830    pub counters: Option<Box<Expression>>,
12831}
12832
12833/// ApproxTopKAccumulate
12834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12835#[cfg_attr(feature = "bindings", derive(TS))]
12836pub struct ApproxTopKAccumulate {
12837    pub this: Box<Expression>,
12838    #[serde(default)]
12839    pub expression: Option<Box<Expression>>,
12840}
12841
12842/// ApproxTopKCombine
12843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12844#[cfg_attr(feature = "bindings", derive(TS))]
12845pub struct ApproxTopKCombine {
12846    pub this: Box<Expression>,
12847    #[serde(default)]
12848    pub expression: Option<Box<Expression>>,
12849}
12850
12851/// ApproxTopKEstimate
12852#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12853#[cfg_attr(feature = "bindings", derive(TS))]
12854pub struct ApproxTopKEstimate {
12855    pub this: Box<Expression>,
12856    #[serde(default)]
12857    pub expression: Option<Box<Expression>>,
12858}
12859
12860/// ApproxTopSum
12861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12862#[cfg_attr(feature = "bindings", derive(TS))]
12863pub struct ApproxTopSum {
12864    pub this: Box<Expression>,
12865    pub expression: Box<Expression>,
12866    #[serde(default)]
12867    pub count: Option<Box<Expression>>,
12868}
12869
12870/// ApproxQuantiles
12871#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12872#[cfg_attr(feature = "bindings", derive(TS))]
12873pub struct ApproxQuantiles {
12874    pub this: Box<Expression>,
12875    #[serde(default)]
12876    pub expression: Option<Box<Expression>>,
12877}
12878
12879/// Minhash
12880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12881#[cfg_attr(feature = "bindings", derive(TS))]
12882pub struct Minhash {
12883    pub this: Box<Expression>,
12884    #[serde(default)]
12885    pub expressions: Vec<Expression>,
12886}
12887
12888/// FarmFingerprint
12889#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12890#[cfg_attr(feature = "bindings", derive(TS))]
12891pub struct FarmFingerprint {
12892    #[serde(default)]
12893    pub expressions: Vec<Expression>,
12894}
12895
12896/// Float64
12897#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12898#[cfg_attr(feature = "bindings", derive(TS))]
12899pub struct Float64 {
12900    pub this: Box<Expression>,
12901    #[serde(default)]
12902    pub expression: Option<Box<Expression>>,
12903}
12904
12905/// Transform
12906#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12907#[cfg_attr(feature = "bindings", derive(TS))]
12908pub struct Transform {
12909    pub this: Box<Expression>,
12910    pub expression: Box<Expression>,
12911}
12912
12913/// Translate
12914#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12915#[cfg_attr(feature = "bindings", derive(TS))]
12916pub struct Translate {
12917    pub this: Box<Expression>,
12918    #[serde(default)]
12919    pub from_: Option<Box<Expression>>,
12920    #[serde(default)]
12921    pub to: Option<Box<Expression>>,
12922}
12923
12924/// Grouping
12925#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12926#[cfg_attr(feature = "bindings", derive(TS))]
12927pub struct Grouping {
12928    #[serde(default)]
12929    pub expressions: Vec<Expression>,
12930}
12931
12932/// GroupingId
12933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12934#[cfg_attr(feature = "bindings", derive(TS))]
12935pub struct GroupingId {
12936    #[serde(default)]
12937    pub expressions: Vec<Expression>,
12938}
12939
12940/// Anonymous
12941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12942#[cfg_attr(feature = "bindings", derive(TS))]
12943pub struct Anonymous {
12944    pub this: Box<Expression>,
12945    #[serde(default)]
12946    pub expressions: Vec<Expression>,
12947}
12948
12949/// AnonymousAggFunc
12950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12951#[cfg_attr(feature = "bindings", derive(TS))]
12952pub struct AnonymousAggFunc {
12953    pub this: Box<Expression>,
12954    #[serde(default)]
12955    pub expressions: Vec<Expression>,
12956}
12957
12958/// CombinedAggFunc
12959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12960#[cfg_attr(feature = "bindings", derive(TS))]
12961pub struct CombinedAggFunc {
12962    pub this: Box<Expression>,
12963    #[serde(default)]
12964    pub expressions: Vec<Expression>,
12965}
12966
12967/// CombinedParameterizedAgg
12968#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12969#[cfg_attr(feature = "bindings", derive(TS))]
12970pub struct CombinedParameterizedAgg {
12971    pub this: Box<Expression>,
12972    #[serde(default)]
12973    pub expressions: Vec<Expression>,
12974    #[serde(default)]
12975    pub params: Vec<Expression>,
12976}
12977
12978/// HashAgg
12979#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12980#[cfg_attr(feature = "bindings", derive(TS))]
12981pub struct HashAgg {
12982    pub this: Box<Expression>,
12983    #[serde(default)]
12984    pub expressions: Vec<Expression>,
12985}
12986
12987/// Hll
12988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12989#[cfg_attr(feature = "bindings", derive(TS))]
12990pub struct Hll {
12991    pub this: Box<Expression>,
12992    #[serde(default)]
12993    pub expressions: Vec<Expression>,
12994}
12995
12996/// Apply
12997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12998#[cfg_attr(feature = "bindings", derive(TS))]
12999pub struct Apply {
13000    pub this: Box<Expression>,
13001    pub expression: Box<Expression>,
13002}
13003
13004/// ToBoolean
13005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13006#[cfg_attr(feature = "bindings", derive(TS))]
13007pub struct ToBoolean {
13008    pub this: Box<Expression>,
13009    #[serde(default)]
13010    pub safe: Option<Box<Expression>>,
13011}
13012
13013/// List
13014#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13015#[cfg_attr(feature = "bindings", derive(TS))]
13016pub struct List {
13017    #[serde(default)]
13018    pub expressions: Vec<Expression>,
13019}
13020
13021/// ToMap - Materialize-style map constructor
13022/// Can hold either:
13023/// - A SELECT subquery (MAP(SELECT 'a', 1))
13024/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
13025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13026#[cfg_attr(feature = "bindings", derive(TS))]
13027pub struct ToMap {
13028    /// Either a Select subquery or a Struct containing PropertyEQ entries
13029    pub this: Box<Expression>,
13030}
13031
13032/// Pad
13033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13034#[cfg_attr(feature = "bindings", derive(TS))]
13035pub struct Pad {
13036    pub this: Box<Expression>,
13037    pub expression: Box<Expression>,
13038    #[serde(default)]
13039    pub fill_pattern: Option<Box<Expression>>,
13040    #[serde(default)]
13041    pub is_left: Option<Box<Expression>>,
13042}
13043
13044/// ToChar
13045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13046#[cfg_attr(feature = "bindings", derive(TS))]
13047pub struct ToChar {
13048    pub this: Box<Expression>,
13049    #[serde(default)]
13050    pub format: Option<String>,
13051    #[serde(default)]
13052    pub nlsparam: Option<Box<Expression>>,
13053    #[serde(default)]
13054    pub is_numeric: Option<Box<Expression>>,
13055}
13056
13057/// StringFunc - String type conversion function (BigQuery STRING)
13058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13059#[cfg_attr(feature = "bindings", derive(TS))]
13060pub struct StringFunc {
13061    pub this: Box<Expression>,
13062    #[serde(default)]
13063    pub zone: Option<Box<Expression>>,
13064}
13065
13066/// ToNumber
13067#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13068#[cfg_attr(feature = "bindings", derive(TS))]
13069pub struct ToNumber {
13070    pub this: Box<Expression>,
13071    #[serde(default)]
13072    pub format: Option<Box<Expression>>,
13073    #[serde(default)]
13074    pub nlsparam: Option<Box<Expression>>,
13075    #[serde(default)]
13076    pub precision: Option<Box<Expression>>,
13077    #[serde(default)]
13078    pub scale: Option<Box<Expression>>,
13079    #[serde(default)]
13080    pub safe: Option<Box<Expression>>,
13081    #[serde(default)]
13082    pub safe_name: Option<Box<Expression>>,
13083}
13084
13085/// ToDouble
13086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13087#[cfg_attr(feature = "bindings", derive(TS))]
13088pub struct ToDouble {
13089    pub this: Box<Expression>,
13090    #[serde(default)]
13091    pub format: Option<String>,
13092    #[serde(default)]
13093    pub safe: Option<Box<Expression>>,
13094}
13095
13096/// ToDecfloat
13097#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13098#[cfg_attr(feature = "bindings", derive(TS))]
13099pub struct ToDecfloat {
13100    pub this: Box<Expression>,
13101    #[serde(default)]
13102    pub format: Option<String>,
13103}
13104
13105/// TryToDecfloat
13106#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13107#[cfg_attr(feature = "bindings", derive(TS))]
13108pub struct TryToDecfloat {
13109    pub this: Box<Expression>,
13110    #[serde(default)]
13111    pub format: Option<String>,
13112}
13113
13114/// ToFile
13115#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13116#[cfg_attr(feature = "bindings", derive(TS))]
13117pub struct ToFile {
13118    pub this: Box<Expression>,
13119    #[serde(default)]
13120    pub path: Option<Box<Expression>>,
13121    #[serde(default)]
13122    pub safe: Option<Box<Expression>>,
13123}
13124
13125/// Columns
13126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13127#[cfg_attr(feature = "bindings", derive(TS))]
13128pub struct Columns {
13129    pub this: Box<Expression>,
13130    #[serde(default)]
13131    pub unpack: Option<Box<Expression>>,
13132}
13133
13134/// ConvertToCharset
13135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13136#[cfg_attr(feature = "bindings", derive(TS))]
13137pub struct ConvertToCharset {
13138    pub this: Box<Expression>,
13139    #[serde(default)]
13140    pub dest: Option<Box<Expression>>,
13141    #[serde(default)]
13142    pub source: Option<Box<Expression>>,
13143}
13144
13145/// ConvertTimezone
13146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13147#[cfg_attr(feature = "bindings", derive(TS))]
13148pub struct ConvertTimezone {
13149    #[serde(default)]
13150    pub source_tz: Option<Box<Expression>>,
13151    #[serde(default)]
13152    pub target_tz: Option<Box<Expression>>,
13153    #[serde(default)]
13154    pub timestamp: Option<Box<Expression>>,
13155    #[serde(default)]
13156    pub options: Vec<Expression>,
13157}
13158
13159/// GenerateSeries
13160#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13161#[cfg_attr(feature = "bindings", derive(TS))]
13162pub struct GenerateSeries {
13163    #[serde(default)]
13164    pub start: Option<Box<Expression>>,
13165    #[serde(default)]
13166    pub end: Option<Box<Expression>>,
13167    #[serde(default)]
13168    pub step: Option<Box<Expression>>,
13169    #[serde(default)]
13170    pub is_end_exclusive: Option<Box<Expression>>,
13171}
13172
13173/// AIAgg
13174#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13175#[cfg_attr(feature = "bindings", derive(TS))]
13176pub struct AIAgg {
13177    pub this: Box<Expression>,
13178    pub expression: Box<Expression>,
13179}
13180
13181/// AIClassify
13182#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13183#[cfg_attr(feature = "bindings", derive(TS))]
13184pub struct AIClassify {
13185    pub this: Box<Expression>,
13186    #[serde(default)]
13187    pub categories: Option<Box<Expression>>,
13188    #[serde(default)]
13189    pub config: Option<Box<Expression>>,
13190}
13191
13192/// ArrayAll
13193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13194#[cfg_attr(feature = "bindings", derive(TS))]
13195pub struct ArrayAll {
13196    pub this: Box<Expression>,
13197    pub expression: Box<Expression>,
13198}
13199
13200/// ArrayAny
13201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13202#[cfg_attr(feature = "bindings", derive(TS))]
13203pub struct ArrayAny {
13204    pub this: Box<Expression>,
13205    pub expression: Box<Expression>,
13206}
13207
13208/// ArrayConstructCompact
13209#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13210#[cfg_attr(feature = "bindings", derive(TS))]
13211pub struct ArrayConstructCompact {
13212    #[serde(default)]
13213    pub expressions: Vec<Expression>,
13214}
13215
13216/// StPoint
13217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13218#[cfg_attr(feature = "bindings", derive(TS))]
13219pub struct StPoint {
13220    pub this: Box<Expression>,
13221    pub expression: Box<Expression>,
13222    #[serde(default)]
13223    pub null: Option<Box<Expression>>,
13224}
13225
13226/// StDistance
13227#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13228#[cfg_attr(feature = "bindings", derive(TS))]
13229pub struct StDistance {
13230    pub this: Box<Expression>,
13231    pub expression: Box<Expression>,
13232    #[serde(default)]
13233    pub use_spheroid: Option<Box<Expression>>,
13234}
13235
13236/// StringToArray
13237#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13238#[cfg_attr(feature = "bindings", derive(TS))]
13239pub struct StringToArray {
13240    pub this: Box<Expression>,
13241    #[serde(default)]
13242    pub expression: Option<Box<Expression>>,
13243    #[serde(default)]
13244    pub null: Option<Box<Expression>>,
13245}
13246
13247/// ArraySum
13248#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13249#[cfg_attr(feature = "bindings", derive(TS))]
13250pub struct ArraySum {
13251    pub this: Box<Expression>,
13252    #[serde(default)]
13253    pub expression: Option<Box<Expression>>,
13254}
13255
13256/// ObjectAgg
13257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13258#[cfg_attr(feature = "bindings", derive(TS))]
13259pub struct ObjectAgg {
13260    pub this: Box<Expression>,
13261    pub expression: Box<Expression>,
13262}
13263
13264/// CastToStrType
13265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13266#[cfg_attr(feature = "bindings", derive(TS))]
13267pub struct CastToStrType {
13268    pub this: Box<Expression>,
13269    #[serde(default)]
13270    pub to: Option<Box<Expression>>,
13271}
13272
13273/// CheckJson
13274#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13275#[cfg_attr(feature = "bindings", derive(TS))]
13276pub struct CheckJson {
13277    pub this: Box<Expression>,
13278}
13279
13280/// CheckXml
13281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13282#[cfg_attr(feature = "bindings", derive(TS))]
13283pub struct CheckXml {
13284    pub this: Box<Expression>,
13285    #[serde(default)]
13286    pub disable_auto_convert: Option<Box<Expression>>,
13287}
13288
13289/// TranslateCharacters
13290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13291#[cfg_attr(feature = "bindings", derive(TS))]
13292pub struct TranslateCharacters {
13293    pub this: Box<Expression>,
13294    pub expression: Box<Expression>,
13295    #[serde(default)]
13296    pub with_error: Option<Box<Expression>>,
13297}
13298
13299/// CurrentSchemas
13300#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13301#[cfg_attr(feature = "bindings", derive(TS))]
13302pub struct CurrentSchemas {
13303    #[serde(default)]
13304    pub this: Option<Box<Expression>>,
13305}
13306
13307/// CurrentDatetime
13308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13309#[cfg_attr(feature = "bindings", derive(TS))]
13310pub struct CurrentDatetime {
13311    #[serde(default)]
13312    pub this: Option<Box<Expression>>,
13313}
13314
13315/// Localtime
13316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13317#[cfg_attr(feature = "bindings", derive(TS))]
13318pub struct Localtime {
13319    #[serde(default)]
13320    pub this: Option<Box<Expression>>,
13321}
13322
13323/// Localtimestamp
13324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13325#[cfg_attr(feature = "bindings", derive(TS))]
13326pub struct Localtimestamp {
13327    #[serde(default)]
13328    pub this: Option<Box<Expression>>,
13329}
13330
13331/// Systimestamp
13332#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13333#[cfg_attr(feature = "bindings", derive(TS))]
13334pub struct Systimestamp {
13335    #[serde(default)]
13336    pub this: Option<Box<Expression>>,
13337}
13338
13339/// CurrentSchema
13340#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13341#[cfg_attr(feature = "bindings", derive(TS))]
13342pub struct CurrentSchema {
13343    #[serde(default)]
13344    pub this: Option<Box<Expression>>,
13345}
13346
13347/// CurrentUser
13348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13349#[cfg_attr(feature = "bindings", derive(TS))]
13350pub struct CurrentUser {
13351    #[serde(default)]
13352    pub this: Option<Box<Expression>>,
13353}
13354
13355/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13356#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13357#[cfg_attr(feature = "bindings", derive(TS))]
13358pub struct SessionUser;
13359
13360/// JSONPathRoot - Represents $ in JSON path expressions
13361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13362#[cfg_attr(feature = "bindings", derive(TS))]
13363pub struct JSONPathRoot;
13364
13365/// UtcTime
13366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13367#[cfg_attr(feature = "bindings", derive(TS))]
13368pub struct UtcTime {
13369    #[serde(default)]
13370    pub this: Option<Box<Expression>>,
13371}
13372
13373/// UtcTimestamp
13374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13375#[cfg_attr(feature = "bindings", derive(TS))]
13376pub struct UtcTimestamp {
13377    #[serde(default)]
13378    pub this: Option<Box<Expression>>,
13379}
13380
13381/// TimestampFunc - TIMESTAMP constructor function
13382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13383#[cfg_attr(feature = "bindings", derive(TS))]
13384pub struct TimestampFunc {
13385    #[serde(default)]
13386    pub this: Option<Box<Expression>>,
13387    #[serde(default)]
13388    pub zone: Option<Box<Expression>>,
13389    #[serde(default)]
13390    pub with_tz: Option<bool>,
13391    #[serde(default)]
13392    pub safe: Option<bool>,
13393}
13394
13395/// DateBin
13396#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13397#[cfg_attr(feature = "bindings", derive(TS))]
13398pub struct DateBin {
13399    pub this: Box<Expression>,
13400    pub expression: Box<Expression>,
13401    #[serde(default)]
13402    pub unit: Option<String>,
13403    #[serde(default)]
13404    pub zone: Option<Box<Expression>>,
13405    #[serde(default)]
13406    pub origin: Option<Box<Expression>>,
13407}
13408
13409/// Datetime
13410#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13411#[cfg_attr(feature = "bindings", derive(TS))]
13412pub struct Datetime {
13413    pub this: Box<Expression>,
13414    #[serde(default)]
13415    pub expression: Option<Box<Expression>>,
13416}
13417
13418/// DatetimeAdd
13419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13420#[cfg_attr(feature = "bindings", derive(TS))]
13421pub struct DatetimeAdd {
13422    pub this: Box<Expression>,
13423    pub expression: Box<Expression>,
13424    #[serde(default)]
13425    pub unit: Option<String>,
13426}
13427
13428/// DatetimeSub
13429#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13430#[cfg_attr(feature = "bindings", derive(TS))]
13431pub struct DatetimeSub {
13432    pub this: Box<Expression>,
13433    pub expression: Box<Expression>,
13434    #[serde(default)]
13435    pub unit: Option<String>,
13436}
13437
13438/// DatetimeDiff
13439#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13440#[cfg_attr(feature = "bindings", derive(TS))]
13441pub struct DatetimeDiff {
13442    pub this: Box<Expression>,
13443    pub expression: Box<Expression>,
13444    #[serde(default)]
13445    pub unit: Option<String>,
13446}
13447
13448/// DatetimeTrunc
13449#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13450#[cfg_attr(feature = "bindings", derive(TS))]
13451pub struct DatetimeTrunc {
13452    pub this: Box<Expression>,
13453    pub unit: String,
13454    #[serde(default)]
13455    pub zone: Option<Box<Expression>>,
13456}
13457
13458/// Dayname
13459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13460#[cfg_attr(feature = "bindings", derive(TS))]
13461pub struct Dayname {
13462    pub this: Box<Expression>,
13463    #[serde(default)]
13464    pub abbreviated: Option<Box<Expression>>,
13465}
13466
13467/// MakeInterval
13468#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13469#[cfg_attr(feature = "bindings", derive(TS))]
13470pub struct MakeInterval {
13471    #[serde(default)]
13472    pub year: Option<Box<Expression>>,
13473    #[serde(default)]
13474    pub month: Option<Box<Expression>>,
13475    #[serde(default)]
13476    pub week: Option<Box<Expression>>,
13477    #[serde(default)]
13478    pub day: Option<Box<Expression>>,
13479    #[serde(default)]
13480    pub hour: Option<Box<Expression>>,
13481    #[serde(default)]
13482    pub minute: Option<Box<Expression>>,
13483    #[serde(default)]
13484    pub second: Option<Box<Expression>>,
13485}
13486
13487/// PreviousDay
13488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13489#[cfg_attr(feature = "bindings", derive(TS))]
13490pub struct PreviousDay {
13491    pub this: Box<Expression>,
13492    pub expression: Box<Expression>,
13493}
13494
13495/// Elt
13496#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13497#[cfg_attr(feature = "bindings", derive(TS))]
13498pub struct Elt {
13499    pub this: Box<Expression>,
13500    #[serde(default)]
13501    pub expressions: Vec<Expression>,
13502}
13503
13504/// TimestampAdd
13505#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13506#[cfg_attr(feature = "bindings", derive(TS))]
13507pub struct TimestampAdd {
13508    pub this: Box<Expression>,
13509    pub expression: Box<Expression>,
13510    #[serde(default)]
13511    pub unit: Option<String>,
13512}
13513
13514/// TimestampSub
13515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13516#[cfg_attr(feature = "bindings", derive(TS))]
13517pub struct TimestampSub {
13518    pub this: Box<Expression>,
13519    pub expression: Box<Expression>,
13520    #[serde(default)]
13521    pub unit: Option<String>,
13522}
13523
13524/// TimestampDiff
13525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13526#[cfg_attr(feature = "bindings", derive(TS))]
13527pub struct TimestampDiff {
13528    pub this: Box<Expression>,
13529    pub expression: Box<Expression>,
13530    #[serde(default)]
13531    pub unit: Option<String>,
13532}
13533
13534/// TimeSlice
13535#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13536#[cfg_attr(feature = "bindings", derive(TS))]
13537pub struct TimeSlice {
13538    pub this: Box<Expression>,
13539    pub expression: Box<Expression>,
13540    pub unit: String,
13541    #[serde(default)]
13542    pub kind: Option<String>,
13543}
13544
13545/// TimeAdd
13546#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13547#[cfg_attr(feature = "bindings", derive(TS))]
13548pub struct TimeAdd {
13549    pub this: Box<Expression>,
13550    pub expression: Box<Expression>,
13551    #[serde(default)]
13552    pub unit: Option<String>,
13553}
13554
13555/// TimeSub
13556#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13557#[cfg_attr(feature = "bindings", derive(TS))]
13558pub struct TimeSub {
13559    pub this: Box<Expression>,
13560    pub expression: Box<Expression>,
13561    #[serde(default)]
13562    pub unit: Option<String>,
13563}
13564
13565/// TimeDiff
13566#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13567#[cfg_attr(feature = "bindings", derive(TS))]
13568pub struct TimeDiff {
13569    pub this: Box<Expression>,
13570    pub expression: Box<Expression>,
13571    #[serde(default)]
13572    pub unit: Option<String>,
13573}
13574
13575/// TimeTrunc
13576#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13577#[cfg_attr(feature = "bindings", derive(TS))]
13578pub struct TimeTrunc {
13579    pub this: Box<Expression>,
13580    pub unit: String,
13581    #[serde(default)]
13582    pub zone: Option<Box<Expression>>,
13583}
13584
13585/// DateFromParts
13586#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13587#[cfg_attr(feature = "bindings", derive(TS))]
13588pub struct DateFromParts {
13589    #[serde(default)]
13590    pub year: Option<Box<Expression>>,
13591    #[serde(default)]
13592    pub month: Option<Box<Expression>>,
13593    #[serde(default)]
13594    pub day: Option<Box<Expression>>,
13595    #[serde(default)]
13596    pub allow_overflow: Option<Box<Expression>>,
13597}
13598
13599/// TimeFromParts
13600#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13601#[cfg_attr(feature = "bindings", derive(TS))]
13602pub struct TimeFromParts {
13603    #[serde(default)]
13604    pub hour: Option<Box<Expression>>,
13605    #[serde(default)]
13606    pub min: Option<Box<Expression>>,
13607    #[serde(default)]
13608    pub sec: Option<Box<Expression>>,
13609    #[serde(default)]
13610    pub nano: Option<Box<Expression>>,
13611    #[serde(default)]
13612    pub fractions: Option<Box<Expression>>,
13613    #[serde(default)]
13614    pub precision: Option<i64>,
13615}
13616
13617/// DecodeCase
13618#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13619#[cfg_attr(feature = "bindings", derive(TS))]
13620pub struct DecodeCase {
13621    #[serde(default)]
13622    pub expressions: Vec<Expression>,
13623}
13624
13625/// Decrypt
13626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13627#[cfg_attr(feature = "bindings", derive(TS))]
13628pub struct Decrypt {
13629    pub this: Box<Expression>,
13630    #[serde(default)]
13631    pub passphrase: Option<Box<Expression>>,
13632    #[serde(default)]
13633    pub aad: Option<Box<Expression>>,
13634    #[serde(default)]
13635    pub encryption_method: Option<Box<Expression>>,
13636    #[serde(default)]
13637    pub safe: Option<Box<Expression>>,
13638}
13639
13640/// DecryptRaw
13641#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13642#[cfg_attr(feature = "bindings", derive(TS))]
13643pub struct DecryptRaw {
13644    pub this: Box<Expression>,
13645    #[serde(default)]
13646    pub key: Option<Box<Expression>>,
13647    #[serde(default)]
13648    pub iv: Option<Box<Expression>>,
13649    #[serde(default)]
13650    pub aad: Option<Box<Expression>>,
13651    #[serde(default)]
13652    pub encryption_method: Option<Box<Expression>>,
13653    #[serde(default)]
13654    pub aead: Option<Box<Expression>>,
13655    #[serde(default)]
13656    pub safe: Option<Box<Expression>>,
13657}
13658
13659/// Encode
13660#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13661#[cfg_attr(feature = "bindings", derive(TS))]
13662pub struct Encode {
13663    pub this: Box<Expression>,
13664    #[serde(default)]
13665    pub charset: Option<Box<Expression>>,
13666}
13667
13668/// Encrypt
13669#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13670#[cfg_attr(feature = "bindings", derive(TS))]
13671pub struct Encrypt {
13672    pub this: Box<Expression>,
13673    #[serde(default)]
13674    pub passphrase: Option<Box<Expression>>,
13675    #[serde(default)]
13676    pub aad: Option<Box<Expression>>,
13677    #[serde(default)]
13678    pub encryption_method: Option<Box<Expression>>,
13679}
13680
13681/// EncryptRaw
13682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13683#[cfg_attr(feature = "bindings", derive(TS))]
13684pub struct EncryptRaw {
13685    pub this: Box<Expression>,
13686    #[serde(default)]
13687    pub key: Option<Box<Expression>>,
13688    #[serde(default)]
13689    pub iv: Option<Box<Expression>>,
13690    #[serde(default)]
13691    pub aad: Option<Box<Expression>>,
13692    #[serde(default)]
13693    pub encryption_method: Option<Box<Expression>>,
13694}
13695
13696/// EqualNull
13697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13698#[cfg_attr(feature = "bindings", derive(TS))]
13699pub struct EqualNull {
13700    pub this: Box<Expression>,
13701    pub expression: Box<Expression>,
13702}
13703
13704/// ToBinary
13705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13706#[cfg_attr(feature = "bindings", derive(TS))]
13707pub struct ToBinary {
13708    pub this: Box<Expression>,
13709    #[serde(default)]
13710    pub format: Option<String>,
13711    #[serde(default)]
13712    pub safe: Option<Box<Expression>>,
13713}
13714
13715/// Base64DecodeBinary
13716#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13717#[cfg_attr(feature = "bindings", derive(TS))]
13718pub struct Base64DecodeBinary {
13719    pub this: Box<Expression>,
13720    #[serde(default)]
13721    pub alphabet: Option<Box<Expression>>,
13722}
13723
13724/// Base64DecodeString
13725#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13726#[cfg_attr(feature = "bindings", derive(TS))]
13727pub struct Base64DecodeString {
13728    pub this: Box<Expression>,
13729    #[serde(default)]
13730    pub alphabet: Option<Box<Expression>>,
13731}
13732
13733/// Base64Encode
13734#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13735#[cfg_attr(feature = "bindings", derive(TS))]
13736pub struct Base64Encode {
13737    pub this: Box<Expression>,
13738    #[serde(default)]
13739    pub max_line_length: Option<Box<Expression>>,
13740    #[serde(default)]
13741    pub alphabet: Option<Box<Expression>>,
13742}
13743
13744/// TryBase64DecodeBinary
13745#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13746#[cfg_attr(feature = "bindings", derive(TS))]
13747pub struct TryBase64DecodeBinary {
13748    pub this: Box<Expression>,
13749    #[serde(default)]
13750    pub alphabet: Option<Box<Expression>>,
13751}
13752
13753/// TryBase64DecodeString
13754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13755#[cfg_attr(feature = "bindings", derive(TS))]
13756pub struct TryBase64DecodeString {
13757    pub this: Box<Expression>,
13758    #[serde(default)]
13759    pub alphabet: Option<Box<Expression>>,
13760}
13761
13762/// GapFill
13763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13764#[cfg_attr(feature = "bindings", derive(TS))]
13765pub struct GapFill {
13766    pub this: Box<Expression>,
13767    #[serde(default)]
13768    pub ts_column: Option<Box<Expression>>,
13769    #[serde(default)]
13770    pub bucket_width: Option<Box<Expression>>,
13771    #[serde(default)]
13772    pub partitioning_columns: Option<Box<Expression>>,
13773    #[serde(default)]
13774    pub value_columns: Option<Box<Expression>>,
13775    #[serde(default)]
13776    pub origin: Option<Box<Expression>>,
13777    #[serde(default)]
13778    pub ignore_nulls: Option<Box<Expression>>,
13779}
13780
13781/// GenerateDateArray
13782#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13783#[cfg_attr(feature = "bindings", derive(TS))]
13784pub struct GenerateDateArray {
13785    #[serde(default)]
13786    pub start: Option<Box<Expression>>,
13787    #[serde(default)]
13788    pub end: Option<Box<Expression>>,
13789    #[serde(default)]
13790    pub step: Option<Box<Expression>>,
13791}
13792
13793/// GenerateTimestampArray
13794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13795#[cfg_attr(feature = "bindings", derive(TS))]
13796pub struct GenerateTimestampArray {
13797    #[serde(default)]
13798    pub start: Option<Box<Expression>>,
13799    #[serde(default)]
13800    pub end: Option<Box<Expression>>,
13801    #[serde(default)]
13802    pub step: Option<Box<Expression>>,
13803}
13804
13805/// GetExtract
13806#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13807#[cfg_attr(feature = "bindings", derive(TS))]
13808pub struct GetExtract {
13809    pub this: Box<Expression>,
13810    pub expression: Box<Expression>,
13811}
13812
13813/// Getbit
13814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13815#[cfg_attr(feature = "bindings", derive(TS))]
13816pub struct Getbit {
13817    pub this: Box<Expression>,
13818    pub expression: Box<Expression>,
13819    #[serde(default)]
13820    pub zero_is_msb: Option<Box<Expression>>,
13821}
13822
13823/// OverflowTruncateBehavior
13824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13825#[cfg_attr(feature = "bindings", derive(TS))]
13826pub struct OverflowTruncateBehavior {
13827    #[serde(default)]
13828    pub this: Option<Box<Expression>>,
13829    #[serde(default)]
13830    pub with_count: Option<Box<Expression>>,
13831}
13832
13833/// HexEncode
13834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13835#[cfg_attr(feature = "bindings", derive(TS))]
13836pub struct HexEncode {
13837    pub this: Box<Expression>,
13838    #[serde(default)]
13839    pub case: Option<Box<Expression>>,
13840}
13841
13842/// Compress
13843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13844#[cfg_attr(feature = "bindings", derive(TS))]
13845pub struct Compress {
13846    pub this: Box<Expression>,
13847    #[serde(default)]
13848    pub method: Option<String>,
13849}
13850
13851/// DecompressBinary
13852#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13853#[cfg_attr(feature = "bindings", derive(TS))]
13854pub struct DecompressBinary {
13855    pub this: Box<Expression>,
13856    pub method: String,
13857}
13858
13859/// DecompressString
13860#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13861#[cfg_attr(feature = "bindings", derive(TS))]
13862pub struct DecompressString {
13863    pub this: Box<Expression>,
13864    pub method: String,
13865}
13866
13867/// Xor
13868#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13869#[cfg_attr(feature = "bindings", derive(TS))]
13870pub struct Xor {
13871    #[serde(default)]
13872    pub this: Option<Box<Expression>>,
13873    #[serde(default)]
13874    pub expression: Option<Box<Expression>>,
13875    #[serde(default)]
13876    pub expressions: Vec<Expression>,
13877}
13878
13879/// Nullif
13880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13881#[cfg_attr(feature = "bindings", derive(TS))]
13882pub struct Nullif {
13883    pub this: Box<Expression>,
13884    pub expression: Box<Expression>,
13885}
13886
13887/// JSON
13888#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13889#[cfg_attr(feature = "bindings", derive(TS))]
13890pub struct JSON {
13891    #[serde(default)]
13892    pub this: Option<Box<Expression>>,
13893    #[serde(default)]
13894    pub with_: Option<Box<Expression>>,
13895    #[serde(default)]
13896    pub unique: bool,
13897}
13898
13899/// JSONPath
13900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13901#[cfg_attr(feature = "bindings", derive(TS))]
13902pub struct JSONPath {
13903    #[serde(default)]
13904    pub expressions: Vec<Expression>,
13905    #[serde(default)]
13906    pub escape: Option<Box<Expression>>,
13907}
13908
13909/// JSONPathFilter
13910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13911#[cfg_attr(feature = "bindings", derive(TS))]
13912pub struct JSONPathFilter {
13913    pub this: Box<Expression>,
13914}
13915
13916/// JSONPathKey
13917#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13918#[cfg_attr(feature = "bindings", derive(TS))]
13919pub struct JSONPathKey {
13920    pub this: Box<Expression>,
13921}
13922
13923/// JSONPathRecursive
13924#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13925#[cfg_attr(feature = "bindings", derive(TS))]
13926pub struct JSONPathRecursive {
13927    #[serde(default)]
13928    pub this: Option<Box<Expression>>,
13929}
13930
13931/// JSONPathScript
13932#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13933#[cfg_attr(feature = "bindings", derive(TS))]
13934pub struct JSONPathScript {
13935    pub this: Box<Expression>,
13936}
13937
13938/// JSONPathSlice
13939#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13940#[cfg_attr(feature = "bindings", derive(TS))]
13941pub struct JSONPathSlice {
13942    #[serde(default)]
13943    pub start: Option<Box<Expression>>,
13944    #[serde(default)]
13945    pub end: Option<Box<Expression>>,
13946    #[serde(default)]
13947    pub step: Option<Box<Expression>>,
13948}
13949
13950/// JSONPathSelector
13951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13952#[cfg_attr(feature = "bindings", derive(TS))]
13953pub struct JSONPathSelector {
13954    pub this: Box<Expression>,
13955}
13956
13957/// JSONPathSubscript
13958#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13959#[cfg_attr(feature = "bindings", derive(TS))]
13960pub struct JSONPathSubscript {
13961    pub this: Box<Expression>,
13962}
13963
13964/// JSONPathUnion
13965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13966#[cfg_attr(feature = "bindings", derive(TS))]
13967pub struct JSONPathUnion {
13968    #[serde(default)]
13969    pub expressions: Vec<Expression>,
13970}
13971
13972/// Format
13973#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13974#[cfg_attr(feature = "bindings", derive(TS))]
13975pub struct Format {
13976    pub this: Box<Expression>,
13977    #[serde(default)]
13978    pub expressions: Vec<Expression>,
13979}
13980
13981/// JSONKeys
13982#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13983#[cfg_attr(feature = "bindings", derive(TS))]
13984pub struct JSONKeys {
13985    pub this: Box<Expression>,
13986    #[serde(default)]
13987    pub expression: Option<Box<Expression>>,
13988    #[serde(default)]
13989    pub expressions: Vec<Expression>,
13990}
13991
13992/// JSONKeyValue
13993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13994#[cfg_attr(feature = "bindings", derive(TS))]
13995pub struct JSONKeyValue {
13996    pub this: Box<Expression>,
13997    pub expression: Box<Expression>,
13998}
13999
14000/// JSONKeysAtDepth
14001#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14002#[cfg_attr(feature = "bindings", derive(TS))]
14003pub struct JSONKeysAtDepth {
14004    pub this: Box<Expression>,
14005    #[serde(default)]
14006    pub expression: Option<Box<Expression>>,
14007    #[serde(default)]
14008    pub mode: Option<Box<Expression>>,
14009}
14010
14011/// JSONObject
14012#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14013#[cfg_attr(feature = "bindings", derive(TS))]
14014pub struct JSONObject {
14015    #[serde(default)]
14016    pub expressions: Vec<Expression>,
14017    #[serde(default)]
14018    pub null_handling: Option<Box<Expression>>,
14019    #[serde(default)]
14020    pub unique_keys: Option<Box<Expression>>,
14021    #[serde(default)]
14022    pub return_type: Option<Box<Expression>>,
14023    #[serde(default)]
14024    pub encoding: Option<Box<Expression>>,
14025}
14026
14027/// JSONObjectAgg
14028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14029#[cfg_attr(feature = "bindings", derive(TS))]
14030pub struct JSONObjectAgg {
14031    #[serde(default)]
14032    pub expressions: Vec<Expression>,
14033    #[serde(default)]
14034    pub null_handling: Option<Box<Expression>>,
14035    #[serde(default)]
14036    pub unique_keys: Option<Box<Expression>>,
14037    #[serde(default)]
14038    pub return_type: Option<Box<Expression>>,
14039    #[serde(default)]
14040    pub encoding: Option<Box<Expression>>,
14041}
14042
14043/// JSONBObjectAgg
14044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14045#[cfg_attr(feature = "bindings", derive(TS))]
14046pub struct JSONBObjectAgg {
14047    pub this: Box<Expression>,
14048    pub expression: Box<Expression>,
14049}
14050
14051/// JSONArray
14052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14053#[cfg_attr(feature = "bindings", derive(TS))]
14054pub struct JSONArray {
14055    #[serde(default)]
14056    pub expressions: Vec<Expression>,
14057    #[serde(default)]
14058    pub null_handling: Option<Box<Expression>>,
14059    #[serde(default)]
14060    pub return_type: Option<Box<Expression>>,
14061    #[serde(default)]
14062    pub strict: Option<Box<Expression>>,
14063}
14064
14065/// JSONArrayAgg
14066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14067#[cfg_attr(feature = "bindings", derive(TS))]
14068pub struct JSONArrayAgg {
14069    pub this: Box<Expression>,
14070    #[serde(default)]
14071    pub order: Option<Box<Expression>>,
14072    #[serde(default)]
14073    pub null_handling: Option<Box<Expression>>,
14074    #[serde(default)]
14075    pub return_type: Option<Box<Expression>>,
14076    #[serde(default)]
14077    pub strict: Option<Box<Expression>>,
14078}
14079
14080/// JSONExists
14081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14082#[cfg_attr(feature = "bindings", derive(TS))]
14083pub struct JSONExists {
14084    pub this: Box<Expression>,
14085    #[serde(default)]
14086    pub path: Option<Box<Expression>>,
14087    #[serde(default)]
14088    pub passing: Option<Box<Expression>>,
14089    #[serde(default)]
14090    pub on_condition: Option<Box<Expression>>,
14091    #[serde(default)]
14092    pub from_dcolonqmark: Option<Box<Expression>>,
14093}
14094
14095/// JSONColumnDef
14096#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14097#[cfg_attr(feature = "bindings", derive(TS))]
14098pub struct JSONColumnDef {
14099    #[serde(default)]
14100    pub this: Option<Box<Expression>>,
14101    #[serde(default)]
14102    pub kind: Option<String>,
14103    #[serde(default)]
14104    pub format_json: bool,
14105    #[serde(default)]
14106    pub path: Option<Box<Expression>>,
14107    #[serde(default)]
14108    pub nested_schema: Option<Box<Expression>>,
14109    #[serde(default)]
14110    pub ordinality: Option<Box<Expression>>,
14111}
14112
14113/// JSONSchema
14114#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14115#[cfg_attr(feature = "bindings", derive(TS))]
14116pub struct JSONSchema {
14117    #[serde(default)]
14118    pub expressions: Vec<Expression>,
14119}
14120
14121/// JSONSet
14122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14123#[cfg_attr(feature = "bindings", derive(TS))]
14124pub struct JSONSet {
14125    pub this: Box<Expression>,
14126    #[serde(default)]
14127    pub expressions: Vec<Expression>,
14128}
14129
14130/// JSONStripNulls
14131#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14132#[cfg_attr(feature = "bindings", derive(TS))]
14133pub struct JSONStripNulls {
14134    pub this: Box<Expression>,
14135    #[serde(default)]
14136    pub expression: Option<Box<Expression>>,
14137    #[serde(default)]
14138    pub include_arrays: Option<Box<Expression>>,
14139    #[serde(default)]
14140    pub remove_empty: Option<Box<Expression>>,
14141}
14142
14143/// JSONValue
14144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14145#[cfg_attr(feature = "bindings", derive(TS))]
14146pub struct JSONValue {
14147    pub this: Box<Expression>,
14148    #[serde(default)]
14149    pub path: Option<Box<Expression>>,
14150    #[serde(default)]
14151    pub returning: Option<Box<Expression>>,
14152    #[serde(default)]
14153    pub on_condition: Option<Box<Expression>>,
14154}
14155
14156/// JSONValueArray
14157#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14158#[cfg_attr(feature = "bindings", derive(TS))]
14159pub struct JSONValueArray {
14160    pub this: Box<Expression>,
14161    #[serde(default)]
14162    pub expression: Option<Box<Expression>>,
14163}
14164
14165/// JSONRemove
14166#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14167#[cfg_attr(feature = "bindings", derive(TS))]
14168pub struct JSONRemove {
14169    pub this: Box<Expression>,
14170    #[serde(default)]
14171    pub expressions: Vec<Expression>,
14172}
14173
14174/// JSONTable
14175#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14176#[cfg_attr(feature = "bindings", derive(TS))]
14177pub struct JSONTable {
14178    pub this: Box<Expression>,
14179    #[serde(default)]
14180    pub schema: Option<Box<Expression>>,
14181    #[serde(default)]
14182    pub path: Option<Box<Expression>>,
14183    #[serde(default)]
14184    pub error_handling: Option<Box<Expression>>,
14185    #[serde(default)]
14186    pub empty_handling: Option<Box<Expression>>,
14187}
14188
14189/// JSONType
14190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14191#[cfg_attr(feature = "bindings", derive(TS))]
14192pub struct JSONType {
14193    pub this: Box<Expression>,
14194    #[serde(default)]
14195    pub expression: Option<Box<Expression>>,
14196}
14197
14198/// ObjectInsert
14199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14200#[cfg_attr(feature = "bindings", derive(TS))]
14201pub struct ObjectInsert {
14202    pub this: Box<Expression>,
14203    #[serde(default)]
14204    pub key: Option<Box<Expression>>,
14205    #[serde(default)]
14206    pub value: Option<Box<Expression>>,
14207    #[serde(default)]
14208    pub update_flag: Option<Box<Expression>>,
14209}
14210
14211/// OpenJSONColumnDef
14212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14213#[cfg_attr(feature = "bindings", derive(TS))]
14214pub struct OpenJSONColumnDef {
14215    pub this: Box<Expression>,
14216    pub kind: String,
14217    #[serde(default)]
14218    pub path: Option<Box<Expression>>,
14219    #[serde(default)]
14220    pub as_json: Option<Box<Expression>>,
14221    /// The parsed data type for proper generation
14222    #[serde(default, skip_serializing_if = "Option::is_none")]
14223    pub data_type: Option<DataType>,
14224}
14225
14226/// OpenJSON
14227#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14228#[cfg_attr(feature = "bindings", derive(TS))]
14229pub struct OpenJSON {
14230    pub this: Box<Expression>,
14231    #[serde(default)]
14232    pub path: Option<Box<Expression>>,
14233    #[serde(default)]
14234    pub expressions: Vec<Expression>,
14235}
14236
14237/// JSONBExists
14238#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14239#[cfg_attr(feature = "bindings", derive(TS))]
14240pub struct JSONBExists {
14241    pub this: Box<Expression>,
14242    #[serde(default)]
14243    pub path: Option<Box<Expression>>,
14244}
14245
14246/// JSONCast
14247#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14248#[cfg_attr(feature = "bindings", derive(TS))]
14249pub struct JSONCast {
14250    pub this: Box<Expression>,
14251    pub to: DataType,
14252}
14253
14254/// JSONExtract
14255#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14256#[cfg_attr(feature = "bindings", derive(TS))]
14257pub struct JSONExtract {
14258    pub this: Box<Expression>,
14259    pub expression: Box<Expression>,
14260    #[serde(default)]
14261    pub only_json_types: Option<Box<Expression>>,
14262    #[serde(default)]
14263    pub expressions: Vec<Expression>,
14264    #[serde(default)]
14265    pub variant_extract: Option<Box<Expression>>,
14266    #[serde(default)]
14267    pub json_query: Option<Box<Expression>>,
14268    #[serde(default)]
14269    pub option: Option<Box<Expression>>,
14270    #[serde(default)]
14271    pub quote: Option<Box<Expression>>,
14272    #[serde(default)]
14273    pub on_condition: Option<Box<Expression>>,
14274    #[serde(default)]
14275    pub requires_json: Option<Box<Expression>>,
14276}
14277
14278/// JSONExtractQuote
14279#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14280#[cfg_attr(feature = "bindings", derive(TS))]
14281pub struct JSONExtractQuote {
14282    #[serde(default)]
14283    pub option: Option<Box<Expression>>,
14284    #[serde(default)]
14285    pub scalar: Option<Box<Expression>>,
14286}
14287
14288/// JSONExtractArray
14289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14290#[cfg_attr(feature = "bindings", derive(TS))]
14291pub struct JSONExtractArray {
14292    pub this: Box<Expression>,
14293    #[serde(default)]
14294    pub expression: Option<Box<Expression>>,
14295}
14296
14297/// JSONExtractScalar
14298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14299#[cfg_attr(feature = "bindings", derive(TS))]
14300pub struct JSONExtractScalar {
14301    pub this: Box<Expression>,
14302    pub expression: Box<Expression>,
14303    #[serde(default)]
14304    pub only_json_types: Option<Box<Expression>>,
14305    #[serde(default)]
14306    pub expressions: Vec<Expression>,
14307    #[serde(default)]
14308    pub json_type: Option<Box<Expression>>,
14309    #[serde(default)]
14310    pub scalar_only: Option<Box<Expression>>,
14311}
14312
14313/// JSONBExtractScalar
14314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14315#[cfg_attr(feature = "bindings", derive(TS))]
14316pub struct JSONBExtractScalar {
14317    pub this: Box<Expression>,
14318    pub expression: Box<Expression>,
14319    #[serde(default)]
14320    pub json_type: Option<Box<Expression>>,
14321}
14322
14323/// JSONFormat
14324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14325#[cfg_attr(feature = "bindings", derive(TS))]
14326pub struct JSONFormat {
14327    #[serde(default)]
14328    pub this: Option<Box<Expression>>,
14329    #[serde(default)]
14330    pub options: Vec<Expression>,
14331    #[serde(default)]
14332    pub is_json: Option<Box<Expression>>,
14333    #[serde(default)]
14334    pub to_json: Option<Box<Expression>>,
14335}
14336
14337/// JSONArrayAppend
14338#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14339#[cfg_attr(feature = "bindings", derive(TS))]
14340pub struct JSONArrayAppend {
14341    pub this: Box<Expression>,
14342    #[serde(default)]
14343    pub expressions: Vec<Expression>,
14344}
14345
14346/// JSONArrayContains
14347#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14348#[cfg_attr(feature = "bindings", derive(TS))]
14349pub struct JSONArrayContains {
14350    pub this: Box<Expression>,
14351    pub expression: Box<Expression>,
14352    #[serde(default)]
14353    pub json_type: Option<Box<Expression>>,
14354}
14355
14356/// JSONArrayInsert
14357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14358#[cfg_attr(feature = "bindings", derive(TS))]
14359pub struct JSONArrayInsert {
14360    pub this: Box<Expression>,
14361    #[serde(default)]
14362    pub expressions: Vec<Expression>,
14363}
14364
14365/// ParseJSON
14366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14367#[cfg_attr(feature = "bindings", derive(TS))]
14368pub struct ParseJSON {
14369    pub this: Box<Expression>,
14370    #[serde(default)]
14371    pub expression: Option<Box<Expression>>,
14372    #[serde(default)]
14373    pub safe: Option<Box<Expression>>,
14374}
14375
14376/// ParseUrl
14377#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14378#[cfg_attr(feature = "bindings", derive(TS))]
14379pub struct ParseUrl {
14380    pub this: Box<Expression>,
14381    #[serde(default)]
14382    pub part_to_extract: Option<Box<Expression>>,
14383    #[serde(default)]
14384    pub key: Option<Box<Expression>>,
14385    #[serde(default)]
14386    pub permissive: Option<Box<Expression>>,
14387}
14388
14389/// ParseIp
14390#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14391#[cfg_attr(feature = "bindings", derive(TS))]
14392pub struct ParseIp {
14393    pub this: Box<Expression>,
14394    #[serde(default)]
14395    pub type_: Option<Box<Expression>>,
14396    #[serde(default)]
14397    pub permissive: Option<Box<Expression>>,
14398}
14399
14400/// ParseTime
14401#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14402#[cfg_attr(feature = "bindings", derive(TS))]
14403pub struct ParseTime {
14404    pub this: Box<Expression>,
14405    pub format: String,
14406}
14407
14408/// ParseDatetime
14409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14410#[cfg_attr(feature = "bindings", derive(TS))]
14411pub struct ParseDatetime {
14412    pub this: Box<Expression>,
14413    #[serde(default)]
14414    pub format: Option<String>,
14415    #[serde(default)]
14416    pub zone: Option<Box<Expression>>,
14417}
14418
14419/// Map
14420#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14421#[cfg_attr(feature = "bindings", derive(TS))]
14422pub struct Map {
14423    #[serde(default)]
14424    pub keys: Vec<Expression>,
14425    #[serde(default)]
14426    pub values: Vec<Expression>,
14427}
14428
14429/// MapCat
14430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14431#[cfg_attr(feature = "bindings", derive(TS))]
14432pub struct MapCat {
14433    pub this: Box<Expression>,
14434    pub expression: Box<Expression>,
14435}
14436
14437/// MapDelete
14438#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14439#[cfg_attr(feature = "bindings", derive(TS))]
14440pub struct MapDelete {
14441    pub this: Box<Expression>,
14442    #[serde(default)]
14443    pub expressions: Vec<Expression>,
14444}
14445
14446/// MapInsert
14447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14448#[cfg_attr(feature = "bindings", derive(TS))]
14449pub struct MapInsert {
14450    pub this: Box<Expression>,
14451    #[serde(default)]
14452    pub key: Option<Box<Expression>>,
14453    #[serde(default)]
14454    pub value: Option<Box<Expression>>,
14455    #[serde(default)]
14456    pub update_flag: Option<Box<Expression>>,
14457}
14458
14459/// MapPick
14460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14461#[cfg_attr(feature = "bindings", derive(TS))]
14462pub struct MapPick {
14463    pub this: Box<Expression>,
14464    #[serde(default)]
14465    pub expressions: Vec<Expression>,
14466}
14467
14468/// ScopeResolution
14469#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14470#[cfg_attr(feature = "bindings", derive(TS))]
14471pub struct ScopeResolution {
14472    #[serde(default)]
14473    pub this: Option<Box<Expression>>,
14474    pub expression: Box<Expression>,
14475}
14476
14477/// Slice
14478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14479#[cfg_attr(feature = "bindings", derive(TS))]
14480pub struct Slice {
14481    #[serde(default)]
14482    pub this: Option<Box<Expression>>,
14483    #[serde(default)]
14484    pub expression: Option<Box<Expression>>,
14485    #[serde(default)]
14486    pub step: Option<Box<Expression>>,
14487}
14488
14489/// VarMap
14490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14491#[cfg_attr(feature = "bindings", derive(TS))]
14492pub struct VarMap {
14493    #[serde(default)]
14494    pub keys: Vec<Expression>,
14495    #[serde(default)]
14496    pub values: Vec<Expression>,
14497}
14498
14499/// MatchAgainst
14500#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14501#[cfg_attr(feature = "bindings", derive(TS))]
14502pub struct MatchAgainst {
14503    pub this: Box<Expression>,
14504    #[serde(default)]
14505    pub expressions: Vec<Expression>,
14506    #[serde(default)]
14507    pub modifier: Option<Box<Expression>>,
14508}
14509
14510/// MD5Digest
14511#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14512#[cfg_attr(feature = "bindings", derive(TS))]
14513pub struct MD5Digest {
14514    pub this: Box<Expression>,
14515    #[serde(default)]
14516    pub expressions: Vec<Expression>,
14517}
14518
14519/// Monthname
14520#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14521#[cfg_attr(feature = "bindings", derive(TS))]
14522pub struct Monthname {
14523    pub this: Box<Expression>,
14524    #[serde(default)]
14525    pub abbreviated: Option<Box<Expression>>,
14526}
14527
14528/// Ntile
14529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14530#[cfg_attr(feature = "bindings", derive(TS))]
14531pub struct Ntile {
14532    #[serde(default)]
14533    pub this: Option<Box<Expression>>,
14534}
14535
14536/// Normalize
14537#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14538#[cfg_attr(feature = "bindings", derive(TS))]
14539pub struct Normalize {
14540    pub this: Box<Expression>,
14541    #[serde(default)]
14542    pub form: Option<Box<Expression>>,
14543    #[serde(default)]
14544    pub is_casefold: Option<Box<Expression>>,
14545}
14546
14547/// Normal
14548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14549#[cfg_attr(feature = "bindings", derive(TS))]
14550pub struct Normal {
14551    pub this: Box<Expression>,
14552    #[serde(default)]
14553    pub stddev: Option<Box<Expression>>,
14554    #[serde(default)]
14555    pub gen: Option<Box<Expression>>,
14556}
14557
14558/// Predict
14559#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14560#[cfg_attr(feature = "bindings", derive(TS))]
14561pub struct Predict {
14562    pub this: Box<Expression>,
14563    pub expression: Box<Expression>,
14564    #[serde(default)]
14565    pub params_struct: Option<Box<Expression>>,
14566}
14567
14568/// MLTranslate
14569#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14570#[cfg_attr(feature = "bindings", derive(TS))]
14571pub struct MLTranslate {
14572    pub this: Box<Expression>,
14573    pub expression: Box<Expression>,
14574    #[serde(default)]
14575    pub params_struct: Option<Box<Expression>>,
14576}
14577
14578/// FeaturesAtTime
14579#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14580#[cfg_attr(feature = "bindings", derive(TS))]
14581pub struct FeaturesAtTime {
14582    pub this: Box<Expression>,
14583    #[serde(default)]
14584    pub time: Option<Box<Expression>>,
14585    #[serde(default)]
14586    pub num_rows: Option<Box<Expression>>,
14587    #[serde(default)]
14588    pub ignore_feature_nulls: Option<Box<Expression>>,
14589}
14590
14591/// GenerateEmbedding
14592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14593#[cfg_attr(feature = "bindings", derive(TS))]
14594pub struct GenerateEmbedding {
14595    pub this: Box<Expression>,
14596    pub expression: Box<Expression>,
14597    #[serde(default)]
14598    pub params_struct: Option<Box<Expression>>,
14599    #[serde(default)]
14600    pub is_text: Option<Box<Expression>>,
14601}
14602
14603/// MLForecast
14604#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14605#[cfg_attr(feature = "bindings", derive(TS))]
14606pub struct MLForecast {
14607    pub this: Box<Expression>,
14608    #[serde(default)]
14609    pub expression: Option<Box<Expression>>,
14610    #[serde(default)]
14611    pub params_struct: Option<Box<Expression>>,
14612}
14613
14614/// ModelAttribute
14615#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14616#[cfg_attr(feature = "bindings", derive(TS))]
14617pub struct ModelAttribute {
14618    pub this: Box<Expression>,
14619    pub expression: Box<Expression>,
14620}
14621
14622/// VectorSearch
14623#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14624#[cfg_attr(feature = "bindings", derive(TS))]
14625pub struct VectorSearch {
14626    pub this: Box<Expression>,
14627    #[serde(default)]
14628    pub column_to_search: Option<Box<Expression>>,
14629    #[serde(default)]
14630    pub query_table: Option<Box<Expression>>,
14631    #[serde(default)]
14632    pub query_column_to_search: Option<Box<Expression>>,
14633    #[serde(default)]
14634    pub top_k: Option<Box<Expression>>,
14635    #[serde(default)]
14636    pub distance_type: Option<Box<Expression>>,
14637    #[serde(default)]
14638    pub options: Vec<Expression>,
14639}
14640
14641/// Quantile
14642#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14643#[cfg_attr(feature = "bindings", derive(TS))]
14644pub struct Quantile {
14645    pub this: Box<Expression>,
14646    #[serde(default)]
14647    pub quantile: Option<Box<Expression>>,
14648}
14649
14650/// ApproxQuantile
14651#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14652#[cfg_attr(feature = "bindings", derive(TS))]
14653pub struct ApproxQuantile {
14654    pub this: Box<Expression>,
14655    #[serde(default)]
14656    pub quantile: Option<Box<Expression>>,
14657    #[serde(default)]
14658    pub accuracy: Option<Box<Expression>>,
14659    #[serde(default)]
14660    pub weight: Option<Box<Expression>>,
14661    #[serde(default)]
14662    pub error_tolerance: Option<Box<Expression>>,
14663}
14664
14665/// ApproxPercentileEstimate
14666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14667#[cfg_attr(feature = "bindings", derive(TS))]
14668pub struct ApproxPercentileEstimate {
14669    pub this: Box<Expression>,
14670    #[serde(default)]
14671    pub percentile: Option<Box<Expression>>,
14672}
14673
14674/// Randn
14675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14676#[cfg_attr(feature = "bindings", derive(TS))]
14677pub struct Randn {
14678    #[serde(default)]
14679    pub this: Option<Box<Expression>>,
14680}
14681
14682/// Randstr
14683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14684#[cfg_attr(feature = "bindings", derive(TS))]
14685pub struct Randstr {
14686    pub this: Box<Expression>,
14687    #[serde(default)]
14688    pub generator: Option<Box<Expression>>,
14689}
14690
14691/// RangeN
14692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14693#[cfg_attr(feature = "bindings", derive(TS))]
14694pub struct RangeN {
14695    pub this: Box<Expression>,
14696    #[serde(default)]
14697    pub expressions: Vec<Expression>,
14698    #[serde(default)]
14699    pub each: Option<Box<Expression>>,
14700}
14701
14702/// RangeBucket
14703#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14704#[cfg_attr(feature = "bindings", derive(TS))]
14705pub struct RangeBucket {
14706    pub this: Box<Expression>,
14707    pub expression: Box<Expression>,
14708}
14709
14710/// ReadCSV
14711#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14712#[cfg_attr(feature = "bindings", derive(TS))]
14713pub struct ReadCSV {
14714    pub this: Box<Expression>,
14715    #[serde(default)]
14716    pub expressions: Vec<Expression>,
14717}
14718
14719/// ReadParquet
14720#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14721#[cfg_attr(feature = "bindings", derive(TS))]
14722pub struct ReadParquet {
14723    #[serde(default)]
14724    pub expressions: Vec<Expression>,
14725}
14726
14727/// Reduce
14728#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14729#[cfg_attr(feature = "bindings", derive(TS))]
14730pub struct Reduce {
14731    pub this: Box<Expression>,
14732    #[serde(default)]
14733    pub initial: Option<Box<Expression>>,
14734    #[serde(default)]
14735    pub merge: Option<Box<Expression>>,
14736    #[serde(default)]
14737    pub finish: Option<Box<Expression>>,
14738}
14739
14740/// RegexpExtractAll
14741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14742#[cfg_attr(feature = "bindings", derive(TS))]
14743pub struct RegexpExtractAll {
14744    pub this: Box<Expression>,
14745    pub expression: Box<Expression>,
14746    #[serde(default)]
14747    pub group: Option<Box<Expression>>,
14748    #[serde(default)]
14749    pub parameters: Option<Box<Expression>>,
14750    #[serde(default)]
14751    pub position: Option<Box<Expression>>,
14752    #[serde(default)]
14753    pub occurrence: Option<Box<Expression>>,
14754}
14755
14756/// RegexpILike
14757#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14758#[cfg_attr(feature = "bindings", derive(TS))]
14759pub struct RegexpILike {
14760    pub this: Box<Expression>,
14761    pub expression: Box<Expression>,
14762    #[serde(default)]
14763    pub flag: Option<Box<Expression>>,
14764}
14765
14766/// RegexpFullMatch
14767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14768#[cfg_attr(feature = "bindings", derive(TS))]
14769pub struct RegexpFullMatch {
14770    pub this: Box<Expression>,
14771    pub expression: Box<Expression>,
14772    #[serde(default)]
14773    pub options: Vec<Expression>,
14774}
14775
14776/// RegexpInstr
14777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14778#[cfg_attr(feature = "bindings", derive(TS))]
14779pub struct RegexpInstr {
14780    pub this: Box<Expression>,
14781    pub expression: Box<Expression>,
14782    #[serde(default)]
14783    pub position: Option<Box<Expression>>,
14784    #[serde(default)]
14785    pub occurrence: Option<Box<Expression>>,
14786    #[serde(default)]
14787    pub option: Option<Box<Expression>>,
14788    #[serde(default)]
14789    pub parameters: Option<Box<Expression>>,
14790    #[serde(default)]
14791    pub group: Option<Box<Expression>>,
14792}
14793
14794/// RegexpSplit
14795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14796#[cfg_attr(feature = "bindings", derive(TS))]
14797pub struct RegexpSplit {
14798    pub this: Box<Expression>,
14799    pub expression: Box<Expression>,
14800    #[serde(default)]
14801    pub limit: Option<Box<Expression>>,
14802}
14803
14804/// RegexpCount
14805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14806#[cfg_attr(feature = "bindings", derive(TS))]
14807pub struct RegexpCount {
14808    pub this: Box<Expression>,
14809    pub expression: Box<Expression>,
14810    #[serde(default)]
14811    pub position: Option<Box<Expression>>,
14812    #[serde(default)]
14813    pub parameters: Option<Box<Expression>>,
14814}
14815
14816/// RegrValx
14817#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14818#[cfg_attr(feature = "bindings", derive(TS))]
14819pub struct RegrValx {
14820    pub this: Box<Expression>,
14821    pub expression: Box<Expression>,
14822}
14823
14824/// RegrValy
14825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14826#[cfg_attr(feature = "bindings", derive(TS))]
14827pub struct RegrValy {
14828    pub this: Box<Expression>,
14829    pub expression: Box<Expression>,
14830}
14831
14832/// RegrAvgy
14833#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14834#[cfg_attr(feature = "bindings", derive(TS))]
14835pub struct RegrAvgy {
14836    pub this: Box<Expression>,
14837    pub expression: Box<Expression>,
14838}
14839
14840/// RegrAvgx
14841#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14842#[cfg_attr(feature = "bindings", derive(TS))]
14843pub struct RegrAvgx {
14844    pub this: Box<Expression>,
14845    pub expression: Box<Expression>,
14846}
14847
14848/// RegrCount
14849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14850#[cfg_attr(feature = "bindings", derive(TS))]
14851pub struct RegrCount {
14852    pub this: Box<Expression>,
14853    pub expression: Box<Expression>,
14854}
14855
14856/// RegrIntercept
14857#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14858#[cfg_attr(feature = "bindings", derive(TS))]
14859pub struct RegrIntercept {
14860    pub this: Box<Expression>,
14861    pub expression: Box<Expression>,
14862}
14863
14864/// RegrR2
14865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14866#[cfg_attr(feature = "bindings", derive(TS))]
14867pub struct RegrR2 {
14868    pub this: Box<Expression>,
14869    pub expression: Box<Expression>,
14870}
14871
14872/// RegrSxx
14873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14874#[cfg_attr(feature = "bindings", derive(TS))]
14875pub struct RegrSxx {
14876    pub this: Box<Expression>,
14877    pub expression: Box<Expression>,
14878}
14879
14880/// RegrSxy
14881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14882#[cfg_attr(feature = "bindings", derive(TS))]
14883pub struct RegrSxy {
14884    pub this: Box<Expression>,
14885    pub expression: Box<Expression>,
14886}
14887
14888/// RegrSyy
14889#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14890#[cfg_attr(feature = "bindings", derive(TS))]
14891pub struct RegrSyy {
14892    pub this: Box<Expression>,
14893    pub expression: Box<Expression>,
14894}
14895
14896/// RegrSlope
14897#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14898#[cfg_attr(feature = "bindings", derive(TS))]
14899pub struct RegrSlope {
14900    pub this: Box<Expression>,
14901    pub expression: Box<Expression>,
14902}
14903
14904/// SafeAdd
14905#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14906#[cfg_attr(feature = "bindings", derive(TS))]
14907pub struct SafeAdd {
14908    pub this: Box<Expression>,
14909    pub expression: Box<Expression>,
14910}
14911
14912/// SafeDivide
14913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14914#[cfg_attr(feature = "bindings", derive(TS))]
14915pub struct SafeDivide {
14916    pub this: Box<Expression>,
14917    pub expression: Box<Expression>,
14918}
14919
14920/// SafeMultiply
14921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14922#[cfg_attr(feature = "bindings", derive(TS))]
14923pub struct SafeMultiply {
14924    pub this: Box<Expression>,
14925    pub expression: Box<Expression>,
14926}
14927
14928/// SafeSubtract
14929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14930#[cfg_attr(feature = "bindings", derive(TS))]
14931pub struct SafeSubtract {
14932    pub this: Box<Expression>,
14933    pub expression: Box<Expression>,
14934}
14935
14936/// SHA2
14937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14938#[cfg_attr(feature = "bindings", derive(TS))]
14939pub struct SHA2 {
14940    pub this: Box<Expression>,
14941    #[serde(default)]
14942    pub length: Option<i64>,
14943}
14944
14945/// SHA2Digest
14946#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14947#[cfg_attr(feature = "bindings", derive(TS))]
14948pub struct SHA2Digest {
14949    pub this: Box<Expression>,
14950    #[serde(default)]
14951    pub length: Option<i64>,
14952}
14953
14954/// SortArray
14955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14956#[cfg_attr(feature = "bindings", derive(TS))]
14957pub struct SortArray {
14958    pub this: Box<Expression>,
14959    #[serde(default)]
14960    pub asc: Option<Box<Expression>>,
14961    #[serde(default)]
14962    pub nulls_first: Option<Box<Expression>>,
14963}
14964
14965/// SplitPart
14966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14967#[cfg_attr(feature = "bindings", derive(TS))]
14968pub struct SplitPart {
14969    pub this: Box<Expression>,
14970    #[serde(default)]
14971    pub delimiter: Option<Box<Expression>>,
14972    #[serde(default)]
14973    pub part_index: Option<Box<Expression>>,
14974}
14975
14976/// SUBSTRING_INDEX(str, delim, count)
14977#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14978#[cfg_attr(feature = "bindings", derive(TS))]
14979pub struct SubstringIndex {
14980    pub this: Box<Expression>,
14981    #[serde(default)]
14982    pub delimiter: Option<Box<Expression>>,
14983    #[serde(default)]
14984    pub count: Option<Box<Expression>>,
14985}
14986
14987/// StandardHash
14988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14989#[cfg_attr(feature = "bindings", derive(TS))]
14990pub struct StandardHash {
14991    pub this: Box<Expression>,
14992    #[serde(default)]
14993    pub expression: Option<Box<Expression>>,
14994}
14995
14996/// StrPosition
14997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14998#[cfg_attr(feature = "bindings", derive(TS))]
14999pub struct StrPosition {
15000    pub this: Box<Expression>,
15001    #[serde(default)]
15002    pub substr: Option<Box<Expression>>,
15003    #[serde(default)]
15004    pub position: Option<Box<Expression>>,
15005    #[serde(default)]
15006    pub occurrence: Option<Box<Expression>>,
15007}
15008
15009/// Search
15010#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15011#[cfg_attr(feature = "bindings", derive(TS))]
15012pub struct Search {
15013    pub this: Box<Expression>,
15014    pub expression: Box<Expression>,
15015    #[serde(default)]
15016    pub json_scope: Option<Box<Expression>>,
15017    #[serde(default)]
15018    pub analyzer: Option<Box<Expression>>,
15019    #[serde(default)]
15020    pub analyzer_options: Option<Box<Expression>>,
15021    #[serde(default)]
15022    pub search_mode: Option<Box<Expression>>,
15023}
15024
15025/// SearchIp
15026#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15027#[cfg_attr(feature = "bindings", derive(TS))]
15028pub struct SearchIp {
15029    pub this: Box<Expression>,
15030    pub expression: Box<Expression>,
15031}
15032
15033/// StrToDate
15034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15035#[cfg_attr(feature = "bindings", derive(TS))]
15036pub struct StrToDate {
15037    pub this: Box<Expression>,
15038    #[serde(default)]
15039    pub format: Option<String>,
15040    #[serde(default)]
15041    pub safe: Option<Box<Expression>>,
15042}
15043
15044/// StrToTime
15045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15046#[cfg_attr(feature = "bindings", derive(TS))]
15047pub struct StrToTime {
15048    pub this: Box<Expression>,
15049    pub format: String,
15050    #[serde(default)]
15051    pub zone: Option<Box<Expression>>,
15052    #[serde(default)]
15053    pub safe: Option<Box<Expression>>,
15054    #[serde(default)]
15055    pub target_type: Option<Box<Expression>>,
15056}
15057
15058/// StrToUnix
15059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15060#[cfg_attr(feature = "bindings", derive(TS))]
15061pub struct StrToUnix {
15062    #[serde(default)]
15063    pub this: Option<Box<Expression>>,
15064    #[serde(default)]
15065    pub format: Option<String>,
15066}
15067
15068/// StrToMap
15069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15070#[cfg_attr(feature = "bindings", derive(TS))]
15071pub struct StrToMap {
15072    pub this: Box<Expression>,
15073    #[serde(default)]
15074    pub pair_delim: Option<Box<Expression>>,
15075    #[serde(default)]
15076    pub key_value_delim: Option<Box<Expression>>,
15077    #[serde(default)]
15078    pub duplicate_resolution_callback: Option<Box<Expression>>,
15079}
15080
15081/// NumberToStr
15082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15083#[cfg_attr(feature = "bindings", derive(TS))]
15084pub struct NumberToStr {
15085    pub this: Box<Expression>,
15086    pub format: String,
15087    #[serde(default)]
15088    pub culture: Option<Box<Expression>>,
15089}
15090
15091/// FromBase
15092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15093#[cfg_attr(feature = "bindings", derive(TS))]
15094pub struct FromBase {
15095    pub this: Box<Expression>,
15096    pub expression: Box<Expression>,
15097}
15098
15099/// Stuff
15100#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15101#[cfg_attr(feature = "bindings", derive(TS))]
15102pub struct Stuff {
15103    pub this: Box<Expression>,
15104    #[serde(default)]
15105    pub start: Option<Box<Expression>>,
15106    #[serde(default)]
15107    pub length: Option<i64>,
15108    pub expression: Box<Expression>,
15109}
15110
15111/// TimeToStr
15112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15113#[cfg_attr(feature = "bindings", derive(TS))]
15114pub struct TimeToStr {
15115    pub this: Box<Expression>,
15116    pub format: String,
15117    #[serde(default)]
15118    pub culture: Option<Box<Expression>>,
15119    #[serde(default)]
15120    pub zone: Option<Box<Expression>>,
15121}
15122
15123/// TimeStrToTime
15124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15125#[cfg_attr(feature = "bindings", derive(TS))]
15126pub struct TimeStrToTime {
15127    pub this: Box<Expression>,
15128    #[serde(default)]
15129    pub zone: Option<Box<Expression>>,
15130}
15131
15132/// TsOrDsAdd
15133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15134#[cfg_attr(feature = "bindings", derive(TS))]
15135pub struct TsOrDsAdd {
15136    pub this: Box<Expression>,
15137    pub expression: Box<Expression>,
15138    #[serde(default)]
15139    pub unit: Option<String>,
15140    #[serde(default)]
15141    pub return_type: Option<Box<Expression>>,
15142}
15143
15144/// TsOrDsDiff
15145#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15146#[cfg_attr(feature = "bindings", derive(TS))]
15147pub struct TsOrDsDiff {
15148    pub this: Box<Expression>,
15149    pub expression: Box<Expression>,
15150    #[serde(default)]
15151    pub unit: Option<String>,
15152}
15153
15154/// TsOrDsToDate
15155#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15156#[cfg_attr(feature = "bindings", derive(TS))]
15157pub struct TsOrDsToDate {
15158    pub this: Box<Expression>,
15159    #[serde(default)]
15160    pub format: Option<String>,
15161    #[serde(default)]
15162    pub safe: Option<Box<Expression>>,
15163}
15164
15165/// TsOrDsToTime
15166#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15167#[cfg_attr(feature = "bindings", derive(TS))]
15168pub struct TsOrDsToTime {
15169    pub this: Box<Expression>,
15170    #[serde(default)]
15171    pub format: Option<String>,
15172    #[serde(default)]
15173    pub safe: Option<Box<Expression>>,
15174}
15175
15176/// Unhex
15177#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15178#[cfg_attr(feature = "bindings", derive(TS))]
15179pub struct Unhex {
15180    pub this: Box<Expression>,
15181    #[serde(default)]
15182    pub expression: Option<Box<Expression>>,
15183}
15184
15185/// Uniform
15186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15187#[cfg_attr(feature = "bindings", derive(TS))]
15188pub struct Uniform {
15189    pub this: Box<Expression>,
15190    pub expression: Box<Expression>,
15191    #[serde(default)]
15192    pub gen: Option<Box<Expression>>,
15193    #[serde(default)]
15194    pub seed: Option<Box<Expression>>,
15195}
15196
15197/// UnixToStr
15198#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15199#[cfg_attr(feature = "bindings", derive(TS))]
15200pub struct UnixToStr {
15201    pub this: Box<Expression>,
15202    #[serde(default)]
15203    pub format: Option<String>,
15204}
15205
15206/// UnixToTime
15207#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15208#[cfg_attr(feature = "bindings", derive(TS))]
15209pub struct UnixToTime {
15210    pub this: Box<Expression>,
15211    #[serde(default)]
15212    pub scale: Option<i64>,
15213    #[serde(default)]
15214    pub zone: Option<Box<Expression>>,
15215    #[serde(default)]
15216    pub hours: Option<Box<Expression>>,
15217    #[serde(default)]
15218    pub minutes: Option<Box<Expression>>,
15219    #[serde(default)]
15220    pub format: Option<String>,
15221    #[serde(default)]
15222    pub target_type: Option<Box<Expression>>,
15223}
15224
15225/// Uuid
15226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15227#[cfg_attr(feature = "bindings", derive(TS))]
15228pub struct Uuid {
15229    #[serde(default)]
15230    pub this: Option<Box<Expression>>,
15231    #[serde(default)]
15232    pub name: Option<String>,
15233    #[serde(default)]
15234    pub is_string: Option<Box<Expression>>,
15235}
15236
15237/// TimestampFromParts
15238#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15239#[cfg_attr(feature = "bindings", derive(TS))]
15240pub struct TimestampFromParts {
15241    #[serde(default)]
15242    pub zone: Option<Box<Expression>>,
15243    #[serde(default)]
15244    pub milli: Option<Box<Expression>>,
15245    #[serde(default)]
15246    pub this: Option<Box<Expression>>,
15247    #[serde(default)]
15248    pub expression: Option<Box<Expression>>,
15249}
15250
15251/// TimestampTzFromParts
15252#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15253#[cfg_attr(feature = "bindings", derive(TS))]
15254pub struct TimestampTzFromParts {
15255    #[serde(default)]
15256    pub zone: Option<Box<Expression>>,
15257}
15258
15259/// Corr
15260#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15261#[cfg_attr(feature = "bindings", derive(TS))]
15262pub struct Corr {
15263    pub this: Box<Expression>,
15264    pub expression: Box<Expression>,
15265    #[serde(default)]
15266    pub null_on_zero_variance: Option<Box<Expression>>,
15267}
15268
15269/// WidthBucket
15270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15271#[cfg_attr(feature = "bindings", derive(TS))]
15272pub struct WidthBucket {
15273    pub this: Box<Expression>,
15274    #[serde(default)]
15275    pub min_value: Option<Box<Expression>>,
15276    #[serde(default)]
15277    pub max_value: Option<Box<Expression>>,
15278    #[serde(default)]
15279    pub num_buckets: Option<Box<Expression>>,
15280    #[serde(default)]
15281    pub threshold: Option<Box<Expression>>,
15282}
15283
15284/// CovarSamp
15285#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15286#[cfg_attr(feature = "bindings", derive(TS))]
15287pub struct CovarSamp {
15288    pub this: Box<Expression>,
15289    pub expression: Box<Expression>,
15290}
15291
15292/// CovarPop
15293#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15294#[cfg_attr(feature = "bindings", derive(TS))]
15295pub struct CovarPop {
15296    pub this: Box<Expression>,
15297    pub expression: Box<Expression>,
15298}
15299
15300/// Week
15301#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15302#[cfg_attr(feature = "bindings", derive(TS))]
15303pub struct Week {
15304    pub this: Box<Expression>,
15305    #[serde(default)]
15306    pub mode: Option<Box<Expression>>,
15307}
15308
15309/// XMLElement
15310#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15311#[cfg_attr(feature = "bindings", derive(TS))]
15312pub struct XMLElement {
15313    pub this: Box<Expression>,
15314    #[serde(default)]
15315    pub expressions: Vec<Expression>,
15316    #[serde(default)]
15317    pub evalname: Option<Box<Expression>>,
15318}
15319
15320/// XMLGet
15321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15322#[cfg_attr(feature = "bindings", derive(TS))]
15323pub struct XMLGet {
15324    pub this: Box<Expression>,
15325    pub expression: Box<Expression>,
15326    #[serde(default)]
15327    pub instance: Option<Box<Expression>>,
15328}
15329
15330/// XMLTable
15331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15332#[cfg_attr(feature = "bindings", derive(TS))]
15333pub struct XMLTable {
15334    pub this: Box<Expression>,
15335    #[serde(default)]
15336    pub namespaces: Option<Box<Expression>>,
15337    #[serde(default)]
15338    pub passing: Option<Box<Expression>>,
15339    #[serde(default)]
15340    pub columns: Vec<Expression>,
15341    #[serde(default)]
15342    pub by_ref: Option<Box<Expression>>,
15343}
15344
15345/// XMLKeyValueOption
15346#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15347#[cfg_attr(feature = "bindings", derive(TS))]
15348pub struct XMLKeyValueOption {
15349    pub this: Box<Expression>,
15350    #[serde(default)]
15351    pub expression: Option<Box<Expression>>,
15352}
15353
15354/// Zipf
15355#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15356#[cfg_attr(feature = "bindings", derive(TS))]
15357pub struct Zipf {
15358    pub this: Box<Expression>,
15359    #[serde(default)]
15360    pub elementcount: Option<Box<Expression>>,
15361    #[serde(default)]
15362    pub gen: Option<Box<Expression>>,
15363}
15364
15365/// Merge
15366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15367#[cfg_attr(feature = "bindings", derive(TS))]
15368pub struct Merge {
15369    pub this: Box<Expression>,
15370    pub using: Box<Expression>,
15371    #[serde(default)]
15372    pub on: Option<Box<Expression>>,
15373    #[serde(default)]
15374    pub using_cond: Option<Box<Expression>>,
15375    #[serde(default)]
15376    pub whens: Option<Box<Expression>>,
15377    #[serde(default)]
15378    pub with_: Option<Box<Expression>>,
15379    #[serde(default)]
15380    pub returning: Option<Box<Expression>>,
15381}
15382
15383/// When
15384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15385#[cfg_attr(feature = "bindings", derive(TS))]
15386pub struct When {
15387    #[serde(default)]
15388    pub matched: Option<Box<Expression>>,
15389    #[serde(default)]
15390    pub source: Option<Box<Expression>>,
15391    #[serde(default)]
15392    pub condition: Option<Box<Expression>>,
15393    pub then: Box<Expression>,
15394}
15395
15396/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15397#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15398#[cfg_attr(feature = "bindings", derive(TS))]
15399pub struct Whens {
15400    #[serde(default)]
15401    pub expressions: Vec<Expression>,
15402}
15403
15404/// NextValueFor
15405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15406#[cfg_attr(feature = "bindings", derive(TS))]
15407pub struct NextValueFor {
15408    pub this: Box<Expression>,
15409    #[serde(default)]
15410    pub order: Option<Box<Expression>>,
15411}
15412
15413#[cfg(test)]
15414mod tests {
15415    use super::*;
15416
15417    #[test]
15418    fn test_source_spans_are_metadata_not_expression_identity() {
15419        let plain = Expression::column("customer_id");
15420        let mut positioned = plain.clone();
15421        if let Expression::Column(column) = &mut positioned {
15422            column.span = Some(Span::new(7, 18, 1, 19));
15423            column.name.span = column.span;
15424        }
15425        assert_eq!(plain, positioned);
15426        assert_ne!(
15427            serde_json::to_value(&plain).unwrap(),
15428            serde_json::to_value(&positioned).unwrap()
15429        );
15430        assert_eq!(
15431            Identifier::new("a"),
15432            Identifier::new("a").with_span(Span::new(3, 4, 1, 5))
15433        );
15434        assert_ne!(Identifier::new("a"), Identifier::quoted("a"));
15435        assert_ne!(plain, Expression::column("other"));
15436        let Expression::Column(column) = plain else {
15437            unreachable!()
15438        };
15439        assert!(column.span.is_none() && column.name.span.is_none());
15440    }
15441
15442    #[test]
15443    #[cfg(feature = "bindings")]
15444    fn export_typescript_types() {
15445        // This test exports TypeScript types to the generated directory
15446        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
15447        Expression::export_all(&ts_rs::Config::default())
15448            .expect("Failed to export Expression types");
15449
15450        let mut variant_names = String::from(
15451            "// This file was generated from the Rust Expression enum. Do not edit it manually.\n\n",
15452        );
15453        variant_names.push_str("export const EXPRESSION_VARIANT_NAMES = [\n");
15454        for name in Expression::SERIALIZED_VARIANT_NAMES {
15455            use std::fmt::Write;
15456            writeln!(variant_names, "  {name:?},").expect("writing to a String cannot fail");
15457        }
15458        variant_names.push_str("] as const;\n");
15459
15460        let output_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
15461            .join("bindings/ExpressionVariantNames.ts");
15462        std::fs::write(output_path, variant_names)
15463            .expect("Failed to export serialized Expression variant names");
15464    }
15465
15466    #[test]
15467    fn test_simple_select_builder() {
15468        let select = Select::new()
15469            .column(Expression::star())
15470            .from(Expression::Table(Box::new(TableRef::new("users"))));
15471
15472        assert_eq!(select.expressions.len(), 1);
15473        assert!(select.from.is_some());
15474    }
15475
15476    #[test]
15477    fn test_expression_alias() {
15478        let expr = Expression::column("id").alias("user_id");
15479
15480        match expr {
15481            Expression::Alias(a) => {
15482                assert_eq!(a.alias.name, "user_id");
15483            }
15484            _ => panic!("Expected Alias"),
15485        }
15486    }
15487
15488    #[test]
15489    fn test_literal_creation() {
15490        let num = Expression::number(42);
15491        let str = Expression::string("hello");
15492
15493        match num {
15494            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
15495                let Literal::Number(n) = lit.as_ref() else {
15496                    unreachable!()
15497                };
15498                assert_eq!(n, "42")
15499            }
15500            _ => panic!("Expected Number"),
15501        }
15502
15503        match str {
15504            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
15505                let Literal::String(s) = lit.as_ref() else {
15506                    unreachable!()
15507                };
15508                assert_eq!(s, "hello")
15509            }
15510            _ => panic!("Expected String"),
15511        }
15512    }
15513
15514    #[test]
15515    fn test_expression_sql() {
15516        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
15517        assert_eq!(expr.sql(), "SELECT 1 + 2");
15518    }
15519
15520    #[test]
15521    fn test_expression_sql_for() {
15522        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
15523        let sql = expr.sql_for(crate::DialectType::Generic);
15524        // Generic mode normalizes IF() to CASE WHEN
15525        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
15526    }
15527}