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    CreateIndex(Box<CreateIndex>),
551    DropIndex(Box<DropIndex>),
552    CreateView(Box<CreateView>),
553    DropView(Box<DropView>),
554    AlterView(Box<AlterView>),
555    AlterIndex(Box<AlterIndex>),
556    Truncate(Box<Truncate>),
557    Use(Box<Use>),
558    Cache(Box<Cache>),
559    Uncache(Box<Uncache>),
560    LoadData(Box<LoadData>),
561    Pragma(Box<Pragma>),
562    Grant(Box<Grant>),
563    Revoke(Box<Revoke>),
564    Comment(Box<Comment>),
565    SetStatement(Box<SetStatement>),
566    // Phase 4: Additional DDL statements
567    CreateSchema(Box<CreateSchema>),
568    DropSchema(Box<DropSchema>),
569    DropNamespace(Box<DropNamespace>),
570    CreateDatabase(Box<CreateDatabase>),
571    DropDatabase(Box<DropDatabase>),
572    CreateFunction(Box<CreateFunction>),
573    DropFunction(Box<DropFunction>),
574    CreateProcedure(Box<CreateProcedure>),
575    DropProcedure(Box<DropProcedure>),
576    CreateSequence(Box<CreateSequence>),
577    CreateSynonym(Box<CreateSynonym>),
578    DropSequence(Box<DropSequence>),
579    AlterSequence(Box<AlterSequence>),
580    CreateTrigger(Box<CreateTrigger>),
581    DropTrigger(Box<DropTrigger>),
582    CreateType(Box<CreateType>),
583    DropType(Box<DropType>),
584    Describe(Box<Describe>),
585    Show(Box<Show>),
586
587    // Transaction and other commands
588    Command(Box<Command>),
589    Kill(Box<Kill>),
590    /// PREPARE statement (PostgreSQL/generic prepared statement definition)
591    Prepare(Box<PrepareStatement>),
592    /// EXEC/EXECUTE statement (TSQL stored procedure call)
593    Execute(Box<ExecuteStatement>),
594
595    /// Snowflake CREATE TASK statement
596    CreateTask(Box<CreateTask>),
597
598    // Placeholder for unparsed/raw SQL
599    Raw(Raw),
600
601    // Paren for grouping
602    Paren(Box<Paren>),
603
604    // Expression with trailing comments (for round-trip preservation)
605    Annotated(Box<Annotated>),
606
607    // === BATCH GENERATED EXPRESSION TYPES ===
608    // Generated from Python sqlglot expressions.py
609    Refresh(Box<Refresh>),
610    LockingStatement(Box<LockingStatement>),
611    SequenceProperties(Box<SequenceProperties>),
612    TruncateTable(Box<TruncateTable>),
613    Clone(Box<Clone>),
614    Attach(Box<Attach>),
615    Detach(Box<Detach>),
616    Install(Box<Install>),
617    Summarize(Box<Summarize>),
618    Declare(Box<Declare>),
619    DeclareItem(Box<DeclareItem>),
620    Set(Box<Set>),
621    Heredoc(Box<Heredoc>),
622    SetItem(Box<SetItem>),
623    QueryBand(Box<QueryBand>),
624    UserDefinedFunction(Box<UserDefinedFunction>),
625    RecursiveWithSearch(Box<RecursiveWithSearch>),
626    ProjectionDef(Box<ProjectionDef>),
627    TableAlias(Box<TableAlias>),
628    ByteString(Box<ByteString>),
629    HexStringExpr(Box<HexStringExpr>),
630    UnicodeString(Box<UnicodeString>),
631    ColumnPosition(Box<ColumnPosition>),
632    ColumnDef(Box<ColumnDef>),
633    AlterColumn(Box<AlterColumn>),
634    AlterSortKey(Box<AlterSortKey>),
635    AlterSet(Box<AlterSet>),
636    RenameColumn(Box<RenameColumn>),
637    Comprehension(Box<Comprehension>),
638    MergeTreeTTLAction(Box<MergeTreeTTLAction>),
639    MergeTreeTTL(Box<MergeTreeTTL>),
640    IndexConstraintOption(Box<IndexConstraintOption>),
641    ColumnConstraint(Box<ColumnConstraint>),
642    PeriodForSystemTimeConstraint(Box<PeriodForSystemTimeConstraint>),
643    CaseSpecificColumnConstraint(Box<CaseSpecificColumnConstraint>),
644    CharacterSetColumnConstraint(Box<CharacterSetColumnConstraint>),
645    CheckColumnConstraint(Box<CheckColumnConstraint>),
646    AssumeColumnConstraint(Box<AssumeColumnConstraint>),
647    CompressColumnConstraint(Box<CompressColumnConstraint>),
648    DateFormatColumnConstraint(Box<DateFormatColumnConstraint>),
649    EphemeralColumnConstraint(Box<EphemeralColumnConstraint>),
650    WithOperator(Box<WithOperator>),
651    GeneratedAsIdentityColumnConstraint(Box<GeneratedAsIdentityColumnConstraint>),
652    AutoIncrementColumnConstraint(AutoIncrementColumnConstraint),
653    CommentColumnConstraint(CommentColumnConstraint),
654    GeneratedAsRowColumnConstraint(Box<GeneratedAsRowColumnConstraint>),
655    IndexColumnConstraint(Box<IndexColumnConstraint>),
656    MaskingPolicyColumnConstraint(Box<MaskingPolicyColumnConstraint>),
657    NotNullColumnConstraint(Box<NotNullColumnConstraint>),
658    PrimaryKeyColumnConstraint(Box<PrimaryKeyColumnConstraint>),
659    UniqueColumnConstraint(Box<UniqueColumnConstraint>),
660    WatermarkColumnConstraint(Box<WatermarkColumnConstraint>),
661    ComputedColumnConstraint(Box<ComputedColumnConstraint>),
662    InOutColumnConstraint(Box<InOutColumnConstraint>),
663    DefaultColumnConstraint(Box<DefaultColumnConstraint>),
664    PathColumnConstraint(Box<PathColumnConstraint>),
665    Constraint(Box<Constraint>),
666    Export(Box<Export>),
667    Filter(Box<Filter>),
668    Changes(Box<Changes>),
669    CopyParameter(Box<CopyParameter>),
670    Credentials(Box<Credentials>),
671    Directory(Box<Directory>),
672    ForeignKey(Box<ForeignKey>),
673    ColumnPrefix(Box<ColumnPrefix>),
674    PrimaryKey(Box<PrimaryKey>),
675    IntoClause(Box<IntoClause>),
676    JoinHint(Box<JoinHint>),
677    Opclass(Box<Opclass>),
678    Index(Box<Index>),
679    IndexParameters(Box<IndexParameters>),
680    ConditionalInsert(Box<ConditionalInsert>),
681    MultitableInserts(Box<MultitableInserts>),
682    OnConflict(Box<OnConflict>),
683    OnCondition(Box<OnCondition>),
684    Returning(Box<Returning>),
685    Introducer(Box<Introducer>),
686    PartitionRange(Box<PartitionRange>),
687    Fetch(Box<Fetch>),
688    Group(Box<Group>),
689    Cube(Box<Cube>),
690    Rollup(Box<Rollup>),
691    GroupingSets(Box<GroupingSets>),
692    LimitOptions(Box<LimitOptions>),
693    Lateral(Box<Lateral>),
694    TableFromRows(Box<TableFromRows>),
695    RowsFrom(Box<RowsFrom>),
696    MatchRecognizeMeasure(Box<MatchRecognizeMeasure>),
697    WithFill(Box<WithFill>),
698    Property(Box<Property>),
699    GrantPrivilege(Box<GrantPrivilege>),
700    GrantPrincipal(Box<GrantPrincipal>),
701    AllowedValuesProperty(Box<AllowedValuesProperty>),
702    AlgorithmProperty(Box<AlgorithmProperty>),
703    AutoIncrementProperty(Box<AutoIncrementProperty>),
704    AutoRefreshProperty(Box<AutoRefreshProperty>),
705    BackupProperty(Box<BackupProperty>),
706    BuildProperty(Box<BuildProperty>),
707    BlockCompressionProperty(Box<BlockCompressionProperty>),
708    CharacterSetProperty(Box<CharacterSetProperty>),
709    ChecksumProperty(Box<ChecksumProperty>),
710    CollateProperty(Box<CollateProperty>),
711    DataBlocksizeProperty(Box<DataBlocksizeProperty>),
712    DataDeletionProperty(Box<DataDeletionProperty>),
713    DefinerProperty(Box<DefinerProperty>),
714    DistKeyProperty(Box<DistKeyProperty>),
715    DistributedByProperty(Box<DistributedByProperty>),
716    DistStyleProperty(Box<DistStyleProperty>),
717    DuplicateKeyProperty(Box<DuplicateKeyProperty>),
718    EngineProperty(Box<EngineProperty>),
719    ToTableProperty(Box<ToTableProperty>),
720    ExecuteAsProperty(Box<ExecuteAsProperty>),
721    ExternalProperty(Box<ExternalProperty>),
722    FallbackProperty(Box<FallbackProperty>),
723    FileFormatProperty(Box<FileFormatProperty>),
724    CredentialsProperty(Box<CredentialsProperty>),
725    FreespaceProperty(Box<FreespaceProperty>),
726    InheritsProperty(Box<InheritsProperty>),
727    InputModelProperty(Box<InputModelProperty>),
728    OutputModelProperty(Box<OutputModelProperty>),
729    IsolatedLoadingProperty(Box<IsolatedLoadingProperty>),
730    JournalProperty(Box<JournalProperty>),
731    LanguageProperty(Box<LanguageProperty>),
732    EnviromentProperty(Box<EnviromentProperty>),
733    ClusteredByProperty(Box<ClusteredByProperty>),
734    DictProperty(Box<DictProperty>),
735    DictRange(Box<DictRange>),
736    OnCluster(Box<OnCluster>),
737    LikeProperty(Box<LikeProperty>),
738    LocationProperty(Box<LocationProperty>),
739    LockProperty(Box<LockProperty>),
740    LockingProperty(Box<LockingProperty>),
741    LogProperty(Box<LogProperty>),
742    MaterializedProperty(Box<MaterializedProperty>),
743    MergeBlockRatioProperty(Box<MergeBlockRatioProperty>),
744    OnProperty(Box<OnProperty>),
745    OnCommitProperty(Box<OnCommitProperty>),
746    PartitionedByProperty(Box<PartitionedByProperty>),
747    PartitionByProperty(Box<PartitionByProperty>),
748    PartitionedByBucket(Box<PartitionedByBucket>),
749    ClusterByColumnsProperty(Box<ClusterByColumnsProperty>),
750    PartitionByTruncate(Box<PartitionByTruncate>),
751    PartitionByRangeProperty(Box<PartitionByRangeProperty>),
752    PartitionByRangePropertyDynamic(Box<PartitionByRangePropertyDynamic>),
753    PartitionByListProperty(Box<PartitionByListProperty>),
754    PartitionList(Box<PartitionList>),
755    Partition(Box<Partition>),
756    RefreshTriggerProperty(Box<RefreshTriggerProperty>),
757    UniqueKeyProperty(Box<UniqueKeyProperty>),
758    RollupProperty(Box<RollupProperty>),
759    PartitionBoundSpec(Box<PartitionBoundSpec>),
760    PartitionedOfProperty(Box<PartitionedOfProperty>),
761    RemoteWithConnectionModelProperty(Box<RemoteWithConnectionModelProperty>),
762    ReturnsProperty(Box<ReturnsProperty>),
763    RowFormatProperty(Box<RowFormatProperty>),
764    RowFormatDelimitedProperty(Box<RowFormatDelimitedProperty>),
765    RowFormatSerdeProperty(Box<RowFormatSerdeProperty>),
766    QueryTransform(Box<QueryTransform>),
767    SampleProperty(Box<SampleProperty>),
768    SecurityProperty(Box<SecurityProperty>),
769    SchemaCommentProperty(Box<SchemaCommentProperty>),
770    SemanticView(Box<SemanticView>),
771    SerdeProperties(Box<SerdeProperties>),
772    SetProperty(Box<SetProperty>),
773    SharingProperty(Box<SharingProperty>),
774    SetConfigProperty(Box<SetConfigProperty>),
775    SettingsProperty(Box<SettingsProperty>),
776    SortKeyProperty(Box<SortKeyProperty>),
777    SqlReadWriteProperty(Box<SqlReadWriteProperty>),
778    SqlSecurityProperty(Box<SqlSecurityProperty>),
779    StabilityProperty(Box<StabilityProperty>),
780    StorageHandlerProperty(Box<StorageHandlerProperty>),
781    TemporaryProperty(Box<TemporaryProperty>),
782    Tags(Box<Tags>),
783    TransformModelProperty(Box<TransformModelProperty>),
784    TransientProperty(Box<TransientProperty>),
785    UsingTemplateProperty(Box<UsingTemplateProperty>),
786    ViewAttributeProperty(Box<ViewAttributeProperty>),
787    VolatileProperty(Box<VolatileProperty>),
788    WithDataProperty(Box<WithDataProperty>),
789    WithJournalTableProperty(Box<WithJournalTableProperty>),
790    WithSchemaBindingProperty(Box<WithSchemaBindingProperty>),
791    WithSystemVersioningProperty(Box<WithSystemVersioningProperty>),
792    WithProcedureOptions(Box<WithProcedureOptions>),
793    EncodeProperty(Box<EncodeProperty>),
794    IncludeProperty(Box<IncludeProperty>),
795    Properties(Box<Properties>),
796    OptionsProperty(Box<OptionsProperty>),
797    InputOutputFormat(Box<InputOutputFormat>),
798    Reference(Box<Reference>),
799    QueryOption(Box<QueryOption>),
800    WithTableHint(Box<WithTableHint>),
801    IndexTableHint(Box<IndexTableHint>),
802    HistoricalData(Box<HistoricalData>),
803    Get(Box<Get>),
804    SetOperation(Box<SetOperation>),
805    Var(Box<Var>),
806    Variadic(Box<Variadic>),
807    Version(Box<Version>),
808    Schema(Box<Schema>),
809    Lock(Box<Lock>),
810    TableSample(Box<TableSample>),
811    Tag(Box<Tag>),
812    UnpivotColumns(Box<UnpivotColumns>),
813    WindowSpec(Box<WindowSpec>),
814    SessionParameter(Box<SessionParameter>),
815    PseudoType(Box<PseudoType>),
816    ObjectIdentifier(Box<ObjectIdentifier>),
817    Transaction(Box<Transaction>),
818    Commit(Box<Commit>),
819    Rollback(Box<Rollback>),
820    AlterSession(Box<AlterSession>),
821    Analyze(Box<Analyze>),
822    AnalyzeStatistics(Box<AnalyzeStatistics>),
823    AnalyzeHistogram(Box<AnalyzeHistogram>),
824    AnalyzeSample(Box<AnalyzeSample>),
825    AnalyzeListChainedRows(Box<AnalyzeListChainedRows>),
826    AnalyzeDelete(Box<AnalyzeDelete>),
827    AnalyzeWith(Box<AnalyzeWith>),
828    AnalyzeValidate(Box<AnalyzeValidate>),
829    AddPartition(Box<AddPartition>),
830    AttachOption(Box<AttachOption>),
831    DropPartition(Box<DropPartition>),
832    ReplacePartition(Box<ReplacePartition>),
833    DPipe(Box<DPipe>),
834    Operator(Box<Operator>),
835    PivotAny(Box<PivotAny>),
836    Aliases(Box<Aliases>),
837    AtIndex(Box<AtIndex>),
838    FromTimeZone(Box<FromTimeZone>),
839    FormatPhrase(Box<FormatPhrase>),
840    ForIn(Box<ForIn>),
841    TimeUnit(Box<TimeUnit>),
842    IntervalOp(Box<IntervalOp>),
843    IntervalSpan(Box<IntervalSpan>),
844    HavingMax(Box<HavingMax>),
845    CosineDistance(Box<CosineDistance>),
846    DotProduct(Box<DotProduct>),
847    EuclideanDistance(Box<EuclideanDistance>),
848    ManhattanDistance(Box<ManhattanDistance>),
849    JarowinklerSimilarity(Box<JarowinklerSimilarity>),
850    Booland(Box<Booland>),
851    Boolor(Box<Boolor>),
852    ParameterizedAgg(Box<ParameterizedAgg>),
853    ArgMax(Box<ArgMax>),
854    ArgMin(Box<ArgMin>),
855    ApproxTopK(Box<ApproxTopK>),
856    ApproxTopKAccumulate(Box<ApproxTopKAccumulate>),
857    ApproxTopKCombine(Box<ApproxTopKCombine>),
858    ApproxTopKEstimate(Box<ApproxTopKEstimate>),
859    ApproxTopSum(Box<ApproxTopSum>),
860    ApproxQuantiles(Box<ApproxQuantiles>),
861    Minhash(Box<Minhash>),
862    FarmFingerprint(Box<FarmFingerprint>),
863    Float64(Box<Float64>),
864    Transform(Box<Transform>),
865    Translate(Box<Translate>),
866    Grouping(Box<Grouping>),
867    GroupingId(Box<GroupingId>),
868    Anonymous(Box<Anonymous>),
869    AnonymousAggFunc(Box<AnonymousAggFunc>),
870    CombinedAggFunc(Box<CombinedAggFunc>),
871    CombinedParameterizedAgg(Box<CombinedParameterizedAgg>),
872    HashAgg(Box<HashAgg>),
873    Hll(Box<Hll>),
874    Apply(Box<Apply>),
875    ToBoolean(Box<ToBoolean>),
876    List(Box<List>),
877    ToMap(Box<ToMap>),
878    Pad(Box<Pad>),
879    ToChar(Box<ToChar>),
880    ToNumber(Box<ToNumber>),
881    ToDouble(Box<ToDouble>),
882    Int64(Box<UnaryFunc>),
883    StringFunc(Box<StringFunc>),
884    ToDecfloat(Box<ToDecfloat>),
885    TryToDecfloat(Box<TryToDecfloat>),
886    ToFile(Box<ToFile>),
887    Columns(Box<Columns>),
888    ConvertToCharset(Box<ConvertToCharset>),
889    ConvertTimezone(Box<ConvertTimezone>),
890    GenerateSeries(Box<GenerateSeries>),
891    AIAgg(Box<AIAgg>),
892    AIClassify(Box<AIClassify>),
893    ArrayAll(Box<ArrayAll>),
894    ArrayAny(Box<ArrayAny>),
895    ArrayConstructCompact(Box<ArrayConstructCompact>),
896    StPoint(Box<StPoint>),
897    StDistance(Box<StDistance>),
898    StringToArray(Box<StringToArray>),
899    ArraySum(Box<ArraySum>),
900    ObjectAgg(Box<ObjectAgg>),
901    CastToStrType(Box<CastToStrType>),
902    CheckJson(Box<CheckJson>),
903    CheckXml(Box<CheckXml>),
904    TranslateCharacters(Box<TranslateCharacters>),
905    CurrentSchemas(Box<CurrentSchemas>),
906    CurrentDatetime(Box<CurrentDatetime>),
907    Localtime(Box<Localtime>),
908    Localtimestamp(Box<Localtimestamp>),
909    Systimestamp(Box<Systimestamp>),
910    CurrentSchema(Box<CurrentSchema>),
911    CurrentUser(Box<CurrentUser>),
912    UtcTime(Box<UtcTime>),
913    UtcTimestamp(Box<UtcTimestamp>),
914    Timestamp(Box<TimestampFunc>),
915    DateBin(Box<DateBin>),
916    Datetime(Box<Datetime>),
917    DatetimeAdd(Box<DatetimeAdd>),
918    DatetimeSub(Box<DatetimeSub>),
919    DatetimeDiff(Box<DatetimeDiff>),
920    DatetimeTrunc(Box<DatetimeTrunc>),
921    Dayname(Box<Dayname>),
922    MakeInterval(Box<MakeInterval>),
923    PreviousDay(Box<PreviousDay>),
924    Elt(Box<Elt>),
925    TimestampAdd(Box<TimestampAdd>),
926    TimestampSub(Box<TimestampSub>),
927    TimestampDiff(Box<TimestampDiff>),
928    TimeSlice(Box<TimeSlice>),
929    TimeAdd(Box<TimeAdd>),
930    TimeSub(Box<TimeSub>),
931    TimeDiff(Box<TimeDiff>),
932    TimeTrunc(Box<TimeTrunc>),
933    DateFromParts(Box<DateFromParts>),
934    TimeFromParts(Box<TimeFromParts>),
935    DecodeCase(Box<DecodeCase>),
936    Decrypt(Box<Decrypt>),
937    DecryptRaw(Box<DecryptRaw>),
938    Encode(Box<Encode>),
939    Encrypt(Box<Encrypt>),
940    EncryptRaw(Box<EncryptRaw>),
941    EqualNull(Box<EqualNull>),
942    ToBinary(Box<ToBinary>),
943    Base64DecodeBinary(Box<Base64DecodeBinary>),
944    Base64DecodeString(Box<Base64DecodeString>),
945    Base64Encode(Box<Base64Encode>),
946    TryBase64DecodeBinary(Box<TryBase64DecodeBinary>),
947    TryBase64DecodeString(Box<TryBase64DecodeString>),
948    GapFill(Box<GapFill>),
949    GenerateDateArray(Box<GenerateDateArray>),
950    GenerateTimestampArray(Box<GenerateTimestampArray>),
951    GetExtract(Box<GetExtract>),
952    Getbit(Box<Getbit>),
953    OverflowTruncateBehavior(Box<OverflowTruncateBehavior>),
954    HexEncode(Box<HexEncode>),
955    Compress(Box<Compress>),
956    DecompressBinary(Box<DecompressBinary>),
957    DecompressString(Box<DecompressString>),
958    Xor(Box<Xor>),
959    Nullif(Box<Nullif>),
960    JSON(Box<JSON>),
961    JSONPath(Box<JSONPath>),
962    JSONPathFilter(Box<JSONPathFilter>),
963    JSONPathKey(Box<JSONPathKey>),
964    JSONPathRecursive(Box<JSONPathRecursive>),
965    JSONPathScript(Box<JSONPathScript>),
966    JSONPathSlice(Box<JSONPathSlice>),
967    JSONPathSelector(Box<JSONPathSelector>),
968    JSONPathSubscript(Box<JSONPathSubscript>),
969    JSONPathUnion(Box<JSONPathUnion>),
970    Format(Box<Format>),
971    JSONKeys(Box<JSONKeys>),
972    JSONKeyValue(Box<JSONKeyValue>),
973    JSONKeysAtDepth(Box<JSONKeysAtDepth>),
974    JSONObject(Box<JSONObject>),
975    JSONObjectAgg(Box<JSONObjectAgg>),
976    JSONBObjectAgg(Box<JSONBObjectAgg>),
977    JSONArray(Box<JSONArray>),
978    JSONArrayAgg(Box<JSONArrayAgg>),
979    JSONExists(Box<JSONExists>),
980    JSONColumnDef(Box<JSONColumnDef>),
981    JSONSchema(Box<JSONSchema>),
982    JSONSet(Box<JSONSet>),
983    JSONStripNulls(Box<JSONStripNulls>),
984    JSONValue(Box<JSONValue>),
985    JSONValueArray(Box<JSONValueArray>),
986    JSONRemove(Box<JSONRemove>),
987    JSONTable(Box<JSONTable>),
988    JSONType(Box<JSONType>),
989    ObjectInsert(Box<ObjectInsert>),
990    OpenJSONColumnDef(Box<OpenJSONColumnDef>),
991    OpenJSON(Box<OpenJSON>),
992    JSONBExists(Box<JSONBExists>),
993    JSONBContains(Box<BinaryFunc>),
994    JSONBExtract(Box<BinaryFunc>),
995    JSONCast(Box<JSONCast>),
996    JSONExtract(Box<JSONExtract>),
997    JSONExtractQuote(Box<JSONExtractQuote>),
998    JSONExtractArray(Box<JSONExtractArray>),
999    JSONExtractScalar(Box<JSONExtractScalar>),
1000    JSONBExtractScalar(Box<JSONBExtractScalar>),
1001    JSONFormat(Box<JSONFormat>),
1002    JSONBool(Box<UnaryFunc>),
1003    JSONPathRoot(JSONPathRoot),
1004    JSONArrayAppend(Box<JSONArrayAppend>),
1005    JSONArrayContains(Box<JSONArrayContains>),
1006    JSONArrayInsert(Box<JSONArrayInsert>),
1007    ParseJSON(Box<ParseJSON>),
1008    ParseUrl(Box<ParseUrl>),
1009    ParseIp(Box<ParseIp>),
1010    ParseTime(Box<ParseTime>),
1011    ParseDatetime(Box<ParseDatetime>),
1012    Map(Box<Map>),
1013    MapCat(Box<MapCat>),
1014    MapDelete(Box<MapDelete>),
1015    MapInsert(Box<MapInsert>),
1016    MapPick(Box<MapPick>),
1017    ScopeResolution(Box<ScopeResolution>),
1018    Slice(Box<Slice>),
1019    VarMap(Box<VarMap>),
1020    MatchAgainst(Box<MatchAgainst>),
1021    MD5Digest(Box<MD5Digest>),
1022    MD5NumberLower64(Box<UnaryFunc>),
1023    MD5NumberUpper64(Box<UnaryFunc>),
1024    Monthname(Box<Monthname>),
1025    Ntile(Box<Ntile>),
1026    Normalize(Box<Normalize>),
1027    Normal(Box<Normal>),
1028    Predict(Box<Predict>),
1029    MLTranslate(Box<MLTranslate>),
1030    FeaturesAtTime(Box<FeaturesAtTime>),
1031    GenerateEmbedding(Box<GenerateEmbedding>),
1032    MLForecast(Box<MLForecast>),
1033    ModelAttribute(Box<ModelAttribute>),
1034    VectorSearch(Box<VectorSearch>),
1035    Quantile(Box<Quantile>),
1036    ApproxQuantile(Box<ApproxQuantile>),
1037    ApproxPercentileEstimate(Box<ApproxPercentileEstimate>),
1038    Randn(Box<Randn>),
1039    Randstr(Box<Randstr>),
1040    RangeN(Box<RangeN>),
1041    RangeBucket(Box<RangeBucket>),
1042    ReadCSV(Box<ReadCSV>),
1043    ReadParquet(Box<ReadParquet>),
1044    Reduce(Box<Reduce>),
1045    RegexpExtractAll(Box<RegexpExtractAll>),
1046    RegexpILike(Box<RegexpILike>),
1047    RegexpFullMatch(Box<RegexpFullMatch>),
1048    RegexpInstr(Box<RegexpInstr>),
1049    RegexpSplit(Box<RegexpSplit>),
1050    RegexpCount(Box<RegexpCount>),
1051    RegrValx(Box<RegrValx>),
1052    RegrValy(Box<RegrValy>),
1053    RegrAvgy(Box<RegrAvgy>),
1054    RegrAvgx(Box<RegrAvgx>),
1055    RegrCount(Box<RegrCount>),
1056    RegrIntercept(Box<RegrIntercept>),
1057    RegrR2(Box<RegrR2>),
1058    RegrSxx(Box<RegrSxx>),
1059    RegrSxy(Box<RegrSxy>),
1060    RegrSyy(Box<RegrSyy>),
1061    RegrSlope(Box<RegrSlope>),
1062    SafeAdd(Box<SafeAdd>),
1063    SafeDivide(Box<SafeDivide>),
1064    SafeMultiply(Box<SafeMultiply>),
1065    SafeSubtract(Box<SafeSubtract>),
1066    SHA2(Box<SHA2>),
1067    SHA2Digest(Box<SHA2Digest>),
1068    SortArray(Box<SortArray>),
1069    SplitPart(Box<SplitPart>),
1070    SubstringIndex(Box<SubstringIndex>),
1071    StandardHash(Box<StandardHash>),
1072    StrPosition(Box<StrPosition>),
1073    Search(Box<Search>),
1074    SearchIp(Box<SearchIp>),
1075    StrToDate(Box<StrToDate>),
1076    DateStrToDate(Box<UnaryFunc>),
1077    DateToDateStr(Box<UnaryFunc>),
1078    StrToTime(Box<StrToTime>),
1079    StrToUnix(Box<StrToUnix>),
1080    StrToMap(Box<StrToMap>),
1081    NumberToStr(Box<NumberToStr>),
1082    FromBase(Box<FromBase>),
1083    Stuff(Box<Stuff>),
1084    TimeToStr(Box<TimeToStr>),
1085    TimeStrToTime(Box<TimeStrToTime>),
1086    TsOrDsAdd(Box<TsOrDsAdd>),
1087    TsOrDsDiff(Box<TsOrDsDiff>),
1088    TsOrDsToDate(Box<TsOrDsToDate>),
1089    TsOrDsToTime(Box<TsOrDsToTime>),
1090    Unhex(Box<Unhex>),
1091    Uniform(Box<Uniform>),
1092    UnixToStr(Box<UnixToStr>),
1093    UnixToTime(Box<UnixToTime>),
1094    Uuid(Box<Uuid>),
1095    TimestampFromParts(Box<TimestampFromParts>),
1096    TimestampTzFromParts(Box<TimestampTzFromParts>),
1097    Corr(Box<Corr>),
1098    WidthBucket(Box<WidthBucket>),
1099    CovarSamp(Box<CovarSamp>),
1100    CovarPop(Box<CovarPop>),
1101    Week(Box<Week>),
1102    XMLElement(Box<XMLElement>),
1103    XMLGet(Box<XMLGet>),
1104    XMLTable(Box<XMLTable>),
1105    XMLKeyValueOption(Box<XMLKeyValueOption>),
1106    Zipf(Box<Zipf>),
1107    Merge(Box<Merge>),
1108    When(Box<When>),
1109    Whens(Box<Whens>),
1110    NextValueFor(Box<NextValueFor>),
1111    /// RETURN statement (DuckDB stored procedures)
1112    ReturnStmt(Box<Expression>),
1113}
1114
1115impl Expression {
1116    /// Create a `Column` variant, boxing the value automatically.
1117    #[inline]
1118    pub fn boxed_column(col: Column) -> Self {
1119        Expression::Column(Box::new(col))
1120    }
1121
1122    /// Create a `Table` variant, boxing the value automatically.
1123    #[inline]
1124    pub fn boxed_table(t: TableRef) -> Self {
1125        Expression::Table(Box::new(t))
1126    }
1127
1128    /// Returns `true` if this expression is a valid top-level SQL statement.
1129    ///
1130    /// Bare expressions like identifiers, literals, and function calls are not
1131    /// valid statements. This is used by `validate()` to reject inputs like
1132    /// `SELECT scooby dooby doo` which the parser splits into `SELECT scooby AS dooby`
1133    /// plus the bare identifier `doo`.
1134    pub fn is_statement(&self) -> bool {
1135        match self {
1136            // Queries
1137            Expression::Select(_)
1138            | Expression::Union(_)
1139            | Expression::Intersect(_)
1140            | Expression::Except(_)
1141            | Expression::Subquery(_)
1142            | Expression::Values(_)
1143            | Expression::PipeOperator(_)
1144
1145            // DML
1146            | Expression::Insert(_)
1147            | Expression::Update(_)
1148            | Expression::Delete(_)
1149            | Expression::Copy(_)
1150            | Expression::Put(_)
1151            | Expression::Merge(_)
1152            | Expression::TryCatch(_)
1153
1154            // DDL
1155            | Expression::CreateTable(_)
1156            | Expression::DropTable(_)
1157            | Expression::Undrop(_)
1158            | Expression::AlterTable(_)
1159            | Expression::CreateIndex(_)
1160            | Expression::DropIndex(_)
1161            | Expression::CreateView(_)
1162            | Expression::DropView(_)
1163            | Expression::AlterView(_)
1164            | Expression::AlterIndex(_)
1165            | Expression::Truncate(_)
1166            | Expression::TruncateTable(_)
1167            | Expression::CreateSchema(_)
1168            | Expression::DropSchema(_)
1169            | Expression::DropNamespace(_)
1170            | Expression::CreateDatabase(_)
1171            | Expression::DropDatabase(_)
1172            | Expression::CreateFunction(_)
1173            | Expression::DropFunction(_)
1174            | Expression::CreateProcedure(_)
1175            | Expression::DropProcedure(_)
1176            | Expression::CreateSequence(_)
1177            | Expression::CreateSynonym(_)
1178            | Expression::DropSequence(_)
1179            | Expression::AlterSequence(_)
1180            | Expression::CreateTrigger(_)
1181            | Expression::DropTrigger(_)
1182            | Expression::CreateType(_)
1183            | Expression::DropType(_)
1184            | Expression::Comment(_)
1185
1186            // Session/Transaction/Control
1187            | Expression::Use(_)
1188            | Expression::Set(_)
1189            | Expression::SetStatement(_)
1190            | Expression::Transaction(_)
1191            | Expression::Commit(_)
1192            | Expression::Rollback(_)
1193            | Expression::Grant(_)
1194            | Expression::Revoke(_)
1195            | Expression::Cache(_)
1196            | Expression::Uncache(_)
1197            | Expression::LoadData(_)
1198            | Expression::Pragma(_)
1199            | Expression::Describe(_)
1200            | Expression::Show(_)
1201            | Expression::Kill(_)
1202            | Expression::Prepare(_)
1203            | Expression::Execute(_)
1204            | Expression::Declare(_)
1205            | Expression::Refresh(_)
1206            | Expression::AlterSession(_)
1207            | Expression::LockingStatement(_)
1208
1209            // Analyze
1210            | Expression::Analyze(_)
1211            | Expression::AnalyzeStatistics(_)
1212            | Expression::AnalyzeHistogram(_)
1213            | Expression::AnalyzeSample(_)
1214            | Expression::AnalyzeListChainedRows(_)
1215            | Expression::AnalyzeDelete(_)
1216
1217            // Attach/Detach/Install/Summarize
1218            | Expression::Attach(_)
1219            | Expression::Detach(_)
1220            | Expression::Install(_)
1221            | Expression::Summarize(_)
1222
1223            // Pivot at statement level
1224            | Expression::Pivot(_)
1225            | Expression::Unpivot(_)
1226
1227            // Command (raw/unparsed statements)
1228            | Expression::Command(_)
1229            | Expression::Raw(_)
1230            | Expression::CreateTask(_)
1231
1232            // Return statement
1233            | Expression::ReturnStmt(_) => true,
1234
1235            // Annotated wraps another expression with comments — check inner
1236            Expression::Annotated(a) => a.this.is_statement(),
1237
1238            // Alias at top level can wrap a statement (e.g., parenthesized subquery with alias)
1239            Expression::Alias(a) => a.this.is_statement(),
1240
1241            // Everything else (identifiers, literals, operators, functions, etc.)
1242            _ => false,
1243        }
1244    }
1245
1246    /// Create a literal number expression from an integer.
1247    pub fn number(n: i64) -> Self {
1248        Expression::Literal(Box::new(Literal::Number(n.to_string())))
1249    }
1250
1251    /// Create a single-quoted literal string expression.
1252    pub fn string(s: impl Into<String>) -> Self {
1253        Expression::Literal(Box::new(Literal::String(s.into())))
1254    }
1255
1256    /// Create a literal number expression from a float.
1257    pub fn float(f: f64) -> Self {
1258        Expression::Literal(Box::new(Literal::Number(f.to_string())))
1259    }
1260
1261    /// Get the inferred type annotation, if present.
1262    ///
1263    /// For value-producing expressions with an `inferred_type` field, returns
1264    /// the stored type. For literals and boolean constants, computes the type
1265    /// on the fly from the variant. For DDL/clause expressions, returns `None`.
1266    pub fn inferred_type(&self) -> Option<&DataType> {
1267        match self {
1268            // Structs with inferred_type field
1269            Expression::And(op)
1270            | Expression::Or(op)
1271            | Expression::Add(op)
1272            | Expression::Sub(op)
1273            | Expression::Mul(op)
1274            | Expression::Div(op)
1275            | Expression::Mod(op)
1276            | Expression::Eq(op)
1277            | Expression::Neq(op)
1278            | Expression::Lt(op)
1279            | Expression::Lte(op)
1280            | Expression::Gt(op)
1281            | Expression::Gte(op)
1282            | Expression::Concat(op)
1283            | Expression::BitwiseAnd(op)
1284            | Expression::BitwiseOr(op)
1285            | Expression::BitwiseXor(op)
1286            | Expression::Adjacent(op)
1287            | Expression::TsMatch(op)
1288            | Expression::PropertyEQ(op)
1289            | Expression::ArrayContainsAll(op)
1290            | Expression::ArrayContainedBy(op)
1291            | Expression::ArrayOverlaps(op)
1292            | Expression::JSONBContainsAllTopKeys(op)
1293            | Expression::JSONBContainsAnyTopKeys(op)
1294            | Expression::JSONBDeleteAtPath(op)
1295            | Expression::ExtendsLeft(op)
1296            | Expression::ExtendsRight(op)
1297            | Expression::Is(op)
1298            | Expression::MemberOf(op)
1299            | Expression::Match(op)
1300            | Expression::NullSafeEq(op)
1301            | Expression::NullSafeNeq(op)
1302            | Expression::Glob(op)
1303            | Expression::BitwiseLeftShift(op)
1304            | Expression::BitwiseRightShift(op) => op.inferred_type.as_ref(),
1305
1306            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1307                op.inferred_type.as_ref()
1308            }
1309
1310            Expression::Like(op) | Expression::ILike(op) => op.inferred_type.as_ref(),
1311
1312            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1313                c.inferred_type.as_ref()
1314            }
1315
1316            Expression::Column(c) => c.inferred_type.as_ref(),
1317            Expression::Function(f) => f.inferred_type.as_ref(),
1318            Expression::AggregateFunction(f) => f.inferred_type.as_ref(),
1319            Expression::WindowFunction(f) => f.inferred_type.as_ref(),
1320            Expression::Case(c) => c.inferred_type.as_ref(),
1321            Expression::Subquery(s) => s.inferred_type.as_ref(),
1322            Expression::Alias(a) => a.inferred_type.as_ref(),
1323            Expression::IfFunc(f) => f.inferred_type.as_ref(),
1324            Expression::Nvl2(f) => f.inferred_type.as_ref(),
1325            Expression::Count(f) => f.inferred_type.as_ref(),
1326            Expression::GroupConcat(f) => f.inferred_type.as_ref(),
1327            Expression::StringAgg(f) => f.inferred_type.as_ref(),
1328            Expression::ListAgg(f) => f.inferred_type.as_ref(),
1329            Expression::SumIf(f) => f.inferred_type.as_ref(),
1330
1331            // UnaryFunc variants
1332            Expression::Upper(f)
1333            | Expression::Lower(f)
1334            | Expression::Length(f)
1335            | Expression::LTrim(f)
1336            | Expression::RTrim(f)
1337            | Expression::Reverse(f)
1338            | Expression::Abs(f)
1339            | Expression::Sqrt(f)
1340            | Expression::Cbrt(f)
1341            | Expression::Ln(f)
1342            | Expression::Exp(f)
1343            | Expression::Sign(f)
1344            | Expression::Date(f)
1345            | Expression::Time(f)
1346            | Expression::Initcap(f)
1347            | Expression::Ascii(f)
1348            | Expression::Chr(f)
1349            | Expression::Soundex(f)
1350            | Expression::ByteLength(f)
1351            | Expression::Hex(f)
1352            | Expression::LowerHex(f)
1353            | Expression::Unicode(f)
1354            | Expression::Typeof(f)
1355            | Expression::Explode(f)
1356            | Expression::ExplodeOuter(f)
1357            | Expression::MapFromEntries(f)
1358            | Expression::MapKeys(f)
1359            | Expression::MapValues(f)
1360            | Expression::ArrayLength(f)
1361            | Expression::ArraySize(f)
1362            | Expression::Cardinality(f)
1363            | Expression::ArrayReverse(f)
1364            | Expression::ArrayDistinct(f)
1365            | Expression::ArrayFlatten(f)
1366            | Expression::ArrayCompact(f)
1367            | Expression::ToArray(f)
1368            | Expression::JsonArrayLength(f)
1369            | Expression::JsonKeys(f)
1370            | Expression::JsonType(f)
1371            | Expression::ParseJson(f)
1372            | Expression::ToJson(f)
1373            | Expression::Radians(f)
1374            | Expression::Degrees(f)
1375            | Expression::Sin(f)
1376            | Expression::Cos(f)
1377            | Expression::Tan(f)
1378            | Expression::Asin(f)
1379            | Expression::Acos(f)
1380            | Expression::Atan(f)
1381            | Expression::IsNan(f)
1382            | Expression::IsInf(f)
1383            | Expression::Year(f)
1384            | Expression::Month(f)
1385            | Expression::Day(f)
1386            | Expression::Hour(f)
1387            | Expression::Minute(f)
1388            | Expression::Second(f)
1389            | Expression::DayOfWeek(f)
1390            | Expression::DayOfWeekIso(f)
1391            | Expression::DayOfMonth(f)
1392            | Expression::DayOfYear(f)
1393            | Expression::WeekOfYear(f)
1394            | Expression::Quarter(f)
1395            | Expression::Epoch(f)
1396            | Expression::EpochMs(f)
1397            | Expression::BitwiseCount(f)
1398            | Expression::DateFromUnixDate(f)
1399            | Expression::UnixDate(f)
1400            | Expression::UnixSeconds(f)
1401            | Expression::UnixMillis(f)
1402            | Expression::UnixMicros(f)
1403            | Expression::TimeStrToDate(f)
1404            | Expression::DateToDi(f)
1405            | Expression::DiToDate(f)
1406            | Expression::TsOrDiToDi(f)
1407            | Expression::TsOrDsToDatetime(f)
1408            | Expression::TsOrDsToTimestamp(f)
1409            | Expression::YearOfWeek(f)
1410            | Expression::YearOfWeekIso(f)
1411            | Expression::SHA(f)
1412            | Expression::SHA1Digest(f)
1413            | Expression::TimeToUnix(f)
1414            | Expression::TimeStrToUnix(f) => f.inferred_type.as_ref(),
1415
1416            // BinaryFunc variants
1417            Expression::Power(f)
1418            | Expression::NullIf(f)
1419            | Expression::IfNull(f)
1420            | Expression::Nvl(f)
1421            | Expression::Contains(f)
1422            | Expression::StartsWith(f)
1423            | Expression::EndsWith(f)
1424            | Expression::Levenshtein(f)
1425            | Expression::ModFunc(f)
1426            | Expression::IntDiv(f)
1427            | Expression::Atan2(f)
1428            | Expression::AddMonths(f)
1429            | Expression::MonthsBetween(f)
1430            | Expression::NextDay(f)
1431            | Expression::UnixToTimeStr(f)
1432            | Expression::ArrayContains(f)
1433            | Expression::ArrayPosition(f)
1434            | Expression::ArrayAppend(f)
1435            | Expression::ArrayPrepend(f)
1436            | Expression::ArrayUnion(f)
1437            | Expression::ArrayExcept(f)
1438            | Expression::ArrayRemove(f)
1439            | Expression::StarMap(f)
1440            | Expression::MapFromArrays(f)
1441            | Expression::MapContainsKey(f)
1442            | Expression::ElementAt(f)
1443            | Expression::JsonMergePatch(f) => f.inferred_type.as_ref(),
1444
1445            // VarArgFunc variants
1446            Expression::Coalesce(f)
1447            | Expression::Greatest(f)
1448            | Expression::Least(f)
1449            | Expression::ArrayConcat(f)
1450            | Expression::ArrayIntersect(f)
1451            | Expression::ArrayZip(f)
1452            | Expression::MapConcat(f)
1453            | Expression::JsonArray(f) => f.inferred_type.as_ref(),
1454
1455            // AggFunc variants
1456            Expression::Sum(f)
1457            | Expression::Avg(f)
1458            | Expression::Min(f)
1459            | Expression::Max(f)
1460            | Expression::ArrayAgg(f)
1461            | Expression::CountIf(f)
1462            | Expression::Stddev(f)
1463            | Expression::StddevPop(f)
1464            | Expression::StddevSamp(f)
1465            | Expression::Variance(f)
1466            | Expression::VarPop(f)
1467            | Expression::VarSamp(f)
1468            | Expression::Median(f)
1469            | Expression::Mode(f)
1470            | Expression::First(f)
1471            | Expression::Last(f)
1472            | Expression::AnyValue(f)
1473            | Expression::ApproxDistinct(f)
1474            | Expression::ApproxCountDistinct(f)
1475            | Expression::LogicalAnd(f)
1476            | Expression::LogicalOr(f)
1477            | Expression::Skewness(f)
1478            | Expression::ArrayConcatAgg(f)
1479            | Expression::ArrayUniqueAgg(f)
1480            | Expression::BoolXorAgg(f)
1481            | Expression::BitwiseAndAgg(f)
1482            | Expression::BitwiseOrAgg(f)
1483            | Expression::BitwiseXorAgg(f) => f.inferred_type.as_ref(),
1484
1485            // Everything else: no inferred_type field
1486            _ => None,
1487        }
1488    }
1489
1490    /// Set the inferred type annotation on this expression.
1491    ///
1492    /// Only has an effect on value-producing expressions with an `inferred_type`
1493    /// field. For other expression types, this is a no-op.
1494    pub fn set_inferred_type(&mut self, dt: DataType) {
1495        match self {
1496            Expression::And(op)
1497            | Expression::Or(op)
1498            | Expression::Add(op)
1499            | Expression::Sub(op)
1500            | Expression::Mul(op)
1501            | Expression::Div(op)
1502            | Expression::Mod(op)
1503            | Expression::Eq(op)
1504            | Expression::Neq(op)
1505            | Expression::Lt(op)
1506            | Expression::Lte(op)
1507            | Expression::Gt(op)
1508            | Expression::Gte(op)
1509            | Expression::Concat(op)
1510            | Expression::BitwiseAnd(op)
1511            | Expression::BitwiseOr(op)
1512            | Expression::BitwiseXor(op)
1513            | Expression::Adjacent(op)
1514            | Expression::TsMatch(op)
1515            | Expression::PropertyEQ(op)
1516            | Expression::ArrayContainsAll(op)
1517            | Expression::ArrayContainedBy(op)
1518            | Expression::ArrayOverlaps(op)
1519            | Expression::JSONBContainsAllTopKeys(op)
1520            | Expression::JSONBContainsAnyTopKeys(op)
1521            | Expression::JSONBDeleteAtPath(op)
1522            | Expression::ExtendsLeft(op)
1523            | Expression::ExtendsRight(op)
1524            | Expression::Is(op)
1525            | Expression::MemberOf(op)
1526            | Expression::Match(op)
1527            | Expression::NullSafeEq(op)
1528            | Expression::NullSafeNeq(op)
1529            | Expression::Glob(op)
1530            | Expression::BitwiseLeftShift(op)
1531            | Expression::BitwiseRightShift(op) => op.inferred_type = Some(dt),
1532
1533            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1534                op.inferred_type = Some(dt)
1535            }
1536
1537            Expression::Like(op) | Expression::ILike(op) => op.inferred_type = Some(dt),
1538
1539            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1540                c.inferred_type = Some(dt)
1541            }
1542
1543            Expression::Column(c) => c.inferred_type = Some(dt),
1544            Expression::Function(f) => f.inferred_type = Some(dt),
1545            Expression::AggregateFunction(f) => f.inferred_type = Some(dt),
1546            Expression::WindowFunction(f) => f.inferred_type = Some(dt),
1547            Expression::Case(c) => c.inferred_type = Some(dt),
1548            Expression::Subquery(s) => s.inferred_type = Some(dt),
1549            Expression::Alias(a) => a.inferred_type = Some(dt),
1550            Expression::IfFunc(f) => f.inferred_type = Some(dt),
1551            Expression::Nvl2(f) => f.inferred_type = Some(dt),
1552            Expression::Count(f) => f.inferred_type = Some(dt),
1553            Expression::GroupConcat(f) => f.inferred_type = Some(dt),
1554            Expression::StringAgg(f) => f.inferred_type = Some(dt),
1555            Expression::ListAgg(f) => f.inferred_type = Some(dt),
1556            Expression::SumIf(f) => f.inferred_type = Some(dt),
1557
1558            // UnaryFunc variants
1559            Expression::Upper(f)
1560            | Expression::Lower(f)
1561            | Expression::Length(f)
1562            | Expression::LTrim(f)
1563            | Expression::RTrim(f)
1564            | Expression::Reverse(f)
1565            | Expression::Abs(f)
1566            | Expression::Sqrt(f)
1567            | Expression::Cbrt(f)
1568            | Expression::Ln(f)
1569            | Expression::Exp(f)
1570            | Expression::Sign(f)
1571            | Expression::Date(f)
1572            | Expression::Time(f)
1573            | Expression::Initcap(f)
1574            | Expression::Ascii(f)
1575            | Expression::Chr(f)
1576            | Expression::Soundex(f)
1577            | Expression::ByteLength(f)
1578            | Expression::Hex(f)
1579            | Expression::LowerHex(f)
1580            | Expression::Unicode(f)
1581            | Expression::Typeof(f)
1582            | Expression::Explode(f)
1583            | Expression::ExplodeOuter(f)
1584            | Expression::MapFromEntries(f)
1585            | Expression::MapKeys(f)
1586            | Expression::MapValues(f)
1587            | Expression::ArrayLength(f)
1588            | Expression::ArraySize(f)
1589            | Expression::Cardinality(f)
1590            | Expression::ArrayReverse(f)
1591            | Expression::ArrayDistinct(f)
1592            | Expression::ArrayFlatten(f)
1593            | Expression::ArrayCompact(f)
1594            | Expression::ToArray(f)
1595            | Expression::JsonArrayLength(f)
1596            | Expression::JsonKeys(f)
1597            | Expression::JsonType(f)
1598            | Expression::ParseJson(f)
1599            | Expression::ToJson(f)
1600            | Expression::Radians(f)
1601            | Expression::Degrees(f)
1602            | Expression::Sin(f)
1603            | Expression::Cos(f)
1604            | Expression::Tan(f)
1605            | Expression::Asin(f)
1606            | Expression::Acos(f)
1607            | Expression::Atan(f)
1608            | Expression::IsNan(f)
1609            | Expression::IsInf(f)
1610            | Expression::Year(f)
1611            | Expression::Month(f)
1612            | Expression::Day(f)
1613            | Expression::Hour(f)
1614            | Expression::Minute(f)
1615            | Expression::Second(f)
1616            | Expression::DayOfWeek(f)
1617            | Expression::DayOfWeekIso(f)
1618            | Expression::DayOfMonth(f)
1619            | Expression::DayOfYear(f)
1620            | Expression::WeekOfYear(f)
1621            | Expression::Quarter(f)
1622            | Expression::Epoch(f)
1623            | Expression::EpochMs(f)
1624            | Expression::BitwiseCount(f)
1625            | Expression::DateFromUnixDate(f)
1626            | Expression::UnixDate(f)
1627            | Expression::UnixSeconds(f)
1628            | Expression::UnixMillis(f)
1629            | Expression::UnixMicros(f)
1630            | Expression::TimeStrToDate(f)
1631            | Expression::DateToDi(f)
1632            | Expression::DiToDate(f)
1633            | Expression::TsOrDiToDi(f)
1634            | Expression::TsOrDsToDatetime(f)
1635            | Expression::TsOrDsToTimestamp(f)
1636            | Expression::YearOfWeek(f)
1637            | Expression::YearOfWeekIso(f)
1638            | Expression::SHA(f)
1639            | Expression::SHA1Digest(f)
1640            | Expression::TimeToUnix(f)
1641            | Expression::TimeStrToUnix(f) => f.inferred_type = Some(dt),
1642
1643            // BinaryFunc variants
1644            Expression::Power(f)
1645            | Expression::NullIf(f)
1646            | Expression::IfNull(f)
1647            | Expression::Nvl(f)
1648            | Expression::Contains(f)
1649            | Expression::StartsWith(f)
1650            | Expression::EndsWith(f)
1651            | Expression::Levenshtein(f)
1652            | Expression::ModFunc(f)
1653            | Expression::IntDiv(f)
1654            | Expression::Atan2(f)
1655            | Expression::AddMonths(f)
1656            | Expression::MonthsBetween(f)
1657            | Expression::NextDay(f)
1658            | Expression::UnixToTimeStr(f)
1659            | Expression::ArrayContains(f)
1660            | Expression::ArrayPosition(f)
1661            | Expression::ArrayAppend(f)
1662            | Expression::ArrayPrepend(f)
1663            | Expression::ArrayUnion(f)
1664            | Expression::ArrayExcept(f)
1665            | Expression::ArrayRemove(f)
1666            | Expression::StarMap(f)
1667            | Expression::MapFromArrays(f)
1668            | Expression::MapContainsKey(f)
1669            | Expression::ElementAt(f)
1670            | Expression::JsonMergePatch(f) => f.inferred_type = Some(dt),
1671
1672            // VarArgFunc variants
1673            Expression::Coalesce(f)
1674            | Expression::Greatest(f)
1675            | Expression::Least(f)
1676            | Expression::ArrayConcat(f)
1677            | Expression::ArrayIntersect(f)
1678            | Expression::ArrayZip(f)
1679            | Expression::MapConcat(f)
1680            | Expression::JsonArray(f) => f.inferred_type = Some(dt),
1681
1682            // AggFunc variants
1683            Expression::Sum(f)
1684            | Expression::Avg(f)
1685            | Expression::Min(f)
1686            | Expression::Max(f)
1687            | Expression::ArrayAgg(f)
1688            | Expression::CountIf(f)
1689            | Expression::Stddev(f)
1690            | Expression::StddevPop(f)
1691            | Expression::StddevSamp(f)
1692            | Expression::Variance(f)
1693            | Expression::VarPop(f)
1694            | Expression::VarSamp(f)
1695            | Expression::Median(f)
1696            | Expression::Mode(f)
1697            | Expression::First(f)
1698            | Expression::Last(f)
1699            | Expression::AnyValue(f)
1700            | Expression::ApproxDistinct(f)
1701            | Expression::ApproxCountDistinct(f)
1702            | Expression::LogicalAnd(f)
1703            | Expression::LogicalOr(f)
1704            | Expression::Skewness(f)
1705            | Expression::ArrayConcatAgg(f)
1706            | Expression::ArrayUniqueAgg(f)
1707            | Expression::BoolXorAgg(f)
1708            | Expression::BitwiseAndAgg(f)
1709            | Expression::BitwiseOrAgg(f)
1710            | Expression::BitwiseXorAgg(f) => f.inferred_type = Some(dt),
1711
1712            // Expressions without inferred_type field - no-op
1713            _ => {}
1714        }
1715    }
1716
1717    /// Create an unqualified column reference (e.g. `name`).
1718    pub fn column(name: impl Into<String>) -> Self {
1719        Expression::Column(Box::new(Column {
1720            name: Identifier::new(name),
1721            table: None,
1722            join_mark: false,
1723            trailing_comments: Vec::new(),
1724            span: None,
1725            inferred_type: None,
1726        }))
1727    }
1728
1729    /// Create a qualified column reference (`table.column`).
1730    pub fn qualified_column(table: impl Into<String>, column: impl Into<String>) -> Self {
1731        Expression::Column(Box::new(Column {
1732            name: Identifier::new(column),
1733            table: Some(Identifier::new(table)),
1734            join_mark: false,
1735            trailing_comments: Vec::new(),
1736            span: None,
1737            inferred_type: None,
1738        }))
1739    }
1740
1741    /// Create a bare identifier expression (not a column reference).
1742    pub fn identifier(name: impl Into<String>) -> Self {
1743        Expression::Identifier(Identifier::new(name))
1744    }
1745
1746    /// Create a NULL expression
1747    pub fn null() -> Self {
1748        Expression::Null(Null)
1749    }
1750
1751    /// Create a TRUE expression
1752    pub fn true_() -> Self {
1753        Expression::Boolean(BooleanLiteral { value: true })
1754    }
1755
1756    /// Create a FALSE expression
1757    pub fn false_() -> Self {
1758        Expression::Boolean(BooleanLiteral { value: false })
1759    }
1760
1761    /// Create a wildcard star (`*`) expression with no EXCEPT/REPLACE/RENAME modifiers.
1762    pub fn star() -> Self {
1763        Expression::Star(Star {
1764            table: None,
1765            except: None,
1766            replace: None,
1767            rename: None,
1768            trailing_comments: Vec::new(),
1769            span: None,
1770        })
1771    }
1772
1773    /// Wrap this expression in an `AS` alias (e.g. `expr AS name`).
1774    pub fn alias(self, name: impl Into<String>) -> Self {
1775        Expression::Alias(Box::new(Alias::new(self, Identifier::new(name))))
1776    }
1777
1778    /// Check if this is a SELECT expression
1779    pub fn is_select(&self) -> bool {
1780        matches!(self, Expression::Select(_))
1781    }
1782
1783    /// Try to get as a Select
1784    pub fn as_select(&self) -> Option<&Select> {
1785        match self {
1786            Expression::Select(s) => Some(s),
1787            _ => None,
1788        }
1789    }
1790
1791    /// Try to get as a mutable Select
1792    pub fn as_select_mut(&mut self) -> Option<&mut Select> {
1793        match self {
1794            Expression::Select(s) => Some(s),
1795            _ => None,
1796        }
1797    }
1798
1799    /// Generate a SQL string for this expression using the generic (dialect-agnostic) generator.
1800    ///
1801    /// Returns an empty string if generation fails. For dialect-specific output,
1802    /// use [`sql_for()`](Self::sql_for) instead.
1803    #[cfg(feature = "generate")]
1804    pub fn sql(&self) -> String {
1805        crate::generator::Generator::sql(self).unwrap_or_default()
1806    }
1807
1808    /// Generate a SQL string for this expression targeting a specific dialect.
1809    ///
1810    /// Dialect-specific rules (identifier quoting, function names, type mappings,
1811    /// syntax variations) are applied automatically.  Returns an empty string if
1812    /// generation fails.
1813    #[cfg(feature = "generate")]
1814    pub fn sql_for(&self, dialect: crate::dialects::DialectType) -> String {
1815        crate::generate(self, dialect).unwrap_or_default()
1816    }
1817}
1818
1819// === Python API accessor methods ===
1820
1821impl Expression {
1822    /// Returns the serde-compatible snake_case variant name without serialization.
1823    /// This is much faster than serializing to JSON and extracting the key.
1824    pub fn variant_name(&self) -> &'static str {
1825        match self {
1826            Expression::Literal(_) => "literal",
1827            Expression::Boolean(_) => "boolean",
1828            Expression::Null(_) => "null",
1829            Expression::Identifier(_) => "identifier",
1830            Expression::Column(_) => "column",
1831            Expression::Table(_) => "table",
1832            Expression::Star(_) => "star",
1833            Expression::BracedWildcard(_) => "braced_wildcard",
1834            Expression::Select(_) => "select",
1835            Expression::Union(_) => "union",
1836            Expression::Intersect(_) => "intersect",
1837            Expression::Except(_) => "except",
1838            Expression::Subquery(_) => "subquery",
1839            Expression::PipeOperator(_) => "pipe_operator",
1840            Expression::Pivot(_) => "pivot",
1841            Expression::PivotAlias(_) => "pivot_alias",
1842            Expression::Unpivot(_) => "unpivot",
1843            Expression::Values(_) => "values",
1844            Expression::PreWhere(_) => "pre_where",
1845            Expression::Stream(_) => "stream",
1846            Expression::UsingData(_) => "using_data",
1847            Expression::XmlNamespace(_) => "xml_namespace",
1848            Expression::Insert(_) => "insert",
1849            Expression::Update(_) => "update",
1850            Expression::Delete(_) => "delete",
1851            Expression::Copy(_) => "copy",
1852            Expression::Put(_) => "put",
1853            Expression::StageReference(_) => "stage_reference",
1854            Expression::Alias(_) => "alias",
1855            Expression::Cast(_) => "cast",
1856            Expression::Collation(_) => "collation",
1857            Expression::Case(_) => "case",
1858            Expression::And(_) => "and",
1859            Expression::Or(_) => "or",
1860            Expression::Add(_) => "add",
1861            Expression::Sub(_) => "sub",
1862            Expression::Mul(_) => "mul",
1863            Expression::Div(_) => "div",
1864            Expression::Mod(_) => "mod",
1865            Expression::Eq(_) => "eq",
1866            Expression::Neq(_) => "neq",
1867            Expression::Lt(_) => "lt",
1868            Expression::Lte(_) => "lte",
1869            Expression::Gt(_) => "gt",
1870            Expression::Gte(_) => "gte",
1871            Expression::Like(_) => "like",
1872            Expression::ILike(_) => "i_like",
1873            Expression::Match(_) => "match",
1874            Expression::BitwiseAnd(_) => "bitwise_and",
1875            Expression::BitwiseOr(_) => "bitwise_or",
1876            Expression::BitwiseXor(_) => "bitwise_xor",
1877            Expression::Concat(_) => "concat",
1878            Expression::Adjacent(_) => "adjacent",
1879            Expression::TsMatch(_) => "ts_match",
1880            Expression::PropertyEQ(_) => "property_e_q",
1881            Expression::ArrayContainsAll(_) => "array_contains_all",
1882            Expression::ArrayContainedBy(_) => "array_contained_by",
1883            Expression::ArrayOverlaps(_) => "array_overlaps",
1884            Expression::JSONBContainsAllTopKeys(_) => "j_s_o_n_b_contains_all_top_keys",
1885            Expression::JSONBContainsAnyTopKeys(_) => "j_s_o_n_b_contains_any_top_keys",
1886            Expression::JSONBDeleteAtPath(_) => "j_s_o_n_b_delete_at_path",
1887            Expression::ExtendsLeft(_) => "extends_left",
1888            Expression::ExtendsRight(_) => "extends_right",
1889            Expression::Not(_) => "not",
1890            Expression::Neg(_) => "neg",
1891            Expression::BitwiseNot(_) => "bitwise_not",
1892            Expression::In(_) => "in",
1893            Expression::Between(_) => "between",
1894            Expression::IsNull(_) => "is_null",
1895            Expression::IsTrue(_) => "is_true",
1896            Expression::IsFalse(_) => "is_false",
1897            Expression::IsJson(_) => "is_json",
1898            Expression::Is(_) => "is",
1899            Expression::Exists(_) => "exists",
1900            Expression::MemberOf(_) => "member_of",
1901            Expression::Function(_) => "function",
1902            Expression::AggregateFunction(_) => "aggregate_function",
1903            Expression::WindowFunction(_) => "window_function",
1904            Expression::From(_) => "from",
1905            Expression::Join(_) => "join",
1906            Expression::JoinedTable(_) => "joined_table",
1907            Expression::Where(_) => "where",
1908            Expression::GroupBy(_) => "group_by",
1909            Expression::Having(_) => "having",
1910            Expression::OrderBy(_) => "order_by",
1911            Expression::Limit(_) => "limit",
1912            Expression::Offset(_) => "offset",
1913            Expression::Qualify(_) => "qualify",
1914            Expression::With(_) => "with",
1915            Expression::Cte(_) => "cte",
1916            Expression::DistributeBy(_) => "distribute_by",
1917            Expression::ClusterBy(_) => "cluster_by",
1918            Expression::SortBy(_) => "sort_by",
1919            Expression::LateralView(_) => "lateral_view",
1920            Expression::Hint(_) => "hint",
1921            Expression::Pseudocolumn(_) => "pseudocolumn",
1922            Expression::Connect(_) => "connect",
1923            Expression::Prior(_) => "prior",
1924            Expression::ConnectByRoot(_) => "connect_by_root",
1925            Expression::MatchRecognize(_) => "match_recognize",
1926            Expression::Ordered(_) => "ordered",
1927            Expression::Window(_) => "window",
1928            Expression::Over(_) => "over",
1929            Expression::WithinGroup(_) => "within_group",
1930            Expression::DataType(_) => "data_type",
1931            Expression::Array(_) => "array",
1932            Expression::Struct(_) => "struct",
1933            Expression::Tuple(_) => "tuple",
1934            Expression::Interval(_) => "interval",
1935            Expression::ConcatWs(_) => "concat_ws",
1936            Expression::Substring(_) => "substring",
1937            Expression::Upper(_) => "upper",
1938            Expression::Lower(_) => "lower",
1939            Expression::Length(_) => "length",
1940            Expression::Trim(_) => "trim",
1941            Expression::LTrim(_) => "l_trim",
1942            Expression::RTrim(_) => "r_trim",
1943            Expression::Replace(_) => "replace",
1944            Expression::Reverse(_) => "reverse",
1945            Expression::Left(_) => "left",
1946            Expression::Right(_) => "right",
1947            Expression::Repeat(_) => "repeat",
1948            Expression::Lpad(_) => "lpad",
1949            Expression::Rpad(_) => "rpad",
1950            Expression::Split(_) => "split",
1951            Expression::RegexpLike(_) => "regexp_like",
1952            Expression::RegexpReplace(_) => "regexp_replace",
1953            Expression::RegexpExtract(_) => "regexp_extract",
1954            Expression::Overlay(_) => "overlay",
1955            Expression::Abs(_) => "abs",
1956            Expression::Round(_) => "round",
1957            Expression::Floor(_) => "floor",
1958            Expression::Ceil(_) => "ceil",
1959            Expression::Power(_) => "power",
1960            Expression::Sqrt(_) => "sqrt",
1961            Expression::Cbrt(_) => "cbrt",
1962            Expression::Ln(_) => "ln",
1963            Expression::Log(_) => "log",
1964            Expression::Exp(_) => "exp",
1965            Expression::Sign(_) => "sign",
1966            Expression::Greatest(_) => "greatest",
1967            Expression::Least(_) => "least",
1968            Expression::CurrentDate(_) => "current_date",
1969            Expression::CurrentTime(_) => "current_time",
1970            Expression::CurrentTimestamp(_) => "current_timestamp",
1971            Expression::CurrentTimestampLTZ(_) => "current_timestamp_l_t_z",
1972            Expression::AtTimeZone(_) => "at_time_zone",
1973            Expression::DateAdd(_) => "date_add",
1974            Expression::DateSub(_) => "date_sub",
1975            Expression::DateDiff(_) => "date_diff",
1976            Expression::DateTrunc(_) => "date_trunc",
1977            Expression::Extract(_) => "extract",
1978            Expression::ToDate(_) => "to_date",
1979            Expression::ToTimestamp(_) => "to_timestamp",
1980            Expression::Date(_) => "date",
1981            Expression::Time(_) => "time",
1982            Expression::DateFromUnixDate(_) => "date_from_unix_date",
1983            Expression::UnixDate(_) => "unix_date",
1984            Expression::UnixSeconds(_) => "unix_seconds",
1985            Expression::UnixMillis(_) => "unix_millis",
1986            Expression::UnixMicros(_) => "unix_micros",
1987            Expression::UnixToTimeStr(_) => "unix_to_time_str",
1988            Expression::TimeStrToDate(_) => "time_str_to_date",
1989            Expression::DateToDi(_) => "date_to_di",
1990            Expression::DiToDate(_) => "di_to_date",
1991            Expression::TsOrDiToDi(_) => "ts_or_di_to_di",
1992            Expression::TsOrDsToDatetime(_) => "ts_or_ds_to_datetime",
1993            Expression::TsOrDsToTimestamp(_) => "ts_or_ds_to_timestamp",
1994            Expression::YearOfWeek(_) => "year_of_week",
1995            Expression::YearOfWeekIso(_) => "year_of_week_iso",
1996            Expression::Coalesce(_) => "coalesce",
1997            Expression::NullIf(_) => "null_if",
1998            Expression::IfFunc(_) => "if_func",
1999            Expression::IfNull(_) => "if_null",
2000            Expression::Nvl(_) => "nvl",
2001            Expression::Nvl2(_) => "nvl2",
2002            Expression::TryCast(_) => "try_cast",
2003            Expression::SafeCast(_) => "safe_cast",
2004            Expression::Count(_) => "count",
2005            Expression::Sum(_) => "sum",
2006            Expression::Avg(_) => "avg",
2007            Expression::Min(_) => "min",
2008            Expression::Max(_) => "max",
2009            Expression::GroupConcat(_) => "group_concat",
2010            Expression::StringAgg(_) => "string_agg",
2011            Expression::ListAgg(_) => "list_agg",
2012            Expression::ArrayAgg(_) => "array_agg",
2013            Expression::CountIf(_) => "count_if",
2014            Expression::SumIf(_) => "sum_if",
2015            Expression::Stddev(_) => "stddev",
2016            Expression::StddevPop(_) => "stddev_pop",
2017            Expression::StddevSamp(_) => "stddev_samp",
2018            Expression::Variance(_) => "variance",
2019            Expression::VarPop(_) => "var_pop",
2020            Expression::VarSamp(_) => "var_samp",
2021            Expression::Median(_) => "median",
2022            Expression::Mode(_) => "mode",
2023            Expression::First(_) => "first",
2024            Expression::Last(_) => "last",
2025            Expression::AnyValue(_) => "any_value",
2026            Expression::ApproxDistinct(_) => "approx_distinct",
2027            Expression::ApproxCountDistinct(_) => "approx_count_distinct",
2028            Expression::ApproxPercentile(_) => "approx_percentile",
2029            Expression::Percentile(_) => "percentile",
2030            Expression::LogicalAnd(_) => "logical_and",
2031            Expression::LogicalOr(_) => "logical_or",
2032            Expression::Skewness(_) => "skewness",
2033            Expression::BitwiseCount(_) => "bitwise_count",
2034            Expression::ArrayConcatAgg(_) => "array_concat_agg",
2035            Expression::ArrayUniqueAgg(_) => "array_unique_agg",
2036            Expression::BoolXorAgg(_) => "bool_xor_agg",
2037            Expression::RowNumber(_) => "row_number",
2038            Expression::Rank(_) => "rank",
2039            Expression::DenseRank(_) => "dense_rank",
2040            Expression::NTile(_) => "n_tile",
2041            Expression::Lead(_) => "lead",
2042            Expression::Lag(_) => "lag",
2043            Expression::FirstValue(_) => "first_value",
2044            Expression::LastValue(_) => "last_value",
2045            Expression::NthValue(_) => "nth_value",
2046            Expression::PercentRank(_) => "percent_rank",
2047            Expression::CumeDist(_) => "cume_dist",
2048            Expression::PercentileCont(_) => "percentile_cont",
2049            Expression::PercentileDisc(_) => "percentile_disc",
2050            Expression::Contains(_) => "contains",
2051            Expression::StartsWith(_) => "starts_with",
2052            Expression::EndsWith(_) => "ends_with",
2053            Expression::Position(_) => "position",
2054            Expression::Initcap(_) => "initcap",
2055            Expression::Ascii(_) => "ascii",
2056            Expression::Chr(_) => "chr",
2057            Expression::CharFunc(_) => "char_func",
2058            Expression::Soundex(_) => "soundex",
2059            Expression::Levenshtein(_) => "levenshtein",
2060            Expression::ByteLength(_) => "byte_length",
2061            Expression::Hex(_) => "hex",
2062            Expression::LowerHex(_) => "lower_hex",
2063            Expression::Unicode(_) => "unicode",
2064            Expression::ModFunc(_) => "mod_func",
2065            Expression::Random(_) => "random",
2066            Expression::Rand(_) => "rand",
2067            Expression::TruncFunc(_) => "trunc_func",
2068            Expression::Pi(_) => "pi",
2069            Expression::Radians(_) => "radians",
2070            Expression::Degrees(_) => "degrees",
2071            Expression::Sin(_) => "sin",
2072            Expression::Cos(_) => "cos",
2073            Expression::Tan(_) => "tan",
2074            Expression::Asin(_) => "asin",
2075            Expression::Acos(_) => "acos",
2076            Expression::Atan(_) => "atan",
2077            Expression::Atan2(_) => "atan2",
2078            Expression::IsNan(_) => "is_nan",
2079            Expression::IsInf(_) => "is_inf",
2080            Expression::IntDiv(_) => "int_div",
2081            Expression::Decode(_) => "decode",
2082            Expression::DateFormat(_) => "date_format",
2083            Expression::FormatDate(_) => "format_date",
2084            Expression::Year(_) => "year",
2085            Expression::Month(_) => "month",
2086            Expression::Day(_) => "day",
2087            Expression::Hour(_) => "hour",
2088            Expression::Minute(_) => "minute",
2089            Expression::Second(_) => "second",
2090            Expression::DayOfWeek(_) => "day_of_week",
2091            Expression::DayOfWeekIso(_) => "day_of_week_iso",
2092            Expression::DayOfMonth(_) => "day_of_month",
2093            Expression::DayOfYear(_) => "day_of_year",
2094            Expression::WeekOfYear(_) => "week_of_year",
2095            Expression::Quarter(_) => "quarter",
2096            Expression::AddMonths(_) => "add_months",
2097            Expression::MonthsBetween(_) => "months_between",
2098            Expression::LastDay(_) => "last_day",
2099            Expression::NextDay(_) => "next_day",
2100            Expression::Epoch(_) => "epoch",
2101            Expression::EpochMs(_) => "epoch_ms",
2102            Expression::FromUnixtime(_) => "from_unixtime",
2103            Expression::UnixTimestamp(_) => "unix_timestamp",
2104            Expression::MakeDate(_) => "make_date",
2105            Expression::MakeTimestamp(_) => "make_timestamp",
2106            Expression::TimestampTrunc(_) => "timestamp_trunc",
2107            Expression::TimeStrToUnix(_) => "time_str_to_unix",
2108            Expression::SessionUser(_) => "session_user",
2109            Expression::SHA(_) => "s_h_a",
2110            Expression::SHA1Digest(_) => "s_h_a1_digest",
2111            Expression::TimeToUnix(_) => "time_to_unix",
2112            Expression::ArrayFunc(_) => "array_func",
2113            Expression::ArrayLength(_) => "array_length",
2114            Expression::ArraySize(_) => "array_size",
2115            Expression::Cardinality(_) => "cardinality",
2116            Expression::ArrayContains(_) => "array_contains",
2117            Expression::ArrayPosition(_) => "array_position",
2118            Expression::ArrayAppend(_) => "array_append",
2119            Expression::ArrayPrepend(_) => "array_prepend",
2120            Expression::ArrayConcat(_) => "array_concat",
2121            Expression::ArraySort(_) => "array_sort",
2122            Expression::ArrayReverse(_) => "array_reverse",
2123            Expression::ArrayDistinct(_) => "array_distinct",
2124            Expression::ArrayJoin(_) => "array_join",
2125            Expression::ArrayToString(_) => "array_to_string",
2126            Expression::Unnest(_) => "unnest",
2127            Expression::Explode(_) => "explode",
2128            Expression::ExplodeOuter(_) => "explode_outer",
2129            Expression::ArrayFilter(_) => "array_filter",
2130            Expression::ArrayTransform(_) => "array_transform",
2131            Expression::ArrayFlatten(_) => "array_flatten",
2132            Expression::ArrayCompact(_) => "array_compact",
2133            Expression::ArrayIntersect(_) => "array_intersect",
2134            Expression::ArrayUnion(_) => "array_union",
2135            Expression::ArrayExcept(_) => "array_except",
2136            Expression::ArrayRemove(_) => "array_remove",
2137            Expression::ArrayZip(_) => "array_zip",
2138            Expression::Sequence(_) => "sequence",
2139            Expression::Generate(_) => "generate",
2140            Expression::ExplodingGenerateSeries(_) => "exploding_generate_series",
2141            Expression::ToArray(_) => "to_array",
2142            Expression::StarMap(_) => "star_map",
2143            Expression::StructFunc(_) => "struct_func",
2144            Expression::StructExtract(_) => "struct_extract",
2145            Expression::NamedStruct(_) => "named_struct",
2146            Expression::MapFunc(_) => "map_func",
2147            Expression::MapFromEntries(_) => "map_from_entries",
2148            Expression::MapFromArrays(_) => "map_from_arrays",
2149            Expression::MapKeys(_) => "map_keys",
2150            Expression::MapValues(_) => "map_values",
2151            Expression::MapContainsKey(_) => "map_contains_key",
2152            Expression::MapConcat(_) => "map_concat",
2153            Expression::ElementAt(_) => "element_at",
2154            Expression::TransformKeys(_) => "transform_keys",
2155            Expression::TransformValues(_) => "transform_values",
2156            Expression::FunctionEmits(_) => "function_emits",
2157            Expression::JsonExtract(_) => "json_extract",
2158            Expression::JsonExtractScalar(_) => "json_extract_scalar",
2159            Expression::JsonExtractPath(_) => "json_extract_path",
2160            Expression::JsonArray(_) => "json_array",
2161            Expression::JsonObject(_) => "json_object",
2162            Expression::JsonQuery(_) => "json_query",
2163            Expression::JsonValue(_) => "json_value",
2164            Expression::JsonArrayLength(_) => "json_array_length",
2165            Expression::JsonKeys(_) => "json_keys",
2166            Expression::JsonType(_) => "json_type",
2167            Expression::ParseJson(_) => "parse_json",
2168            Expression::ToJson(_) => "to_json",
2169            Expression::JsonSet(_) => "json_set",
2170            Expression::JsonInsert(_) => "json_insert",
2171            Expression::JsonRemove(_) => "json_remove",
2172            Expression::JsonMergePatch(_) => "json_merge_patch",
2173            Expression::JsonArrayAgg(_) => "json_array_agg",
2174            Expression::JsonObjectAgg(_) => "json_object_agg",
2175            Expression::Convert(_) => "convert",
2176            Expression::Typeof(_) => "typeof",
2177            Expression::Lambda(_) => "lambda",
2178            Expression::Parameter(_) => "parameter",
2179            Expression::Placeholder(_) => "placeholder",
2180            Expression::NamedArgument(_) => "named_argument",
2181            Expression::TableArgument(_) => "table_argument",
2182            Expression::SqlComment(_) => "sql_comment",
2183            Expression::NullSafeEq(_) => "null_safe_eq",
2184            Expression::NullSafeNeq(_) => "null_safe_neq",
2185            Expression::Glob(_) => "glob",
2186            Expression::SimilarTo(_) => "similar_to",
2187            Expression::Any(_) => "any",
2188            Expression::All(_) => "all",
2189            Expression::Overlaps(_) => "overlaps",
2190            Expression::BitwiseLeftShift(_) => "bitwise_left_shift",
2191            Expression::BitwiseRightShift(_) => "bitwise_right_shift",
2192            Expression::BitwiseAndAgg(_) => "bitwise_and_agg",
2193            Expression::BitwiseOrAgg(_) => "bitwise_or_agg",
2194            Expression::BitwiseXorAgg(_) => "bitwise_xor_agg",
2195            Expression::Subscript(_) => "subscript",
2196            Expression::Dot(_) => "dot",
2197            Expression::MethodCall(_) => "method_call",
2198            Expression::ArraySlice(_) => "array_slice",
2199            Expression::CreateTable(_) => "create_table",
2200            Expression::DropTable(_) => "drop_table",
2201            Expression::Undrop(_) => "undrop",
2202            Expression::AlterTable(_) => "alter_table",
2203            Expression::CreateIndex(_) => "create_index",
2204            Expression::DropIndex(_) => "drop_index",
2205            Expression::CreateView(_) => "create_view",
2206            Expression::DropView(_) => "drop_view",
2207            Expression::AlterView(_) => "alter_view",
2208            Expression::AlterIndex(_) => "alter_index",
2209            Expression::Truncate(_) => "truncate",
2210            Expression::Use(_) => "use",
2211            Expression::Cache(_) => "cache",
2212            Expression::Uncache(_) => "uncache",
2213            Expression::LoadData(_) => "load_data",
2214            Expression::Pragma(_) => "pragma",
2215            Expression::Grant(_) => "grant",
2216            Expression::Revoke(_) => "revoke",
2217            Expression::Comment(_) => "comment",
2218            Expression::SetStatement(_) => "set_statement",
2219            Expression::CreateSchema(_) => "create_schema",
2220            Expression::DropSchema(_) => "drop_schema",
2221            Expression::DropNamespace(_) => "drop_namespace",
2222            Expression::CreateDatabase(_) => "create_database",
2223            Expression::DropDatabase(_) => "drop_database",
2224            Expression::CreateFunction(_) => "create_function",
2225            Expression::DropFunction(_) => "drop_function",
2226            Expression::CreateProcedure(_) => "create_procedure",
2227            Expression::DropProcedure(_) => "drop_procedure",
2228            Expression::CreateSequence(_) => "create_sequence",
2229            Expression::CreateSynonym(_) => "create_synonym",
2230            Expression::DropSequence(_) => "drop_sequence",
2231            Expression::AlterSequence(_) => "alter_sequence",
2232            Expression::CreateTrigger(_) => "create_trigger",
2233            Expression::DropTrigger(_) => "drop_trigger",
2234            Expression::CreateType(_) => "create_type",
2235            Expression::DropType(_) => "drop_type",
2236            Expression::Describe(_) => "describe",
2237            Expression::Show(_) => "show",
2238            Expression::Command(_) => "command",
2239            Expression::TryCatch(_) => "try_catch",
2240            Expression::Kill(_) => "kill",
2241            Expression::Prepare(_) => "prepare",
2242            Expression::Execute(_) => "execute",
2243            Expression::Raw(_) => "raw",
2244            Expression::CreateTask(_) => "create_task",
2245            Expression::Paren(_) => "paren",
2246            Expression::Annotated(_) => "annotated",
2247            Expression::Refresh(_) => "refresh",
2248            Expression::LockingStatement(_) => "locking_statement",
2249            Expression::SequenceProperties(_) => "sequence_properties",
2250            Expression::TruncateTable(_) => "truncate_table",
2251            Expression::Clone(_) => "clone",
2252            Expression::Attach(_) => "attach",
2253            Expression::Detach(_) => "detach",
2254            Expression::Install(_) => "install",
2255            Expression::Summarize(_) => "summarize",
2256            Expression::Declare(_) => "declare",
2257            Expression::DeclareItem(_) => "declare_item",
2258            Expression::Set(_) => "set",
2259            Expression::Heredoc(_) => "heredoc",
2260            Expression::SetItem(_) => "set_item",
2261            Expression::QueryBand(_) => "query_band",
2262            Expression::UserDefinedFunction(_) => "user_defined_function",
2263            Expression::RecursiveWithSearch(_) => "recursive_with_search",
2264            Expression::ProjectionDef(_) => "projection_def",
2265            Expression::TableAlias(_) => "table_alias",
2266            Expression::ByteString(_) => "byte_string",
2267            Expression::HexStringExpr(_) => "hex_string_expr",
2268            Expression::UnicodeString(_) => "unicode_string",
2269            Expression::ColumnPosition(_) => "column_position",
2270            Expression::ColumnDef(_) => "column_def",
2271            Expression::AlterColumn(_) => "alter_column",
2272            Expression::AlterSortKey(_) => "alter_sort_key",
2273            Expression::AlterSet(_) => "alter_set",
2274            Expression::RenameColumn(_) => "rename_column",
2275            Expression::Comprehension(_) => "comprehension",
2276            Expression::MergeTreeTTLAction(_) => "merge_tree_t_t_l_action",
2277            Expression::MergeTreeTTL(_) => "merge_tree_t_t_l",
2278            Expression::IndexConstraintOption(_) => "index_constraint_option",
2279            Expression::ColumnConstraint(_) => "column_constraint",
2280            Expression::PeriodForSystemTimeConstraint(_) => "period_for_system_time_constraint",
2281            Expression::CaseSpecificColumnConstraint(_) => "case_specific_column_constraint",
2282            Expression::CharacterSetColumnConstraint(_) => "character_set_column_constraint",
2283            Expression::CheckColumnConstraint(_) => "check_column_constraint",
2284            Expression::AssumeColumnConstraint(_) => "assume_column_constraint",
2285            Expression::CompressColumnConstraint(_) => "compress_column_constraint",
2286            Expression::DateFormatColumnConstraint(_) => "date_format_column_constraint",
2287            Expression::EphemeralColumnConstraint(_) => "ephemeral_column_constraint",
2288            Expression::WithOperator(_) => "with_operator",
2289            Expression::GeneratedAsIdentityColumnConstraint(_) => {
2290                "generated_as_identity_column_constraint"
2291            }
2292            Expression::AutoIncrementColumnConstraint(_) => "auto_increment_column_constraint",
2293            Expression::CommentColumnConstraint(_) => "comment_column_constraint",
2294            Expression::GeneratedAsRowColumnConstraint(_) => "generated_as_row_column_constraint",
2295            Expression::IndexColumnConstraint(_) => "index_column_constraint",
2296            Expression::MaskingPolicyColumnConstraint(_) => "masking_policy_column_constraint",
2297            Expression::NotNullColumnConstraint(_) => "not_null_column_constraint",
2298            Expression::PrimaryKeyColumnConstraint(_) => "primary_key_column_constraint",
2299            Expression::UniqueColumnConstraint(_) => "unique_column_constraint",
2300            Expression::WatermarkColumnConstraint(_) => "watermark_column_constraint",
2301            Expression::ComputedColumnConstraint(_) => "computed_column_constraint",
2302            Expression::InOutColumnConstraint(_) => "in_out_column_constraint",
2303            Expression::DefaultColumnConstraint(_) => "default_column_constraint",
2304            Expression::PathColumnConstraint(_) => "path_column_constraint",
2305            Expression::Constraint(_) => "constraint",
2306            Expression::Export(_) => "export",
2307            Expression::Filter(_) => "filter",
2308            Expression::Changes(_) => "changes",
2309            Expression::CopyParameter(_) => "copy_parameter",
2310            Expression::Credentials(_) => "credentials",
2311            Expression::Directory(_) => "directory",
2312            Expression::ForeignKey(_) => "foreign_key",
2313            Expression::ColumnPrefix(_) => "column_prefix",
2314            Expression::PrimaryKey(_) => "primary_key",
2315            Expression::IntoClause(_) => "into_clause",
2316            Expression::JoinHint(_) => "join_hint",
2317            Expression::Opclass(_) => "opclass",
2318            Expression::Index(_) => "index",
2319            Expression::IndexParameters(_) => "index_parameters",
2320            Expression::ConditionalInsert(_) => "conditional_insert",
2321            Expression::MultitableInserts(_) => "multitable_inserts",
2322            Expression::OnConflict(_) => "on_conflict",
2323            Expression::OnCondition(_) => "on_condition",
2324            Expression::Returning(_) => "returning",
2325            Expression::Introducer(_) => "introducer",
2326            Expression::PartitionRange(_) => "partition_range",
2327            Expression::Fetch(_) => "fetch",
2328            Expression::Group(_) => "group",
2329            Expression::Cube(_) => "cube",
2330            Expression::Rollup(_) => "rollup",
2331            Expression::GroupingSets(_) => "grouping_sets",
2332            Expression::LimitOptions(_) => "limit_options",
2333            Expression::Lateral(_) => "lateral",
2334            Expression::TableFromRows(_) => "table_from_rows",
2335            Expression::RowsFrom(_) => "rows_from",
2336            Expression::MatchRecognizeMeasure(_) => "match_recognize_measure",
2337            Expression::WithFill(_) => "with_fill",
2338            Expression::Property(_) => "property",
2339            Expression::GrantPrivilege(_) => "grant_privilege",
2340            Expression::GrantPrincipal(_) => "grant_principal",
2341            Expression::AllowedValuesProperty(_) => "allowed_values_property",
2342            Expression::AlgorithmProperty(_) => "algorithm_property",
2343            Expression::AutoIncrementProperty(_) => "auto_increment_property",
2344            Expression::AutoRefreshProperty(_) => "auto_refresh_property",
2345            Expression::BackupProperty(_) => "backup_property",
2346            Expression::BuildProperty(_) => "build_property",
2347            Expression::BlockCompressionProperty(_) => "block_compression_property",
2348            Expression::CharacterSetProperty(_) => "character_set_property",
2349            Expression::ChecksumProperty(_) => "checksum_property",
2350            Expression::CollateProperty(_) => "collate_property",
2351            Expression::DataBlocksizeProperty(_) => "data_blocksize_property",
2352            Expression::DataDeletionProperty(_) => "data_deletion_property",
2353            Expression::DefinerProperty(_) => "definer_property",
2354            Expression::DistKeyProperty(_) => "dist_key_property",
2355            Expression::DistributedByProperty(_) => "distributed_by_property",
2356            Expression::DistStyleProperty(_) => "dist_style_property",
2357            Expression::DuplicateKeyProperty(_) => "duplicate_key_property",
2358            Expression::EngineProperty(_) => "engine_property",
2359            Expression::ToTableProperty(_) => "to_table_property",
2360            Expression::ExecuteAsProperty(_) => "execute_as_property",
2361            Expression::ExternalProperty(_) => "external_property",
2362            Expression::FallbackProperty(_) => "fallback_property",
2363            Expression::FileFormatProperty(_) => "file_format_property",
2364            Expression::CredentialsProperty(_) => "credentials_property",
2365            Expression::FreespaceProperty(_) => "freespace_property",
2366            Expression::InheritsProperty(_) => "inherits_property",
2367            Expression::InputModelProperty(_) => "input_model_property",
2368            Expression::OutputModelProperty(_) => "output_model_property",
2369            Expression::IsolatedLoadingProperty(_) => "isolated_loading_property",
2370            Expression::JournalProperty(_) => "journal_property",
2371            Expression::LanguageProperty(_) => "language_property",
2372            Expression::EnviromentProperty(_) => "enviroment_property",
2373            Expression::ClusteredByProperty(_) => "clustered_by_property",
2374            Expression::DictProperty(_) => "dict_property",
2375            Expression::DictRange(_) => "dict_range",
2376            Expression::OnCluster(_) => "on_cluster",
2377            Expression::LikeProperty(_) => "like_property",
2378            Expression::LocationProperty(_) => "location_property",
2379            Expression::LockProperty(_) => "lock_property",
2380            Expression::LockingProperty(_) => "locking_property",
2381            Expression::LogProperty(_) => "log_property",
2382            Expression::MaterializedProperty(_) => "materialized_property",
2383            Expression::MergeBlockRatioProperty(_) => "merge_block_ratio_property",
2384            Expression::OnProperty(_) => "on_property",
2385            Expression::OnCommitProperty(_) => "on_commit_property",
2386            Expression::PartitionedByProperty(_) => "partitioned_by_property",
2387            Expression::PartitionByProperty(_) => "partition_by_property",
2388            Expression::PartitionedByBucket(_) => "partitioned_by_bucket",
2389            Expression::ClusterByColumnsProperty(_) => "cluster_by_columns_property",
2390            Expression::PartitionByTruncate(_) => "partition_by_truncate",
2391            Expression::PartitionByRangeProperty(_) => "partition_by_range_property",
2392            Expression::PartitionByRangePropertyDynamic(_) => "partition_by_range_property_dynamic",
2393            Expression::PartitionByListProperty(_) => "partition_by_list_property",
2394            Expression::PartitionList(_) => "partition_list",
2395            Expression::Partition(_) => "partition",
2396            Expression::RefreshTriggerProperty(_) => "refresh_trigger_property",
2397            Expression::UniqueKeyProperty(_) => "unique_key_property",
2398            Expression::RollupProperty(_) => "rollup_property",
2399            Expression::PartitionBoundSpec(_) => "partition_bound_spec",
2400            Expression::PartitionedOfProperty(_) => "partitioned_of_property",
2401            Expression::RemoteWithConnectionModelProperty(_) => {
2402                "remote_with_connection_model_property"
2403            }
2404            Expression::ReturnsProperty(_) => "returns_property",
2405            Expression::RowFormatProperty(_) => "row_format_property",
2406            Expression::RowFormatDelimitedProperty(_) => "row_format_delimited_property",
2407            Expression::RowFormatSerdeProperty(_) => "row_format_serde_property",
2408            Expression::QueryTransform(_) => "query_transform",
2409            Expression::SampleProperty(_) => "sample_property",
2410            Expression::SecurityProperty(_) => "security_property",
2411            Expression::SchemaCommentProperty(_) => "schema_comment_property",
2412            Expression::SemanticView(_) => "semantic_view",
2413            Expression::SerdeProperties(_) => "serde_properties",
2414            Expression::SetProperty(_) => "set_property",
2415            Expression::SharingProperty(_) => "sharing_property",
2416            Expression::SetConfigProperty(_) => "set_config_property",
2417            Expression::SettingsProperty(_) => "settings_property",
2418            Expression::SortKeyProperty(_) => "sort_key_property",
2419            Expression::SqlReadWriteProperty(_) => "sql_read_write_property",
2420            Expression::SqlSecurityProperty(_) => "sql_security_property",
2421            Expression::StabilityProperty(_) => "stability_property",
2422            Expression::StorageHandlerProperty(_) => "storage_handler_property",
2423            Expression::TemporaryProperty(_) => "temporary_property",
2424            Expression::Tags(_) => "tags",
2425            Expression::TransformModelProperty(_) => "transform_model_property",
2426            Expression::TransientProperty(_) => "transient_property",
2427            Expression::UsingTemplateProperty(_) => "using_template_property",
2428            Expression::ViewAttributeProperty(_) => "view_attribute_property",
2429            Expression::VolatileProperty(_) => "volatile_property",
2430            Expression::WithDataProperty(_) => "with_data_property",
2431            Expression::WithJournalTableProperty(_) => "with_journal_table_property",
2432            Expression::WithSchemaBindingProperty(_) => "with_schema_binding_property",
2433            Expression::WithSystemVersioningProperty(_) => "with_system_versioning_property",
2434            Expression::WithProcedureOptions(_) => "with_procedure_options",
2435            Expression::EncodeProperty(_) => "encode_property",
2436            Expression::IncludeProperty(_) => "include_property",
2437            Expression::Properties(_) => "properties",
2438            Expression::OptionsProperty(_) => "options_property",
2439            Expression::InputOutputFormat(_) => "input_output_format",
2440            Expression::Reference(_) => "reference",
2441            Expression::QueryOption(_) => "query_option",
2442            Expression::WithTableHint(_) => "with_table_hint",
2443            Expression::IndexTableHint(_) => "index_table_hint",
2444            Expression::HistoricalData(_) => "historical_data",
2445            Expression::Get(_) => "get",
2446            Expression::SetOperation(_) => "set_operation",
2447            Expression::Var(_) => "var",
2448            Expression::Variadic(_) => "variadic",
2449            Expression::Version(_) => "version",
2450            Expression::Schema(_) => "schema",
2451            Expression::Lock(_) => "lock",
2452            Expression::TableSample(_) => "table_sample",
2453            Expression::Tag(_) => "tag",
2454            Expression::UnpivotColumns(_) => "unpivot_columns",
2455            Expression::WindowSpec(_) => "window_spec",
2456            Expression::SessionParameter(_) => "session_parameter",
2457            Expression::PseudoType(_) => "pseudo_type",
2458            Expression::ObjectIdentifier(_) => "object_identifier",
2459            Expression::Transaction(_) => "transaction",
2460            Expression::Commit(_) => "commit",
2461            Expression::Rollback(_) => "rollback",
2462            Expression::AlterSession(_) => "alter_session",
2463            Expression::Analyze(_) => "analyze",
2464            Expression::AnalyzeStatistics(_) => "analyze_statistics",
2465            Expression::AnalyzeHistogram(_) => "analyze_histogram",
2466            Expression::AnalyzeSample(_) => "analyze_sample",
2467            Expression::AnalyzeListChainedRows(_) => "analyze_list_chained_rows",
2468            Expression::AnalyzeDelete(_) => "analyze_delete",
2469            Expression::AnalyzeWith(_) => "analyze_with",
2470            Expression::AnalyzeValidate(_) => "analyze_validate",
2471            Expression::AddPartition(_) => "add_partition",
2472            Expression::AttachOption(_) => "attach_option",
2473            Expression::DropPartition(_) => "drop_partition",
2474            Expression::ReplacePartition(_) => "replace_partition",
2475            Expression::DPipe(_) => "d_pipe",
2476            Expression::Operator(_) => "operator",
2477            Expression::PivotAny(_) => "pivot_any",
2478            Expression::Aliases(_) => "aliases",
2479            Expression::AtIndex(_) => "at_index",
2480            Expression::FromTimeZone(_) => "from_time_zone",
2481            Expression::FormatPhrase(_) => "format_phrase",
2482            Expression::ForIn(_) => "for_in",
2483            Expression::TimeUnit(_) => "time_unit",
2484            Expression::IntervalOp(_) => "interval_op",
2485            Expression::IntervalSpan(_) => "interval_span",
2486            Expression::HavingMax(_) => "having_max",
2487            Expression::CosineDistance(_) => "cosine_distance",
2488            Expression::DotProduct(_) => "dot_product",
2489            Expression::EuclideanDistance(_) => "euclidean_distance",
2490            Expression::ManhattanDistance(_) => "manhattan_distance",
2491            Expression::JarowinklerSimilarity(_) => "jarowinkler_similarity",
2492            Expression::Booland(_) => "booland",
2493            Expression::Boolor(_) => "boolor",
2494            Expression::ParameterizedAgg(_) => "parameterized_agg",
2495            Expression::ArgMax(_) => "arg_max",
2496            Expression::ArgMin(_) => "arg_min",
2497            Expression::ApproxTopK(_) => "approx_top_k",
2498            Expression::ApproxTopKAccumulate(_) => "approx_top_k_accumulate",
2499            Expression::ApproxTopKCombine(_) => "approx_top_k_combine",
2500            Expression::ApproxTopKEstimate(_) => "approx_top_k_estimate",
2501            Expression::ApproxTopSum(_) => "approx_top_sum",
2502            Expression::ApproxQuantiles(_) => "approx_quantiles",
2503            Expression::Minhash(_) => "minhash",
2504            Expression::FarmFingerprint(_) => "farm_fingerprint",
2505            Expression::Float64(_) => "float64",
2506            Expression::Transform(_) => "transform",
2507            Expression::Translate(_) => "translate",
2508            Expression::Grouping(_) => "grouping",
2509            Expression::GroupingId(_) => "grouping_id",
2510            Expression::Anonymous(_) => "anonymous",
2511            Expression::AnonymousAggFunc(_) => "anonymous_agg_func",
2512            Expression::CombinedAggFunc(_) => "combined_agg_func",
2513            Expression::CombinedParameterizedAgg(_) => "combined_parameterized_agg",
2514            Expression::HashAgg(_) => "hash_agg",
2515            Expression::Hll(_) => "hll",
2516            Expression::Apply(_) => "apply",
2517            Expression::ToBoolean(_) => "to_boolean",
2518            Expression::List(_) => "list",
2519            Expression::ToMap(_) => "to_map",
2520            Expression::Pad(_) => "pad",
2521            Expression::ToChar(_) => "to_char",
2522            Expression::ToNumber(_) => "to_number",
2523            Expression::ToDouble(_) => "to_double",
2524            Expression::Int64(_) => "int64",
2525            Expression::StringFunc(_) => "string_func",
2526            Expression::ToDecfloat(_) => "to_decfloat",
2527            Expression::TryToDecfloat(_) => "try_to_decfloat",
2528            Expression::ToFile(_) => "to_file",
2529            Expression::Columns(_) => "columns",
2530            Expression::ConvertToCharset(_) => "convert_to_charset",
2531            Expression::ConvertTimezone(_) => "convert_timezone",
2532            Expression::GenerateSeries(_) => "generate_series",
2533            Expression::AIAgg(_) => "a_i_agg",
2534            Expression::AIClassify(_) => "a_i_classify",
2535            Expression::ArrayAll(_) => "array_all",
2536            Expression::ArrayAny(_) => "array_any",
2537            Expression::ArrayConstructCompact(_) => "array_construct_compact",
2538            Expression::StPoint(_) => "st_point",
2539            Expression::StDistance(_) => "st_distance",
2540            Expression::StringToArray(_) => "string_to_array",
2541            Expression::ArraySum(_) => "array_sum",
2542            Expression::ObjectAgg(_) => "object_agg",
2543            Expression::CastToStrType(_) => "cast_to_str_type",
2544            Expression::CheckJson(_) => "check_json",
2545            Expression::CheckXml(_) => "check_xml",
2546            Expression::TranslateCharacters(_) => "translate_characters",
2547            Expression::CurrentSchemas(_) => "current_schemas",
2548            Expression::CurrentDatetime(_) => "current_datetime",
2549            Expression::Localtime(_) => "localtime",
2550            Expression::Localtimestamp(_) => "localtimestamp",
2551            Expression::Systimestamp(_) => "systimestamp",
2552            Expression::CurrentSchema(_) => "current_schema",
2553            Expression::CurrentUser(_) => "current_user",
2554            Expression::UtcTime(_) => "utc_time",
2555            Expression::UtcTimestamp(_) => "utc_timestamp",
2556            Expression::Timestamp(_) => "timestamp",
2557            Expression::DateBin(_) => "date_bin",
2558            Expression::Datetime(_) => "datetime",
2559            Expression::DatetimeAdd(_) => "datetime_add",
2560            Expression::DatetimeSub(_) => "datetime_sub",
2561            Expression::DatetimeDiff(_) => "datetime_diff",
2562            Expression::DatetimeTrunc(_) => "datetime_trunc",
2563            Expression::Dayname(_) => "dayname",
2564            Expression::MakeInterval(_) => "make_interval",
2565            Expression::PreviousDay(_) => "previous_day",
2566            Expression::Elt(_) => "elt",
2567            Expression::TimestampAdd(_) => "timestamp_add",
2568            Expression::TimestampSub(_) => "timestamp_sub",
2569            Expression::TimestampDiff(_) => "timestamp_diff",
2570            Expression::TimeSlice(_) => "time_slice",
2571            Expression::TimeAdd(_) => "time_add",
2572            Expression::TimeSub(_) => "time_sub",
2573            Expression::TimeDiff(_) => "time_diff",
2574            Expression::TimeTrunc(_) => "time_trunc",
2575            Expression::DateFromParts(_) => "date_from_parts",
2576            Expression::TimeFromParts(_) => "time_from_parts",
2577            Expression::DecodeCase(_) => "decode_case",
2578            Expression::Decrypt(_) => "decrypt",
2579            Expression::DecryptRaw(_) => "decrypt_raw",
2580            Expression::Encode(_) => "encode",
2581            Expression::Encrypt(_) => "encrypt",
2582            Expression::EncryptRaw(_) => "encrypt_raw",
2583            Expression::EqualNull(_) => "equal_null",
2584            Expression::ToBinary(_) => "to_binary",
2585            Expression::Base64DecodeBinary(_) => "base64_decode_binary",
2586            Expression::Base64DecodeString(_) => "base64_decode_string",
2587            Expression::Base64Encode(_) => "base64_encode",
2588            Expression::TryBase64DecodeBinary(_) => "try_base64_decode_binary",
2589            Expression::TryBase64DecodeString(_) => "try_base64_decode_string",
2590            Expression::GapFill(_) => "gap_fill",
2591            Expression::GenerateDateArray(_) => "generate_date_array",
2592            Expression::GenerateTimestampArray(_) => "generate_timestamp_array",
2593            Expression::GetExtract(_) => "get_extract",
2594            Expression::Getbit(_) => "getbit",
2595            Expression::OverflowTruncateBehavior(_) => "overflow_truncate_behavior",
2596            Expression::HexEncode(_) => "hex_encode",
2597            Expression::Compress(_) => "compress",
2598            Expression::DecompressBinary(_) => "decompress_binary",
2599            Expression::DecompressString(_) => "decompress_string",
2600            Expression::Xor(_) => "xor",
2601            Expression::Nullif(_) => "nullif",
2602            Expression::JSON(_) => "j_s_o_n",
2603            Expression::JSONPath(_) => "j_s_o_n_path",
2604            Expression::JSONPathFilter(_) => "j_s_o_n_path_filter",
2605            Expression::JSONPathKey(_) => "j_s_o_n_path_key",
2606            Expression::JSONPathRecursive(_) => "j_s_o_n_path_recursive",
2607            Expression::JSONPathScript(_) => "j_s_o_n_path_script",
2608            Expression::JSONPathSlice(_) => "j_s_o_n_path_slice",
2609            Expression::JSONPathSelector(_) => "j_s_o_n_path_selector",
2610            Expression::JSONPathSubscript(_) => "j_s_o_n_path_subscript",
2611            Expression::JSONPathUnion(_) => "j_s_o_n_path_union",
2612            Expression::Format(_) => "format",
2613            Expression::JSONKeys(_) => "j_s_o_n_keys",
2614            Expression::JSONKeyValue(_) => "j_s_o_n_key_value",
2615            Expression::JSONKeysAtDepth(_) => "j_s_o_n_keys_at_depth",
2616            Expression::JSONObject(_) => "j_s_o_n_object",
2617            Expression::JSONObjectAgg(_) => "j_s_o_n_object_agg",
2618            Expression::JSONBObjectAgg(_) => "j_s_o_n_b_object_agg",
2619            Expression::JSONArray(_) => "j_s_o_n_array",
2620            Expression::JSONArrayAgg(_) => "j_s_o_n_array_agg",
2621            Expression::JSONExists(_) => "j_s_o_n_exists",
2622            Expression::JSONColumnDef(_) => "j_s_o_n_column_def",
2623            Expression::JSONSchema(_) => "j_s_o_n_schema",
2624            Expression::JSONSet(_) => "j_s_o_n_set",
2625            Expression::JSONStripNulls(_) => "j_s_o_n_strip_nulls",
2626            Expression::JSONValue(_) => "j_s_o_n_value",
2627            Expression::JSONValueArray(_) => "j_s_o_n_value_array",
2628            Expression::JSONRemove(_) => "j_s_o_n_remove",
2629            Expression::JSONTable(_) => "j_s_o_n_table",
2630            Expression::JSONType(_) => "j_s_o_n_type",
2631            Expression::ObjectInsert(_) => "object_insert",
2632            Expression::OpenJSONColumnDef(_) => "open_j_s_o_n_column_def",
2633            Expression::OpenJSON(_) => "open_j_s_o_n",
2634            Expression::JSONBExists(_) => "j_s_o_n_b_exists",
2635            Expression::JSONBContains(_) => "j_s_o_n_b_contains",
2636            Expression::JSONBExtract(_) => "j_s_o_n_b_extract",
2637            Expression::JSONCast(_) => "j_s_o_n_cast",
2638            Expression::JSONExtract(_) => "j_s_o_n_extract",
2639            Expression::JSONExtractQuote(_) => "j_s_o_n_extract_quote",
2640            Expression::JSONExtractArray(_) => "j_s_o_n_extract_array",
2641            Expression::JSONExtractScalar(_) => "j_s_o_n_extract_scalar",
2642            Expression::JSONBExtractScalar(_) => "j_s_o_n_b_extract_scalar",
2643            Expression::JSONFormat(_) => "j_s_o_n_format",
2644            Expression::JSONBool(_) => "j_s_o_n_bool",
2645            Expression::JSONPathRoot(_) => "j_s_o_n_path_root",
2646            Expression::JSONArrayAppend(_) => "j_s_o_n_array_append",
2647            Expression::JSONArrayContains(_) => "j_s_o_n_array_contains",
2648            Expression::JSONArrayInsert(_) => "j_s_o_n_array_insert",
2649            Expression::ParseJSON(_) => "parse_j_s_o_n",
2650            Expression::ParseUrl(_) => "parse_url",
2651            Expression::ParseIp(_) => "parse_ip",
2652            Expression::ParseTime(_) => "parse_time",
2653            Expression::ParseDatetime(_) => "parse_datetime",
2654            Expression::Map(_) => "map",
2655            Expression::MapCat(_) => "map_cat",
2656            Expression::MapDelete(_) => "map_delete",
2657            Expression::MapInsert(_) => "map_insert",
2658            Expression::MapPick(_) => "map_pick",
2659            Expression::ScopeResolution(_) => "scope_resolution",
2660            Expression::Slice(_) => "slice",
2661            Expression::VarMap(_) => "var_map",
2662            Expression::MatchAgainst(_) => "match_against",
2663            Expression::MD5Digest(_) => "m_d5_digest",
2664            Expression::MD5NumberLower64(_) => "m_d5_number_lower64",
2665            Expression::MD5NumberUpper64(_) => "m_d5_number_upper64",
2666            Expression::Monthname(_) => "monthname",
2667            Expression::Ntile(_) => "ntile",
2668            Expression::Normalize(_) => "normalize",
2669            Expression::Normal(_) => "normal",
2670            Expression::Predict(_) => "predict",
2671            Expression::MLTranslate(_) => "m_l_translate",
2672            Expression::FeaturesAtTime(_) => "features_at_time",
2673            Expression::GenerateEmbedding(_) => "generate_embedding",
2674            Expression::MLForecast(_) => "m_l_forecast",
2675            Expression::ModelAttribute(_) => "model_attribute",
2676            Expression::VectorSearch(_) => "vector_search",
2677            Expression::Quantile(_) => "quantile",
2678            Expression::ApproxQuantile(_) => "approx_quantile",
2679            Expression::ApproxPercentileEstimate(_) => "approx_percentile_estimate",
2680            Expression::Randn(_) => "randn",
2681            Expression::Randstr(_) => "randstr",
2682            Expression::RangeN(_) => "range_n",
2683            Expression::RangeBucket(_) => "range_bucket",
2684            Expression::ReadCSV(_) => "read_c_s_v",
2685            Expression::ReadParquet(_) => "read_parquet",
2686            Expression::Reduce(_) => "reduce",
2687            Expression::RegexpExtractAll(_) => "regexp_extract_all",
2688            Expression::RegexpILike(_) => "regexp_i_like",
2689            Expression::RegexpFullMatch(_) => "regexp_full_match",
2690            Expression::RegexpInstr(_) => "regexp_instr",
2691            Expression::RegexpSplit(_) => "regexp_split",
2692            Expression::RegexpCount(_) => "regexp_count",
2693            Expression::RegrValx(_) => "regr_valx",
2694            Expression::RegrValy(_) => "regr_valy",
2695            Expression::RegrAvgy(_) => "regr_avgy",
2696            Expression::RegrAvgx(_) => "regr_avgx",
2697            Expression::RegrCount(_) => "regr_count",
2698            Expression::RegrIntercept(_) => "regr_intercept",
2699            Expression::RegrR2(_) => "regr_r2",
2700            Expression::RegrSxx(_) => "regr_sxx",
2701            Expression::RegrSxy(_) => "regr_sxy",
2702            Expression::RegrSyy(_) => "regr_syy",
2703            Expression::RegrSlope(_) => "regr_slope",
2704            Expression::SafeAdd(_) => "safe_add",
2705            Expression::SafeDivide(_) => "safe_divide",
2706            Expression::SafeMultiply(_) => "safe_multiply",
2707            Expression::SafeSubtract(_) => "safe_subtract",
2708            Expression::SHA2(_) => "s_h_a2",
2709            Expression::SHA2Digest(_) => "s_h_a2_digest",
2710            Expression::SortArray(_) => "sort_array",
2711            Expression::SplitPart(_) => "split_part",
2712            Expression::SubstringIndex(_) => "substring_index",
2713            Expression::StandardHash(_) => "standard_hash",
2714            Expression::StrPosition(_) => "str_position",
2715            Expression::Search(_) => "search",
2716            Expression::SearchIp(_) => "search_ip",
2717            Expression::StrToDate(_) => "str_to_date",
2718            Expression::DateStrToDate(_) => "date_str_to_date",
2719            Expression::DateToDateStr(_) => "date_to_date_str",
2720            Expression::StrToTime(_) => "str_to_time",
2721            Expression::StrToUnix(_) => "str_to_unix",
2722            Expression::StrToMap(_) => "str_to_map",
2723            Expression::NumberToStr(_) => "number_to_str",
2724            Expression::FromBase(_) => "from_base",
2725            Expression::Stuff(_) => "stuff",
2726            Expression::TimeToStr(_) => "time_to_str",
2727            Expression::TimeStrToTime(_) => "time_str_to_time",
2728            Expression::TsOrDsAdd(_) => "ts_or_ds_add",
2729            Expression::TsOrDsDiff(_) => "ts_or_ds_diff",
2730            Expression::TsOrDsToDate(_) => "ts_or_ds_to_date",
2731            Expression::TsOrDsToTime(_) => "ts_or_ds_to_time",
2732            Expression::Unhex(_) => "unhex",
2733            Expression::Uniform(_) => "uniform",
2734            Expression::UnixToStr(_) => "unix_to_str",
2735            Expression::UnixToTime(_) => "unix_to_time",
2736            Expression::Uuid(_) => "uuid",
2737            Expression::TimestampFromParts(_) => "timestamp_from_parts",
2738            Expression::TimestampTzFromParts(_) => "timestamp_tz_from_parts",
2739            Expression::Corr(_) => "corr",
2740            Expression::WidthBucket(_) => "width_bucket",
2741            Expression::CovarSamp(_) => "covar_samp",
2742            Expression::CovarPop(_) => "covar_pop",
2743            Expression::Week(_) => "week",
2744            Expression::XMLElement(_) => "x_m_l_element",
2745            Expression::XMLGet(_) => "x_m_l_get",
2746            Expression::XMLTable(_) => "x_m_l_table",
2747            Expression::XMLKeyValueOption(_) => "x_m_l_key_value_option",
2748            Expression::Zipf(_) => "zipf",
2749            Expression::Merge(_) => "merge",
2750            Expression::When(_) => "when",
2751            Expression::Whens(_) => "whens",
2752            Expression::NextValueFor(_) => "next_value_for",
2753            Expression::ReturnStmt(_) => "return_stmt",
2754        }
2755    }
2756
2757    /// Returns the primary child expression (".this" in sqlglot).
2758    pub fn get_this(&self) -> Option<&Expression> {
2759        match self {
2760            // Unary ops
2761            Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this),
2762            // UnaryFunc variants
2763            Expression::Upper(f)
2764            | Expression::Lower(f)
2765            | Expression::Length(f)
2766            | Expression::LTrim(f)
2767            | Expression::RTrim(f)
2768            | Expression::Reverse(f)
2769            | Expression::Abs(f)
2770            | Expression::Sqrt(f)
2771            | Expression::Cbrt(f)
2772            | Expression::Ln(f)
2773            | Expression::Exp(f)
2774            | Expression::Sign(f)
2775            | Expression::Date(f)
2776            | Expression::Time(f)
2777            | Expression::Initcap(f)
2778            | Expression::Ascii(f)
2779            | Expression::Chr(f)
2780            | Expression::Soundex(f)
2781            | Expression::ByteLength(f)
2782            | Expression::Hex(f)
2783            | Expression::LowerHex(f)
2784            | Expression::Unicode(f)
2785            | Expression::Typeof(f)
2786            | Expression::Explode(f)
2787            | Expression::ExplodeOuter(f)
2788            | Expression::MapFromEntries(f)
2789            | Expression::MapKeys(f)
2790            | Expression::MapValues(f)
2791            | Expression::ArrayLength(f)
2792            | Expression::ArraySize(f)
2793            | Expression::Cardinality(f)
2794            | Expression::ArrayReverse(f)
2795            | Expression::ArrayDistinct(f)
2796            | Expression::ArrayFlatten(f)
2797            | Expression::ArrayCompact(f)
2798            | Expression::ToArray(f)
2799            | Expression::JsonArrayLength(f)
2800            | Expression::JsonKeys(f)
2801            | Expression::JsonType(f)
2802            | Expression::ParseJson(f)
2803            | Expression::ToJson(f)
2804            | Expression::Radians(f)
2805            | Expression::Degrees(f)
2806            | Expression::Sin(f)
2807            | Expression::Cos(f)
2808            | Expression::Tan(f)
2809            | Expression::Asin(f)
2810            | Expression::Acos(f)
2811            | Expression::Atan(f)
2812            | Expression::IsNan(f)
2813            | Expression::IsInf(f)
2814            | Expression::Year(f)
2815            | Expression::Month(f)
2816            | Expression::Day(f)
2817            | Expression::Hour(f)
2818            | Expression::Minute(f)
2819            | Expression::Second(f)
2820            | Expression::DayOfWeek(f)
2821            | Expression::DayOfWeekIso(f)
2822            | Expression::DayOfMonth(f)
2823            | Expression::DayOfYear(f)
2824            | Expression::WeekOfYear(f)
2825            | Expression::Quarter(f)
2826            | Expression::Epoch(f)
2827            | Expression::EpochMs(f)
2828            | Expression::BitwiseCount(f)
2829            | Expression::DateFromUnixDate(f)
2830            | Expression::UnixDate(f)
2831            | Expression::UnixSeconds(f)
2832            | Expression::UnixMillis(f)
2833            | Expression::UnixMicros(f)
2834            | Expression::TimeStrToDate(f)
2835            | Expression::DateToDi(f)
2836            | Expression::DiToDate(f)
2837            | Expression::TsOrDiToDi(f)
2838            | Expression::TsOrDsToDatetime(f)
2839            | Expression::TsOrDsToTimestamp(f)
2840            | Expression::YearOfWeek(f)
2841            | Expression::YearOfWeekIso(f)
2842            | Expression::SHA(f)
2843            | Expression::SHA1Digest(f)
2844            | Expression::TimeToUnix(f)
2845            | Expression::TimeStrToUnix(f)
2846            | Expression::Int64(f)
2847            | Expression::JSONBool(f)
2848            | Expression::MD5NumberLower64(f)
2849            | Expression::MD5NumberUpper64(f)
2850            | Expression::DateStrToDate(f)
2851            | Expression::DateToDateStr(f) => Some(&f.this),
2852            // BinaryFunc - this is the primary child
2853            Expression::Power(f)
2854            | Expression::NullIf(f)
2855            | Expression::IfNull(f)
2856            | Expression::Nvl(f)
2857            | Expression::Contains(f)
2858            | Expression::StartsWith(f)
2859            | Expression::EndsWith(f)
2860            | Expression::Levenshtein(f)
2861            | Expression::ModFunc(f)
2862            | Expression::IntDiv(f)
2863            | Expression::Atan2(f)
2864            | Expression::AddMonths(f)
2865            | Expression::MonthsBetween(f)
2866            | Expression::NextDay(f)
2867            | Expression::UnixToTimeStr(f)
2868            | Expression::ArrayContains(f)
2869            | Expression::ArrayPosition(f)
2870            | Expression::ArrayAppend(f)
2871            | Expression::ArrayPrepend(f)
2872            | Expression::ArrayUnion(f)
2873            | Expression::ArrayExcept(f)
2874            | Expression::ArrayRemove(f)
2875            | Expression::StarMap(f)
2876            | Expression::MapFromArrays(f)
2877            | Expression::MapContainsKey(f)
2878            | Expression::ElementAt(f)
2879            | Expression::JsonMergePatch(f)
2880            | Expression::JSONBContains(f)
2881            | Expression::JSONBExtract(f) => Some(&f.this),
2882            // AggFunc - this is the primary child
2883            Expression::Sum(af)
2884            | Expression::Avg(af)
2885            | Expression::Min(af)
2886            | Expression::Max(af)
2887            | Expression::ArrayAgg(af)
2888            | Expression::CountIf(af)
2889            | Expression::Stddev(af)
2890            | Expression::StddevPop(af)
2891            | Expression::StddevSamp(af)
2892            | Expression::Variance(af)
2893            | Expression::VarPop(af)
2894            | Expression::VarSamp(af)
2895            | Expression::Median(af)
2896            | Expression::Mode(af)
2897            | Expression::First(af)
2898            | Expression::Last(af)
2899            | Expression::AnyValue(af)
2900            | Expression::ApproxDistinct(af)
2901            | Expression::ApproxCountDistinct(af)
2902            | Expression::LogicalAnd(af)
2903            | Expression::LogicalOr(af)
2904            | Expression::Skewness(af)
2905            | Expression::ArrayConcatAgg(af)
2906            | Expression::ArrayUniqueAgg(af)
2907            | Expression::BoolXorAgg(af)
2908            | Expression::BitwiseAndAgg(af)
2909            | Expression::BitwiseOrAgg(af)
2910            | Expression::BitwiseXorAgg(af) => Some(&af.this),
2911            // Binary operations - left is "this" in sqlglot
2912            Expression::And(op)
2913            | Expression::Or(op)
2914            | Expression::Add(op)
2915            | Expression::Sub(op)
2916            | Expression::Mul(op)
2917            | Expression::Div(op)
2918            | Expression::Mod(op)
2919            | Expression::Eq(op)
2920            | Expression::Neq(op)
2921            | Expression::Lt(op)
2922            | Expression::Lte(op)
2923            | Expression::Gt(op)
2924            | Expression::Gte(op)
2925            | Expression::BitwiseAnd(op)
2926            | Expression::BitwiseOr(op)
2927            | Expression::BitwiseXor(op)
2928            | Expression::Concat(op)
2929            | Expression::Adjacent(op)
2930            | Expression::TsMatch(op)
2931            | Expression::PropertyEQ(op)
2932            | Expression::ArrayContainsAll(op)
2933            | Expression::ArrayContainedBy(op)
2934            | Expression::ArrayOverlaps(op)
2935            | Expression::JSONBContainsAllTopKeys(op)
2936            | Expression::JSONBContainsAnyTopKeys(op)
2937            | Expression::JSONBDeleteAtPath(op)
2938            | Expression::ExtendsLeft(op)
2939            | Expression::ExtendsRight(op)
2940            | Expression::Is(op)
2941            | Expression::MemberOf(op)
2942            | Expression::Match(op)
2943            | Expression::NullSafeEq(op)
2944            | Expression::NullSafeNeq(op)
2945            | Expression::Glob(op)
2946            | Expression::BitwiseLeftShift(op)
2947            | Expression::BitwiseRightShift(op) => Some(&op.left),
2948            // Like operations - left is "this"
2949            Expression::Like(op) | Expression::ILike(op) => Some(&op.left),
2950            // Structural types with .this
2951            Expression::Alias(a) => Some(&a.this),
2952            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => Some(&c.this),
2953            Expression::Paren(p) => Some(&p.this),
2954            Expression::Annotated(a) => Some(&a.this),
2955            Expression::Subquery(s) => Some(&s.this),
2956            Expression::Where(w) => Some(&w.this),
2957            Expression::Having(h) => Some(&h.this),
2958            Expression::Qualify(q) => Some(&q.this),
2959            Expression::IsNull(i) => Some(&i.this),
2960            Expression::Exists(e) => Some(&e.this),
2961            Expression::Ordered(o) => Some(&o.this),
2962            Expression::WindowFunction(wf) => Some(&wf.this),
2963            Expression::Cte(cte) => Some(&cte.this),
2964            Expression::Between(b) => Some(&b.this),
2965            Expression::In(i) => Some(&i.this),
2966            Expression::ReturnStmt(e) => Some(e),
2967            _ => None,
2968        }
2969    }
2970
2971    /// Returns the secondary child expression (".expression" in sqlglot).
2972    pub fn get_expression(&self) -> Option<&Expression> {
2973        match self {
2974            // Binary operations - right is "expression"
2975            Expression::And(op)
2976            | Expression::Or(op)
2977            | Expression::Add(op)
2978            | Expression::Sub(op)
2979            | Expression::Mul(op)
2980            | Expression::Div(op)
2981            | Expression::Mod(op)
2982            | Expression::Eq(op)
2983            | Expression::Neq(op)
2984            | Expression::Lt(op)
2985            | Expression::Lte(op)
2986            | Expression::Gt(op)
2987            | Expression::Gte(op)
2988            | Expression::BitwiseAnd(op)
2989            | Expression::BitwiseOr(op)
2990            | Expression::BitwiseXor(op)
2991            | Expression::Concat(op)
2992            | Expression::Adjacent(op)
2993            | Expression::TsMatch(op)
2994            | Expression::PropertyEQ(op)
2995            | Expression::ArrayContainsAll(op)
2996            | Expression::ArrayContainedBy(op)
2997            | Expression::ArrayOverlaps(op)
2998            | Expression::JSONBContainsAllTopKeys(op)
2999            | Expression::JSONBContainsAnyTopKeys(op)
3000            | Expression::JSONBDeleteAtPath(op)
3001            | Expression::ExtendsLeft(op)
3002            | Expression::ExtendsRight(op)
3003            | Expression::Is(op)
3004            | Expression::MemberOf(op)
3005            | Expression::Match(op)
3006            | Expression::NullSafeEq(op)
3007            | Expression::NullSafeNeq(op)
3008            | Expression::Glob(op)
3009            | Expression::BitwiseLeftShift(op)
3010            | Expression::BitwiseRightShift(op) => Some(&op.right),
3011            // Like operations - right is "expression"
3012            Expression::Like(op) | Expression::ILike(op) => Some(&op.right),
3013            // BinaryFunc - expression is the secondary
3014            Expression::Power(f)
3015            | Expression::NullIf(f)
3016            | Expression::IfNull(f)
3017            | Expression::Nvl(f)
3018            | Expression::Contains(f)
3019            | Expression::StartsWith(f)
3020            | Expression::EndsWith(f)
3021            | Expression::Levenshtein(f)
3022            | Expression::ModFunc(f)
3023            | Expression::IntDiv(f)
3024            | Expression::Atan2(f)
3025            | Expression::AddMonths(f)
3026            | Expression::MonthsBetween(f)
3027            | Expression::NextDay(f)
3028            | Expression::UnixToTimeStr(f)
3029            | Expression::ArrayContains(f)
3030            | Expression::ArrayPosition(f)
3031            | Expression::ArrayAppend(f)
3032            | Expression::ArrayPrepend(f)
3033            | Expression::ArrayUnion(f)
3034            | Expression::ArrayExcept(f)
3035            | Expression::ArrayRemove(f)
3036            | Expression::StarMap(f)
3037            | Expression::MapFromArrays(f)
3038            | Expression::MapContainsKey(f)
3039            | Expression::ElementAt(f)
3040            | Expression::JsonMergePatch(f)
3041            | Expression::JSONBContains(f)
3042            | Expression::JSONBExtract(f) => Some(&f.expression),
3043            _ => None,
3044        }
3045    }
3046
3047    /// Returns the list of child expressions (".expressions" in sqlglot).
3048    pub fn get_expressions(&self) -> &[Expression] {
3049        match self {
3050            Expression::Select(s) => &s.expressions,
3051            Expression::Function(f) => &f.args,
3052            Expression::AggregateFunction(f) => &f.args,
3053            Expression::From(f) => &f.expressions,
3054            Expression::GroupBy(g) => &g.expressions,
3055            Expression::In(i) => &i.expressions,
3056            Expression::Array(a) => &a.expressions,
3057            Expression::Tuple(t) => &t.expressions,
3058            Expression::Coalesce(f)
3059            | Expression::Greatest(f)
3060            | Expression::Least(f)
3061            | Expression::ArrayConcat(f)
3062            | Expression::ArrayIntersect(f)
3063            | Expression::ArrayZip(f)
3064            | Expression::MapConcat(f)
3065            | Expression::JsonArray(f) => &f.expressions,
3066            _ => &[],
3067        }
3068    }
3069
3070    /// Returns the name of this expression as a string slice.
3071    pub fn get_name(&self) -> &str {
3072        match self {
3073            Expression::Identifier(id) => &id.name,
3074            Expression::Column(col) => &col.name.name,
3075            Expression::Table(t) => &t.name.name,
3076            Expression::Literal(lit) => lit.value_str(),
3077            Expression::Star(_) => "*",
3078            Expression::Function(f) => &f.name,
3079            Expression::AggregateFunction(f) => &f.name,
3080            Expression::Alias(a) => a.this.get_name(),
3081            Expression::Boolean(b) => {
3082                if b.value {
3083                    "TRUE"
3084                } else {
3085                    "FALSE"
3086                }
3087            }
3088            Expression::Null(_) => "NULL",
3089            _ => "",
3090        }
3091    }
3092
3093    /// Returns the alias name if this expression has one.
3094    pub fn get_alias(&self) -> &str {
3095        match self {
3096            Expression::Alias(a) => &a.alias.name,
3097            Expression::Table(t) => t.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3098            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3099            _ => "",
3100        }
3101    }
3102
3103    /// Returns the output name of this expression (what it shows up as in a SELECT).
3104    pub fn get_output_name(&self) -> &str {
3105        match self {
3106            Expression::Alias(a) => &a.alias.name,
3107            Expression::Column(c) => &c.name.name,
3108            Expression::Identifier(id) => &id.name,
3109            Expression::Literal(lit) => lit.value_str(),
3110            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3111            Expression::Star(_) => "*",
3112            _ => "",
3113        }
3114    }
3115
3116    /// Returns comments attached to this expression.
3117    pub fn get_comments(&self) -> Vec<&str> {
3118        match self {
3119            Expression::Identifier(id) => id.trailing_comments.iter().map(|s| s.as_str()).collect(),
3120            Expression::Column(c) => c.trailing_comments.iter().map(|s| s.as_str()).collect(),
3121            Expression::Star(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3122            Expression::Paren(p) => p.trailing_comments.iter().map(|s| s.as_str()).collect(),
3123            Expression::Annotated(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3124            Expression::Alias(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3125            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
3126                c.trailing_comments.iter().map(|s| s.as_str()).collect()
3127            }
3128            Expression::And(op)
3129            | Expression::Or(op)
3130            | Expression::Add(op)
3131            | Expression::Sub(op)
3132            | Expression::Mul(op)
3133            | Expression::Div(op)
3134            | Expression::Mod(op)
3135            | Expression::Eq(op)
3136            | Expression::Neq(op)
3137            | Expression::Lt(op)
3138            | Expression::Lte(op)
3139            | Expression::Gt(op)
3140            | Expression::Gte(op)
3141            | Expression::Concat(op)
3142            | Expression::BitwiseAnd(op)
3143            | Expression::BitwiseOr(op)
3144            | Expression::BitwiseXor(op) => {
3145                op.trailing_comments.iter().map(|s| s.as_str()).collect()
3146            }
3147            Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(),
3148            Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3149            _ => Vec::new(),
3150        }
3151    }
3152}
3153
3154impl fmt::Display for Expression {
3155    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3156        // Basic display - full SQL generation is in generator module
3157        match self {
3158            Expression::Literal(lit) => write!(f, "{}", lit),
3159            Expression::Identifier(id) => write!(f, "{}", id),
3160            Expression::Column(col) => write!(f, "{}", col),
3161            Expression::Star(_) => write!(f, "*"),
3162            Expression::Null(_) => write!(f, "NULL"),
3163            Expression::Boolean(b) => write!(f, "{}", if b.value { "TRUE" } else { "FALSE" }),
3164            Expression::Select(_) => write!(f, "SELECT ..."),
3165            _ => write!(f, "{:?}", self),
3166        }
3167    }
3168}
3169
3170/// Represent a SQL literal value.
3171///
3172/// Numeric values are stored as their original text representation (not parsed
3173/// to `i64`/`f64`) so that precision, trailing zeros, and hex notation are
3174/// preserved across round-trips.
3175///
3176/// Dialect-specific literal forms (triple-quoted strings, dollar-quoted
3177/// strings, raw strings, etc.) each have a dedicated variant so that the
3178/// generator can emit them with the correct syntax.
3179#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3180#[cfg_attr(feature = "bindings", derive(TS))]
3181#[serde(tag = "literal_type", content = "value", rename_all = "snake_case")]
3182pub enum Literal {
3183    /// Single-quoted string literal: `'hello'`
3184    String(String),
3185    /// Numeric literal, stored as the original text: `42`, `3.14`, `1e10`
3186    Number(String),
3187    /// Hex string literal: `X'FF'`
3188    HexString(String),
3189    /// Hex number: 0xA, 0xFF (BigQuery, SQLite style) - represents an integer in hex notation
3190    HexNumber(String),
3191    BitString(String),
3192    /// Byte string: b"..." (BigQuery style)
3193    ByteString(String),
3194    /// National string: N'abc'
3195    NationalString(String),
3196    /// DATE literal: DATE '2024-01-15'
3197    Date(String),
3198    /// TIME literal: TIME '10:30:00'
3199    Time(String),
3200    /// TIMESTAMP literal: TIMESTAMP '2024-01-15 10:30:00'
3201    Timestamp(String),
3202    /// DATETIME literal: DATETIME '2024-01-15 10:30:00' (BigQuery)
3203    Datetime(String),
3204    /// Triple-quoted string: """...""" or '''...'''
3205    /// Contains (content, quote_char) where quote_char is '"' or '\''
3206    TripleQuotedString(String, char),
3207    /// Escape string: E'...' (PostgreSQL)
3208    EscapeString(String),
3209    /// Dollar-quoted string: $$...$$  (PostgreSQL)
3210    DollarString(String),
3211    /// Raw string: r"..." or r'...' (BigQuery, Spark, Databricks)
3212    /// In raw strings, backslashes are literal and not escape characters.
3213    /// When converting to a regular string, backslashes must be doubled.
3214    RawString(String),
3215}
3216
3217impl Literal {
3218    /// Returns the inner value as a string slice, regardless of literal type.
3219    pub fn value_str(&self) -> &str {
3220        match self {
3221            Literal::String(s)
3222            | Literal::Number(s)
3223            | Literal::HexString(s)
3224            | Literal::HexNumber(s)
3225            | Literal::BitString(s)
3226            | Literal::ByteString(s)
3227            | Literal::NationalString(s)
3228            | Literal::Date(s)
3229            | Literal::Time(s)
3230            | Literal::Timestamp(s)
3231            | Literal::Datetime(s)
3232            | Literal::EscapeString(s)
3233            | Literal::DollarString(s)
3234            | Literal::RawString(s) => s.as_str(),
3235            Literal::TripleQuotedString(s, _) => s.as_str(),
3236        }
3237    }
3238
3239    /// Returns `true` if this is a string-type literal.
3240    pub fn is_string(&self) -> bool {
3241        matches!(
3242            self,
3243            Literal::String(_)
3244                | Literal::NationalString(_)
3245                | Literal::EscapeString(_)
3246                | Literal::DollarString(_)
3247                | Literal::RawString(_)
3248                | Literal::TripleQuotedString(_, _)
3249        )
3250    }
3251
3252    /// Returns `true` if this is a numeric literal.
3253    pub fn is_number(&self) -> bool {
3254        matches!(self, Literal::Number(_) | Literal::HexNumber(_))
3255    }
3256}
3257
3258impl fmt::Display for Literal {
3259    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3260        match self {
3261            Literal::String(s) => write!(f, "'{}'", s),
3262            Literal::Number(n) => write!(f, "{}", n),
3263            Literal::HexString(h) => write!(f, "X'{}'", h),
3264            Literal::HexNumber(h) => write!(f, "0x{}", h),
3265            Literal::BitString(b) => write!(f, "B'{}'", b),
3266            Literal::ByteString(b) => write!(f, "b'{}'", b),
3267            Literal::NationalString(s) => write!(f, "N'{}'", s),
3268            Literal::Date(d) => write!(f, "DATE '{}'", d),
3269            Literal::Time(t) => write!(f, "TIME '{}'", t),
3270            Literal::Timestamp(ts) => write!(f, "TIMESTAMP '{}'", ts),
3271            Literal::Datetime(dt) => write!(f, "DATETIME '{}'", dt),
3272            Literal::TripleQuotedString(s, q) => {
3273                write!(f, "{0}{0}{0}{1}{0}{0}{0}", q, s)
3274            }
3275            Literal::EscapeString(s) => write!(f, "E'{}'", s),
3276            Literal::DollarString(s) => write!(f, "$${}$$", s),
3277            Literal::RawString(s) => write!(f, "r'{}'", s),
3278        }
3279    }
3280}
3281
3282/// Boolean literal
3283#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3284#[cfg_attr(feature = "bindings", derive(TS))]
3285pub struct BooleanLiteral {
3286    pub value: bool,
3287}
3288
3289/// NULL literal
3290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3291#[cfg_attr(feature = "bindings", derive(TS))]
3292pub struct Null;
3293
3294/// Represent a SQL identifier (table name, column name, alias, keyword-as-name, etc.).
3295///
3296/// The `quoted` flag indicates whether the identifier was originally delimited
3297/// (double-quoted, backtick-quoted, or bracket-quoted depending on the
3298/// dialect). The generator uses this flag to decide whether to emit quoting
3299/// characters.
3300#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3301#[cfg_attr(feature = "bindings", derive(TS))]
3302pub struct Identifier {
3303    /// The raw text of the identifier, without any quoting characters.
3304    pub name: String,
3305    /// Whether the identifier was quoted in the source SQL.
3306    pub quoted: bool,
3307    #[serde(default)]
3308    pub trailing_comments: Vec<String>,
3309    /// Source position span (populated during parsing, None for programmatically constructed nodes)
3310    #[serde(default, skip_serializing_if = "Option::is_none")]
3311    pub span: Option<Span>,
3312}
3313
3314impl Identifier {
3315    pub fn new(name: impl Into<String>) -> Self {
3316        Self {
3317            name: name.into(),
3318            quoted: false,
3319            trailing_comments: Vec::new(),
3320            span: None,
3321        }
3322    }
3323
3324    pub fn quoted(name: impl Into<String>) -> Self {
3325        Self {
3326            name: name.into(),
3327            quoted: true,
3328            trailing_comments: Vec::new(),
3329            span: None,
3330        }
3331    }
3332
3333    pub fn empty() -> Self {
3334        Self {
3335            name: String::new(),
3336            quoted: false,
3337            trailing_comments: Vec::new(),
3338            span: None,
3339        }
3340    }
3341
3342    pub fn is_empty(&self) -> bool {
3343        self.name.is_empty()
3344    }
3345
3346    /// Set the source span on this identifier
3347    pub fn with_span(mut self, span: Span) -> Self {
3348        self.span = Some(span);
3349        self
3350    }
3351}
3352
3353impl fmt::Display for Identifier {
3354    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3355        if self.quoted {
3356            write!(f, "\"{}\"", self.name)
3357        } else {
3358            write!(f, "{}", self.name)
3359        }
3360    }
3361}
3362
3363/// Represent a column reference, optionally qualified by a table name.
3364///
3365/// Renders as `name` when unqualified, or `table.name` when qualified.
3366/// Use [`Expression::column()`] or [`Expression::qualified_column()`] for
3367/// convenient construction.
3368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3369#[cfg_attr(feature = "bindings", derive(TS))]
3370pub struct Column {
3371    /// The column name.
3372    pub name: Identifier,
3373    /// Optional table qualifier (e.g. `t` in `t.col`).
3374    pub table: Option<Identifier>,
3375    /// Oracle-style join marker (+) for outer joins
3376    #[serde(default)]
3377    pub join_mark: bool,
3378    /// Trailing comments that appeared after this column reference
3379    #[serde(default)]
3380    pub trailing_comments: Vec<String>,
3381    /// Source position span
3382    #[serde(default, skip_serializing_if = "Option::is_none")]
3383    pub span: Option<Span>,
3384    /// Inferred data type from type annotation
3385    #[serde(default, skip_serializing_if = "Option::is_none")]
3386    #[ast(skip)]
3387    pub inferred_type: Option<DataType>,
3388}
3389
3390impl fmt::Display for Column {
3391    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3392        if let Some(table) = &self.table {
3393            write!(f, "{}.{}", table, self.name)
3394        } else {
3395            write!(f, "{}", self.name)
3396        }
3397    }
3398}
3399
3400/// Represent a table reference with optional schema and catalog qualifiers.
3401///
3402/// Renders as `name`, `schema.name`, or `catalog.schema.name` depending on
3403/// which qualifiers are present. Supports aliases, column alias lists,
3404/// time-travel clauses (Snowflake, BigQuery), table hints (TSQL), and
3405/// several other dialect-specific extensions.
3406#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3407#[cfg_attr(feature = "bindings", derive(TS))]
3408pub struct TableRef {
3409    /// The unqualified table name.
3410    pub name: Identifier,
3411    /// Optional schema qualifier (e.g. `public` in `public.users`).
3412    pub schema: Option<Identifier>,
3413    /// Optional catalog qualifier (e.g. `mydb` in `mydb.public.users`).
3414    pub catalog: Option<Identifier>,
3415    /// Optional table alias (e.g. `t` in `FROM users AS t`).
3416    pub alias: Option<Identifier>,
3417    /// Whether AS keyword was explicitly used for the alias
3418    #[serde(default)]
3419    pub alias_explicit_as: bool,
3420    /// Column aliases for table alias: AS t(c1, c2)
3421    #[serde(default)]
3422    pub column_aliases: Vec<Identifier>,
3423    /// Leading comments that appeared before this table reference in a FROM clause
3424    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3425    pub leading_comments: Vec<String>,
3426    /// Trailing comments that appeared after this table reference
3427    #[serde(default)]
3428    pub trailing_comments: Vec<String>,
3429    /// Snowflake time travel: BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
3430    #[serde(default)]
3431    pub when: Option<Box<HistoricalData>>,
3432    /// PostgreSQL ONLY modifier: prevents scanning child tables in inheritance hierarchy
3433    #[serde(default)]
3434    pub only: bool,
3435    /// ClickHouse FINAL modifier: forces final aggregation for MergeTree tables
3436    #[serde(default)]
3437    pub final_: bool,
3438    /// TABLESAMPLE clause attached to this table reference (DuckDB, BigQuery)
3439    #[serde(default, skip_serializing_if = "Option::is_none")]
3440    pub table_sample: Option<Box<Sample>>,
3441    /// TSQL table hints: WITH (TABLOCK, INDEX(myindex), ...)
3442    #[serde(default)]
3443    pub hints: Vec<Expression>,
3444    /// TSQL: FOR SYSTEM_TIME temporal clause
3445    /// Contains the full clause text, e.g., "FOR SYSTEM_TIME BETWEEN c AND d"
3446    #[serde(default, skip_serializing_if = "Option::is_none")]
3447    pub system_time: Option<String>,
3448    /// MySQL: PARTITION(p0, p1, ...) hint for reading from specific partitions
3449    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3450    pub partitions: Vec<Identifier>,
3451    /// Snowflake IDENTIFIER() function: dynamic table name from string/variable
3452    /// When set, this is used instead of the name field
3453    #[serde(default, skip_serializing_if = "Option::is_none")]
3454    pub identifier_func: Option<Box<Expression>>,
3455    /// Snowflake CHANGES clause: CHANGES (INFORMATION => ...) AT (...) END (...)
3456    #[serde(default, skip_serializing_if = "Option::is_none")]
3457    pub changes: Option<Box<Changes>>,
3458    /// Time travel version clause: FOR VERSION AS OF / FOR TIMESTAMP AS OF (Presto/Trino, BigQuery, Databricks)
3459    #[serde(default, skip_serializing_if = "Option::is_none")]
3460    pub version: Option<Box<Version>>,
3461    /// Source position span
3462    #[serde(default, skip_serializing_if = "Option::is_none")]
3463    pub span: Option<Span>,
3464}
3465
3466impl TableRef {
3467    pub fn new(name: impl Into<String>) -> Self {
3468        Self {
3469            name: Identifier::new(name),
3470            schema: None,
3471            catalog: None,
3472            alias: None,
3473            alias_explicit_as: false,
3474            column_aliases: Vec::new(),
3475            leading_comments: Vec::new(),
3476            trailing_comments: Vec::new(),
3477            when: None,
3478            only: false,
3479            final_: false,
3480            table_sample: None,
3481            hints: Vec::new(),
3482            system_time: None,
3483            partitions: Vec::new(),
3484            identifier_func: None,
3485            changes: None,
3486            version: None,
3487            span: None,
3488        }
3489    }
3490
3491    /// Create with a schema qualifier.
3492    pub fn new_with_schema(name: impl Into<String>, schema: impl Into<String>) -> Self {
3493        let mut t = Self::new(name);
3494        t.schema = Some(Identifier::new(schema));
3495        t
3496    }
3497
3498    /// Create with catalog and schema qualifiers.
3499    pub fn new_with_catalog(
3500        name: impl Into<String>,
3501        schema: impl Into<String>,
3502        catalog: impl Into<String>,
3503    ) -> Self {
3504        let mut t = Self::new(name);
3505        t.schema = Some(Identifier::new(schema));
3506        t.catalog = Some(Identifier::new(catalog));
3507        t
3508    }
3509
3510    /// Create from an Identifier, preserving the quoted flag
3511    pub fn from_identifier(name: Identifier) -> Self {
3512        Self {
3513            name,
3514            schema: None,
3515            catalog: None,
3516            alias: None,
3517            alias_explicit_as: false,
3518            column_aliases: Vec::new(),
3519            leading_comments: Vec::new(),
3520            trailing_comments: Vec::new(),
3521            when: None,
3522            only: false,
3523            final_: false,
3524            table_sample: None,
3525            hints: Vec::new(),
3526            system_time: None,
3527            partitions: Vec::new(),
3528            identifier_func: None,
3529            changes: None,
3530            version: None,
3531            span: None,
3532        }
3533    }
3534
3535    pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
3536        self.alias = Some(Identifier::new(alias));
3537        self
3538    }
3539
3540    pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
3541        self.schema = Some(Identifier::new(schema));
3542        self
3543    }
3544}
3545
3546/// Represent a wildcard star expression (`*`, `table.*`).
3547///
3548/// Supports the EXCEPT/EXCLUDE, REPLACE, and RENAME modifiers found in
3549/// DuckDB, BigQuery, and Snowflake (e.g. `SELECT * EXCEPT (id) FROM t`).
3550#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3551#[cfg_attr(feature = "bindings", derive(TS))]
3552pub struct Star {
3553    /// Optional table qualifier (e.g. `t` in `t.*`).
3554    pub table: Option<Identifier>,
3555    /// EXCLUDE / EXCEPT columns (DuckDB, BigQuery, Snowflake)
3556    pub except: Option<Vec<Identifier>>,
3557    /// REPLACE expressions (BigQuery, Snowflake)
3558    pub replace: Option<Vec<Alias>>,
3559    /// RENAME columns (Snowflake)
3560    pub rename: Option<Vec<(Identifier, Identifier)>>,
3561    /// Trailing comments that appeared after the star
3562    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3563    pub trailing_comments: Vec<String>,
3564    /// Source position span
3565    #[serde(default, skip_serializing_if = "Option::is_none")]
3566    pub span: Option<Span>,
3567}
3568
3569/// Represent a complete SELECT statement.
3570///
3571/// This is the most feature-rich AST node, covering the full surface area of
3572/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3573/// `Vec` are omitted from the generated SQL when absent.
3574///
3575/// # Key Fields
3576///
3577/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3578/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3579/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3580/// - `where_clause` -- the WHERE predicate.
3581/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3582/// - `having` -- HAVING predicate.
3583/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3584/// - `limit` / `offset` / `fetch` -- result set limiting.
3585/// - `with` -- Common Table Expressions (CTEs).
3586/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3587/// - `windows` -- named window definitions (WINDOW w AS ...).
3588///
3589/// Dialect-specific extensions are supported via fields like `prewhere`
3590/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3591/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3593#[cfg_attr(feature = "bindings", derive(TS))]
3594pub struct Select {
3595    /// The select-list: columns, expressions, aliases, and wildcards.
3596    pub expressions: Vec<Expression>,
3597    /// The FROM clause, containing one or more table sources.
3598    pub from: Option<From>,
3599    /// JOIN clauses applied after the FROM source.
3600    pub joins: Vec<Join>,
3601    pub lateral_views: Vec<LateralView>,
3602    /// ClickHouse PREWHERE clause
3603    #[serde(default, skip_serializing_if = "Option::is_none")]
3604    pub prewhere: Option<Expression>,
3605    pub where_clause: Option<Where>,
3606    pub group_by: Option<GroupBy>,
3607    pub having: Option<Having>,
3608    pub qualify: Option<Qualify>,
3609    pub order_by: Option<OrderBy>,
3610    pub distribute_by: Option<DistributeBy>,
3611    pub cluster_by: Option<ClusterBy>,
3612    pub sort_by: Option<SortBy>,
3613    pub limit: Option<Limit>,
3614    pub offset: Option<Offset>,
3615    /// ClickHouse LIMIT BY clause expressions
3616    #[serde(default, skip_serializing_if = "Option::is_none")]
3617    pub limit_by: Option<Vec<Expression>>,
3618    pub fetch: Option<Fetch>,
3619    pub distinct: bool,
3620    pub distinct_on: Option<Vec<Expression>>,
3621    pub top: Option<Top>,
3622    pub with: Option<With>,
3623    pub sample: Option<Sample>,
3624    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3625    #[serde(default, skip_serializing_if = "Option::is_none")]
3626    pub settings: Option<Vec<Expression>>,
3627    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3628    #[serde(default, skip_serializing_if = "Option::is_none")]
3629    pub format: Option<Expression>,
3630    pub windows: Option<Vec<NamedWindow>>,
3631    pub hint: Option<Hint>,
3632    /// Oracle CONNECT BY clause for hierarchical queries
3633    pub connect: Option<Connect>,
3634    /// SELECT ... INTO table_name for creating tables
3635    pub into: Option<SelectInto>,
3636    /// FOR UPDATE/SHARE locking clauses
3637    #[serde(default)]
3638    pub locks: Vec<Lock>,
3639    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3640    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3641    pub for_xml: Vec<Expression>,
3642    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3643    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3644    pub for_json: Vec<Expression>,
3645    /// Leading comments before the statement
3646    #[serde(default)]
3647    pub leading_comments: Vec<String>,
3648    /// Comments that appear after SELECT keyword (before expressions)
3649    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3650    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3651    pub post_select_comments: Vec<String>,
3652    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3653    #[serde(default, skip_serializing_if = "Option::is_none")]
3654    pub kind: Option<String>,
3655    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3656    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3657    pub operation_modifiers: Vec<String>,
3658    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3659    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3660    pub qualify_after_window: bool,
3661    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3662    #[serde(default, skip_serializing_if = "Option::is_none")]
3663    pub option: Option<String>,
3664    /// Redshift-style EXCLUDE clause at the end of the projection list
3665    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3666    #[serde(default, skip_serializing_if = "Option::is_none")]
3667    pub exclude: Option<Vec<Expression>>,
3668}
3669
3670impl Select {
3671    pub fn new() -> Self {
3672        Self {
3673            expressions: Vec::new(),
3674            from: None,
3675            joins: Vec::new(),
3676            lateral_views: Vec::new(),
3677            prewhere: None,
3678            where_clause: None,
3679            group_by: None,
3680            having: None,
3681            qualify: None,
3682            order_by: None,
3683            distribute_by: None,
3684            cluster_by: None,
3685            sort_by: None,
3686            limit: None,
3687            offset: None,
3688            limit_by: None,
3689            fetch: None,
3690            distinct: false,
3691            distinct_on: None,
3692            top: None,
3693            with: None,
3694            sample: None,
3695            settings: None,
3696            format: None,
3697            windows: None,
3698            hint: None,
3699            connect: None,
3700            into: None,
3701            locks: Vec::new(),
3702            for_xml: Vec::new(),
3703            for_json: Vec::new(),
3704            leading_comments: Vec::new(),
3705            post_select_comments: Vec::new(),
3706            kind: None,
3707            operation_modifiers: Vec::new(),
3708            qualify_after_window: false,
3709            option: None,
3710            exclude: None,
3711        }
3712    }
3713
3714    /// Add a column to select
3715    pub fn column(mut self, expr: Expression) -> Self {
3716        self.expressions.push(expr);
3717        self
3718    }
3719
3720    /// Set the FROM clause
3721    pub fn from(mut self, table: Expression) -> Self {
3722        self.from = Some(From {
3723            expressions: vec![table],
3724        });
3725        self
3726    }
3727
3728    /// Add a WHERE clause
3729    pub fn where_(mut self, condition: Expression) -> Self {
3730        self.where_clause = Some(Where { this: condition });
3731        self
3732    }
3733
3734    /// Set DISTINCT
3735    pub fn distinct(mut self) -> Self {
3736        self.distinct = true;
3737        self
3738    }
3739
3740    /// Add a JOIN
3741    pub fn join(mut self, join: Join) -> Self {
3742        self.joins.push(join);
3743        self
3744    }
3745
3746    /// Set ORDER BY
3747    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
3748        self.order_by = Some(OrderBy {
3749            expressions,
3750            siblings: false,
3751            comments: Vec::new(),
3752        });
3753        self
3754    }
3755
3756    /// Set LIMIT
3757    pub fn limit(mut self, n: Expression) -> Self {
3758        self.limit = Some(Limit {
3759            this: n,
3760            percent: false,
3761            comments: Vec::new(),
3762        });
3763        self
3764    }
3765
3766    /// Set OFFSET
3767    pub fn offset(mut self, n: Expression) -> Self {
3768        self.offset = Some(Offset {
3769            this: n,
3770            rows: None,
3771        });
3772        self
3773    }
3774}
3775
3776impl Default for Select {
3777    fn default() -> Self {
3778        Self::new()
3779    }
3780}
3781
3782/// Represent a UNION set operation between two query expressions.
3783///
3784/// When `all` is true, duplicate rows are preserved (UNION ALL).
3785/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
3786/// Supports DuckDB's BY NAME modifier and BigQuery's CORRESPONDING modifier.
3787#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3788#[cfg_attr(feature = "bindings", derive(TS))]
3789pub struct Union {
3790    /// The left-hand query operand.
3791    pub left: Expression,
3792    /// The right-hand query operand.
3793    pub right: Expression,
3794    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
3795    pub all: bool,
3796    /// Whether DISTINCT was explicitly specified
3797    #[serde(default)]
3798    pub distinct: bool,
3799    /// Optional WITH clause
3800    pub with: Option<With>,
3801    /// ORDER BY applied to entire UNION result
3802    pub order_by: Option<OrderBy>,
3803    /// LIMIT applied to entire UNION result
3804    pub limit: Option<Box<Expression>>,
3805    /// OFFSET applied to entire UNION result
3806    pub offset: Option<Box<Expression>>,
3807    /// DISTRIBUTE BY clause (Hive/Spark)
3808    #[serde(default, skip_serializing_if = "Option::is_none")]
3809    pub distribute_by: Option<DistributeBy>,
3810    /// SORT BY clause (Hive/Spark)
3811    #[serde(default, skip_serializing_if = "Option::is_none")]
3812    pub sort_by: Option<SortBy>,
3813    /// CLUSTER BY clause (Hive/Spark)
3814    #[serde(default, skip_serializing_if = "Option::is_none")]
3815    pub cluster_by: Option<ClusterBy>,
3816    /// DuckDB BY NAME modifier
3817    #[serde(default)]
3818    pub by_name: bool,
3819    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3820    #[serde(default, skip_serializing_if = "Option::is_none")]
3821    pub side: Option<String>,
3822    /// BigQuery: Set operation kind (INNER)
3823    #[serde(default, skip_serializing_if = "Option::is_none")]
3824    pub kind: Option<String>,
3825    /// BigQuery: CORRESPONDING modifier
3826    #[serde(default)]
3827    pub corresponding: bool,
3828    /// BigQuery: STRICT modifier (before CORRESPONDING)
3829    #[serde(default)]
3830    pub strict: bool,
3831    /// BigQuery: BY (columns) after CORRESPONDING
3832    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3833    pub on_columns: Vec<Expression>,
3834}
3835
3836/// Iteratively flatten the left-recursive chain to prevent stack overflow
3837/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3838impl Drop for Union {
3839    fn drop(&mut self) {
3840        loop {
3841            if let Expression::Union(ref mut inner) = self.left {
3842                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3843                let old_left = std::mem::replace(&mut self.left, next_left);
3844                drop(old_left);
3845            } else {
3846                break;
3847            }
3848        }
3849    }
3850}
3851
3852/// Represent an INTERSECT set operation between two query expressions.
3853///
3854/// Returns only rows that appear in both operands. When `all` is true,
3855/// duplicates are preserved according to their multiplicity.
3856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3857#[cfg_attr(feature = "bindings", derive(TS))]
3858pub struct Intersect {
3859    /// The left-hand query operand.
3860    pub left: Expression,
3861    /// The right-hand query operand.
3862    pub right: Expression,
3863    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
3864    pub all: bool,
3865    /// Whether DISTINCT was explicitly specified
3866    #[serde(default)]
3867    pub distinct: bool,
3868    /// Optional WITH clause
3869    pub with: Option<With>,
3870    /// ORDER BY applied to entire INTERSECT result
3871    pub order_by: Option<OrderBy>,
3872    /// LIMIT applied to entire INTERSECT result
3873    pub limit: Option<Box<Expression>>,
3874    /// OFFSET applied to entire INTERSECT result
3875    pub offset: Option<Box<Expression>>,
3876    /// DISTRIBUTE BY clause (Hive/Spark)
3877    #[serde(default, skip_serializing_if = "Option::is_none")]
3878    pub distribute_by: Option<DistributeBy>,
3879    /// SORT BY clause (Hive/Spark)
3880    #[serde(default, skip_serializing_if = "Option::is_none")]
3881    pub sort_by: Option<SortBy>,
3882    /// CLUSTER BY clause (Hive/Spark)
3883    #[serde(default, skip_serializing_if = "Option::is_none")]
3884    pub cluster_by: Option<ClusterBy>,
3885    /// DuckDB BY NAME modifier
3886    #[serde(default)]
3887    pub by_name: bool,
3888    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3889    #[serde(default, skip_serializing_if = "Option::is_none")]
3890    pub side: Option<String>,
3891    /// BigQuery: Set operation kind (INNER)
3892    #[serde(default, skip_serializing_if = "Option::is_none")]
3893    pub kind: Option<String>,
3894    /// BigQuery: CORRESPONDING modifier
3895    #[serde(default)]
3896    pub corresponding: bool,
3897    /// BigQuery: STRICT modifier (before CORRESPONDING)
3898    #[serde(default)]
3899    pub strict: bool,
3900    /// BigQuery: BY (columns) after CORRESPONDING
3901    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3902    pub on_columns: Vec<Expression>,
3903}
3904
3905impl Drop for Intersect {
3906    fn drop(&mut self) {
3907        loop {
3908            if let Expression::Intersect(ref mut inner) = self.left {
3909                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3910                let old_left = std::mem::replace(&mut self.left, next_left);
3911                drop(old_left);
3912            } else {
3913                break;
3914            }
3915        }
3916    }
3917}
3918
3919/// Represent an EXCEPT (MINUS) set operation between two query expressions.
3920///
3921/// Returns rows from the left operand that do not appear in the right operand.
3922/// When `all` is true, duplicates are subtracted according to their multiplicity.
3923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3924#[cfg_attr(feature = "bindings", derive(TS))]
3925pub struct Except {
3926    /// The left-hand query operand.
3927    pub left: Expression,
3928    /// The right-hand query operand (rows to subtract).
3929    pub right: Expression,
3930    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
3931    pub all: bool,
3932    /// Whether DISTINCT was explicitly specified
3933    #[serde(default)]
3934    pub distinct: bool,
3935    /// Optional WITH clause
3936    pub with: Option<With>,
3937    /// ORDER BY applied to entire EXCEPT result
3938    pub order_by: Option<OrderBy>,
3939    /// LIMIT applied to entire EXCEPT result
3940    pub limit: Option<Box<Expression>>,
3941    /// OFFSET applied to entire EXCEPT result
3942    pub offset: Option<Box<Expression>>,
3943    /// DISTRIBUTE BY clause (Hive/Spark)
3944    #[serde(default, skip_serializing_if = "Option::is_none")]
3945    pub distribute_by: Option<DistributeBy>,
3946    /// SORT BY clause (Hive/Spark)
3947    #[serde(default, skip_serializing_if = "Option::is_none")]
3948    pub sort_by: Option<SortBy>,
3949    /// CLUSTER BY clause (Hive/Spark)
3950    #[serde(default, skip_serializing_if = "Option::is_none")]
3951    pub cluster_by: Option<ClusterBy>,
3952    /// DuckDB BY NAME modifier
3953    #[serde(default)]
3954    pub by_name: bool,
3955    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3956    #[serde(default, skip_serializing_if = "Option::is_none")]
3957    pub side: Option<String>,
3958    /// BigQuery: Set operation kind (INNER)
3959    #[serde(default, skip_serializing_if = "Option::is_none")]
3960    pub kind: Option<String>,
3961    /// BigQuery: CORRESPONDING modifier
3962    #[serde(default)]
3963    pub corresponding: bool,
3964    /// BigQuery: STRICT modifier (before CORRESPONDING)
3965    #[serde(default)]
3966    pub strict: bool,
3967    /// BigQuery: BY (columns) after CORRESPONDING
3968    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3969    pub on_columns: Vec<Expression>,
3970}
3971
3972impl Drop for Except {
3973    fn drop(&mut self) {
3974        loop {
3975            if let Expression::Except(ref mut inner) = self.left {
3976                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3977                let old_left = std::mem::replace(&mut self.left, next_left);
3978                drop(old_left);
3979            } else {
3980                break;
3981            }
3982        }
3983    }
3984}
3985
3986/// INTO clause for SELECT INTO statements
3987#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3988#[cfg_attr(feature = "bindings", derive(TS))]
3989pub struct SelectInto {
3990    /// Target table or variable (used when single target)
3991    pub this: Expression,
3992    /// Whether TEMPORARY keyword was used
3993    #[serde(default)]
3994    pub temporary: bool,
3995    /// Whether UNLOGGED keyword was used (PostgreSQL)
3996    #[serde(default)]
3997    pub unlogged: bool,
3998    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
3999    #[serde(default)]
4000    pub bulk_collect: bool,
4001    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4002    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4003    pub expressions: Vec<Expression>,
4004}
4005
4006/// Represent a parenthesized subquery expression.
4007///
4008/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4009/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4010/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4011/// modifiers are rendered inside or outside the parentheses.
4012///
4013/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4014/// scalar subqueries in select-lists, and derived tables.
4015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4016#[cfg_attr(feature = "bindings", derive(TS))]
4017pub struct Subquery {
4018    /// The inner query expression.
4019    pub this: Expression,
4020    /// Optional alias for the derived table.
4021    pub alias: Option<Identifier>,
4022    /// Optional column aliases: AS t(c1, c2)
4023    pub column_aliases: Vec<Identifier>,
4024    /// Whether AS keyword was explicitly used for the alias.
4025    #[serde(default)]
4026    pub alias_explicit_as: bool,
4027    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4028    #[serde(skip_serializing_if = "Option::is_none", default)]
4029    pub alias_keyword: Option<String>,
4030    /// ORDER BY clause (for parenthesized queries)
4031    pub order_by: Option<OrderBy>,
4032    /// LIMIT clause
4033    pub limit: Option<Limit>,
4034    /// OFFSET clause
4035    pub offset: Option<Offset>,
4036    /// DISTRIBUTE BY clause (Hive/Spark)
4037    #[serde(default, skip_serializing_if = "Option::is_none")]
4038    pub distribute_by: Option<DistributeBy>,
4039    /// SORT BY clause (Hive/Spark)
4040    #[serde(default, skip_serializing_if = "Option::is_none")]
4041    pub sort_by: Option<SortBy>,
4042    /// CLUSTER BY clause (Hive/Spark)
4043    #[serde(default, skip_serializing_if = "Option::is_none")]
4044    pub cluster_by: Option<ClusterBy>,
4045    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4046    #[serde(default)]
4047    pub lateral: bool,
4048    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4049    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4050    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4051    #[serde(default)]
4052    pub modifiers_inside: bool,
4053    /// Trailing comments after the closing paren
4054    #[serde(default)]
4055    pub trailing_comments: Vec<String>,
4056    /// Inferred data type from type annotation
4057    #[serde(default, skip_serializing_if = "Option::is_none")]
4058    #[ast(skip)]
4059    pub inferred_type: Option<DataType>,
4060}
4061
4062/// Pipe operator expression: query |> transform
4063///
4064/// Used in DataFusion and BigQuery pipe syntax:
4065///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4067#[cfg_attr(feature = "bindings", derive(TS))]
4068pub struct PipeOperator {
4069    /// The input query/expression (left side of |>)
4070    pub this: Expression,
4071    /// The piped operation (right side of |>)
4072    pub expression: Expression,
4073}
4074
4075/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4077#[cfg_attr(feature = "bindings", derive(TS))]
4078pub struct Values {
4079    /// The rows of values
4080    pub expressions: Vec<Tuple>,
4081    /// Optional alias for the table
4082    pub alias: Option<Identifier>,
4083    /// Optional column aliases: AS t(c1, c2)
4084    pub column_aliases: Vec<Identifier>,
4085}
4086
4087/// PIVOT operation - supports both standard and DuckDB simplified syntax
4088///
4089/// Standard syntax (in FROM clause):
4090///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4091///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4092///
4093/// DuckDB simplified syntax (statement-level):
4094///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4095///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4096#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4097#[cfg_attr(feature = "bindings", derive(TS))]
4098pub struct Pivot {
4099    /// Source table/expression
4100    pub this: Expression,
4101    /// For standard PIVOT: the aggregation function(s) (first is primary)
4102    /// For DuckDB simplified: unused (use `using` instead)
4103    #[serde(default)]
4104    pub expressions: Vec<Expression>,
4105    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4106    #[serde(default)]
4107    pub fields: Vec<Expression>,
4108    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4109    #[serde(default)]
4110    pub using: Vec<Expression>,
4111    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4112    #[serde(default)]
4113    pub group: Option<Box<Expression>>,
4114    /// Whether this is an UNPIVOT (vs PIVOT)
4115    #[serde(default)]
4116    pub unpivot: bool,
4117    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4118    #[serde(default)]
4119    pub into: Option<Box<Expression>>,
4120    /// Optional alias
4121    #[serde(default)]
4122    pub alias: Option<Identifier>,
4123    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4124    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4125    pub alias_columns: Vec<Identifier>,
4126    /// Include/exclude nulls (for UNPIVOT)
4127    #[serde(default)]
4128    pub include_nulls: Option<bool>,
4129    /// Default on null value (Snowflake)
4130    #[serde(default)]
4131    pub default_on_null: Option<Box<Expression>>,
4132    /// WITH clause (CTEs)
4133    #[serde(default, skip_serializing_if = "Option::is_none")]
4134    pub with: Option<With>,
4135}
4136
4137/// UNPIVOT operation
4138#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4139#[cfg_attr(feature = "bindings", derive(TS))]
4140pub struct Unpivot {
4141    pub this: Expression,
4142    pub value_column: Identifier,
4143    pub name_column: Identifier,
4144    pub columns: Vec<Expression>,
4145    pub alias: Option<Identifier>,
4146    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4147    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4148    pub alias_columns: Vec<Identifier>,
4149    /// Whether the value_column was parenthesized in the original SQL
4150    #[serde(default)]
4151    pub value_column_parenthesized: bool,
4152    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4153    #[serde(default)]
4154    pub include_nulls: Option<bool>,
4155    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4156    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4157    pub extra_value_columns: Vec<Identifier>,
4158}
4159
4160/// PIVOT alias for aliasing pivot expressions
4161/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4163#[cfg_attr(feature = "bindings", derive(TS))]
4164pub struct PivotAlias {
4165    pub this: Expression,
4166    pub alias: Expression,
4167}
4168
4169/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4171#[cfg_attr(feature = "bindings", derive(TS))]
4172pub struct PreWhere {
4173    pub this: Expression,
4174}
4175
4176/// STREAM definition (Snowflake) - for change data capture
4177#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4178#[cfg_attr(feature = "bindings", derive(TS))]
4179pub struct Stream {
4180    pub this: Expression,
4181    #[serde(skip_serializing_if = "Option::is_none")]
4182    pub on: Option<Expression>,
4183    #[serde(skip_serializing_if = "Option::is_none")]
4184    pub show_initial_rows: Option<bool>,
4185}
4186
4187/// USING DATA clause for data import statements
4188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4189#[cfg_attr(feature = "bindings", derive(TS))]
4190pub struct UsingData {
4191    pub this: Expression,
4192}
4193
4194/// XML Namespace declaration
4195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4196#[cfg_attr(feature = "bindings", derive(TS))]
4197pub struct XmlNamespace {
4198    pub this: Expression,
4199    #[serde(skip_serializing_if = "Option::is_none")]
4200    pub alias: Option<Identifier>,
4201}
4202
4203/// ROW FORMAT clause for Hive/Spark
4204#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4205#[cfg_attr(feature = "bindings", derive(TS))]
4206pub struct RowFormat {
4207    pub delimited: bool,
4208    pub fields_terminated_by: Option<String>,
4209    pub collection_items_terminated_by: Option<String>,
4210    pub map_keys_terminated_by: Option<String>,
4211    pub lines_terminated_by: Option<String>,
4212    pub null_defined_as: Option<String>,
4213}
4214
4215/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4217#[cfg_attr(feature = "bindings", derive(TS))]
4218pub struct DirectoryInsert {
4219    pub local: bool,
4220    pub path: String,
4221    pub row_format: Option<RowFormat>,
4222    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4223    #[serde(default)]
4224    pub stored_as: Option<String>,
4225}
4226
4227/// INSERT statement
4228#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4229#[cfg_attr(feature = "bindings", derive(TS))]
4230pub struct Insert {
4231    pub table: TableRef,
4232    pub columns: Vec<Identifier>,
4233    pub values: Vec<Vec<Expression>>,
4234    pub query: Option<Expression>,
4235    /// INSERT OVERWRITE for Hive/Spark
4236    pub overwrite: bool,
4237    /// PARTITION clause for Hive/Spark
4238    pub partition: Vec<(Identifier, Option<Expression>)>,
4239    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4240    #[serde(default)]
4241    pub directory: Option<DirectoryInsert>,
4242    /// RETURNING clause (PostgreSQL, SQLite)
4243    #[serde(default)]
4244    pub returning: Vec<Expression>,
4245    /// OUTPUT clause (TSQL)
4246    #[serde(default)]
4247    pub output: Option<OutputClause>,
4248    /// ON CONFLICT clause (PostgreSQL, SQLite)
4249    #[serde(default)]
4250    pub on_conflict: Option<Box<Expression>>,
4251    /// Leading comments before the statement
4252    #[serde(default)]
4253    pub leading_comments: Vec<String>,
4254    /// IF EXISTS clause (Hive)
4255    #[serde(default)]
4256    pub if_exists: bool,
4257    /// WITH clause (CTEs)
4258    #[serde(default)]
4259    pub with: Option<With>,
4260    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4261    #[serde(default)]
4262    pub ignore: bool,
4263    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4264    #[serde(default)]
4265    pub source_alias: Option<Identifier>,
4266    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4267    #[serde(default)]
4268    pub alias: Option<Identifier>,
4269    /// Whether the alias uses explicit AS keyword
4270    #[serde(default)]
4271    pub alias_explicit_as: bool,
4272    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4273    #[serde(default)]
4274    pub default_values: bool,
4275    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4276    #[serde(default)]
4277    pub by_name: bool,
4278    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4279    #[serde(default, skip_serializing_if = "Option::is_none")]
4280    pub conflict_action: Option<String>,
4281    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4282    #[serde(default)]
4283    pub is_replace: bool,
4284    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4285    #[serde(default, skip_serializing_if = "Option::is_none")]
4286    pub hint: Option<Hint>,
4287    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4288    #[serde(default)]
4289    pub replace_where: Option<Box<Expression>>,
4290    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4291    #[serde(default)]
4292    pub source: Option<Box<Expression>>,
4293    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4294    #[serde(default, skip_serializing_if = "Option::is_none")]
4295    pub function_target: Option<Box<Expression>>,
4296    /// ClickHouse: PARTITION BY expr
4297    #[serde(default, skip_serializing_if = "Option::is_none")]
4298    pub partition_by: Option<Box<Expression>>,
4299    /// ClickHouse: SETTINGS key = val, ...
4300    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4301    pub settings: Vec<Expression>,
4302}
4303
4304/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4306#[cfg_attr(feature = "bindings", derive(TS))]
4307pub struct OutputClause {
4308    /// Columns/expressions to output
4309    pub columns: Vec<Expression>,
4310    /// Optional INTO target table or table variable
4311    #[serde(default)]
4312    pub into_table: Option<Expression>,
4313}
4314
4315/// UPDATE statement
4316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4317#[cfg_attr(feature = "bindings", derive(TS))]
4318pub struct Update {
4319    pub table: TableRef,
4320    #[serde(default)]
4321    pub hint: Option<Hint>,
4322    /// Additional tables for multi-table UPDATE (MySQL syntax)
4323    #[serde(default)]
4324    pub extra_tables: Vec<TableRef>,
4325    /// JOINs attached to the table list (MySQL multi-table syntax)
4326    #[serde(default)]
4327    pub table_joins: Vec<Join>,
4328    pub set: Vec<(Identifier, Expression)>,
4329    pub from_clause: Option<From>,
4330    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4331    #[serde(default)]
4332    pub from_joins: Vec<Join>,
4333    pub where_clause: Option<Where>,
4334    /// RETURNING clause (PostgreSQL, SQLite)
4335    #[serde(default)]
4336    pub returning: Vec<Expression>,
4337    /// OUTPUT clause (TSQL)
4338    #[serde(default)]
4339    pub output: Option<OutputClause>,
4340    /// WITH clause (CTEs)
4341    #[serde(default)]
4342    pub with: Option<With>,
4343    /// Leading comments before the statement
4344    #[serde(default)]
4345    pub leading_comments: Vec<String>,
4346    /// LIMIT clause (MySQL)
4347    #[serde(default)]
4348    pub limit: Option<Expression>,
4349    /// ORDER BY clause (MySQL)
4350    #[serde(default)]
4351    pub order_by: Option<OrderBy>,
4352    /// Whether FROM clause appears before SET (Snowflake syntax)
4353    #[serde(default)]
4354    pub from_before_set: bool,
4355}
4356
4357/// DELETE statement
4358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4359#[cfg_attr(feature = "bindings", derive(TS))]
4360pub struct Delete {
4361    pub table: TableRef,
4362    #[serde(default)]
4363    pub hint: Option<Hint>,
4364    /// ClickHouse: ON CLUSTER clause for distributed DDL
4365    #[serde(default, skip_serializing_if = "Option::is_none")]
4366    pub on_cluster: Option<OnCluster>,
4367    /// Optional alias for the table
4368    pub alias: Option<Identifier>,
4369    /// Whether the alias was declared with explicit AS keyword
4370    #[serde(default)]
4371    pub alias_explicit_as: bool,
4372    /// PostgreSQL/DuckDB USING clause - additional tables to join
4373    pub using: Vec<TableRef>,
4374    pub where_clause: Option<Where>,
4375    /// OUTPUT clause (TSQL)
4376    #[serde(default)]
4377    pub output: Option<OutputClause>,
4378    /// Leading comments before the statement
4379    #[serde(default)]
4380    pub leading_comments: Vec<String>,
4381    /// WITH clause (CTEs)
4382    #[serde(default)]
4383    pub with: Option<With>,
4384    /// LIMIT clause (MySQL)
4385    #[serde(default)]
4386    pub limit: Option<Expression>,
4387    /// ORDER BY clause (MySQL)
4388    #[serde(default)]
4389    pub order_by: Option<OrderBy>,
4390    /// RETURNING clause (PostgreSQL)
4391    #[serde(default)]
4392    pub returning: Vec<Expression>,
4393    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4394    /// These are the target tables to delete from
4395    #[serde(default)]
4396    pub tables: Vec<TableRef>,
4397    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4398    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4399    #[serde(default)]
4400    pub tables_from_using: bool,
4401    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4402    #[serde(default)]
4403    pub joins: Vec<Join>,
4404    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4405    #[serde(default)]
4406    pub force_index: Option<String>,
4407    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4408    #[serde(default)]
4409    pub no_from: bool,
4410}
4411
4412/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4413#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4414#[cfg_attr(feature = "bindings", derive(TS))]
4415pub struct CopyStmt {
4416    /// Target table or query
4417    pub this: Expression,
4418    /// True for FROM (loading into table), false for TO (exporting)
4419    pub kind: bool,
4420    /// Source/destination file(s) or stage
4421    pub files: Vec<Expression>,
4422    /// Copy parameters
4423    #[serde(default)]
4424    pub params: Vec<CopyParameter>,
4425    /// Credentials for external access
4426    #[serde(default)]
4427    pub credentials: Option<Box<Credentials>>,
4428    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4429    #[serde(default)]
4430    pub is_into: bool,
4431    /// Whether parameters are wrapped in WITH (...) syntax
4432    #[serde(default)]
4433    pub with_wrapped: bool,
4434}
4435
4436/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4438#[cfg_attr(feature = "bindings", derive(TS))]
4439pub struct CopyParameter {
4440    pub name: String,
4441    pub value: Option<Expression>,
4442    pub values: Vec<Expression>,
4443    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4444    #[serde(default)]
4445    pub eq: bool,
4446}
4447
4448/// Credentials for external access (S3, Azure, etc.)
4449#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4450#[cfg_attr(feature = "bindings", derive(TS))]
4451pub struct Credentials {
4452    pub credentials: Vec<(String, String)>,
4453    pub encryption: Option<String>,
4454    pub storage: Option<String>,
4455}
4456
4457/// PUT statement (Snowflake)
4458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4459#[cfg_attr(feature = "bindings", derive(TS))]
4460pub struct PutStmt {
4461    /// Source file path
4462    pub source: String,
4463    /// Whether source was quoted in the original SQL
4464    #[serde(default)]
4465    pub source_quoted: bool,
4466    /// Target stage
4467    pub target: Expression,
4468    /// PUT parameters
4469    #[serde(default)]
4470    pub params: Vec<CopyParameter>,
4471}
4472
4473/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4475#[cfg_attr(feature = "bindings", derive(TS))]
4476pub struct StageReference {
4477    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4478    pub name: String,
4479    /// Optional path within the stage (e.g., "/path/to/file.csv")
4480    #[serde(default)]
4481    pub path: Option<String>,
4482    /// Optional FILE_FORMAT parameter
4483    #[serde(default)]
4484    pub file_format: Option<Expression>,
4485    /// Optional PATTERN parameter
4486    #[serde(default)]
4487    pub pattern: Option<String>,
4488    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4489    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4490    pub quoted: bool,
4491}
4492
4493/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4495#[cfg_attr(feature = "bindings", derive(TS))]
4496pub struct HistoricalData {
4497    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4498    pub this: Box<Expression>,
4499    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4500    pub kind: String,
4501    /// The expression value (e.g., the statement ID or timestamp)
4502    pub expression: Box<Expression>,
4503}
4504
4505/// Represent an aliased expression (`expr AS name`).
4506///
4507/// Used for column aliases in select-lists, table aliases on subqueries,
4508/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4510#[cfg_attr(feature = "bindings", derive(TS))]
4511pub struct Alias {
4512    /// The expression being aliased.
4513    pub this: Expression,
4514    /// The alias name (required for simple aliases, optional when only column aliases provided)
4515    pub alias: Identifier,
4516    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4517    #[serde(default)]
4518    pub column_aliases: Vec<Identifier>,
4519    /// Whether AS keyword was explicitly used for the alias.
4520    #[serde(default)]
4521    pub alias_explicit_as: bool,
4522    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4523    #[serde(skip_serializing_if = "Option::is_none", default)]
4524    pub alias_keyword: Option<String>,
4525    /// Comments that appeared between the expression and AS keyword
4526    #[serde(default)]
4527    pub pre_alias_comments: Vec<String>,
4528    /// Trailing comments that appeared after the alias
4529    #[serde(default)]
4530    pub trailing_comments: Vec<String>,
4531    /// Inferred data type from type annotation
4532    #[serde(default, skip_serializing_if = "Option::is_none")]
4533    #[ast(skip)]
4534    pub inferred_type: Option<DataType>,
4535}
4536
4537impl Alias {
4538    /// Create a simple alias
4539    pub fn new(this: Expression, alias: Identifier) -> Self {
4540        Self {
4541            this,
4542            alias,
4543            column_aliases: Vec::new(),
4544            alias_explicit_as: false,
4545            alias_keyword: None,
4546            pre_alias_comments: Vec::new(),
4547            trailing_comments: Vec::new(),
4548            inferred_type: None,
4549        }
4550    }
4551
4552    /// Create an alias with column aliases only (no table alias name)
4553    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4554        Self {
4555            this,
4556            alias: Identifier::empty(),
4557            column_aliases,
4558            alias_explicit_as: false,
4559            alias_keyword: None,
4560            pre_alias_comments: Vec::new(),
4561            trailing_comments: Vec::new(),
4562            inferred_type: None,
4563        }
4564    }
4565}
4566
4567/// Represent a type cast expression.
4568///
4569/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4570/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4571/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4572/// CONVERSION ERROR (Oracle) clauses.
4573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4574#[cfg_attr(feature = "bindings", derive(TS))]
4575pub struct Cast {
4576    /// The expression being cast.
4577    pub this: Expression,
4578    /// The target data type.
4579    pub to: DataType,
4580    #[serde(default)]
4581    pub trailing_comments: Vec<String>,
4582    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4583    #[serde(default)]
4584    pub double_colon_syntax: bool,
4585    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4586    #[serde(skip_serializing_if = "Option::is_none", default)]
4587    pub format: Option<Box<Expression>>,
4588    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4589    #[serde(skip_serializing_if = "Option::is_none", default)]
4590    pub default: Option<Box<Expression>>,
4591    /// Inferred data type from type annotation
4592    #[serde(default, skip_serializing_if = "Option::is_none")]
4593    #[ast(skip)]
4594    pub inferred_type: Option<DataType>,
4595}
4596
4597///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4598#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4599#[cfg_attr(feature = "bindings", derive(TS))]
4600pub struct CollationExpr {
4601    pub this: Expression,
4602    pub collation: String,
4603    /// True if the collation was single-quoted in the original SQL (string literal)
4604    #[serde(default)]
4605    pub quoted: bool,
4606    /// True if the collation was double-quoted in the original SQL (identifier)
4607    #[serde(default)]
4608    pub double_quoted: bool,
4609}
4610
4611/// Represent a CASE expression (both simple and searched forms).
4612///
4613/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4614/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4615/// Each entry in `whens` is a `(condition, result)` pair.
4616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4617#[cfg_attr(feature = "bindings", derive(TS))]
4618pub struct Case {
4619    /// The operand for simple CASE, or `None` for searched CASE.
4620    pub operand: Option<Expression>,
4621    /// Pairs of (WHEN condition, THEN result).
4622    pub whens: Vec<(Expression, Expression)>,
4623    /// Optional ELSE result.
4624    pub else_: Option<Expression>,
4625    /// Comments from the CASE keyword (emitted after END)
4626    #[serde(default)]
4627    #[serde(skip_serializing_if = "Vec::is_empty")]
4628    pub comments: Vec<String>,
4629    /// Inferred data type from type annotation
4630    #[serde(default, skip_serializing_if = "Option::is_none")]
4631    #[ast(skip)]
4632    pub inferred_type: Option<DataType>,
4633}
4634
4635/// Represent a binary operation (two operands separated by an operator).
4636///
4637/// This is the shared payload struct for all binary operator variants in the
4638/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4639/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4640/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4641/// preservation of inline comments around operators.
4642#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4643#[cfg_attr(feature = "bindings", derive(TS))]
4644pub struct BinaryOp {
4645    pub left: Expression,
4646    pub right: Expression,
4647    /// Comments after the left operand (before the operator)
4648    #[serde(default)]
4649    pub left_comments: Vec<String>,
4650    /// Comments after the operator (before the right operand)
4651    #[serde(default)]
4652    pub operator_comments: Vec<String>,
4653    /// Comments after the right operand
4654    #[serde(default)]
4655    pub trailing_comments: Vec<String>,
4656    /// Inferred data type from type annotation
4657    #[serde(default, skip_serializing_if = "Option::is_none")]
4658    #[ast(skip)]
4659    pub inferred_type: Option<DataType>,
4660}
4661
4662impl BinaryOp {
4663    pub fn new(left: Expression, right: Expression) -> Self {
4664        Self {
4665            left,
4666            right,
4667            left_comments: Vec::new(),
4668            operator_comments: Vec::new(),
4669            trailing_comments: Vec::new(),
4670            inferred_type: None,
4671        }
4672    }
4673}
4674
4675/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4676#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4677#[cfg_attr(feature = "bindings", derive(TS))]
4678pub struct LikeOp {
4679    pub left: Expression,
4680    pub right: Expression,
4681    /// ESCAPE character/expression
4682    #[serde(default)]
4683    pub escape: Option<Expression>,
4684    /// Quantifier: ANY, ALL, or SOME
4685    #[serde(default)]
4686    pub quantifier: Option<String>,
4687    /// Inferred data type from type annotation
4688    #[serde(default, skip_serializing_if = "Option::is_none")]
4689    #[ast(skip)]
4690    pub inferred_type: Option<DataType>,
4691}
4692
4693impl LikeOp {
4694    pub fn new(left: Expression, right: Expression) -> Self {
4695        Self {
4696            left,
4697            right,
4698            escape: None,
4699            quantifier: None,
4700            inferred_type: None,
4701        }
4702    }
4703
4704    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4705        Self {
4706            left,
4707            right,
4708            escape: Some(escape),
4709            quantifier: None,
4710            inferred_type: None,
4711        }
4712    }
4713}
4714
4715/// Represent a unary operation (single operand with a prefix operator).
4716///
4717/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4719#[cfg_attr(feature = "bindings", derive(TS))]
4720pub struct UnaryOp {
4721    /// The operand expression.
4722    pub this: Expression,
4723    /// Inferred data type from type annotation
4724    #[serde(default, skip_serializing_if = "Option::is_none")]
4725    #[ast(skip)]
4726    pub inferred_type: Option<DataType>,
4727}
4728
4729impl UnaryOp {
4730    pub fn new(this: Expression) -> Self {
4731        Self {
4732            this,
4733            inferred_type: None,
4734        }
4735    }
4736}
4737
4738/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4739///
4740/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4741/// but not both. When `not` is true, the predicate is `NOT IN`.
4742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4743#[cfg_attr(feature = "bindings", derive(TS))]
4744pub struct In {
4745    /// The expression being tested.
4746    pub this: Expression,
4747    /// The value list (mutually exclusive with `query`).
4748    pub expressions: Vec<Expression>,
4749    /// A subquery (mutually exclusive with `expressions`).
4750    pub query: Option<Expression>,
4751    /// Whether this is NOT IN.
4752    pub not: bool,
4753    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4754    pub global: bool,
4755    /// BigQuery: IN UNNEST(expr)
4756    #[serde(default, skip_serializing_if = "Option::is_none")]
4757    pub unnest: Option<Box<Expression>>,
4758    /// Whether the right side is a bare field reference (no parentheses).
4759    /// Matches Python sqlglot's `field` attribute on `In` expression.
4760    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4761    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4762    pub is_field: bool,
4763}
4764
4765/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4766#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4767#[cfg_attr(feature = "bindings", derive(TS))]
4768pub struct Between {
4769    /// The expression being tested.
4770    pub this: Expression,
4771    /// The lower bound.
4772    pub low: Expression,
4773    /// The upper bound.
4774    pub high: Expression,
4775    /// Whether this is NOT BETWEEN.
4776    pub not: bool,
4777    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4778    #[serde(default)]
4779    pub symmetric: Option<bool>,
4780}
4781
4782/// IS NULL predicate
4783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4784#[cfg_attr(feature = "bindings", derive(TS))]
4785pub struct IsNull {
4786    pub this: Expression,
4787    pub not: bool,
4788    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4789    #[serde(default)]
4790    pub postfix_form: bool,
4791}
4792
4793/// IS TRUE / IS FALSE predicate
4794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4795#[cfg_attr(feature = "bindings", derive(TS))]
4796pub struct IsTrueFalse {
4797    pub this: Expression,
4798    pub not: bool,
4799}
4800
4801/// IS JSON predicate (SQL standard)
4802/// Checks if a value is valid JSON
4803#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4804#[cfg_attr(feature = "bindings", derive(TS))]
4805pub struct IsJson {
4806    pub this: Expression,
4807    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4808    pub json_type: Option<String>,
4809    /// Key uniqueness constraint
4810    pub unique_keys: Option<JsonUniqueKeys>,
4811    /// Whether IS NOT JSON
4812    pub negated: bool,
4813}
4814
4815/// JSON unique keys constraint variants
4816#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4817#[cfg_attr(feature = "bindings", derive(TS))]
4818pub enum JsonUniqueKeys {
4819    /// WITH UNIQUE KEYS
4820    With,
4821    /// WITHOUT UNIQUE KEYS
4822    Without,
4823    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4824    Shorthand,
4825}
4826
4827/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4828#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4829#[cfg_attr(feature = "bindings", derive(TS))]
4830pub struct Exists {
4831    /// The subquery expression.
4832    pub this: Expression,
4833    /// Whether this is NOT EXISTS.
4834    pub not: bool,
4835}
4836
4837/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
4838///
4839/// This is the generic function node. Well-known aggregates, window functions,
4840/// and built-in functions each have their own dedicated `Expression` variants
4841/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
4842/// not recognize as built-ins are represented with this struct.
4843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4844#[cfg_attr(feature = "bindings", derive(TS))]
4845pub struct Function {
4846    /// The function name, as originally written (may be schema-qualified).
4847    pub name: String,
4848    /// Positional arguments to the function.
4849    pub args: Vec<Expression>,
4850    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
4851    pub distinct: bool,
4852    #[serde(default)]
4853    pub trailing_comments: Vec<String>,
4854    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
4855    #[serde(default)]
4856    pub use_bracket_syntax: bool,
4857    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
4858    #[serde(default)]
4859    pub no_parens: bool,
4860    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
4861    #[serde(default)]
4862    pub quoted: bool,
4863    /// Source position span
4864    #[serde(default, skip_serializing_if = "Option::is_none")]
4865    pub span: Option<Span>,
4866    /// Inferred data type from type annotation
4867    #[serde(default, skip_serializing_if = "Option::is_none")]
4868    #[ast(skip)]
4869    pub inferred_type: Option<DataType>,
4870}
4871
4872impl Default for Function {
4873    fn default() -> Self {
4874        Self {
4875            name: String::new(),
4876            args: Vec::new(),
4877            distinct: false,
4878            trailing_comments: Vec::new(),
4879            use_bracket_syntax: false,
4880            no_parens: false,
4881            quoted: false,
4882            span: None,
4883            inferred_type: None,
4884        }
4885    }
4886}
4887
4888impl Function {
4889    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
4890        Self {
4891            name: name.into(),
4892            args,
4893            distinct: false,
4894            trailing_comments: Vec::new(),
4895            use_bracket_syntax: false,
4896            no_parens: false,
4897            quoted: false,
4898            span: None,
4899            inferred_type: None,
4900        }
4901    }
4902}
4903
4904/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
4905///
4906/// This struct is used for aggregate function calls that are not covered by
4907/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
4908/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
4909/// IGNORE NULLS / RESPECT NULLS modifiers.
4910#[derive(
4911    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
4912)]
4913#[cfg_attr(feature = "bindings", derive(TS))]
4914pub struct AggregateFunction {
4915    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
4916    pub name: String,
4917    /// Positional arguments.
4918    pub args: Vec<Expression>,
4919    /// Whether DISTINCT was specified.
4920    pub distinct: bool,
4921    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
4922    pub filter: Option<Expression>,
4923    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
4924    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4925    pub order_by: Vec<Ordered>,
4926    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
4927    #[serde(default, skip_serializing_if = "Option::is_none")]
4928    pub limit: Option<Box<Expression>>,
4929    /// IGNORE NULLS / RESPECT NULLS
4930    #[serde(default, skip_serializing_if = "Option::is_none")]
4931    pub ignore_nulls: Option<bool>,
4932    /// Inferred data type from type annotation
4933    #[serde(default, skip_serializing_if = "Option::is_none")]
4934    #[ast(skip)]
4935    pub inferred_type: Option<DataType>,
4936}
4937
4938/// Represent a window function call with its OVER clause.
4939///
4940/// The inner `this` expression is typically a window-specific expression
4941/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
4942/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
4943/// frame specification.
4944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4945#[cfg_attr(feature = "bindings", derive(TS))]
4946pub struct WindowFunction {
4947    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
4948    pub this: Expression,
4949    /// The OVER clause defining the window partitioning, ordering, and frame.
4950    pub over: Over,
4951    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
4952    #[serde(default, skip_serializing_if = "Option::is_none")]
4953    pub keep: Option<Keep>,
4954    /// Inferred data type from type annotation
4955    #[serde(default, skip_serializing_if = "Option::is_none")]
4956    #[ast(skip)]
4957    pub inferred_type: Option<DataType>,
4958}
4959
4960/// Oracle KEEP clause for aggregate functions
4961/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
4962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4963#[cfg_attr(feature = "bindings", derive(TS))]
4964pub struct Keep {
4965    /// true = FIRST, false = LAST
4966    pub first: bool,
4967    /// ORDER BY clause inside KEEP
4968    pub order_by: Vec<Ordered>,
4969}
4970
4971/// WITHIN GROUP clause (for ordered-set aggregate functions)
4972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4973#[cfg_attr(feature = "bindings", derive(TS))]
4974pub struct WithinGroup {
4975    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
4976    pub this: Expression,
4977    /// The ORDER BY clause within the group
4978    pub order_by: Vec<Ordered>,
4979}
4980
4981/// Represent the FROM clause of a SELECT statement.
4982///
4983/// Contains one or more table sources (tables, subqueries, table-valued
4984/// functions, etc.). Multiple entries represent comma-separated implicit joins.
4985#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4986#[cfg_attr(feature = "bindings", derive(TS))]
4987pub struct From {
4988    /// The table source expressions.
4989    pub expressions: Vec<Expression>,
4990}
4991
4992/// Represent a JOIN clause between two table sources.
4993///
4994/// The join condition can be specified via `on` (ON predicate) or `using`
4995/// (USING column list), but not both. The `kind` field determines the join
4996/// type (INNER, LEFT, CROSS, etc.).
4997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4998#[cfg_attr(feature = "bindings", derive(TS))]
4999pub struct Join {
5000    /// The right-hand table expression being joined.
5001    pub this: Expression,
5002    /// The ON condition (mutually exclusive with `using`).
5003    pub on: Option<Expression>,
5004    /// The USING column list (mutually exclusive with `on`).
5005    pub using: Vec<Identifier>,
5006    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5007    pub kind: JoinKind,
5008    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5009    pub use_inner_keyword: bool,
5010    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5011    pub use_outer_keyword: bool,
5012    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5013    pub deferred_condition: bool,
5014    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5015    #[serde(default, skip_serializing_if = "Option::is_none")]
5016    pub join_hint: Option<String>,
5017    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5018    #[serde(default, skip_serializing_if = "Option::is_none")]
5019    pub match_condition: Option<Expression>,
5020    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5021    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5022    pub pivots: Vec<Expression>,
5023    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5024    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5025    pub comments: Vec<String>,
5026    /// Nesting group identifier for nested join pretty-printing.
5027    /// Joins in the same group were parsed together; group boundaries come from
5028    /// deferred condition resolution phases.
5029    #[serde(default)]
5030    pub nesting_group: usize,
5031    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5032    #[serde(default)]
5033    pub directed: bool,
5034}
5035
5036/// Enumerate all supported SQL join types.
5037///
5038/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5039/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5040/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5041/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5042#[derive(
5043    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5044)]
5045#[cfg_attr(feature = "bindings", derive(TS))]
5046pub enum JoinKind {
5047    Inner,
5048    Left,
5049    Right,
5050    Full,
5051    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5052    Cross,
5053    Natural,
5054    NaturalLeft,
5055    NaturalRight,
5056    NaturalFull,
5057    Semi,
5058    Anti,
5059    // Directional SEMI/ANTI joins
5060    LeftSemi,
5061    LeftAnti,
5062    RightSemi,
5063    RightAnti,
5064    // SQL Server specific
5065    CrossApply,
5066    OuterApply,
5067    // Time-series specific
5068    AsOf,
5069    AsOfLeft,
5070    AsOfRight,
5071    // Lateral join
5072    Lateral,
5073    LeftLateral,
5074    // MySQL specific
5075    Straight,
5076    // Implicit join (comma-separated tables: FROM a, b)
5077    Implicit,
5078    // ClickHouse ARRAY JOIN
5079    Array,
5080    LeftArray,
5081    // ClickHouse PASTE JOIN (positional join)
5082    Paste,
5083    // DuckDB POSITIONAL JOIN
5084    Positional,
5085}
5086
5087impl Default for JoinKind {
5088    fn default() -> Self {
5089        JoinKind::Inner
5090    }
5091}
5092
5093/// Parenthesized table expression with joins
5094/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5095#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5096#[cfg_attr(feature = "bindings", derive(TS))]
5097pub struct JoinedTable {
5098    /// The left-hand side table expression
5099    pub left: Expression,
5100    /// The joins applied to the left table
5101    pub joins: Vec<Join>,
5102    /// LATERAL VIEW clauses (Hive/Spark)
5103    pub lateral_views: Vec<LateralView>,
5104    /// Optional alias for the joined table expression
5105    pub alias: Option<Identifier>,
5106}
5107
5108/// Represent a WHERE clause containing a boolean filter predicate.
5109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5110#[cfg_attr(feature = "bindings", derive(TS))]
5111pub struct Where {
5112    /// The filter predicate expression.
5113    pub this: Expression,
5114}
5115
5116/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5117///
5118/// The `expressions` list may contain plain columns, ordinal positions,
5119/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5120#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5121#[cfg_attr(feature = "bindings", derive(TS))]
5122pub struct GroupBy {
5123    /// The grouping expressions.
5124    pub expressions: Vec<Expression>,
5125    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5126    #[serde(default)]
5127    pub all: Option<bool>,
5128    /// ClickHouse: WITH TOTALS modifier
5129    #[serde(default)]
5130    pub totals: bool,
5131    /// Leading comments that appeared before the GROUP BY keyword
5132    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5133    pub comments: Vec<String>,
5134}
5135
5136/// Represent a HAVING clause containing a predicate over aggregate results.
5137#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5138#[cfg_attr(feature = "bindings", derive(TS))]
5139pub struct Having {
5140    /// The filter predicate, typically involving aggregate functions.
5141    pub this: Expression,
5142    /// Leading comments that appeared before the HAVING keyword
5143    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5144    pub comments: Vec<String>,
5145}
5146
5147/// Represent an ORDER BY clause containing one or more sort specifications.
5148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5149#[cfg_attr(feature = "bindings", derive(TS))]
5150pub struct OrderBy {
5151    /// The sort specifications, each with direction and null ordering.
5152    pub expressions: Vec<Ordered>,
5153    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5154    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5155    pub siblings: bool,
5156    /// Leading comments that appeared before the ORDER BY keyword
5157    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5158    pub comments: Vec<String>,
5159}
5160
5161/// Represent an expression with sort direction and null ordering.
5162///
5163/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5164/// When `desc` is false the sort is ascending. The `nulls_first` field
5165/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5166/// (database default).
5167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5168#[cfg_attr(feature = "bindings", derive(TS))]
5169pub struct Ordered {
5170    /// The expression to sort by.
5171    pub this: Expression,
5172    /// Whether the sort direction is descending (true) or ascending (false).
5173    pub desc: bool,
5174    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5175    pub nulls_first: Option<bool>,
5176    /// Whether ASC was explicitly written (not just implied)
5177    #[serde(default)]
5178    pub explicit_asc: bool,
5179    /// ClickHouse WITH FILL clause
5180    #[serde(default, skip_serializing_if = "Option::is_none")]
5181    pub with_fill: Option<Box<WithFill>>,
5182}
5183
5184impl Ordered {
5185    pub fn asc(expr: Expression) -> Self {
5186        Self {
5187            this: expr,
5188            desc: false,
5189            nulls_first: None,
5190            explicit_asc: false,
5191            with_fill: None,
5192        }
5193    }
5194
5195    pub fn desc(expr: Expression) -> Self {
5196        Self {
5197            this: expr,
5198            desc: true,
5199            nulls_first: None,
5200            explicit_asc: false,
5201            with_fill: None,
5202        }
5203    }
5204}
5205
5206/// DISTRIBUTE BY clause (Hive/Spark)
5207/// Controls how rows are distributed across reducers
5208#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5209#[cfg_attr(feature = "bindings", derive(TS))]
5210#[cfg_attr(feature = "bindings", ts(export))]
5211pub struct DistributeBy {
5212    pub expressions: Vec<Expression>,
5213}
5214
5215/// CLUSTER BY clause (Hive/Spark)
5216/// Combines DISTRIBUTE BY and SORT BY on the same columns
5217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5218#[cfg_attr(feature = "bindings", derive(TS))]
5219#[cfg_attr(feature = "bindings", ts(export))]
5220pub struct ClusterBy {
5221    pub expressions: Vec<Ordered>,
5222}
5223
5224/// SORT BY clause (Hive/Spark)
5225/// Sorts data within each reducer (local sort, not global)
5226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5227#[cfg_attr(feature = "bindings", derive(TS))]
5228#[cfg_attr(feature = "bindings", ts(export))]
5229pub struct SortBy {
5230    pub expressions: Vec<Ordered>,
5231}
5232
5233/// LATERAL VIEW clause (Hive/Spark)
5234/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5235#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5236#[cfg_attr(feature = "bindings", derive(TS))]
5237#[cfg_attr(feature = "bindings", ts(export))]
5238pub struct LateralView {
5239    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5240    pub this: Expression,
5241    /// Table alias for the generated table
5242    pub table_alias: Option<Identifier>,
5243    /// Column aliases for the generated columns
5244    pub column_aliases: Vec<Identifier>,
5245    /// OUTER keyword - preserve nulls when input is empty/null
5246    pub outer: bool,
5247}
5248
5249/// Query hint
5250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5251#[cfg_attr(feature = "bindings", derive(TS))]
5252#[cfg_attr(feature = "bindings", ts(export))]
5253pub struct Hint {
5254    pub expressions: Vec<HintExpression>,
5255}
5256
5257/// Individual hint expression
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 enum HintExpression {
5262    /// Function-style hint: USE_HASH(table)
5263    Function { name: String, args: Vec<Expression> },
5264    /// Simple identifier hint: PARALLEL
5265    Identifier(String),
5266    /// Raw hint text (unparsed)
5267    Raw(String),
5268}
5269
5270/// Pseudocolumn type
5271#[derive(
5272    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5273)]
5274#[cfg_attr(feature = "bindings", derive(TS))]
5275#[cfg_attr(feature = "bindings", ts(export))]
5276pub enum PseudocolumnType {
5277    Rownum,      // Oracle ROWNUM
5278    Rowid,       // Oracle ROWID
5279    Level,       // Oracle LEVEL (for CONNECT BY)
5280    Sysdate,     // Oracle SYSDATE
5281    ObjectId,    // Oracle OBJECT_ID
5282    ObjectValue, // Oracle OBJECT_VALUE
5283}
5284
5285impl PseudocolumnType {
5286    pub fn as_str(&self) -> &'static str {
5287        match self {
5288            PseudocolumnType::Rownum => "ROWNUM",
5289            PseudocolumnType::Rowid => "ROWID",
5290            PseudocolumnType::Level => "LEVEL",
5291            PseudocolumnType::Sysdate => "SYSDATE",
5292            PseudocolumnType::ObjectId => "OBJECT_ID",
5293            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5294        }
5295    }
5296
5297    pub fn from_str(s: &str) -> Option<Self> {
5298        match s.to_uppercase().as_str() {
5299            "ROWNUM" => Some(PseudocolumnType::Rownum),
5300            "ROWID" => Some(PseudocolumnType::Rowid),
5301            "LEVEL" => Some(PseudocolumnType::Level),
5302            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5303            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5304            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5305            _ => None,
5306        }
5307    }
5308}
5309
5310/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5311/// These are special identifiers that should not be quoted
5312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5313#[cfg_attr(feature = "bindings", derive(TS))]
5314#[cfg_attr(feature = "bindings", ts(export))]
5315pub struct Pseudocolumn {
5316    pub kind: PseudocolumnType,
5317}
5318
5319impl Pseudocolumn {
5320    pub fn rownum() -> Self {
5321        Self {
5322            kind: PseudocolumnType::Rownum,
5323        }
5324    }
5325
5326    pub fn rowid() -> Self {
5327        Self {
5328            kind: PseudocolumnType::Rowid,
5329        }
5330    }
5331
5332    pub fn level() -> Self {
5333        Self {
5334            kind: PseudocolumnType::Level,
5335        }
5336    }
5337}
5338
5339/// Oracle CONNECT BY clause for hierarchical queries
5340#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5341#[cfg_attr(feature = "bindings", derive(TS))]
5342#[cfg_attr(feature = "bindings", ts(export))]
5343pub struct Connect {
5344    /// START WITH condition (optional, can come before or after CONNECT BY)
5345    pub start: Option<Expression>,
5346    /// CONNECT BY condition (required, contains PRIOR references)
5347    pub connect: Expression,
5348    /// NOCYCLE keyword to prevent infinite loops
5349    pub nocycle: bool,
5350}
5351
5352/// Oracle PRIOR expression - references parent row's value in CONNECT BY
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 Prior {
5357    pub this: Expression,
5358}
5359
5360/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5362#[cfg_attr(feature = "bindings", derive(TS))]
5363#[cfg_attr(feature = "bindings", ts(export))]
5364pub struct ConnectByRoot {
5365    pub this: Expression,
5366}
5367
5368/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5370#[cfg_attr(feature = "bindings", derive(TS))]
5371#[cfg_attr(feature = "bindings", ts(export))]
5372pub struct MatchRecognize {
5373    /// Source table/expression
5374    pub this: Option<Box<Expression>>,
5375    /// PARTITION BY expressions
5376    pub partition_by: Option<Vec<Expression>>,
5377    /// ORDER BY expressions
5378    pub order_by: Option<Vec<Ordered>>,
5379    /// MEASURES definitions
5380    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5381    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5382    pub rows: Option<MatchRecognizeRows>,
5383    /// AFTER MATCH SKIP behavior
5384    pub after: Option<MatchRecognizeAfter>,
5385    /// PATTERN definition (stored as raw string for complex regex patterns)
5386    pub pattern: Option<String>,
5387    /// DEFINE clauses (pattern variable definitions)
5388    pub define: Option<Vec<(Identifier, Expression)>>,
5389    /// Optional alias for the result
5390    pub alias: Option<Identifier>,
5391    /// Whether AS keyword was explicitly present before alias
5392    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5393    pub alias_explicit_as: bool,
5394}
5395
5396/// MEASURES expression with optional RUNNING/FINAL semantics
5397#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5398#[cfg_attr(feature = "bindings", derive(TS))]
5399#[cfg_attr(feature = "bindings", ts(export))]
5400pub struct MatchRecognizeMeasure {
5401    /// The measure expression
5402    pub this: Expression,
5403    /// RUNNING or FINAL semantics (Snowflake-specific)
5404    pub window_frame: Option<MatchRecognizeSemantics>,
5405}
5406
5407/// Semantics for MEASURES in MATCH_RECOGNIZE
5408#[derive(
5409    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5410)]
5411#[cfg_attr(feature = "bindings", derive(TS))]
5412#[cfg_attr(feature = "bindings", ts(export))]
5413pub enum MatchRecognizeSemantics {
5414    Running,
5415    Final,
5416}
5417
5418/// Row output semantics for MATCH_RECOGNIZE
5419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5420#[cfg_attr(feature = "bindings", derive(TS))]
5421#[cfg_attr(feature = "bindings", ts(export))]
5422pub enum MatchRecognizeRows {
5423    OneRowPerMatch,
5424    AllRowsPerMatch,
5425    AllRowsPerMatchShowEmptyMatches,
5426    AllRowsPerMatchOmitEmptyMatches,
5427    AllRowsPerMatchWithUnmatchedRows,
5428}
5429
5430/// AFTER MATCH SKIP behavior
5431#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5432#[cfg_attr(feature = "bindings", derive(TS))]
5433#[cfg_attr(feature = "bindings", ts(export))]
5434pub enum MatchRecognizeAfter {
5435    PastLastRow,
5436    ToNextRow,
5437    ToFirst(Identifier),
5438    ToLast(Identifier),
5439}
5440
5441/// Represent a LIMIT clause that restricts the number of returned rows.
5442#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5443#[cfg_attr(feature = "bindings", derive(TS))]
5444pub struct Limit {
5445    /// The limit count expression.
5446    pub this: Expression,
5447    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5448    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5449    pub percent: bool,
5450    /// Comments from before the LIMIT keyword (emitted after the limit value)
5451    #[serde(default)]
5452    #[serde(skip_serializing_if = "Vec::is_empty")]
5453    pub comments: Vec<String>,
5454}
5455
5456/// OFFSET clause
5457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5458#[cfg_attr(feature = "bindings", derive(TS))]
5459pub struct Offset {
5460    pub this: Expression,
5461    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5462    #[serde(skip_serializing_if = "Option::is_none", default)]
5463    pub rows: Option<bool>,
5464}
5465
5466/// TOP clause (SQL Server)
5467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5468#[cfg_attr(feature = "bindings", derive(TS))]
5469pub struct Top {
5470    pub this: Expression,
5471    pub percent: bool,
5472    pub with_ties: bool,
5473    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5474    #[serde(default)]
5475    pub parenthesized: bool,
5476}
5477
5478/// FETCH FIRST/NEXT clause (SQL standard)
5479#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5480#[cfg_attr(feature = "bindings", derive(TS))]
5481pub struct Fetch {
5482    /// FIRST or NEXT
5483    pub direction: String,
5484    /// Count expression (optional)
5485    pub count: Option<Expression>,
5486    /// PERCENT modifier
5487    pub percent: bool,
5488    /// ROWS or ROW keyword present
5489    pub rows: bool,
5490    /// WITH TIES modifier
5491    pub with_ties: bool,
5492}
5493
5494/// Represent a QUALIFY clause for filtering on window function results.
5495///
5496/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5497/// typically references a window function (e.g.
5498/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5500#[cfg_attr(feature = "bindings", derive(TS))]
5501pub struct Qualify {
5502    /// The filter predicate over window function results.
5503    pub this: Expression,
5504}
5505
5506/// SAMPLE / TABLESAMPLE clause
5507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5508#[cfg_attr(feature = "bindings", derive(TS))]
5509pub struct Sample {
5510    pub method: SampleMethod,
5511    pub size: Expression,
5512    pub seed: Option<Expression>,
5513    /// ClickHouse OFFSET expression after SAMPLE size
5514    #[serde(default)]
5515    pub offset: Option<Expression>,
5516    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5517    pub unit_after_size: bool,
5518    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5519    #[serde(default)]
5520    pub use_sample_keyword: bool,
5521    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5522    #[serde(default)]
5523    pub explicit_method: bool,
5524    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5525    #[serde(default)]
5526    pub method_before_size: bool,
5527    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5528    #[serde(default)]
5529    pub use_seed_keyword: bool,
5530    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5531    pub bucket_numerator: Option<Box<Expression>>,
5532    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5533    pub bucket_denominator: Option<Box<Expression>>,
5534    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5535    pub bucket_field: Option<Box<Expression>>,
5536    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5537    #[serde(default)]
5538    pub is_using_sample: bool,
5539    /// Whether the unit was explicitly PERCENT (vs ROWS)
5540    #[serde(default)]
5541    pub is_percent: bool,
5542    /// Whether to suppress method output (for cross-dialect transpilation)
5543    #[serde(default)]
5544    pub suppress_method_output: bool,
5545}
5546
5547/// Sample method
5548#[derive(
5549    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5550)]
5551#[cfg_attr(feature = "bindings", derive(TS))]
5552pub enum SampleMethod {
5553    Bernoulli,
5554    System,
5555    Block,
5556    Row,
5557    Percent,
5558    /// Hive bucket sampling
5559    Bucket,
5560    /// DuckDB reservoir sampling
5561    Reservoir,
5562}
5563
5564/// Named window definition (WINDOW w AS (...))
5565#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5566#[cfg_attr(feature = "bindings", derive(TS))]
5567pub struct NamedWindow {
5568    pub name: Identifier,
5569    pub spec: Over,
5570}
5571
5572/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5573///
5574/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5575/// that reference themselves. Each CTE is defined in the `ctes` vector and
5576/// can be referenced by name in subsequent CTEs and in the main query body.
5577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5578#[cfg_attr(feature = "bindings", derive(TS))]
5579pub struct With {
5580    /// The list of CTE definitions, in order.
5581    pub ctes: Vec<Cte>,
5582    /// Whether the WITH RECURSIVE keyword was used.
5583    pub recursive: bool,
5584    /// Leading comments before the statement
5585    #[serde(default)]
5586    pub leading_comments: Vec<String>,
5587    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5588    #[serde(default, skip_serializing_if = "Option::is_none")]
5589    pub search: Option<Box<Expression>>,
5590}
5591
5592/// Represent a single Common Table Expression definition.
5593///
5594/// A CTE has a name (`alias`), an optional column list, and a body query.
5595/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5596/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5597/// the expression comes before the alias (`alias_first`).
5598#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5599#[cfg_attr(feature = "bindings", derive(TS))]
5600pub struct Cte {
5601    /// The CTE name.
5602    pub alias: Identifier,
5603    /// The CTE body (typically a SELECT, UNION, etc.).
5604    pub this: Expression,
5605    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5606    pub columns: Vec<Identifier>,
5607    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5608    pub materialized: Option<bool>,
5609    /// USING KEY (columns) for DuckDB recursive CTEs
5610    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5611    pub key_expressions: Vec<Identifier>,
5612    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5613    #[serde(default)]
5614    pub alias_first: bool,
5615    /// Comments associated with this CTE (placed after alias name, before AS)
5616    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5617    pub comments: Vec<String>,
5618}
5619
5620/// Window specification
5621#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5622#[cfg_attr(feature = "bindings", derive(TS))]
5623pub struct WindowSpec {
5624    pub partition_by: Vec<Expression>,
5625    pub order_by: Vec<Ordered>,
5626    pub frame: Option<WindowFrame>,
5627}
5628
5629/// OVER clause
5630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5631#[cfg_attr(feature = "bindings", derive(TS))]
5632pub struct Over {
5633    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
5634    pub window_name: Option<Identifier>,
5635    pub partition_by: Vec<Expression>,
5636    pub order_by: Vec<Ordered>,
5637    pub frame: Option<WindowFrame>,
5638    pub alias: Option<Identifier>,
5639}
5640
5641/// Window frame
5642#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5643#[cfg_attr(feature = "bindings", derive(TS))]
5644pub struct WindowFrame {
5645    pub kind: WindowFrameKind,
5646    pub start: WindowFrameBound,
5647    pub end: Option<WindowFrameBound>,
5648    pub exclude: Option<WindowFrameExclude>,
5649    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
5650    #[serde(default, skip_serializing_if = "Option::is_none")]
5651    pub kind_text: Option<String>,
5652    /// Original text of the start bound side keyword (e.g. "preceding")
5653    #[serde(default, skip_serializing_if = "Option::is_none")]
5654    pub start_side_text: Option<String>,
5655    /// Original text of the end bound side keyword
5656    #[serde(default, skip_serializing_if = "Option::is_none")]
5657    pub end_side_text: Option<String>,
5658}
5659
5660#[derive(
5661    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5662)]
5663#[cfg_attr(feature = "bindings", derive(TS))]
5664pub enum WindowFrameKind {
5665    Rows,
5666    Range,
5667    Groups,
5668}
5669
5670/// EXCLUDE clause for window frames
5671#[derive(
5672    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5673)]
5674#[cfg_attr(feature = "bindings", derive(TS))]
5675pub enum WindowFrameExclude {
5676    CurrentRow,
5677    Group,
5678    Ties,
5679    NoOthers,
5680}
5681
5682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5683#[cfg_attr(feature = "bindings", derive(TS))]
5684pub enum WindowFrameBound {
5685    CurrentRow,
5686    UnboundedPreceding,
5687    UnboundedFollowing,
5688    Preceding(Box<Expression>),
5689    Following(Box<Expression>),
5690    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
5691    BarePreceding,
5692    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
5693    BareFollowing,
5694    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
5695    Value(Box<Expression>),
5696}
5697
5698/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
5699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5700#[cfg_attr(feature = "bindings", derive(TS))]
5701pub struct StructField {
5702    pub name: String,
5703    pub data_type: DataType,
5704    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5705    pub options: Vec<Expression>,
5706    #[serde(default, skip_serializing_if = "Option::is_none")]
5707    pub comment: Option<String>,
5708}
5709
5710impl StructField {
5711    /// Create a new struct field without options
5712    pub fn new(name: String, data_type: DataType) -> Self {
5713        Self {
5714            name,
5715            data_type,
5716            options: Vec::new(),
5717            comment: None,
5718        }
5719    }
5720
5721    /// Create a new struct field with options
5722    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
5723        Self {
5724            name,
5725            data_type,
5726            options,
5727            comment: None,
5728        }
5729    }
5730
5731    /// Create a new struct field with options and comment
5732    pub fn with_options_and_comment(
5733        name: String,
5734        data_type: DataType,
5735        options: Vec<Expression>,
5736        comment: Option<String>,
5737    ) -> Self {
5738        Self {
5739            name,
5740            data_type,
5741            options,
5742            comment,
5743        }
5744    }
5745}
5746
5747/// Enumerate all SQL data types recognized by the parser.
5748///
5749/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
5750/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
5751/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
5752///
5753/// This enum is used in CAST expressions, column definitions, function return
5754/// types, and anywhere a data type specification appears in SQL.
5755///
5756/// Types that do not match any known variant fall through to `Custom { name }`,
5757/// preserving the original type name for round-trip fidelity.
5758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5759#[cfg_attr(feature = "bindings", derive(TS))]
5760#[serde(tag = "data_type", rename_all = "snake_case")]
5761pub enum DataType {
5762    // Numeric
5763    Boolean,
5764    TinyInt {
5765        length: Option<u32>,
5766    },
5767    SmallInt {
5768        length: Option<u32>,
5769    },
5770    /// Int type with optional length. `integer_spelling` indicates whether the original
5771    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
5772    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
5773    Int {
5774        length: Option<u32>,
5775        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5776        integer_spelling: bool,
5777    },
5778    BigInt {
5779        length: Option<u32>,
5780    },
5781    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
5782    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
5783    /// preserve the original spelling.
5784    Float {
5785        precision: Option<u32>,
5786        scale: Option<u32>,
5787        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5788        real_spelling: bool,
5789    },
5790    Double {
5791        precision: Option<u32>,
5792        scale: Option<u32>,
5793    },
5794    Decimal {
5795        precision: Option<u32>,
5796        scale: Option<u32>,
5797    },
5798
5799    // String
5800    Char {
5801        length: Option<u32>,
5802    },
5803    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
5804    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
5805    VarChar {
5806        length: Option<u32>,
5807        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5808        parenthesized_length: bool,
5809    },
5810    /// String type with optional max length (BigQuery STRING(n))
5811    String {
5812        length: Option<u32>,
5813    },
5814    Text,
5815    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
5816    TextWithLength {
5817        length: u32,
5818    },
5819
5820    // Binary
5821    Binary {
5822        length: Option<u32>,
5823    },
5824    VarBinary {
5825        length: Option<u32>,
5826    },
5827    Blob,
5828
5829    // Bit
5830    Bit {
5831        length: Option<u32>,
5832    },
5833    VarBit {
5834        length: Option<u32>,
5835    },
5836
5837    // Date/Time
5838    Date,
5839    Time {
5840        precision: Option<u32>,
5841        #[serde(default)]
5842        timezone: bool,
5843    },
5844    Timestamp {
5845        precision: Option<u32>,
5846        timezone: bool,
5847    },
5848    Interval {
5849        unit: Option<String>,
5850        /// For range intervals like INTERVAL DAY TO HOUR
5851        #[serde(default, skip_serializing_if = "Option::is_none")]
5852        to: Option<String>,
5853    },
5854
5855    // JSON
5856    Json,
5857    JsonB,
5858
5859    // UUID
5860    Uuid,
5861
5862    // Array
5863    Array {
5864        element_type: Box<DataType>,
5865        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
5866        #[serde(default, skip_serializing_if = "Option::is_none")]
5867        dimension: Option<u32>,
5868    },
5869
5870    /// List type (Materialize): INT LIST, TEXT LIST LIST
5871    /// Uses postfix LIST syntax instead of ARRAY<T>
5872    List {
5873        element_type: Box<DataType>,
5874    },
5875
5876    // Struct/Map
5877    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
5878    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
5879    Struct {
5880        fields: Vec<StructField>,
5881        nested: bool,
5882    },
5883    Map {
5884        key_type: Box<DataType>,
5885        value_type: Box<DataType>,
5886    },
5887
5888    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
5889    Enum {
5890        values: Vec<String>,
5891        #[serde(default, skip_serializing_if = "Vec::is_empty")]
5892        assignments: Vec<Option<String>>,
5893    },
5894
5895    // Set type (MySQL): SET('a', 'b', 'c')
5896    Set {
5897        values: Vec<String>,
5898    },
5899
5900    // Union type (DuckDB): UNION(num INT, str TEXT)
5901    Union {
5902        fields: Vec<(String, DataType)>,
5903    },
5904
5905    // Vector (Snowflake / SingleStore)
5906    Vector {
5907        #[serde(default)]
5908        element_type: Option<Box<DataType>>,
5909        dimension: Option<u32>,
5910    },
5911
5912    // Object (Snowflake structured type)
5913    // fields: Vec of (field_name, field_type, not_null)
5914    Object {
5915        fields: Vec<(String, DataType, bool)>,
5916        modifier: Option<String>,
5917    },
5918
5919    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
5920    Nullable {
5921        inner: Box<DataType>,
5922    },
5923
5924    // Custom/User-defined
5925    Custom {
5926        name: String,
5927    },
5928
5929    // Spatial types
5930    Geometry {
5931        subtype: Option<String>,
5932        srid: Option<u32>,
5933    },
5934    Geography {
5935        subtype: Option<String>,
5936        srid: Option<u32>,
5937    },
5938
5939    // Character Set (for CONVERT USING in MySQL)
5940    // Renders as CHAR CHARACTER SET {name} in cast target
5941    CharacterSet {
5942        name: String,
5943    },
5944
5945    // Unknown
5946    Unknown,
5947}
5948
5949/// Array expression
5950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5951#[cfg_attr(feature = "bindings", derive(TS))]
5952#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
5953pub struct Array {
5954    pub expressions: Vec<Expression>,
5955}
5956
5957/// Struct expression
5958#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5959#[cfg_attr(feature = "bindings", derive(TS))]
5960pub struct Struct {
5961    pub fields: Vec<(Option<String>, Expression)>,
5962}
5963
5964/// Tuple expression
5965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5966#[cfg_attr(feature = "bindings", derive(TS))]
5967pub struct Tuple {
5968    pub expressions: Vec<Expression>,
5969}
5970
5971/// Interval expression
5972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5973#[cfg_attr(feature = "bindings", derive(TS))]
5974pub struct Interval {
5975    /// The value expression (e.g., '1', 5, column_ref)
5976    pub this: Option<Expression>,
5977    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
5978    pub unit: Option<IntervalUnitSpec>,
5979}
5980
5981/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
5982#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5983#[cfg_attr(feature = "bindings", derive(TS))]
5984#[serde(tag = "type", rename_all = "snake_case")]
5985pub enum IntervalUnitSpec {
5986    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
5987    Simple {
5988        unit: IntervalUnit,
5989        /// Whether to use plural form (e.g., DAYS vs DAY)
5990        use_plural: bool,
5991    },
5992    /// Interval span (e.g., HOUR TO SECOND)
5993    Span(IntervalSpan),
5994    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
5995    /// The start and end can be expressions like function calls with precision
5996    ExprSpan(IntervalSpanExpr),
5997    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
5998    Expr(Box<Expression>),
5999}
6000
6001/// Interval span for ranges like HOUR TO SECOND
6002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6003#[cfg_attr(feature = "bindings", derive(TS))]
6004pub struct IntervalSpan {
6005    /// Start unit (e.g., HOUR)
6006    pub this: IntervalUnit,
6007    /// End unit (e.g., SECOND)
6008    pub expression: IntervalUnit,
6009}
6010
6011/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6012/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6014#[cfg_attr(feature = "bindings", derive(TS))]
6015pub struct IntervalSpanExpr {
6016    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6017    pub this: Box<Expression>,
6018    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6019    pub expression: Box<Expression>,
6020}
6021
6022#[derive(
6023    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6024)]
6025#[cfg_attr(feature = "bindings", derive(TS))]
6026pub enum IntervalUnit {
6027    Year,
6028    Quarter,
6029    Month,
6030    Week,
6031    Day,
6032    Hour,
6033    Minute,
6034    Second,
6035    Millisecond,
6036    Microsecond,
6037    Nanosecond,
6038}
6039
6040/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6041#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6042#[cfg_attr(feature = "bindings", derive(TS))]
6043pub struct Command {
6044    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6045    pub this: String,
6046}
6047
6048/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6049/// Syntax: PREPARE name [(type, ...)] AS statement
6050#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6051#[cfg_attr(feature = "bindings", derive(TS))]
6052pub struct PrepareStatement {
6053    /// The prepared statement name.
6054    pub name: Identifier,
6055    /// Optional PostgreSQL parameter type list.
6056    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6057    pub parameter_types: Vec<DataType>,
6058    /// The statement to execute when the prepared statement is invoked.
6059    pub statement: Expression,
6060}
6061
6062/// T-SQL TRY/CATCH block.
6063#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6064#[cfg_attr(feature = "bindings", derive(TS))]
6065pub struct TryCatch {
6066    /// Statements inside BEGIN TRY ... END TRY.
6067    #[serde(default)]
6068    pub try_body: Vec<Expression>,
6069    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6070    #[serde(default, skip_serializing_if = "Option::is_none")]
6071    pub catch_body: Option<Vec<Expression>>,
6072}
6073
6074/// EXEC/EXECUTE statement (TSQL stored procedure call)
6075/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6077#[cfg_attr(feature = "bindings", derive(TS))]
6078pub struct ExecuteStatement {
6079    /// The procedure name (can be qualified: schema.proc_name)
6080    pub this: Expression,
6081    /// Named parameters: @param=value pairs
6082    #[serde(default)]
6083    pub parameters: Vec<ExecuteParameter>,
6084    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6085    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6086    pub arguments: Vec<Expression>,
6087    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6088    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6089    pub prepared: bool,
6090    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6091    #[serde(default, skip_serializing_if = "Option::is_none")]
6092    pub suffix: Option<String>,
6093}
6094
6095/// Named parameter in EXEC statement: @name=value
6096#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6097#[cfg_attr(feature = "bindings", derive(TS))]
6098pub struct ExecuteParameter {
6099    /// Parameter name (including @)
6100    pub name: String,
6101    /// Parameter value
6102    pub value: Expression,
6103    /// Whether this is a positional parameter (no = sign)
6104    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6105    pub positional: bool,
6106    /// TSQL OUTPUT modifier on parameter
6107    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6108    pub output: bool,
6109}
6110
6111/// KILL statement (MySQL/MariaDB)
6112/// KILL [CONNECTION | QUERY] <id>
6113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6114#[cfg_attr(feature = "bindings", derive(TS))]
6115pub struct Kill {
6116    /// The target (process ID or connection ID)
6117    pub this: Expression,
6118    /// Optional kind: "CONNECTION" or "QUERY"
6119    pub kind: Option<String>,
6120}
6121
6122/// Snowflake CREATE TASK statement
6123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6124#[cfg_attr(feature = "bindings", derive(TS))]
6125pub struct CreateTask {
6126    pub or_replace: bool,
6127    pub if_not_exists: bool,
6128    /// Task name (possibly qualified: db.schema.task)
6129    pub name: String,
6130    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6131    pub properties: String,
6132    /// The SQL statement body after AS
6133    pub body: Expression,
6134}
6135
6136/// Raw/unparsed SQL
6137#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6138#[cfg_attr(feature = "bindings", derive(TS))]
6139pub struct Raw {
6140    pub sql: String,
6141}
6142
6143// ============================================================================
6144// Function expression types
6145// ============================================================================
6146
6147/// Generic unary function (takes a single argument)
6148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6149#[cfg_attr(feature = "bindings", derive(TS))]
6150pub struct UnaryFunc {
6151    pub this: Expression,
6152    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6153    #[serde(skip_serializing_if = "Option::is_none", default)]
6154    pub original_name: Option<String>,
6155    /// Inferred data type from type annotation
6156    #[serde(default, skip_serializing_if = "Option::is_none")]
6157    #[ast(skip)]
6158    pub inferred_type: Option<DataType>,
6159}
6160
6161impl UnaryFunc {
6162    /// Create a new UnaryFunc with no original_name
6163    pub fn new(this: Expression) -> Self {
6164        Self {
6165            this,
6166            original_name: None,
6167            inferred_type: None,
6168        }
6169    }
6170
6171    /// Create a new UnaryFunc with an original name for round-trip preservation
6172    pub fn with_name(this: Expression, name: String) -> Self {
6173        Self {
6174            this,
6175            original_name: Some(name),
6176            inferred_type: None,
6177        }
6178    }
6179}
6180
6181/// CHAR/CHR function with multiple args and optional USING charset
6182/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6183/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6184#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6185#[cfg_attr(feature = "bindings", derive(TS))]
6186pub struct CharFunc {
6187    pub args: Vec<Expression>,
6188    #[serde(skip_serializing_if = "Option::is_none", default)]
6189    pub charset: Option<String>,
6190    /// Original function name (CHAR or CHR), defaults to CHAR
6191    #[serde(skip_serializing_if = "Option::is_none", default)]
6192    pub name: Option<String>,
6193}
6194
6195/// Generic binary function (takes two arguments)
6196#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6197#[cfg_attr(feature = "bindings", derive(TS))]
6198pub struct BinaryFunc {
6199    pub this: Expression,
6200    pub expression: Expression,
6201    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6202    #[serde(skip_serializing_if = "Option::is_none", default)]
6203    pub original_name: Option<String>,
6204    /// Inferred data type from type annotation
6205    #[serde(default, skip_serializing_if = "Option::is_none")]
6206    #[ast(skip)]
6207    pub inferred_type: Option<DataType>,
6208}
6209
6210/// Variable argument function
6211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6212#[cfg_attr(feature = "bindings", derive(TS))]
6213pub struct VarArgFunc {
6214    pub expressions: Vec<Expression>,
6215    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6216    #[serde(skip_serializing_if = "Option::is_none", default)]
6217    pub original_name: Option<String>,
6218    /// Inferred data type from type annotation
6219    #[serde(default, skip_serializing_if = "Option::is_none")]
6220    #[ast(skip)]
6221    pub inferred_type: Option<DataType>,
6222}
6223
6224/// CONCAT_WS function
6225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6226#[cfg_attr(feature = "bindings", derive(TS))]
6227pub struct ConcatWs {
6228    pub separator: Expression,
6229    pub expressions: Vec<Expression>,
6230}
6231
6232/// SUBSTRING function
6233#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6234#[cfg_attr(feature = "bindings", derive(TS))]
6235pub struct SubstringFunc {
6236    pub this: Expression,
6237    pub start: Expression,
6238    pub length: Option<Expression>,
6239    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6240    #[serde(default)]
6241    pub from_for_syntax: bool,
6242}
6243
6244/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6246#[cfg_attr(feature = "bindings", derive(TS))]
6247pub struct OverlayFunc {
6248    pub this: Expression,
6249    pub replacement: Expression,
6250    pub from: Expression,
6251    pub length: Option<Expression>,
6252}
6253
6254/// TRIM function
6255#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6256#[cfg_attr(feature = "bindings", derive(TS))]
6257pub struct TrimFunc {
6258    pub this: Expression,
6259    pub characters: Option<Expression>,
6260    pub position: TrimPosition,
6261    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6262    #[serde(default)]
6263    pub sql_standard_syntax: bool,
6264    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6265    #[serde(default)]
6266    pub position_explicit: bool,
6267}
6268
6269#[derive(
6270    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6271)]
6272#[cfg_attr(feature = "bindings", derive(TS))]
6273pub enum TrimPosition {
6274    Both,
6275    Leading,
6276    Trailing,
6277}
6278
6279/// REPLACE function
6280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6281#[cfg_attr(feature = "bindings", derive(TS))]
6282pub struct ReplaceFunc {
6283    pub this: Expression,
6284    pub old: Expression,
6285    pub new: Expression,
6286}
6287
6288/// LEFT/RIGHT function
6289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6290#[cfg_attr(feature = "bindings", derive(TS))]
6291pub struct LeftRightFunc {
6292    pub this: Expression,
6293    pub length: Expression,
6294}
6295
6296/// REPEAT function
6297#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6298#[cfg_attr(feature = "bindings", derive(TS))]
6299pub struct RepeatFunc {
6300    pub this: Expression,
6301    pub times: Expression,
6302}
6303
6304/// LPAD/RPAD function
6305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6306#[cfg_attr(feature = "bindings", derive(TS))]
6307pub struct PadFunc {
6308    pub this: Expression,
6309    pub length: Expression,
6310    pub fill: Option<Expression>,
6311}
6312
6313/// SPLIT function
6314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6315#[cfg_attr(feature = "bindings", derive(TS))]
6316pub struct SplitFunc {
6317    pub this: Expression,
6318    pub delimiter: Expression,
6319}
6320
6321/// REGEXP_LIKE function
6322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6323#[cfg_attr(feature = "bindings", derive(TS))]
6324pub struct RegexpFunc {
6325    pub this: Expression,
6326    pub pattern: Expression,
6327    pub flags: Option<Expression>,
6328}
6329
6330/// REGEXP_REPLACE function
6331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6332#[cfg_attr(feature = "bindings", derive(TS))]
6333pub struct RegexpReplaceFunc {
6334    pub this: Expression,
6335    pub pattern: Expression,
6336    pub replacement: Expression,
6337    pub flags: Option<Expression>,
6338}
6339
6340/// REGEXP_EXTRACT function
6341#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6342#[cfg_attr(feature = "bindings", derive(TS))]
6343pub struct RegexpExtractFunc {
6344    pub this: Expression,
6345    pub pattern: Expression,
6346    pub group: Option<Expression>,
6347}
6348
6349/// ROUND function
6350#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6351#[cfg_attr(feature = "bindings", derive(TS))]
6352pub struct RoundFunc {
6353    pub this: Expression,
6354    pub decimals: Option<Expression>,
6355}
6356
6357/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6359#[cfg_attr(feature = "bindings", derive(TS))]
6360pub struct FloorFunc {
6361    pub this: Expression,
6362    pub scale: Option<Expression>,
6363    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6364    #[serde(skip_serializing_if = "Option::is_none", default)]
6365    pub to: Option<Expression>,
6366}
6367
6368/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6370#[cfg_attr(feature = "bindings", derive(TS))]
6371pub struct CeilFunc {
6372    pub this: Expression,
6373    #[serde(skip_serializing_if = "Option::is_none", default)]
6374    pub decimals: Option<Expression>,
6375    /// Time unit for Druid-style CEIL(time TO unit) syntax
6376    #[serde(skip_serializing_if = "Option::is_none", default)]
6377    pub to: Option<Expression>,
6378}
6379
6380/// LOG function
6381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6382#[cfg_attr(feature = "bindings", derive(TS))]
6383pub struct LogFunc {
6384    pub this: Expression,
6385    pub base: Option<Expression>,
6386}
6387
6388/// CURRENT_DATE (no arguments)
6389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6390#[cfg_attr(feature = "bindings", derive(TS))]
6391pub struct CurrentDate;
6392
6393/// CURRENT_TIME
6394#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6395#[cfg_attr(feature = "bindings", derive(TS))]
6396pub struct CurrentTime {
6397    pub precision: Option<u32>,
6398}
6399
6400/// CURRENT_TIMESTAMP
6401#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6402#[cfg_attr(feature = "bindings", derive(TS))]
6403pub struct CurrentTimestamp {
6404    pub precision: Option<u32>,
6405    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6406    #[serde(default)]
6407    pub sysdate: bool,
6408}
6409
6410/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6412#[cfg_attr(feature = "bindings", derive(TS))]
6413pub struct CurrentTimestampLTZ {
6414    pub precision: Option<u32>,
6415}
6416
6417/// AT TIME ZONE expression for timezone conversion
6418#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6419#[cfg_attr(feature = "bindings", derive(TS))]
6420pub struct AtTimeZone {
6421    /// The expression to convert
6422    pub this: Expression,
6423    /// The target timezone
6424    pub zone: Expression,
6425}
6426
6427/// DATE_ADD / DATE_SUB function
6428#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6429#[cfg_attr(feature = "bindings", derive(TS))]
6430pub struct DateAddFunc {
6431    pub this: Expression,
6432    pub interval: Expression,
6433    pub unit: IntervalUnit,
6434}
6435
6436/// DATEDIFF function
6437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6438#[cfg_attr(feature = "bindings", derive(TS))]
6439pub struct DateDiffFunc {
6440    pub this: Expression,
6441    pub expression: Expression,
6442    pub unit: Option<IntervalUnit>,
6443}
6444
6445/// DATE_TRUNC function
6446#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6447#[cfg_attr(feature = "bindings", derive(TS))]
6448pub struct DateTruncFunc {
6449    pub this: Expression,
6450    pub unit: DateTimeField,
6451}
6452
6453/// EXTRACT function
6454#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6455#[cfg_attr(feature = "bindings", derive(TS))]
6456pub struct ExtractFunc {
6457    pub this: Expression,
6458    pub field: DateTimeField,
6459}
6460
6461#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6462#[cfg_attr(feature = "bindings", derive(TS))]
6463pub enum DateTimeField {
6464    Year,
6465    Month,
6466    Day,
6467    Hour,
6468    Minute,
6469    Second,
6470    Millisecond,
6471    Microsecond,
6472    DayOfWeek,
6473    DayOfYear,
6474    Week,
6475    /// Week with a modifier like WEEK(monday), WEEK(sunday)
6476    WeekWithModifier(String),
6477    Quarter,
6478    Epoch,
6479    Timezone,
6480    TimezoneHour,
6481    TimezoneMinute,
6482    Date,
6483    Time,
6484    /// Custom datetime field for dialect-specific or arbitrary fields
6485    Custom(String),
6486}
6487
6488/// TO_DATE function
6489#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6490#[cfg_attr(feature = "bindings", derive(TS))]
6491pub struct ToDateFunc {
6492    pub this: Expression,
6493    pub format: Option<Expression>,
6494}
6495
6496/// TO_TIMESTAMP function
6497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6498#[cfg_attr(feature = "bindings", derive(TS))]
6499pub struct ToTimestampFunc {
6500    pub this: Expression,
6501    pub format: Option<Expression>,
6502}
6503
6504/// IF function
6505#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6506#[cfg_attr(feature = "bindings", derive(TS))]
6507pub struct IfFunc {
6508    pub condition: Expression,
6509    pub true_value: Expression,
6510    pub false_value: Option<Expression>,
6511    /// Original function name (IF, IFF, IIF) for round-trip preservation
6512    #[serde(skip_serializing_if = "Option::is_none", default)]
6513    pub original_name: Option<String>,
6514    /// Inferred data type from type annotation
6515    #[serde(default, skip_serializing_if = "Option::is_none")]
6516    #[ast(skip)]
6517    pub inferred_type: Option<DataType>,
6518}
6519
6520/// NVL2 function
6521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6522#[cfg_attr(feature = "bindings", derive(TS))]
6523pub struct Nvl2Func {
6524    pub this: Expression,
6525    pub true_value: Expression,
6526    pub false_value: Expression,
6527    /// Inferred data type from type annotation
6528    #[serde(default, skip_serializing_if = "Option::is_none")]
6529    #[ast(skip)]
6530    pub inferred_type: Option<DataType>,
6531}
6532
6533// ============================================================================
6534// Typed Aggregate Function types
6535// ============================================================================
6536
6537/// Generic aggregate function base type
6538#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6539#[cfg_attr(feature = "bindings", derive(TS))]
6540pub struct AggFunc {
6541    pub this: Expression,
6542    pub distinct: bool,
6543    pub filter: Option<Expression>,
6544    pub order_by: Vec<Ordered>,
6545    /// Original function name (case-preserving) when parsed from SQL
6546    #[serde(skip_serializing_if = "Option::is_none", default)]
6547    pub name: Option<String>,
6548    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
6549    #[serde(skip_serializing_if = "Option::is_none", default)]
6550    pub ignore_nulls: Option<bool>,
6551    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
6552    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
6553    #[serde(skip_serializing_if = "Option::is_none", default)]
6554    pub having_max: Option<(Box<Expression>, bool)>,
6555    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
6556    #[serde(skip_serializing_if = "Option::is_none", default)]
6557    pub limit: Option<Box<Expression>>,
6558    /// Inferred data type from type annotation
6559    #[serde(default, skip_serializing_if = "Option::is_none")]
6560    #[ast(skip)]
6561    pub inferred_type: Option<DataType>,
6562}
6563
6564/// COUNT function with optional star
6565#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6566#[cfg_attr(feature = "bindings", derive(TS))]
6567pub struct CountFunc {
6568    pub this: Option<Expression>,
6569    pub star: bool,
6570    pub distinct: bool,
6571    pub filter: Option<Expression>,
6572    /// IGNORE NULLS (true) or RESPECT NULLS (false)
6573    #[serde(default, skip_serializing_if = "Option::is_none")]
6574    pub ignore_nulls: Option<bool>,
6575    /// Original function name for case preservation (e.g., "count" or "COUNT")
6576    #[serde(default, skip_serializing_if = "Option::is_none")]
6577    pub original_name: Option<String>,
6578    /// Inferred data type from type annotation
6579    #[serde(default, skip_serializing_if = "Option::is_none")]
6580    #[ast(skip)]
6581    pub inferred_type: Option<DataType>,
6582}
6583
6584/// GROUP_CONCAT function (MySQL style)
6585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6586#[cfg_attr(feature = "bindings", derive(TS))]
6587pub struct GroupConcatFunc {
6588    pub this: Expression,
6589    pub separator: Option<Expression>,
6590    pub order_by: Option<Vec<Ordered>>,
6591    pub distinct: bool,
6592    pub filter: Option<Expression>,
6593    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
6594    #[serde(default, skip_serializing_if = "Option::is_none")]
6595    pub limit: Option<Box<Expression>>,
6596    /// Inferred data type from type annotation
6597    #[serde(default, skip_serializing_if = "Option::is_none")]
6598    #[ast(skip)]
6599    pub inferred_type: Option<DataType>,
6600}
6601
6602/// STRING_AGG function (PostgreSQL/Standard SQL)
6603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6604#[cfg_attr(feature = "bindings", derive(TS))]
6605pub struct StringAggFunc {
6606    pub this: Expression,
6607    #[serde(default)]
6608    pub separator: Option<Expression>,
6609    #[serde(default)]
6610    pub order_by: Option<Vec<Ordered>>,
6611    #[serde(default)]
6612    pub distinct: bool,
6613    #[serde(default)]
6614    pub filter: Option<Expression>,
6615    /// BigQuery LIMIT inside STRING_AGG
6616    #[serde(default, skip_serializing_if = "Option::is_none")]
6617    pub limit: Option<Box<Expression>>,
6618    /// Inferred data type from type annotation
6619    #[serde(default, skip_serializing_if = "Option::is_none")]
6620    #[ast(skip)]
6621    pub inferred_type: Option<DataType>,
6622}
6623
6624/// LISTAGG function (Oracle style)
6625#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6626#[cfg_attr(feature = "bindings", derive(TS))]
6627pub struct ListAggFunc {
6628    pub this: Expression,
6629    pub separator: Option<Expression>,
6630    pub on_overflow: Option<ListAggOverflow>,
6631    pub order_by: Option<Vec<Ordered>>,
6632    pub distinct: bool,
6633    pub filter: Option<Expression>,
6634    /// Inferred data type from type annotation
6635    #[serde(default, skip_serializing_if = "Option::is_none")]
6636    #[ast(skip)]
6637    pub inferred_type: Option<DataType>,
6638}
6639
6640/// LISTAGG ON OVERFLOW behavior
6641#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6642#[cfg_attr(feature = "bindings", derive(TS))]
6643pub enum ListAggOverflow {
6644    Error,
6645    Truncate {
6646        filler: Option<Expression>,
6647        with_count: bool,
6648    },
6649}
6650
6651/// SUM_IF / COUNT_IF function
6652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6653#[cfg_attr(feature = "bindings", derive(TS))]
6654pub struct SumIfFunc {
6655    pub this: Expression,
6656    pub condition: Expression,
6657    pub filter: Option<Expression>,
6658    /// Inferred data type from type annotation
6659    #[serde(default, skip_serializing_if = "Option::is_none")]
6660    #[ast(skip)]
6661    pub inferred_type: Option<DataType>,
6662}
6663
6664/// APPROX_PERCENTILE function
6665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6666#[cfg_attr(feature = "bindings", derive(TS))]
6667pub struct ApproxPercentileFunc {
6668    pub this: Expression,
6669    pub percentile: Expression,
6670    pub accuracy: Option<Expression>,
6671    pub filter: Option<Expression>,
6672}
6673
6674/// PERCENTILE_CONT / PERCENTILE_DISC function
6675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6676#[cfg_attr(feature = "bindings", derive(TS))]
6677pub struct PercentileFunc {
6678    pub this: Expression,
6679    pub percentile: Expression,
6680    pub order_by: Option<Vec<Ordered>>,
6681    pub filter: Option<Expression>,
6682}
6683
6684// ============================================================================
6685// Typed Window Function types
6686// ============================================================================
6687
6688/// ROW_NUMBER function (no arguments)
6689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6690#[cfg_attr(feature = "bindings", derive(TS))]
6691pub struct RowNumber;
6692
6693/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6695#[cfg_attr(feature = "bindings", derive(TS))]
6696pub struct Rank {
6697    /// DuckDB: RANK(ORDER BY col) - order by inside function
6698    #[serde(default, skip_serializing_if = "Option::is_none")]
6699    pub order_by: Option<Vec<Ordered>>,
6700    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6701    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6702    pub args: Vec<Expression>,
6703}
6704
6705/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
6706#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6707#[cfg_attr(feature = "bindings", derive(TS))]
6708pub struct DenseRank {
6709    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6710    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6711    pub args: Vec<Expression>,
6712}
6713
6714/// NTILE function (DuckDB allows ORDER BY inside)
6715#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6716#[cfg_attr(feature = "bindings", derive(TS))]
6717pub struct NTileFunc {
6718    /// num_buckets is optional to support Databricks NTILE() without arguments
6719    #[serde(default, skip_serializing_if = "Option::is_none")]
6720    pub num_buckets: Option<Expression>,
6721    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
6722    #[serde(default, skip_serializing_if = "Option::is_none")]
6723    pub order_by: Option<Vec<Ordered>>,
6724}
6725
6726/// LEAD / LAG function
6727#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6728#[cfg_attr(feature = "bindings", derive(TS))]
6729pub struct LeadLagFunc {
6730    pub this: Expression,
6731    pub offset: Option<Expression>,
6732    pub default: Option<Expression>,
6733    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6734    #[serde(default, skip_serializing_if = "Option::is_none")]
6735    pub ignore_nulls: Option<bool>,
6736}
6737
6738/// FIRST_VALUE / LAST_VALUE function
6739#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6740#[cfg_attr(feature = "bindings", derive(TS))]
6741pub struct ValueFunc {
6742    pub this: Expression,
6743    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6744    #[serde(default, skip_serializing_if = "Option::is_none")]
6745    pub ignore_nulls: Option<bool>,
6746    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
6747    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6748    pub order_by: Vec<Ordered>,
6749}
6750
6751/// NTH_VALUE function
6752#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6753#[cfg_attr(feature = "bindings", derive(TS))]
6754pub struct NthValueFunc {
6755    pub this: Expression,
6756    pub offset: Expression,
6757    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6758    #[serde(default, skip_serializing_if = "Option::is_none")]
6759    pub ignore_nulls: Option<bool>,
6760    /// Snowflake FROM FIRST / FROM LAST clause
6761    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
6762    #[serde(default, skip_serializing_if = "Option::is_none")]
6763    pub from_first: Option<bool>,
6764}
6765
6766/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6768#[cfg_attr(feature = "bindings", derive(TS))]
6769pub struct PercentRank {
6770    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
6771    #[serde(default, skip_serializing_if = "Option::is_none")]
6772    pub order_by: Option<Vec<Ordered>>,
6773    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6774    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6775    pub args: Vec<Expression>,
6776}
6777
6778/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6779#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6780#[cfg_attr(feature = "bindings", derive(TS))]
6781pub struct CumeDist {
6782    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
6783    #[serde(default, skip_serializing_if = "Option::is_none")]
6784    pub order_by: Option<Vec<Ordered>>,
6785    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6786    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6787    pub args: Vec<Expression>,
6788}
6789
6790// ============================================================================
6791// Additional String Function types
6792// ============================================================================
6793
6794/// POSITION/INSTR function
6795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6796#[cfg_attr(feature = "bindings", derive(TS))]
6797pub struct PositionFunc {
6798    pub substring: Expression,
6799    pub string: Expression,
6800    pub start: Option<Expression>,
6801}
6802
6803// ============================================================================
6804// Additional Math Function types
6805// ============================================================================
6806
6807/// RANDOM function (no arguments)
6808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6809#[cfg_attr(feature = "bindings", derive(TS))]
6810pub struct Random;
6811
6812/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
6813#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6814#[cfg_attr(feature = "bindings", derive(TS))]
6815pub struct Rand {
6816    pub seed: Option<Box<Expression>>,
6817    /// Teradata RANDOM lower bound
6818    #[serde(default)]
6819    pub lower: Option<Box<Expression>>,
6820    /// Teradata RANDOM upper bound
6821    #[serde(default)]
6822    pub upper: Option<Box<Expression>>,
6823}
6824
6825/// TRUNCATE / TRUNC function
6826#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6827#[cfg_attr(feature = "bindings", derive(TS))]
6828pub struct TruncateFunc {
6829    pub this: Expression,
6830    pub decimals: Option<Expression>,
6831}
6832
6833/// PI function (no arguments)
6834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6835#[cfg_attr(feature = "bindings", derive(TS))]
6836pub struct Pi;
6837
6838// ============================================================================
6839// Control Flow Function types
6840// ============================================================================
6841
6842/// DECODE function (Oracle style)
6843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6844#[cfg_attr(feature = "bindings", derive(TS))]
6845pub struct DecodeFunc {
6846    pub this: Expression,
6847    pub search_results: Vec<(Expression, Expression)>,
6848    pub default: Option<Expression>,
6849}
6850
6851// ============================================================================
6852// Additional Date/Time Function types
6853// ============================================================================
6854
6855/// DATE_FORMAT / FORMAT_DATE function
6856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6857#[cfg_attr(feature = "bindings", derive(TS))]
6858pub struct DateFormatFunc {
6859    pub this: Expression,
6860    pub format: Expression,
6861}
6862
6863/// FROM_UNIXTIME function
6864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6865#[cfg_attr(feature = "bindings", derive(TS))]
6866pub struct FromUnixtimeFunc {
6867    pub this: Expression,
6868    pub format: Option<Expression>,
6869}
6870
6871/// UNIX_TIMESTAMP function
6872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6873#[cfg_attr(feature = "bindings", derive(TS))]
6874pub struct UnixTimestampFunc {
6875    pub this: Option<Expression>,
6876    pub format: Option<Expression>,
6877}
6878
6879/// MAKE_DATE function
6880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6881#[cfg_attr(feature = "bindings", derive(TS))]
6882pub struct MakeDateFunc {
6883    pub year: Expression,
6884    pub month: Expression,
6885    pub day: Expression,
6886}
6887
6888/// MAKE_TIMESTAMP function
6889#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6890#[cfg_attr(feature = "bindings", derive(TS))]
6891pub struct MakeTimestampFunc {
6892    pub year: Expression,
6893    pub month: Expression,
6894    pub day: Expression,
6895    pub hour: Expression,
6896    pub minute: Expression,
6897    pub second: Expression,
6898    pub timezone: Option<Expression>,
6899}
6900
6901/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
6902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6903#[cfg_attr(feature = "bindings", derive(TS))]
6904pub struct LastDayFunc {
6905    pub this: Expression,
6906    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
6907    #[serde(skip_serializing_if = "Option::is_none", default)]
6908    pub unit: Option<DateTimeField>,
6909}
6910
6911// ============================================================================
6912// Array Function types
6913// ============================================================================
6914
6915/// ARRAY constructor
6916#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6917#[cfg_attr(feature = "bindings", derive(TS))]
6918pub struct ArrayConstructor {
6919    pub expressions: Vec<Expression>,
6920    pub bracket_notation: bool,
6921    /// True if LIST keyword was used instead of ARRAY (DuckDB)
6922    pub use_list_keyword: bool,
6923}
6924
6925/// ARRAY_SORT function
6926#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6927#[cfg_attr(feature = "bindings", derive(TS))]
6928pub struct ArraySortFunc {
6929    pub this: Expression,
6930    pub comparator: Option<Expression>,
6931    pub desc: bool,
6932    pub nulls_first: Option<bool>,
6933}
6934
6935/// ARRAY_JOIN / ARRAY_TO_STRING function
6936#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6937#[cfg_attr(feature = "bindings", derive(TS))]
6938pub struct ArrayJoinFunc {
6939    pub this: Expression,
6940    pub separator: Expression,
6941    pub null_replacement: Option<Expression>,
6942}
6943
6944/// UNNEST function
6945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6946#[cfg_attr(feature = "bindings", derive(TS))]
6947pub struct UnnestFunc {
6948    pub this: Expression,
6949    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
6950    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6951    pub expressions: Vec<Expression>,
6952    pub with_ordinality: bool,
6953    pub alias: Option<Identifier>,
6954    /// BigQuery: offset alias for WITH OFFSET AS <name>
6955    #[serde(default, skip_serializing_if = "Option::is_none")]
6956    pub offset_alias: Option<Identifier>,
6957}
6958
6959/// ARRAY_FILTER function (with lambda)
6960#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6961#[cfg_attr(feature = "bindings", derive(TS))]
6962pub struct ArrayFilterFunc {
6963    pub this: Expression,
6964    pub filter: Expression,
6965}
6966
6967/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
6968#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6969#[cfg_attr(feature = "bindings", derive(TS))]
6970pub struct ArrayTransformFunc {
6971    pub this: Expression,
6972    pub transform: Expression,
6973}
6974
6975/// SEQUENCE / GENERATE_SERIES function
6976#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6977#[cfg_attr(feature = "bindings", derive(TS))]
6978pub struct SequenceFunc {
6979    pub start: Expression,
6980    pub stop: Expression,
6981    pub step: Option<Expression>,
6982}
6983
6984// ============================================================================
6985// Struct Function types
6986// ============================================================================
6987
6988/// STRUCT constructor
6989#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6990#[cfg_attr(feature = "bindings", derive(TS))]
6991pub struct StructConstructor {
6992    pub fields: Vec<(Option<Identifier>, Expression)>,
6993}
6994
6995/// STRUCT_EXTRACT function
6996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6997#[cfg_attr(feature = "bindings", derive(TS))]
6998pub struct StructExtractFunc {
6999    pub this: Expression,
7000    pub field: Identifier,
7001}
7002
7003/// NAMED_STRUCT function
7004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7005#[cfg_attr(feature = "bindings", derive(TS))]
7006pub struct NamedStructFunc {
7007    pub pairs: Vec<(Expression, Expression)>,
7008}
7009
7010// ============================================================================
7011// Map Function types
7012// ============================================================================
7013
7014/// MAP constructor
7015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7016#[cfg_attr(feature = "bindings", derive(TS))]
7017pub struct MapConstructor {
7018    pub keys: Vec<Expression>,
7019    pub values: Vec<Expression>,
7020    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7021    #[serde(default)]
7022    pub curly_brace_syntax: bool,
7023    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7024    #[serde(default)]
7025    pub with_map_keyword: bool,
7026}
7027
7028/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7029#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7030#[cfg_attr(feature = "bindings", derive(TS))]
7031pub struct TransformFunc {
7032    pub this: Expression,
7033    pub transform: Expression,
7034}
7035
7036/// Function call with EMITS clause (Exasol)
7037/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7039#[cfg_attr(feature = "bindings", derive(TS))]
7040pub struct FunctionEmits {
7041    /// The function call expression
7042    pub this: Expression,
7043    /// The EMITS schema definition
7044    pub emits: Expression,
7045}
7046
7047// ============================================================================
7048// JSON Function types
7049// ============================================================================
7050
7051/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7053#[cfg_attr(feature = "bindings", derive(TS))]
7054pub struct JsonExtractFunc {
7055    pub this: Expression,
7056    pub path: Expression,
7057    pub returning: Option<DataType>,
7058    /// True if parsed from -> or ->> operator syntax
7059    #[serde(default)]
7060    pub arrow_syntax: bool,
7061    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7062    #[serde(default)]
7063    pub hash_arrow_syntax: bool,
7064    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7065    #[serde(default)]
7066    pub wrapper_option: Option<String>,
7067    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7068    #[serde(default)]
7069    pub quotes_option: Option<String>,
7070    /// ON SCALAR STRING flag
7071    #[serde(default)]
7072    pub on_scalar_string: bool,
7073    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7074    #[serde(default)]
7075    pub on_error: Option<String>,
7076}
7077
7078/// JSON path extraction
7079#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7080#[cfg_attr(feature = "bindings", derive(TS))]
7081pub struct JsonPathFunc {
7082    pub this: Expression,
7083    pub paths: Vec<Expression>,
7084}
7085
7086/// JSON_OBJECT function
7087#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7088#[cfg_attr(feature = "bindings", derive(TS))]
7089pub struct JsonObjectFunc {
7090    pub pairs: Vec<(Expression, Expression)>,
7091    pub null_handling: Option<JsonNullHandling>,
7092    #[serde(default)]
7093    pub with_unique_keys: bool,
7094    #[serde(default)]
7095    pub returning_type: Option<DataType>,
7096    #[serde(default)]
7097    pub format_json: bool,
7098    #[serde(default)]
7099    pub encoding: Option<String>,
7100    /// For JSON_OBJECT(*) syntax
7101    #[serde(default)]
7102    pub star: bool,
7103}
7104
7105/// JSON null handling options
7106#[derive(
7107    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7108)]
7109#[cfg_attr(feature = "bindings", derive(TS))]
7110pub enum JsonNullHandling {
7111    NullOnNull,
7112    AbsentOnNull,
7113}
7114
7115/// JSON_SET / JSON_INSERT function
7116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7117#[cfg_attr(feature = "bindings", derive(TS))]
7118pub struct JsonModifyFunc {
7119    pub this: Expression,
7120    pub path_values: Vec<(Expression, Expression)>,
7121}
7122
7123/// JSON_ARRAYAGG function
7124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7125#[cfg_attr(feature = "bindings", derive(TS))]
7126pub struct JsonArrayAggFunc {
7127    pub this: Expression,
7128    pub order_by: Option<Vec<Ordered>>,
7129    pub null_handling: Option<JsonNullHandling>,
7130    pub filter: Option<Expression>,
7131}
7132
7133/// JSON_OBJECTAGG function
7134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7135#[cfg_attr(feature = "bindings", derive(TS))]
7136pub struct JsonObjectAggFunc {
7137    pub key: Expression,
7138    pub value: Expression,
7139    pub null_handling: Option<JsonNullHandling>,
7140    pub filter: Option<Expression>,
7141}
7142
7143// ============================================================================
7144// Type Casting Function types
7145// ============================================================================
7146
7147/// CONVERT function (SQL Server style)
7148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7149#[cfg_attr(feature = "bindings", derive(TS))]
7150pub struct ConvertFunc {
7151    pub this: Expression,
7152    pub to: DataType,
7153    pub style: Option<Expression>,
7154}
7155
7156// ============================================================================
7157// Additional Expression types
7158// ============================================================================
7159
7160/// Lambda expression
7161#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7162#[cfg_attr(feature = "bindings", derive(TS))]
7163pub struct LambdaExpr {
7164    pub parameters: Vec<Identifier>,
7165    pub body: Expression,
7166    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7167    #[serde(default)]
7168    pub colon: bool,
7169    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7170    /// Maps parameter index to data type
7171    #[serde(default)]
7172    pub parameter_types: Vec<Option<DataType>>,
7173}
7174
7175/// Parameter (parameterized queries)
7176#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7177#[cfg_attr(feature = "bindings", derive(TS))]
7178pub struct Parameter {
7179    pub name: Option<String>,
7180    pub index: Option<u32>,
7181    pub style: ParameterStyle,
7182    /// Whether the name was quoted (e.g., @"x" vs @x)
7183    #[serde(default)]
7184    pub quoted: bool,
7185    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7186    #[serde(default)]
7187    pub string_quoted: bool,
7188    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7189    #[serde(default)]
7190    pub expression: Option<String>,
7191}
7192
7193/// Parameter placeholder styles
7194#[derive(
7195    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7196)]
7197#[cfg_attr(feature = "bindings", derive(TS))]
7198pub enum ParameterStyle {
7199    Question,     // ?
7200    Dollar,       // $1, $2
7201    DollarBrace,  // ${name} (Databricks, Hive template variables)
7202    Brace,        // {name} (Spark/Databricks widget/template variables)
7203    Colon,        // :name
7204    At,           // @name
7205    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7206    DoubleDollar, // $$name
7207    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7208}
7209
7210/// Placeholder expression
7211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7212#[cfg_attr(feature = "bindings", derive(TS))]
7213pub struct Placeholder {
7214    pub index: Option<u32>,
7215}
7216
7217/// Named argument in function call: name => value or name := value
7218#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7219#[cfg_attr(feature = "bindings", derive(TS))]
7220pub struct NamedArgument {
7221    pub name: Identifier,
7222    pub value: Expression,
7223    /// The separator used: `=>`, `:=`, or `=`
7224    pub separator: NamedArgSeparator,
7225}
7226
7227/// Separator style for named arguments
7228#[derive(
7229    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7230)]
7231#[cfg_attr(feature = "bindings", derive(TS))]
7232pub enum NamedArgSeparator {
7233    /// `=>` (standard SQL, Snowflake, BigQuery)
7234    DArrow,
7235    /// `:=` (Oracle, MySQL)
7236    ColonEq,
7237    /// `=` (simple equals, some dialects)
7238    Eq,
7239}
7240
7241/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7242/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7243#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7244#[cfg_attr(feature = "bindings", derive(TS))]
7245pub struct TableArgument {
7246    /// The keyword prefix: "TABLE" or "MODEL"
7247    pub prefix: String,
7248    /// The table/model reference expression
7249    pub this: Expression,
7250}
7251
7252/// SQL Comment preservation
7253#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7254#[cfg_attr(feature = "bindings", derive(TS))]
7255pub struct SqlComment {
7256    pub text: String,
7257    pub is_block: bool,
7258}
7259
7260// ============================================================================
7261// Additional Predicate types
7262// ============================================================================
7263
7264/// SIMILAR TO expression
7265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7266#[cfg_attr(feature = "bindings", derive(TS))]
7267pub struct SimilarToExpr {
7268    pub this: Expression,
7269    pub pattern: Expression,
7270    pub escape: Option<Expression>,
7271    pub not: bool,
7272}
7273
7274/// ANY / ALL quantified expression
7275#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7276#[cfg_attr(feature = "bindings", derive(TS))]
7277pub struct QuantifiedExpr {
7278    pub this: Expression,
7279    pub subquery: Expression,
7280    pub op: Option<QuantifiedOp>,
7281}
7282
7283/// Comparison operator for quantified expressions
7284#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7285#[cfg_attr(feature = "bindings", derive(TS))]
7286pub enum QuantifiedOp {
7287    Eq,
7288    Neq,
7289    Lt,
7290    Lte,
7291    Gt,
7292    Gte,
7293}
7294
7295/// OVERLAPS expression
7296/// Supports two forms:
7297/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7298/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7299#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7300#[cfg_attr(feature = "bindings", derive(TS))]
7301pub struct OverlapsExpr {
7302    /// Left operand for simple binary form
7303    #[serde(skip_serializing_if = "Option::is_none")]
7304    pub this: Option<Expression>,
7305    /// Right operand for simple binary form
7306    #[serde(skip_serializing_if = "Option::is_none")]
7307    pub expression: Option<Expression>,
7308    /// Left range start for full ANSI form
7309    #[serde(skip_serializing_if = "Option::is_none")]
7310    pub left_start: Option<Expression>,
7311    /// Left range end for full ANSI form
7312    #[serde(skip_serializing_if = "Option::is_none")]
7313    pub left_end: Option<Expression>,
7314    /// Right range start for full ANSI form
7315    #[serde(skip_serializing_if = "Option::is_none")]
7316    pub right_start: Option<Expression>,
7317    /// Right range end for full ANSI form
7318    #[serde(skip_serializing_if = "Option::is_none")]
7319    pub right_end: Option<Expression>,
7320}
7321
7322// ============================================================================
7323// Array/Struct/Map access
7324// ============================================================================
7325
7326/// Subscript access (array[index] or map[key])
7327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7328#[cfg_attr(feature = "bindings", derive(TS))]
7329pub struct Subscript {
7330    pub this: Expression,
7331    pub index: Expression,
7332}
7333
7334/// Dot access (struct.field)
7335#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7336#[cfg_attr(feature = "bindings", derive(TS))]
7337pub struct DotAccess {
7338    pub this: Expression,
7339    pub field: Identifier,
7340}
7341
7342/// Method call (expr.method(args))
7343#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7344#[cfg_attr(feature = "bindings", derive(TS))]
7345pub struct MethodCall {
7346    pub this: Expression,
7347    pub method: Identifier,
7348    pub args: Vec<Expression>,
7349}
7350
7351/// Array slice (array[start:end])
7352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7353#[cfg_attr(feature = "bindings", derive(TS))]
7354pub struct ArraySlice {
7355    pub this: Expression,
7356    pub start: Option<Expression>,
7357    pub end: Option<Expression>,
7358}
7359
7360// ============================================================================
7361// DDL (Data Definition Language) Statements
7362// ============================================================================
7363
7364/// ON COMMIT behavior for temporary tables
7365#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7366#[cfg_attr(feature = "bindings", derive(TS))]
7367pub enum OnCommit {
7368    /// ON COMMIT PRESERVE ROWS
7369    PreserveRows,
7370    /// ON COMMIT DELETE ROWS
7371    DeleteRows,
7372}
7373
7374/// CREATE TABLE statement
7375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7376#[cfg_attr(feature = "bindings", derive(TS))]
7377pub struct CreateTable {
7378    pub name: TableRef,
7379    /// ClickHouse: ON CLUSTER clause for distributed DDL
7380    #[serde(default, skip_serializing_if = "Option::is_none")]
7381    pub on_cluster: Option<OnCluster>,
7382    pub columns: Vec<ColumnDef>,
7383    pub constraints: Vec<TableConstraint>,
7384    pub if_not_exists: bool,
7385    pub temporary: bool,
7386    pub or_replace: bool,
7387    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
7388    #[serde(default, skip_serializing_if = "Option::is_none")]
7389    pub table_modifier: Option<String>,
7390    pub as_select: Option<Expression>,
7391    /// Whether the AS SELECT was wrapped in parentheses
7392    #[serde(default)]
7393    pub as_select_parenthesized: bool,
7394    /// ON COMMIT behavior for temporary tables
7395    #[serde(default)]
7396    pub on_commit: Option<OnCommit>,
7397    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
7398    #[serde(default)]
7399    pub clone_source: Option<TableRef>,
7400    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
7401    #[serde(default, skip_serializing_if = "Option::is_none")]
7402    pub clone_at_clause: Option<Expression>,
7403    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
7404    #[serde(default)]
7405    pub is_copy: bool,
7406    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
7407    #[serde(default)]
7408    pub shallow_clone: bool,
7409    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
7410    #[serde(default)]
7411    pub deep_clone: bool,
7412    /// Leading comments before the statement
7413    #[serde(default)]
7414    pub leading_comments: Vec<String>,
7415    /// WITH properties (e.g., WITH (FORMAT='parquet'))
7416    #[serde(default)]
7417    pub with_properties: Vec<(String, String)>,
7418    /// Teradata: table options after name before columns (comma-separated)
7419    #[serde(default)]
7420    pub teradata_post_name_options: Vec<String>,
7421    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
7422    #[serde(default)]
7423    pub with_data: Option<bool>,
7424    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
7425    #[serde(default)]
7426    pub with_statistics: Option<bool>,
7427    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
7428    #[serde(default)]
7429    pub teradata_indexes: Vec<TeradataIndex>,
7430    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
7431    #[serde(default)]
7432    pub with_cte: Option<With>,
7433    /// Table properties like DEFAULT COLLATE (BigQuery)
7434    #[serde(default)]
7435    pub properties: Vec<Expression>,
7436    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
7437    #[serde(default, skip_serializing_if = "Option::is_none")]
7438    pub partition_of: Option<Expression>,
7439    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
7440    #[serde(default)]
7441    pub post_table_properties: Vec<Expression>,
7442    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
7443    #[serde(default)]
7444    pub mysql_table_options: Vec<(String, String)>,
7445    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
7446    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7447    pub inherits: Vec<TableRef>,
7448    /// TSQL ON filegroup or ON filegroup (partition_column) clause
7449    #[serde(default, skip_serializing_if = "Option::is_none")]
7450    pub on_property: Option<OnProperty>,
7451    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
7452    #[serde(default)]
7453    pub copy_grants: bool,
7454    /// Snowflake: USING TEMPLATE expression for schema inference
7455    #[serde(default, skip_serializing_if = "Option::is_none")]
7456    pub using_template: Option<Box<Expression>>,
7457    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
7458    #[serde(default, skip_serializing_if = "Option::is_none")]
7459    pub rollup: Option<RollupProperty>,
7460    /// ClickHouse: UUID 'xxx' clause after table name
7461    #[serde(default, skip_serializing_if = "Option::is_none")]
7462    pub uuid: Option<String>,
7463    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
7464    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
7465    /// could appear in other engines.
7466    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7467    pub with_partition_columns: Vec<ColumnDef>,
7468    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
7469    /// for external tables that reference a Cloud Resource connection.
7470    #[serde(default, skip_serializing_if = "Option::is_none")]
7471    pub with_connection: Option<TableRef>,
7472}
7473
7474/// Teradata index specification for CREATE TABLE
7475#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7476#[cfg_attr(feature = "bindings", derive(TS))]
7477pub struct TeradataIndex {
7478    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
7479    pub kind: TeradataIndexKind,
7480    /// Optional index name
7481    pub name: Option<String>,
7482    /// Optional column list
7483    pub columns: Vec<String>,
7484}
7485
7486/// Kind of Teradata index
7487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7488#[cfg_attr(feature = "bindings", derive(TS))]
7489pub enum TeradataIndexKind {
7490    /// NO PRIMARY INDEX
7491    NoPrimary,
7492    /// PRIMARY INDEX
7493    Primary,
7494    /// PRIMARY AMP INDEX
7495    PrimaryAmp,
7496    /// UNIQUE INDEX
7497    Unique,
7498    /// UNIQUE PRIMARY INDEX
7499    UniquePrimary,
7500    /// INDEX (secondary, non-primary)
7501    Secondary,
7502}
7503
7504impl CreateTable {
7505    pub fn new(name: impl Into<String>) -> Self {
7506        Self {
7507            name: TableRef::new(name),
7508            on_cluster: None,
7509            columns: Vec::new(),
7510            constraints: Vec::new(),
7511            if_not_exists: false,
7512            temporary: false,
7513            or_replace: false,
7514            table_modifier: None,
7515            as_select: None,
7516            as_select_parenthesized: false,
7517            on_commit: None,
7518            clone_source: None,
7519            clone_at_clause: None,
7520            shallow_clone: false,
7521            deep_clone: false,
7522            is_copy: false,
7523            leading_comments: Vec::new(),
7524            with_properties: Vec::new(),
7525            teradata_post_name_options: Vec::new(),
7526            with_data: None,
7527            with_statistics: None,
7528            teradata_indexes: Vec::new(),
7529            with_cte: None,
7530            properties: Vec::new(),
7531            partition_of: None,
7532            post_table_properties: Vec::new(),
7533            mysql_table_options: Vec::new(),
7534            inherits: Vec::new(),
7535            on_property: None,
7536            copy_grants: false,
7537            using_template: None,
7538            rollup: None,
7539            uuid: None,
7540            with_partition_columns: Vec::new(),
7541            with_connection: None,
7542        }
7543    }
7544}
7545
7546/// Sort order for PRIMARY KEY ASC/DESC
7547#[derive(
7548    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
7549)]
7550#[cfg_attr(feature = "bindings", derive(TS))]
7551pub enum SortOrder {
7552    Asc,
7553    Desc,
7554}
7555
7556/// Type of column constraint for tracking order
7557#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7558#[cfg_attr(feature = "bindings", derive(TS))]
7559pub enum ConstraintType {
7560    NotNull,
7561    Null,
7562    PrimaryKey,
7563    Unique,
7564    Default,
7565    AutoIncrement,
7566    Collate,
7567    Comment,
7568    References,
7569    Check,
7570    GeneratedAsIdentity,
7571    /// Snowflake: TAG (key='value', ...)
7572    Tags,
7573    /// Computed/generated column
7574    ComputedColumn,
7575    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
7576    GeneratedAsRow,
7577    /// MySQL: ON UPDATE expression
7578    OnUpdate,
7579    /// PATH constraint for XMLTABLE/JSON_TABLE columns
7580    Path,
7581    /// Redshift: ENCODE encoding_type
7582    Encode,
7583}
7584
7585/// Column definition in CREATE TABLE
7586#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7587#[cfg_attr(feature = "bindings", derive(TS))]
7588pub struct ColumnDef {
7589    pub name: Identifier,
7590    pub data_type: DataType,
7591    pub nullable: Option<bool>,
7592    pub default: Option<Expression>,
7593    pub primary_key: bool,
7594    /// Sort order for PRIMARY KEY (ASC/DESC)
7595    #[serde(default)]
7596    pub primary_key_order: Option<SortOrder>,
7597    pub unique: bool,
7598    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
7599    #[serde(default)]
7600    pub unique_nulls_not_distinct: bool,
7601    pub auto_increment: bool,
7602    pub comment: Option<String>,
7603    pub constraints: Vec<ColumnConstraint>,
7604    /// Track original order of constraints for accurate regeneration
7605    #[serde(default)]
7606    pub constraint_order: Vec<ConstraintType>,
7607    /// Teradata: FORMAT 'pattern'
7608    #[serde(default)]
7609    pub format: Option<String>,
7610    /// Teradata: TITLE 'title'
7611    #[serde(default)]
7612    pub title: Option<String>,
7613    /// Teradata: INLINE LENGTH n
7614    #[serde(default)]
7615    pub inline_length: Option<u64>,
7616    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
7617    #[serde(default)]
7618    pub compress: Option<Vec<Expression>>,
7619    /// Teradata: CHARACTER SET name
7620    #[serde(default)]
7621    pub character_set: Option<String>,
7622    /// Teradata: UPPERCASE
7623    #[serde(default)]
7624    pub uppercase: bool,
7625    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
7626    #[serde(default)]
7627    pub casespecific: Option<bool>,
7628    /// Snowflake: AUTOINCREMENT START value
7629    #[serde(default)]
7630    pub auto_increment_start: Option<Box<Expression>>,
7631    /// Snowflake: AUTOINCREMENT INCREMENT value
7632    #[serde(default)]
7633    pub auto_increment_increment: Option<Box<Expression>>,
7634    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
7635    #[serde(default)]
7636    pub auto_increment_order: Option<bool>,
7637    /// MySQL: UNSIGNED modifier
7638    #[serde(default)]
7639    pub unsigned: bool,
7640    /// MySQL: ZEROFILL modifier
7641    #[serde(default)]
7642    pub zerofill: bool,
7643    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
7644    #[serde(default, skip_serializing_if = "Option::is_none")]
7645    pub on_update: Option<Expression>,
7646    /// MySQL: column VISIBLE/INVISIBLE modifier.
7647    #[serde(default, skip_serializing_if = "Option::is_none")]
7648    pub visible: Option<bool>,
7649    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
7650    #[serde(default, skip_serializing_if = "Option::is_none")]
7651    pub unique_constraint_name: Option<String>,
7652    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
7653    #[serde(default, skip_serializing_if = "Option::is_none")]
7654    pub not_null_constraint_name: Option<String>,
7655    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
7656    #[serde(default, skip_serializing_if = "Option::is_none")]
7657    pub primary_key_constraint_name: Option<String>,
7658    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
7659    #[serde(default, skip_serializing_if = "Option::is_none")]
7660    pub check_constraint_name: Option<String>,
7661    /// BigQuery: OPTIONS (key=value, ...) on column
7662    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7663    pub options: Vec<Expression>,
7664    /// SQLite: Column definition without explicit type
7665    #[serde(default)]
7666    pub no_type: bool,
7667    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
7668    #[serde(default, skip_serializing_if = "Option::is_none")]
7669    pub encoding: Option<String>,
7670    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
7671    #[serde(default, skip_serializing_if = "Option::is_none")]
7672    pub codec: Option<String>,
7673    /// ClickHouse: EPHEMERAL [expr] modifier
7674    #[serde(default, skip_serializing_if = "Option::is_none")]
7675    pub ephemeral: Option<Option<Box<Expression>>>,
7676    /// ClickHouse: MATERIALIZED expr modifier
7677    #[serde(default, skip_serializing_if = "Option::is_none")]
7678    pub materialized_expr: Option<Box<Expression>>,
7679    /// ClickHouse: ALIAS expr modifier
7680    #[serde(default, skip_serializing_if = "Option::is_none")]
7681    pub alias_expr: Option<Box<Expression>>,
7682    /// ClickHouse: TTL expr modifier on columns
7683    #[serde(default, skip_serializing_if = "Option::is_none")]
7684    pub ttl_expr: Option<Box<Expression>>,
7685    /// TSQL: NOT FOR REPLICATION
7686    #[serde(default)]
7687    pub not_for_replication: bool,
7688}
7689
7690impl ColumnDef {
7691    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
7692        Self {
7693            name: Identifier::new(name),
7694            data_type,
7695            nullable: None,
7696            default: None,
7697            primary_key: false,
7698            primary_key_order: None,
7699            unique: false,
7700            unique_nulls_not_distinct: false,
7701            auto_increment: false,
7702            comment: None,
7703            constraints: Vec::new(),
7704            constraint_order: Vec::new(),
7705            format: None,
7706            title: None,
7707            inline_length: None,
7708            compress: None,
7709            character_set: None,
7710            uppercase: false,
7711            casespecific: None,
7712            auto_increment_start: None,
7713            auto_increment_increment: None,
7714            auto_increment_order: None,
7715            unsigned: false,
7716            zerofill: false,
7717            on_update: None,
7718            visible: None,
7719            unique_constraint_name: None,
7720            not_null_constraint_name: None,
7721            primary_key_constraint_name: None,
7722            check_constraint_name: None,
7723            options: Vec::new(),
7724            no_type: false,
7725            encoding: None,
7726            codec: None,
7727            ephemeral: None,
7728            materialized_expr: None,
7729            alias_expr: None,
7730            ttl_expr: None,
7731            not_for_replication: false,
7732        }
7733    }
7734}
7735
7736/// Column-level constraint
7737#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7738#[cfg_attr(feature = "bindings", derive(TS))]
7739pub enum ColumnConstraint {
7740    NotNull,
7741    Null,
7742    Unique,
7743    PrimaryKey,
7744    Default(Expression),
7745    Check(Expression),
7746    References(ForeignKeyRef),
7747    GeneratedAsIdentity(GeneratedAsIdentity),
7748    Collate(Identifier),
7749    Comment(String),
7750    /// Snowflake: TAG (key='value', ...)
7751    Tags(Tags),
7752    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
7753    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
7754    ComputedColumn(ComputedColumn),
7755    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7756    GeneratedAsRow(GeneratedAsRow),
7757    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
7758    Path(Expression),
7759}
7760
7761/// Computed/generated column constraint
7762#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7763#[cfg_attr(feature = "bindings", derive(TS))]
7764pub struct ComputedColumn {
7765    /// The expression that computes the column value
7766    pub expression: Box<Expression>,
7767    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
7768    #[serde(default)]
7769    pub persisted: bool,
7770    /// NOT NULL (TSQL computed columns)
7771    #[serde(default)]
7772    pub not_null: bool,
7773    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
7774    /// When None, defaults to dialect-appropriate output
7775    #[serde(default)]
7776    pub persistence_kind: Option<String>,
7777    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
7778    #[serde(default, skip_serializing_if = "Option::is_none")]
7779    pub data_type: Option<DataType>,
7780}
7781
7782/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7784#[cfg_attr(feature = "bindings", derive(TS))]
7785pub struct GeneratedAsRow {
7786    /// true = ROW START, false = ROW END
7787    pub start: bool,
7788    /// HIDDEN modifier
7789    #[serde(default)]
7790    pub hidden: bool,
7791}
7792
7793/// Generated identity column constraint
7794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7795#[cfg_attr(feature = "bindings", derive(TS))]
7796pub struct GeneratedAsIdentity {
7797    /// True for ALWAYS, False for BY DEFAULT
7798    pub always: bool,
7799    /// ON NULL (only valid with BY DEFAULT)
7800    pub on_null: bool,
7801    /// START WITH value
7802    pub start: Option<Box<Expression>>,
7803    /// INCREMENT BY value
7804    pub increment: Option<Box<Expression>>,
7805    /// MINVALUE
7806    pub minvalue: Option<Box<Expression>>,
7807    /// MAXVALUE
7808    pub maxvalue: Option<Box<Expression>>,
7809    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
7810    pub cycle: Option<bool>,
7811}
7812
7813/// Constraint modifiers (shared between table-level constraints)
7814#[derive(
7815    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
7816)]
7817#[cfg_attr(feature = "bindings", derive(TS))]
7818pub struct ConstraintModifiers {
7819    /// ENFORCED / NOT ENFORCED
7820    pub enforced: Option<bool>,
7821    /// DEFERRABLE / NOT DEFERRABLE
7822    pub deferrable: Option<bool>,
7823    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
7824    pub initially_deferred: Option<bool>,
7825    /// NORELY (Oracle)
7826    pub norely: bool,
7827    /// RELY (Oracle)
7828    pub rely: bool,
7829    /// USING index type (MySQL): BTREE or HASH
7830    #[serde(default)]
7831    pub using: Option<String>,
7832    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
7833    #[serde(default)]
7834    pub using_before_columns: bool,
7835    /// MySQL index COMMENT 'text'
7836    #[serde(default, skip_serializing_if = "Option::is_none")]
7837    pub comment: Option<String>,
7838    /// MySQL index VISIBLE/INVISIBLE
7839    #[serde(default, skip_serializing_if = "Option::is_none")]
7840    pub visible: Option<bool>,
7841    /// MySQL ENGINE_ATTRIBUTE = 'value'
7842    #[serde(default, skip_serializing_if = "Option::is_none")]
7843    pub engine_attribute: Option<String>,
7844    /// MySQL WITH PARSER name
7845    #[serde(default, skip_serializing_if = "Option::is_none")]
7846    pub with_parser: Option<String>,
7847    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
7848    #[serde(default)]
7849    pub not_valid: bool,
7850    /// TSQL CLUSTERED/NONCLUSTERED modifier
7851    #[serde(default, skip_serializing_if = "Option::is_none")]
7852    pub clustered: Option<String>,
7853    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
7854    #[serde(default, skip_serializing_if = "Option::is_none")]
7855    pub on_conflict: Option<String>,
7856    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
7857    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7858    pub with_options: Vec<(String, String)>,
7859    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
7860    #[serde(default, skip_serializing_if = "Option::is_none")]
7861    pub on_filegroup: Option<Identifier>,
7862}
7863
7864/// Table-level constraint
7865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7866#[cfg_attr(feature = "bindings", derive(TS))]
7867pub enum TableConstraint {
7868    PrimaryKey {
7869        name: Option<Identifier>,
7870        columns: Vec<Identifier>,
7871        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
7872        #[serde(default)]
7873        include_columns: Vec<Identifier>,
7874        #[serde(default)]
7875        modifiers: ConstraintModifiers,
7876        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
7877        #[serde(default)]
7878        has_constraint_keyword: bool,
7879    },
7880    Unique {
7881        name: Option<Identifier>,
7882        columns: Vec<Identifier>,
7883        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
7884        #[serde(default)]
7885        columns_parenthesized: bool,
7886        #[serde(default)]
7887        modifiers: ConstraintModifiers,
7888        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
7889        #[serde(default)]
7890        has_constraint_keyword: bool,
7891        /// PostgreSQL 15+: NULLS NOT DISTINCT
7892        #[serde(default)]
7893        nulls_not_distinct: bool,
7894    },
7895    ForeignKey {
7896        name: Option<Identifier>,
7897        columns: Vec<Identifier>,
7898        #[serde(default)]
7899        references: Option<ForeignKeyRef>,
7900        /// ON DELETE action when REFERENCES is absent
7901        #[serde(default)]
7902        on_delete: Option<ReferentialAction>,
7903        /// ON UPDATE action when REFERENCES is absent
7904        #[serde(default)]
7905        on_update: Option<ReferentialAction>,
7906        #[serde(default)]
7907        modifiers: ConstraintModifiers,
7908    },
7909    Check {
7910        name: Option<Identifier>,
7911        expression: Expression,
7912        #[serde(default)]
7913        modifiers: ConstraintModifiers,
7914    },
7915    /// ClickHouse ASSUME constraint (query optimization assumption)
7916    Assume {
7917        name: Option<Identifier>,
7918        expression: Expression,
7919    },
7920    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
7921    Default {
7922        name: Option<Identifier>,
7923        expression: Expression,
7924        column: Identifier,
7925    },
7926    /// INDEX / KEY constraint (MySQL)
7927    Index {
7928        name: Option<Identifier>,
7929        columns: Vec<Identifier>,
7930        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
7931        #[serde(default)]
7932        kind: Option<String>,
7933        #[serde(default)]
7934        modifiers: ConstraintModifiers,
7935        /// True if KEY keyword was used instead of INDEX
7936        #[serde(default)]
7937        use_key_keyword: bool,
7938        /// ClickHouse: indexed expression (instead of columns)
7939        #[serde(default, skip_serializing_if = "Option::is_none")]
7940        expression: Option<Box<Expression>>,
7941        /// ClickHouse: TYPE type_func(args)
7942        #[serde(default, skip_serializing_if = "Option::is_none")]
7943        index_type: Option<Box<Expression>>,
7944        /// ClickHouse: GRANULARITY n
7945        #[serde(default, skip_serializing_if = "Option::is_none")]
7946        granularity: Option<Box<Expression>>,
7947    },
7948    /// ClickHouse PROJECTION definition
7949    Projection {
7950        name: Identifier,
7951        expression: Expression,
7952    },
7953    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
7954    Like {
7955        source: TableRef,
7956        /// Options as (INCLUDING|EXCLUDING, property) pairs
7957        options: Vec<(LikeOptionAction, String)>,
7958    },
7959    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
7960    PeriodForSystemTime {
7961        start_col: Identifier,
7962        end_col: Identifier,
7963    },
7964    /// PostgreSQL EXCLUDE constraint
7965    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
7966    Exclude {
7967        name: Option<Identifier>,
7968        /// Index access method (gist, btree, etc.)
7969        #[serde(default)]
7970        using: Option<String>,
7971        /// Elements: (expression, operator) pairs
7972        elements: Vec<ExcludeElement>,
7973        /// INCLUDE columns
7974        #[serde(default)]
7975        include_columns: Vec<Identifier>,
7976        /// WHERE predicate
7977        #[serde(default)]
7978        where_clause: Option<Box<Expression>>,
7979        /// WITH (storage_parameters)
7980        #[serde(default)]
7981        with_params: Vec<(String, String)>,
7982        /// USING INDEX TABLESPACE tablespace_name
7983        #[serde(default)]
7984        using_index_tablespace: Option<String>,
7985        #[serde(default)]
7986        modifiers: ConstraintModifiers,
7987    },
7988    /// Snowflake TAG clause: TAG (key='value', key2='value2')
7989    Tags(Tags),
7990    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
7991    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
7992    /// for all deferrable constraints in the table
7993    InitiallyDeferred {
7994        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
7995        deferred: bool,
7996    },
7997}
7998
7999/// Element in an EXCLUDE constraint: expression WITH operator
8000#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8001#[cfg_attr(feature = "bindings", derive(TS))]
8002pub struct ExcludeElement {
8003    /// The column expression (may include operator class, ordering, nulls)
8004    pub expression: String,
8005    /// The operator (e.g., &&, =)
8006    pub operator: String,
8007}
8008
8009/// Action for LIKE clause options
8010#[derive(
8011    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8012)]
8013#[cfg_attr(feature = "bindings", derive(TS))]
8014pub enum LikeOptionAction {
8015    Including,
8016    Excluding,
8017}
8018
8019/// MATCH type for foreign keys
8020#[derive(
8021    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8022)]
8023#[cfg_attr(feature = "bindings", derive(TS))]
8024pub enum MatchType {
8025    Full,
8026    Partial,
8027    Simple,
8028}
8029
8030/// Foreign key reference
8031#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8032#[cfg_attr(feature = "bindings", derive(TS))]
8033pub struct ForeignKeyRef {
8034    pub table: TableRef,
8035    pub columns: Vec<Identifier>,
8036    pub on_delete: Option<ReferentialAction>,
8037    pub on_update: Option<ReferentialAction>,
8038    /// True if ON UPDATE appears before ON DELETE in the original SQL
8039    #[serde(default)]
8040    pub on_update_first: bool,
8041    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8042    #[serde(default)]
8043    pub match_type: Option<MatchType>,
8044    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8045    #[serde(default)]
8046    pub match_after_actions: bool,
8047    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8048    #[serde(default)]
8049    pub constraint_name: Option<String>,
8050    /// DEFERRABLE / NOT DEFERRABLE
8051    #[serde(default)]
8052    pub deferrable: Option<bool>,
8053    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8054    #[serde(default)]
8055    pub has_foreign_key_keywords: bool,
8056}
8057
8058/// Referential action for foreign keys
8059#[derive(
8060    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8061)]
8062#[cfg_attr(feature = "bindings", derive(TS))]
8063pub enum ReferentialAction {
8064    Cascade,
8065    SetNull,
8066    SetDefault,
8067    Restrict,
8068    NoAction,
8069}
8070
8071/// DROP TABLE statement
8072#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8073#[cfg_attr(feature = "bindings", derive(TS))]
8074pub struct DropTable {
8075    pub names: Vec<TableRef>,
8076    pub if_exists: bool,
8077    pub cascade: bool,
8078    /// Oracle: CASCADE CONSTRAINTS
8079    #[serde(default)]
8080    pub cascade_constraints: bool,
8081    /// Oracle: PURGE
8082    #[serde(default)]
8083    pub purge: bool,
8084    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8085    #[serde(default)]
8086    pub leading_comments: Vec<String>,
8087    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8088    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8089    #[serde(default, skip_serializing_if = "Option::is_none")]
8090    pub object_id_args: Option<String>,
8091    /// ClickHouse: SYNC modifier
8092    #[serde(default)]
8093    pub sync: bool,
8094    /// Snowflake: DROP ICEBERG TABLE
8095    #[serde(default)]
8096    pub iceberg: bool,
8097    /// RESTRICT modifier (opposite of CASCADE)
8098    #[serde(default)]
8099    pub restrict: bool,
8100}
8101
8102impl DropTable {
8103    pub fn new(name: impl Into<String>) -> Self {
8104        Self {
8105            names: vec![TableRef::new(name)],
8106            if_exists: false,
8107            cascade: false,
8108            cascade_constraints: false,
8109            purge: false,
8110            leading_comments: Vec::new(),
8111            object_id_args: None,
8112            sync: false,
8113            iceberg: false,
8114            restrict: false,
8115        }
8116    }
8117}
8118
8119/// UNDROP object statement (Snowflake, ClickHouse)
8120#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8121#[cfg_attr(feature = "bindings", derive(TS))]
8122pub struct Undrop {
8123    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8124    pub kind: String,
8125    /// The object name
8126    pub name: TableRef,
8127    /// IF EXISTS clause
8128    #[serde(default)]
8129    pub if_exists: bool,
8130    /// Snowflake: optional RENAME TO target
8131    #[serde(default, skip_serializing_if = "Option::is_none")]
8132    pub rename_to: Option<TableRef>,
8133}
8134
8135/// ALTER TABLE statement
8136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8137#[cfg_attr(feature = "bindings", derive(TS))]
8138pub struct AlterTable {
8139    pub name: TableRef,
8140    pub actions: Vec<AlterTableAction>,
8141    /// IF EXISTS clause
8142    #[serde(default)]
8143    pub if_exists: bool,
8144    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8145    #[serde(default, skip_serializing_if = "Option::is_none")]
8146    pub algorithm: Option<String>,
8147    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8148    #[serde(default, skip_serializing_if = "Option::is_none")]
8149    pub lock: Option<String>,
8150    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8151    #[serde(default, skip_serializing_if = "Option::is_none")]
8152    pub with_check: Option<String>,
8153    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8154    #[serde(default, skip_serializing_if = "Option::is_none")]
8155    pub partition: Option<Vec<(Identifier, Expression)>>,
8156    /// ClickHouse: ON CLUSTER clause for distributed DDL
8157    #[serde(default, skip_serializing_if = "Option::is_none")]
8158    pub on_cluster: Option<OnCluster>,
8159    /// Snowflake: ALTER ICEBERG TABLE
8160    #[serde(default, skip_serializing_if = "Option::is_none")]
8161    pub table_modifier: Option<String>,
8162}
8163
8164impl AlterTable {
8165    pub fn new(name: impl Into<String>) -> Self {
8166        Self {
8167            name: TableRef::new(name),
8168            actions: Vec::new(),
8169            if_exists: false,
8170            algorithm: None,
8171            lock: None,
8172            with_check: None,
8173            partition: None,
8174            on_cluster: None,
8175            table_modifier: None,
8176        }
8177    }
8178}
8179
8180/// Column position for ADD COLUMN (MySQL/MariaDB)
8181#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8182#[cfg_attr(feature = "bindings", derive(TS))]
8183pub enum ColumnPosition {
8184    First,
8185    After(Identifier),
8186}
8187
8188/// Actions for ALTER TABLE
8189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8190#[cfg_attr(feature = "bindings", derive(TS))]
8191pub enum AlterTableAction {
8192    AddColumn {
8193        column: ColumnDef,
8194        if_not_exists: bool,
8195        position: Option<ColumnPosition>,
8196    },
8197    DropColumn {
8198        name: Identifier,
8199        if_exists: bool,
8200        cascade: bool,
8201    },
8202    RenameColumn {
8203        old_name: Identifier,
8204        new_name: Identifier,
8205        if_exists: bool,
8206    },
8207    AlterColumn {
8208        name: Identifier,
8209        action: AlterColumnAction,
8210        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8211        #[serde(default)]
8212        use_modify_keyword: bool,
8213    },
8214    RenameTable(TableRef),
8215    AddConstraint(TableConstraint),
8216    DropConstraint {
8217        name: Identifier,
8218        if_exists: bool,
8219    },
8220    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8221    DropForeignKey {
8222        name: Identifier,
8223    },
8224    /// DROP PARTITION action (Hive/BigQuery)
8225    DropPartition {
8226        /// List of partitions to drop (each partition is a list of key=value pairs)
8227        partitions: Vec<Vec<(Identifier, Expression)>>,
8228        if_exists: bool,
8229    },
8230    /// ADD PARTITION action (Hive/Spark)
8231    AddPartition {
8232        /// The partition expression
8233        partition: Expression,
8234        if_not_exists: bool,
8235        location: Option<Expression>,
8236    },
8237    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8238    Delete {
8239        where_clause: Expression,
8240    },
8241    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8242    SwapWith(TableRef),
8243    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8244    SetProperty {
8245        properties: Vec<(String, Expression)>,
8246    },
8247    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8248    UnsetProperty {
8249        properties: Vec<String>,
8250    },
8251    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8252    ClusterBy {
8253        expressions: Vec<Expression>,
8254    },
8255    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8256    SetTag {
8257        expressions: Vec<(String, Expression)>,
8258    },
8259    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8260    UnsetTag {
8261        names: Vec<String>,
8262    },
8263    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8264    SetOptions {
8265        expressions: Vec<Expression>,
8266    },
8267    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8268    AlterIndex {
8269        name: Identifier,
8270        visible: bool,
8271    },
8272    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8273    SetAttribute {
8274        attribute: String,
8275    },
8276    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8277    SetStageFileFormat {
8278        options: Option<Expression>,
8279    },
8280    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8281    SetStageCopyOptions {
8282        options: Option<Expression>,
8283    },
8284    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8285    AddColumns {
8286        columns: Vec<ColumnDef>,
8287        cascade: bool,
8288    },
8289    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8290    DropColumns {
8291        names: Vec<Identifier>,
8292    },
8293    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8294    /// In SingleStore, data_type can be omitted for simple column renames
8295    ChangeColumn {
8296        old_name: Identifier,
8297        new_name: Identifier,
8298        #[serde(default, skip_serializing_if = "Option::is_none")]
8299        data_type: Option<DataType>,
8300        comment: Option<String>,
8301        #[serde(default)]
8302        cascade: bool,
8303    },
8304    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
8305    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
8306    AlterSortKey {
8307        /// AUTO or NONE keyword
8308        this: Option<String>,
8309        /// Column list for (col1, col2) syntax
8310        expressions: Vec<Expression>,
8311        /// Whether COMPOUND keyword was present
8312        compound: bool,
8313    },
8314    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
8315    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
8316    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
8317    AlterDistStyle {
8318        /// Distribution style: ALL, EVEN, AUTO, or KEY
8319        style: String,
8320        /// DISTKEY column (only when style is KEY)
8321        distkey: Option<Identifier>,
8322    },
8323    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
8324    SetTableProperties {
8325        properties: Vec<(Expression, Expression)>,
8326    },
8327    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
8328    SetLocation {
8329        location: String,
8330    },
8331    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
8332    SetFileFormat {
8333        format: String,
8334    },
8335    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
8336    ReplacePartition {
8337        partition: Expression,
8338        source: Option<Box<Expression>>,
8339    },
8340    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
8341    Raw {
8342        sql: String,
8343    },
8344}
8345
8346/// Actions for ALTER COLUMN
8347#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8348#[cfg_attr(feature = "bindings", derive(TS))]
8349pub enum AlterColumnAction {
8350    SetDataType {
8351        data_type: DataType,
8352        /// USING expression for type conversion (PostgreSQL)
8353        using: Option<Expression>,
8354        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
8355        #[serde(default, skip_serializing_if = "Option::is_none")]
8356        collate: Option<String>,
8357    },
8358    SetDefault(Expression),
8359    DropDefault,
8360    SetNotNull,
8361    DropNotNull,
8362    /// Set column comment
8363    Comment(String),
8364    /// MySQL: SET VISIBLE
8365    SetVisible,
8366    /// MySQL: SET INVISIBLE
8367    SetInvisible,
8368}
8369
8370/// CREATE INDEX statement
8371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8372#[cfg_attr(feature = "bindings", derive(TS))]
8373pub struct CreateIndex {
8374    pub name: Identifier,
8375    pub table: TableRef,
8376    pub columns: Vec<IndexColumn>,
8377    pub unique: bool,
8378    pub if_not_exists: bool,
8379    pub using: Option<String>,
8380    /// TSQL CLUSTERED/NONCLUSTERED modifier
8381    #[serde(default)]
8382    pub clustered: Option<String>,
8383    /// PostgreSQL CONCURRENTLY modifier
8384    #[serde(default)]
8385    pub concurrently: bool,
8386    /// PostgreSQL WHERE clause for partial indexes
8387    #[serde(default)]
8388    pub where_clause: Option<Box<Expression>>,
8389    /// PostgreSQL INCLUDE columns
8390    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8391    pub include_columns: Vec<Identifier>,
8392    /// TSQL WITH options (e.g., allow_page_locks=on)
8393    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8394    pub with_options: Vec<(String, String)>,
8395    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
8396    #[serde(default)]
8397    pub on_filegroup: Option<String>,
8398}
8399
8400impl CreateIndex {
8401    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
8402        Self {
8403            name: Identifier::new(name),
8404            table: TableRef::new(table),
8405            columns: Vec::new(),
8406            unique: false,
8407            if_not_exists: false,
8408            using: None,
8409            clustered: None,
8410            concurrently: false,
8411            where_clause: None,
8412            include_columns: Vec::new(),
8413            with_options: Vec::new(),
8414            on_filegroup: None,
8415        }
8416    }
8417}
8418
8419/// Index column specification
8420#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8421#[cfg_attr(feature = "bindings", derive(TS))]
8422pub struct IndexColumn {
8423    pub column: Identifier,
8424    pub desc: bool,
8425    /// Explicit ASC keyword was present
8426    #[serde(default)]
8427    pub asc: bool,
8428    pub nulls_first: Option<bool>,
8429    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
8430    #[serde(default, skip_serializing_if = "Option::is_none")]
8431    pub opclass: Option<String>,
8432}
8433
8434/// DROP INDEX statement
8435#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8436#[cfg_attr(feature = "bindings", derive(TS))]
8437pub struct DropIndex {
8438    pub name: TableRef,
8439    pub table: Option<TableRef>,
8440    pub if_exists: bool,
8441    /// PostgreSQL CONCURRENTLY modifier
8442    #[serde(default)]
8443    pub concurrently: bool,
8444}
8445
8446impl DropIndex {
8447    pub fn new(name: impl Into<String>) -> Self {
8448        Self {
8449            name: TableRef::new(name),
8450            table: None,
8451            if_exists: false,
8452            concurrently: false,
8453        }
8454    }
8455}
8456
8457/// View column definition with optional COMMENT and OPTIONS (BigQuery)
8458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8459#[cfg_attr(feature = "bindings", derive(TS))]
8460pub struct ViewColumn {
8461    pub name: Identifier,
8462    pub comment: Option<String>,
8463    /// BigQuery: OPTIONS (key=value, ...) on column
8464    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8465    pub options: Vec<Expression>,
8466}
8467
8468impl ViewColumn {
8469    pub fn new(name: impl Into<String>) -> Self {
8470        Self {
8471            name: Identifier::new(name),
8472            comment: None,
8473            options: Vec::new(),
8474        }
8475    }
8476
8477    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
8478        Self {
8479            name: Identifier::new(name),
8480            comment: Some(comment.into()),
8481            options: Vec::new(),
8482        }
8483    }
8484}
8485
8486/// CREATE VIEW statement
8487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8488#[cfg_attr(feature = "bindings", derive(TS))]
8489pub struct CreateView {
8490    pub name: TableRef,
8491    pub columns: Vec<ViewColumn>,
8492    pub query: Expression,
8493    pub or_replace: bool,
8494    /// TSQL: CREATE OR ALTER
8495    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
8496    pub or_alter: bool,
8497    pub if_not_exists: bool,
8498    pub materialized: bool,
8499    pub temporary: bool,
8500    /// Snowflake: SECURE VIEW
8501    #[serde(default)]
8502    pub secure: bool,
8503    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
8504    #[serde(skip_serializing_if = "Option::is_none")]
8505    pub algorithm: Option<String>,
8506    /// MySQL: DEFINER=user@host
8507    #[serde(skip_serializing_if = "Option::is_none")]
8508    pub definer: Option<String>,
8509    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
8510    #[serde(skip_serializing_if = "Option::is_none")]
8511    pub security: Option<FunctionSecurity>,
8512    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
8513    #[serde(default = "default_true")]
8514    pub security_sql_style: bool,
8515    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
8516    #[serde(default)]
8517    pub security_after_name: bool,
8518    /// Whether the query was parenthesized: AS (SELECT ...)
8519    #[serde(default)]
8520    pub query_parenthesized: bool,
8521    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
8522    #[serde(skip_serializing_if = "Option::is_none")]
8523    pub locking_mode: Option<String>,
8524    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
8525    #[serde(skip_serializing_if = "Option::is_none")]
8526    pub locking_access: Option<String>,
8527    /// Snowflake: COPY GRANTS
8528    #[serde(default)]
8529    pub copy_grants: bool,
8530    /// Snowflake: COMMENT = 'text'
8531    #[serde(skip_serializing_if = "Option::is_none", default)]
8532    pub comment: Option<String>,
8533    /// Snowflake: WITH ROW ACCESS POLICY ... clause
8534    #[serde(skip_serializing_if = "Option::is_none", default)]
8535    pub row_access_policy: Option<String>,
8536    /// Snowflake: TAG (name='value', ...)
8537    #[serde(default)]
8538    pub tags: Vec<(String, String)>,
8539    /// BigQuery: OPTIONS (key=value, ...)
8540    #[serde(default)]
8541    pub options: Vec<Expression>,
8542    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
8543    #[serde(skip_serializing_if = "Option::is_none", default)]
8544    pub build: Option<String>,
8545    /// Doris: REFRESH property for materialized views
8546    #[serde(skip_serializing_if = "Option::is_none", default)]
8547    pub refresh: Option<Box<RefreshTriggerProperty>>,
8548    /// Doris: Schema with typed column definitions for materialized views
8549    /// This is used instead of `columns` when the view has typed column definitions
8550    #[serde(skip_serializing_if = "Option::is_none", default)]
8551    pub schema: Option<Box<Schema>>,
8552    /// Doris: KEY (columns) for materialized views
8553    #[serde(skip_serializing_if = "Option::is_none", default)]
8554    pub unique_key: Option<Box<UniqueKeyProperty>>,
8555    /// Redshift: WITH NO SCHEMA BINDING
8556    #[serde(default)]
8557    pub no_schema_binding: bool,
8558    /// Redshift: AUTO REFRESH YES|NO for materialized views
8559    #[serde(skip_serializing_if = "Option::is_none", default)]
8560    pub auto_refresh: Option<bool>,
8561    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
8562    #[serde(skip_serializing_if = "Option::is_none", default)]
8563    pub clickhouse_population: Option<String>,
8564    /// ClickHouse: ON CLUSTER clause
8565    #[serde(default, skip_serializing_if = "Option::is_none")]
8566    pub on_cluster: Option<OnCluster>,
8567    /// ClickHouse: TO destination_table
8568    #[serde(default, skip_serializing_if = "Option::is_none")]
8569    pub to_table: Option<TableRef>,
8570    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
8571    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8572    pub table_properties: Vec<Expression>,
8573}
8574
8575impl CreateView {
8576    pub fn new(name: impl Into<String>, query: Expression) -> Self {
8577        Self {
8578            name: TableRef::new(name),
8579            columns: Vec::new(),
8580            query,
8581            or_replace: false,
8582            or_alter: false,
8583            if_not_exists: false,
8584            materialized: false,
8585            temporary: false,
8586            secure: false,
8587            algorithm: None,
8588            definer: None,
8589            security: None,
8590            security_sql_style: true,
8591            security_after_name: false,
8592            query_parenthesized: false,
8593            locking_mode: None,
8594            locking_access: None,
8595            copy_grants: false,
8596            comment: None,
8597            row_access_policy: None,
8598            tags: Vec::new(),
8599            options: Vec::new(),
8600            build: None,
8601            refresh: None,
8602            schema: None,
8603            unique_key: None,
8604            no_schema_binding: false,
8605            auto_refresh: None,
8606            clickhouse_population: None,
8607            on_cluster: None,
8608            to_table: None,
8609            table_properties: Vec::new(),
8610        }
8611    }
8612}
8613
8614/// DROP VIEW statement
8615#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8616#[cfg_attr(feature = "bindings", derive(TS))]
8617pub struct DropView {
8618    pub name: TableRef,
8619    pub if_exists: bool,
8620    pub materialized: bool,
8621}
8622
8623impl DropView {
8624    pub fn new(name: impl Into<String>) -> Self {
8625        Self {
8626            name: TableRef::new(name),
8627            if_exists: false,
8628            materialized: false,
8629        }
8630    }
8631}
8632
8633/// TRUNCATE TABLE statement
8634#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8635#[cfg_attr(feature = "bindings", derive(TS))]
8636pub struct Truncate {
8637    /// Target of TRUNCATE (TABLE vs DATABASE)
8638    #[serde(default)]
8639    pub target: TruncateTarget,
8640    /// IF EXISTS clause
8641    #[serde(default)]
8642    pub if_exists: bool,
8643    pub table: TableRef,
8644    /// ClickHouse: ON CLUSTER clause for distributed DDL
8645    #[serde(default, skip_serializing_if = "Option::is_none")]
8646    pub on_cluster: Option<OnCluster>,
8647    pub cascade: bool,
8648    /// Additional tables for multi-table TRUNCATE
8649    #[serde(default)]
8650    pub extra_tables: Vec<TruncateTableEntry>,
8651    /// RESTART IDENTITY or CONTINUE IDENTITY
8652    #[serde(default)]
8653    pub identity: Option<TruncateIdentity>,
8654    /// RESTRICT option (alternative to CASCADE)
8655    #[serde(default)]
8656    pub restrict: bool,
8657    /// Hive PARTITION clause: PARTITION(key=value, ...)
8658    #[serde(default, skip_serializing_if = "Option::is_none")]
8659    pub partition: Option<Box<Expression>>,
8660}
8661
8662/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
8663#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8664#[cfg_attr(feature = "bindings", derive(TS))]
8665pub struct TruncateTableEntry {
8666    pub table: TableRef,
8667    /// Whether the table has a * suffix (inherit children)
8668    #[serde(default)]
8669    pub star: bool,
8670}
8671
8672/// TRUNCATE target type
8673#[derive(
8674    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8675)]
8676#[cfg_attr(feature = "bindings", derive(TS))]
8677pub enum TruncateTarget {
8678    Table,
8679    Database,
8680}
8681
8682impl Default for TruncateTarget {
8683    fn default() -> Self {
8684        TruncateTarget::Table
8685    }
8686}
8687
8688/// TRUNCATE identity option
8689#[derive(
8690    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8691)]
8692#[cfg_attr(feature = "bindings", derive(TS))]
8693pub enum TruncateIdentity {
8694    Restart,
8695    Continue,
8696}
8697
8698impl Truncate {
8699    pub fn new(table: impl Into<String>) -> Self {
8700        Self {
8701            target: TruncateTarget::Table,
8702            if_exists: false,
8703            table: TableRef::new(table),
8704            on_cluster: None,
8705            cascade: false,
8706            extra_tables: Vec::new(),
8707            identity: None,
8708            restrict: false,
8709            partition: None,
8710        }
8711    }
8712}
8713
8714/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
8715#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8716#[cfg_attr(feature = "bindings", derive(TS))]
8717pub struct Use {
8718    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
8719    pub kind: Option<UseKind>,
8720    /// The name of the object
8721    pub this: Identifier,
8722}
8723
8724/// Kind of USE statement
8725#[derive(
8726    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8727)]
8728#[cfg_attr(feature = "bindings", derive(TS))]
8729pub enum UseKind {
8730    Database,
8731    Schema,
8732    Role,
8733    Warehouse,
8734    Catalog,
8735    /// Snowflake: USE SECONDARY ROLES ALL|NONE
8736    SecondaryRoles,
8737}
8738
8739/// SET variable statement
8740#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8741#[cfg_attr(feature = "bindings", derive(TS))]
8742pub struct SetStatement {
8743    /// The items being set
8744    pub items: Vec<SetItem>,
8745}
8746
8747/// A single SET item (variable assignment)
8748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8749#[cfg_attr(feature = "bindings", derive(TS))]
8750pub struct SetItem {
8751    /// The variable name
8752    pub name: Expression,
8753    /// The value to set
8754    pub value: Expression,
8755    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
8756    pub kind: Option<String>,
8757    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
8758    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
8759    pub no_equals: bool,
8760}
8761
8762/// CACHE TABLE statement (Spark)
8763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8764#[cfg_attr(feature = "bindings", derive(TS))]
8765pub struct Cache {
8766    /// The table to cache
8767    pub table: Identifier,
8768    /// LAZY keyword - defer caching until first use
8769    pub lazy: bool,
8770    /// Optional OPTIONS clause (key-value pairs)
8771    pub options: Vec<(Expression, Expression)>,
8772    /// Optional AS clause with query
8773    pub query: Option<Expression>,
8774}
8775
8776/// UNCACHE TABLE statement (Spark)
8777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8778#[cfg_attr(feature = "bindings", derive(TS))]
8779pub struct Uncache {
8780    /// The table to uncache
8781    pub table: Identifier,
8782    /// IF EXISTS clause
8783    pub if_exists: bool,
8784}
8785
8786/// LOAD DATA statement (Hive)
8787#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8788#[cfg_attr(feature = "bindings", derive(TS))]
8789pub struct LoadData {
8790    /// LOCAL keyword - load from local filesystem
8791    pub local: bool,
8792    /// The path to load data from (INPATH value)
8793    pub inpath: String,
8794    /// Whether to overwrite existing data
8795    pub overwrite: bool,
8796    /// The target table
8797    pub table: Expression,
8798    /// Optional PARTITION clause with key-value pairs
8799    pub partition: Vec<(Identifier, Expression)>,
8800    /// Optional INPUTFORMAT clause
8801    pub input_format: Option<String>,
8802    /// Optional SERDE clause
8803    pub serde: Option<String>,
8804}
8805
8806/// PRAGMA statement (SQLite)
8807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8808#[cfg_attr(feature = "bindings", derive(TS))]
8809pub struct Pragma {
8810    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
8811    pub schema: Option<Identifier>,
8812    /// The pragma name
8813    pub name: Identifier,
8814    /// Optional value for assignment (PRAGMA name = value)
8815    pub value: Option<Expression>,
8816    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
8817    pub args: Vec<Expression>,
8818    /// Whether this pragma should be generated using assignment syntax.
8819    #[serde(default)]
8820    pub use_assignment_syntax: bool,
8821}
8822
8823/// A privilege with optional column list for GRANT/REVOKE
8824/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
8825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8826#[cfg_attr(feature = "bindings", derive(TS))]
8827pub struct Privilege {
8828    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
8829    pub name: String,
8830    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
8831    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8832    pub columns: Vec<String>,
8833}
8834
8835/// Principal in GRANT/REVOKE (user, role, etc.)
8836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8837#[cfg_attr(feature = "bindings", derive(TS))]
8838pub struct GrantPrincipal {
8839    /// The name of the principal
8840    pub name: Identifier,
8841    /// Whether prefixed with ROLE keyword
8842    pub is_role: bool,
8843    /// Whether prefixed with GROUP keyword (Redshift)
8844    #[serde(default)]
8845    pub is_group: bool,
8846    /// Whether prefixed with SHARE keyword (Snowflake)
8847    #[serde(default)]
8848    pub is_share: bool,
8849}
8850
8851/// GRANT statement
8852#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8853#[cfg_attr(feature = "bindings", derive(TS))]
8854pub struct Grant {
8855    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
8856    pub privileges: Vec<Privilege>,
8857    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
8858    pub kind: Option<String>,
8859    /// The object to grant on
8860    pub securable: Identifier,
8861    /// Function parameter types (for FUNCTION kind)
8862    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8863    pub function_params: Vec<String>,
8864    /// The grantees
8865    pub principals: Vec<GrantPrincipal>,
8866    /// WITH GRANT OPTION
8867    pub grant_option: bool,
8868    /// TSQL: AS principal (the grantor role)
8869    #[serde(default, skip_serializing_if = "Option::is_none")]
8870    pub as_principal: Option<Identifier>,
8871}
8872
8873/// REVOKE statement
8874#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8875#[cfg_attr(feature = "bindings", derive(TS))]
8876pub struct Revoke {
8877    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
8878    pub privileges: Vec<Privilege>,
8879    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
8880    pub kind: Option<String>,
8881    /// The object to revoke from
8882    pub securable: Identifier,
8883    /// Function parameter types (for FUNCTION kind)
8884    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8885    pub function_params: Vec<String>,
8886    /// The grantees
8887    pub principals: Vec<GrantPrincipal>,
8888    /// GRANT OPTION FOR
8889    pub grant_option: bool,
8890    /// CASCADE
8891    pub cascade: bool,
8892    /// RESTRICT
8893    #[serde(default)]
8894    pub restrict: bool,
8895}
8896
8897/// COMMENT ON statement
8898#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8899#[cfg_attr(feature = "bindings", derive(TS))]
8900pub struct Comment {
8901    /// The object being commented on
8902    pub this: Expression,
8903    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
8904    pub kind: String,
8905    /// The comment text expression
8906    pub expression: Expression,
8907    /// IF EXISTS clause
8908    pub exists: bool,
8909    /// MATERIALIZED keyword
8910    pub materialized: bool,
8911}
8912
8913// ============================================================================
8914// Phase 4: Additional DDL Statements
8915// ============================================================================
8916
8917/// ALTER VIEW statement
8918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8919#[cfg_attr(feature = "bindings", derive(TS))]
8920pub struct AlterView {
8921    pub name: TableRef,
8922    pub actions: Vec<AlterViewAction>,
8923    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
8924    #[serde(default, skip_serializing_if = "Option::is_none")]
8925    pub algorithm: Option<String>,
8926    /// MySQL: DEFINER = 'user'@'host'
8927    #[serde(default, skip_serializing_if = "Option::is_none")]
8928    pub definer: Option<String>,
8929    /// MySQL: SQL SECURITY = DEFINER|INVOKER
8930    #[serde(default, skip_serializing_if = "Option::is_none")]
8931    pub sql_security: Option<String>,
8932    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
8933    #[serde(default, skip_serializing_if = "Option::is_none")]
8934    pub with_option: Option<String>,
8935    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
8936    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8937    pub columns: Vec<ViewColumn>,
8938}
8939
8940/// Actions for ALTER VIEW
8941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8942#[cfg_attr(feature = "bindings", derive(TS))]
8943pub enum AlterViewAction {
8944    /// Rename the view
8945    Rename(TableRef),
8946    /// Change owner
8947    OwnerTo(Identifier),
8948    /// Set schema
8949    SetSchema(Identifier),
8950    /// Set authorization (Trino/Presto)
8951    SetAuthorization(String),
8952    /// Alter column
8953    AlterColumn {
8954        name: Identifier,
8955        action: AlterColumnAction,
8956    },
8957    /// Redefine view as query (SELECT, UNION, etc.)
8958    AsSelect(Box<Expression>),
8959    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
8960    SetTblproperties(Vec<(String, String)>),
8961    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
8962    UnsetTblproperties(Vec<String>),
8963}
8964
8965impl AlterView {
8966    pub fn new(name: impl Into<String>) -> Self {
8967        Self {
8968            name: TableRef::new(name),
8969            actions: Vec::new(),
8970            algorithm: None,
8971            definer: None,
8972            sql_security: None,
8973            with_option: None,
8974            columns: Vec::new(),
8975        }
8976    }
8977}
8978
8979/// ALTER INDEX statement
8980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8981#[cfg_attr(feature = "bindings", derive(TS))]
8982pub struct AlterIndex {
8983    pub name: Identifier,
8984    pub table: Option<TableRef>,
8985    pub actions: Vec<AlterIndexAction>,
8986}
8987
8988/// Actions for ALTER INDEX
8989#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8990#[cfg_attr(feature = "bindings", derive(TS))]
8991pub enum AlterIndexAction {
8992    /// Rename the index
8993    Rename(Identifier),
8994    /// Set tablespace
8995    SetTablespace(Identifier),
8996    /// Set visibility (MySQL)
8997    Visible(bool),
8998}
8999
9000impl AlterIndex {
9001    pub fn new(name: impl Into<String>) -> Self {
9002        Self {
9003            name: Identifier::new(name),
9004            table: None,
9005            actions: Vec::new(),
9006        }
9007    }
9008}
9009
9010/// CREATE SCHEMA statement
9011#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9012#[cfg_attr(feature = "bindings", derive(TS))]
9013pub struct CreateSchema {
9014    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9015    pub name: Vec<Identifier>,
9016    pub if_not_exists: bool,
9017    pub authorization: Option<Identifier>,
9018    /// CLONE source parts, possibly dot-qualified
9019    #[serde(default)]
9020    pub clone_from: Option<Vec<Identifier>>,
9021    /// AT/BEFORE clause for time travel (Snowflake)
9022    #[serde(default)]
9023    pub at_clause: Option<Expression>,
9024    /// Schema properties like DEFAULT COLLATE
9025    #[serde(default)]
9026    pub properties: Vec<Expression>,
9027    /// Leading comments before the statement
9028    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9029    pub leading_comments: Vec<String>,
9030}
9031
9032impl CreateSchema {
9033    pub fn new(name: impl Into<String>) -> Self {
9034        Self {
9035            name: vec![Identifier::new(name)],
9036            if_not_exists: false,
9037            authorization: None,
9038            clone_from: None,
9039            at_clause: None,
9040            properties: Vec::new(),
9041            leading_comments: Vec::new(),
9042        }
9043    }
9044}
9045
9046/// DROP SCHEMA statement
9047#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9048#[cfg_attr(feature = "bindings", derive(TS))]
9049pub struct DropSchema {
9050    pub name: Identifier,
9051    pub if_exists: bool,
9052    pub cascade: bool,
9053}
9054
9055impl DropSchema {
9056    pub fn new(name: impl Into<String>) -> Self {
9057        Self {
9058            name: Identifier::new(name),
9059            if_exists: false,
9060            cascade: false,
9061        }
9062    }
9063}
9064
9065/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9067#[cfg_attr(feature = "bindings", derive(TS))]
9068pub struct DropNamespace {
9069    pub name: Identifier,
9070    pub if_exists: bool,
9071    pub cascade: bool,
9072}
9073
9074impl DropNamespace {
9075    pub fn new(name: impl Into<String>) -> Self {
9076        Self {
9077            name: Identifier::new(name),
9078            if_exists: false,
9079            cascade: false,
9080        }
9081    }
9082}
9083
9084/// CREATE DATABASE statement
9085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9086#[cfg_attr(feature = "bindings", derive(TS))]
9087pub struct CreateDatabase {
9088    pub name: Identifier,
9089    pub if_not_exists: bool,
9090    pub options: Vec<DatabaseOption>,
9091    /// Snowflake CLONE source
9092    #[serde(default)]
9093    pub clone_from: Option<Identifier>,
9094    /// AT/BEFORE clause for time travel (Snowflake)
9095    #[serde(default)]
9096    pub at_clause: Option<Expression>,
9097}
9098
9099/// Database option
9100#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9101#[cfg_attr(feature = "bindings", derive(TS))]
9102pub enum DatabaseOption {
9103    CharacterSet(String),
9104    Collate(String),
9105    Owner(Identifier),
9106    Template(Identifier),
9107    Encoding(String),
9108    Location(String),
9109}
9110
9111impl CreateDatabase {
9112    pub fn new(name: impl Into<String>) -> Self {
9113        Self {
9114            name: Identifier::new(name),
9115            if_not_exists: false,
9116            options: Vec::new(),
9117            clone_from: None,
9118            at_clause: None,
9119        }
9120    }
9121}
9122
9123/// DROP DATABASE statement
9124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9125#[cfg_attr(feature = "bindings", derive(TS))]
9126pub struct DropDatabase {
9127    pub name: Identifier,
9128    pub if_exists: bool,
9129    /// ClickHouse: SYNC modifier
9130    #[serde(default)]
9131    pub sync: bool,
9132}
9133
9134impl DropDatabase {
9135    pub fn new(name: impl Into<String>) -> Self {
9136        Self {
9137            name: Identifier::new(name),
9138            if_exists: false,
9139            sync: false,
9140        }
9141    }
9142}
9143
9144/// CREATE FUNCTION statement
9145#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9146#[cfg_attr(feature = "bindings", derive(TS))]
9147pub struct CreateFunction {
9148    pub name: TableRef,
9149    pub parameters: Vec<FunctionParameter>,
9150    pub return_type: Option<DataType>,
9151    pub body: Option<FunctionBody>,
9152    pub or_replace: bool,
9153    /// TSQL: CREATE OR ALTER
9154    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9155    pub or_alter: bool,
9156    pub if_not_exists: bool,
9157    pub temporary: bool,
9158    pub language: Option<String>,
9159    pub deterministic: Option<bool>,
9160    pub returns_null_on_null_input: Option<bool>,
9161    pub security: Option<FunctionSecurity>,
9162    /// Whether parentheses were present in the original syntax
9163    #[serde(default = "default_true")]
9164    pub has_parens: bool,
9165    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9166    #[serde(default)]
9167    pub sql_data_access: Option<SqlDataAccess>,
9168    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9169    #[serde(default, skip_serializing_if = "Option::is_none")]
9170    pub returns_table_body: Option<String>,
9171    /// True if LANGUAGE clause appears before RETURNS clause
9172    #[serde(default)]
9173    pub language_first: bool,
9174    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9175    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9176    pub set_options: Vec<FunctionSetOption>,
9177    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9178    #[serde(default)]
9179    pub strict: bool,
9180    /// BigQuery: OPTIONS (key=value, ...)
9181    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9182    pub options: Vec<Expression>,
9183    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9184    #[serde(default)]
9185    pub is_table_function: bool,
9186    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9187    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9188    pub property_order: Vec<FunctionPropertyKind>,
9189    /// Hive: USING JAR|FILE|ARCHIVE '...'
9190    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9191    pub using_resources: Vec<FunctionUsingResource>,
9192    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9193    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9194    pub environment: Vec<Expression>,
9195    /// HANDLER 'handler_function' clause (Databricks)
9196    #[serde(default, skip_serializing_if = "Option::is_none")]
9197    pub handler: Option<String>,
9198    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9199    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9200    pub handler_uses_eq: bool,
9201    /// Snowflake: RUNTIME_VERSION='3.11'
9202    #[serde(default, skip_serializing_if = "Option::is_none")]
9203    pub runtime_version: Option<String>,
9204    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9205    #[serde(default, skip_serializing_if = "Option::is_none")]
9206    pub packages: Option<Vec<String>>,
9207    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9208    #[serde(default, skip_serializing_if = "Option::is_none")]
9209    pub parameter_style: Option<String>,
9210}
9211
9212/// A SET option in CREATE FUNCTION (PostgreSQL)
9213#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9214#[cfg_attr(feature = "bindings", derive(TS))]
9215pub struct FunctionSetOption {
9216    pub name: String,
9217    pub value: FunctionSetValue,
9218}
9219
9220/// The value of a SET option
9221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9222#[cfg_attr(feature = "bindings", derive(TS))]
9223pub enum FunctionSetValue {
9224    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9225    Value { value: String, use_to: bool },
9226    /// SET key FROM CURRENT
9227    FromCurrent,
9228}
9229
9230/// SQL data access characteristics for functions
9231#[derive(
9232    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9233)]
9234#[cfg_attr(feature = "bindings", derive(TS))]
9235pub enum SqlDataAccess {
9236    /// NO SQL
9237    NoSql,
9238    /// CONTAINS SQL
9239    ContainsSql,
9240    /// READS SQL DATA
9241    ReadsSqlData,
9242    /// MODIFIES SQL DATA
9243    ModifiesSqlData,
9244}
9245
9246/// Types of properties in CREATE FUNCTION for tracking their original order
9247#[derive(
9248    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9249)]
9250#[cfg_attr(feature = "bindings", derive(TS))]
9251pub enum FunctionPropertyKind {
9252    /// SET option
9253    Set,
9254    /// AS body
9255    As,
9256    /// Hive: USING JAR|FILE|ARCHIVE ...
9257    Using,
9258    /// LANGUAGE clause
9259    Language,
9260    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9261    Determinism,
9262    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
9263    NullInput,
9264    /// SECURITY DEFINER/INVOKER
9265    Security,
9266    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
9267    SqlDataAccess,
9268    /// OPTIONS clause (BigQuery)
9269    Options,
9270    /// ENVIRONMENT clause (Databricks)
9271    Environment,
9272    /// HANDLER clause (Databricks)
9273    Handler,
9274    /// Snowflake: RUNTIME_VERSION='...'
9275    RuntimeVersion,
9276    /// Snowflake: PACKAGES=(...)
9277    Packages,
9278    /// PARAMETER STYLE clause (Databricks)
9279    ParameterStyle,
9280}
9281
9282/// Hive CREATE FUNCTION resource in a USING clause
9283#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9284#[cfg_attr(feature = "bindings", derive(TS))]
9285pub struct FunctionUsingResource {
9286    pub kind: String,
9287    pub uri: String,
9288}
9289
9290/// Function parameter
9291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9292#[cfg_attr(feature = "bindings", derive(TS))]
9293pub struct FunctionParameter {
9294    pub name: Option<Identifier>,
9295    pub data_type: DataType,
9296    pub mode: Option<ParameterMode>,
9297    pub default: Option<Expression>,
9298    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
9299    #[serde(default, skip_serializing_if = "Option::is_none")]
9300    pub mode_text: Option<String>,
9301}
9302
9303/// Parameter mode (IN, OUT, INOUT, VARIADIC)
9304#[derive(
9305    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9306)]
9307#[cfg_attr(feature = "bindings", derive(TS))]
9308pub enum ParameterMode {
9309    In,
9310    Out,
9311    InOut,
9312    Variadic,
9313}
9314
9315/// Function body
9316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9317#[cfg_attr(feature = "bindings", derive(TS))]
9318pub enum FunctionBody {
9319    /// AS $$ ... $$ (dollar-quoted)
9320    Block(String),
9321    /// AS 'string' (single-quoted string literal body)
9322    StringLiteral(String),
9323    /// AS 'expression'
9324    Expression(Expression),
9325    /// EXTERNAL NAME 'library'
9326    External(String),
9327    /// RETURN expression
9328    Return(Expression),
9329    /// BEGIN ... END block with parsed statements
9330    Statements(Vec<Expression>),
9331    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
9332    /// Stores (content, optional_tag)
9333    DollarQuoted {
9334        content: String,
9335        tag: Option<String>,
9336    },
9337    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
9338    RawBlock(String),
9339}
9340
9341/// Function security (DEFINER, INVOKER, or NONE)
9342#[derive(
9343    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9344)]
9345#[cfg_attr(feature = "bindings", derive(TS))]
9346pub enum FunctionSecurity {
9347    Definer,
9348    Invoker,
9349    /// StarRocks/MySQL: SECURITY NONE
9350    None,
9351}
9352
9353impl CreateFunction {
9354    pub fn new(name: impl Into<String>) -> Self {
9355        Self {
9356            name: TableRef::new(name),
9357            parameters: Vec::new(),
9358            return_type: None,
9359            body: None,
9360            or_replace: false,
9361            or_alter: false,
9362            if_not_exists: false,
9363            temporary: false,
9364            language: None,
9365            deterministic: None,
9366            returns_null_on_null_input: None,
9367            security: None,
9368            has_parens: true,
9369            sql_data_access: None,
9370            returns_table_body: None,
9371            language_first: false,
9372            set_options: Vec::new(),
9373            strict: false,
9374            options: Vec::new(),
9375            is_table_function: false,
9376            property_order: Vec::new(),
9377            using_resources: Vec::new(),
9378            environment: Vec::new(),
9379            handler: None,
9380            handler_uses_eq: false,
9381            runtime_version: None,
9382            packages: None,
9383            parameter_style: None,
9384        }
9385    }
9386}
9387
9388/// DROP FUNCTION statement
9389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9390#[cfg_attr(feature = "bindings", derive(TS))]
9391pub struct DropFunction {
9392    pub name: TableRef,
9393    pub parameters: Option<Vec<DataType>>,
9394    pub if_exists: bool,
9395    pub cascade: bool,
9396}
9397
9398impl DropFunction {
9399    pub fn new(name: impl Into<String>) -> Self {
9400        Self {
9401            name: TableRef::new(name),
9402            parameters: None,
9403            if_exists: false,
9404            cascade: false,
9405        }
9406    }
9407}
9408
9409/// CREATE PROCEDURE statement
9410#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9411#[cfg_attr(feature = "bindings", derive(TS))]
9412pub struct CreateProcedure {
9413    pub name: TableRef,
9414    pub parameters: Vec<FunctionParameter>,
9415    pub body: Option<FunctionBody>,
9416    pub or_replace: bool,
9417    /// TSQL: CREATE OR ALTER
9418    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9419    pub or_alter: bool,
9420    pub if_not_exists: bool,
9421    pub language: Option<String>,
9422    pub security: Option<FunctionSecurity>,
9423    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
9424    #[serde(default)]
9425    pub return_type: Option<DataType>,
9426    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
9427    #[serde(default)]
9428    pub execute_as: Option<String>,
9429    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
9430    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9431    pub with_options: Vec<String>,
9432    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
9433    #[serde(default = "default_true", skip_serializing_if = "is_true")]
9434    pub has_parens: bool,
9435    /// Whether the short form PROC was used (instead of PROCEDURE)
9436    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9437    pub use_proc_keyword: bool,
9438}
9439
9440impl CreateProcedure {
9441    pub fn new(name: impl Into<String>) -> Self {
9442        Self {
9443            name: TableRef::new(name),
9444            parameters: Vec::new(),
9445            body: None,
9446            or_replace: false,
9447            or_alter: false,
9448            if_not_exists: false,
9449            language: None,
9450            security: None,
9451            return_type: None,
9452            execute_as: None,
9453            with_options: Vec::new(),
9454            has_parens: true,
9455            use_proc_keyword: false,
9456        }
9457    }
9458}
9459
9460/// DROP PROCEDURE statement
9461#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9462#[cfg_attr(feature = "bindings", derive(TS))]
9463pub struct DropProcedure {
9464    pub name: TableRef,
9465    pub parameters: Option<Vec<DataType>>,
9466    pub if_exists: bool,
9467    pub cascade: bool,
9468}
9469
9470impl DropProcedure {
9471    pub fn new(name: impl Into<String>) -> Self {
9472        Self {
9473            name: TableRef::new(name),
9474            parameters: None,
9475            if_exists: false,
9476            cascade: false,
9477        }
9478    }
9479}
9480
9481/// Sequence property tag for ordering
9482#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9483#[cfg_attr(feature = "bindings", derive(TS))]
9484pub enum SeqPropKind {
9485    Start,
9486    Increment,
9487    Minvalue,
9488    Maxvalue,
9489    Cache,
9490    NoCache,
9491    Cycle,
9492    NoCycle,
9493    OwnedBy,
9494    Order,
9495    NoOrder,
9496    Comment,
9497    /// SHARING=<value> (Oracle)
9498    Sharing,
9499    /// KEEP (Oracle)
9500    Keep,
9501    /// NOKEEP (Oracle)
9502    NoKeep,
9503    /// SCALE [EXTEND|NOEXTEND] (Oracle)
9504    Scale,
9505    /// NOSCALE (Oracle)
9506    NoScale,
9507    /// SHARD [EXTEND|NOEXTEND] (Oracle)
9508    Shard,
9509    /// NOSHARD (Oracle)
9510    NoShard,
9511    /// SESSION (Oracle)
9512    Session,
9513    /// GLOBAL (Oracle)
9514    Global,
9515    /// NOCACHE (single word, Oracle)
9516    NoCacheWord,
9517    /// NOCYCLE (single word, Oracle)
9518    NoCycleWord,
9519    /// NOMINVALUE (single word, Oracle)
9520    NoMinvalueWord,
9521    /// NOMAXVALUE (single word, Oracle)
9522    NoMaxvalueWord,
9523}
9524
9525/// CREATE SYNONYM statement (TSQL)
9526#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9527#[cfg_attr(feature = "bindings", derive(TS))]
9528pub struct CreateSynonym {
9529    /// The synonym name (can be qualified: schema.synonym_name)
9530    pub name: TableRef,
9531    /// The target object the synonym refers to
9532    pub target: TableRef,
9533}
9534
9535/// CREATE SEQUENCE statement
9536#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9537#[cfg_attr(feature = "bindings", derive(TS))]
9538pub struct CreateSequence {
9539    pub name: TableRef,
9540    pub if_not_exists: bool,
9541    pub temporary: bool,
9542    #[serde(default)]
9543    pub or_replace: bool,
9544    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
9545    #[serde(default, skip_serializing_if = "Option::is_none")]
9546    pub as_type: Option<DataType>,
9547    pub increment: Option<i64>,
9548    pub minvalue: Option<SequenceBound>,
9549    pub maxvalue: Option<SequenceBound>,
9550    pub start: Option<i64>,
9551    pub cache: Option<i64>,
9552    pub cycle: bool,
9553    pub owned_by: Option<TableRef>,
9554    /// Whether OWNED BY NONE was specified
9555    #[serde(default)]
9556    pub owned_by_none: bool,
9557    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
9558    #[serde(default)]
9559    pub order: Option<bool>,
9560    /// Snowflake: COMMENT = 'value'
9561    #[serde(default)]
9562    pub comment: Option<String>,
9563    /// SHARING=<value> (Oracle)
9564    #[serde(default, skip_serializing_if = "Option::is_none")]
9565    pub sharing: Option<String>,
9566    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
9567    #[serde(default, skip_serializing_if = "Option::is_none")]
9568    pub scale_modifier: Option<String>,
9569    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
9570    #[serde(default, skip_serializing_if = "Option::is_none")]
9571    pub shard_modifier: Option<String>,
9572    /// Tracks the order in which properties appeared in the source
9573    #[serde(default)]
9574    pub property_order: Vec<SeqPropKind>,
9575}
9576
9577/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
9578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9579#[cfg_attr(feature = "bindings", derive(TS))]
9580pub enum SequenceBound {
9581    Value(i64),
9582    None,
9583}
9584
9585impl CreateSequence {
9586    pub fn new(name: impl Into<String>) -> Self {
9587        Self {
9588            name: TableRef::new(name),
9589            if_not_exists: false,
9590            temporary: false,
9591            or_replace: false,
9592            as_type: None,
9593            increment: None,
9594            minvalue: None,
9595            maxvalue: None,
9596            start: None,
9597            cache: None,
9598            cycle: false,
9599            owned_by: None,
9600            owned_by_none: false,
9601            order: None,
9602            comment: None,
9603            sharing: None,
9604            scale_modifier: None,
9605            shard_modifier: None,
9606            property_order: Vec::new(),
9607        }
9608    }
9609}
9610
9611/// DROP SEQUENCE statement
9612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9613#[cfg_attr(feature = "bindings", derive(TS))]
9614pub struct DropSequence {
9615    pub name: TableRef,
9616    pub if_exists: bool,
9617    pub cascade: bool,
9618}
9619
9620impl DropSequence {
9621    pub fn new(name: impl Into<String>) -> Self {
9622        Self {
9623            name: TableRef::new(name),
9624            if_exists: false,
9625            cascade: false,
9626        }
9627    }
9628}
9629
9630/// ALTER SEQUENCE statement
9631#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9632#[cfg_attr(feature = "bindings", derive(TS))]
9633pub struct AlterSequence {
9634    pub name: TableRef,
9635    pub if_exists: bool,
9636    pub increment: Option<i64>,
9637    pub minvalue: Option<SequenceBound>,
9638    pub maxvalue: Option<SequenceBound>,
9639    pub start: Option<i64>,
9640    pub restart: Option<Option<i64>>,
9641    pub cache: Option<i64>,
9642    pub cycle: Option<bool>,
9643    pub owned_by: Option<Option<TableRef>>,
9644}
9645
9646impl AlterSequence {
9647    pub fn new(name: impl Into<String>) -> Self {
9648        Self {
9649            name: TableRef::new(name),
9650            if_exists: false,
9651            increment: None,
9652            minvalue: None,
9653            maxvalue: None,
9654            start: None,
9655            restart: None,
9656            cache: None,
9657            cycle: None,
9658            owned_by: None,
9659        }
9660    }
9661}
9662
9663/// CREATE TRIGGER statement
9664#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9665#[cfg_attr(feature = "bindings", derive(TS))]
9666pub struct CreateTrigger {
9667    pub name: Identifier,
9668    pub table: TableRef,
9669    pub timing: TriggerTiming,
9670    pub events: Vec<TriggerEvent>,
9671    #[serde(default, skip_serializing_if = "Option::is_none")]
9672    pub for_each: Option<TriggerForEach>,
9673    pub when: Option<Expression>,
9674    /// Whether the WHEN clause was parenthesized in the original SQL
9675    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9676    pub when_paren: bool,
9677    pub body: TriggerBody,
9678    pub or_replace: bool,
9679    /// TSQL: CREATE OR ALTER
9680    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9681    pub or_alter: bool,
9682    pub constraint: bool,
9683    pub deferrable: Option<bool>,
9684    pub initially_deferred: Option<bool>,
9685    pub referencing: Option<TriggerReferencing>,
9686}
9687
9688/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
9689#[derive(
9690    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9691)]
9692#[cfg_attr(feature = "bindings", derive(TS))]
9693pub enum TriggerTiming {
9694    Before,
9695    After,
9696    InsteadOf,
9697}
9698
9699/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
9700#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9701#[cfg_attr(feature = "bindings", derive(TS))]
9702pub enum TriggerEvent {
9703    Insert,
9704    Update(Option<Vec<Identifier>>),
9705    Delete,
9706    Truncate,
9707}
9708
9709/// Trigger FOR EACH clause
9710#[derive(
9711    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9712)]
9713#[cfg_attr(feature = "bindings", derive(TS))]
9714pub enum TriggerForEach {
9715    Row,
9716    Statement,
9717}
9718
9719/// Trigger body
9720#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9721#[cfg_attr(feature = "bindings", derive(TS))]
9722pub enum TriggerBody {
9723    /// EXECUTE FUNCTION/PROCEDURE name(args)
9724    Execute {
9725        function: TableRef,
9726        args: Vec<Expression>,
9727    },
9728    /// BEGIN ... END block
9729    Block(String),
9730}
9731
9732/// Trigger REFERENCING clause
9733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9734#[cfg_attr(feature = "bindings", derive(TS))]
9735pub struct TriggerReferencing {
9736    pub old_table: Option<Identifier>,
9737    pub new_table: Option<Identifier>,
9738    pub old_row: Option<Identifier>,
9739    pub new_row: Option<Identifier>,
9740}
9741
9742impl CreateTrigger {
9743    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
9744        Self {
9745            name: Identifier::new(name),
9746            table: TableRef::new(table),
9747            timing: TriggerTiming::Before,
9748            events: Vec::new(),
9749            for_each: Some(TriggerForEach::Row),
9750            when: None,
9751            when_paren: false,
9752            body: TriggerBody::Execute {
9753                function: TableRef::new(""),
9754                args: Vec::new(),
9755            },
9756            or_replace: false,
9757            or_alter: false,
9758            constraint: false,
9759            deferrable: None,
9760            initially_deferred: None,
9761            referencing: None,
9762        }
9763    }
9764}
9765
9766/// DROP TRIGGER statement
9767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9768#[cfg_attr(feature = "bindings", derive(TS))]
9769pub struct DropTrigger {
9770    pub name: Identifier,
9771    pub table: Option<TableRef>,
9772    pub if_exists: bool,
9773    pub cascade: bool,
9774}
9775
9776impl DropTrigger {
9777    pub fn new(name: impl Into<String>) -> Self {
9778        Self {
9779            name: Identifier::new(name),
9780            table: None,
9781            if_exists: false,
9782            cascade: false,
9783        }
9784    }
9785}
9786
9787/// CREATE TYPE statement
9788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9789#[cfg_attr(feature = "bindings", derive(TS))]
9790pub struct CreateType {
9791    pub name: TableRef,
9792    pub definition: TypeDefinition,
9793    pub if_not_exists: bool,
9794}
9795
9796/// Type definition
9797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9798#[cfg_attr(feature = "bindings", derive(TS))]
9799pub enum TypeDefinition {
9800    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
9801    Enum(Vec<String>),
9802    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
9803    Composite(Vec<TypeAttribute>),
9804    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
9805    Range {
9806        subtype: DataType,
9807        subtype_diff: Option<String>,
9808        canonical: Option<String>,
9809    },
9810    /// Base type (for advanced usage)
9811    Base {
9812        input: String,
9813        output: String,
9814        internallength: Option<i32>,
9815    },
9816    /// Domain type
9817    Domain {
9818        base_type: DataType,
9819        default: Option<Expression>,
9820        constraints: Vec<DomainConstraint>,
9821    },
9822}
9823
9824/// Type attribute for composite types
9825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9826#[cfg_attr(feature = "bindings", derive(TS))]
9827pub struct TypeAttribute {
9828    pub name: Identifier,
9829    pub data_type: DataType,
9830    pub collate: Option<Identifier>,
9831}
9832
9833/// Domain constraint
9834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9835#[cfg_attr(feature = "bindings", derive(TS))]
9836pub struct DomainConstraint {
9837    pub name: Option<Identifier>,
9838    pub check: Expression,
9839}
9840
9841impl CreateType {
9842    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
9843        Self {
9844            name: TableRef::new(name),
9845            definition: TypeDefinition::Enum(values),
9846            if_not_exists: false,
9847        }
9848    }
9849
9850    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
9851        Self {
9852            name: TableRef::new(name),
9853            definition: TypeDefinition::Composite(attributes),
9854            if_not_exists: false,
9855        }
9856    }
9857}
9858
9859/// DROP TYPE statement
9860#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9861#[cfg_attr(feature = "bindings", derive(TS))]
9862pub struct DropType {
9863    pub name: TableRef,
9864    pub if_exists: bool,
9865    pub cascade: bool,
9866}
9867
9868impl DropType {
9869    pub fn new(name: impl Into<String>) -> Self {
9870        Self {
9871            name: TableRef::new(name),
9872            if_exists: false,
9873            cascade: false,
9874        }
9875    }
9876}
9877
9878/// DESCRIBE statement - shows table structure or query plan
9879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9880#[cfg_attr(feature = "bindings", derive(TS))]
9881pub struct Describe {
9882    /// The target to describe (table name or query)
9883    pub target: Expression,
9884    /// EXTENDED format
9885    pub extended: bool,
9886    /// FORMATTED format
9887    pub formatted: bool,
9888    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
9889    #[serde(default)]
9890    pub kind: Option<String>,
9891    /// Properties like type=stage
9892    #[serde(default)]
9893    pub properties: Vec<(String, String)>,
9894    /// Style keyword (e.g., "ANALYZE", "HISTORY")
9895    #[serde(default, skip_serializing_if = "Option::is_none")]
9896    pub style: Option<String>,
9897    /// Partition specification for DESCRIBE PARTITION
9898    #[serde(default)]
9899    pub partition: Option<Box<Expression>>,
9900    /// Leading comments before the statement
9901    #[serde(default)]
9902    pub leading_comments: Vec<String>,
9903    /// AS JSON suffix (Databricks)
9904    #[serde(default)]
9905    pub as_json: bool,
9906    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
9907    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9908    pub params: Vec<String>,
9909}
9910
9911impl Describe {
9912    pub fn new(target: Expression) -> Self {
9913        Self {
9914            target,
9915            extended: false,
9916            formatted: false,
9917            kind: None,
9918            properties: Vec::new(),
9919            style: None,
9920            partition: None,
9921            leading_comments: Vec::new(),
9922            as_json: false,
9923            params: Vec::new(),
9924        }
9925    }
9926}
9927
9928/// SHOW statement - displays database objects
9929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9930#[cfg_attr(feature = "bindings", derive(TS))]
9931pub struct Show {
9932    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
9933    pub this: String,
9934    /// Whether TERSE was specified
9935    #[serde(default)]
9936    pub terse: bool,
9937    /// Whether HISTORY was specified
9938    #[serde(default)]
9939    pub history: bool,
9940    /// LIKE pattern
9941    pub like: Option<Expression>,
9942    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
9943    pub scope_kind: Option<String>,
9944    /// IN scope object
9945    pub scope: Option<Expression>,
9946    /// STARTS WITH pattern
9947    pub starts_with: Option<Expression>,
9948    /// LIMIT clause
9949    pub limit: Option<Box<Limit>>,
9950    /// FROM clause (for specific object)
9951    pub from: Option<Expression>,
9952    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
9953    #[serde(default, skip_serializing_if = "Option::is_none")]
9954    pub where_clause: Option<Expression>,
9955    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
9956    #[serde(default, skip_serializing_if = "Option::is_none")]
9957    pub for_target: Option<Expression>,
9958    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
9959    #[serde(default, skip_serializing_if = "Option::is_none")]
9960    pub db: Option<Expression>,
9961    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
9962    #[serde(default, skip_serializing_if = "Option::is_none")]
9963    pub target: Option<Expression>,
9964    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
9965    #[serde(default, skip_serializing_if = "Option::is_none")]
9966    pub mutex: Option<bool>,
9967    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
9968    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9969    pub privileges: Vec<String>,
9970}
9971
9972impl Show {
9973    pub fn new(this: impl Into<String>) -> Self {
9974        Self {
9975            this: this.into(),
9976            terse: false,
9977            history: false,
9978            like: None,
9979            scope_kind: None,
9980            scope: None,
9981            starts_with: None,
9982            limit: None,
9983            from: None,
9984            where_clause: None,
9985            for_target: None,
9986            db: None,
9987            target: None,
9988            mutex: None,
9989            privileges: Vec::new(),
9990        }
9991    }
9992}
9993
9994/// Represent an explicit parenthesized expression for grouping precedence.
9995///
9996/// Preserves user-written parentheses so that `(a + b) * c` round-trips
9997/// correctly instead of being flattened to `a + b * c`.
9998#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9999#[cfg_attr(feature = "bindings", derive(TS))]
10000pub struct Paren {
10001    /// The inner expression wrapped by parentheses.
10002    pub this: Expression,
10003    #[serde(default)]
10004    pub trailing_comments: Vec<String>,
10005}
10006
10007/// Expression annotated with trailing comments (for round-trip preservation)
10008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10009#[cfg_attr(feature = "bindings", derive(TS))]
10010pub struct Annotated {
10011    pub this: Expression,
10012    pub trailing_comments: Vec<String>,
10013}
10014
10015// === BATCH GENERATED STRUCT DEFINITIONS ===
10016// Generated from Python sqlglot expressions.py
10017
10018/// Refresh
10019#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10020#[cfg_attr(feature = "bindings", derive(TS))]
10021pub struct Refresh {
10022    pub this: Box<Expression>,
10023    pub kind: String,
10024}
10025
10026/// LockingStatement
10027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10028#[cfg_attr(feature = "bindings", derive(TS))]
10029pub struct LockingStatement {
10030    pub this: Box<Expression>,
10031    pub expression: Box<Expression>,
10032}
10033
10034/// SequenceProperties
10035#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10036#[cfg_attr(feature = "bindings", derive(TS))]
10037pub struct SequenceProperties {
10038    #[serde(default)]
10039    pub increment: Option<Box<Expression>>,
10040    #[serde(default)]
10041    pub minvalue: Option<Box<Expression>>,
10042    #[serde(default)]
10043    pub maxvalue: Option<Box<Expression>>,
10044    #[serde(default)]
10045    pub cache: Option<Box<Expression>>,
10046    #[serde(default)]
10047    pub start: Option<Box<Expression>>,
10048    #[serde(default)]
10049    pub owned: Option<Box<Expression>>,
10050    #[serde(default)]
10051    pub options: Vec<Expression>,
10052}
10053
10054/// TruncateTable
10055#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10056#[cfg_attr(feature = "bindings", derive(TS))]
10057pub struct TruncateTable {
10058    #[serde(default)]
10059    pub expressions: Vec<Expression>,
10060    #[serde(default)]
10061    pub is_database: Option<Box<Expression>>,
10062    #[serde(default)]
10063    pub exists: bool,
10064    #[serde(default)]
10065    pub only: Option<Box<Expression>>,
10066    #[serde(default)]
10067    pub cluster: Option<Box<Expression>>,
10068    #[serde(default)]
10069    pub identity: Option<Box<Expression>>,
10070    #[serde(default)]
10071    pub option: Option<Box<Expression>>,
10072    #[serde(default)]
10073    pub partition: Option<Box<Expression>>,
10074}
10075
10076/// Clone
10077#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10078#[cfg_attr(feature = "bindings", derive(TS))]
10079pub struct Clone {
10080    pub this: Box<Expression>,
10081    #[serde(default)]
10082    pub shallow: Option<Box<Expression>>,
10083    #[serde(default)]
10084    pub copy: Option<Box<Expression>>,
10085}
10086
10087/// Attach
10088#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10089#[cfg_attr(feature = "bindings", derive(TS))]
10090pub struct Attach {
10091    pub this: Box<Expression>,
10092    #[serde(default)]
10093    pub exists: bool,
10094    #[serde(default)]
10095    pub expressions: Vec<Expression>,
10096}
10097
10098/// Detach
10099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10100#[cfg_attr(feature = "bindings", derive(TS))]
10101pub struct Detach {
10102    pub this: Box<Expression>,
10103    #[serde(default)]
10104    pub exists: bool,
10105}
10106
10107/// Install
10108#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10109#[cfg_attr(feature = "bindings", derive(TS))]
10110pub struct Install {
10111    pub this: Box<Expression>,
10112    #[serde(default)]
10113    pub from_: Option<Box<Expression>>,
10114    #[serde(default)]
10115    pub force: Option<Box<Expression>>,
10116}
10117
10118/// Summarize
10119#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10120#[cfg_attr(feature = "bindings", derive(TS))]
10121pub struct Summarize {
10122    pub this: Box<Expression>,
10123    #[serde(default)]
10124    pub table: Option<Box<Expression>>,
10125}
10126
10127/// Declare
10128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10129#[cfg_attr(feature = "bindings", derive(TS))]
10130pub struct Declare {
10131    #[serde(default)]
10132    pub expressions: Vec<Expression>,
10133    #[serde(default)]
10134    pub replace: bool,
10135}
10136
10137/// DeclareItem
10138#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10139#[cfg_attr(feature = "bindings", derive(TS))]
10140pub struct DeclareItem {
10141    pub this: Box<Expression>,
10142    #[serde(default)]
10143    pub kind: Option<String>,
10144    #[serde(default)]
10145    pub default: Option<Box<Expression>>,
10146    #[serde(default)]
10147    pub has_as: bool,
10148    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10149    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10150    pub additional_names: Vec<Expression>,
10151}
10152
10153/// Set
10154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10155#[cfg_attr(feature = "bindings", derive(TS))]
10156pub struct Set {
10157    #[serde(default)]
10158    pub expressions: Vec<Expression>,
10159    #[serde(default)]
10160    pub unset: Option<Box<Expression>>,
10161    #[serde(default)]
10162    pub tag: Option<Box<Expression>>,
10163}
10164
10165/// Heredoc
10166#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10167#[cfg_attr(feature = "bindings", derive(TS))]
10168pub struct Heredoc {
10169    pub this: Box<Expression>,
10170    #[serde(default)]
10171    pub tag: Option<Box<Expression>>,
10172}
10173
10174/// QueryBand
10175#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10176#[cfg_attr(feature = "bindings", derive(TS))]
10177pub struct QueryBand {
10178    pub this: Box<Expression>,
10179    #[serde(default)]
10180    pub scope: Option<Box<Expression>>,
10181    #[serde(default)]
10182    pub update: Option<Box<Expression>>,
10183}
10184
10185/// UserDefinedFunction
10186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10187#[cfg_attr(feature = "bindings", derive(TS))]
10188pub struct UserDefinedFunction {
10189    pub this: Box<Expression>,
10190    #[serde(default)]
10191    pub expressions: Vec<Expression>,
10192    #[serde(default)]
10193    pub wrapped: Option<Box<Expression>>,
10194}
10195
10196/// RecursiveWithSearch
10197#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10198#[cfg_attr(feature = "bindings", derive(TS))]
10199pub struct RecursiveWithSearch {
10200    pub kind: String,
10201    pub this: Box<Expression>,
10202    pub expression: Box<Expression>,
10203    #[serde(default)]
10204    pub using: Option<Box<Expression>>,
10205}
10206
10207/// ProjectionDef
10208#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10209#[cfg_attr(feature = "bindings", derive(TS))]
10210pub struct ProjectionDef {
10211    pub this: Box<Expression>,
10212    pub expression: Box<Expression>,
10213}
10214
10215/// TableAlias
10216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10217#[cfg_attr(feature = "bindings", derive(TS))]
10218pub struct TableAlias {
10219    #[serde(default)]
10220    pub this: Option<Box<Expression>>,
10221    #[serde(default)]
10222    pub columns: Vec<Expression>,
10223}
10224
10225/// ByteString
10226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10227#[cfg_attr(feature = "bindings", derive(TS))]
10228pub struct ByteString {
10229    pub this: Box<Expression>,
10230    #[serde(default)]
10231    pub is_bytes: Option<Box<Expression>>,
10232}
10233
10234/// HexStringExpr - Hex string expression (not literal)
10235/// BigQuery: converts to FROM_HEX(this)
10236#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10237#[cfg_attr(feature = "bindings", derive(TS))]
10238pub struct HexStringExpr {
10239    pub this: Box<Expression>,
10240    #[serde(default)]
10241    pub is_integer: Option<bool>,
10242}
10243
10244/// UnicodeString
10245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10246#[cfg_attr(feature = "bindings", derive(TS))]
10247pub struct UnicodeString {
10248    pub this: Box<Expression>,
10249    #[serde(default)]
10250    pub escape: Option<Box<Expression>>,
10251}
10252
10253/// AlterColumn
10254#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10255#[cfg_attr(feature = "bindings", derive(TS))]
10256pub struct AlterColumn {
10257    pub this: Box<Expression>,
10258    #[serde(default)]
10259    pub dtype: Option<Box<Expression>>,
10260    #[serde(default)]
10261    pub collate: Option<Box<Expression>>,
10262    #[serde(default)]
10263    pub using: Option<Box<Expression>>,
10264    #[serde(default)]
10265    pub default: Option<Box<Expression>>,
10266    #[serde(default)]
10267    pub drop: Option<Box<Expression>>,
10268    #[serde(default)]
10269    pub comment: Option<Box<Expression>>,
10270    #[serde(default)]
10271    pub allow_null: Option<Box<Expression>>,
10272    #[serde(default)]
10273    pub visible: Option<Box<Expression>>,
10274    #[serde(default)]
10275    pub rename_to: Option<Box<Expression>>,
10276}
10277
10278/// AlterSortKey
10279#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10280#[cfg_attr(feature = "bindings", derive(TS))]
10281pub struct AlterSortKey {
10282    #[serde(default)]
10283    pub this: Option<Box<Expression>>,
10284    #[serde(default)]
10285    pub expressions: Vec<Expression>,
10286    #[serde(default)]
10287    pub compound: Option<Box<Expression>>,
10288}
10289
10290/// AlterSet
10291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10292#[cfg_attr(feature = "bindings", derive(TS))]
10293pub struct AlterSet {
10294    #[serde(default)]
10295    pub expressions: Vec<Expression>,
10296    #[serde(default)]
10297    pub option: Option<Box<Expression>>,
10298    #[serde(default)]
10299    pub tablespace: Option<Box<Expression>>,
10300    #[serde(default)]
10301    pub access_method: Option<Box<Expression>>,
10302    #[serde(default)]
10303    pub file_format: Option<Box<Expression>>,
10304    #[serde(default)]
10305    pub copy_options: Option<Box<Expression>>,
10306    #[serde(default)]
10307    pub tag: Option<Box<Expression>>,
10308    #[serde(default)]
10309    pub location: Option<Box<Expression>>,
10310    #[serde(default)]
10311    pub serde: Option<Box<Expression>>,
10312}
10313
10314/// RenameColumn
10315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10316#[cfg_attr(feature = "bindings", derive(TS))]
10317pub struct RenameColumn {
10318    pub this: Box<Expression>,
10319    #[serde(default)]
10320    pub to: Option<Box<Expression>>,
10321    #[serde(default)]
10322    pub exists: bool,
10323}
10324
10325/// Comprehension
10326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10327#[cfg_attr(feature = "bindings", derive(TS))]
10328pub struct Comprehension {
10329    pub this: Box<Expression>,
10330    pub expression: Box<Expression>,
10331    #[serde(default)]
10332    pub position: Option<Box<Expression>>,
10333    #[serde(default)]
10334    pub iterator: Option<Box<Expression>>,
10335    #[serde(default)]
10336    pub condition: Option<Box<Expression>>,
10337}
10338
10339/// MergeTreeTTLAction
10340#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10341#[cfg_attr(feature = "bindings", derive(TS))]
10342pub struct MergeTreeTTLAction {
10343    pub this: Box<Expression>,
10344    #[serde(default)]
10345    pub delete: Option<Box<Expression>>,
10346    #[serde(default)]
10347    pub recompress: Option<Box<Expression>>,
10348    #[serde(default)]
10349    pub to_disk: Option<Box<Expression>>,
10350    #[serde(default)]
10351    pub to_volume: Option<Box<Expression>>,
10352}
10353
10354/// MergeTreeTTL
10355#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10356#[cfg_attr(feature = "bindings", derive(TS))]
10357pub struct MergeTreeTTL {
10358    #[serde(default)]
10359    pub expressions: Vec<Expression>,
10360    #[serde(default)]
10361    pub where_: Option<Box<Expression>>,
10362    #[serde(default)]
10363    pub group: Option<Box<Expression>>,
10364    #[serde(default)]
10365    pub aggregates: Option<Box<Expression>>,
10366}
10367
10368/// IndexConstraintOption
10369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10370#[cfg_attr(feature = "bindings", derive(TS))]
10371pub struct IndexConstraintOption {
10372    #[serde(default)]
10373    pub key_block_size: Option<Box<Expression>>,
10374    #[serde(default)]
10375    pub using: Option<Box<Expression>>,
10376    #[serde(default)]
10377    pub parser: Option<Box<Expression>>,
10378    #[serde(default)]
10379    pub comment: Option<Box<Expression>>,
10380    #[serde(default)]
10381    pub visible: Option<Box<Expression>>,
10382    #[serde(default)]
10383    pub engine_attr: Option<Box<Expression>>,
10384    #[serde(default)]
10385    pub secondary_engine_attr: Option<Box<Expression>>,
10386}
10387
10388/// PeriodForSystemTimeConstraint
10389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10390#[cfg_attr(feature = "bindings", derive(TS))]
10391pub struct PeriodForSystemTimeConstraint {
10392    pub this: Box<Expression>,
10393    pub expression: Box<Expression>,
10394}
10395
10396/// CaseSpecificColumnConstraint
10397#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10398#[cfg_attr(feature = "bindings", derive(TS))]
10399pub struct CaseSpecificColumnConstraint {
10400    #[serde(default)]
10401    pub not_: Option<Box<Expression>>,
10402}
10403
10404/// CharacterSetColumnConstraint
10405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10406#[cfg_attr(feature = "bindings", derive(TS))]
10407pub struct CharacterSetColumnConstraint {
10408    pub this: Box<Expression>,
10409}
10410
10411/// CheckColumnConstraint
10412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10413#[cfg_attr(feature = "bindings", derive(TS))]
10414pub struct CheckColumnConstraint {
10415    pub this: Box<Expression>,
10416    #[serde(default)]
10417    pub enforced: Option<Box<Expression>>,
10418}
10419
10420/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
10421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10422#[cfg_attr(feature = "bindings", derive(TS))]
10423pub struct AssumeColumnConstraint {
10424    pub this: Box<Expression>,
10425}
10426
10427/// CompressColumnConstraint
10428#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10429#[cfg_attr(feature = "bindings", derive(TS))]
10430pub struct CompressColumnConstraint {
10431    #[serde(default)]
10432    pub this: Option<Box<Expression>>,
10433}
10434
10435/// DateFormatColumnConstraint
10436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10437#[cfg_attr(feature = "bindings", derive(TS))]
10438pub struct DateFormatColumnConstraint {
10439    pub this: Box<Expression>,
10440}
10441
10442/// EphemeralColumnConstraint
10443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10444#[cfg_attr(feature = "bindings", derive(TS))]
10445pub struct EphemeralColumnConstraint {
10446    #[serde(default)]
10447    pub this: Option<Box<Expression>>,
10448}
10449
10450/// WithOperator
10451#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10452#[cfg_attr(feature = "bindings", derive(TS))]
10453pub struct WithOperator {
10454    pub this: Box<Expression>,
10455    pub op: String,
10456}
10457
10458/// GeneratedAsIdentityColumnConstraint
10459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10460#[cfg_attr(feature = "bindings", derive(TS))]
10461pub struct GeneratedAsIdentityColumnConstraint {
10462    #[serde(default)]
10463    pub this: Option<Box<Expression>>,
10464    #[serde(default)]
10465    pub expression: Option<Box<Expression>>,
10466    #[serde(default)]
10467    pub on_null: Option<Box<Expression>>,
10468    #[serde(default)]
10469    pub start: Option<Box<Expression>>,
10470    #[serde(default)]
10471    pub increment: Option<Box<Expression>>,
10472    #[serde(default)]
10473    pub minvalue: Option<Box<Expression>>,
10474    #[serde(default)]
10475    pub maxvalue: Option<Box<Expression>>,
10476    #[serde(default)]
10477    pub cycle: Option<Box<Expression>>,
10478    #[serde(default)]
10479    pub order: Option<Box<Expression>>,
10480}
10481
10482/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
10483/// TSQL: outputs "IDENTITY"
10484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10485#[cfg_attr(feature = "bindings", derive(TS))]
10486pub struct AutoIncrementColumnConstraint;
10487
10488/// CommentColumnConstraint - Column comment marker
10489#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10490#[cfg_attr(feature = "bindings", derive(TS))]
10491pub struct CommentColumnConstraint;
10492
10493/// GeneratedAsRowColumnConstraint
10494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10495#[cfg_attr(feature = "bindings", derive(TS))]
10496pub struct GeneratedAsRowColumnConstraint {
10497    #[serde(default)]
10498    pub start: Option<Box<Expression>>,
10499    #[serde(default)]
10500    pub hidden: Option<Box<Expression>>,
10501}
10502
10503/// IndexColumnConstraint
10504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10505#[cfg_attr(feature = "bindings", derive(TS))]
10506pub struct IndexColumnConstraint {
10507    #[serde(default)]
10508    pub this: Option<Box<Expression>>,
10509    #[serde(default)]
10510    pub expressions: Vec<Expression>,
10511    #[serde(default)]
10512    pub kind: Option<String>,
10513    #[serde(default)]
10514    pub index_type: Option<Box<Expression>>,
10515    #[serde(default)]
10516    pub options: Vec<Expression>,
10517    #[serde(default)]
10518    pub expression: Option<Box<Expression>>,
10519    #[serde(default)]
10520    pub granularity: Option<Box<Expression>>,
10521}
10522
10523/// MaskingPolicyColumnConstraint
10524#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10525#[cfg_attr(feature = "bindings", derive(TS))]
10526pub struct MaskingPolicyColumnConstraint {
10527    pub this: Box<Expression>,
10528    #[serde(default)]
10529    pub expressions: Vec<Expression>,
10530}
10531
10532/// NotNullColumnConstraint
10533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10534#[cfg_attr(feature = "bindings", derive(TS))]
10535pub struct NotNullColumnConstraint {
10536    #[serde(default)]
10537    pub allow_null: Option<Box<Expression>>,
10538}
10539
10540/// DefaultColumnConstraint - DEFAULT value for a column
10541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10542#[cfg_attr(feature = "bindings", derive(TS))]
10543pub struct DefaultColumnConstraint {
10544    pub this: Box<Expression>,
10545    /// TSQL: DEFAULT value FOR column (table-level default constraint)
10546    #[serde(default, skip_serializing_if = "Option::is_none")]
10547    pub for_column: Option<Identifier>,
10548}
10549
10550/// PrimaryKeyColumnConstraint
10551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10552#[cfg_attr(feature = "bindings", derive(TS))]
10553pub struct PrimaryKeyColumnConstraint {
10554    #[serde(default)]
10555    pub desc: Option<Box<Expression>>,
10556    #[serde(default)]
10557    pub options: Vec<Expression>,
10558}
10559
10560/// UniqueColumnConstraint
10561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10562#[cfg_attr(feature = "bindings", derive(TS))]
10563pub struct UniqueColumnConstraint {
10564    #[serde(default)]
10565    pub this: Option<Box<Expression>>,
10566    #[serde(default)]
10567    pub index_type: Option<Box<Expression>>,
10568    #[serde(default)]
10569    pub on_conflict: Option<Box<Expression>>,
10570    #[serde(default)]
10571    pub nulls: Option<Box<Expression>>,
10572    #[serde(default)]
10573    pub options: Vec<Expression>,
10574}
10575
10576/// WatermarkColumnConstraint
10577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10578#[cfg_attr(feature = "bindings", derive(TS))]
10579pub struct WatermarkColumnConstraint {
10580    pub this: Box<Expression>,
10581    pub expression: Box<Expression>,
10582}
10583
10584/// ComputedColumnConstraint
10585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10586#[cfg_attr(feature = "bindings", derive(TS))]
10587pub struct ComputedColumnConstraint {
10588    pub this: Box<Expression>,
10589    #[serde(default)]
10590    pub persisted: Option<Box<Expression>>,
10591    #[serde(default)]
10592    pub not_null: Option<Box<Expression>>,
10593    #[serde(default)]
10594    pub data_type: Option<Box<Expression>>,
10595}
10596
10597/// InOutColumnConstraint
10598#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10599#[cfg_attr(feature = "bindings", derive(TS))]
10600pub struct InOutColumnConstraint {
10601    #[serde(default)]
10602    pub input_: Option<Box<Expression>>,
10603    #[serde(default)]
10604    pub output: Option<Box<Expression>>,
10605}
10606
10607/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
10608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10609#[cfg_attr(feature = "bindings", derive(TS))]
10610pub struct PathColumnConstraint {
10611    pub this: Box<Expression>,
10612}
10613
10614/// Constraint
10615#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10616#[cfg_attr(feature = "bindings", derive(TS))]
10617pub struct Constraint {
10618    pub this: Box<Expression>,
10619    #[serde(default)]
10620    pub expressions: Vec<Expression>,
10621}
10622
10623/// Export
10624#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10625#[cfg_attr(feature = "bindings", derive(TS))]
10626pub struct Export {
10627    pub this: Box<Expression>,
10628    #[serde(default)]
10629    pub connection: Option<Box<Expression>>,
10630    #[serde(default)]
10631    pub options: Vec<Expression>,
10632}
10633
10634/// Filter
10635#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10636#[cfg_attr(feature = "bindings", derive(TS))]
10637pub struct Filter {
10638    pub this: Box<Expression>,
10639    pub expression: Box<Expression>,
10640}
10641
10642/// Changes
10643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10644#[cfg_attr(feature = "bindings", derive(TS))]
10645pub struct Changes {
10646    #[serde(default)]
10647    pub information: Option<Box<Expression>>,
10648    #[serde(default)]
10649    pub at_before: Option<Box<Expression>>,
10650    #[serde(default)]
10651    pub end: Option<Box<Expression>>,
10652}
10653
10654/// Directory
10655#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10656#[cfg_attr(feature = "bindings", derive(TS))]
10657pub struct Directory {
10658    pub this: Box<Expression>,
10659    #[serde(default)]
10660    pub local: Option<Box<Expression>>,
10661    #[serde(default)]
10662    pub row_format: Option<Box<Expression>>,
10663}
10664
10665/// ForeignKey
10666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10667#[cfg_attr(feature = "bindings", derive(TS))]
10668pub struct ForeignKey {
10669    #[serde(default)]
10670    pub expressions: Vec<Expression>,
10671    #[serde(default)]
10672    pub reference: Option<Box<Expression>>,
10673    #[serde(default)]
10674    pub delete: Option<Box<Expression>>,
10675    #[serde(default)]
10676    pub update: Option<Box<Expression>>,
10677    #[serde(default)]
10678    pub options: Vec<Expression>,
10679}
10680
10681/// ColumnPrefix
10682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10683#[cfg_attr(feature = "bindings", derive(TS))]
10684pub struct ColumnPrefix {
10685    pub this: Box<Expression>,
10686    pub expression: Box<Expression>,
10687}
10688
10689/// PrimaryKey
10690#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10691#[cfg_attr(feature = "bindings", derive(TS))]
10692pub struct PrimaryKey {
10693    #[serde(default)]
10694    pub this: Option<Box<Expression>>,
10695    #[serde(default)]
10696    pub expressions: Vec<Expression>,
10697    #[serde(default)]
10698    pub options: Vec<Expression>,
10699    #[serde(default)]
10700    pub include: Option<Box<Expression>>,
10701}
10702
10703/// Into
10704#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10705#[cfg_attr(feature = "bindings", derive(TS))]
10706pub struct IntoClause {
10707    #[serde(default)]
10708    pub this: Option<Box<Expression>>,
10709    #[serde(default)]
10710    pub temporary: bool,
10711    #[serde(default)]
10712    pub unlogged: Option<Box<Expression>>,
10713    #[serde(default)]
10714    pub bulk_collect: Option<Box<Expression>>,
10715    #[serde(default)]
10716    pub expressions: Vec<Expression>,
10717}
10718
10719/// JoinHint
10720#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10721#[cfg_attr(feature = "bindings", derive(TS))]
10722pub struct JoinHint {
10723    pub this: Box<Expression>,
10724    #[serde(default)]
10725    pub expressions: Vec<Expression>,
10726}
10727
10728/// Opclass
10729#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10730#[cfg_attr(feature = "bindings", derive(TS))]
10731pub struct Opclass {
10732    pub this: Box<Expression>,
10733    pub expression: Box<Expression>,
10734}
10735
10736/// Index
10737#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10738#[cfg_attr(feature = "bindings", derive(TS))]
10739pub struct Index {
10740    #[serde(default)]
10741    pub this: Option<Box<Expression>>,
10742    #[serde(default)]
10743    pub table: Option<Box<Expression>>,
10744    #[serde(default)]
10745    pub unique: bool,
10746    #[serde(default)]
10747    pub primary: Option<Box<Expression>>,
10748    #[serde(default)]
10749    pub amp: Option<Box<Expression>>,
10750    #[serde(default)]
10751    pub params: Vec<Expression>,
10752}
10753
10754/// IndexParameters
10755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10756#[cfg_attr(feature = "bindings", derive(TS))]
10757pub struct IndexParameters {
10758    #[serde(default)]
10759    pub using: Option<Box<Expression>>,
10760    #[serde(default)]
10761    pub include: Option<Box<Expression>>,
10762    #[serde(default)]
10763    pub columns: Vec<Expression>,
10764    #[serde(default)]
10765    pub with_storage: Option<Box<Expression>>,
10766    #[serde(default)]
10767    pub partition_by: Option<Box<Expression>>,
10768    #[serde(default)]
10769    pub tablespace: Option<Box<Expression>>,
10770    #[serde(default)]
10771    pub where_: Option<Box<Expression>>,
10772    #[serde(default)]
10773    pub on: Option<Box<Expression>>,
10774}
10775
10776/// ConditionalInsert
10777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10778#[cfg_attr(feature = "bindings", derive(TS))]
10779pub struct ConditionalInsert {
10780    pub this: Box<Expression>,
10781    #[serde(default)]
10782    pub expression: Option<Box<Expression>>,
10783    #[serde(default)]
10784    pub else_: Option<Box<Expression>>,
10785}
10786
10787/// MultitableInserts
10788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10789#[cfg_attr(feature = "bindings", derive(TS))]
10790pub struct MultitableInserts {
10791    #[serde(default)]
10792    pub expressions: Vec<Expression>,
10793    pub kind: String,
10794    #[serde(default)]
10795    pub source: Option<Box<Expression>>,
10796    /// Leading comments before the statement
10797    #[serde(default)]
10798    pub leading_comments: Vec<String>,
10799    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
10800    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10801    pub overwrite: bool,
10802}
10803
10804/// OnConflict
10805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10806#[cfg_attr(feature = "bindings", derive(TS))]
10807pub struct OnConflict {
10808    #[serde(default)]
10809    pub duplicate: Option<Box<Expression>>,
10810    #[serde(default)]
10811    pub expressions: Vec<Expression>,
10812    #[serde(default)]
10813    pub action: Option<Box<Expression>>,
10814    #[serde(default)]
10815    pub conflict_keys: Option<Box<Expression>>,
10816    #[serde(default)]
10817    pub index_predicate: Option<Box<Expression>>,
10818    #[serde(default)]
10819    pub constraint: Option<Box<Expression>>,
10820    #[serde(default)]
10821    pub where_: Option<Box<Expression>>,
10822}
10823
10824/// OnCondition
10825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10826#[cfg_attr(feature = "bindings", derive(TS))]
10827pub struct OnCondition {
10828    #[serde(default)]
10829    pub error: Option<Box<Expression>>,
10830    #[serde(default)]
10831    pub empty: Option<Box<Expression>>,
10832    #[serde(default)]
10833    pub null: Option<Box<Expression>>,
10834}
10835
10836/// Returning
10837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10838#[cfg_attr(feature = "bindings", derive(TS))]
10839pub struct Returning {
10840    #[serde(default)]
10841    pub expressions: Vec<Expression>,
10842    #[serde(default)]
10843    pub into: Option<Box<Expression>>,
10844}
10845
10846/// Introducer
10847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10848#[cfg_attr(feature = "bindings", derive(TS))]
10849pub struct Introducer {
10850    pub this: Box<Expression>,
10851    pub expression: Box<Expression>,
10852}
10853
10854/// PartitionRange
10855#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10856#[cfg_attr(feature = "bindings", derive(TS))]
10857pub struct PartitionRange {
10858    pub this: Box<Expression>,
10859    #[serde(default)]
10860    pub expression: Option<Box<Expression>>,
10861    #[serde(default)]
10862    pub expressions: Vec<Expression>,
10863}
10864
10865/// Group
10866#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10867#[cfg_attr(feature = "bindings", derive(TS))]
10868pub struct Group {
10869    #[serde(default)]
10870    pub expressions: Vec<Expression>,
10871    #[serde(default)]
10872    pub grouping_sets: Option<Box<Expression>>,
10873    #[serde(default)]
10874    pub cube: Option<Box<Expression>>,
10875    #[serde(default)]
10876    pub rollup: Option<Box<Expression>>,
10877    #[serde(default)]
10878    pub totals: Option<Box<Expression>>,
10879    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
10880    #[serde(default)]
10881    pub all: Option<bool>,
10882}
10883
10884/// Cube
10885#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10886#[cfg_attr(feature = "bindings", derive(TS))]
10887pub struct Cube {
10888    #[serde(default)]
10889    pub expressions: Vec<Expression>,
10890}
10891
10892/// Rollup
10893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10894#[cfg_attr(feature = "bindings", derive(TS))]
10895pub struct Rollup {
10896    #[serde(default)]
10897    pub expressions: Vec<Expression>,
10898}
10899
10900/// GroupingSets
10901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10902#[cfg_attr(feature = "bindings", derive(TS))]
10903pub struct GroupingSets {
10904    #[serde(default)]
10905    pub expressions: Vec<Expression>,
10906}
10907
10908/// LimitOptions
10909#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10910#[cfg_attr(feature = "bindings", derive(TS))]
10911pub struct LimitOptions {
10912    #[serde(default)]
10913    pub percent: Option<Box<Expression>>,
10914    #[serde(default)]
10915    pub rows: Option<Box<Expression>>,
10916    #[serde(default)]
10917    pub with_ties: Option<Box<Expression>>,
10918}
10919
10920/// Lateral
10921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10922#[cfg_attr(feature = "bindings", derive(TS))]
10923pub struct Lateral {
10924    pub this: Box<Expression>,
10925    #[serde(default)]
10926    pub view: Option<Box<Expression>>,
10927    #[serde(default)]
10928    pub outer: Option<Box<Expression>>,
10929    #[serde(default)]
10930    pub alias: Option<String>,
10931    /// Whether the alias was originally quoted (backtick/double-quote)
10932    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10933    pub alias_quoted: bool,
10934    #[serde(default)]
10935    pub cross_apply: Option<Box<Expression>>,
10936    #[serde(default)]
10937    pub ordinality: Option<Box<Expression>>,
10938    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
10939    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10940    pub column_aliases: Vec<String>,
10941}
10942
10943/// TableFromRows
10944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10945#[cfg_attr(feature = "bindings", derive(TS))]
10946pub struct TableFromRows {
10947    pub this: Box<Expression>,
10948    #[serde(default)]
10949    pub alias: Option<String>,
10950    #[serde(default)]
10951    pub joins: Vec<Expression>,
10952    #[serde(default)]
10953    pub pivots: Option<Box<Expression>>,
10954    #[serde(default)]
10955    pub sample: Option<Box<Expression>>,
10956}
10957
10958/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
10959/// Used for set-returning functions with typed column definitions
10960#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10961#[cfg_attr(feature = "bindings", derive(TS))]
10962pub struct RowsFrom {
10963    /// List of function expressions, each potentially with an alias and typed columns
10964    pub expressions: Vec<Expression>,
10965    /// WITH ORDINALITY modifier
10966    #[serde(default)]
10967    pub ordinality: bool,
10968    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
10969    #[serde(default)]
10970    pub alias: Option<Box<Expression>>,
10971}
10972
10973/// WithFill
10974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10975#[cfg_attr(feature = "bindings", derive(TS))]
10976pub struct WithFill {
10977    #[serde(default)]
10978    pub from_: Option<Box<Expression>>,
10979    #[serde(default)]
10980    pub to: Option<Box<Expression>>,
10981    #[serde(default)]
10982    pub step: Option<Box<Expression>>,
10983    #[serde(default)]
10984    pub staleness: Option<Box<Expression>>,
10985    #[serde(default)]
10986    pub interpolate: Option<Box<Expression>>,
10987}
10988
10989/// Property
10990#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10991#[cfg_attr(feature = "bindings", derive(TS))]
10992pub struct Property {
10993    pub this: Box<Expression>,
10994    #[serde(default)]
10995    pub value: Option<Box<Expression>>,
10996}
10997
10998/// GrantPrivilege
10999#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11000#[cfg_attr(feature = "bindings", derive(TS))]
11001pub struct GrantPrivilege {
11002    pub this: Box<Expression>,
11003    #[serde(default)]
11004    pub expressions: Vec<Expression>,
11005}
11006
11007/// AllowedValuesProperty
11008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11009#[cfg_attr(feature = "bindings", derive(TS))]
11010pub struct AllowedValuesProperty {
11011    #[serde(default)]
11012    pub expressions: Vec<Expression>,
11013}
11014
11015/// AlgorithmProperty
11016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11017#[cfg_attr(feature = "bindings", derive(TS))]
11018pub struct AlgorithmProperty {
11019    pub this: Box<Expression>,
11020}
11021
11022/// AutoIncrementProperty
11023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11024#[cfg_attr(feature = "bindings", derive(TS))]
11025pub struct AutoIncrementProperty {
11026    pub this: Box<Expression>,
11027}
11028
11029/// AutoRefreshProperty
11030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11031#[cfg_attr(feature = "bindings", derive(TS))]
11032pub struct AutoRefreshProperty {
11033    pub this: Box<Expression>,
11034}
11035
11036/// BackupProperty
11037#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11038#[cfg_attr(feature = "bindings", derive(TS))]
11039pub struct BackupProperty {
11040    pub this: Box<Expression>,
11041}
11042
11043/// BuildProperty
11044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11045#[cfg_attr(feature = "bindings", derive(TS))]
11046pub struct BuildProperty {
11047    pub this: Box<Expression>,
11048}
11049
11050/// BlockCompressionProperty
11051#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11052#[cfg_attr(feature = "bindings", derive(TS))]
11053pub struct BlockCompressionProperty {
11054    #[serde(default)]
11055    pub autotemp: Option<Box<Expression>>,
11056    #[serde(default)]
11057    pub always: Option<Box<Expression>>,
11058    #[serde(default)]
11059    pub default: Option<Box<Expression>>,
11060    #[serde(default)]
11061    pub manual: Option<Box<Expression>>,
11062    #[serde(default)]
11063    pub never: Option<Box<Expression>>,
11064}
11065
11066/// CharacterSetProperty
11067#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11068#[cfg_attr(feature = "bindings", derive(TS))]
11069pub struct CharacterSetProperty {
11070    pub this: Box<Expression>,
11071    #[serde(default)]
11072    pub default: Option<Box<Expression>>,
11073}
11074
11075/// ChecksumProperty
11076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11077#[cfg_attr(feature = "bindings", derive(TS))]
11078pub struct ChecksumProperty {
11079    #[serde(default)]
11080    pub on: Option<Box<Expression>>,
11081    #[serde(default)]
11082    pub default: Option<Box<Expression>>,
11083}
11084
11085/// CollateProperty
11086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11087#[cfg_attr(feature = "bindings", derive(TS))]
11088pub struct CollateProperty {
11089    pub this: Box<Expression>,
11090    #[serde(default)]
11091    pub default: Option<Box<Expression>>,
11092}
11093
11094/// DataBlocksizeProperty
11095#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11096#[cfg_attr(feature = "bindings", derive(TS))]
11097pub struct DataBlocksizeProperty {
11098    #[serde(default)]
11099    pub size: Option<i64>,
11100    #[serde(default)]
11101    pub units: Option<Box<Expression>>,
11102    #[serde(default)]
11103    pub minimum: Option<Box<Expression>>,
11104    #[serde(default)]
11105    pub maximum: Option<Box<Expression>>,
11106    #[serde(default)]
11107    pub default: Option<Box<Expression>>,
11108}
11109
11110/// DataDeletionProperty
11111#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11112#[cfg_attr(feature = "bindings", derive(TS))]
11113pub struct DataDeletionProperty {
11114    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11115    #[ast(skip)]
11116    pub on: Box<Expression>,
11117    #[serde(default)]
11118    pub filter_column: Option<Box<Expression>>,
11119    #[serde(default)]
11120    pub retention_period: Option<Box<Expression>>,
11121}
11122
11123/// DefinerProperty
11124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11125#[cfg_attr(feature = "bindings", derive(TS))]
11126pub struct DefinerProperty {
11127    pub this: Box<Expression>,
11128}
11129
11130/// DistKeyProperty
11131#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11132#[cfg_attr(feature = "bindings", derive(TS))]
11133pub struct DistKeyProperty {
11134    pub this: Box<Expression>,
11135}
11136
11137/// DistributedByProperty
11138#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11139#[cfg_attr(feature = "bindings", derive(TS))]
11140pub struct DistributedByProperty {
11141    #[serde(default)]
11142    pub expressions: Vec<Expression>,
11143    pub kind: String,
11144    #[serde(default)]
11145    pub buckets: Option<Box<Expression>>,
11146    #[serde(default)]
11147    pub order: Option<Box<Expression>>,
11148}
11149
11150/// DistStyleProperty
11151#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11152#[cfg_attr(feature = "bindings", derive(TS))]
11153pub struct DistStyleProperty {
11154    pub this: Box<Expression>,
11155}
11156
11157/// DuplicateKeyProperty
11158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11159#[cfg_attr(feature = "bindings", derive(TS))]
11160pub struct DuplicateKeyProperty {
11161    #[serde(default)]
11162    pub expressions: Vec<Expression>,
11163}
11164
11165/// EngineProperty
11166#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11167#[cfg_attr(feature = "bindings", derive(TS))]
11168pub struct EngineProperty {
11169    pub this: Box<Expression>,
11170}
11171
11172/// ToTableProperty
11173#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11174#[cfg_attr(feature = "bindings", derive(TS))]
11175pub struct ToTableProperty {
11176    pub this: Box<Expression>,
11177}
11178
11179/// ExecuteAsProperty
11180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11181#[cfg_attr(feature = "bindings", derive(TS))]
11182pub struct ExecuteAsProperty {
11183    pub this: Box<Expression>,
11184}
11185
11186/// ExternalProperty
11187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11188#[cfg_attr(feature = "bindings", derive(TS))]
11189pub struct ExternalProperty {
11190    #[serde(default)]
11191    pub this: Option<Box<Expression>>,
11192}
11193
11194/// FallbackProperty
11195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11196#[cfg_attr(feature = "bindings", derive(TS))]
11197pub struct FallbackProperty {
11198    #[serde(default)]
11199    pub no: Option<Box<Expression>>,
11200    #[serde(default)]
11201    pub protection: Option<Box<Expression>>,
11202}
11203
11204/// FileFormatProperty
11205#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11206#[cfg_attr(feature = "bindings", derive(TS))]
11207pub struct FileFormatProperty {
11208    #[serde(default)]
11209    pub this: Option<Box<Expression>>,
11210    #[serde(default)]
11211    pub expressions: Vec<Expression>,
11212    #[serde(default)]
11213    pub hive_format: Option<Box<Expression>>,
11214}
11215
11216/// CredentialsProperty
11217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11218#[cfg_attr(feature = "bindings", derive(TS))]
11219pub struct CredentialsProperty {
11220    #[serde(default)]
11221    pub expressions: Vec<Expression>,
11222}
11223
11224/// FreespaceProperty
11225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11226#[cfg_attr(feature = "bindings", derive(TS))]
11227pub struct FreespaceProperty {
11228    pub this: Box<Expression>,
11229    #[serde(default)]
11230    pub percent: Option<Box<Expression>>,
11231}
11232
11233/// InheritsProperty
11234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11235#[cfg_attr(feature = "bindings", derive(TS))]
11236pub struct InheritsProperty {
11237    #[serde(default)]
11238    pub expressions: Vec<Expression>,
11239}
11240
11241/// InputModelProperty
11242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11243#[cfg_attr(feature = "bindings", derive(TS))]
11244pub struct InputModelProperty {
11245    pub this: Box<Expression>,
11246}
11247
11248/// OutputModelProperty
11249#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11250#[cfg_attr(feature = "bindings", derive(TS))]
11251pub struct OutputModelProperty {
11252    pub this: Box<Expression>,
11253}
11254
11255/// IsolatedLoadingProperty
11256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11257#[cfg_attr(feature = "bindings", derive(TS))]
11258pub struct IsolatedLoadingProperty {
11259    #[serde(default)]
11260    pub no: Option<Box<Expression>>,
11261    #[serde(default)]
11262    pub concurrent: Option<Box<Expression>>,
11263    #[serde(default)]
11264    pub target: Option<Box<Expression>>,
11265}
11266
11267/// JournalProperty
11268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11269#[cfg_attr(feature = "bindings", derive(TS))]
11270pub struct JournalProperty {
11271    #[serde(default)]
11272    pub no: Option<Box<Expression>>,
11273    #[serde(default)]
11274    pub dual: Option<Box<Expression>>,
11275    #[serde(default)]
11276    pub before: Option<Box<Expression>>,
11277    #[serde(default)]
11278    pub local: Option<Box<Expression>>,
11279    #[serde(default)]
11280    pub after: Option<Box<Expression>>,
11281}
11282
11283/// LanguageProperty
11284#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11285#[cfg_attr(feature = "bindings", derive(TS))]
11286pub struct LanguageProperty {
11287    pub this: Box<Expression>,
11288}
11289
11290/// EnviromentProperty
11291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11292#[cfg_attr(feature = "bindings", derive(TS))]
11293pub struct EnviromentProperty {
11294    #[serde(default)]
11295    pub expressions: Vec<Expression>,
11296}
11297
11298/// ClusteredByProperty
11299#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11300#[cfg_attr(feature = "bindings", derive(TS))]
11301pub struct ClusteredByProperty {
11302    #[serde(default)]
11303    pub expressions: Vec<Expression>,
11304    #[serde(default)]
11305    pub sorted_by: Option<Box<Expression>>,
11306    #[serde(default)]
11307    pub buckets: Option<Box<Expression>>,
11308}
11309
11310/// DictProperty
11311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11312#[cfg_attr(feature = "bindings", derive(TS))]
11313pub struct DictProperty {
11314    pub this: Box<Expression>,
11315    pub kind: String,
11316    #[serde(default)]
11317    pub settings: Option<Box<Expression>>,
11318}
11319
11320/// DictRange
11321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11322#[cfg_attr(feature = "bindings", derive(TS))]
11323pub struct DictRange {
11324    pub this: Box<Expression>,
11325    #[serde(default)]
11326    pub min: Option<Box<Expression>>,
11327    #[serde(default)]
11328    pub max: Option<Box<Expression>>,
11329}
11330
11331/// OnCluster
11332#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11333#[cfg_attr(feature = "bindings", derive(TS))]
11334pub struct OnCluster {
11335    pub this: Box<Expression>,
11336}
11337
11338/// LikeProperty
11339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11340#[cfg_attr(feature = "bindings", derive(TS))]
11341pub struct LikeProperty {
11342    pub this: Box<Expression>,
11343    #[serde(default)]
11344    pub expressions: Vec<Expression>,
11345}
11346
11347/// LocationProperty
11348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11349#[cfg_attr(feature = "bindings", derive(TS))]
11350pub struct LocationProperty {
11351    pub this: Box<Expression>,
11352}
11353
11354/// LockProperty
11355#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11356#[cfg_attr(feature = "bindings", derive(TS))]
11357pub struct LockProperty {
11358    pub this: Box<Expression>,
11359}
11360
11361/// LockingProperty
11362#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11363#[cfg_attr(feature = "bindings", derive(TS))]
11364pub struct LockingProperty {
11365    #[serde(default)]
11366    pub this: Option<Box<Expression>>,
11367    pub kind: String,
11368    #[serde(default)]
11369    pub for_or_in: Option<Box<Expression>>,
11370    #[serde(default)]
11371    pub lock_type: Option<Box<Expression>>,
11372    #[serde(default)]
11373    pub override_: Option<Box<Expression>>,
11374}
11375
11376/// LogProperty
11377#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11378#[cfg_attr(feature = "bindings", derive(TS))]
11379pub struct LogProperty {
11380    #[serde(default)]
11381    pub no: Option<Box<Expression>>,
11382}
11383
11384/// MaterializedProperty
11385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11386#[cfg_attr(feature = "bindings", derive(TS))]
11387pub struct MaterializedProperty {
11388    #[serde(default)]
11389    pub this: Option<Box<Expression>>,
11390}
11391
11392/// MergeBlockRatioProperty
11393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11394#[cfg_attr(feature = "bindings", derive(TS))]
11395pub struct MergeBlockRatioProperty {
11396    #[serde(default)]
11397    pub this: Option<Box<Expression>>,
11398    #[serde(default)]
11399    pub no: Option<Box<Expression>>,
11400    #[serde(default)]
11401    pub default: Option<Box<Expression>>,
11402    #[serde(default)]
11403    pub percent: Option<Box<Expression>>,
11404}
11405
11406/// OnProperty
11407#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11408#[cfg_attr(feature = "bindings", derive(TS))]
11409pub struct OnProperty {
11410    pub this: Box<Expression>,
11411}
11412
11413/// OnCommitProperty
11414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11415#[cfg_attr(feature = "bindings", derive(TS))]
11416pub struct OnCommitProperty {
11417    #[serde(default)]
11418    pub delete: Option<Box<Expression>>,
11419}
11420
11421/// PartitionedByProperty
11422#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11423#[cfg_attr(feature = "bindings", derive(TS))]
11424pub struct PartitionedByProperty {
11425    pub this: Box<Expression>,
11426}
11427
11428/// BigQuery PARTITION BY property in CREATE TABLE statements.
11429#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11430#[cfg_attr(feature = "bindings", derive(TS))]
11431pub struct PartitionByProperty {
11432    #[serde(default)]
11433    pub expressions: Vec<Expression>,
11434}
11435
11436/// PartitionedByBucket
11437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11438#[cfg_attr(feature = "bindings", derive(TS))]
11439pub struct PartitionedByBucket {
11440    pub this: Box<Expression>,
11441    pub expression: Box<Expression>,
11442}
11443
11444/// BigQuery CLUSTER BY property in CREATE TABLE statements.
11445#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11446#[cfg_attr(feature = "bindings", derive(TS))]
11447pub struct ClusterByColumnsProperty {
11448    #[serde(default)]
11449    pub columns: Vec<Identifier>,
11450}
11451
11452/// PartitionByTruncate
11453#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11454#[cfg_attr(feature = "bindings", derive(TS))]
11455pub struct PartitionByTruncate {
11456    pub this: Box<Expression>,
11457    pub expression: Box<Expression>,
11458}
11459
11460/// PartitionByRangeProperty
11461#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11462#[cfg_attr(feature = "bindings", derive(TS))]
11463pub struct PartitionByRangeProperty {
11464    #[serde(default)]
11465    pub partition_expressions: Option<Box<Expression>>,
11466    #[serde(default)]
11467    pub create_expressions: Option<Box<Expression>>,
11468}
11469
11470/// PartitionByRangePropertyDynamic
11471#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11472#[cfg_attr(feature = "bindings", derive(TS))]
11473pub struct PartitionByRangePropertyDynamic {
11474    #[serde(default)]
11475    pub this: Option<Box<Expression>>,
11476    #[serde(default)]
11477    pub start: Option<Box<Expression>>,
11478    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
11479    #[serde(default)]
11480    pub use_start_end: bool,
11481    #[serde(default)]
11482    pub end: Option<Box<Expression>>,
11483    #[serde(default)]
11484    pub every: Option<Box<Expression>>,
11485}
11486
11487/// PartitionByListProperty
11488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11489#[cfg_attr(feature = "bindings", derive(TS))]
11490pub struct PartitionByListProperty {
11491    #[serde(default)]
11492    pub partition_expressions: Option<Box<Expression>>,
11493    #[serde(default)]
11494    pub create_expressions: Option<Box<Expression>>,
11495}
11496
11497/// PartitionList
11498#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11499#[cfg_attr(feature = "bindings", derive(TS))]
11500pub struct PartitionList {
11501    pub this: Box<Expression>,
11502    #[serde(default)]
11503    pub expressions: Vec<Expression>,
11504}
11505
11506/// Partition - represents PARTITION/SUBPARTITION clause
11507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11508#[cfg_attr(feature = "bindings", derive(TS))]
11509pub struct Partition {
11510    pub expressions: Vec<Expression>,
11511    #[serde(default)]
11512    pub subpartition: bool,
11513}
11514
11515/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
11516/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
11517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11518#[cfg_attr(feature = "bindings", derive(TS))]
11519pub struct RefreshTriggerProperty {
11520    /// Method: COMPLETE or AUTO
11521    pub method: String,
11522    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
11523    #[serde(default)]
11524    pub kind: Option<String>,
11525    /// For SCHEDULE: EVERY n (the number)
11526    #[serde(default)]
11527    pub every: Option<Box<Expression>>,
11528    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
11529    #[serde(default)]
11530    pub unit: Option<String>,
11531    /// For SCHEDULE: STARTS 'datetime'
11532    #[serde(default)]
11533    pub starts: Option<Box<Expression>>,
11534}
11535
11536/// UniqueKeyProperty
11537#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11538#[cfg_attr(feature = "bindings", derive(TS))]
11539pub struct UniqueKeyProperty {
11540    #[serde(default)]
11541    pub expressions: Vec<Expression>,
11542}
11543
11544/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
11545#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11546#[cfg_attr(feature = "bindings", derive(TS))]
11547pub struct RollupProperty {
11548    pub expressions: Vec<RollupIndex>,
11549}
11550
11551/// RollupIndex - A single rollup index: name(col1, col2)
11552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11553#[cfg_attr(feature = "bindings", derive(TS))]
11554pub struct RollupIndex {
11555    pub name: Identifier,
11556    pub expressions: Vec<Identifier>,
11557}
11558
11559/// PartitionBoundSpec
11560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11561#[cfg_attr(feature = "bindings", derive(TS))]
11562pub struct PartitionBoundSpec {
11563    #[serde(default)]
11564    pub this: Option<Box<Expression>>,
11565    #[serde(default)]
11566    pub expression: Option<Box<Expression>>,
11567    #[serde(default)]
11568    pub from_expressions: Option<Box<Expression>>,
11569    #[serde(default)]
11570    pub to_expressions: Option<Box<Expression>>,
11571}
11572
11573/// PartitionedOfProperty
11574#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11575#[cfg_attr(feature = "bindings", derive(TS))]
11576pub struct PartitionedOfProperty {
11577    pub this: Box<Expression>,
11578    pub expression: Box<Expression>,
11579}
11580
11581/// RemoteWithConnectionModelProperty
11582#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11583#[cfg_attr(feature = "bindings", derive(TS))]
11584pub struct RemoteWithConnectionModelProperty {
11585    pub this: Box<Expression>,
11586}
11587
11588/// ReturnsProperty
11589#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11590#[cfg_attr(feature = "bindings", derive(TS))]
11591pub struct ReturnsProperty {
11592    #[serde(default)]
11593    pub this: Option<Box<Expression>>,
11594    #[serde(default)]
11595    pub is_table: Option<Box<Expression>>,
11596    #[serde(default)]
11597    pub table: Option<Box<Expression>>,
11598    #[serde(default)]
11599    pub null: Option<Box<Expression>>,
11600}
11601
11602/// RowFormatProperty
11603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11604#[cfg_attr(feature = "bindings", derive(TS))]
11605pub struct RowFormatProperty {
11606    pub this: Box<Expression>,
11607}
11608
11609/// RowFormatDelimitedProperty
11610#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11611#[cfg_attr(feature = "bindings", derive(TS))]
11612pub struct RowFormatDelimitedProperty {
11613    #[serde(default)]
11614    pub fields: Option<Box<Expression>>,
11615    #[serde(default)]
11616    pub escaped: Option<Box<Expression>>,
11617    #[serde(default)]
11618    pub collection_items: Option<Box<Expression>>,
11619    #[serde(default)]
11620    pub map_keys: Option<Box<Expression>>,
11621    #[serde(default)]
11622    pub lines: Option<Box<Expression>>,
11623    #[serde(default)]
11624    pub null: Option<Box<Expression>>,
11625    #[serde(default)]
11626    pub serde: Option<Box<Expression>>,
11627}
11628
11629/// RowFormatSerdeProperty
11630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11631#[cfg_attr(feature = "bindings", derive(TS))]
11632pub struct RowFormatSerdeProperty {
11633    pub this: Box<Expression>,
11634    #[serde(default)]
11635    pub serde_properties: Option<Box<Expression>>,
11636}
11637
11638/// QueryTransform
11639#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11640#[cfg_attr(feature = "bindings", derive(TS))]
11641pub struct QueryTransform {
11642    #[serde(default)]
11643    pub expressions: Vec<Expression>,
11644    #[serde(default)]
11645    pub command_script: Option<Box<Expression>>,
11646    #[serde(default)]
11647    pub schema: Option<Box<Expression>>,
11648    #[serde(default)]
11649    pub row_format_before: Option<Box<Expression>>,
11650    #[serde(default)]
11651    pub record_writer: Option<Box<Expression>>,
11652    #[serde(default)]
11653    pub row_format_after: Option<Box<Expression>>,
11654    #[serde(default)]
11655    pub record_reader: Option<Box<Expression>>,
11656}
11657
11658/// SampleProperty
11659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11660#[cfg_attr(feature = "bindings", derive(TS))]
11661pub struct SampleProperty {
11662    pub this: Box<Expression>,
11663}
11664
11665/// SecurityProperty
11666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11667#[cfg_attr(feature = "bindings", derive(TS))]
11668pub struct SecurityProperty {
11669    pub this: Box<Expression>,
11670}
11671
11672/// SchemaCommentProperty
11673#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11674#[cfg_attr(feature = "bindings", derive(TS))]
11675pub struct SchemaCommentProperty {
11676    pub this: Box<Expression>,
11677}
11678
11679/// SemanticView
11680#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11681#[cfg_attr(feature = "bindings", derive(TS))]
11682pub struct SemanticView {
11683    pub this: Box<Expression>,
11684    #[serde(default)]
11685    pub metrics: Option<Box<Expression>>,
11686    #[serde(default)]
11687    pub dimensions: Option<Box<Expression>>,
11688    #[serde(default)]
11689    pub facts: Option<Box<Expression>>,
11690    #[serde(default)]
11691    pub where_: Option<Box<Expression>>,
11692}
11693
11694/// SerdeProperties
11695#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11696#[cfg_attr(feature = "bindings", derive(TS))]
11697pub struct SerdeProperties {
11698    #[serde(default)]
11699    pub expressions: Vec<Expression>,
11700    #[serde(default)]
11701    pub with_: Option<Box<Expression>>,
11702}
11703
11704/// SetProperty
11705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11706#[cfg_attr(feature = "bindings", derive(TS))]
11707pub struct SetProperty {
11708    #[serde(default)]
11709    pub multi: Option<Box<Expression>>,
11710}
11711
11712/// SharingProperty
11713#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11714#[cfg_attr(feature = "bindings", derive(TS))]
11715pub struct SharingProperty {
11716    #[serde(default)]
11717    pub this: Option<Box<Expression>>,
11718}
11719
11720/// SetConfigProperty
11721#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11722#[cfg_attr(feature = "bindings", derive(TS))]
11723pub struct SetConfigProperty {
11724    pub this: Box<Expression>,
11725}
11726
11727/// SettingsProperty
11728#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11729#[cfg_attr(feature = "bindings", derive(TS))]
11730pub struct SettingsProperty {
11731    #[serde(default)]
11732    pub expressions: Vec<Expression>,
11733}
11734
11735/// SortKeyProperty
11736#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11737#[cfg_attr(feature = "bindings", derive(TS))]
11738pub struct SortKeyProperty {
11739    pub this: Box<Expression>,
11740    #[serde(default)]
11741    pub compound: Option<Box<Expression>>,
11742}
11743
11744/// SqlReadWriteProperty
11745#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11746#[cfg_attr(feature = "bindings", derive(TS))]
11747pub struct SqlReadWriteProperty {
11748    pub this: Box<Expression>,
11749}
11750
11751/// SqlSecurityProperty
11752#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11753#[cfg_attr(feature = "bindings", derive(TS))]
11754pub struct SqlSecurityProperty {
11755    pub this: Box<Expression>,
11756}
11757
11758/// StabilityProperty
11759#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11760#[cfg_attr(feature = "bindings", derive(TS))]
11761pub struct StabilityProperty {
11762    pub this: Box<Expression>,
11763}
11764
11765/// StorageHandlerProperty
11766#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11767#[cfg_attr(feature = "bindings", derive(TS))]
11768pub struct StorageHandlerProperty {
11769    pub this: Box<Expression>,
11770}
11771
11772/// TemporaryProperty
11773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11774#[cfg_attr(feature = "bindings", derive(TS))]
11775pub struct TemporaryProperty {
11776    #[serde(default)]
11777    pub this: Option<Box<Expression>>,
11778}
11779
11780/// Tags
11781#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11782#[cfg_attr(feature = "bindings", derive(TS))]
11783pub struct Tags {
11784    #[serde(default)]
11785    pub expressions: Vec<Expression>,
11786}
11787
11788/// TransformModelProperty
11789#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11790#[cfg_attr(feature = "bindings", derive(TS))]
11791pub struct TransformModelProperty {
11792    #[serde(default)]
11793    pub expressions: Vec<Expression>,
11794}
11795
11796/// TransientProperty
11797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11798#[cfg_attr(feature = "bindings", derive(TS))]
11799pub struct TransientProperty {
11800    #[serde(default)]
11801    pub this: Option<Box<Expression>>,
11802}
11803
11804/// UsingTemplateProperty
11805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11806#[cfg_attr(feature = "bindings", derive(TS))]
11807pub struct UsingTemplateProperty {
11808    pub this: Box<Expression>,
11809}
11810
11811/// ViewAttributeProperty
11812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11813#[cfg_attr(feature = "bindings", derive(TS))]
11814pub struct ViewAttributeProperty {
11815    pub this: Box<Expression>,
11816}
11817
11818/// VolatileProperty
11819#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11820#[cfg_attr(feature = "bindings", derive(TS))]
11821pub struct VolatileProperty {
11822    #[serde(default)]
11823    pub this: Option<Box<Expression>>,
11824}
11825
11826/// WithDataProperty
11827#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11828#[cfg_attr(feature = "bindings", derive(TS))]
11829pub struct WithDataProperty {
11830    #[serde(default)]
11831    pub no: Option<Box<Expression>>,
11832    #[serde(default)]
11833    pub statistics: Option<Box<Expression>>,
11834}
11835
11836/// WithJournalTableProperty
11837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11838#[cfg_attr(feature = "bindings", derive(TS))]
11839pub struct WithJournalTableProperty {
11840    pub this: Box<Expression>,
11841}
11842
11843/// WithSchemaBindingProperty
11844#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11845#[cfg_attr(feature = "bindings", derive(TS))]
11846pub struct WithSchemaBindingProperty {
11847    pub this: Box<Expression>,
11848}
11849
11850/// WithSystemVersioningProperty
11851#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11852#[cfg_attr(feature = "bindings", derive(TS))]
11853pub struct WithSystemVersioningProperty {
11854    #[serde(default)]
11855    pub on: Option<Box<Expression>>,
11856    #[serde(default)]
11857    pub this: Option<Box<Expression>>,
11858    #[serde(default)]
11859    pub data_consistency: Option<Box<Expression>>,
11860    #[serde(default)]
11861    pub retention_period: Option<Box<Expression>>,
11862    #[serde(default)]
11863    pub with_: Option<Box<Expression>>,
11864}
11865
11866/// WithProcedureOptions
11867#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11868#[cfg_attr(feature = "bindings", derive(TS))]
11869pub struct WithProcedureOptions {
11870    #[serde(default)]
11871    pub expressions: Vec<Expression>,
11872}
11873
11874/// EncodeProperty
11875#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11876#[cfg_attr(feature = "bindings", derive(TS))]
11877pub struct EncodeProperty {
11878    pub this: Box<Expression>,
11879    #[serde(default)]
11880    pub properties: Vec<Expression>,
11881    #[serde(default)]
11882    pub key: Option<Box<Expression>>,
11883}
11884
11885/// IncludeProperty
11886#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11887#[cfg_attr(feature = "bindings", derive(TS))]
11888pub struct IncludeProperty {
11889    pub this: Box<Expression>,
11890    #[serde(default)]
11891    pub alias: Option<String>,
11892    #[serde(default)]
11893    pub column_def: Option<Box<Expression>>,
11894}
11895
11896/// Properties
11897#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11898#[cfg_attr(feature = "bindings", derive(TS))]
11899pub struct Properties {
11900    #[serde(default)]
11901    pub expressions: Vec<Expression>,
11902}
11903
11904/// Key/value pair in a BigQuery OPTIONS (...) clause.
11905#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11906#[cfg_attr(feature = "bindings", derive(TS))]
11907pub struct OptionEntry {
11908    pub key: Identifier,
11909    pub value: Expression,
11910}
11911
11912/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
11913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11914#[cfg_attr(feature = "bindings", derive(TS))]
11915pub struct OptionsProperty {
11916    #[serde(default)]
11917    pub entries: Vec<OptionEntry>,
11918}
11919
11920/// InputOutputFormat
11921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11922#[cfg_attr(feature = "bindings", derive(TS))]
11923pub struct InputOutputFormat {
11924    #[serde(default)]
11925    pub input_format: Option<Box<Expression>>,
11926    #[serde(default)]
11927    pub output_format: Option<Box<Expression>>,
11928}
11929
11930/// Reference
11931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11932#[cfg_attr(feature = "bindings", derive(TS))]
11933pub struct Reference {
11934    pub this: Box<Expression>,
11935    #[serde(default)]
11936    pub expressions: Vec<Expression>,
11937    #[serde(default)]
11938    pub options: Vec<Expression>,
11939}
11940
11941/// QueryOption
11942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11943#[cfg_attr(feature = "bindings", derive(TS))]
11944pub struct QueryOption {
11945    pub this: Box<Expression>,
11946    #[serde(default)]
11947    pub expression: Option<Box<Expression>>,
11948}
11949
11950/// WithTableHint
11951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11952#[cfg_attr(feature = "bindings", derive(TS))]
11953pub struct WithTableHint {
11954    #[serde(default)]
11955    pub expressions: Vec<Expression>,
11956}
11957
11958/// IndexTableHint
11959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11960#[cfg_attr(feature = "bindings", derive(TS))]
11961pub struct IndexTableHint {
11962    pub this: Box<Expression>,
11963    #[serde(default)]
11964    pub expressions: Vec<Expression>,
11965    #[serde(default)]
11966    pub target: Option<Box<Expression>>,
11967}
11968
11969/// Get
11970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11971#[cfg_attr(feature = "bindings", derive(TS))]
11972pub struct Get {
11973    pub this: Box<Expression>,
11974    #[serde(default)]
11975    pub target: Option<Box<Expression>>,
11976    #[serde(default)]
11977    pub properties: Vec<Expression>,
11978}
11979
11980/// SetOperation
11981#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11982#[cfg_attr(feature = "bindings", derive(TS))]
11983pub struct SetOperation {
11984    #[serde(default)]
11985    pub with_: Option<Box<Expression>>,
11986    pub this: Box<Expression>,
11987    pub expression: Box<Expression>,
11988    #[serde(default)]
11989    pub distinct: bool,
11990    #[serde(default)]
11991    pub by_name: Option<Box<Expression>>,
11992    #[serde(default)]
11993    pub side: Option<Box<Expression>>,
11994    #[serde(default)]
11995    pub kind: Option<String>,
11996    #[serde(default)]
11997    pub on: Option<Box<Expression>>,
11998}
11999
12000/// Var - Simple variable reference (for SQL variables, keywords as values)
12001#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12002#[cfg_attr(feature = "bindings", derive(TS))]
12003pub struct Var {
12004    pub this: String,
12005}
12006
12007/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12009#[cfg_attr(feature = "bindings", derive(TS))]
12010pub struct Variadic {
12011    pub this: Box<Expression>,
12012}
12013
12014/// Version
12015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12016#[cfg_attr(feature = "bindings", derive(TS))]
12017pub struct Version {
12018    pub this: Box<Expression>,
12019    pub kind: String,
12020    #[serde(default)]
12021    pub expression: Option<Box<Expression>>,
12022}
12023
12024/// Schema
12025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12026#[cfg_attr(feature = "bindings", derive(TS))]
12027pub struct Schema {
12028    #[serde(default)]
12029    pub this: Option<Box<Expression>>,
12030    #[serde(default)]
12031    pub expressions: Vec<Expression>,
12032}
12033
12034/// Lock
12035#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12036#[cfg_attr(feature = "bindings", derive(TS))]
12037pub struct Lock {
12038    #[serde(default)]
12039    pub update: Option<Box<Expression>>,
12040    #[serde(default)]
12041    pub expressions: Vec<Expression>,
12042    #[serde(default)]
12043    pub wait: Option<Box<Expression>>,
12044    #[serde(default)]
12045    pub key: Option<Box<Expression>>,
12046}
12047
12048/// TableSample - wraps an expression with a TABLESAMPLE clause
12049/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12050#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12051#[cfg_attr(feature = "bindings", derive(TS))]
12052pub struct TableSample {
12053    /// The expression being sampled (subquery, function, etc.)
12054    #[serde(default, skip_serializing_if = "Option::is_none")]
12055    pub this: Option<Box<Expression>>,
12056    /// The sample specification
12057    #[serde(default, skip_serializing_if = "Option::is_none")]
12058    pub sample: Option<Box<Sample>>,
12059    #[serde(default)]
12060    pub expressions: Vec<Expression>,
12061    #[serde(default)]
12062    pub method: Option<String>,
12063    #[serde(default)]
12064    pub bucket_numerator: Option<Box<Expression>>,
12065    #[serde(default)]
12066    pub bucket_denominator: Option<Box<Expression>>,
12067    #[serde(default)]
12068    pub bucket_field: Option<Box<Expression>>,
12069    #[serde(default)]
12070    pub percent: Option<Box<Expression>>,
12071    #[serde(default)]
12072    pub rows: Option<Box<Expression>>,
12073    #[serde(default)]
12074    pub size: Option<i64>,
12075    #[serde(default)]
12076    pub seed: Option<Box<Expression>>,
12077}
12078
12079/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12080#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12081#[cfg_attr(feature = "bindings", derive(TS))]
12082pub struct Tag {
12083    #[serde(default)]
12084    pub this: Option<Box<Expression>>,
12085    #[serde(default)]
12086    pub prefix: Option<Box<Expression>>,
12087    #[serde(default)]
12088    pub postfix: Option<Box<Expression>>,
12089}
12090
12091/// UnpivotColumns
12092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12093#[cfg_attr(feature = "bindings", derive(TS))]
12094pub struct UnpivotColumns {
12095    pub this: Box<Expression>,
12096    #[serde(default)]
12097    pub expressions: Vec<Expression>,
12098}
12099
12100/// SessionParameter
12101#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12102#[cfg_attr(feature = "bindings", derive(TS))]
12103pub struct SessionParameter {
12104    pub this: Box<Expression>,
12105    #[serde(default)]
12106    pub kind: Option<String>,
12107}
12108
12109/// PseudoType
12110#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12111#[cfg_attr(feature = "bindings", derive(TS))]
12112pub struct PseudoType {
12113    pub this: Box<Expression>,
12114}
12115
12116/// ObjectIdentifier
12117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12118#[cfg_attr(feature = "bindings", derive(TS))]
12119pub struct ObjectIdentifier {
12120    pub this: Box<Expression>,
12121}
12122
12123/// Transaction
12124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12125#[cfg_attr(feature = "bindings", derive(TS))]
12126pub struct Transaction {
12127    #[serde(default)]
12128    pub this: Option<Box<Expression>>,
12129    #[serde(default)]
12130    pub modes: Option<Box<Expression>>,
12131    #[serde(default)]
12132    pub mark: Option<Box<Expression>>,
12133}
12134
12135/// Commit
12136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12137#[cfg_attr(feature = "bindings", derive(TS))]
12138pub struct Commit {
12139    #[serde(default)]
12140    pub chain: Option<Box<Expression>>,
12141    #[serde(default)]
12142    pub this: Option<Box<Expression>>,
12143    #[serde(default)]
12144    pub durability: Option<Box<Expression>>,
12145}
12146
12147/// Rollback
12148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12149#[cfg_attr(feature = "bindings", derive(TS))]
12150pub struct Rollback {
12151    #[serde(default)]
12152    pub savepoint: Option<Box<Expression>>,
12153    #[serde(default)]
12154    pub this: Option<Box<Expression>>,
12155}
12156
12157/// AlterSession
12158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12159#[cfg_attr(feature = "bindings", derive(TS))]
12160pub struct AlterSession {
12161    #[serde(default)]
12162    pub expressions: Vec<Expression>,
12163    #[serde(default)]
12164    pub unset: Option<Box<Expression>>,
12165}
12166
12167/// Analyze
12168#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12169#[cfg_attr(feature = "bindings", derive(TS))]
12170pub struct Analyze {
12171    #[serde(default)]
12172    pub kind: Option<String>,
12173    #[serde(default)]
12174    pub this: Option<Box<Expression>>,
12175    #[serde(default)]
12176    pub options: Vec<Expression>,
12177    #[serde(default)]
12178    pub mode: Option<Box<Expression>>,
12179    #[serde(default)]
12180    pub partition: Option<Box<Expression>>,
12181    #[serde(default)]
12182    pub expression: Option<Box<Expression>>,
12183    #[serde(default)]
12184    pub properties: Vec<Expression>,
12185    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12186    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12187    pub columns: Vec<String>,
12188}
12189
12190/// AnalyzeStatistics
12191#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12192#[cfg_attr(feature = "bindings", derive(TS))]
12193pub struct AnalyzeStatistics {
12194    pub kind: String,
12195    #[serde(default)]
12196    pub option: Option<Box<Expression>>,
12197    #[serde(default)]
12198    pub this: Option<Box<Expression>>,
12199    #[serde(default)]
12200    pub expressions: Vec<Expression>,
12201}
12202
12203/// AnalyzeHistogram
12204#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12205#[cfg_attr(feature = "bindings", derive(TS))]
12206pub struct AnalyzeHistogram {
12207    pub this: Box<Expression>,
12208    #[serde(default)]
12209    pub expressions: Vec<Expression>,
12210    #[serde(default)]
12211    pub expression: Option<Box<Expression>>,
12212    #[serde(default)]
12213    pub update_options: Option<Box<Expression>>,
12214}
12215
12216/// AnalyzeSample
12217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12218#[cfg_attr(feature = "bindings", derive(TS))]
12219pub struct AnalyzeSample {
12220    pub kind: String,
12221    #[serde(default)]
12222    pub sample: Option<Box<Expression>>,
12223}
12224
12225/// AnalyzeListChainedRows
12226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12227#[cfg_attr(feature = "bindings", derive(TS))]
12228pub struct AnalyzeListChainedRows {
12229    #[serde(default)]
12230    pub expression: Option<Box<Expression>>,
12231}
12232
12233/// AnalyzeDelete
12234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12235#[cfg_attr(feature = "bindings", derive(TS))]
12236pub struct AnalyzeDelete {
12237    #[serde(default)]
12238    pub kind: Option<String>,
12239}
12240
12241/// AnalyzeWith
12242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12243#[cfg_attr(feature = "bindings", derive(TS))]
12244pub struct AnalyzeWith {
12245    #[serde(default)]
12246    pub expressions: Vec<Expression>,
12247}
12248
12249/// AnalyzeValidate
12250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12251#[cfg_attr(feature = "bindings", derive(TS))]
12252pub struct AnalyzeValidate {
12253    pub kind: String,
12254    #[serde(default)]
12255    pub this: Option<Box<Expression>>,
12256    #[serde(default)]
12257    pub expression: Option<Box<Expression>>,
12258}
12259
12260/// AddPartition
12261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12262#[cfg_attr(feature = "bindings", derive(TS))]
12263pub struct AddPartition {
12264    pub this: Box<Expression>,
12265    #[serde(default)]
12266    pub exists: bool,
12267    #[serde(default)]
12268    pub location: Option<Box<Expression>>,
12269}
12270
12271/// AttachOption
12272#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12273#[cfg_attr(feature = "bindings", derive(TS))]
12274pub struct AttachOption {
12275    pub this: Box<Expression>,
12276    #[serde(default)]
12277    pub expression: Option<Box<Expression>>,
12278}
12279
12280/// DropPartition
12281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12282#[cfg_attr(feature = "bindings", derive(TS))]
12283pub struct DropPartition {
12284    #[serde(default)]
12285    pub expressions: Vec<Expression>,
12286    #[serde(default)]
12287    pub exists: bool,
12288}
12289
12290/// ReplacePartition
12291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12292#[cfg_attr(feature = "bindings", derive(TS))]
12293pub struct ReplacePartition {
12294    pub expression: Box<Expression>,
12295    #[serde(default)]
12296    pub source: Option<Box<Expression>>,
12297}
12298
12299/// DPipe
12300#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12301#[cfg_attr(feature = "bindings", derive(TS))]
12302pub struct DPipe {
12303    pub this: Box<Expression>,
12304    pub expression: Box<Expression>,
12305    #[serde(default)]
12306    pub safe: Option<Box<Expression>>,
12307}
12308
12309/// Operator
12310#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12311#[cfg_attr(feature = "bindings", derive(TS))]
12312pub struct Operator {
12313    pub this: Box<Expression>,
12314    #[serde(default)]
12315    pub operator: Option<Box<Expression>>,
12316    pub expression: Box<Expression>,
12317    /// Comments between OPERATOR() and the RHS expression
12318    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12319    pub comments: Vec<String>,
12320}
12321
12322/// PivotAny
12323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12324#[cfg_attr(feature = "bindings", derive(TS))]
12325pub struct PivotAny {
12326    #[serde(default)]
12327    pub this: Option<Box<Expression>>,
12328}
12329
12330/// Aliases
12331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12332#[cfg_attr(feature = "bindings", derive(TS))]
12333pub struct Aliases {
12334    pub this: Box<Expression>,
12335    #[serde(default)]
12336    pub expressions: Vec<Expression>,
12337}
12338
12339/// AtIndex
12340#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12341#[cfg_attr(feature = "bindings", derive(TS))]
12342pub struct AtIndex {
12343    pub this: Box<Expression>,
12344    pub expression: Box<Expression>,
12345}
12346
12347/// FromTimeZone
12348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12349#[cfg_attr(feature = "bindings", derive(TS))]
12350pub struct FromTimeZone {
12351    pub this: Box<Expression>,
12352    #[serde(default)]
12353    pub zone: Option<Box<Expression>>,
12354}
12355
12356/// Format override for a column in Teradata
12357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12358#[cfg_attr(feature = "bindings", derive(TS))]
12359pub struct FormatPhrase {
12360    pub this: Box<Expression>,
12361    pub format: String,
12362}
12363
12364/// ForIn
12365#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12366#[cfg_attr(feature = "bindings", derive(TS))]
12367pub struct ForIn {
12368    pub this: Box<Expression>,
12369    pub expression: Box<Expression>,
12370}
12371
12372/// Automatically converts unit arg into a var.
12373#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12374#[cfg_attr(feature = "bindings", derive(TS))]
12375pub struct TimeUnit {
12376    #[serde(default)]
12377    pub unit: Option<String>,
12378}
12379
12380/// IntervalOp
12381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12382#[cfg_attr(feature = "bindings", derive(TS))]
12383pub struct IntervalOp {
12384    #[serde(default)]
12385    pub unit: Option<String>,
12386    pub expression: Box<Expression>,
12387}
12388
12389/// HavingMax
12390#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12391#[cfg_attr(feature = "bindings", derive(TS))]
12392pub struct HavingMax {
12393    pub this: Box<Expression>,
12394    pub expression: Box<Expression>,
12395    #[serde(default)]
12396    pub max: Option<Box<Expression>>,
12397}
12398
12399/// CosineDistance
12400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12401#[cfg_attr(feature = "bindings", derive(TS))]
12402pub struct CosineDistance {
12403    pub this: Box<Expression>,
12404    pub expression: Box<Expression>,
12405}
12406
12407/// DotProduct
12408#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12409#[cfg_attr(feature = "bindings", derive(TS))]
12410pub struct DotProduct {
12411    pub this: Box<Expression>,
12412    pub expression: Box<Expression>,
12413}
12414
12415/// EuclideanDistance
12416#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12417#[cfg_attr(feature = "bindings", derive(TS))]
12418pub struct EuclideanDistance {
12419    pub this: Box<Expression>,
12420    pub expression: Box<Expression>,
12421}
12422
12423/// ManhattanDistance
12424#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12425#[cfg_attr(feature = "bindings", derive(TS))]
12426pub struct ManhattanDistance {
12427    pub this: Box<Expression>,
12428    pub expression: Box<Expression>,
12429}
12430
12431/// JarowinklerSimilarity
12432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12433#[cfg_attr(feature = "bindings", derive(TS))]
12434pub struct JarowinklerSimilarity {
12435    pub this: Box<Expression>,
12436    pub expression: Box<Expression>,
12437}
12438
12439/// Booland
12440#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12441#[cfg_attr(feature = "bindings", derive(TS))]
12442pub struct Booland {
12443    pub this: Box<Expression>,
12444    pub expression: Box<Expression>,
12445}
12446
12447/// Boolor
12448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12449#[cfg_attr(feature = "bindings", derive(TS))]
12450pub struct Boolor {
12451    pub this: Box<Expression>,
12452    pub expression: Box<Expression>,
12453}
12454
12455/// ParameterizedAgg
12456#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12457#[cfg_attr(feature = "bindings", derive(TS))]
12458pub struct ParameterizedAgg {
12459    pub this: Box<Expression>,
12460    #[serde(default)]
12461    pub expressions: Vec<Expression>,
12462    #[serde(default)]
12463    pub params: Vec<Expression>,
12464}
12465
12466/// ArgMax
12467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12468#[cfg_attr(feature = "bindings", derive(TS))]
12469pub struct ArgMax {
12470    pub this: Box<Expression>,
12471    pub expression: Box<Expression>,
12472    #[serde(default)]
12473    pub count: Option<Box<Expression>>,
12474}
12475
12476/// ArgMin
12477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12478#[cfg_attr(feature = "bindings", derive(TS))]
12479pub struct ArgMin {
12480    pub this: Box<Expression>,
12481    pub expression: Box<Expression>,
12482    #[serde(default)]
12483    pub count: Option<Box<Expression>>,
12484}
12485
12486/// ApproxTopK
12487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12488#[cfg_attr(feature = "bindings", derive(TS))]
12489pub struct ApproxTopK {
12490    pub this: Box<Expression>,
12491    #[serde(default)]
12492    pub expression: Option<Box<Expression>>,
12493    #[serde(default)]
12494    pub counters: Option<Box<Expression>>,
12495}
12496
12497/// ApproxTopKAccumulate
12498#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12499#[cfg_attr(feature = "bindings", derive(TS))]
12500pub struct ApproxTopKAccumulate {
12501    pub this: Box<Expression>,
12502    #[serde(default)]
12503    pub expression: Option<Box<Expression>>,
12504}
12505
12506/// ApproxTopKCombine
12507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12508#[cfg_attr(feature = "bindings", derive(TS))]
12509pub struct ApproxTopKCombine {
12510    pub this: Box<Expression>,
12511    #[serde(default)]
12512    pub expression: Option<Box<Expression>>,
12513}
12514
12515/// ApproxTopKEstimate
12516#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12517#[cfg_attr(feature = "bindings", derive(TS))]
12518pub struct ApproxTopKEstimate {
12519    pub this: Box<Expression>,
12520    #[serde(default)]
12521    pub expression: Option<Box<Expression>>,
12522}
12523
12524/// ApproxTopSum
12525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12526#[cfg_attr(feature = "bindings", derive(TS))]
12527pub struct ApproxTopSum {
12528    pub this: Box<Expression>,
12529    pub expression: Box<Expression>,
12530    #[serde(default)]
12531    pub count: Option<Box<Expression>>,
12532}
12533
12534/// ApproxQuantiles
12535#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12536#[cfg_attr(feature = "bindings", derive(TS))]
12537pub struct ApproxQuantiles {
12538    pub this: Box<Expression>,
12539    #[serde(default)]
12540    pub expression: Option<Box<Expression>>,
12541}
12542
12543/// Minhash
12544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12545#[cfg_attr(feature = "bindings", derive(TS))]
12546pub struct Minhash {
12547    pub this: Box<Expression>,
12548    #[serde(default)]
12549    pub expressions: Vec<Expression>,
12550}
12551
12552/// FarmFingerprint
12553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12554#[cfg_attr(feature = "bindings", derive(TS))]
12555pub struct FarmFingerprint {
12556    #[serde(default)]
12557    pub expressions: Vec<Expression>,
12558}
12559
12560/// Float64
12561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12562#[cfg_attr(feature = "bindings", derive(TS))]
12563pub struct Float64 {
12564    pub this: Box<Expression>,
12565    #[serde(default)]
12566    pub expression: Option<Box<Expression>>,
12567}
12568
12569/// Transform
12570#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12571#[cfg_attr(feature = "bindings", derive(TS))]
12572pub struct Transform {
12573    pub this: Box<Expression>,
12574    pub expression: Box<Expression>,
12575}
12576
12577/// Translate
12578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12579#[cfg_attr(feature = "bindings", derive(TS))]
12580pub struct Translate {
12581    pub this: Box<Expression>,
12582    #[serde(default)]
12583    pub from_: Option<Box<Expression>>,
12584    #[serde(default)]
12585    pub to: Option<Box<Expression>>,
12586}
12587
12588/// Grouping
12589#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12590#[cfg_attr(feature = "bindings", derive(TS))]
12591pub struct Grouping {
12592    #[serde(default)]
12593    pub expressions: Vec<Expression>,
12594}
12595
12596/// GroupingId
12597#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12598#[cfg_attr(feature = "bindings", derive(TS))]
12599pub struct GroupingId {
12600    #[serde(default)]
12601    pub expressions: Vec<Expression>,
12602}
12603
12604/// Anonymous
12605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12606#[cfg_attr(feature = "bindings", derive(TS))]
12607pub struct Anonymous {
12608    pub this: Box<Expression>,
12609    #[serde(default)]
12610    pub expressions: Vec<Expression>,
12611}
12612
12613/// AnonymousAggFunc
12614#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12615#[cfg_attr(feature = "bindings", derive(TS))]
12616pub struct AnonymousAggFunc {
12617    pub this: Box<Expression>,
12618    #[serde(default)]
12619    pub expressions: Vec<Expression>,
12620}
12621
12622/// CombinedAggFunc
12623#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12624#[cfg_attr(feature = "bindings", derive(TS))]
12625pub struct CombinedAggFunc {
12626    pub this: Box<Expression>,
12627    #[serde(default)]
12628    pub expressions: Vec<Expression>,
12629}
12630
12631/// CombinedParameterizedAgg
12632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12633#[cfg_attr(feature = "bindings", derive(TS))]
12634pub struct CombinedParameterizedAgg {
12635    pub this: Box<Expression>,
12636    #[serde(default)]
12637    pub expressions: Vec<Expression>,
12638    #[serde(default)]
12639    pub params: Vec<Expression>,
12640}
12641
12642/// HashAgg
12643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12644#[cfg_attr(feature = "bindings", derive(TS))]
12645pub struct HashAgg {
12646    pub this: Box<Expression>,
12647    #[serde(default)]
12648    pub expressions: Vec<Expression>,
12649}
12650
12651/// Hll
12652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12653#[cfg_attr(feature = "bindings", derive(TS))]
12654pub struct Hll {
12655    pub this: Box<Expression>,
12656    #[serde(default)]
12657    pub expressions: Vec<Expression>,
12658}
12659
12660/// Apply
12661#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12662#[cfg_attr(feature = "bindings", derive(TS))]
12663pub struct Apply {
12664    pub this: Box<Expression>,
12665    pub expression: Box<Expression>,
12666}
12667
12668/// ToBoolean
12669#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12670#[cfg_attr(feature = "bindings", derive(TS))]
12671pub struct ToBoolean {
12672    pub this: Box<Expression>,
12673    #[serde(default)]
12674    pub safe: Option<Box<Expression>>,
12675}
12676
12677/// List
12678#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12679#[cfg_attr(feature = "bindings", derive(TS))]
12680pub struct List {
12681    #[serde(default)]
12682    pub expressions: Vec<Expression>,
12683}
12684
12685/// ToMap - Materialize-style map constructor
12686/// Can hold either:
12687/// - A SELECT subquery (MAP(SELECT 'a', 1))
12688/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
12689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12690#[cfg_attr(feature = "bindings", derive(TS))]
12691pub struct ToMap {
12692    /// Either a Select subquery or a Struct containing PropertyEQ entries
12693    pub this: Box<Expression>,
12694}
12695
12696/// Pad
12697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12698#[cfg_attr(feature = "bindings", derive(TS))]
12699pub struct Pad {
12700    pub this: Box<Expression>,
12701    pub expression: Box<Expression>,
12702    #[serde(default)]
12703    pub fill_pattern: Option<Box<Expression>>,
12704    #[serde(default)]
12705    pub is_left: Option<Box<Expression>>,
12706}
12707
12708/// ToChar
12709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12710#[cfg_attr(feature = "bindings", derive(TS))]
12711pub struct ToChar {
12712    pub this: Box<Expression>,
12713    #[serde(default)]
12714    pub format: Option<String>,
12715    #[serde(default)]
12716    pub nlsparam: Option<Box<Expression>>,
12717    #[serde(default)]
12718    pub is_numeric: Option<Box<Expression>>,
12719}
12720
12721/// StringFunc - String type conversion function (BigQuery STRING)
12722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12723#[cfg_attr(feature = "bindings", derive(TS))]
12724pub struct StringFunc {
12725    pub this: Box<Expression>,
12726    #[serde(default)]
12727    pub zone: Option<Box<Expression>>,
12728}
12729
12730/// ToNumber
12731#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12732#[cfg_attr(feature = "bindings", derive(TS))]
12733pub struct ToNumber {
12734    pub this: Box<Expression>,
12735    #[serde(default)]
12736    pub format: Option<Box<Expression>>,
12737    #[serde(default)]
12738    pub nlsparam: Option<Box<Expression>>,
12739    #[serde(default)]
12740    pub precision: Option<Box<Expression>>,
12741    #[serde(default)]
12742    pub scale: Option<Box<Expression>>,
12743    #[serde(default)]
12744    pub safe: Option<Box<Expression>>,
12745    #[serde(default)]
12746    pub safe_name: Option<Box<Expression>>,
12747}
12748
12749/// ToDouble
12750#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12751#[cfg_attr(feature = "bindings", derive(TS))]
12752pub struct ToDouble {
12753    pub this: Box<Expression>,
12754    #[serde(default)]
12755    pub format: Option<String>,
12756    #[serde(default)]
12757    pub safe: Option<Box<Expression>>,
12758}
12759
12760/// ToDecfloat
12761#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12762#[cfg_attr(feature = "bindings", derive(TS))]
12763pub struct ToDecfloat {
12764    pub this: Box<Expression>,
12765    #[serde(default)]
12766    pub format: Option<String>,
12767}
12768
12769/// TryToDecfloat
12770#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12771#[cfg_attr(feature = "bindings", derive(TS))]
12772pub struct TryToDecfloat {
12773    pub this: Box<Expression>,
12774    #[serde(default)]
12775    pub format: Option<String>,
12776}
12777
12778/// ToFile
12779#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12780#[cfg_attr(feature = "bindings", derive(TS))]
12781pub struct ToFile {
12782    pub this: Box<Expression>,
12783    #[serde(default)]
12784    pub path: Option<Box<Expression>>,
12785    #[serde(default)]
12786    pub safe: Option<Box<Expression>>,
12787}
12788
12789/// Columns
12790#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12791#[cfg_attr(feature = "bindings", derive(TS))]
12792pub struct Columns {
12793    pub this: Box<Expression>,
12794    #[serde(default)]
12795    pub unpack: Option<Box<Expression>>,
12796}
12797
12798/// ConvertToCharset
12799#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12800#[cfg_attr(feature = "bindings", derive(TS))]
12801pub struct ConvertToCharset {
12802    pub this: Box<Expression>,
12803    #[serde(default)]
12804    pub dest: Option<Box<Expression>>,
12805    #[serde(default)]
12806    pub source: Option<Box<Expression>>,
12807}
12808
12809/// ConvertTimezone
12810#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12811#[cfg_attr(feature = "bindings", derive(TS))]
12812pub struct ConvertTimezone {
12813    #[serde(default)]
12814    pub source_tz: Option<Box<Expression>>,
12815    #[serde(default)]
12816    pub target_tz: Option<Box<Expression>>,
12817    #[serde(default)]
12818    pub timestamp: Option<Box<Expression>>,
12819    #[serde(default)]
12820    pub options: Vec<Expression>,
12821}
12822
12823/// GenerateSeries
12824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12825#[cfg_attr(feature = "bindings", derive(TS))]
12826pub struct GenerateSeries {
12827    #[serde(default)]
12828    pub start: Option<Box<Expression>>,
12829    #[serde(default)]
12830    pub end: Option<Box<Expression>>,
12831    #[serde(default)]
12832    pub step: Option<Box<Expression>>,
12833    #[serde(default)]
12834    pub is_end_exclusive: Option<Box<Expression>>,
12835}
12836
12837/// AIAgg
12838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12839#[cfg_attr(feature = "bindings", derive(TS))]
12840pub struct AIAgg {
12841    pub this: Box<Expression>,
12842    pub expression: Box<Expression>,
12843}
12844
12845/// AIClassify
12846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12847#[cfg_attr(feature = "bindings", derive(TS))]
12848pub struct AIClassify {
12849    pub this: Box<Expression>,
12850    #[serde(default)]
12851    pub categories: Option<Box<Expression>>,
12852    #[serde(default)]
12853    pub config: Option<Box<Expression>>,
12854}
12855
12856/// ArrayAll
12857#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12858#[cfg_attr(feature = "bindings", derive(TS))]
12859pub struct ArrayAll {
12860    pub this: Box<Expression>,
12861    pub expression: Box<Expression>,
12862}
12863
12864/// ArrayAny
12865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12866#[cfg_attr(feature = "bindings", derive(TS))]
12867pub struct ArrayAny {
12868    pub this: Box<Expression>,
12869    pub expression: Box<Expression>,
12870}
12871
12872/// ArrayConstructCompact
12873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12874#[cfg_attr(feature = "bindings", derive(TS))]
12875pub struct ArrayConstructCompact {
12876    #[serde(default)]
12877    pub expressions: Vec<Expression>,
12878}
12879
12880/// StPoint
12881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12882#[cfg_attr(feature = "bindings", derive(TS))]
12883pub struct StPoint {
12884    pub this: Box<Expression>,
12885    pub expression: Box<Expression>,
12886    #[serde(default)]
12887    pub null: Option<Box<Expression>>,
12888}
12889
12890/// StDistance
12891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12892#[cfg_attr(feature = "bindings", derive(TS))]
12893pub struct StDistance {
12894    pub this: Box<Expression>,
12895    pub expression: Box<Expression>,
12896    #[serde(default)]
12897    pub use_spheroid: Option<Box<Expression>>,
12898}
12899
12900/// StringToArray
12901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12902#[cfg_attr(feature = "bindings", derive(TS))]
12903pub struct StringToArray {
12904    pub this: Box<Expression>,
12905    #[serde(default)]
12906    pub expression: Option<Box<Expression>>,
12907    #[serde(default)]
12908    pub null: Option<Box<Expression>>,
12909}
12910
12911/// ArraySum
12912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12913#[cfg_attr(feature = "bindings", derive(TS))]
12914pub struct ArraySum {
12915    pub this: Box<Expression>,
12916    #[serde(default)]
12917    pub expression: Option<Box<Expression>>,
12918}
12919
12920/// ObjectAgg
12921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12922#[cfg_attr(feature = "bindings", derive(TS))]
12923pub struct ObjectAgg {
12924    pub this: Box<Expression>,
12925    pub expression: Box<Expression>,
12926}
12927
12928/// CastToStrType
12929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12930#[cfg_attr(feature = "bindings", derive(TS))]
12931pub struct CastToStrType {
12932    pub this: Box<Expression>,
12933    #[serde(default)]
12934    pub to: Option<Box<Expression>>,
12935}
12936
12937/// CheckJson
12938#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12939#[cfg_attr(feature = "bindings", derive(TS))]
12940pub struct CheckJson {
12941    pub this: Box<Expression>,
12942}
12943
12944/// CheckXml
12945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12946#[cfg_attr(feature = "bindings", derive(TS))]
12947pub struct CheckXml {
12948    pub this: Box<Expression>,
12949    #[serde(default)]
12950    pub disable_auto_convert: Option<Box<Expression>>,
12951}
12952
12953/// TranslateCharacters
12954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12955#[cfg_attr(feature = "bindings", derive(TS))]
12956pub struct TranslateCharacters {
12957    pub this: Box<Expression>,
12958    pub expression: Box<Expression>,
12959    #[serde(default)]
12960    pub with_error: Option<Box<Expression>>,
12961}
12962
12963/// CurrentSchemas
12964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12965#[cfg_attr(feature = "bindings", derive(TS))]
12966pub struct CurrentSchemas {
12967    #[serde(default)]
12968    pub this: Option<Box<Expression>>,
12969}
12970
12971/// CurrentDatetime
12972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12973#[cfg_attr(feature = "bindings", derive(TS))]
12974pub struct CurrentDatetime {
12975    #[serde(default)]
12976    pub this: Option<Box<Expression>>,
12977}
12978
12979/// Localtime
12980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12981#[cfg_attr(feature = "bindings", derive(TS))]
12982pub struct Localtime {
12983    #[serde(default)]
12984    pub this: Option<Box<Expression>>,
12985}
12986
12987/// Localtimestamp
12988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12989#[cfg_attr(feature = "bindings", derive(TS))]
12990pub struct Localtimestamp {
12991    #[serde(default)]
12992    pub this: Option<Box<Expression>>,
12993}
12994
12995/// Systimestamp
12996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12997#[cfg_attr(feature = "bindings", derive(TS))]
12998pub struct Systimestamp {
12999    #[serde(default)]
13000    pub this: Option<Box<Expression>>,
13001}
13002
13003/// CurrentSchema
13004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13005#[cfg_attr(feature = "bindings", derive(TS))]
13006pub struct CurrentSchema {
13007    #[serde(default)]
13008    pub this: Option<Box<Expression>>,
13009}
13010
13011/// CurrentUser
13012#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13013#[cfg_attr(feature = "bindings", derive(TS))]
13014pub struct CurrentUser {
13015    #[serde(default)]
13016    pub this: Option<Box<Expression>>,
13017}
13018
13019/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13020#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13021#[cfg_attr(feature = "bindings", derive(TS))]
13022pub struct SessionUser;
13023
13024/// JSONPathRoot - Represents $ in JSON path expressions
13025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13026#[cfg_attr(feature = "bindings", derive(TS))]
13027pub struct JSONPathRoot;
13028
13029/// UtcTime
13030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13031#[cfg_attr(feature = "bindings", derive(TS))]
13032pub struct UtcTime {
13033    #[serde(default)]
13034    pub this: Option<Box<Expression>>,
13035}
13036
13037/// UtcTimestamp
13038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13039#[cfg_attr(feature = "bindings", derive(TS))]
13040pub struct UtcTimestamp {
13041    #[serde(default)]
13042    pub this: Option<Box<Expression>>,
13043}
13044
13045/// TimestampFunc - TIMESTAMP constructor function
13046#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13047#[cfg_attr(feature = "bindings", derive(TS))]
13048pub struct TimestampFunc {
13049    #[serde(default)]
13050    pub this: Option<Box<Expression>>,
13051    #[serde(default)]
13052    pub zone: Option<Box<Expression>>,
13053    #[serde(default)]
13054    pub with_tz: Option<bool>,
13055    #[serde(default)]
13056    pub safe: Option<bool>,
13057}
13058
13059/// DateBin
13060#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13061#[cfg_attr(feature = "bindings", derive(TS))]
13062pub struct DateBin {
13063    pub this: Box<Expression>,
13064    pub expression: Box<Expression>,
13065    #[serde(default)]
13066    pub unit: Option<String>,
13067    #[serde(default)]
13068    pub zone: Option<Box<Expression>>,
13069    #[serde(default)]
13070    pub origin: Option<Box<Expression>>,
13071}
13072
13073/// Datetime
13074#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13075#[cfg_attr(feature = "bindings", derive(TS))]
13076pub struct Datetime {
13077    pub this: Box<Expression>,
13078    #[serde(default)]
13079    pub expression: Option<Box<Expression>>,
13080}
13081
13082/// DatetimeAdd
13083#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13084#[cfg_attr(feature = "bindings", derive(TS))]
13085pub struct DatetimeAdd {
13086    pub this: Box<Expression>,
13087    pub expression: Box<Expression>,
13088    #[serde(default)]
13089    pub unit: Option<String>,
13090}
13091
13092/// DatetimeSub
13093#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13094#[cfg_attr(feature = "bindings", derive(TS))]
13095pub struct DatetimeSub {
13096    pub this: Box<Expression>,
13097    pub expression: Box<Expression>,
13098    #[serde(default)]
13099    pub unit: Option<String>,
13100}
13101
13102/// DatetimeDiff
13103#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13104#[cfg_attr(feature = "bindings", derive(TS))]
13105pub struct DatetimeDiff {
13106    pub this: Box<Expression>,
13107    pub expression: Box<Expression>,
13108    #[serde(default)]
13109    pub unit: Option<String>,
13110}
13111
13112/// DatetimeTrunc
13113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13114#[cfg_attr(feature = "bindings", derive(TS))]
13115pub struct DatetimeTrunc {
13116    pub this: Box<Expression>,
13117    pub unit: String,
13118    #[serde(default)]
13119    pub zone: Option<Box<Expression>>,
13120}
13121
13122/// Dayname
13123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13124#[cfg_attr(feature = "bindings", derive(TS))]
13125pub struct Dayname {
13126    pub this: Box<Expression>,
13127    #[serde(default)]
13128    pub abbreviated: Option<Box<Expression>>,
13129}
13130
13131/// MakeInterval
13132#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13133#[cfg_attr(feature = "bindings", derive(TS))]
13134pub struct MakeInterval {
13135    #[serde(default)]
13136    pub year: Option<Box<Expression>>,
13137    #[serde(default)]
13138    pub month: Option<Box<Expression>>,
13139    #[serde(default)]
13140    pub week: Option<Box<Expression>>,
13141    #[serde(default)]
13142    pub day: Option<Box<Expression>>,
13143    #[serde(default)]
13144    pub hour: Option<Box<Expression>>,
13145    #[serde(default)]
13146    pub minute: Option<Box<Expression>>,
13147    #[serde(default)]
13148    pub second: Option<Box<Expression>>,
13149}
13150
13151/// PreviousDay
13152#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13153#[cfg_attr(feature = "bindings", derive(TS))]
13154pub struct PreviousDay {
13155    pub this: Box<Expression>,
13156    pub expression: Box<Expression>,
13157}
13158
13159/// Elt
13160#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13161#[cfg_attr(feature = "bindings", derive(TS))]
13162pub struct Elt {
13163    pub this: Box<Expression>,
13164    #[serde(default)]
13165    pub expressions: Vec<Expression>,
13166}
13167
13168/// TimestampAdd
13169#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13170#[cfg_attr(feature = "bindings", derive(TS))]
13171pub struct TimestampAdd {
13172    pub this: Box<Expression>,
13173    pub expression: Box<Expression>,
13174    #[serde(default)]
13175    pub unit: Option<String>,
13176}
13177
13178/// TimestampSub
13179#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13180#[cfg_attr(feature = "bindings", derive(TS))]
13181pub struct TimestampSub {
13182    pub this: Box<Expression>,
13183    pub expression: Box<Expression>,
13184    #[serde(default)]
13185    pub unit: Option<String>,
13186}
13187
13188/// TimestampDiff
13189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13190#[cfg_attr(feature = "bindings", derive(TS))]
13191pub struct TimestampDiff {
13192    pub this: Box<Expression>,
13193    pub expression: Box<Expression>,
13194    #[serde(default)]
13195    pub unit: Option<String>,
13196}
13197
13198/// TimeSlice
13199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13200#[cfg_attr(feature = "bindings", derive(TS))]
13201pub struct TimeSlice {
13202    pub this: Box<Expression>,
13203    pub expression: Box<Expression>,
13204    pub unit: String,
13205    #[serde(default)]
13206    pub kind: Option<String>,
13207}
13208
13209/// TimeAdd
13210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13211#[cfg_attr(feature = "bindings", derive(TS))]
13212pub struct TimeAdd {
13213    pub this: Box<Expression>,
13214    pub expression: Box<Expression>,
13215    #[serde(default)]
13216    pub unit: Option<String>,
13217}
13218
13219/// TimeSub
13220#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13221#[cfg_attr(feature = "bindings", derive(TS))]
13222pub struct TimeSub {
13223    pub this: Box<Expression>,
13224    pub expression: Box<Expression>,
13225    #[serde(default)]
13226    pub unit: Option<String>,
13227}
13228
13229/// TimeDiff
13230#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13231#[cfg_attr(feature = "bindings", derive(TS))]
13232pub struct TimeDiff {
13233    pub this: Box<Expression>,
13234    pub expression: Box<Expression>,
13235    #[serde(default)]
13236    pub unit: Option<String>,
13237}
13238
13239/// TimeTrunc
13240#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13241#[cfg_attr(feature = "bindings", derive(TS))]
13242pub struct TimeTrunc {
13243    pub this: Box<Expression>,
13244    pub unit: String,
13245    #[serde(default)]
13246    pub zone: Option<Box<Expression>>,
13247}
13248
13249/// DateFromParts
13250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13251#[cfg_attr(feature = "bindings", derive(TS))]
13252pub struct DateFromParts {
13253    #[serde(default)]
13254    pub year: Option<Box<Expression>>,
13255    #[serde(default)]
13256    pub month: Option<Box<Expression>>,
13257    #[serde(default)]
13258    pub day: Option<Box<Expression>>,
13259    #[serde(default)]
13260    pub allow_overflow: Option<Box<Expression>>,
13261}
13262
13263/// TimeFromParts
13264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13265#[cfg_attr(feature = "bindings", derive(TS))]
13266pub struct TimeFromParts {
13267    #[serde(default)]
13268    pub hour: Option<Box<Expression>>,
13269    #[serde(default)]
13270    pub min: Option<Box<Expression>>,
13271    #[serde(default)]
13272    pub sec: Option<Box<Expression>>,
13273    #[serde(default)]
13274    pub nano: Option<Box<Expression>>,
13275    #[serde(default)]
13276    pub fractions: Option<Box<Expression>>,
13277    #[serde(default)]
13278    pub precision: Option<i64>,
13279}
13280
13281/// DecodeCase
13282#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13283#[cfg_attr(feature = "bindings", derive(TS))]
13284pub struct DecodeCase {
13285    #[serde(default)]
13286    pub expressions: Vec<Expression>,
13287}
13288
13289/// Decrypt
13290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13291#[cfg_attr(feature = "bindings", derive(TS))]
13292pub struct Decrypt {
13293    pub this: Box<Expression>,
13294    #[serde(default)]
13295    pub passphrase: Option<Box<Expression>>,
13296    #[serde(default)]
13297    pub aad: Option<Box<Expression>>,
13298    #[serde(default)]
13299    pub encryption_method: Option<Box<Expression>>,
13300    #[serde(default)]
13301    pub safe: Option<Box<Expression>>,
13302}
13303
13304/// DecryptRaw
13305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13306#[cfg_attr(feature = "bindings", derive(TS))]
13307pub struct DecryptRaw {
13308    pub this: Box<Expression>,
13309    #[serde(default)]
13310    pub key: Option<Box<Expression>>,
13311    #[serde(default)]
13312    pub iv: Option<Box<Expression>>,
13313    #[serde(default)]
13314    pub aad: Option<Box<Expression>>,
13315    #[serde(default)]
13316    pub encryption_method: Option<Box<Expression>>,
13317    #[serde(default)]
13318    pub aead: Option<Box<Expression>>,
13319    #[serde(default)]
13320    pub safe: Option<Box<Expression>>,
13321}
13322
13323/// Encode
13324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13325#[cfg_attr(feature = "bindings", derive(TS))]
13326pub struct Encode {
13327    pub this: Box<Expression>,
13328    #[serde(default)]
13329    pub charset: Option<Box<Expression>>,
13330}
13331
13332/// Encrypt
13333#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13334#[cfg_attr(feature = "bindings", derive(TS))]
13335pub struct Encrypt {
13336    pub this: Box<Expression>,
13337    #[serde(default)]
13338    pub passphrase: Option<Box<Expression>>,
13339    #[serde(default)]
13340    pub aad: Option<Box<Expression>>,
13341    #[serde(default)]
13342    pub encryption_method: Option<Box<Expression>>,
13343}
13344
13345/// EncryptRaw
13346#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13347#[cfg_attr(feature = "bindings", derive(TS))]
13348pub struct EncryptRaw {
13349    pub this: Box<Expression>,
13350    #[serde(default)]
13351    pub key: Option<Box<Expression>>,
13352    #[serde(default)]
13353    pub iv: Option<Box<Expression>>,
13354    #[serde(default)]
13355    pub aad: Option<Box<Expression>>,
13356    #[serde(default)]
13357    pub encryption_method: Option<Box<Expression>>,
13358}
13359
13360/// EqualNull
13361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13362#[cfg_attr(feature = "bindings", derive(TS))]
13363pub struct EqualNull {
13364    pub this: Box<Expression>,
13365    pub expression: Box<Expression>,
13366}
13367
13368/// ToBinary
13369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13370#[cfg_attr(feature = "bindings", derive(TS))]
13371pub struct ToBinary {
13372    pub this: Box<Expression>,
13373    #[serde(default)]
13374    pub format: Option<String>,
13375    #[serde(default)]
13376    pub safe: Option<Box<Expression>>,
13377}
13378
13379/// Base64DecodeBinary
13380#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13381#[cfg_attr(feature = "bindings", derive(TS))]
13382pub struct Base64DecodeBinary {
13383    pub this: Box<Expression>,
13384    #[serde(default)]
13385    pub alphabet: Option<Box<Expression>>,
13386}
13387
13388/// Base64DecodeString
13389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13390#[cfg_attr(feature = "bindings", derive(TS))]
13391pub struct Base64DecodeString {
13392    pub this: Box<Expression>,
13393    #[serde(default)]
13394    pub alphabet: Option<Box<Expression>>,
13395}
13396
13397/// Base64Encode
13398#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13399#[cfg_attr(feature = "bindings", derive(TS))]
13400pub struct Base64Encode {
13401    pub this: Box<Expression>,
13402    #[serde(default)]
13403    pub max_line_length: Option<Box<Expression>>,
13404    #[serde(default)]
13405    pub alphabet: Option<Box<Expression>>,
13406}
13407
13408/// TryBase64DecodeBinary
13409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13410#[cfg_attr(feature = "bindings", derive(TS))]
13411pub struct TryBase64DecodeBinary {
13412    pub this: Box<Expression>,
13413    #[serde(default)]
13414    pub alphabet: Option<Box<Expression>>,
13415}
13416
13417/// TryBase64DecodeString
13418#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13419#[cfg_attr(feature = "bindings", derive(TS))]
13420pub struct TryBase64DecodeString {
13421    pub this: Box<Expression>,
13422    #[serde(default)]
13423    pub alphabet: Option<Box<Expression>>,
13424}
13425
13426/// GapFill
13427#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13428#[cfg_attr(feature = "bindings", derive(TS))]
13429pub struct GapFill {
13430    pub this: Box<Expression>,
13431    #[serde(default)]
13432    pub ts_column: Option<Box<Expression>>,
13433    #[serde(default)]
13434    pub bucket_width: Option<Box<Expression>>,
13435    #[serde(default)]
13436    pub partitioning_columns: Option<Box<Expression>>,
13437    #[serde(default)]
13438    pub value_columns: Option<Box<Expression>>,
13439    #[serde(default)]
13440    pub origin: Option<Box<Expression>>,
13441    #[serde(default)]
13442    pub ignore_nulls: Option<Box<Expression>>,
13443}
13444
13445/// GenerateDateArray
13446#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13447#[cfg_attr(feature = "bindings", derive(TS))]
13448pub struct GenerateDateArray {
13449    #[serde(default)]
13450    pub start: Option<Box<Expression>>,
13451    #[serde(default)]
13452    pub end: Option<Box<Expression>>,
13453    #[serde(default)]
13454    pub step: Option<Box<Expression>>,
13455}
13456
13457/// GenerateTimestampArray
13458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13459#[cfg_attr(feature = "bindings", derive(TS))]
13460pub struct GenerateTimestampArray {
13461    #[serde(default)]
13462    pub start: Option<Box<Expression>>,
13463    #[serde(default)]
13464    pub end: Option<Box<Expression>>,
13465    #[serde(default)]
13466    pub step: Option<Box<Expression>>,
13467}
13468
13469/// GetExtract
13470#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13471#[cfg_attr(feature = "bindings", derive(TS))]
13472pub struct GetExtract {
13473    pub this: Box<Expression>,
13474    pub expression: Box<Expression>,
13475}
13476
13477/// Getbit
13478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13479#[cfg_attr(feature = "bindings", derive(TS))]
13480pub struct Getbit {
13481    pub this: Box<Expression>,
13482    pub expression: Box<Expression>,
13483    #[serde(default)]
13484    pub zero_is_msb: Option<Box<Expression>>,
13485}
13486
13487/// OverflowTruncateBehavior
13488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13489#[cfg_attr(feature = "bindings", derive(TS))]
13490pub struct OverflowTruncateBehavior {
13491    #[serde(default)]
13492    pub this: Option<Box<Expression>>,
13493    #[serde(default)]
13494    pub with_count: Option<Box<Expression>>,
13495}
13496
13497/// HexEncode
13498#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13499#[cfg_attr(feature = "bindings", derive(TS))]
13500pub struct HexEncode {
13501    pub this: Box<Expression>,
13502    #[serde(default)]
13503    pub case: Option<Box<Expression>>,
13504}
13505
13506/// Compress
13507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13508#[cfg_attr(feature = "bindings", derive(TS))]
13509pub struct Compress {
13510    pub this: Box<Expression>,
13511    #[serde(default)]
13512    pub method: Option<String>,
13513}
13514
13515/// DecompressBinary
13516#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13517#[cfg_attr(feature = "bindings", derive(TS))]
13518pub struct DecompressBinary {
13519    pub this: Box<Expression>,
13520    pub method: String,
13521}
13522
13523/// DecompressString
13524#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13525#[cfg_attr(feature = "bindings", derive(TS))]
13526pub struct DecompressString {
13527    pub this: Box<Expression>,
13528    pub method: String,
13529}
13530
13531/// Xor
13532#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13533#[cfg_attr(feature = "bindings", derive(TS))]
13534pub struct Xor {
13535    #[serde(default)]
13536    pub this: Option<Box<Expression>>,
13537    #[serde(default)]
13538    pub expression: Option<Box<Expression>>,
13539    #[serde(default)]
13540    pub expressions: Vec<Expression>,
13541}
13542
13543/// Nullif
13544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13545#[cfg_attr(feature = "bindings", derive(TS))]
13546pub struct Nullif {
13547    pub this: Box<Expression>,
13548    pub expression: Box<Expression>,
13549}
13550
13551/// JSON
13552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13553#[cfg_attr(feature = "bindings", derive(TS))]
13554pub struct JSON {
13555    #[serde(default)]
13556    pub this: Option<Box<Expression>>,
13557    #[serde(default)]
13558    pub with_: Option<Box<Expression>>,
13559    #[serde(default)]
13560    pub unique: bool,
13561}
13562
13563/// JSONPath
13564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13565#[cfg_attr(feature = "bindings", derive(TS))]
13566pub struct JSONPath {
13567    #[serde(default)]
13568    pub expressions: Vec<Expression>,
13569    #[serde(default)]
13570    pub escape: Option<Box<Expression>>,
13571}
13572
13573/// JSONPathFilter
13574#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13575#[cfg_attr(feature = "bindings", derive(TS))]
13576pub struct JSONPathFilter {
13577    pub this: Box<Expression>,
13578}
13579
13580/// JSONPathKey
13581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13582#[cfg_attr(feature = "bindings", derive(TS))]
13583pub struct JSONPathKey {
13584    pub this: Box<Expression>,
13585}
13586
13587/// JSONPathRecursive
13588#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13589#[cfg_attr(feature = "bindings", derive(TS))]
13590pub struct JSONPathRecursive {
13591    #[serde(default)]
13592    pub this: Option<Box<Expression>>,
13593}
13594
13595/// JSONPathScript
13596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13597#[cfg_attr(feature = "bindings", derive(TS))]
13598pub struct JSONPathScript {
13599    pub this: Box<Expression>,
13600}
13601
13602/// JSONPathSlice
13603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13604#[cfg_attr(feature = "bindings", derive(TS))]
13605pub struct JSONPathSlice {
13606    #[serde(default)]
13607    pub start: Option<Box<Expression>>,
13608    #[serde(default)]
13609    pub end: Option<Box<Expression>>,
13610    #[serde(default)]
13611    pub step: Option<Box<Expression>>,
13612}
13613
13614/// JSONPathSelector
13615#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13616#[cfg_attr(feature = "bindings", derive(TS))]
13617pub struct JSONPathSelector {
13618    pub this: Box<Expression>,
13619}
13620
13621/// JSONPathSubscript
13622#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13623#[cfg_attr(feature = "bindings", derive(TS))]
13624pub struct JSONPathSubscript {
13625    pub this: Box<Expression>,
13626}
13627
13628/// JSONPathUnion
13629#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13630#[cfg_attr(feature = "bindings", derive(TS))]
13631pub struct JSONPathUnion {
13632    #[serde(default)]
13633    pub expressions: Vec<Expression>,
13634}
13635
13636/// Format
13637#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13638#[cfg_attr(feature = "bindings", derive(TS))]
13639pub struct Format {
13640    pub this: Box<Expression>,
13641    #[serde(default)]
13642    pub expressions: Vec<Expression>,
13643}
13644
13645/// JSONKeys
13646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13647#[cfg_attr(feature = "bindings", derive(TS))]
13648pub struct JSONKeys {
13649    pub this: Box<Expression>,
13650    #[serde(default)]
13651    pub expression: Option<Box<Expression>>,
13652    #[serde(default)]
13653    pub expressions: Vec<Expression>,
13654}
13655
13656/// JSONKeyValue
13657#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13658#[cfg_attr(feature = "bindings", derive(TS))]
13659pub struct JSONKeyValue {
13660    pub this: Box<Expression>,
13661    pub expression: Box<Expression>,
13662}
13663
13664/// JSONKeysAtDepth
13665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13666#[cfg_attr(feature = "bindings", derive(TS))]
13667pub struct JSONKeysAtDepth {
13668    pub this: Box<Expression>,
13669    #[serde(default)]
13670    pub expression: Option<Box<Expression>>,
13671    #[serde(default)]
13672    pub mode: Option<Box<Expression>>,
13673}
13674
13675/// JSONObject
13676#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13677#[cfg_attr(feature = "bindings", derive(TS))]
13678pub struct JSONObject {
13679    #[serde(default)]
13680    pub expressions: Vec<Expression>,
13681    #[serde(default)]
13682    pub null_handling: Option<Box<Expression>>,
13683    #[serde(default)]
13684    pub unique_keys: Option<Box<Expression>>,
13685    #[serde(default)]
13686    pub return_type: Option<Box<Expression>>,
13687    #[serde(default)]
13688    pub encoding: Option<Box<Expression>>,
13689}
13690
13691/// JSONObjectAgg
13692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13693#[cfg_attr(feature = "bindings", derive(TS))]
13694pub struct JSONObjectAgg {
13695    #[serde(default)]
13696    pub expressions: Vec<Expression>,
13697    #[serde(default)]
13698    pub null_handling: Option<Box<Expression>>,
13699    #[serde(default)]
13700    pub unique_keys: Option<Box<Expression>>,
13701    #[serde(default)]
13702    pub return_type: Option<Box<Expression>>,
13703    #[serde(default)]
13704    pub encoding: Option<Box<Expression>>,
13705}
13706
13707/// JSONBObjectAgg
13708#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13709#[cfg_attr(feature = "bindings", derive(TS))]
13710pub struct JSONBObjectAgg {
13711    pub this: Box<Expression>,
13712    pub expression: Box<Expression>,
13713}
13714
13715/// JSONArray
13716#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13717#[cfg_attr(feature = "bindings", derive(TS))]
13718pub struct JSONArray {
13719    #[serde(default)]
13720    pub expressions: Vec<Expression>,
13721    #[serde(default)]
13722    pub null_handling: Option<Box<Expression>>,
13723    #[serde(default)]
13724    pub return_type: Option<Box<Expression>>,
13725    #[serde(default)]
13726    pub strict: Option<Box<Expression>>,
13727}
13728
13729/// JSONArrayAgg
13730#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13731#[cfg_attr(feature = "bindings", derive(TS))]
13732pub struct JSONArrayAgg {
13733    pub this: Box<Expression>,
13734    #[serde(default)]
13735    pub order: Option<Box<Expression>>,
13736    #[serde(default)]
13737    pub null_handling: Option<Box<Expression>>,
13738    #[serde(default)]
13739    pub return_type: Option<Box<Expression>>,
13740    #[serde(default)]
13741    pub strict: Option<Box<Expression>>,
13742}
13743
13744/// JSONExists
13745#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13746#[cfg_attr(feature = "bindings", derive(TS))]
13747pub struct JSONExists {
13748    pub this: Box<Expression>,
13749    #[serde(default)]
13750    pub path: Option<Box<Expression>>,
13751    #[serde(default)]
13752    pub passing: Option<Box<Expression>>,
13753    #[serde(default)]
13754    pub on_condition: Option<Box<Expression>>,
13755    #[serde(default)]
13756    pub from_dcolonqmark: Option<Box<Expression>>,
13757}
13758
13759/// JSONColumnDef
13760#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13761#[cfg_attr(feature = "bindings", derive(TS))]
13762pub struct JSONColumnDef {
13763    #[serde(default)]
13764    pub this: Option<Box<Expression>>,
13765    #[serde(default)]
13766    pub kind: Option<String>,
13767    #[serde(default)]
13768    pub format_json: bool,
13769    #[serde(default)]
13770    pub path: Option<Box<Expression>>,
13771    #[serde(default)]
13772    pub nested_schema: Option<Box<Expression>>,
13773    #[serde(default)]
13774    pub ordinality: Option<Box<Expression>>,
13775}
13776
13777/// JSONSchema
13778#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13779#[cfg_attr(feature = "bindings", derive(TS))]
13780pub struct JSONSchema {
13781    #[serde(default)]
13782    pub expressions: Vec<Expression>,
13783}
13784
13785/// JSONSet
13786#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13787#[cfg_attr(feature = "bindings", derive(TS))]
13788pub struct JSONSet {
13789    pub this: Box<Expression>,
13790    #[serde(default)]
13791    pub expressions: Vec<Expression>,
13792}
13793
13794/// JSONStripNulls
13795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13796#[cfg_attr(feature = "bindings", derive(TS))]
13797pub struct JSONStripNulls {
13798    pub this: Box<Expression>,
13799    #[serde(default)]
13800    pub expression: Option<Box<Expression>>,
13801    #[serde(default)]
13802    pub include_arrays: Option<Box<Expression>>,
13803    #[serde(default)]
13804    pub remove_empty: Option<Box<Expression>>,
13805}
13806
13807/// JSONValue
13808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13809#[cfg_attr(feature = "bindings", derive(TS))]
13810pub struct JSONValue {
13811    pub this: Box<Expression>,
13812    #[serde(default)]
13813    pub path: Option<Box<Expression>>,
13814    #[serde(default)]
13815    pub returning: Option<Box<Expression>>,
13816    #[serde(default)]
13817    pub on_condition: Option<Box<Expression>>,
13818}
13819
13820/// JSONValueArray
13821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13822#[cfg_attr(feature = "bindings", derive(TS))]
13823pub struct JSONValueArray {
13824    pub this: Box<Expression>,
13825    #[serde(default)]
13826    pub expression: Option<Box<Expression>>,
13827}
13828
13829/// JSONRemove
13830#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13831#[cfg_attr(feature = "bindings", derive(TS))]
13832pub struct JSONRemove {
13833    pub this: Box<Expression>,
13834    #[serde(default)]
13835    pub expressions: Vec<Expression>,
13836}
13837
13838/// JSONTable
13839#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13840#[cfg_attr(feature = "bindings", derive(TS))]
13841pub struct JSONTable {
13842    pub this: Box<Expression>,
13843    #[serde(default)]
13844    pub schema: Option<Box<Expression>>,
13845    #[serde(default)]
13846    pub path: Option<Box<Expression>>,
13847    #[serde(default)]
13848    pub error_handling: Option<Box<Expression>>,
13849    #[serde(default)]
13850    pub empty_handling: Option<Box<Expression>>,
13851}
13852
13853/// JSONType
13854#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13855#[cfg_attr(feature = "bindings", derive(TS))]
13856pub struct JSONType {
13857    pub this: Box<Expression>,
13858    #[serde(default)]
13859    pub expression: Option<Box<Expression>>,
13860}
13861
13862/// ObjectInsert
13863#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13864#[cfg_attr(feature = "bindings", derive(TS))]
13865pub struct ObjectInsert {
13866    pub this: Box<Expression>,
13867    #[serde(default)]
13868    pub key: Option<Box<Expression>>,
13869    #[serde(default)]
13870    pub value: Option<Box<Expression>>,
13871    #[serde(default)]
13872    pub update_flag: Option<Box<Expression>>,
13873}
13874
13875/// OpenJSONColumnDef
13876#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13877#[cfg_attr(feature = "bindings", derive(TS))]
13878pub struct OpenJSONColumnDef {
13879    pub this: Box<Expression>,
13880    pub kind: String,
13881    #[serde(default)]
13882    pub path: Option<Box<Expression>>,
13883    #[serde(default)]
13884    pub as_json: Option<Box<Expression>>,
13885    /// The parsed data type for proper generation
13886    #[serde(default, skip_serializing_if = "Option::is_none")]
13887    pub data_type: Option<DataType>,
13888}
13889
13890/// OpenJSON
13891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13892#[cfg_attr(feature = "bindings", derive(TS))]
13893pub struct OpenJSON {
13894    pub this: Box<Expression>,
13895    #[serde(default)]
13896    pub path: Option<Box<Expression>>,
13897    #[serde(default)]
13898    pub expressions: Vec<Expression>,
13899}
13900
13901/// JSONBExists
13902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13903#[cfg_attr(feature = "bindings", derive(TS))]
13904pub struct JSONBExists {
13905    pub this: Box<Expression>,
13906    #[serde(default)]
13907    pub path: Option<Box<Expression>>,
13908}
13909
13910/// JSONCast
13911#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13912#[cfg_attr(feature = "bindings", derive(TS))]
13913pub struct JSONCast {
13914    pub this: Box<Expression>,
13915    pub to: DataType,
13916}
13917
13918/// JSONExtract
13919#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13920#[cfg_attr(feature = "bindings", derive(TS))]
13921pub struct JSONExtract {
13922    pub this: Box<Expression>,
13923    pub expression: Box<Expression>,
13924    #[serde(default)]
13925    pub only_json_types: Option<Box<Expression>>,
13926    #[serde(default)]
13927    pub expressions: Vec<Expression>,
13928    #[serde(default)]
13929    pub variant_extract: Option<Box<Expression>>,
13930    #[serde(default)]
13931    pub json_query: Option<Box<Expression>>,
13932    #[serde(default)]
13933    pub option: Option<Box<Expression>>,
13934    #[serde(default)]
13935    pub quote: Option<Box<Expression>>,
13936    #[serde(default)]
13937    pub on_condition: Option<Box<Expression>>,
13938    #[serde(default)]
13939    pub requires_json: Option<Box<Expression>>,
13940}
13941
13942/// JSONExtractQuote
13943#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13944#[cfg_attr(feature = "bindings", derive(TS))]
13945pub struct JSONExtractQuote {
13946    #[serde(default)]
13947    pub option: Option<Box<Expression>>,
13948    #[serde(default)]
13949    pub scalar: Option<Box<Expression>>,
13950}
13951
13952/// JSONExtractArray
13953#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13954#[cfg_attr(feature = "bindings", derive(TS))]
13955pub struct JSONExtractArray {
13956    pub this: Box<Expression>,
13957    #[serde(default)]
13958    pub expression: Option<Box<Expression>>,
13959}
13960
13961/// JSONExtractScalar
13962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13963#[cfg_attr(feature = "bindings", derive(TS))]
13964pub struct JSONExtractScalar {
13965    pub this: Box<Expression>,
13966    pub expression: Box<Expression>,
13967    #[serde(default)]
13968    pub only_json_types: Option<Box<Expression>>,
13969    #[serde(default)]
13970    pub expressions: Vec<Expression>,
13971    #[serde(default)]
13972    pub json_type: Option<Box<Expression>>,
13973    #[serde(default)]
13974    pub scalar_only: Option<Box<Expression>>,
13975}
13976
13977/// JSONBExtractScalar
13978#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13979#[cfg_attr(feature = "bindings", derive(TS))]
13980pub struct JSONBExtractScalar {
13981    pub this: Box<Expression>,
13982    pub expression: Box<Expression>,
13983    #[serde(default)]
13984    pub json_type: Option<Box<Expression>>,
13985}
13986
13987/// JSONFormat
13988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13989#[cfg_attr(feature = "bindings", derive(TS))]
13990pub struct JSONFormat {
13991    #[serde(default)]
13992    pub this: Option<Box<Expression>>,
13993    #[serde(default)]
13994    pub options: Vec<Expression>,
13995    #[serde(default)]
13996    pub is_json: Option<Box<Expression>>,
13997    #[serde(default)]
13998    pub to_json: Option<Box<Expression>>,
13999}
14000
14001/// JSONArrayAppend
14002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14003#[cfg_attr(feature = "bindings", derive(TS))]
14004pub struct JSONArrayAppend {
14005    pub this: Box<Expression>,
14006    #[serde(default)]
14007    pub expressions: Vec<Expression>,
14008}
14009
14010/// JSONArrayContains
14011#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14012#[cfg_attr(feature = "bindings", derive(TS))]
14013pub struct JSONArrayContains {
14014    pub this: Box<Expression>,
14015    pub expression: Box<Expression>,
14016    #[serde(default)]
14017    pub json_type: Option<Box<Expression>>,
14018}
14019
14020/// JSONArrayInsert
14021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14022#[cfg_attr(feature = "bindings", derive(TS))]
14023pub struct JSONArrayInsert {
14024    pub this: Box<Expression>,
14025    #[serde(default)]
14026    pub expressions: Vec<Expression>,
14027}
14028
14029/// ParseJSON
14030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14031#[cfg_attr(feature = "bindings", derive(TS))]
14032pub struct ParseJSON {
14033    pub this: Box<Expression>,
14034    #[serde(default)]
14035    pub expression: Option<Box<Expression>>,
14036    #[serde(default)]
14037    pub safe: Option<Box<Expression>>,
14038}
14039
14040/// ParseUrl
14041#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14042#[cfg_attr(feature = "bindings", derive(TS))]
14043pub struct ParseUrl {
14044    pub this: Box<Expression>,
14045    #[serde(default)]
14046    pub part_to_extract: Option<Box<Expression>>,
14047    #[serde(default)]
14048    pub key: Option<Box<Expression>>,
14049    #[serde(default)]
14050    pub permissive: Option<Box<Expression>>,
14051}
14052
14053/// ParseIp
14054#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14055#[cfg_attr(feature = "bindings", derive(TS))]
14056pub struct ParseIp {
14057    pub this: Box<Expression>,
14058    #[serde(default)]
14059    pub type_: Option<Box<Expression>>,
14060    #[serde(default)]
14061    pub permissive: Option<Box<Expression>>,
14062}
14063
14064/// ParseTime
14065#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14066#[cfg_attr(feature = "bindings", derive(TS))]
14067pub struct ParseTime {
14068    pub this: Box<Expression>,
14069    pub format: String,
14070}
14071
14072/// ParseDatetime
14073#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14074#[cfg_attr(feature = "bindings", derive(TS))]
14075pub struct ParseDatetime {
14076    pub this: Box<Expression>,
14077    #[serde(default)]
14078    pub format: Option<String>,
14079    #[serde(default)]
14080    pub zone: Option<Box<Expression>>,
14081}
14082
14083/// Map
14084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14085#[cfg_attr(feature = "bindings", derive(TS))]
14086pub struct Map {
14087    #[serde(default)]
14088    pub keys: Vec<Expression>,
14089    #[serde(default)]
14090    pub values: Vec<Expression>,
14091}
14092
14093/// MapCat
14094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14095#[cfg_attr(feature = "bindings", derive(TS))]
14096pub struct MapCat {
14097    pub this: Box<Expression>,
14098    pub expression: Box<Expression>,
14099}
14100
14101/// MapDelete
14102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14103#[cfg_attr(feature = "bindings", derive(TS))]
14104pub struct MapDelete {
14105    pub this: Box<Expression>,
14106    #[serde(default)]
14107    pub expressions: Vec<Expression>,
14108}
14109
14110/// MapInsert
14111#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14112#[cfg_attr(feature = "bindings", derive(TS))]
14113pub struct MapInsert {
14114    pub this: Box<Expression>,
14115    #[serde(default)]
14116    pub key: Option<Box<Expression>>,
14117    #[serde(default)]
14118    pub value: Option<Box<Expression>>,
14119    #[serde(default)]
14120    pub update_flag: Option<Box<Expression>>,
14121}
14122
14123/// MapPick
14124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14125#[cfg_attr(feature = "bindings", derive(TS))]
14126pub struct MapPick {
14127    pub this: Box<Expression>,
14128    #[serde(default)]
14129    pub expressions: Vec<Expression>,
14130}
14131
14132/// ScopeResolution
14133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14134#[cfg_attr(feature = "bindings", derive(TS))]
14135pub struct ScopeResolution {
14136    #[serde(default)]
14137    pub this: Option<Box<Expression>>,
14138    pub expression: Box<Expression>,
14139}
14140
14141/// Slice
14142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14143#[cfg_attr(feature = "bindings", derive(TS))]
14144pub struct Slice {
14145    #[serde(default)]
14146    pub this: Option<Box<Expression>>,
14147    #[serde(default)]
14148    pub expression: Option<Box<Expression>>,
14149    #[serde(default)]
14150    pub step: Option<Box<Expression>>,
14151}
14152
14153/// VarMap
14154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14155#[cfg_attr(feature = "bindings", derive(TS))]
14156pub struct VarMap {
14157    #[serde(default)]
14158    pub keys: Vec<Expression>,
14159    #[serde(default)]
14160    pub values: Vec<Expression>,
14161}
14162
14163/// MatchAgainst
14164#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14165#[cfg_attr(feature = "bindings", derive(TS))]
14166pub struct MatchAgainst {
14167    pub this: Box<Expression>,
14168    #[serde(default)]
14169    pub expressions: Vec<Expression>,
14170    #[serde(default)]
14171    pub modifier: Option<Box<Expression>>,
14172}
14173
14174/// MD5Digest
14175#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14176#[cfg_attr(feature = "bindings", derive(TS))]
14177pub struct MD5Digest {
14178    pub this: Box<Expression>,
14179    #[serde(default)]
14180    pub expressions: Vec<Expression>,
14181}
14182
14183/// Monthname
14184#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14185#[cfg_attr(feature = "bindings", derive(TS))]
14186pub struct Monthname {
14187    pub this: Box<Expression>,
14188    #[serde(default)]
14189    pub abbreviated: Option<Box<Expression>>,
14190}
14191
14192/// Ntile
14193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14194#[cfg_attr(feature = "bindings", derive(TS))]
14195pub struct Ntile {
14196    #[serde(default)]
14197    pub this: Option<Box<Expression>>,
14198}
14199
14200/// Normalize
14201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14202#[cfg_attr(feature = "bindings", derive(TS))]
14203pub struct Normalize {
14204    pub this: Box<Expression>,
14205    #[serde(default)]
14206    pub form: Option<Box<Expression>>,
14207    #[serde(default)]
14208    pub is_casefold: Option<Box<Expression>>,
14209}
14210
14211/// Normal
14212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14213#[cfg_attr(feature = "bindings", derive(TS))]
14214pub struct Normal {
14215    pub this: Box<Expression>,
14216    #[serde(default)]
14217    pub stddev: Option<Box<Expression>>,
14218    #[serde(default)]
14219    pub gen: Option<Box<Expression>>,
14220}
14221
14222/// Predict
14223#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14224#[cfg_attr(feature = "bindings", derive(TS))]
14225pub struct Predict {
14226    pub this: Box<Expression>,
14227    pub expression: Box<Expression>,
14228    #[serde(default)]
14229    pub params_struct: Option<Box<Expression>>,
14230}
14231
14232/// MLTranslate
14233#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14234#[cfg_attr(feature = "bindings", derive(TS))]
14235pub struct MLTranslate {
14236    pub this: Box<Expression>,
14237    pub expression: Box<Expression>,
14238    #[serde(default)]
14239    pub params_struct: Option<Box<Expression>>,
14240}
14241
14242/// FeaturesAtTime
14243#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14244#[cfg_attr(feature = "bindings", derive(TS))]
14245pub struct FeaturesAtTime {
14246    pub this: Box<Expression>,
14247    #[serde(default)]
14248    pub time: Option<Box<Expression>>,
14249    #[serde(default)]
14250    pub num_rows: Option<Box<Expression>>,
14251    #[serde(default)]
14252    pub ignore_feature_nulls: Option<Box<Expression>>,
14253}
14254
14255/// GenerateEmbedding
14256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14257#[cfg_attr(feature = "bindings", derive(TS))]
14258pub struct GenerateEmbedding {
14259    pub this: Box<Expression>,
14260    pub expression: Box<Expression>,
14261    #[serde(default)]
14262    pub params_struct: Option<Box<Expression>>,
14263    #[serde(default)]
14264    pub is_text: Option<Box<Expression>>,
14265}
14266
14267/// MLForecast
14268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14269#[cfg_attr(feature = "bindings", derive(TS))]
14270pub struct MLForecast {
14271    pub this: Box<Expression>,
14272    #[serde(default)]
14273    pub expression: Option<Box<Expression>>,
14274    #[serde(default)]
14275    pub params_struct: Option<Box<Expression>>,
14276}
14277
14278/// ModelAttribute
14279#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14280#[cfg_attr(feature = "bindings", derive(TS))]
14281pub struct ModelAttribute {
14282    pub this: Box<Expression>,
14283    pub expression: Box<Expression>,
14284}
14285
14286/// VectorSearch
14287#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14288#[cfg_attr(feature = "bindings", derive(TS))]
14289pub struct VectorSearch {
14290    pub this: Box<Expression>,
14291    #[serde(default)]
14292    pub column_to_search: Option<Box<Expression>>,
14293    #[serde(default)]
14294    pub query_table: Option<Box<Expression>>,
14295    #[serde(default)]
14296    pub query_column_to_search: Option<Box<Expression>>,
14297    #[serde(default)]
14298    pub top_k: Option<Box<Expression>>,
14299    #[serde(default)]
14300    pub distance_type: Option<Box<Expression>>,
14301    #[serde(default)]
14302    pub options: Vec<Expression>,
14303}
14304
14305/// Quantile
14306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14307#[cfg_attr(feature = "bindings", derive(TS))]
14308pub struct Quantile {
14309    pub this: Box<Expression>,
14310    #[serde(default)]
14311    pub quantile: Option<Box<Expression>>,
14312}
14313
14314/// ApproxQuantile
14315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14316#[cfg_attr(feature = "bindings", derive(TS))]
14317pub struct ApproxQuantile {
14318    pub this: Box<Expression>,
14319    #[serde(default)]
14320    pub quantile: Option<Box<Expression>>,
14321    #[serde(default)]
14322    pub accuracy: Option<Box<Expression>>,
14323    #[serde(default)]
14324    pub weight: Option<Box<Expression>>,
14325    #[serde(default)]
14326    pub error_tolerance: Option<Box<Expression>>,
14327}
14328
14329/// ApproxPercentileEstimate
14330#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14331#[cfg_attr(feature = "bindings", derive(TS))]
14332pub struct ApproxPercentileEstimate {
14333    pub this: Box<Expression>,
14334    #[serde(default)]
14335    pub percentile: Option<Box<Expression>>,
14336}
14337
14338/// Randn
14339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14340#[cfg_attr(feature = "bindings", derive(TS))]
14341pub struct Randn {
14342    #[serde(default)]
14343    pub this: Option<Box<Expression>>,
14344}
14345
14346/// Randstr
14347#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14348#[cfg_attr(feature = "bindings", derive(TS))]
14349pub struct Randstr {
14350    pub this: Box<Expression>,
14351    #[serde(default)]
14352    pub generator: Option<Box<Expression>>,
14353}
14354
14355/// RangeN
14356#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14357#[cfg_attr(feature = "bindings", derive(TS))]
14358pub struct RangeN {
14359    pub this: Box<Expression>,
14360    #[serde(default)]
14361    pub expressions: Vec<Expression>,
14362    #[serde(default)]
14363    pub each: Option<Box<Expression>>,
14364}
14365
14366/// RangeBucket
14367#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14368#[cfg_attr(feature = "bindings", derive(TS))]
14369pub struct RangeBucket {
14370    pub this: Box<Expression>,
14371    pub expression: Box<Expression>,
14372}
14373
14374/// ReadCSV
14375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14376#[cfg_attr(feature = "bindings", derive(TS))]
14377pub struct ReadCSV {
14378    pub this: Box<Expression>,
14379    #[serde(default)]
14380    pub expressions: Vec<Expression>,
14381}
14382
14383/// ReadParquet
14384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14385#[cfg_attr(feature = "bindings", derive(TS))]
14386pub struct ReadParquet {
14387    #[serde(default)]
14388    pub expressions: Vec<Expression>,
14389}
14390
14391/// Reduce
14392#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14393#[cfg_attr(feature = "bindings", derive(TS))]
14394pub struct Reduce {
14395    pub this: Box<Expression>,
14396    #[serde(default)]
14397    pub initial: Option<Box<Expression>>,
14398    #[serde(default)]
14399    pub merge: Option<Box<Expression>>,
14400    #[serde(default)]
14401    pub finish: Option<Box<Expression>>,
14402}
14403
14404/// RegexpExtractAll
14405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14406#[cfg_attr(feature = "bindings", derive(TS))]
14407pub struct RegexpExtractAll {
14408    pub this: Box<Expression>,
14409    pub expression: Box<Expression>,
14410    #[serde(default)]
14411    pub group: Option<Box<Expression>>,
14412    #[serde(default)]
14413    pub parameters: Option<Box<Expression>>,
14414    #[serde(default)]
14415    pub position: Option<Box<Expression>>,
14416    #[serde(default)]
14417    pub occurrence: Option<Box<Expression>>,
14418}
14419
14420/// RegexpILike
14421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14422#[cfg_attr(feature = "bindings", derive(TS))]
14423pub struct RegexpILike {
14424    pub this: Box<Expression>,
14425    pub expression: Box<Expression>,
14426    #[serde(default)]
14427    pub flag: Option<Box<Expression>>,
14428}
14429
14430/// RegexpFullMatch
14431#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14432#[cfg_attr(feature = "bindings", derive(TS))]
14433pub struct RegexpFullMatch {
14434    pub this: Box<Expression>,
14435    pub expression: Box<Expression>,
14436    #[serde(default)]
14437    pub options: Vec<Expression>,
14438}
14439
14440/// RegexpInstr
14441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14442#[cfg_attr(feature = "bindings", derive(TS))]
14443pub struct RegexpInstr {
14444    pub this: Box<Expression>,
14445    pub expression: Box<Expression>,
14446    #[serde(default)]
14447    pub position: Option<Box<Expression>>,
14448    #[serde(default)]
14449    pub occurrence: Option<Box<Expression>>,
14450    #[serde(default)]
14451    pub option: Option<Box<Expression>>,
14452    #[serde(default)]
14453    pub parameters: Option<Box<Expression>>,
14454    #[serde(default)]
14455    pub group: Option<Box<Expression>>,
14456}
14457
14458/// RegexpSplit
14459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14460#[cfg_attr(feature = "bindings", derive(TS))]
14461pub struct RegexpSplit {
14462    pub this: Box<Expression>,
14463    pub expression: Box<Expression>,
14464    #[serde(default)]
14465    pub limit: Option<Box<Expression>>,
14466}
14467
14468/// RegexpCount
14469#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14470#[cfg_attr(feature = "bindings", derive(TS))]
14471pub struct RegexpCount {
14472    pub this: Box<Expression>,
14473    pub expression: Box<Expression>,
14474    #[serde(default)]
14475    pub position: Option<Box<Expression>>,
14476    #[serde(default)]
14477    pub parameters: Option<Box<Expression>>,
14478}
14479
14480/// RegrValx
14481#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14482#[cfg_attr(feature = "bindings", derive(TS))]
14483pub struct RegrValx {
14484    pub this: Box<Expression>,
14485    pub expression: Box<Expression>,
14486}
14487
14488/// RegrValy
14489#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14490#[cfg_attr(feature = "bindings", derive(TS))]
14491pub struct RegrValy {
14492    pub this: Box<Expression>,
14493    pub expression: Box<Expression>,
14494}
14495
14496/// RegrAvgy
14497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14498#[cfg_attr(feature = "bindings", derive(TS))]
14499pub struct RegrAvgy {
14500    pub this: Box<Expression>,
14501    pub expression: Box<Expression>,
14502}
14503
14504/// RegrAvgx
14505#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14506#[cfg_attr(feature = "bindings", derive(TS))]
14507pub struct RegrAvgx {
14508    pub this: Box<Expression>,
14509    pub expression: Box<Expression>,
14510}
14511
14512/// RegrCount
14513#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14514#[cfg_attr(feature = "bindings", derive(TS))]
14515pub struct RegrCount {
14516    pub this: Box<Expression>,
14517    pub expression: Box<Expression>,
14518}
14519
14520/// RegrIntercept
14521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14522#[cfg_attr(feature = "bindings", derive(TS))]
14523pub struct RegrIntercept {
14524    pub this: Box<Expression>,
14525    pub expression: Box<Expression>,
14526}
14527
14528/// RegrR2
14529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14530#[cfg_attr(feature = "bindings", derive(TS))]
14531pub struct RegrR2 {
14532    pub this: Box<Expression>,
14533    pub expression: Box<Expression>,
14534}
14535
14536/// RegrSxx
14537#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14538#[cfg_attr(feature = "bindings", derive(TS))]
14539pub struct RegrSxx {
14540    pub this: Box<Expression>,
14541    pub expression: Box<Expression>,
14542}
14543
14544/// RegrSxy
14545#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14546#[cfg_attr(feature = "bindings", derive(TS))]
14547pub struct RegrSxy {
14548    pub this: Box<Expression>,
14549    pub expression: Box<Expression>,
14550}
14551
14552/// RegrSyy
14553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14554#[cfg_attr(feature = "bindings", derive(TS))]
14555pub struct RegrSyy {
14556    pub this: Box<Expression>,
14557    pub expression: Box<Expression>,
14558}
14559
14560/// RegrSlope
14561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14562#[cfg_attr(feature = "bindings", derive(TS))]
14563pub struct RegrSlope {
14564    pub this: Box<Expression>,
14565    pub expression: Box<Expression>,
14566}
14567
14568/// SafeAdd
14569#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14570#[cfg_attr(feature = "bindings", derive(TS))]
14571pub struct SafeAdd {
14572    pub this: Box<Expression>,
14573    pub expression: Box<Expression>,
14574}
14575
14576/// SafeDivide
14577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14578#[cfg_attr(feature = "bindings", derive(TS))]
14579pub struct SafeDivide {
14580    pub this: Box<Expression>,
14581    pub expression: Box<Expression>,
14582}
14583
14584/// SafeMultiply
14585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14586#[cfg_attr(feature = "bindings", derive(TS))]
14587pub struct SafeMultiply {
14588    pub this: Box<Expression>,
14589    pub expression: Box<Expression>,
14590}
14591
14592/// SafeSubtract
14593#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14594#[cfg_attr(feature = "bindings", derive(TS))]
14595pub struct SafeSubtract {
14596    pub this: Box<Expression>,
14597    pub expression: Box<Expression>,
14598}
14599
14600/// SHA2
14601#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14602#[cfg_attr(feature = "bindings", derive(TS))]
14603pub struct SHA2 {
14604    pub this: Box<Expression>,
14605    #[serde(default)]
14606    pub length: Option<i64>,
14607}
14608
14609/// SHA2Digest
14610#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14611#[cfg_attr(feature = "bindings", derive(TS))]
14612pub struct SHA2Digest {
14613    pub this: Box<Expression>,
14614    #[serde(default)]
14615    pub length: Option<i64>,
14616}
14617
14618/// SortArray
14619#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14620#[cfg_attr(feature = "bindings", derive(TS))]
14621pub struct SortArray {
14622    pub this: Box<Expression>,
14623    #[serde(default)]
14624    pub asc: Option<Box<Expression>>,
14625    #[serde(default)]
14626    pub nulls_first: Option<Box<Expression>>,
14627}
14628
14629/// SplitPart
14630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14631#[cfg_attr(feature = "bindings", derive(TS))]
14632pub struct SplitPart {
14633    pub this: Box<Expression>,
14634    #[serde(default)]
14635    pub delimiter: Option<Box<Expression>>,
14636    #[serde(default)]
14637    pub part_index: Option<Box<Expression>>,
14638}
14639
14640/// SUBSTRING_INDEX(str, delim, count)
14641#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14642#[cfg_attr(feature = "bindings", derive(TS))]
14643pub struct SubstringIndex {
14644    pub this: Box<Expression>,
14645    #[serde(default)]
14646    pub delimiter: Option<Box<Expression>>,
14647    #[serde(default)]
14648    pub count: Option<Box<Expression>>,
14649}
14650
14651/// StandardHash
14652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14653#[cfg_attr(feature = "bindings", derive(TS))]
14654pub struct StandardHash {
14655    pub this: Box<Expression>,
14656    #[serde(default)]
14657    pub expression: Option<Box<Expression>>,
14658}
14659
14660/// StrPosition
14661#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14662#[cfg_attr(feature = "bindings", derive(TS))]
14663pub struct StrPosition {
14664    pub this: Box<Expression>,
14665    #[serde(default)]
14666    pub substr: Option<Box<Expression>>,
14667    #[serde(default)]
14668    pub position: Option<Box<Expression>>,
14669    #[serde(default)]
14670    pub occurrence: Option<Box<Expression>>,
14671}
14672
14673/// Search
14674#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14675#[cfg_attr(feature = "bindings", derive(TS))]
14676pub struct Search {
14677    pub this: Box<Expression>,
14678    pub expression: Box<Expression>,
14679    #[serde(default)]
14680    pub json_scope: Option<Box<Expression>>,
14681    #[serde(default)]
14682    pub analyzer: Option<Box<Expression>>,
14683    #[serde(default)]
14684    pub analyzer_options: Option<Box<Expression>>,
14685    #[serde(default)]
14686    pub search_mode: Option<Box<Expression>>,
14687}
14688
14689/// SearchIp
14690#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14691#[cfg_attr(feature = "bindings", derive(TS))]
14692pub struct SearchIp {
14693    pub this: Box<Expression>,
14694    pub expression: Box<Expression>,
14695}
14696
14697/// StrToDate
14698#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14699#[cfg_attr(feature = "bindings", derive(TS))]
14700pub struct StrToDate {
14701    pub this: Box<Expression>,
14702    #[serde(default)]
14703    pub format: Option<String>,
14704    #[serde(default)]
14705    pub safe: Option<Box<Expression>>,
14706}
14707
14708/// StrToTime
14709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14710#[cfg_attr(feature = "bindings", derive(TS))]
14711pub struct StrToTime {
14712    pub this: Box<Expression>,
14713    pub format: String,
14714    #[serde(default)]
14715    pub zone: Option<Box<Expression>>,
14716    #[serde(default)]
14717    pub safe: Option<Box<Expression>>,
14718    #[serde(default)]
14719    pub target_type: Option<Box<Expression>>,
14720}
14721
14722/// StrToUnix
14723#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14724#[cfg_attr(feature = "bindings", derive(TS))]
14725pub struct StrToUnix {
14726    #[serde(default)]
14727    pub this: Option<Box<Expression>>,
14728    #[serde(default)]
14729    pub format: Option<String>,
14730}
14731
14732/// StrToMap
14733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14734#[cfg_attr(feature = "bindings", derive(TS))]
14735pub struct StrToMap {
14736    pub this: Box<Expression>,
14737    #[serde(default)]
14738    pub pair_delim: Option<Box<Expression>>,
14739    #[serde(default)]
14740    pub key_value_delim: Option<Box<Expression>>,
14741    #[serde(default)]
14742    pub duplicate_resolution_callback: Option<Box<Expression>>,
14743}
14744
14745/// NumberToStr
14746#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14747#[cfg_attr(feature = "bindings", derive(TS))]
14748pub struct NumberToStr {
14749    pub this: Box<Expression>,
14750    pub format: String,
14751    #[serde(default)]
14752    pub culture: Option<Box<Expression>>,
14753}
14754
14755/// FromBase
14756#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14757#[cfg_attr(feature = "bindings", derive(TS))]
14758pub struct FromBase {
14759    pub this: Box<Expression>,
14760    pub expression: Box<Expression>,
14761}
14762
14763/// Stuff
14764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14765#[cfg_attr(feature = "bindings", derive(TS))]
14766pub struct Stuff {
14767    pub this: Box<Expression>,
14768    #[serde(default)]
14769    pub start: Option<Box<Expression>>,
14770    #[serde(default)]
14771    pub length: Option<i64>,
14772    pub expression: Box<Expression>,
14773}
14774
14775/// TimeToStr
14776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14777#[cfg_attr(feature = "bindings", derive(TS))]
14778pub struct TimeToStr {
14779    pub this: Box<Expression>,
14780    pub format: String,
14781    #[serde(default)]
14782    pub culture: Option<Box<Expression>>,
14783    #[serde(default)]
14784    pub zone: Option<Box<Expression>>,
14785}
14786
14787/// TimeStrToTime
14788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14789#[cfg_attr(feature = "bindings", derive(TS))]
14790pub struct TimeStrToTime {
14791    pub this: Box<Expression>,
14792    #[serde(default)]
14793    pub zone: Option<Box<Expression>>,
14794}
14795
14796/// TsOrDsAdd
14797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14798#[cfg_attr(feature = "bindings", derive(TS))]
14799pub struct TsOrDsAdd {
14800    pub this: Box<Expression>,
14801    pub expression: Box<Expression>,
14802    #[serde(default)]
14803    pub unit: Option<String>,
14804    #[serde(default)]
14805    pub return_type: Option<Box<Expression>>,
14806}
14807
14808/// TsOrDsDiff
14809#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14810#[cfg_attr(feature = "bindings", derive(TS))]
14811pub struct TsOrDsDiff {
14812    pub this: Box<Expression>,
14813    pub expression: Box<Expression>,
14814    #[serde(default)]
14815    pub unit: Option<String>,
14816}
14817
14818/// TsOrDsToDate
14819#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14820#[cfg_attr(feature = "bindings", derive(TS))]
14821pub struct TsOrDsToDate {
14822    pub this: Box<Expression>,
14823    #[serde(default)]
14824    pub format: Option<String>,
14825    #[serde(default)]
14826    pub safe: Option<Box<Expression>>,
14827}
14828
14829/// TsOrDsToTime
14830#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14831#[cfg_attr(feature = "bindings", derive(TS))]
14832pub struct TsOrDsToTime {
14833    pub this: Box<Expression>,
14834    #[serde(default)]
14835    pub format: Option<String>,
14836    #[serde(default)]
14837    pub safe: Option<Box<Expression>>,
14838}
14839
14840/// Unhex
14841#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14842#[cfg_attr(feature = "bindings", derive(TS))]
14843pub struct Unhex {
14844    pub this: Box<Expression>,
14845    #[serde(default)]
14846    pub expression: Option<Box<Expression>>,
14847}
14848
14849/// Uniform
14850#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14851#[cfg_attr(feature = "bindings", derive(TS))]
14852pub struct Uniform {
14853    pub this: Box<Expression>,
14854    pub expression: Box<Expression>,
14855    #[serde(default)]
14856    pub gen: Option<Box<Expression>>,
14857    #[serde(default)]
14858    pub seed: Option<Box<Expression>>,
14859}
14860
14861/// UnixToStr
14862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14863#[cfg_attr(feature = "bindings", derive(TS))]
14864pub struct UnixToStr {
14865    pub this: Box<Expression>,
14866    #[serde(default)]
14867    pub format: Option<String>,
14868}
14869
14870/// UnixToTime
14871#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14872#[cfg_attr(feature = "bindings", derive(TS))]
14873pub struct UnixToTime {
14874    pub this: Box<Expression>,
14875    #[serde(default)]
14876    pub scale: Option<i64>,
14877    #[serde(default)]
14878    pub zone: Option<Box<Expression>>,
14879    #[serde(default)]
14880    pub hours: Option<Box<Expression>>,
14881    #[serde(default)]
14882    pub minutes: Option<Box<Expression>>,
14883    #[serde(default)]
14884    pub format: Option<String>,
14885    #[serde(default)]
14886    pub target_type: Option<Box<Expression>>,
14887}
14888
14889/// Uuid
14890#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14891#[cfg_attr(feature = "bindings", derive(TS))]
14892pub struct Uuid {
14893    #[serde(default)]
14894    pub this: Option<Box<Expression>>,
14895    #[serde(default)]
14896    pub name: Option<String>,
14897    #[serde(default)]
14898    pub is_string: Option<Box<Expression>>,
14899}
14900
14901/// TimestampFromParts
14902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14903#[cfg_attr(feature = "bindings", derive(TS))]
14904pub struct TimestampFromParts {
14905    #[serde(default)]
14906    pub zone: Option<Box<Expression>>,
14907    #[serde(default)]
14908    pub milli: Option<Box<Expression>>,
14909    #[serde(default)]
14910    pub this: Option<Box<Expression>>,
14911    #[serde(default)]
14912    pub expression: Option<Box<Expression>>,
14913}
14914
14915/// TimestampTzFromParts
14916#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14917#[cfg_attr(feature = "bindings", derive(TS))]
14918pub struct TimestampTzFromParts {
14919    #[serde(default)]
14920    pub zone: Option<Box<Expression>>,
14921}
14922
14923/// Corr
14924#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14925#[cfg_attr(feature = "bindings", derive(TS))]
14926pub struct Corr {
14927    pub this: Box<Expression>,
14928    pub expression: Box<Expression>,
14929    #[serde(default)]
14930    pub null_on_zero_variance: Option<Box<Expression>>,
14931}
14932
14933/// WidthBucket
14934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14935#[cfg_attr(feature = "bindings", derive(TS))]
14936pub struct WidthBucket {
14937    pub this: Box<Expression>,
14938    #[serde(default)]
14939    pub min_value: Option<Box<Expression>>,
14940    #[serde(default)]
14941    pub max_value: Option<Box<Expression>>,
14942    #[serde(default)]
14943    pub num_buckets: Option<Box<Expression>>,
14944    #[serde(default)]
14945    pub threshold: Option<Box<Expression>>,
14946}
14947
14948/// CovarSamp
14949#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14950#[cfg_attr(feature = "bindings", derive(TS))]
14951pub struct CovarSamp {
14952    pub this: Box<Expression>,
14953    pub expression: Box<Expression>,
14954}
14955
14956/// CovarPop
14957#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14958#[cfg_attr(feature = "bindings", derive(TS))]
14959pub struct CovarPop {
14960    pub this: Box<Expression>,
14961    pub expression: Box<Expression>,
14962}
14963
14964/// Week
14965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14966#[cfg_attr(feature = "bindings", derive(TS))]
14967pub struct Week {
14968    pub this: Box<Expression>,
14969    #[serde(default)]
14970    pub mode: Option<Box<Expression>>,
14971}
14972
14973/// XMLElement
14974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14975#[cfg_attr(feature = "bindings", derive(TS))]
14976pub struct XMLElement {
14977    pub this: Box<Expression>,
14978    #[serde(default)]
14979    pub expressions: Vec<Expression>,
14980    #[serde(default)]
14981    pub evalname: Option<Box<Expression>>,
14982}
14983
14984/// XMLGet
14985#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14986#[cfg_attr(feature = "bindings", derive(TS))]
14987pub struct XMLGet {
14988    pub this: Box<Expression>,
14989    pub expression: Box<Expression>,
14990    #[serde(default)]
14991    pub instance: Option<Box<Expression>>,
14992}
14993
14994/// XMLTable
14995#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14996#[cfg_attr(feature = "bindings", derive(TS))]
14997pub struct XMLTable {
14998    pub this: Box<Expression>,
14999    #[serde(default)]
15000    pub namespaces: Option<Box<Expression>>,
15001    #[serde(default)]
15002    pub passing: Option<Box<Expression>>,
15003    #[serde(default)]
15004    pub columns: Vec<Expression>,
15005    #[serde(default)]
15006    pub by_ref: Option<Box<Expression>>,
15007}
15008
15009/// XMLKeyValueOption
15010#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15011#[cfg_attr(feature = "bindings", derive(TS))]
15012pub struct XMLKeyValueOption {
15013    pub this: Box<Expression>,
15014    #[serde(default)]
15015    pub expression: Option<Box<Expression>>,
15016}
15017
15018/// Zipf
15019#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15020#[cfg_attr(feature = "bindings", derive(TS))]
15021pub struct Zipf {
15022    pub this: Box<Expression>,
15023    #[serde(default)]
15024    pub elementcount: Option<Box<Expression>>,
15025    #[serde(default)]
15026    pub gen: Option<Box<Expression>>,
15027}
15028
15029/// Merge
15030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15031#[cfg_attr(feature = "bindings", derive(TS))]
15032pub struct Merge {
15033    pub this: Box<Expression>,
15034    pub using: Box<Expression>,
15035    #[serde(default)]
15036    pub on: Option<Box<Expression>>,
15037    #[serde(default)]
15038    pub using_cond: Option<Box<Expression>>,
15039    #[serde(default)]
15040    pub whens: Option<Box<Expression>>,
15041    #[serde(default)]
15042    pub with_: Option<Box<Expression>>,
15043    #[serde(default)]
15044    pub returning: Option<Box<Expression>>,
15045}
15046
15047/// When
15048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15049#[cfg_attr(feature = "bindings", derive(TS))]
15050pub struct When {
15051    #[serde(default)]
15052    pub matched: Option<Box<Expression>>,
15053    #[serde(default)]
15054    pub source: Option<Box<Expression>>,
15055    #[serde(default)]
15056    pub condition: Option<Box<Expression>>,
15057    pub then: Box<Expression>,
15058}
15059
15060/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15061#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15062#[cfg_attr(feature = "bindings", derive(TS))]
15063pub struct Whens {
15064    #[serde(default)]
15065    pub expressions: Vec<Expression>,
15066}
15067
15068/// NextValueFor
15069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15070#[cfg_attr(feature = "bindings", derive(TS))]
15071pub struct NextValueFor {
15072    pub this: Box<Expression>,
15073    #[serde(default)]
15074    pub order: Option<Box<Expression>>,
15075}
15076
15077#[cfg(test)]
15078mod tests {
15079    use super::*;
15080
15081    #[test]
15082    #[cfg(feature = "bindings")]
15083    fn export_typescript_types() {
15084        // This test exports TypeScript types to the generated directory
15085        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
15086        Expression::export_all(&ts_rs::Config::default())
15087            .expect("Failed to export Expression types");
15088    }
15089
15090    #[test]
15091    fn test_simple_select_builder() {
15092        let select = Select::new()
15093            .column(Expression::star())
15094            .from(Expression::Table(Box::new(TableRef::new("users"))));
15095
15096        assert_eq!(select.expressions.len(), 1);
15097        assert!(select.from.is_some());
15098    }
15099
15100    #[test]
15101    fn test_expression_alias() {
15102        let expr = Expression::column("id").alias("user_id");
15103
15104        match expr {
15105            Expression::Alias(a) => {
15106                assert_eq!(a.alias.name, "user_id");
15107            }
15108            _ => panic!("Expected Alias"),
15109        }
15110    }
15111
15112    #[test]
15113    fn test_literal_creation() {
15114        let num = Expression::number(42);
15115        let str = Expression::string("hello");
15116
15117        match num {
15118            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
15119                let Literal::Number(n) = lit.as_ref() else {
15120                    unreachable!()
15121                };
15122                assert_eq!(n, "42")
15123            }
15124            _ => panic!("Expected Number"),
15125        }
15126
15127        match str {
15128            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
15129                let Literal::String(s) = lit.as_ref() else {
15130                    unreachable!()
15131                };
15132                assert_eq!(s, "hello")
15133            }
15134            _ => panic!("Expected String"),
15135        }
15136    }
15137
15138    #[test]
15139    fn test_expression_sql() {
15140        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
15141        assert_eq!(expr.sql(), "SELECT 1 + 2");
15142    }
15143
15144    #[test]
15145    fn test_expression_sql_for() {
15146        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
15147        let sql = expr.sql_for(crate::DialectType::Generic);
15148        // Generic mode normalizes IF() to CASE WHEN
15149        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
15150    }
15151}