Skip to main content

polyglot_sql/
expressions.rs

1//! SQL Expression AST (Abstract Syntax Tree).
2//!
3//! This module defines all the AST node types used to represent parsed SQL
4//! statements and expressions. The design follows Python sqlglot's expression
5//! hierarchy, ported to a Rust enum-based AST.
6//!
7//! # Architecture
8//!
9//! The central type is [`Expression`], a large tagged enum with one variant per
10//! SQL construct. Inner structs carry the fields for each variant. Most
11//! heap-allocated variants are wrapped in `Box` to keep the enum size small.
12//!
13//! # Variant Groups
14//!
15//! | Group | Examples | Purpose |
16//! |---|---|---|
17//! | **Queries** | `Select`, `Union`, `Intersect`, `Except`, `Subquery` | Top-level query structures |
18//! | **DML** | `Insert`, `Update`, `Delete`, `Merge`, `Copy` | Data manipulation |
19//! | **DDL** | `CreateTable`, `AlterTable`, `DropView`, `CreateIndex` | Schema definition |
20//! | **Clauses** | `From`, `Join`, `Where`, `GroupBy`, `OrderBy`, `With` | Query clauses |
21//! | **Operators** | `And`, `Or`, `Add`, `Eq`, `Like`, `Not` | Binary and unary operations |
22//! | **Functions** | `Function`, `AggregateFunction`, `WindowFunction`, `Count`, `Sum` | Scalar, aggregate, and window functions |
23//! | **Literals** | `Literal`, `Boolean`, `Null`, `Interval` | Constant values |
24//! | **Types** | `DataType`, `Cast`, `TryCast`, `SafeCast` | Data types and casts |
25//! | **Identifiers** | `Identifier`, `Column`, `Table`, `Star` | Name references |
26//!
27//! # SQL Generation
28//!
29//! Every `Expression` can be rendered back to SQL via [`Expression::sql()`]
30//! (generic dialect) or [`Expression::sql_for()`] (specific dialect). The
31//! actual generation logic lives in the `generator` module.
32
33use crate::tokens::Span;
34use serde::{Deserialize, Serialize};
35use std::fmt;
36#[cfg(feature = "bindings")]
37use ts_rs::TS;
38
39/// Helper function for serde default value
40fn default_true() -> bool {
41    true
42}
43
44fn is_true(v: &bool) -> bool {
45    *v
46}
47
48/// Represent any SQL expression or statement as a single, recursive AST node.
49///
50/// `Expression` is the root type of the polyglot AST. Every parsed SQL
51/// construct -- from a simple integer literal to a multi-CTE query with
52/// window functions -- is represented as a variant of this enum.
53///
54/// Variants are organized into logical groups (see the module-level docs).
55/// Most non-trivial variants box their payload so that `size_of::<Expression>()`
56/// stays small (currently two words: tag + pointer).
57///
58/// # Constructing Expressions
59///
60/// Use the convenience constructors on `impl Expression` for common cases:
61///
62/// ```rust,ignore
63/// use polyglot_sql::expressions::Expression;
64///
65/// let col  = Expression::column("id");
66/// let lit  = Expression::number(42);
67/// let star = Expression::star();
68/// ```
69///
70/// # Generating SQL
71///
72/// ```rust,ignore
73/// let expr = Expression::column("name");
74/// assert_eq!(expr.sql(), "name");
75/// ```
76#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
77#[cfg_attr(feature = "bindings", derive(TS))]
78#[serde(rename_all = "snake_case")]
79#[cfg_attr(feature = "bindings", ts(export))]
80pub enum Expression {
81    // Literals
82    Literal(Box<Literal>),
83    Boolean(BooleanLiteral),
84    Null(Null),
85
86    // Identifiers
87    Identifier(Identifier),
88    Column(Box<Column>),
89    Table(Box<TableRef>),
90    Star(Star),
91    /// Snowflake braced wildcard syntax: {*}, {tbl.*}, {* EXCLUDE (...)}, {* ILIKE '...'}
92    BracedWildcard(Box<Expression>),
93
94    // Queries
95    Select(Box<Select>),
96    Union(Box<Union>),
97    Intersect(Box<Intersect>),
98    Except(Box<Except>),
99    Subquery(Box<Subquery>),
100    PipeOperator(Box<PipeOperator>),
101    Pivot(Box<Pivot>),
102    PivotAlias(Box<PivotAlias>),
103    Unpivot(Box<Unpivot>),
104    Values(Box<Values>),
105    PreWhere(Box<PreWhere>),
106    Stream(Box<Stream>),
107    UsingData(Box<UsingData>),
108    XmlNamespace(Box<XmlNamespace>),
109
110    // DML
111    Insert(Box<Insert>),
112    Update(Box<Update>),
113    Delete(Box<Delete>),
114    Copy(Box<CopyStmt>),
115    Put(Box<PutStmt>),
116    StageReference(Box<StageReference>),
117    TryCatch(Box<TryCatch>),
118
119    // Expressions
120    Alias(Box<Alias>),
121    Cast(Box<Cast>),
122    Collation(Box<CollationExpr>),
123    Case(Box<Case>),
124
125    // Binary operations
126    And(Box<BinaryOp>),
127    Or(Box<BinaryOp>),
128    Add(Box<BinaryOp>),
129    Sub(Box<BinaryOp>),
130    Mul(Box<BinaryOp>),
131    Div(Box<BinaryOp>),
132    Mod(Box<BinaryOp>),
133    Eq(Box<BinaryOp>),
134    Neq(Box<BinaryOp>),
135    Lt(Box<BinaryOp>),
136    Lte(Box<BinaryOp>),
137    Gt(Box<BinaryOp>),
138    Gte(Box<BinaryOp>),
139    Like(Box<LikeOp>),
140    ILike(Box<LikeOp>),
141    /// SQLite MATCH operator (FTS)
142    Match(Box<BinaryOp>),
143    BitwiseAnd(Box<BinaryOp>),
144    BitwiseOr(Box<BinaryOp>),
145    BitwiseXor(Box<BinaryOp>),
146    Concat(Box<BinaryOp>),
147    Adjacent(Box<BinaryOp>),   // PostgreSQL range adjacency operator (-|-)
148    TsMatch(Box<BinaryOp>),    // PostgreSQL text search match operator (@@)
149    PropertyEQ(Box<BinaryOp>), // := assignment operator (MySQL @var := val, DuckDB named args)
150
151    // PostgreSQL array/JSONB operators
152    ArrayContainsAll(Box<BinaryOp>), // @> operator (array contains all)
153    ArrayContainedBy(Box<BinaryOp>), // <@ operator (array contained by)
154    ArrayOverlaps(Box<BinaryOp>),    // && operator (array overlaps)
155    JSONBContainsAllTopKeys(Box<BinaryOp>), // ?& operator (JSONB contains all keys)
156    JSONBContainsAnyTopKeys(Box<BinaryOp>), // ?| operator (JSONB contains any key)
157    JSONBDeleteAtPath(Box<BinaryOp>), // #- operator (JSONB delete at path)
158    ExtendsLeft(Box<BinaryOp>),      // &< operator (PostgreSQL range extends left)
159    ExtendsRight(Box<BinaryOp>),     // &> operator (PostgreSQL range extends right)
160
161    // Unary operations
162    Not(Box<UnaryOp>),
163    Neg(Box<UnaryOp>),
164    BitwiseNot(Box<UnaryOp>),
165
166    // Predicates
167    In(Box<In>),
168    Between(Box<Between>),
169    IsNull(Box<IsNull>),
170    IsTrue(Box<IsTrueFalse>),
171    IsFalse(Box<IsTrueFalse>),
172    IsJson(Box<IsJson>),
173    Is(Box<BinaryOp>), // General IS expression (e.g., a IS ?)
174    Exists(Box<Exists>),
175    /// MySQL MEMBER OF operator: expr MEMBER OF(json_array)
176    MemberOf(Box<BinaryOp>),
177
178    // Functions
179    Function(Box<Function>),
180    AggregateFunction(Box<AggregateFunction>),
181    WindowFunction(Box<WindowFunction>),
182
183    // Clauses
184    From(Box<From>),
185    Join(Box<Join>),
186    JoinedTable(Box<JoinedTable>),
187    Where(Box<Where>),
188    GroupBy(Box<GroupBy>),
189    Having(Box<Having>),
190    OrderBy(Box<OrderBy>),
191    Limit(Box<Limit>),
192    Offset(Box<Offset>),
193    Qualify(Box<Qualify>),
194    With(Box<With>),
195    Cte(Box<Cte>),
196    DistributeBy(Box<DistributeBy>),
197    ClusterBy(Box<ClusterBy>),
198    SortBy(Box<SortBy>),
199    LateralView(Box<LateralView>),
200    Hint(Box<Hint>),
201    Pseudocolumn(Pseudocolumn),
202
203    // Oracle hierarchical queries (CONNECT BY)
204    Connect(Box<Connect>),
205    Prior(Box<Prior>),
206    ConnectByRoot(Box<ConnectByRoot>),
207
208    // Pattern matching (MATCH_RECOGNIZE)
209    MatchRecognize(Box<MatchRecognize>),
210
211    // Order expressions
212    Ordered(Box<Ordered>),
213
214    // Window specifications
215    Window(Box<WindowSpec>),
216    Over(Box<Over>),
217    WithinGroup(Box<WithinGroup>),
218
219    // Data types
220    DataType(DataType),
221
222    // Arrays and structs
223    Array(Box<Array>),
224    Struct(Box<Struct>),
225    Tuple(Box<Tuple>),
226
227    // Interval
228    Interval(Box<Interval>),
229
230    // String functions
231    ConcatWs(Box<ConcatWs>),
232    Substring(Box<SubstringFunc>),
233    Upper(Box<UnaryFunc>),
234    Lower(Box<UnaryFunc>),
235    Length(Box<UnaryFunc>),
236    Trim(Box<TrimFunc>),
237    LTrim(Box<UnaryFunc>),
238    RTrim(Box<UnaryFunc>),
239    Replace(Box<ReplaceFunc>),
240    Reverse(Box<UnaryFunc>),
241    Left(Box<LeftRightFunc>),
242    Right(Box<LeftRightFunc>),
243    Repeat(Box<RepeatFunc>),
244    Lpad(Box<PadFunc>),
245    Rpad(Box<PadFunc>),
246    Split(Box<SplitFunc>),
247    RegexpLike(Box<RegexpFunc>),
248    RegexpReplace(Box<RegexpReplaceFunc>),
249    RegexpExtract(Box<RegexpExtractFunc>),
250    Overlay(Box<OverlayFunc>),
251
252    // Math functions
253    Abs(Box<UnaryFunc>),
254    Round(Box<RoundFunc>),
255    Floor(Box<FloorFunc>),
256    Ceil(Box<CeilFunc>),
257    Power(Box<BinaryFunc>),
258    Sqrt(Box<UnaryFunc>),
259    Cbrt(Box<UnaryFunc>),
260    Ln(Box<UnaryFunc>),
261    Log(Box<LogFunc>),
262    Exp(Box<UnaryFunc>),
263    Sign(Box<UnaryFunc>),
264    Greatest(Box<VarArgFunc>),
265    Least(Box<VarArgFunc>),
266
267    // Date/time functions
268    CurrentDate(CurrentDate),
269    CurrentTime(CurrentTime),
270    CurrentTimestamp(CurrentTimestamp),
271    CurrentTimestampLTZ(CurrentTimestampLTZ),
272    AtTimeZone(Box<AtTimeZone>),
273    DateAdd(Box<DateAddFunc>),
274    DateSub(Box<DateAddFunc>),
275    DateDiff(Box<DateDiffFunc>),
276    DateTrunc(Box<DateTruncFunc>),
277    Extract(Box<ExtractFunc>),
278    ToDate(Box<ToDateFunc>),
279    ToTimestamp(Box<ToTimestampFunc>),
280    Date(Box<UnaryFunc>),
281    Time(Box<UnaryFunc>),
282    DateFromUnixDate(Box<UnaryFunc>),
283    UnixDate(Box<UnaryFunc>),
284    UnixSeconds(Box<UnaryFunc>),
285    UnixMillis(Box<UnaryFunc>),
286    UnixMicros(Box<UnaryFunc>),
287    UnixToTimeStr(Box<BinaryFunc>),
288    TimeStrToDate(Box<UnaryFunc>),
289    DateToDi(Box<UnaryFunc>),
290    DiToDate(Box<UnaryFunc>),
291    TsOrDiToDi(Box<UnaryFunc>),
292    TsOrDsToDatetime(Box<UnaryFunc>),
293    TsOrDsToTimestamp(Box<UnaryFunc>),
294    YearOfWeek(Box<UnaryFunc>),
295    YearOfWeekIso(Box<UnaryFunc>),
296
297    // Control flow functions
298    Coalesce(Box<VarArgFunc>),
299    NullIf(Box<BinaryFunc>),
300    IfFunc(Box<IfFunc>),
301    IfNull(Box<BinaryFunc>),
302    Nvl(Box<BinaryFunc>),
303    Nvl2(Box<Nvl2Func>),
304
305    // Type conversion
306    TryCast(Box<Cast>),
307    SafeCast(Box<Cast>),
308
309    // Typed aggregate functions
310    Count(Box<CountFunc>),
311    Sum(Box<AggFunc>),
312    Avg(Box<AggFunc>),
313    Min(Box<AggFunc>),
314    Max(Box<AggFunc>),
315    GroupConcat(Box<GroupConcatFunc>),
316    StringAgg(Box<StringAggFunc>),
317    ListAgg(Box<ListAggFunc>),
318    ArrayAgg(Box<AggFunc>),
319    CountIf(Box<AggFunc>),
320    SumIf(Box<SumIfFunc>),
321    Stddev(Box<AggFunc>),
322    StddevPop(Box<AggFunc>),
323    StddevSamp(Box<AggFunc>),
324    Variance(Box<AggFunc>),
325    VarPop(Box<AggFunc>),
326    VarSamp(Box<AggFunc>),
327    Median(Box<AggFunc>),
328    Mode(Box<AggFunc>),
329    First(Box<AggFunc>),
330    Last(Box<AggFunc>),
331    AnyValue(Box<AggFunc>),
332    ApproxDistinct(Box<AggFunc>),
333    ApproxCountDistinct(Box<AggFunc>),
334    ApproxPercentile(Box<ApproxPercentileFunc>),
335    Percentile(Box<PercentileFunc>),
336    LogicalAnd(Box<AggFunc>),
337    LogicalOr(Box<AggFunc>),
338    Skewness(Box<AggFunc>),
339    BitwiseCount(Box<UnaryFunc>),
340    ArrayConcatAgg(Box<AggFunc>),
341    ArrayUniqueAgg(Box<AggFunc>),
342    BoolXorAgg(Box<AggFunc>),
343
344    // Typed window functions
345    RowNumber(RowNumber),
346    Rank(Rank),
347    DenseRank(DenseRank),
348    NTile(Box<NTileFunc>),
349    Lead(Box<LeadLagFunc>),
350    Lag(Box<LeadLagFunc>),
351    FirstValue(Box<ValueFunc>),
352    LastValue(Box<ValueFunc>),
353    NthValue(Box<NthValueFunc>),
354    PercentRank(PercentRank),
355    CumeDist(CumeDist),
356    PercentileCont(Box<PercentileFunc>),
357    PercentileDisc(Box<PercentileFunc>),
358
359    // Additional string functions
360    Contains(Box<BinaryFunc>),
361    StartsWith(Box<BinaryFunc>),
362    EndsWith(Box<BinaryFunc>),
363    Position(Box<PositionFunc>),
364    Initcap(Box<UnaryFunc>),
365    Ascii(Box<UnaryFunc>),
366    Chr(Box<UnaryFunc>),
367    /// MySQL CHAR function with multiple args and optional USING charset
368    CharFunc(Box<CharFunc>),
369    Soundex(Box<UnaryFunc>),
370    Levenshtein(Box<BinaryFunc>),
371    ByteLength(Box<UnaryFunc>),
372    Hex(Box<UnaryFunc>),
373    LowerHex(Box<UnaryFunc>),
374    Unicode(Box<UnaryFunc>),
375
376    // Additional math functions
377    ModFunc(Box<BinaryFunc>),
378    Random(Random),
379    Rand(Box<Rand>),
380    TruncFunc(Box<TruncateFunc>),
381    Pi(Pi),
382    Radians(Box<UnaryFunc>),
383    Degrees(Box<UnaryFunc>),
384    Sin(Box<UnaryFunc>),
385    Cos(Box<UnaryFunc>),
386    Tan(Box<UnaryFunc>),
387    Asin(Box<UnaryFunc>),
388    Acos(Box<UnaryFunc>),
389    Atan(Box<UnaryFunc>),
390    Atan2(Box<BinaryFunc>),
391    IsNan(Box<UnaryFunc>),
392    IsInf(Box<UnaryFunc>),
393    IntDiv(Box<BinaryFunc>),
394
395    // Control flow
396    Decode(Box<DecodeFunc>),
397
398    // Additional date/time functions
399    DateFormat(Box<DateFormatFunc>),
400    FormatDate(Box<DateFormatFunc>),
401    Year(Box<UnaryFunc>),
402    Month(Box<UnaryFunc>),
403    Day(Box<UnaryFunc>),
404    Hour(Box<UnaryFunc>),
405    Minute(Box<UnaryFunc>),
406    Second(Box<UnaryFunc>),
407    DayOfWeek(Box<UnaryFunc>),
408    DayOfWeekIso(Box<UnaryFunc>),
409    DayOfMonth(Box<UnaryFunc>),
410    DayOfYear(Box<UnaryFunc>),
411    WeekOfYear(Box<UnaryFunc>),
412    Quarter(Box<UnaryFunc>),
413    AddMonths(Box<BinaryFunc>),
414    MonthsBetween(Box<BinaryFunc>),
415    LastDay(Box<LastDayFunc>),
416    NextDay(Box<BinaryFunc>),
417    Epoch(Box<UnaryFunc>),
418    EpochMs(Box<UnaryFunc>),
419    FromUnixtime(Box<FromUnixtimeFunc>),
420    UnixTimestamp(Box<UnixTimestampFunc>),
421    MakeDate(Box<MakeDateFunc>),
422    MakeTimestamp(Box<MakeTimestampFunc>),
423    TimestampTrunc(Box<DateTruncFunc>),
424    TimeStrToUnix(Box<UnaryFunc>),
425
426    // Session/User functions
427    SessionUser(SessionUser),
428
429    // Hash/Crypto functions
430    SHA(Box<UnaryFunc>),
431    SHA1Digest(Box<UnaryFunc>),
432
433    // Time conversion functions
434    TimeToUnix(Box<UnaryFunc>),
435
436    // Array functions
437    ArrayFunc(Box<ArrayConstructor>),
438    ArrayLength(Box<UnaryFunc>),
439    ArraySize(Box<UnaryFunc>),
440    Cardinality(Box<UnaryFunc>),
441    ArrayContains(Box<BinaryFunc>),
442    ArrayPosition(Box<BinaryFunc>),
443    ArrayAppend(Box<BinaryFunc>),
444    ArrayPrepend(Box<BinaryFunc>),
445    ArrayConcat(Box<VarArgFunc>),
446    ArraySort(Box<ArraySortFunc>),
447    ArrayReverse(Box<UnaryFunc>),
448    ArrayDistinct(Box<UnaryFunc>),
449    ArrayJoin(Box<ArrayJoinFunc>),
450    ArrayToString(Box<ArrayJoinFunc>),
451    Unnest(Box<UnnestFunc>),
452    Explode(Box<UnaryFunc>),
453    ExplodeOuter(Box<UnaryFunc>),
454    ArrayFilter(Box<ArrayFilterFunc>),
455    ArrayTransform(Box<ArrayTransformFunc>),
456    ArrayFlatten(Box<UnaryFunc>),
457    ArrayCompact(Box<UnaryFunc>),
458    ArrayIntersect(Box<VarArgFunc>),
459    ArrayUnion(Box<BinaryFunc>),
460    ArrayExcept(Box<BinaryFunc>),
461    ArrayRemove(Box<BinaryFunc>),
462    ArrayZip(Box<VarArgFunc>),
463    Sequence(Box<SequenceFunc>),
464    Generate(Box<SequenceFunc>),
465    ExplodingGenerateSeries(Box<SequenceFunc>),
466    ToArray(Box<UnaryFunc>),
467    StarMap(Box<BinaryFunc>),
468
469    // Struct functions
470    StructFunc(Box<StructConstructor>),
471    StructExtract(Box<StructExtractFunc>),
472    NamedStruct(Box<NamedStructFunc>),
473
474    // Map functions
475    MapFunc(Box<MapConstructor>),
476    MapFromEntries(Box<UnaryFunc>),
477    MapFromArrays(Box<BinaryFunc>),
478    MapKeys(Box<UnaryFunc>),
479    MapValues(Box<UnaryFunc>),
480    MapContainsKey(Box<BinaryFunc>),
481    MapConcat(Box<VarArgFunc>),
482    ElementAt(Box<BinaryFunc>),
483    TransformKeys(Box<TransformFunc>),
484    TransformValues(Box<TransformFunc>),
485
486    // Exasol: function call with EMITS clause
487    FunctionEmits(Box<FunctionEmits>),
488
489    // JSON functions
490    JsonExtract(Box<JsonExtractFunc>),
491    JsonExtractScalar(Box<JsonExtractFunc>),
492    JsonExtractPath(Box<JsonPathFunc>),
493    JsonArray(Box<VarArgFunc>),
494    JsonObject(Box<JsonObjectFunc>),
495    JsonQuery(Box<JsonExtractFunc>),
496    JsonValue(Box<JsonExtractFunc>),
497    JsonArrayLength(Box<UnaryFunc>),
498    JsonKeys(Box<UnaryFunc>),
499    JsonType(Box<UnaryFunc>),
500    ParseJson(Box<UnaryFunc>),
501    ToJson(Box<UnaryFunc>),
502    JsonSet(Box<JsonModifyFunc>),
503    JsonInsert(Box<JsonModifyFunc>),
504    JsonRemove(Box<JsonPathFunc>),
505    JsonMergePatch(Box<BinaryFunc>),
506    JsonArrayAgg(Box<JsonArrayAggFunc>),
507    JsonObjectAgg(Box<JsonObjectAggFunc>),
508
509    // Type casting/conversion
510    Convert(Box<ConvertFunc>),
511    Typeof(Box<UnaryFunc>),
512
513    // Additional expressions
514    Lambda(Box<LambdaExpr>),
515    Parameter(Box<Parameter>),
516    Placeholder(Placeholder),
517    NamedArgument(Box<NamedArgument>),
518    /// TABLE ref or MODEL ref used as a function argument (BigQuery)
519    /// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
520    TableArgument(Box<TableArgument>),
521    SqlComment(Box<SqlComment>),
522
523    // Additional predicates
524    NullSafeEq(Box<BinaryOp>),
525    NullSafeNeq(Box<BinaryOp>),
526    Glob(Box<BinaryOp>),
527    SimilarTo(Box<SimilarToExpr>),
528    Any(Box<QuantifiedExpr>),
529    All(Box<QuantifiedExpr>),
530    Overlaps(Box<OverlapsExpr>),
531
532    // Bitwise operations
533    BitwiseLeftShift(Box<BinaryOp>),
534    BitwiseRightShift(Box<BinaryOp>),
535    BitwiseAndAgg(Box<AggFunc>),
536    BitwiseOrAgg(Box<AggFunc>),
537    BitwiseXorAgg(Box<AggFunc>),
538
539    // Array/struct/map access
540    Subscript(Box<Subscript>),
541    Dot(Box<DotAccess>),
542    MethodCall(Box<MethodCall>),
543    ArraySlice(Box<ArraySlice>),
544
545    // DDL statements
546    CreateTable(Box<CreateTable>),
547    DropTable(Box<DropTable>),
548    Undrop(Box<Undrop>),
549    AlterTable(Box<AlterTable>),
550    SplitTable(Box<SplitTable>),
551    FlashbackTable(Box<FlashbackTable>),
552    CreateIndex(Box<CreateIndex>),
553    DropIndex(Box<DropIndex>),
554    CreateView(Box<CreateView>),
555    DropView(Box<DropView>),
556    AlterView(Box<AlterView>),
557    AlterIndex(Box<AlterIndex>),
558    Truncate(Box<Truncate>),
559    Use(Box<Use>),
560    Cache(Box<Cache>),
561    Uncache(Box<Uncache>),
562    LoadData(Box<LoadData>),
563    Pragma(Box<Pragma>),
564    Grant(Box<Grant>),
565    Revoke(Box<Revoke>),
566    Comment(Box<Comment>),
567    SetStatement(Box<SetStatement>),
568    // Phase 4: Additional DDL statements
569    CreateSchema(Box<CreateSchema>),
570    DropSchema(Box<DropSchema>),
571    DropNamespace(Box<DropNamespace>),
572    CreateDatabase(Box<CreateDatabase>),
573    DropDatabase(Box<DropDatabase>),
574    CreateFunction(Box<CreateFunction>),
575    DropFunction(Box<DropFunction>),
576    CreateProcedure(Box<CreateProcedure>),
577    DropProcedure(Box<DropProcedure>),
578    CreateSequence(Box<CreateSequence>),
579    CreateSynonym(Box<CreateSynonym>),
580    DropSequence(Box<DropSequence>),
581    AlterSequence(Box<AlterSequence>),
582    CreateTrigger(Box<CreateTrigger>),
583    DropTrigger(Box<DropTrigger>),
584    CreateType(Box<CreateType>),
585    DropType(Box<DropType>),
586    Describe(Box<Describe>),
587    Show(Box<Show>),
588
589    // Transaction and other commands
590    Command(Box<Command>),
591    Kill(Box<Kill>),
592    /// PREPARE statement (PostgreSQL/generic prepared statement definition)
593    Prepare(Box<PrepareStatement>),
594    /// EXEC/EXECUTE statement (TSQL stored procedure call)
595    Execute(Box<ExecuteStatement>),
596
597    /// Snowflake CREATE TASK statement
598    CreateTask(Box<CreateTask>),
599
600    // Placeholder for unparsed/raw SQL
601    Raw(Raw),
602
603    // Paren for grouping
604    Paren(Box<Paren>),
605
606    // Expression with trailing comments (for round-trip preservation)
607    Annotated(Box<Annotated>),
608
609    // === BATCH GENERATED EXPRESSION TYPES ===
610    // Generated from Python sqlglot expressions.py
611    Refresh(Box<Refresh>),
612    LockingStatement(Box<LockingStatement>),
613    SequenceProperties(Box<SequenceProperties>),
614    TruncateTable(Box<TruncateTable>),
615    Clone(Box<Clone>),
616    Attach(Box<Attach>),
617    Detach(Box<Detach>),
618    Install(Box<Install>),
619    Summarize(Box<Summarize>),
620    Declare(Box<Declare>),
621    DeclareItem(Box<DeclareItem>),
622    Set(Box<Set>),
623    Heredoc(Box<Heredoc>),
624    SetItem(Box<SetItem>),
625    QueryBand(Box<QueryBand>),
626    UserDefinedFunction(Box<UserDefinedFunction>),
627    RecursiveWithSearch(Box<RecursiveWithSearch>),
628    ProjectionDef(Box<ProjectionDef>),
629    TableAlias(Box<TableAlias>),
630    ByteString(Box<ByteString>),
631    HexStringExpr(Box<HexStringExpr>),
632    UnicodeString(Box<UnicodeString>),
633    ColumnPosition(Box<ColumnPosition>),
634    ColumnDef(Box<ColumnDef>),
635    AlterColumn(Box<AlterColumn>),
636    AlterSortKey(Box<AlterSortKey>),
637    AlterSet(Box<AlterSet>),
638    RenameColumn(Box<RenameColumn>),
639    Comprehension(Box<Comprehension>),
640    MergeTreeTTLAction(Box<MergeTreeTTLAction>),
641    MergeTreeTTL(Box<MergeTreeTTL>),
642    IndexConstraintOption(Box<IndexConstraintOption>),
643    ColumnConstraint(Box<ColumnConstraint>),
644    PeriodForSystemTimeConstraint(Box<PeriodForSystemTimeConstraint>),
645    CaseSpecificColumnConstraint(Box<CaseSpecificColumnConstraint>),
646    CharacterSetColumnConstraint(Box<CharacterSetColumnConstraint>),
647    CheckColumnConstraint(Box<CheckColumnConstraint>),
648    AssumeColumnConstraint(Box<AssumeColumnConstraint>),
649    CompressColumnConstraint(Box<CompressColumnConstraint>),
650    DateFormatColumnConstraint(Box<DateFormatColumnConstraint>),
651    EphemeralColumnConstraint(Box<EphemeralColumnConstraint>),
652    WithOperator(Box<WithOperator>),
653    GeneratedAsIdentityColumnConstraint(Box<GeneratedAsIdentityColumnConstraint>),
654    AutoIncrementColumnConstraint(AutoIncrementColumnConstraint),
655    CommentColumnConstraint(CommentColumnConstraint),
656    GeneratedAsRowColumnConstraint(Box<GeneratedAsRowColumnConstraint>),
657    IndexColumnConstraint(Box<IndexColumnConstraint>),
658    MaskingPolicyColumnConstraint(Box<MaskingPolicyColumnConstraint>),
659    NotNullColumnConstraint(Box<NotNullColumnConstraint>),
660    PrimaryKeyColumnConstraint(Box<PrimaryKeyColumnConstraint>),
661    UniqueColumnConstraint(Box<UniqueColumnConstraint>),
662    WatermarkColumnConstraint(Box<WatermarkColumnConstraint>),
663    ComputedColumnConstraint(Box<ComputedColumnConstraint>),
664    InOutColumnConstraint(Box<InOutColumnConstraint>),
665    DefaultColumnConstraint(Box<DefaultColumnConstraint>),
666    PathColumnConstraint(Box<PathColumnConstraint>),
667    Constraint(Box<Constraint>),
668    Export(Box<Export>),
669    Filter(Box<Filter>),
670    Changes(Box<Changes>),
671    CopyParameter(Box<CopyParameter>),
672    Credentials(Box<Credentials>),
673    Directory(Box<Directory>),
674    ForeignKey(Box<ForeignKey>),
675    ColumnPrefix(Box<ColumnPrefix>),
676    PrimaryKey(Box<PrimaryKey>),
677    IntoClause(Box<IntoClause>),
678    JoinHint(Box<JoinHint>),
679    Opclass(Box<Opclass>),
680    Index(Box<Index>),
681    IndexParameters(Box<IndexParameters>),
682    ConditionalInsert(Box<ConditionalInsert>),
683    MultitableInserts(Box<MultitableInserts>),
684    OnConflict(Box<OnConflict>),
685    OnCondition(Box<OnCondition>),
686    Returning(Box<Returning>),
687    Introducer(Box<Introducer>),
688    PartitionRange(Box<PartitionRange>),
689    Fetch(Box<Fetch>),
690    Group(Box<Group>),
691    Cube(Box<Cube>),
692    Rollup(Box<Rollup>),
693    GroupingSets(Box<GroupingSets>),
694    LimitOptions(Box<LimitOptions>),
695    Lateral(Box<Lateral>),
696    TableFromRows(Box<TableFromRows>),
697    RowsFrom(Box<RowsFrom>),
698    MatchRecognizeMeasure(Box<MatchRecognizeMeasure>),
699    WithFill(Box<WithFill>),
700    Property(Box<Property>),
701    GrantPrivilege(Box<GrantPrivilege>),
702    GrantPrincipal(Box<GrantPrincipal>),
703    AllowedValuesProperty(Box<AllowedValuesProperty>),
704    AlgorithmProperty(Box<AlgorithmProperty>),
705    AutoIncrementProperty(Box<AutoIncrementProperty>),
706    AutoRefreshProperty(Box<AutoRefreshProperty>),
707    BackupProperty(Box<BackupProperty>),
708    BuildProperty(Box<BuildProperty>),
709    BlockCompressionProperty(Box<BlockCompressionProperty>),
710    CharacterSetProperty(Box<CharacterSetProperty>),
711    ChecksumProperty(Box<ChecksumProperty>),
712    CollateProperty(Box<CollateProperty>),
713    DataBlocksizeProperty(Box<DataBlocksizeProperty>),
714    DataDeletionProperty(Box<DataDeletionProperty>),
715    DefinerProperty(Box<DefinerProperty>),
716    DistKeyProperty(Box<DistKeyProperty>),
717    DistributedByProperty(Box<DistributedByProperty>),
718    DistStyleProperty(Box<DistStyleProperty>),
719    DuplicateKeyProperty(Box<DuplicateKeyProperty>),
720    EngineProperty(Box<EngineProperty>),
721    ToTableProperty(Box<ToTableProperty>),
722    ExecuteAsProperty(Box<ExecuteAsProperty>),
723    ExternalProperty(Box<ExternalProperty>),
724    FallbackProperty(Box<FallbackProperty>),
725    FileFormatProperty(Box<FileFormatProperty>),
726    CredentialsProperty(Box<CredentialsProperty>),
727    FreespaceProperty(Box<FreespaceProperty>),
728    InheritsProperty(Box<InheritsProperty>),
729    InputModelProperty(Box<InputModelProperty>),
730    OutputModelProperty(Box<OutputModelProperty>),
731    IsolatedLoadingProperty(Box<IsolatedLoadingProperty>),
732    JournalProperty(Box<JournalProperty>),
733    LanguageProperty(Box<LanguageProperty>),
734    EnviromentProperty(Box<EnviromentProperty>),
735    ClusteredByProperty(Box<ClusteredByProperty>),
736    DictProperty(Box<DictProperty>),
737    DictRange(Box<DictRange>),
738    OnCluster(Box<OnCluster>),
739    LikeProperty(Box<LikeProperty>),
740    LocationProperty(Box<LocationProperty>),
741    LockProperty(Box<LockProperty>),
742    LockingProperty(Box<LockingProperty>),
743    LogProperty(Box<LogProperty>),
744    MaterializedProperty(Box<MaterializedProperty>),
745    MergeBlockRatioProperty(Box<MergeBlockRatioProperty>),
746    OnProperty(Box<OnProperty>),
747    OnCommitProperty(Box<OnCommitProperty>),
748    PartitionedByProperty(Box<PartitionedByProperty>),
749    PartitionByProperty(Box<PartitionByProperty>),
750    PartitionedByBucket(Box<PartitionedByBucket>),
751    ClusterByColumnsProperty(Box<ClusterByColumnsProperty>),
752    PartitionByTruncate(Box<PartitionByTruncate>),
753    PartitionByRangeProperty(Box<PartitionByRangeProperty>),
754    PartitionByRangePropertyDynamic(Box<PartitionByRangePropertyDynamic>),
755    PartitionByListProperty(Box<PartitionByListProperty>),
756    PartitionList(Box<PartitionList>),
757    Partition(Box<Partition>),
758    RefreshTriggerProperty(Box<RefreshTriggerProperty>),
759    UniqueKeyProperty(Box<UniqueKeyProperty>),
760    RollupProperty(Box<RollupProperty>),
761    PartitionBoundSpec(Box<PartitionBoundSpec>),
762    PartitionedOfProperty(Box<PartitionedOfProperty>),
763    RemoteWithConnectionModelProperty(Box<RemoteWithConnectionModelProperty>),
764    ReturnsProperty(Box<ReturnsProperty>),
765    RowFormatProperty(Box<RowFormatProperty>),
766    RowFormatDelimitedProperty(Box<RowFormatDelimitedProperty>),
767    RowFormatSerdeProperty(Box<RowFormatSerdeProperty>),
768    QueryTransform(Box<QueryTransform>),
769    SampleProperty(Box<SampleProperty>),
770    SecurityProperty(Box<SecurityProperty>),
771    SchemaCommentProperty(Box<SchemaCommentProperty>),
772    SemanticView(Box<SemanticView>),
773    SerdeProperties(Box<SerdeProperties>),
774    SetProperty(Box<SetProperty>),
775    SharingProperty(Box<SharingProperty>),
776    SetConfigProperty(Box<SetConfigProperty>),
777    SettingsProperty(Box<SettingsProperty>),
778    SortKeyProperty(Box<SortKeyProperty>),
779    SqlReadWriteProperty(Box<SqlReadWriteProperty>),
780    SqlSecurityProperty(Box<SqlSecurityProperty>),
781    StabilityProperty(Box<StabilityProperty>),
782    StorageHandlerProperty(Box<StorageHandlerProperty>),
783    TemporaryProperty(Box<TemporaryProperty>),
784    Tags(Box<Tags>),
785    TransformModelProperty(Box<TransformModelProperty>),
786    TransientProperty(Box<TransientProperty>),
787    UsingTemplateProperty(Box<UsingTemplateProperty>),
788    ViewAttributeProperty(Box<ViewAttributeProperty>),
789    VolatileProperty(Box<VolatileProperty>),
790    WithDataProperty(Box<WithDataProperty>),
791    WithJournalTableProperty(Box<WithJournalTableProperty>),
792    WithSchemaBindingProperty(Box<WithSchemaBindingProperty>),
793    WithSystemVersioningProperty(Box<WithSystemVersioningProperty>),
794    WithProcedureOptions(Box<WithProcedureOptions>),
795    EncodeProperty(Box<EncodeProperty>),
796    IncludeProperty(Box<IncludeProperty>),
797    Properties(Box<Properties>),
798    OptionsProperty(Box<OptionsProperty>),
799    InputOutputFormat(Box<InputOutputFormat>),
800    Reference(Box<Reference>),
801    QueryOption(Box<QueryOption>),
802    WithTableHint(Box<WithTableHint>),
803    IndexTableHint(Box<IndexTableHint>),
804    HistoricalData(Box<HistoricalData>),
805    Get(Box<Get>),
806    SetOperation(Box<SetOperation>),
807    Var(Box<Var>),
808    Variadic(Box<Variadic>),
809    Version(Box<Version>),
810    Schema(Box<Schema>),
811    Lock(Box<Lock>),
812    TableSample(Box<TableSample>),
813    Tag(Box<Tag>),
814    UnpivotColumns(Box<UnpivotColumns>),
815    WindowSpec(Box<WindowSpec>),
816    SessionParameter(Box<SessionParameter>),
817    PseudoType(Box<PseudoType>),
818    ObjectIdentifier(Box<ObjectIdentifier>),
819    Transaction(Box<Transaction>),
820    Commit(Box<Commit>),
821    Rollback(Box<Rollback>),
822    AlterSession(Box<AlterSession>),
823    Analyze(Box<Analyze>),
824    AnalyzeStatistics(Box<AnalyzeStatistics>),
825    AnalyzeHistogram(Box<AnalyzeHistogram>),
826    AnalyzeSample(Box<AnalyzeSample>),
827    AnalyzeListChainedRows(Box<AnalyzeListChainedRows>),
828    AnalyzeDelete(Box<AnalyzeDelete>),
829    AnalyzeWith(Box<AnalyzeWith>),
830    AnalyzeValidate(Box<AnalyzeValidate>),
831    AddPartition(Box<AddPartition>),
832    AttachOption(Box<AttachOption>),
833    DropPartition(Box<DropPartition>),
834    ReplacePartition(Box<ReplacePartition>),
835    DPipe(Box<DPipe>),
836    Operator(Box<Operator>),
837    PivotAny(Box<PivotAny>),
838    Aliases(Box<Aliases>),
839    AtIndex(Box<AtIndex>),
840    FromTimeZone(Box<FromTimeZone>),
841    FormatPhrase(Box<FormatPhrase>),
842    ForIn(Box<ForIn>),
843    TimeUnit(Box<TimeUnit>),
844    IntervalOp(Box<IntervalOp>),
845    IntervalSpan(Box<IntervalSpan>),
846    HavingMax(Box<HavingMax>),
847    CosineDistance(Box<CosineDistance>),
848    DotProduct(Box<DotProduct>),
849    EuclideanDistance(Box<EuclideanDistance>),
850    ManhattanDistance(Box<ManhattanDistance>),
851    JarowinklerSimilarity(Box<JarowinklerSimilarity>),
852    Booland(Box<Booland>),
853    Boolor(Box<Boolor>),
854    ParameterizedAgg(Box<ParameterizedAgg>),
855    ArgMax(Box<ArgMax>),
856    ArgMin(Box<ArgMin>),
857    ApproxTopK(Box<ApproxTopK>),
858    ApproxTopKAccumulate(Box<ApproxTopKAccumulate>),
859    ApproxTopKCombine(Box<ApproxTopKCombine>),
860    ApproxTopKEstimate(Box<ApproxTopKEstimate>),
861    ApproxTopSum(Box<ApproxTopSum>),
862    ApproxQuantiles(Box<ApproxQuantiles>),
863    Minhash(Box<Minhash>),
864    FarmFingerprint(Box<FarmFingerprint>),
865    Float64(Box<Float64>),
866    Transform(Box<Transform>),
867    Translate(Box<Translate>),
868    Grouping(Box<Grouping>),
869    GroupingId(Box<GroupingId>),
870    Anonymous(Box<Anonymous>),
871    AnonymousAggFunc(Box<AnonymousAggFunc>),
872    CombinedAggFunc(Box<CombinedAggFunc>),
873    CombinedParameterizedAgg(Box<CombinedParameterizedAgg>),
874    HashAgg(Box<HashAgg>),
875    Hll(Box<Hll>),
876    Apply(Box<Apply>),
877    ToBoolean(Box<ToBoolean>),
878    List(Box<List>),
879    ToMap(Box<ToMap>),
880    Pad(Box<Pad>),
881    ToChar(Box<ToChar>),
882    ToNumber(Box<ToNumber>),
883    ToDouble(Box<ToDouble>),
884    Int64(Box<UnaryFunc>),
885    StringFunc(Box<StringFunc>),
886    ToDecfloat(Box<ToDecfloat>),
887    TryToDecfloat(Box<TryToDecfloat>),
888    ToFile(Box<ToFile>),
889    Columns(Box<Columns>),
890    ConvertToCharset(Box<ConvertToCharset>),
891    ConvertTimezone(Box<ConvertTimezone>),
892    GenerateSeries(Box<GenerateSeries>),
893    AIAgg(Box<AIAgg>),
894    AIClassify(Box<AIClassify>),
895    ArrayAll(Box<ArrayAll>),
896    ArrayAny(Box<ArrayAny>),
897    ArrayConstructCompact(Box<ArrayConstructCompact>),
898    StPoint(Box<StPoint>),
899    StDistance(Box<StDistance>),
900    StringToArray(Box<StringToArray>),
901    ArraySum(Box<ArraySum>),
902    ObjectAgg(Box<ObjectAgg>),
903    CastToStrType(Box<CastToStrType>),
904    CheckJson(Box<CheckJson>),
905    CheckXml(Box<CheckXml>),
906    TranslateCharacters(Box<TranslateCharacters>),
907    CurrentSchemas(Box<CurrentSchemas>),
908    CurrentDatetime(Box<CurrentDatetime>),
909    Localtime(Box<Localtime>),
910    Localtimestamp(Box<Localtimestamp>),
911    Systimestamp(Box<Systimestamp>),
912    CurrentSchema(Box<CurrentSchema>),
913    CurrentUser(Box<CurrentUser>),
914    UtcTime(Box<UtcTime>),
915    UtcTimestamp(Box<UtcTimestamp>),
916    Timestamp(Box<TimestampFunc>),
917    DateBin(Box<DateBin>),
918    Datetime(Box<Datetime>),
919    DatetimeAdd(Box<DatetimeAdd>),
920    DatetimeSub(Box<DatetimeSub>),
921    DatetimeDiff(Box<DatetimeDiff>),
922    DatetimeTrunc(Box<DatetimeTrunc>),
923    Dayname(Box<Dayname>),
924    MakeInterval(Box<MakeInterval>),
925    PreviousDay(Box<PreviousDay>),
926    Elt(Box<Elt>),
927    TimestampAdd(Box<TimestampAdd>),
928    TimestampSub(Box<TimestampSub>),
929    TimestampDiff(Box<TimestampDiff>),
930    TimeSlice(Box<TimeSlice>),
931    TimeAdd(Box<TimeAdd>),
932    TimeSub(Box<TimeSub>),
933    TimeDiff(Box<TimeDiff>),
934    TimeTrunc(Box<TimeTrunc>),
935    DateFromParts(Box<DateFromParts>),
936    TimeFromParts(Box<TimeFromParts>),
937    DecodeCase(Box<DecodeCase>),
938    Decrypt(Box<Decrypt>),
939    DecryptRaw(Box<DecryptRaw>),
940    Encode(Box<Encode>),
941    Encrypt(Box<Encrypt>),
942    EncryptRaw(Box<EncryptRaw>),
943    EqualNull(Box<EqualNull>),
944    ToBinary(Box<ToBinary>),
945    Base64DecodeBinary(Box<Base64DecodeBinary>),
946    Base64DecodeString(Box<Base64DecodeString>),
947    Base64Encode(Box<Base64Encode>),
948    TryBase64DecodeBinary(Box<TryBase64DecodeBinary>),
949    TryBase64DecodeString(Box<TryBase64DecodeString>),
950    GapFill(Box<GapFill>),
951    GenerateDateArray(Box<GenerateDateArray>),
952    GenerateTimestampArray(Box<GenerateTimestampArray>),
953    GetExtract(Box<GetExtract>),
954    Getbit(Box<Getbit>),
955    OverflowTruncateBehavior(Box<OverflowTruncateBehavior>),
956    HexEncode(Box<HexEncode>),
957    Compress(Box<Compress>),
958    DecompressBinary(Box<DecompressBinary>),
959    DecompressString(Box<DecompressString>),
960    Xor(Box<Xor>),
961    Nullif(Box<Nullif>),
962    JSON(Box<JSON>),
963    JSONPath(Box<JSONPath>),
964    JSONPathFilter(Box<JSONPathFilter>),
965    JSONPathKey(Box<JSONPathKey>),
966    JSONPathRecursive(Box<JSONPathRecursive>),
967    JSONPathScript(Box<JSONPathScript>),
968    JSONPathSlice(Box<JSONPathSlice>),
969    JSONPathSelector(Box<JSONPathSelector>),
970    JSONPathSubscript(Box<JSONPathSubscript>),
971    JSONPathUnion(Box<JSONPathUnion>),
972    Format(Box<Format>),
973    JSONKeys(Box<JSONKeys>),
974    JSONKeyValue(Box<JSONKeyValue>),
975    JSONKeysAtDepth(Box<JSONKeysAtDepth>),
976    JSONObject(Box<JSONObject>),
977    JSONObjectAgg(Box<JSONObjectAgg>),
978    JSONBObjectAgg(Box<JSONBObjectAgg>),
979    JSONArray(Box<JSONArray>),
980    JSONArrayAgg(Box<JSONArrayAgg>),
981    JSONExists(Box<JSONExists>),
982    JSONColumnDef(Box<JSONColumnDef>),
983    JSONSchema(Box<JSONSchema>),
984    JSONSet(Box<JSONSet>),
985    JSONStripNulls(Box<JSONStripNulls>),
986    JSONValue(Box<JSONValue>),
987    JSONValueArray(Box<JSONValueArray>),
988    JSONRemove(Box<JSONRemove>),
989    JSONTable(Box<JSONTable>),
990    JSONType(Box<JSONType>),
991    ObjectInsert(Box<ObjectInsert>),
992    OpenJSONColumnDef(Box<OpenJSONColumnDef>),
993    OpenJSON(Box<OpenJSON>),
994    JSONBExists(Box<JSONBExists>),
995    JSONBContains(Box<BinaryFunc>),
996    JSONBExtract(Box<BinaryFunc>),
997    JSONCast(Box<JSONCast>),
998    JSONExtract(Box<JSONExtract>),
999    JSONExtractQuote(Box<JSONExtractQuote>),
1000    JSONExtractArray(Box<JSONExtractArray>),
1001    JSONExtractScalar(Box<JSONExtractScalar>),
1002    JSONBExtractScalar(Box<JSONBExtractScalar>),
1003    JSONFormat(Box<JSONFormat>),
1004    JSONBool(Box<UnaryFunc>),
1005    JSONPathRoot(JSONPathRoot),
1006    JSONArrayAppend(Box<JSONArrayAppend>),
1007    JSONArrayContains(Box<JSONArrayContains>),
1008    JSONArrayInsert(Box<JSONArrayInsert>),
1009    ParseJSON(Box<ParseJSON>),
1010    ParseUrl(Box<ParseUrl>),
1011    ParseIp(Box<ParseIp>),
1012    ParseTime(Box<ParseTime>),
1013    ParseDatetime(Box<ParseDatetime>),
1014    Map(Box<Map>),
1015    MapCat(Box<MapCat>),
1016    MapDelete(Box<MapDelete>),
1017    MapInsert(Box<MapInsert>),
1018    MapPick(Box<MapPick>),
1019    ScopeResolution(Box<ScopeResolution>),
1020    Slice(Box<Slice>),
1021    VarMap(Box<VarMap>),
1022    MatchAgainst(Box<MatchAgainst>),
1023    MD5Digest(Box<MD5Digest>),
1024    MD5NumberLower64(Box<UnaryFunc>),
1025    MD5NumberUpper64(Box<UnaryFunc>),
1026    Monthname(Box<Monthname>),
1027    Ntile(Box<Ntile>),
1028    Normalize(Box<Normalize>),
1029    Normal(Box<Normal>),
1030    Predict(Box<Predict>),
1031    MLTranslate(Box<MLTranslate>),
1032    FeaturesAtTime(Box<FeaturesAtTime>),
1033    GenerateEmbedding(Box<GenerateEmbedding>),
1034    MLForecast(Box<MLForecast>),
1035    ModelAttribute(Box<ModelAttribute>),
1036    VectorSearch(Box<VectorSearch>),
1037    Quantile(Box<Quantile>),
1038    ApproxQuantile(Box<ApproxQuantile>),
1039    ApproxPercentileEstimate(Box<ApproxPercentileEstimate>),
1040    Randn(Box<Randn>),
1041    Randstr(Box<Randstr>),
1042    RangeN(Box<RangeN>),
1043    RangeBucket(Box<RangeBucket>),
1044    ReadCSV(Box<ReadCSV>),
1045    ReadParquet(Box<ReadParquet>),
1046    Reduce(Box<Reduce>),
1047    RegexpExtractAll(Box<RegexpExtractAll>),
1048    RegexpILike(Box<RegexpILike>),
1049    RegexpFullMatch(Box<RegexpFullMatch>),
1050    RegexpInstr(Box<RegexpInstr>),
1051    RegexpSplit(Box<RegexpSplit>),
1052    RegexpCount(Box<RegexpCount>),
1053    RegrValx(Box<RegrValx>),
1054    RegrValy(Box<RegrValy>),
1055    RegrAvgy(Box<RegrAvgy>),
1056    RegrAvgx(Box<RegrAvgx>),
1057    RegrCount(Box<RegrCount>),
1058    RegrIntercept(Box<RegrIntercept>),
1059    RegrR2(Box<RegrR2>),
1060    RegrSxx(Box<RegrSxx>),
1061    RegrSxy(Box<RegrSxy>),
1062    RegrSyy(Box<RegrSyy>),
1063    RegrSlope(Box<RegrSlope>),
1064    SafeAdd(Box<SafeAdd>),
1065    SafeDivide(Box<SafeDivide>),
1066    SafeMultiply(Box<SafeMultiply>),
1067    SafeSubtract(Box<SafeSubtract>),
1068    SHA2(Box<SHA2>),
1069    SHA2Digest(Box<SHA2Digest>),
1070    SortArray(Box<SortArray>),
1071    SplitPart(Box<SplitPart>),
1072    SubstringIndex(Box<SubstringIndex>),
1073    StandardHash(Box<StandardHash>),
1074    StrPosition(Box<StrPosition>),
1075    Search(Box<Search>),
1076    SearchIp(Box<SearchIp>),
1077    StrToDate(Box<StrToDate>),
1078    DateStrToDate(Box<UnaryFunc>),
1079    DateToDateStr(Box<UnaryFunc>),
1080    StrToTime(Box<StrToTime>),
1081    StrToUnix(Box<StrToUnix>),
1082    StrToMap(Box<StrToMap>),
1083    NumberToStr(Box<NumberToStr>),
1084    FromBase(Box<FromBase>),
1085    Stuff(Box<Stuff>),
1086    TimeToStr(Box<TimeToStr>),
1087    TimeStrToTime(Box<TimeStrToTime>),
1088    TsOrDsAdd(Box<TsOrDsAdd>),
1089    TsOrDsDiff(Box<TsOrDsDiff>),
1090    TsOrDsToDate(Box<TsOrDsToDate>),
1091    TsOrDsToTime(Box<TsOrDsToTime>),
1092    Unhex(Box<Unhex>),
1093    Uniform(Box<Uniform>),
1094    UnixToStr(Box<UnixToStr>),
1095    UnixToTime(Box<UnixToTime>),
1096    Uuid(Box<Uuid>),
1097    TimestampFromParts(Box<TimestampFromParts>),
1098    TimestampTzFromParts(Box<TimestampTzFromParts>),
1099    Corr(Box<Corr>),
1100    WidthBucket(Box<WidthBucket>),
1101    CovarSamp(Box<CovarSamp>),
1102    CovarPop(Box<CovarPop>),
1103    Week(Box<Week>),
1104    XMLElement(Box<XMLElement>),
1105    XMLGet(Box<XMLGet>),
1106    XMLTable(Box<XMLTable>),
1107    XMLKeyValueOption(Box<XMLKeyValueOption>),
1108    Zipf(Box<Zipf>),
1109    Merge(Box<Merge>),
1110    When(Box<When>),
1111    Whens(Box<Whens>),
1112    NextValueFor(Box<NextValueFor>),
1113    /// RETURN statement (DuckDB stored procedures)
1114    ReturnStmt(Box<Expression>),
1115}
1116
1117impl Expression {
1118    /// Create a `Column` variant, boxing the value automatically.
1119    #[inline]
1120    pub fn boxed_column(col: Column) -> Self {
1121        Expression::Column(Box::new(col))
1122    }
1123
1124    /// Create a `Table` variant, boxing the value automatically.
1125    #[inline]
1126    pub fn boxed_table(t: TableRef) -> Self {
1127        Expression::Table(Box::new(t))
1128    }
1129
1130    /// Returns `true` if this expression is a valid top-level SQL statement.
1131    ///
1132    /// Bare expressions like identifiers, literals, and function calls are not
1133    /// valid statements. This is used by `validate()` to reject inputs like
1134    /// `SELECT scooby dooby doo` which the parser splits into `SELECT scooby AS dooby`
1135    /// plus the bare identifier `doo`.
1136    pub fn is_statement(&self) -> bool {
1137        match self {
1138            // Queries
1139            Expression::Select(_)
1140            | Expression::Union(_)
1141            | Expression::Intersect(_)
1142            | Expression::Except(_)
1143            | Expression::Subquery(_)
1144            | Expression::Values(_)
1145            | Expression::PipeOperator(_)
1146
1147            // DML
1148            | Expression::Insert(_)
1149            | Expression::Update(_)
1150            | Expression::Delete(_)
1151            | Expression::Copy(_)
1152            | Expression::Put(_)
1153            | Expression::Merge(_)
1154            | Expression::TryCatch(_)
1155
1156            // DDL
1157            | Expression::CreateTable(_)
1158            | Expression::DropTable(_)
1159            | Expression::Undrop(_)
1160            | Expression::AlterTable(_)
1161            | Expression::SplitTable(_)
1162            | Expression::FlashbackTable(_)
1163            | Expression::CreateIndex(_)
1164            | Expression::DropIndex(_)
1165            | Expression::CreateView(_)
1166            | Expression::DropView(_)
1167            | Expression::AlterView(_)
1168            | Expression::AlterIndex(_)
1169            | Expression::Truncate(_)
1170            | Expression::TruncateTable(_)
1171            | Expression::CreateSchema(_)
1172            | Expression::DropSchema(_)
1173            | Expression::DropNamespace(_)
1174            | Expression::CreateDatabase(_)
1175            | Expression::DropDatabase(_)
1176            | Expression::CreateFunction(_)
1177            | Expression::DropFunction(_)
1178            | Expression::CreateProcedure(_)
1179            | Expression::DropProcedure(_)
1180            | Expression::CreateSequence(_)
1181            | Expression::CreateSynonym(_)
1182            | Expression::DropSequence(_)
1183            | Expression::AlterSequence(_)
1184            | Expression::CreateTrigger(_)
1185            | Expression::DropTrigger(_)
1186            | Expression::CreateType(_)
1187            | Expression::DropType(_)
1188            | Expression::Comment(_)
1189
1190            // Session/Transaction/Control
1191            | Expression::Use(_)
1192            | Expression::Set(_)
1193            | Expression::SetStatement(_)
1194            | Expression::Transaction(_)
1195            | Expression::Commit(_)
1196            | Expression::Rollback(_)
1197            | Expression::Grant(_)
1198            | Expression::Revoke(_)
1199            | Expression::Cache(_)
1200            | Expression::Uncache(_)
1201            | Expression::LoadData(_)
1202            | Expression::Pragma(_)
1203            | Expression::Describe(_)
1204            | Expression::Show(_)
1205            | Expression::Kill(_)
1206            | Expression::Prepare(_)
1207            | Expression::Execute(_)
1208            | Expression::Declare(_)
1209            | Expression::Refresh(_)
1210            | Expression::AlterSession(_)
1211            | Expression::LockingStatement(_)
1212
1213            // Analyze
1214            | Expression::Analyze(_)
1215            | Expression::AnalyzeStatistics(_)
1216            | Expression::AnalyzeHistogram(_)
1217            | Expression::AnalyzeSample(_)
1218            | Expression::AnalyzeListChainedRows(_)
1219            | Expression::AnalyzeDelete(_)
1220
1221            // Attach/Detach/Install/Summarize
1222            | Expression::Attach(_)
1223            | Expression::Detach(_)
1224            | Expression::Install(_)
1225            | Expression::Summarize(_)
1226
1227            // Pivot at statement level
1228            | Expression::Pivot(_)
1229            | Expression::Unpivot(_)
1230
1231            // Command (raw/unparsed statements)
1232            | Expression::Command(_)
1233            | Expression::Raw(_)
1234            | Expression::CreateTask(_)
1235
1236            // Return statement
1237            | Expression::ReturnStmt(_) => true,
1238
1239            // Annotated wraps another expression with comments — check inner
1240            Expression::Annotated(a) => a.this.is_statement(),
1241
1242            // Alias at top level can wrap a statement (e.g., parenthesized subquery with alias)
1243            Expression::Alias(a) => a.this.is_statement(),
1244
1245            // Everything else (identifiers, literals, operators, functions, etc.)
1246            _ => false,
1247        }
1248    }
1249
1250    /// Create a literal number expression from an integer.
1251    pub fn number(n: i64) -> Self {
1252        Expression::Literal(Box::new(Literal::Number(n.to_string())))
1253    }
1254
1255    /// Create a single-quoted literal string expression.
1256    pub fn string(s: impl Into<String>) -> Self {
1257        Expression::Literal(Box::new(Literal::String(s.into())))
1258    }
1259
1260    /// Create a literal number expression from a float.
1261    pub fn float(f: f64) -> Self {
1262        Expression::Literal(Box::new(Literal::Number(f.to_string())))
1263    }
1264
1265    /// Get the inferred type annotation, if present.
1266    ///
1267    /// For value-producing expressions with an `inferred_type` field, returns
1268    /// the stored type. For literals and boolean constants, computes the type
1269    /// on the fly from the variant. For DDL/clause expressions, returns `None`.
1270    pub fn inferred_type(&self) -> Option<&DataType> {
1271        match self {
1272            // Structs with inferred_type field
1273            Expression::And(op)
1274            | Expression::Or(op)
1275            | Expression::Add(op)
1276            | Expression::Sub(op)
1277            | Expression::Mul(op)
1278            | Expression::Div(op)
1279            | Expression::Mod(op)
1280            | Expression::Eq(op)
1281            | Expression::Neq(op)
1282            | Expression::Lt(op)
1283            | Expression::Lte(op)
1284            | Expression::Gt(op)
1285            | Expression::Gte(op)
1286            | Expression::Concat(op)
1287            | Expression::BitwiseAnd(op)
1288            | Expression::BitwiseOr(op)
1289            | Expression::BitwiseXor(op)
1290            | Expression::Adjacent(op)
1291            | Expression::TsMatch(op)
1292            | Expression::PropertyEQ(op)
1293            | Expression::ArrayContainsAll(op)
1294            | Expression::ArrayContainedBy(op)
1295            | Expression::ArrayOverlaps(op)
1296            | Expression::JSONBContainsAllTopKeys(op)
1297            | Expression::JSONBContainsAnyTopKeys(op)
1298            | Expression::JSONBDeleteAtPath(op)
1299            | Expression::ExtendsLeft(op)
1300            | Expression::ExtendsRight(op)
1301            | Expression::Is(op)
1302            | Expression::MemberOf(op)
1303            | Expression::Match(op)
1304            | Expression::NullSafeEq(op)
1305            | Expression::NullSafeNeq(op)
1306            | Expression::Glob(op)
1307            | Expression::BitwiseLeftShift(op)
1308            | Expression::BitwiseRightShift(op) => op.inferred_type.as_ref(),
1309
1310            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1311                op.inferred_type.as_ref()
1312            }
1313
1314            Expression::Like(op) | Expression::ILike(op) => op.inferred_type.as_ref(),
1315
1316            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1317                c.inferred_type.as_ref()
1318            }
1319
1320            Expression::Column(c) => c.inferred_type.as_ref(),
1321            Expression::Function(f) => f.inferred_type.as_ref(),
1322            Expression::AggregateFunction(f) => f.inferred_type.as_ref(),
1323            Expression::WindowFunction(f) => f.inferred_type.as_ref(),
1324            Expression::Case(c) => c.inferred_type.as_ref(),
1325            Expression::Subquery(s) => s.inferred_type.as_ref(),
1326            Expression::Alias(a) => a.inferred_type.as_ref(),
1327            Expression::Unnest(u) => u.inferred_type.as_ref(),
1328            Expression::IfFunc(f) => f.inferred_type.as_ref(),
1329            Expression::Nvl2(f) => f.inferred_type.as_ref(),
1330            Expression::Count(f) => f.inferred_type.as_ref(),
1331            Expression::GroupConcat(f) => f.inferred_type.as_ref(),
1332            Expression::StringAgg(f) => f.inferred_type.as_ref(),
1333            Expression::ListAgg(f) => f.inferred_type.as_ref(),
1334            Expression::SumIf(f) => f.inferred_type.as_ref(),
1335
1336            // UnaryFunc variants
1337            Expression::Upper(f)
1338            | Expression::Lower(f)
1339            | Expression::Length(f)
1340            | Expression::LTrim(f)
1341            | Expression::RTrim(f)
1342            | Expression::Reverse(f)
1343            | Expression::Abs(f)
1344            | Expression::Sqrt(f)
1345            | Expression::Cbrt(f)
1346            | Expression::Ln(f)
1347            | Expression::Exp(f)
1348            | Expression::Sign(f)
1349            | Expression::Date(f)
1350            | Expression::Time(f)
1351            | Expression::Initcap(f)
1352            | Expression::Ascii(f)
1353            | Expression::Chr(f)
1354            | Expression::Soundex(f)
1355            | Expression::ByteLength(f)
1356            | Expression::Hex(f)
1357            | Expression::LowerHex(f)
1358            | Expression::Unicode(f)
1359            | Expression::Typeof(f)
1360            | Expression::Explode(f)
1361            | Expression::ExplodeOuter(f)
1362            | Expression::MapFromEntries(f)
1363            | Expression::MapKeys(f)
1364            | Expression::MapValues(f)
1365            | Expression::ArrayLength(f)
1366            | Expression::ArraySize(f)
1367            | Expression::Cardinality(f)
1368            | Expression::ArrayReverse(f)
1369            | Expression::ArrayDistinct(f)
1370            | Expression::ArrayFlatten(f)
1371            | Expression::ArrayCompact(f)
1372            | Expression::ToArray(f)
1373            | Expression::JsonArrayLength(f)
1374            | Expression::JsonKeys(f)
1375            | Expression::JsonType(f)
1376            | Expression::ParseJson(f)
1377            | Expression::ToJson(f)
1378            | Expression::Radians(f)
1379            | Expression::Degrees(f)
1380            | Expression::Sin(f)
1381            | Expression::Cos(f)
1382            | Expression::Tan(f)
1383            | Expression::Asin(f)
1384            | Expression::Acos(f)
1385            | Expression::Atan(f)
1386            | Expression::IsNan(f)
1387            | Expression::IsInf(f)
1388            | Expression::Year(f)
1389            | Expression::Month(f)
1390            | Expression::Day(f)
1391            | Expression::Hour(f)
1392            | Expression::Minute(f)
1393            | Expression::Second(f)
1394            | Expression::DayOfWeek(f)
1395            | Expression::DayOfWeekIso(f)
1396            | Expression::DayOfMonth(f)
1397            | Expression::DayOfYear(f)
1398            | Expression::WeekOfYear(f)
1399            | Expression::Quarter(f)
1400            | Expression::Epoch(f)
1401            | Expression::EpochMs(f)
1402            | Expression::BitwiseCount(f)
1403            | Expression::DateFromUnixDate(f)
1404            | Expression::UnixDate(f)
1405            | Expression::UnixSeconds(f)
1406            | Expression::UnixMillis(f)
1407            | Expression::UnixMicros(f)
1408            | Expression::TimeStrToDate(f)
1409            | Expression::DateToDi(f)
1410            | Expression::DiToDate(f)
1411            | Expression::TsOrDiToDi(f)
1412            | Expression::TsOrDsToDatetime(f)
1413            | Expression::TsOrDsToTimestamp(f)
1414            | Expression::YearOfWeek(f)
1415            | Expression::YearOfWeekIso(f)
1416            | Expression::SHA(f)
1417            | Expression::SHA1Digest(f)
1418            | Expression::TimeToUnix(f)
1419            | Expression::TimeStrToUnix(f) => f.inferred_type.as_ref(),
1420
1421            // BinaryFunc variants
1422            Expression::Power(f)
1423            | Expression::NullIf(f)
1424            | Expression::IfNull(f)
1425            | Expression::Nvl(f)
1426            | Expression::Contains(f)
1427            | Expression::StartsWith(f)
1428            | Expression::EndsWith(f)
1429            | Expression::Levenshtein(f)
1430            | Expression::ModFunc(f)
1431            | Expression::IntDiv(f)
1432            | Expression::Atan2(f)
1433            | Expression::AddMonths(f)
1434            | Expression::MonthsBetween(f)
1435            | Expression::NextDay(f)
1436            | Expression::UnixToTimeStr(f)
1437            | Expression::ArrayContains(f)
1438            | Expression::ArrayPosition(f)
1439            | Expression::ArrayAppend(f)
1440            | Expression::ArrayPrepend(f)
1441            | Expression::ArrayUnion(f)
1442            | Expression::ArrayExcept(f)
1443            | Expression::ArrayRemove(f)
1444            | Expression::StarMap(f)
1445            | Expression::MapFromArrays(f)
1446            | Expression::MapContainsKey(f)
1447            | Expression::ElementAt(f)
1448            | Expression::JsonMergePatch(f) => f.inferred_type.as_ref(),
1449
1450            // VarArgFunc variants
1451            Expression::Coalesce(f)
1452            | Expression::Greatest(f)
1453            | Expression::Least(f)
1454            | Expression::ArrayConcat(f)
1455            | Expression::ArrayIntersect(f)
1456            | Expression::ArrayZip(f)
1457            | Expression::MapConcat(f)
1458            | Expression::JsonArray(f) => f.inferred_type.as_ref(),
1459
1460            // AggFunc variants
1461            Expression::Sum(f)
1462            | Expression::Avg(f)
1463            | Expression::Min(f)
1464            | Expression::Max(f)
1465            | Expression::ArrayAgg(f)
1466            | Expression::CountIf(f)
1467            | Expression::Stddev(f)
1468            | Expression::StddevPop(f)
1469            | Expression::StddevSamp(f)
1470            | Expression::Variance(f)
1471            | Expression::VarPop(f)
1472            | Expression::VarSamp(f)
1473            | Expression::Median(f)
1474            | Expression::Mode(f)
1475            | Expression::First(f)
1476            | Expression::Last(f)
1477            | Expression::AnyValue(f)
1478            | Expression::ApproxDistinct(f)
1479            | Expression::ApproxCountDistinct(f)
1480            | Expression::LogicalAnd(f)
1481            | Expression::LogicalOr(f)
1482            | Expression::Skewness(f)
1483            | Expression::ArrayConcatAgg(f)
1484            | Expression::ArrayUniqueAgg(f)
1485            | Expression::BoolXorAgg(f)
1486            | Expression::BitwiseAndAgg(f)
1487            | Expression::BitwiseOrAgg(f)
1488            | Expression::BitwiseXorAgg(f) => f.inferred_type.as_ref(),
1489
1490            // Everything else: no inferred_type field
1491            _ => None,
1492        }
1493    }
1494
1495    /// Set the inferred type annotation on this expression.
1496    ///
1497    /// Only has an effect on value-producing expressions with an `inferred_type`
1498    /// field. For other expression types, this is a no-op.
1499    pub fn set_inferred_type(&mut self, dt: DataType) {
1500        match self {
1501            Expression::And(op)
1502            | Expression::Or(op)
1503            | Expression::Add(op)
1504            | Expression::Sub(op)
1505            | Expression::Mul(op)
1506            | Expression::Div(op)
1507            | Expression::Mod(op)
1508            | Expression::Eq(op)
1509            | Expression::Neq(op)
1510            | Expression::Lt(op)
1511            | Expression::Lte(op)
1512            | Expression::Gt(op)
1513            | Expression::Gte(op)
1514            | Expression::Concat(op)
1515            | Expression::BitwiseAnd(op)
1516            | Expression::BitwiseOr(op)
1517            | Expression::BitwiseXor(op)
1518            | Expression::Adjacent(op)
1519            | Expression::TsMatch(op)
1520            | Expression::PropertyEQ(op)
1521            | Expression::ArrayContainsAll(op)
1522            | Expression::ArrayContainedBy(op)
1523            | Expression::ArrayOverlaps(op)
1524            | Expression::JSONBContainsAllTopKeys(op)
1525            | Expression::JSONBContainsAnyTopKeys(op)
1526            | Expression::JSONBDeleteAtPath(op)
1527            | Expression::ExtendsLeft(op)
1528            | Expression::ExtendsRight(op)
1529            | Expression::Is(op)
1530            | Expression::MemberOf(op)
1531            | Expression::Match(op)
1532            | Expression::NullSafeEq(op)
1533            | Expression::NullSafeNeq(op)
1534            | Expression::Glob(op)
1535            | Expression::BitwiseLeftShift(op)
1536            | Expression::BitwiseRightShift(op) => op.inferred_type = Some(dt),
1537
1538            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1539                op.inferred_type = Some(dt)
1540            }
1541
1542            Expression::Like(op) | Expression::ILike(op) => op.inferred_type = Some(dt),
1543
1544            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1545                c.inferred_type = Some(dt)
1546            }
1547
1548            Expression::Column(c) => c.inferred_type = Some(dt),
1549            Expression::Function(f) => f.inferred_type = Some(dt),
1550            Expression::AggregateFunction(f) => f.inferred_type = Some(dt),
1551            Expression::WindowFunction(f) => f.inferred_type = Some(dt),
1552            Expression::Case(c) => c.inferred_type = Some(dt),
1553            Expression::Subquery(s) => s.inferred_type = Some(dt),
1554            Expression::Alias(a) => a.inferred_type = Some(dt),
1555            Expression::Unnest(u) => u.inferred_type = Some(dt),
1556            Expression::IfFunc(f) => f.inferred_type = Some(dt),
1557            Expression::Nvl2(f) => f.inferred_type = Some(dt),
1558            Expression::Count(f) => f.inferred_type = Some(dt),
1559            Expression::GroupConcat(f) => f.inferred_type = Some(dt),
1560            Expression::StringAgg(f) => f.inferred_type = Some(dt),
1561            Expression::ListAgg(f) => f.inferred_type = Some(dt),
1562            Expression::SumIf(f) => f.inferred_type = Some(dt),
1563
1564            // UnaryFunc variants
1565            Expression::Upper(f)
1566            | Expression::Lower(f)
1567            | Expression::Length(f)
1568            | Expression::LTrim(f)
1569            | Expression::RTrim(f)
1570            | Expression::Reverse(f)
1571            | Expression::Abs(f)
1572            | Expression::Sqrt(f)
1573            | Expression::Cbrt(f)
1574            | Expression::Ln(f)
1575            | Expression::Exp(f)
1576            | Expression::Sign(f)
1577            | Expression::Date(f)
1578            | Expression::Time(f)
1579            | Expression::Initcap(f)
1580            | Expression::Ascii(f)
1581            | Expression::Chr(f)
1582            | Expression::Soundex(f)
1583            | Expression::ByteLength(f)
1584            | Expression::Hex(f)
1585            | Expression::LowerHex(f)
1586            | Expression::Unicode(f)
1587            | Expression::Typeof(f)
1588            | Expression::Explode(f)
1589            | Expression::ExplodeOuter(f)
1590            | Expression::MapFromEntries(f)
1591            | Expression::MapKeys(f)
1592            | Expression::MapValues(f)
1593            | Expression::ArrayLength(f)
1594            | Expression::ArraySize(f)
1595            | Expression::Cardinality(f)
1596            | Expression::ArrayReverse(f)
1597            | Expression::ArrayDistinct(f)
1598            | Expression::ArrayFlatten(f)
1599            | Expression::ArrayCompact(f)
1600            | Expression::ToArray(f)
1601            | Expression::JsonArrayLength(f)
1602            | Expression::JsonKeys(f)
1603            | Expression::JsonType(f)
1604            | Expression::ParseJson(f)
1605            | Expression::ToJson(f)
1606            | Expression::Radians(f)
1607            | Expression::Degrees(f)
1608            | Expression::Sin(f)
1609            | Expression::Cos(f)
1610            | Expression::Tan(f)
1611            | Expression::Asin(f)
1612            | Expression::Acos(f)
1613            | Expression::Atan(f)
1614            | Expression::IsNan(f)
1615            | Expression::IsInf(f)
1616            | Expression::Year(f)
1617            | Expression::Month(f)
1618            | Expression::Day(f)
1619            | Expression::Hour(f)
1620            | Expression::Minute(f)
1621            | Expression::Second(f)
1622            | Expression::DayOfWeek(f)
1623            | Expression::DayOfWeekIso(f)
1624            | Expression::DayOfMonth(f)
1625            | Expression::DayOfYear(f)
1626            | Expression::WeekOfYear(f)
1627            | Expression::Quarter(f)
1628            | Expression::Epoch(f)
1629            | Expression::EpochMs(f)
1630            | Expression::BitwiseCount(f)
1631            | Expression::DateFromUnixDate(f)
1632            | Expression::UnixDate(f)
1633            | Expression::UnixSeconds(f)
1634            | Expression::UnixMillis(f)
1635            | Expression::UnixMicros(f)
1636            | Expression::TimeStrToDate(f)
1637            | Expression::DateToDi(f)
1638            | Expression::DiToDate(f)
1639            | Expression::TsOrDiToDi(f)
1640            | Expression::TsOrDsToDatetime(f)
1641            | Expression::TsOrDsToTimestamp(f)
1642            | Expression::YearOfWeek(f)
1643            | Expression::YearOfWeekIso(f)
1644            | Expression::SHA(f)
1645            | Expression::SHA1Digest(f)
1646            | Expression::TimeToUnix(f)
1647            | Expression::TimeStrToUnix(f) => f.inferred_type = Some(dt),
1648
1649            // BinaryFunc variants
1650            Expression::Power(f)
1651            | Expression::NullIf(f)
1652            | Expression::IfNull(f)
1653            | Expression::Nvl(f)
1654            | Expression::Contains(f)
1655            | Expression::StartsWith(f)
1656            | Expression::EndsWith(f)
1657            | Expression::Levenshtein(f)
1658            | Expression::ModFunc(f)
1659            | Expression::IntDiv(f)
1660            | Expression::Atan2(f)
1661            | Expression::AddMonths(f)
1662            | Expression::MonthsBetween(f)
1663            | Expression::NextDay(f)
1664            | Expression::UnixToTimeStr(f)
1665            | Expression::ArrayContains(f)
1666            | Expression::ArrayPosition(f)
1667            | Expression::ArrayAppend(f)
1668            | Expression::ArrayPrepend(f)
1669            | Expression::ArrayUnion(f)
1670            | Expression::ArrayExcept(f)
1671            | Expression::ArrayRemove(f)
1672            | Expression::StarMap(f)
1673            | Expression::MapFromArrays(f)
1674            | Expression::MapContainsKey(f)
1675            | Expression::ElementAt(f)
1676            | Expression::JsonMergePatch(f) => f.inferred_type = Some(dt),
1677
1678            // VarArgFunc variants
1679            Expression::Coalesce(f)
1680            | Expression::Greatest(f)
1681            | Expression::Least(f)
1682            | Expression::ArrayConcat(f)
1683            | Expression::ArrayIntersect(f)
1684            | Expression::ArrayZip(f)
1685            | Expression::MapConcat(f)
1686            | Expression::JsonArray(f) => f.inferred_type = Some(dt),
1687
1688            // AggFunc variants
1689            Expression::Sum(f)
1690            | Expression::Avg(f)
1691            | Expression::Min(f)
1692            | Expression::Max(f)
1693            | Expression::ArrayAgg(f)
1694            | Expression::CountIf(f)
1695            | Expression::Stddev(f)
1696            | Expression::StddevPop(f)
1697            | Expression::StddevSamp(f)
1698            | Expression::Variance(f)
1699            | Expression::VarPop(f)
1700            | Expression::VarSamp(f)
1701            | Expression::Median(f)
1702            | Expression::Mode(f)
1703            | Expression::First(f)
1704            | Expression::Last(f)
1705            | Expression::AnyValue(f)
1706            | Expression::ApproxDistinct(f)
1707            | Expression::ApproxCountDistinct(f)
1708            | Expression::LogicalAnd(f)
1709            | Expression::LogicalOr(f)
1710            | Expression::Skewness(f)
1711            | Expression::ArrayConcatAgg(f)
1712            | Expression::ArrayUniqueAgg(f)
1713            | Expression::BoolXorAgg(f)
1714            | Expression::BitwiseAndAgg(f)
1715            | Expression::BitwiseOrAgg(f)
1716            | Expression::BitwiseXorAgg(f) => f.inferred_type = Some(dt),
1717
1718            // Expressions without inferred_type field - no-op
1719            _ => {}
1720        }
1721    }
1722
1723    /// Create an unqualified column reference (e.g. `name`).
1724    pub fn column(name: impl Into<String>) -> Self {
1725        Expression::Column(Box::new(Column {
1726            name: Identifier::new(name),
1727            table: None,
1728            join_mark: false,
1729            trailing_comments: Vec::new(),
1730            span: None,
1731            inferred_type: None,
1732        }))
1733    }
1734
1735    /// Create a qualified column reference (`table.column`).
1736    pub fn qualified_column(table: impl Into<String>, column: impl Into<String>) -> Self {
1737        Expression::Column(Box::new(Column {
1738            name: Identifier::new(column),
1739            table: Some(Identifier::new(table)),
1740            join_mark: false,
1741            trailing_comments: Vec::new(),
1742            span: None,
1743            inferred_type: None,
1744        }))
1745    }
1746
1747    /// Create a bare identifier expression (not a column reference).
1748    pub fn identifier(name: impl Into<String>) -> Self {
1749        Expression::Identifier(Identifier::new(name))
1750    }
1751
1752    /// Create a NULL expression
1753    pub fn null() -> Self {
1754        Expression::Null(Null)
1755    }
1756
1757    /// Create a TRUE expression
1758    pub fn true_() -> Self {
1759        Expression::Boolean(BooleanLiteral { value: true })
1760    }
1761
1762    /// Create a FALSE expression
1763    pub fn false_() -> Self {
1764        Expression::Boolean(BooleanLiteral { value: false })
1765    }
1766
1767    /// Create a wildcard star (`*`) expression with no EXCEPT/REPLACE/RENAME modifiers.
1768    pub fn star() -> Self {
1769        Expression::Star(Star {
1770            table: None,
1771            except: None,
1772            replace: None,
1773            rename: None,
1774            trailing_comments: Vec::new(),
1775            span: None,
1776        })
1777    }
1778
1779    /// Wrap this expression in an `AS` alias (e.g. `expr AS name`).
1780    pub fn alias(self, name: impl Into<String>) -> Self {
1781        Expression::Alias(Box::new(Alias::new(self, Identifier::new(name))))
1782    }
1783
1784    /// Check if this is a SELECT expression
1785    pub fn is_select(&self) -> bool {
1786        matches!(self, Expression::Select(_))
1787    }
1788
1789    /// Try to get as a Select
1790    pub fn as_select(&self) -> Option<&Select> {
1791        match self {
1792            Expression::Select(s) => Some(s),
1793            _ => None,
1794        }
1795    }
1796
1797    /// Try to get as a mutable Select
1798    pub fn as_select_mut(&mut self) -> Option<&mut Select> {
1799        match self {
1800            Expression::Select(s) => Some(s),
1801            _ => None,
1802        }
1803    }
1804
1805    /// Generate a SQL string for this expression using the generic (dialect-agnostic) generator.
1806    ///
1807    /// Returns an empty string if generation fails. For dialect-specific output,
1808    /// use [`sql_for()`](Self::sql_for) instead.
1809    #[cfg(feature = "generate")]
1810    pub fn sql(&self) -> String {
1811        crate::generator::Generator::sql(self).unwrap_or_default()
1812    }
1813
1814    /// Generate a SQL string for this expression targeting a specific dialect.
1815    ///
1816    /// Dialect-specific rules (identifier quoting, function names, type mappings,
1817    /// syntax variations) are applied automatically.  Returns an empty string if
1818    /// generation fails.
1819    #[cfg(feature = "generate")]
1820    pub fn sql_for(&self, dialect: crate::dialects::DialectType) -> String {
1821        crate::generate(self, dialect).unwrap_or_default()
1822    }
1823}
1824
1825// === Python API accessor methods ===
1826
1827impl Expression {
1828    /// Returns the serde-compatible snake_case variant name without serialization.
1829    /// This is much faster than serializing to JSON and extracting the key.
1830    pub fn variant_name(&self) -> &'static str {
1831        match self {
1832            Expression::Literal(_) => "literal",
1833            Expression::Boolean(_) => "boolean",
1834            Expression::Null(_) => "null",
1835            Expression::Identifier(_) => "identifier",
1836            Expression::Column(_) => "column",
1837            Expression::Table(_) => "table",
1838            Expression::Star(_) => "star",
1839            Expression::BracedWildcard(_) => "braced_wildcard",
1840            Expression::Select(_) => "select",
1841            Expression::Union(_) => "union",
1842            Expression::Intersect(_) => "intersect",
1843            Expression::Except(_) => "except",
1844            Expression::Subquery(_) => "subquery",
1845            Expression::PipeOperator(_) => "pipe_operator",
1846            Expression::Pivot(_) => "pivot",
1847            Expression::PivotAlias(_) => "pivot_alias",
1848            Expression::Unpivot(_) => "unpivot",
1849            Expression::Values(_) => "values",
1850            Expression::PreWhere(_) => "pre_where",
1851            Expression::Stream(_) => "stream",
1852            Expression::UsingData(_) => "using_data",
1853            Expression::XmlNamespace(_) => "xml_namespace",
1854            Expression::Insert(_) => "insert",
1855            Expression::Update(_) => "update",
1856            Expression::Delete(_) => "delete",
1857            Expression::Copy(_) => "copy",
1858            Expression::Put(_) => "put",
1859            Expression::StageReference(_) => "stage_reference",
1860            Expression::Alias(_) => "alias",
1861            Expression::Cast(_) => "cast",
1862            Expression::Collation(_) => "collation",
1863            Expression::Case(_) => "case",
1864            Expression::And(_) => "and",
1865            Expression::Or(_) => "or",
1866            Expression::Add(_) => "add",
1867            Expression::Sub(_) => "sub",
1868            Expression::Mul(_) => "mul",
1869            Expression::Div(_) => "div",
1870            Expression::Mod(_) => "mod",
1871            Expression::Eq(_) => "eq",
1872            Expression::Neq(_) => "neq",
1873            Expression::Lt(_) => "lt",
1874            Expression::Lte(_) => "lte",
1875            Expression::Gt(_) => "gt",
1876            Expression::Gte(_) => "gte",
1877            Expression::Like(_) => "like",
1878            Expression::ILike(_) => "i_like",
1879            Expression::Match(_) => "match",
1880            Expression::BitwiseAnd(_) => "bitwise_and",
1881            Expression::BitwiseOr(_) => "bitwise_or",
1882            Expression::BitwiseXor(_) => "bitwise_xor",
1883            Expression::Concat(_) => "concat",
1884            Expression::Adjacent(_) => "adjacent",
1885            Expression::TsMatch(_) => "ts_match",
1886            Expression::PropertyEQ(_) => "property_e_q",
1887            Expression::ArrayContainsAll(_) => "array_contains_all",
1888            Expression::ArrayContainedBy(_) => "array_contained_by",
1889            Expression::ArrayOverlaps(_) => "array_overlaps",
1890            Expression::JSONBContainsAllTopKeys(_) => "j_s_o_n_b_contains_all_top_keys",
1891            Expression::JSONBContainsAnyTopKeys(_) => "j_s_o_n_b_contains_any_top_keys",
1892            Expression::JSONBDeleteAtPath(_) => "j_s_o_n_b_delete_at_path",
1893            Expression::ExtendsLeft(_) => "extends_left",
1894            Expression::ExtendsRight(_) => "extends_right",
1895            Expression::Not(_) => "not",
1896            Expression::Neg(_) => "neg",
1897            Expression::BitwiseNot(_) => "bitwise_not",
1898            Expression::In(_) => "in",
1899            Expression::Between(_) => "between",
1900            Expression::IsNull(_) => "is_null",
1901            Expression::IsTrue(_) => "is_true",
1902            Expression::IsFalse(_) => "is_false",
1903            Expression::IsJson(_) => "is_json",
1904            Expression::Is(_) => "is",
1905            Expression::Exists(_) => "exists",
1906            Expression::MemberOf(_) => "member_of",
1907            Expression::Function(_) => "function",
1908            Expression::AggregateFunction(_) => "aggregate_function",
1909            Expression::WindowFunction(_) => "window_function",
1910            Expression::From(_) => "from",
1911            Expression::Join(_) => "join",
1912            Expression::JoinedTable(_) => "joined_table",
1913            Expression::Where(_) => "where",
1914            Expression::GroupBy(_) => "group_by",
1915            Expression::Having(_) => "having",
1916            Expression::OrderBy(_) => "order_by",
1917            Expression::Limit(_) => "limit",
1918            Expression::Offset(_) => "offset",
1919            Expression::Qualify(_) => "qualify",
1920            Expression::With(_) => "with",
1921            Expression::Cte(_) => "cte",
1922            Expression::DistributeBy(_) => "distribute_by",
1923            Expression::ClusterBy(_) => "cluster_by",
1924            Expression::SortBy(_) => "sort_by",
1925            Expression::LateralView(_) => "lateral_view",
1926            Expression::Hint(_) => "hint",
1927            Expression::Pseudocolumn(_) => "pseudocolumn",
1928            Expression::Connect(_) => "connect",
1929            Expression::Prior(_) => "prior",
1930            Expression::ConnectByRoot(_) => "connect_by_root",
1931            Expression::MatchRecognize(_) => "match_recognize",
1932            Expression::Ordered(_) => "ordered",
1933            Expression::Window(_) => "window",
1934            Expression::Over(_) => "over",
1935            Expression::WithinGroup(_) => "within_group",
1936            Expression::DataType(_) => "data_type",
1937            Expression::Array(_) => "array",
1938            Expression::Struct(_) => "struct",
1939            Expression::Tuple(_) => "tuple",
1940            Expression::Interval(_) => "interval",
1941            Expression::ConcatWs(_) => "concat_ws",
1942            Expression::Substring(_) => "substring",
1943            Expression::Upper(_) => "upper",
1944            Expression::Lower(_) => "lower",
1945            Expression::Length(_) => "length",
1946            Expression::Trim(_) => "trim",
1947            Expression::LTrim(_) => "l_trim",
1948            Expression::RTrim(_) => "r_trim",
1949            Expression::Replace(_) => "replace",
1950            Expression::Reverse(_) => "reverse",
1951            Expression::Left(_) => "left",
1952            Expression::Right(_) => "right",
1953            Expression::Repeat(_) => "repeat",
1954            Expression::Lpad(_) => "lpad",
1955            Expression::Rpad(_) => "rpad",
1956            Expression::Split(_) => "split",
1957            Expression::RegexpLike(_) => "regexp_like",
1958            Expression::RegexpReplace(_) => "regexp_replace",
1959            Expression::RegexpExtract(_) => "regexp_extract",
1960            Expression::Overlay(_) => "overlay",
1961            Expression::Abs(_) => "abs",
1962            Expression::Round(_) => "round",
1963            Expression::Floor(_) => "floor",
1964            Expression::Ceil(_) => "ceil",
1965            Expression::Power(_) => "power",
1966            Expression::Sqrt(_) => "sqrt",
1967            Expression::Cbrt(_) => "cbrt",
1968            Expression::Ln(_) => "ln",
1969            Expression::Log(_) => "log",
1970            Expression::Exp(_) => "exp",
1971            Expression::Sign(_) => "sign",
1972            Expression::Greatest(_) => "greatest",
1973            Expression::Least(_) => "least",
1974            Expression::CurrentDate(_) => "current_date",
1975            Expression::CurrentTime(_) => "current_time",
1976            Expression::CurrentTimestamp(_) => "current_timestamp",
1977            Expression::CurrentTimestampLTZ(_) => "current_timestamp_l_t_z",
1978            Expression::AtTimeZone(_) => "at_time_zone",
1979            Expression::DateAdd(_) => "date_add",
1980            Expression::DateSub(_) => "date_sub",
1981            Expression::DateDiff(_) => "date_diff",
1982            Expression::DateTrunc(_) => "date_trunc",
1983            Expression::Extract(_) => "extract",
1984            Expression::ToDate(_) => "to_date",
1985            Expression::ToTimestamp(_) => "to_timestamp",
1986            Expression::Date(_) => "date",
1987            Expression::Time(_) => "time",
1988            Expression::DateFromUnixDate(_) => "date_from_unix_date",
1989            Expression::UnixDate(_) => "unix_date",
1990            Expression::UnixSeconds(_) => "unix_seconds",
1991            Expression::UnixMillis(_) => "unix_millis",
1992            Expression::UnixMicros(_) => "unix_micros",
1993            Expression::UnixToTimeStr(_) => "unix_to_time_str",
1994            Expression::TimeStrToDate(_) => "time_str_to_date",
1995            Expression::DateToDi(_) => "date_to_di",
1996            Expression::DiToDate(_) => "di_to_date",
1997            Expression::TsOrDiToDi(_) => "ts_or_di_to_di",
1998            Expression::TsOrDsToDatetime(_) => "ts_or_ds_to_datetime",
1999            Expression::TsOrDsToTimestamp(_) => "ts_or_ds_to_timestamp",
2000            Expression::YearOfWeek(_) => "year_of_week",
2001            Expression::YearOfWeekIso(_) => "year_of_week_iso",
2002            Expression::Coalesce(_) => "coalesce",
2003            Expression::NullIf(_) => "null_if",
2004            Expression::IfFunc(_) => "if_func",
2005            Expression::IfNull(_) => "if_null",
2006            Expression::Nvl(_) => "nvl",
2007            Expression::Nvl2(_) => "nvl2",
2008            Expression::TryCast(_) => "try_cast",
2009            Expression::SafeCast(_) => "safe_cast",
2010            Expression::Count(_) => "count",
2011            Expression::Sum(_) => "sum",
2012            Expression::Avg(_) => "avg",
2013            Expression::Min(_) => "min",
2014            Expression::Max(_) => "max",
2015            Expression::GroupConcat(_) => "group_concat",
2016            Expression::StringAgg(_) => "string_agg",
2017            Expression::ListAgg(_) => "list_agg",
2018            Expression::ArrayAgg(_) => "array_agg",
2019            Expression::CountIf(_) => "count_if",
2020            Expression::SumIf(_) => "sum_if",
2021            Expression::Stddev(_) => "stddev",
2022            Expression::StddevPop(_) => "stddev_pop",
2023            Expression::StddevSamp(_) => "stddev_samp",
2024            Expression::Variance(_) => "variance",
2025            Expression::VarPop(_) => "var_pop",
2026            Expression::VarSamp(_) => "var_samp",
2027            Expression::Median(_) => "median",
2028            Expression::Mode(_) => "mode",
2029            Expression::First(_) => "first",
2030            Expression::Last(_) => "last",
2031            Expression::AnyValue(_) => "any_value",
2032            Expression::ApproxDistinct(_) => "approx_distinct",
2033            Expression::ApproxCountDistinct(_) => "approx_count_distinct",
2034            Expression::ApproxPercentile(_) => "approx_percentile",
2035            Expression::Percentile(_) => "percentile",
2036            Expression::LogicalAnd(_) => "logical_and",
2037            Expression::LogicalOr(_) => "logical_or",
2038            Expression::Skewness(_) => "skewness",
2039            Expression::BitwiseCount(_) => "bitwise_count",
2040            Expression::ArrayConcatAgg(_) => "array_concat_agg",
2041            Expression::ArrayUniqueAgg(_) => "array_unique_agg",
2042            Expression::BoolXorAgg(_) => "bool_xor_agg",
2043            Expression::RowNumber(_) => "row_number",
2044            Expression::Rank(_) => "rank",
2045            Expression::DenseRank(_) => "dense_rank",
2046            Expression::NTile(_) => "n_tile",
2047            Expression::Lead(_) => "lead",
2048            Expression::Lag(_) => "lag",
2049            Expression::FirstValue(_) => "first_value",
2050            Expression::LastValue(_) => "last_value",
2051            Expression::NthValue(_) => "nth_value",
2052            Expression::PercentRank(_) => "percent_rank",
2053            Expression::CumeDist(_) => "cume_dist",
2054            Expression::PercentileCont(_) => "percentile_cont",
2055            Expression::PercentileDisc(_) => "percentile_disc",
2056            Expression::Contains(_) => "contains",
2057            Expression::StartsWith(_) => "starts_with",
2058            Expression::EndsWith(_) => "ends_with",
2059            Expression::Position(_) => "position",
2060            Expression::Initcap(_) => "initcap",
2061            Expression::Ascii(_) => "ascii",
2062            Expression::Chr(_) => "chr",
2063            Expression::CharFunc(_) => "char_func",
2064            Expression::Soundex(_) => "soundex",
2065            Expression::Levenshtein(_) => "levenshtein",
2066            Expression::ByteLength(_) => "byte_length",
2067            Expression::Hex(_) => "hex",
2068            Expression::LowerHex(_) => "lower_hex",
2069            Expression::Unicode(_) => "unicode",
2070            Expression::ModFunc(_) => "mod_func",
2071            Expression::Random(_) => "random",
2072            Expression::Rand(_) => "rand",
2073            Expression::TruncFunc(_) => "trunc_func",
2074            Expression::Pi(_) => "pi",
2075            Expression::Radians(_) => "radians",
2076            Expression::Degrees(_) => "degrees",
2077            Expression::Sin(_) => "sin",
2078            Expression::Cos(_) => "cos",
2079            Expression::Tan(_) => "tan",
2080            Expression::Asin(_) => "asin",
2081            Expression::Acos(_) => "acos",
2082            Expression::Atan(_) => "atan",
2083            Expression::Atan2(_) => "atan2",
2084            Expression::IsNan(_) => "is_nan",
2085            Expression::IsInf(_) => "is_inf",
2086            Expression::IntDiv(_) => "int_div",
2087            Expression::Decode(_) => "decode",
2088            Expression::DateFormat(_) => "date_format",
2089            Expression::FormatDate(_) => "format_date",
2090            Expression::Year(_) => "year",
2091            Expression::Month(_) => "month",
2092            Expression::Day(_) => "day",
2093            Expression::Hour(_) => "hour",
2094            Expression::Minute(_) => "minute",
2095            Expression::Second(_) => "second",
2096            Expression::DayOfWeek(_) => "day_of_week",
2097            Expression::DayOfWeekIso(_) => "day_of_week_iso",
2098            Expression::DayOfMonth(_) => "day_of_month",
2099            Expression::DayOfYear(_) => "day_of_year",
2100            Expression::WeekOfYear(_) => "week_of_year",
2101            Expression::Quarter(_) => "quarter",
2102            Expression::AddMonths(_) => "add_months",
2103            Expression::MonthsBetween(_) => "months_between",
2104            Expression::LastDay(_) => "last_day",
2105            Expression::NextDay(_) => "next_day",
2106            Expression::Epoch(_) => "epoch",
2107            Expression::EpochMs(_) => "epoch_ms",
2108            Expression::FromUnixtime(_) => "from_unixtime",
2109            Expression::UnixTimestamp(_) => "unix_timestamp",
2110            Expression::MakeDate(_) => "make_date",
2111            Expression::MakeTimestamp(_) => "make_timestamp",
2112            Expression::TimestampTrunc(_) => "timestamp_trunc",
2113            Expression::TimeStrToUnix(_) => "time_str_to_unix",
2114            Expression::SessionUser(_) => "session_user",
2115            Expression::SHA(_) => "s_h_a",
2116            Expression::SHA1Digest(_) => "s_h_a1_digest",
2117            Expression::TimeToUnix(_) => "time_to_unix",
2118            Expression::ArrayFunc(_) => "array_func",
2119            Expression::ArrayLength(_) => "array_length",
2120            Expression::ArraySize(_) => "array_size",
2121            Expression::Cardinality(_) => "cardinality",
2122            Expression::ArrayContains(_) => "array_contains",
2123            Expression::ArrayPosition(_) => "array_position",
2124            Expression::ArrayAppend(_) => "array_append",
2125            Expression::ArrayPrepend(_) => "array_prepend",
2126            Expression::ArrayConcat(_) => "array_concat",
2127            Expression::ArraySort(_) => "array_sort",
2128            Expression::ArrayReverse(_) => "array_reverse",
2129            Expression::ArrayDistinct(_) => "array_distinct",
2130            Expression::ArrayJoin(_) => "array_join",
2131            Expression::ArrayToString(_) => "array_to_string",
2132            Expression::Unnest(_) => "unnest",
2133            Expression::Explode(_) => "explode",
2134            Expression::ExplodeOuter(_) => "explode_outer",
2135            Expression::ArrayFilter(_) => "array_filter",
2136            Expression::ArrayTransform(_) => "array_transform",
2137            Expression::ArrayFlatten(_) => "array_flatten",
2138            Expression::ArrayCompact(_) => "array_compact",
2139            Expression::ArrayIntersect(_) => "array_intersect",
2140            Expression::ArrayUnion(_) => "array_union",
2141            Expression::ArrayExcept(_) => "array_except",
2142            Expression::ArrayRemove(_) => "array_remove",
2143            Expression::ArrayZip(_) => "array_zip",
2144            Expression::Sequence(_) => "sequence",
2145            Expression::Generate(_) => "generate",
2146            Expression::ExplodingGenerateSeries(_) => "exploding_generate_series",
2147            Expression::ToArray(_) => "to_array",
2148            Expression::StarMap(_) => "star_map",
2149            Expression::StructFunc(_) => "struct_func",
2150            Expression::StructExtract(_) => "struct_extract",
2151            Expression::NamedStruct(_) => "named_struct",
2152            Expression::MapFunc(_) => "map_func",
2153            Expression::MapFromEntries(_) => "map_from_entries",
2154            Expression::MapFromArrays(_) => "map_from_arrays",
2155            Expression::MapKeys(_) => "map_keys",
2156            Expression::MapValues(_) => "map_values",
2157            Expression::MapContainsKey(_) => "map_contains_key",
2158            Expression::MapConcat(_) => "map_concat",
2159            Expression::ElementAt(_) => "element_at",
2160            Expression::TransformKeys(_) => "transform_keys",
2161            Expression::TransformValues(_) => "transform_values",
2162            Expression::FunctionEmits(_) => "function_emits",
2163            Expression::JsonExtract(_) => "json_extract",
2164            Expression::JsonExtractScalar(_) => "json_extract_scalar",
2165            Expression::JsonExtractPath(_) => "json_extract_path",
2166            Expression::JsonArray(_) => "json_array",
2167            Expression::JsonObject(_) => "json_object",
2168            Expression::JsonQuery(_) => "json_query",
2169            Expression::JsonValue(_) => "json_value",
2170            Expression::JsonArrayLength(_) => "json_array_length",
2171            Expression::JsonKeys(_) => "json_keys",
2172            Expression::JsonType(_) => "json_type",
2173            Expression::ParseJson(_) => "parse_json",
2174            Expression::ToJson(_) => "to_json",
2175            Expression::JsonSet(_) => "json_set",
2176            Expression::JsonInsert(_) => "json_insert",
2177            Expression::JsonRemove(_) => "json_remove",
2178            Expression::JsonMergePatch(_) => "json_merge_patch",
2179            Expression::JsonArrayAgg(_) => "json_array_agg",
2180            Expression::JsonObjectAgg(_) => "json_object_agg",
2181            Expression::Convert(_) => "convert",
2182            Expression::Typeof(_) => "typeof",
2183            Expression::Lambda(_) => "lambda",
2184            Expression::Parameter(_) => "parameter",
2185            Expression::Placeholder(_) => "placeholder",
2186            Expression::NamedArgument(_) => "named_argument",
2187            Expression::TableArgument(_) => "table_argument",
2188            Expression::SqlComment(_) => "sql_comment",
2189            Expression::NullSafeEq(_) => "null_safe_eq",
2190            Expression::NullSafeNeq(_) => "null_safe_neq",
2191            Expression::Glob(_) => "glob",
2192            Expression::SimilarTo(_) => "similar_to",
2193            Expression::Any(_) => "any",
2194            Expression::All(_) => "all",
2195            Expression::Overlaps(_) => "overlaps",
2196            Expression::BitwiseLeftShift(_) => "bitwise_left_shift",
2197            Expression::BitwiseRightShift(_) => "bitwise_right_shift",
2198            Expression::BitwiseAndAgg(_) => "bitwise_and_agg",
2199            Expression::BitwiseOrAgg(_) => "bitwise_or_agg",
2200            Expression::BitwiseXorAgg(_) => "bitwise_xor_agg",
2201            Expression::Subscript(_) => "subscript",
2202            Expression::Dot(_) => "dot",
2203            Expression::MethodCall(_) => "method_call",
2204            Expression::ArraySlice(_) => "array_slice",
2205            Expression::CreateTable(_) => "create_table",
2206            Expression::DropTable(_) => "drop_table",
2207            Expression::Undrop(_) => "undrop",
2208            Expression::AlterTable(_) => "alter_table",
2209            Expression::SplitTable(_) => "split_table",
2210            Expression::FlashbackTable(_) => "flashback_table",
2211            Expression::CreateIndex(_) => "create_index",
2212            Expression::DropIndex(_) => "drop_index",
2213            Expression::CreateView(_) => "create_view",
2214            Expression::DropView(_) => "drop_view",
2215            Expression::AlterView(_) => "alter_view",
2216            Expression::AlterIndex(_) => "alter_index",
2217            Expression::Truncate(_) => "truncate",
2218            Expression::Use(_) => "use",
2219            Expression::Cache(_) => "cache",
2220            Expression::Uncache(_) => "uncache",
2221            Expression::LoadData(_) => "load_data",
2222            Expression::Pragma(_) => "pragma",
2223            Expression::Grant(_) => "grant",
2224            Expression::Revoke(_) => "revoke",
2225            Expression::Comment(_) => "comment",
2226            Expression::SetStatement(_) => "set_statement",
2227            Expression::CreateSchema(_) => "create_schema",
2228            Expression::DropSchema(_) => "drop_schema",
2229            Expression::DropNamespace(_) => "drop_namespace",
2230            Expression::CreateDatabase(_) => "create_database",
2231            Expression::DropDatabase(_) => "drop_database",
2232            Expression::CreateFunction(_) => "create_function",
2233            Expression::DropFunction(_) => "drop_function",
2234            Expression::CreateProcedure(_) => "create_procedure",
2235            Expression::DropProcedure(_) => "drop_procedure",
2236            Expression::CreateSequence(_) => "create_sequence",
2237            Expression::CreateSynonym(_) => "create_synonym",
2238            Expression::DropSequence(_) => "drop_sequence",
2239            Expression::AlterSequence(_) => "alter_sequence",
2240            Expression::CreateTrigger(_) => "create_trigger",
2241            Expression::DropTrigger(_) => "drop_trigger",
2242            Expression::CreateType(_) => "create_type",
2243            Expression::DropType(_) => "drop_type",
2244            Expression::Describe(_) => "describe",
2245            Expression::Show(_) => "show",
2246            Expression::Command(_) => "command",
2247            Expression::TryCatch(_) => "try_catch",
2248            Expression::Kill(_) => "kill",
2249            Expression::Prepare(_) => "prepare",
2250            Expression::Execute(_) => "execute",
2251            Expression::Raw(_) => "raw",
2252            Expression::CreateTask(_) => "create_task",
2253            Expression::Paren(_) => "paren",
2254            Expression::Annotated(_) => "annotated",
2255            Expression::Refresh(_) => "refresh",
2256            Expression::LockingStatement(_) => "locking_statement",
2257            Expression::SequenceProperties(_) => "sequence_properties",
2258            Expression::TruncateTable(_) => "truncate_table",
2259            Expression::Clone(_) => "clone",
2260            Expression::Attach(_) => "attach",
2261            Expression::Detach(_) => "detach",
2262            Expression::Install(_) => "install",
2263            Expression::Summarize(_) => "summarize",
2264            Expression::Declare(_) => "declare",
2265            Expression::DeclareItem(_) => "declare_item",
2266            Expression::Set(_) => "set",
2267            Expression::Heredoc(_) => "heredoc",
2268            Expression::SetItem(_) => "set_item",
2269            Expression::QueryBand(_) => "query_band",
2270            Expression::UserDefinedFunction(_) => "user_defined_function",
2271            Expression::RecursiveWithSearch(_) => "recursive_with_search",
2272            Expression::ProjectionDef(_) => "projection_def",
2273            Expression::TableAlias(_) => "table_alias",
2274            Expression::ByteString(_) => "byte_string",
2275            Expression::HexStringExpr(_) => "hex_string_expr",
2276            Expression::UnicodeString(_) => "unicode_string",
2277            Expression::ColumnPosition(_) => "column_position",
2278            Expression::ColumnDef(_) => "column_def",
2279            Expression::AlterColumn(_) => "alter_column",
2280            Expression::AlterSortKey(_) => "alter_sort_key",
2281            Expression::AlterSet(_) => "alter_set",
2282            Expression::RenameColumn(_) => "rename_column",
2283            Expression::Comprehension(_) => "comprehension",
2284            Expression::MergeTreeTTLAction(_) => "merge_tree_t_t_l_action",
2285            Expression::MergeTreeTTL(_) => "merge_tree_t_t_l",
2286            Expression::IndexConstraintOption(_) => "index_constraint_option",
2287            Expression::ColumnConstraint(_) => "column_constraint",
2288            Expression::PeriodForSystemTimeConstraint(_) => "period_for_system_time_constraint",
2289            Expression::CaseSpecificColumnConstraint(_) => "case_specific_column_constraint",
2290            Expression::CharacterSetColumnConstraint(_) => "character_set_column_constraint",
2291            Expression::CheckColumnConstraint(_) => "check_column_constraint",
2292            Expression::AssumeColumnConstraint(_) => "assume_column_constraint",
2293            Expression::CompressColumnConstraint(_) => "compress_column_constraint",
2294            Expression::DateFormatColumnConstraint(_) => "date_format_column_constraint",
2295            Expression::EphemeralColumnConstraint(_) => "ephemeral_column_constraint",
2296            Expression::WithOperator(_) => "with_operator",
2297            Expression::GeneratedAsIdentityColumnConstraint(_) => {
2298                "generated_as_identity_column_constraint"
2299            }
2300            Expression::AutoIncrementColumnConstraint(_) => "auto_increment_column_constraint",
2301            Expression::CommentColumnConstraint(_) => "comment_column_constraint",
2302            Expression::GeneratedAsRowColumnConstraint(_) => "generated_as_row_column_constraint",
2303            Expression::IndexColumnConstraint(_) => "index_column_constraint",
2304            Expression::MaskingPolicyColumnConstraint(_) => "masking_policy_column_constraint",
2305            Expression::NotNullColumnConstraint(_) => "not_null_column_constraint",
2306            Expression::PrimaryKeyColumnConstraint(_) => "primary_key_column_constraint",
2307            Expression::UniqueColumnConstraint(_) => "unique_column_constraint",
2308            Expression::WatermarkColumnConstraint(_) => "watermark_column_constraint",
2309            Expression::ComputedColumnConstraint(_) => "computed_column_constraint",
2310            Expression::InOutColumnConstraint(_) => "in_out_column_constraint",
2311            Expression::DefaultColumnConstraint(_) => "default_column_constraint",
2312            Expression::PathColumnConstraint(_) => "path_column_constraint",
2313            Expression::Constraint(_) => "constraint",
2314            Expression::Export(_) => "export",
2315            Expression::Filter(_) => "filter",
2316            Expression::Changes(_) => "changes",
2317            Expression::CopyParameter(_) => "copy_parameter",
2318            Expression::Credentials(_) => "credentials",
2319            Expression::Directory(_) => "directory",
2320            Expression::ForeignKey(_) => "foreign_key",
2321            Expression::ColumnPrefix(_) => "column_prefix",
2322            Expression::PrimaryKey(_) => "primary_key",
2323            Expression::IntoClause(_) => "into_clause",
2324            Expression::JoinHint(_) => "join_hint",
2325            Expression::Opclass(_) => "opclass",
2326            Expression::Index(_) => "index",
2327            Expression::IndexParameters(_) => "index_parameters",
2328            Expression::ConditionalInsert(_) => "conditional_insert",
2329            Expression::MultitableInserts(_) => "multitable_inserts",
2330            Expression::OnConflict(_) => "on_conflict",
2331            Expression::OnCondition(_) => "on_condition",
2332            Expression::Returning(_) => "returning",
2333            Expression::Introducer(_) => "introducer",
2334            Expression::PartitionRange(_) => "partition_range",
2335            Expression::Fetch(_) => "fetch",
2336            Expression::Group(_) => "group",
2337            Expression::Cube(_) => "cube",
2338            Expression::Rollup(_) => "rollup",
2339            Expression::GroupingSets(_) => "grouping_sets",
2340            Expression::LimitOptions(_) => "limit_options",
2341            Expression::Lateral(_) => "lateral",
2342            Expression::TableFromRows(_) => "table_from_rows",
2343            Expression::RowsFrom(_) => "rows_from",
2344            Expression::MatchRecognizeMeasure(_) => "match_recognize_measure",
2345            Expression::WithFill(_) => "with_fill",
2346            Expression::Property(_) => "property",
2347            Expression::GrantPrivilege(_) => "grant_privilege",
2348            Expression::GrantPrincipal(_) => "grant_principal",
2349            Expression::AllowedValuesProperty(_) => "allowed_values_property",
2350            Expression::AlgorithmProperty(_) => "algorithm_property",
2351            Expression::AutoIncrementProperty(_) => "auto_increment_property",
2352            Expression::AutoRefreshProperty(_) => "auto_refresh_property",
2353            Expression::BackupProperty(_) => "backup_property",
2354            Expression::BuildProperty(_) => "build_property",
2355            Expression::BlockCompressionProperty(_) => "block_compression_property",
2356            Expression::CharacterSetProperty(_) => "character_set_property",
2357            Expression::ChecksumProperty(_) => "checksum_property",
2358            Expression::CollateProperty(_) => "collate_property",
2359            Expression::DataBlocksizeProperty(_) => "data_blocksize_property",
2360            Expression::DataDeletionProperty(_) => "data_deletion_property",
2361            Expression::DefinerProperty(_) => "definer_property",
2362            Expression::DistKeyProperty(_) => "dist_key_property",
2363            Expression::DistributedByProperty(_) => "distributed_by_property",
2364            Expression::DistStyleProperty(_) => "dist_style_property",
2365            Expression::DuplicateKeyProperty(_) => "duplicate_key_property",
2366            Expression::EngineProperty(_) => "engine_property",
2367            Expression::ToTableProperty(_) => "to_table_property",
2368            Expression::ExecuteAsProperty(_) => "execute_as_property",
2369            Expression::ExternalProperty(_) => "external_property",
2370            Expression::FallbackProperty(_) => "fallback_property",
2371            Expression::FileFormatProperty(_) => "file_format_property",
2372            Expression::CredentialsProperty(_) => "credentials_property",
2373            Expression::FreespaceProperty(_) => "freespace_property",
2374            Expression::InheritsProperty(_) => "inherits_property",
2375            Expression::InputModelProperty(_) => "input_model_property",
2376            Expression::OutputModelProperty(_) => "output_model_property",
2377            Expression::IsolatedLoadingProperty(_) => "isolated_loading_property",
2378            Expression::JournalProperty(_) => "journal_property",
2379            Expression::LanguageProperty(_) => "language_property",
2380            Expression::EnviromentProperty(_) => "enviroment_property",
2381            Expression::ClusteredByProperty(_) => "clustered_by_property",
2382            Expression::DictProperty(_) => "dict_property",
2383            Expression::DictRange(_) => "dict_range",
2384            Expression::OnCluster(_) => "on_cluster",
2385            Expression::LikeProperty(_) => "like_property",
2386            Expression::LocationProperty(_) => "location_property",
2387            Expression::LockProperty(_) => "lock_property",
2388            Expression::LockingProperty(_) => "locking_property",
2389            Expression::LogProperty(_) => "log_property",
2390            Expression::MaterializedProperty(_) => "materialized_property",
2391            Expression::MergeBlockRatioProperty(_) => "merge_block_ratio_property",
2392            Expression::OnProperty(_) => "on_property",
2393            Expression::OnCommitProperty(_) => "on_commit_property",
2394            Expression::PartitionedByProperty(_) => "partitioned_by_property",
2395            Expression::PartitionByProperty(_) => "partition_by_property",
2396            Expression::PartitionedByBucket(_) => "partitioned_by_bucket",
2397            Expression::ClusterByColumnsProperty(_) => "cluster_by_columns_property",
2398            Expression::PartitionByTruncate(_) => "partition_by_truncate",
2399            Expression::PartitionByRangeProperty(_) => "partition_by_range_property",
2400            Expression::PartitionByRangePropertyDynamic(_) => "partition_by_range_property_dynamic",
2401            Expression::PartitionByListProperty(_) => "partition_by_list_property",
2402            Expression::PartitionList(_) => "partition_list",
2403            Expression::Partition(_) => "partition",
2404            Expression::RefreshTriggerProperty(_) => "refresh_trigger_property",
2405            Expression::UniqueKeyProperty(_) => "unique_key_property",
2406            Expression::RollupProperty(_) => "rollup_property",
2407            Expression::PartitionBoundSpec(_) => "partition_bound_spec",
2408            Expression::PartitionedOfProperty(_) => "partitioned_of_property",
2409            Expression::RemoteWithConnectionModelProperty(_) => {
2410                "remote_with_connection_model_property"
2411            }
2412            Expression::ReturnsProperty(_) => "returns_property",
2413            Expression::RowFormatProperty(_) => "row_format_property",
2414            Expression::RowFormatDelimitedProperty(_) => "row_format_delimited_property",
2415            Expression::RowFormatSerdeProperty(_) => "row_format_serde_property",
2416            Expression::QueryTransform(_) => "query_transform",
2417            Expression::SampleProperty(_) => "sample_property",
2418            Expression::SecurityProperty(_) => "security_property",
2419            Expression::SchemaCommentProperty(_) => "schema_comment_property",
2420            Expression::SemanticView(_) => "semantic_view",
2421            Expression::SerdeProperties(_) => "serde_properties",
2422            Expression::SetProperty(_) => "set_property",
2423            Expression::SharingProperty(_) => "sharing_property",
2424            Expression::SetConfigProperty(_) => "set_config_property",
2425            Expression::SettingsProperty(_) => "settings_property",
2426            Expression::SortKeyProperty(_) => "sort_key_property",
2427            Expression::SqlReadWriteProperty(_) => "sql_read_write_property",
2428            Expression::SqlSecurityProperty(_) => "sql_security_property",
2429            Expression::StabilityProperty(_) => "stability_property",
2430            Expression::StorageHandlerProperty(_) => "storage_handler_property",
2431            Expression::TemporaryProperty(_) => "temporary_property",
2432            Expression::Tags(_) => "tags",
2433            Expression::TransformModelProperty(_) => "transform_model_property",
2434            Expression::TransientProperty(_) => "transient_property",
2435            Expression::UsingTemplateProperty(_) => "using_template_property",
2436            Expression::ViewAttributeProperty(_) => "view_attribute_property",
2437            Expression::VolatileProperty(_) => "volatile_property",
2438            Expression::WithDataProperty(_) => "with_data_property",
2439            Expression::WithJournalTableProperty(_) => "with_journal_table_property",
2440            Expression::WithSchemaBindingProperty(_) => "with_schema_binding_property",
2441            Expression::WithSystemVersioningProperty(_) => "with_system_versioning_property",
2442            Expression::WithProcedureOptions(_) => "with_procedure_options",
2443            Expression::EncodeProperty(_) => "encode_property",
2444            Expression::IncludeProperty(_) => "include_property",
2445            Expression::Properties(_) => "properties",
2446            Expression::OptionsProperty(_) => "options_property",
2447            Expression::InputOutputFormat(_) => "input_output_format",
2448            Expression::Reference(_) => "reference",
2449            Expression::QueryOption(_) => "query_option",
2450            Expression::WithTableHint(_) => "with_table_hint",
2451            Expression::IndexTableHint(_) => "index_table_hint",
2452            Expression::HistoricalData(_) => "historical_data",
2453            Expression::Get(_) => "get",
2454            Expression::SetOperation(_) => "set_operation",
2455            Expression::Var(_) => "var",
2456            Expression::Variadic(_) => "variadic",
2457            Expression::Version(_) => "version",
2458            Expression::Schema(_) => "schema",
2459            Expression::Lock(_) => "lock",
2460            Expression::TableSample(_) => "table_sample",
2461            Expression::Tag(_) => "tag",
2462            Expression::UnpivotColumns(_) => "unpivot_columns",
2463            Expression::WindowSpec(_) => "window_spec",
2464            Expression::SessionParameter(_) => "session_parameter",
2465            Expression::PseudoType(_) => "pseudo_type",
2466            Expression::ObjectIdentifier(_) => "object_identifier",
2467            Expression::Transaction(_) => "transaction",
2468            Expression::Commit(_) => "commit",
2469            Expression::Rollback(_) => "rollback",
2470            Expression::AlterSession(_) => "alter_session",
2471            Expression::Analyze(_) => "analyze",
2472            Expression::AnalyzeStatistics(_) => "analyze_statistics",
2473            Expression::AnalyzeHistogram(_) => "analyze_histogram",
2474            Expression::AnalyzeSample(_) => "analyze_sample",
2475            Expression::AnalyzeListChainedRows(_) => "analyze_list_chained_rows",
2476            Expression::AnalyzeDelete(_) => "analyze_delete",
2477            Expression::AnalyzeWith(_) => "analyze_with",
2478            Expression::AnalyzeValidate(_) => "analyze_validate",
2479            Expression::AddPartition(_) => "add_partition",
2480            Expression::AttachOption(_) => "attach_option",
2481            Expression::DropPartition(_) => "drop_partition",
2482            Expression::ReplacePartition(_) => "replace_partition",
2483            Expression::DPipe(_) => "d_pipe",
2484            Expression::Operator(_) => "operator",
2485            Expression::PivotAny(_) => "pivot_any",
2486            Expression::Aliases(_) => "aliases",
2487            Expression::AtIndex(_) => "at_index",
2488            Expression::FromTimeZone(_) => "from_time_zone",
2489            Expression::FormatPhrase(_) => "format_phrase",
2490            Expression::ForIn(_) => "for_in",
2491            Expression::TimeUnit(_) => "time_unit",
2492            Expression::IntervalOp(_) => "interval_op",
2493            Expression::IntervalSpan(_) => "interval_span",
2494            Expression::HavingMax(_) => "having_max",
2495            Expression::CosineDistance(_) => "cosine_distance",
2496            Expression::DotProduct(_) => "dot_product",
2497            Expression::EuclideanDistance(_) => "euclidean_distance",
2498            Expression::ManhattanDistance(_) => "manhattan_distance",
2499            Expression::JarowinklerSimilarity(_) => "jarowinkler_similarity",
2500            Expression::Booland(_) => "booland",
2501            Expression::Boolor(_) => "boolor",
2502            Expression::ParameterizedAgg(_) => "parameterized_agg",
2503            Expression::ArgMax(_) => "arg_max",
2504            Expression::ArgMin(_) => "arg_min",
2505            Expression::ApproxTopK(_) => "approx_top_k",
2506            Expression::ApproxTopKAccumulate(_) => "approx_top_k_accumulate",
2507            Expression::ApproxTopKCombine(_) => "approx_top_k_combine",
2508            Expression::ApproxTopKEstimate(_) => "approx_top_k_estimate",
2509            Expression::ApproxTopSum(_) => "approx_top_sum",
2510            Expression::ApproxQuantiles(_) => "approx_quantiles",
2511            Expression::Minhash(_) => "minhash",
2512            Expression::FarmFingerprint(_) => "farm_fingerprint",
2513            Expression::Float64(_) => "float64",
2514            Expression::Transform(_) => "transform",
2515            Expression::Translate(_) => "translate",
2516            Expression::Grouping(_) => "grouping",
2517            Expression::GroupingId(_) => "grouping_id",
2518            Expression::Anonymous(_) => "anonymous",
2519            Expression::AnonymousAggFunc(_) => "anonymous_agg_func",
2520            Expression::CombinedAggFunc(_) => "combined_agg_func",
2521            Expression::CombinedParameterizedAgg(_) => "combined_parameterized_agg",
2522            Expression::HashAgg(_) => "hash_agg",
2523            Expression::Hll(_) => "hll",
2524            Expression::Apply(_) => "apply",
2525            Expression::ToBoolean(_) => "to_boolean",
2526            Expression::List(_) => "list",
2527            Expression::ToMap(_) => "to_map",
2528            Expression::Pad(_) => "pad",
2529            Expression::ToChar(_) => "to_char",
2530            Expression::ToNumber(_) => "to_number",
2531            Expression::ToDouble(_) => "to_double",
2532            Expression::Int64(_) => "int64",
2533            Expression::StringFunc(_) => "string_func",
2534            Expression::ToDecfloat(_) => "to_decfloat",
2535            Expression::TryToDecfloat(_) => "try_to_decfloat",
2536            Expression::ToFile(_) => "to_file",
2537            Expression::Columns(_) => "columns",
2538            Expression::ConvertToCharset(_) => "convert_to_charset",
2539            Expression::ConvertTimezone(_) => "convert_timezone",
2540            Expression::GenerateSeries(_) => "generate_series",
2541            Expression::AIAgg(_) => "a_i_agg",
2542            Expression::AIClassify(_) => "a_i_classify",
2543            Expression::ArrayAll(_) => "array_all",
2544            Expression::ArrayAny(_) => "array_any",
2545            Expression::ArrayConstructCompact(_) => "array_construct_compact",
2546            Expression::StPoint(_) => "st_point",
2547            Expression::StDistance(_) => "st_distance",
2548            Expression::StringToArray(_) => "string_to_array",
2549            Expression::ArraySum(_) => "array_sum",
2550            Expression::ObjectAgg(_) => "object_agg",
2551            Expression::CastToStrType(_) => "cast_to_str_type",
2552            Expression::CheckJson(_) => "check_json",
2553            Expression::CheckXml(_) => "check_xml",
2554            Expression::TranslateCharacters(_) => "translate_characters",
2555            Expression::CurrentSchemas(_) => "current_schemas",
2556            Expression::CurrentDatetime(_) => "current_datetime",
2557            Expression::Localtime(_) => "localtime",
2558            Expression::Localtimestamp(_) => "localtimestamp",
2559            Expression::Systimestamp(_) => "systimestamp",
2560            Expression::CurrentSchema(_) => "current_schema",
2561            Expression::CurrentUser(_) => "current_user",
2562            Expression::UtcTime(_) => "utc_time",
2563            Expression::UtcTimestamp(_) => "utc_timestamp",
2564            Expression::Timestamp(_) => "timestamp",
2565            Expression::DateBin(_) => "date_bin",
2566            Expression::Datetime(_) => "datetime",
2567            Expression::DatetimeAdd(_) => "datetime_add",
2568            Expression::DatetimeSub(_) => "datetime_sub",
2569            Expression::DatetimeDiff(_) => "datetime_diff",
2570            Expression::DatetimeTrunc(_) => "datetime_trunc",
2571            Expression::Dayname(_) => "dayname",
2572            Expression::MakeInterval(_) => "make_interval",
2573            Expression::PreviousDay(_) => "previous_day",
2574            Expression::Elt(_) => "elt",
2575            Expression::TimestampAdd(_) => "timestamp_add",
2576            Expression::TimestampSub(_) => "timestamp_sub",
2577            Expression::TimestampDiff(_) => "timestamp_diff",
2578            Expression::TimeSlice(_) => "time_slice",
2579            Expression::TimeAdd(_) => "time_add",
2580            Expression::TimeSub(_) => "time_sub",
2581            Expression::TimeDiff(_) => "time_diff",
2582            Expression::TimeTrunc(_) => "time_trunc",
2583            Expression::DateFromParts(_) => "date_from_parts",
2584            Expression::TimeFromParts(_) => "time_from_parts",
2585            Expression::DecodeCase(_) => "decode_case",
2586            Expression::Decrypt(_) => "decrypt",
2587            Expression::DecryptRaw(_) => "decrypt_raw",
2588            Expression::Encode(_) => "encode",
2589            Expression::Encrypt(_) => "encrypt",
2590            Expression::EncryptRaw(_) => "encrypt_raw",
2591            Expression::EqualNull(_) => "equal_null",
2592            Expression::ToBinary(_) => "to_binary",
2593            Expression::Base64DecodeBinary(_) => "base64_decode_binary",
2594            Expression::Base64DecodeString(_) => "base64_decode_string",
2595            Expression::Base64Encode(_) => "base64_encode",
2596            Expression::TryBase64DecodeBinary(_) => "try_base64_decode_binary",
2597            Expression::TryBase64DecodeString(_) => "try_base64_decode_string",
2598            Expression::GapFill(_) => "gap_fill",
2599            Expression::GenerateDateArray(_) => "generate_date_array",
2600            Expression::GenerateTimestampArray(_) => "generate_timestamp_array",
2601            Expression::GetExtract(_) => "get_extract",
2602            Expression::Getbit(_) => "getbit",
2603            Expression::OverflowTruncateBehavior(_) => "overflow_truncate_behavior",
2604            Expression::HexEncode(_) => "hex_encode",
2605            Expression::Compress(_) => "compress",
2606            Expression::DecompressBinary(_) => "decompress_binary",
2607            Expression::DecompressString(_) => "decompress_string",
2608            Expression::Xor(_) => "xor",
2609            Expression::Nullif(_) => "nullif",
2610            Expression::JSON(_) => "j_s_o_n",
2611            Expression::JSONPath(_) => "j_s_o_n_path",
2612            Expression::JSONPathFilter(_) => "j_s_o_n_path_filter",
2613            Expression::JSONPathKey(_) => "j_s_o_n_path_key",
2614            Expression::JSONPathRecursive(_) => "j_s_o_n_path_recursive",
2615            Expression::JSONPathScript(_) => "j_s_o_n_path_script",
2616            Expression::JSONPathSlice(_) => "j_s_o_n_path_slice",
2617            Expression::JSONPathSelector(_) => "j_s_o_n_path_selector",
2618            Expression::JSONPathSubscript(_) => "j_s_o_n_path_subscript",
2619            Expression::JSONPathUnion(_) => "j_s_o_n_path_union",
2620            Expression::Format(_) => "format",
2621            Expression::JSONKeys(_) => "j_s_o_n_keys",
2622            Expression::JSONKeyValue(_) => "j_s_o_n_key_value",
2623            Expression::JSONKeysAtDepth(_) => "j_s_o_n_keys_at_depth",
2624            Expression::JSONObject(_) => "j_s_o_n_object",
2625            Expression::JSONObjectAgg(_) => "j_s_o_n_object_agg",
2626            Expression::JSONBObjectAgg(_) => "j_s_o_n_b_object_agg",
2627            Expression::JSONArray(_) => "j_s_o_n_array",
2628            Expression::JSONArrayAgg(_) => "j_s_o_n_array_agg",
2629            Expression::JSONExists(_) => "j_s_o_n_exists",
2630            Expression::JSONColumnDef(_) => "j_s_o_n_column_def",
2631            Expression::JSONSchema(_) => "j_s_o_n_schema",
2632            Expression::JSONSet(_) => "j_s_o_n_set",
2633            Expression::JSONStripNulls(_) => "j_s_o_n_strip_nulls",
2634            Expression::JSONValue(_) => "j_s_o_n_value",
2635            Expression::JSONValueArray(_) => "j_s_o_n_value_array",
2636            Expression::JSONRemove(_) => "j_s_o_n_remove",
2637            Expression::JSONTable(_) => "j_s_o_n_table",
2638            Expression::JSONType(_) => "j_s_o_n_type",
2639            Expression::ObjectInsert(_) => "object_insert",
2640            Expression::OpenJSONColumnDef(_) => "open_j_s_o_n_column_def",
2641            Expression::OpenJSON(_) => "open_j_s_o_n",
2642            Expression::JSONBExists(_) => "j_s_o_n_b_exists",
2643            Expression::JSONBContains(_) => "j_s_o_n_b_contains",
2644            Expression::JSONBExtract(_) => "j_s_o_n_b_extract",
2645            Expression::JSONCast(_) => "j_s_o_n_cast",
2646            Expression::JSONExtract(_) => "j_s_o_n_extract",
2647            Expression::JSONExtractQuote(_) => "j_s_o_n_extract_quote",
2648            Expression::JSONExtractArray(_) => "j_s_o_n_extract_array",
2649            Expression::JSONExtractScalar(_) => "j_s_o_n_extract_scalar",
2650            Expression::JSONBExtractScalar(_) => "j_s_o_n_b_extract_scalar",
2651            Expression::JSONFormat(_) => "j_s_o_n_format",
2652            Expression::JSONBool(_) => "j_s_o_n_bool",
2653            Expression::JSONPathRoot(_) => "j_s_o_n_path_root",
2654            Expression::JSONArrayAppend(_) => "j_s_o_n_array_append",
2655            Expression::JSONArrayContains(_) => "j_s_o_n_array_contains",
2656            Expression::JSONArrayInsert(_) => "j_s_o_n_array_insert",
2657            Expression::ParseJSON(_) => "parse_j_s_o_n",
2658            Expression::ParseUrl(_) => "parse_url",
2659            Expression::ParseIp(_) => "parse_ip",
2660            Expression::ParseTime(_) => "parse_time",
2661            Expression::ParseDatetime(_) => "parse_datetime",
2662            Expression::Map(_) => "map",
2663            Expression::MapCat(_) => "map_cat",
2664            Expression::MapDelete(_) => "map_delete",
2665            Expression::MapInsert(_) => "map_insert",
2666            Expression::MapPick(_) => "map_pick",
2667            Expression::ScopeResolution(_) => "scope_resolution",
2668            Expression::Slice(_) => "slice",
2669            Expression::VarMap(_) => "var_map",
2670            Expression::MatchAgainst(_) => "match_against",
2671            Expression::MD5Digest(_) => "m_d5_digest",
2672            Expression::MD5NumberLower64(_) => "m_d5_number_lower64",
2673            Expression::MD5NumberUpper64(_) => "m_d5_number_upper64",
2674            Expression::Monthname(_) => "monthname",
2675            Expression::Ntile(_) => "ntile",
2676            Expression::Normalize(_) => "normalize",
2677            Expression::Normal(_) => "normal",
2678            Expression::Predict(_) => "predict",
2679            Expression::MLTranslate(_) => "m_l_translate",
2680            Expression::FeaturesAtTime(_) => "features_at_time",
2681            Expression::GenerateEmbedding(_) => "generate_embedding",
2682            Expression::MLForecast(_) => "m_l_forecast",
2683            Expression::ModelAttribute(_) => "model_attribute",
2684            Expression::VectorSearch(_) => "vector_search",
2685            Expression::Quantile(_) => "quantile",
2686            Expression::ApproxQuantile(_) => "approx_quantile",
2687            Expression::ApproxPercentileEstimate(_) => "approx_percentile_estimate",
2688            Expression::Randn(_) => "randn",
2689            Expression::Randstr(_) => "randstr",
2690            Expression::RangeN(_) => "range_n",
2691            Expression::RangeBucket(_) => "range_bucket",
2692            Expression::ReadCSV(_) => "read_c_s_v",
2693            Expression::ReadParquet(_) => "read_parquet",
2694            Expression::Reduce(_) => "reduce",
2695            Expression::RegexpExtractAll(_) => "regexp_extract_all",
2696            Expression::RegexpILike(_) => "regexp_i_like",
2697            Expression::RegexpFullMatch(_) => "regexp_full_match",
2698            Expression::RegexpInstr(_) => "regexp_instr",
2699            Expression::RegexpSplit(_) => "regexp_split",
2700            Expression::RegexpCount(_) => "regexp_count",
2701            Expression::RegrValx(_) => "regr_valx",
2702            Expression::RegrValy(_) => "regr_valy",
2703            Expression::RegrAvgy(_) => "regr_avgy",
2704            Expression::RegrAvgx(_) => "regr_avgx",
2705            Expression::RegrCount(_) => "regr_count",
2706            Expression::RegrIntercept(_) => "regr_intercept",
2707            Expression::RegrR2(_) => "regr_r2",
2708            Expression::RegrSxx(_) => "regr_sxx",
2709            Expression::RegrSxy(_) => "regr_sxy",
2710            Expression::RegrSyy(_) => "regr_syy",
2711            Expression::RegrSlope(_) => "regr_slope",
2712            Expression::SafeAdd(_) => "safe_add",
2713            Expression::SafeDivide(_) => "safe_divide",
2714            Expression::SafeMultiply(_) => "safe_multiply",
2715            Expression::SafeSubtract(_) => "safe_subtract",
2716            Expression::SHA2(_) => "s_h_a2",
2717            Expression::SHA2Digest(_) => "s_h_a2_digest",
2718            Expression::SortArray(_) => "sort_array",
2719            Expression::SplitPart(_) => "split_part",
2720            Expression::SubstringIndex(_) => "substring_index",
2721            Expression::StandardHash(_) => "standard_hash",
2722            Expression::StrPosition(_) => "str_position",
2723            Expression::Search(_) => "search",
2724            Expression::SearchIp(_) => "search_ip",
2725            Expression::StrToDate(_) => "str_to_date",
2726            Expression::DateStrToDate(_) => "date_str_to_date",
2727            Expression::DateToDateStr(_) => "date_to_date_str",
2728            Expression::StrToTime(_) => "str_to_time",
2729            Expression::StrToUnix(_) => "str_to_unix",
2730            Expression::StrToMap(_) => "str_to_map",
2731            Expression::NumberToStr(_) => "number_to_str",
2732            Expression::FromBase(_) => "from_base",
2733            Expression::Stuff(_) => "stuff",
2734            Expression::TimeToStr(_) => "time_to_str",
2735            Expression::TimeStrToTime(_) => "time_str_to_time",
2736            Expression::TsOrDsAdd(_) => "ts_or_ds_add",
2737            Expression::TsOrDsDiff(_) => "ts_or_ds_diff",
2738            Expression::TsOrDsToDate(_) => "ts_or_ds_to_date",
2739            Expression::TsOrDsToTime(_) => "ts_or_ds_to_time",
2740            Expression::Unhex(_) => "unhex",
2741            Expression::Uniform(_) => "uniform",
2742            Expression::UnixToStr(_) => "unix_to_str",
2743            Expression::UnixToTime(_) => "unix_to_time",
2744            Expression::Uuid(_) => "uuid",
2745            Expression::TimestampFromParts(_) => "timestamp_from_parts",
2746            Expression::TimestampTzFromParts(_) => "timestamp_tz_from_parts",
2747            Expression::Corr(_) => "corr",
2748            Expression::WidthBucket(_) => "width_bucket",
2749            Expression::CovarSamp(_) => "covar_samp",
2750            Expression::CovarPop(_) => "covar_pop",
2751            Expression::Week(_) => "week",
2752            Expression::XMLElement(_) => "x_m_l_element",
2753            Expression::XMLGet(_) => "x_m_l_get",
2754            Expression::XMLTable(_) => "x_m_l_table",
2755            Expression::XMLKeyValueOption(_) => "x_m_l_key_value_option",
2756            Expression::Zipf(_) => "zipf",
2757            Expression::Merge(_) => "merge",
2758            Expression::When(_) => "when",
2759            Expression::Whens(_) => "whens",
2760            Expression::NextValueFor(_) => "next_value_for",
2761            Expression::ReturnStmt(_) => "return_stmt",
2762        }
2763    }
2764
2765    /// Returns the primary child expression (".this" in sqlglot).
2766    pub fn get_this(&self) -> Option<&Expression> {
2767        match self {
2768            // Unary ops
2769            Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this),
2770            // UnaryFunc variants
2771            Expression::Upper(f)
2772            | Expression::Lower(f)
2773            | Expression::Length(f)
2774            | Expression::LTrim(f)
2775            | Expression::RTrim(f)
2776            | Expression::Reverse(f)
2777            | Expression::Abs(f)
2778            | Expression::Sqrt(f)
2779            | Expression::Cbrt(f)
2780            | Expression::Ln(f)
2781            | Expression::Exp(f)
2782            | Expression::Sign(f)
2783            | Expression::Date(f)
2784            | Expression::Time(f)
2785            | Expression::Initcap(f)
2786            | Expression::Ascii(f)
2787            | Expression::Chr(f)
2788            | Expression::Soundex(f)
2789            | Expression::ByteLength(f)
2790            | Expression::Hex(f)
2791            | Expression::LowerHex(f)
2792            | Expression::Unicode(f)
2793            | Expression::Typeof(f)
2794            | Expression::Explode(f)
2795            | Expression::ExplodeOuter(f)
2796            | Expression::MapFromEntries(f)
2797            | Expression::MapKeys(f)
2798            | Expression::MapValues(f)
2799            | Expression::ArrayLength(f)
2800            | Expression::ArraySize(f)
2801            | Expression::Cardinality(f)
2802            | Expression::ArrayReverse(f)
2803            | Expression::ArrayDistinct(f)
2804            | Expression::ArrayFlatten(f)
2805            | Expression::ArrayCompact(f)
2806            | Expression::ToArray(f)
2807            | Expression::JsonArrayLength(f)
2808            | Expression::JsonKeys(f)
2809            | Expression::JsonType(f)
2810            | Expression::ParseJson(f)
2811            | Expression::ToJson(f)
2812            | Expression::Radians(f)
2813            | Expression::Degrees(f)
2814            | Expression::Sin(f)
2815            | Expression::Cos(f)
2816            | Expression::Tan(f)
2817            | Expression::Asin(f)
2818            | Expression::Acos(f)
2819            | Expression::Atan(f)
2820            | Expression::IsNan(f)
2821            | Expression::IsInf(f)
2822            | Expression::Year(f)
2823            | Expression::Month(f)
2824            | Expression::Day(f)
2825            | Expression::Hour(f)
2826            | Expression::Minute(f)
2827            | Expression::Second(f)
2828            | Expression::DayOfWeek(f)
2829            | Expression::DayOfWeekIso(f)
2830            | Expression::DayOfMonth(f)
2831            | Expression::DayOfYear(f)
2832            | Expression::WeekOfYear(f)
2833            | Expression::Quarter(f)
2834            | Expression::Epoch(f)
2835            | Expression::EpochMs(f)
2836            | Expression::BitwiseCount(f)
2837            | Expression::DateFromUnixDate(f)
2838            | Expression::UnixDate(f)
2839            | Expression::UnixSeconds(f)
2840            | Expression::UnixMillis(f)
2841            | Expression::UnixMicros(f)
2842            | Expression::TimeStrToDate(f)
2843            | Expression::DateToDi(f)
2844            | Expression::DiToDate(f)
2845            | Expression::TsOrDiToDi(f)
2846            | Expression::TsOrDsToDatetime(f)
2847            | Expression::TsOrDsToTimestamp(f)
2848            | Expression::YearOfWeek(f)
2849            | Expression::YearOfWeekIso(f)
2850            | Expression::SHA(f)
2851            | Expression::SHA1Digest(f)
2852            | Expression::TimeToUnix(f)
2853            | Expression::TimeStrToUnix(f)
2854            | Expression::Int64(f)
2855            | Expression::JSONBool(f)
2856            | Expression::MD5NumberLower64(f)
2857            | Expression::MD5NumberUpper64(f)
2858            | Expression::DateStrToDate(f)
2859            | Expression::DateToDateStr(f) => Some(&f.this),
2860            // BinaryFunc - this is the primary child
2861            Expression::Power(f)
2862            | Expression::NullIf(f)
2863            | Expression::IfNull(f)
2864            | Expression::Nvl(f)
2865            | Expression::Contains(f)
2866            | Expression::StartsWith(f)
2867            | Expression::EndsWith(f)
2868            | Expression::Levenshtein(f)
2869            | Expression::ModFunc(f)
2870            | Expression::IntDiv(f)
2871            | Expression::Atan2(f)
2872            | Expression::AddMonths(f)
2873            | Expression::MonthsBetween(f)
2874            | Expression::NextDay(f)
2875            | Expression::UnixToTimeStr(f)
2876            | Expression::ArrayContains(f)
2877            | Expression::ArrayPosition(f)
2878            | Expression::ArrayAppend(f)
2879            | Expression::ArrayPrepend(f)
2880            | Expression::ArrayUnion(f)
2881            | Expression::ArrayExcept(f)
2882            | Expression::ArrayRemove(f)
2883            | Expression::StarMap(f)
2884            | Expression::MapFromArrays(f)
2885            | Expression::MapContainsKey(f)
2886            | Expression::ElementAt(f)
2887            | Expression::JsonMergePatch(f)
2888            | Expression::JSONBContains(f)
2889            | Expression::JSONBExtract(f) => Some(&f.this),
2890            // AggFunc - this is the primary child
2891            Expression::Sum(af)
2892            | Expression::Avg(af)
2893            | Expression::Min(af)
2894            | Expression::Max(af)
2895            | Expression::ArrayAgg(af)
2896            | Expression::CountIf(af)
2897            | Expression::Stddev(af)
2898            | Expression::StddevPop(af)
2899            | Expression::StddevSamp(af)
2900            | Expression::Variance(af)
2901            | Expression::VarPop(af)
2902            | Expression::VarSamp(af)
2903            | Expression::Median(af)
2904            | Expression::Mode(af)
2905            | Expression::First(af)
2906            | Expression::Last(af)
2907            | Expression::AnyValue(af)
2908            | Expression::ApproxDistinct(af)
2909            | Expression::ApproxCountDistinct(af)
2910            | Expression::LogicalAnd(af)
2911            | Expression::LogicalOr(af)
2912            | Expression::Skewness(af)
2913            | Expression::ArrayConcatAgg(af)
2914            | Expression::ArrayUniqueAgg(af)
2915            | Expression::BoolXorAgg(af)
2916            | Expression::BitwiseAndAgg(af)
2917            | Expression::BitwiseOrAgg(af)
2918            | Expression::BitwiseXorAgg(af) => Some(&af.this),
2919            // Binary operations - left is "this" in sqlglot
2920            Expression::And(op)
2921            | Expression::Or(op)
2922            | Expression::Add(op)
2923            | Expression::Sub(op)
2924            | Expression::Mul(op)
2925            | Expression::Div(op)
2926            | Expression::Mod(op)
2927            | Expression::Eq(op)
2928            | Expression::Neq(op)
2929            | Expression::Lt(op)
2930            | Expression::Lte(op)
2931            | Expression::Gt(op)
2932            | Expression::Gte(op)
2933            | Expression::BitwiseAnd(op)
2934            | Expression::BitwiseOr(op)
2935            | Expression::BitwiseXor(op)
2936            | Expression::Concat(op)
2937            | Expression::Adjacent(op)
2938            | Expression::TsMatch(op)
2939            | Expression::PropertyEQ(op)
2940            | Expression::ArrayContainsAll(op)
2941            | Expression::ArrayContainedBy(op)
2942            | Expression::ArrayOverlaps(op)
2943            | Expression::JSONBContainsAllTopKeys(op)
2944            | Expression::JSONBContainsAnyTopKeys(op)
2945            | Expression::JSONBDeleteAtPath(op)
2946            | Expression::ExtendsLeft(op)
2947            | Expression::ExtendsRight(op)
2948            | Expression::Is(op)
2949            | Expression::MemberOf(op)
2950            | Expression::Match(op)
2951            | Expression::NullSafeEq(op)
2952            | Expression::NullSafeNeq(op)
2953            | Expression::Glob(op)
2954            | Expression::BitwiseLeftShift(op)
2955            | Expression::BitwiseRightShift(op) => Some(&op.left),
2956            // Like operations - left is "this"
2957            Expression::Like(op) | Expression::ILike(op) => Some(&op.left),
2958            // Structural types with .this
2959            Expression::Alias(a) => Some(&a.this),
2960            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => Some(&c.this),
2961            Expression::Paren(p) => Some(&p.this),
2962            Expression::Annotated(a) => Some(&a.this),
2963            Expression::Subquery(s) => Some(&s.this),
2964            Expression::Where(w) => Some(&w.this),
2965            Expression::Having(h) => Some(&h.this),
2966            Expression::Qualify(q) => Some(&q.this),
2967            Expression::IsNull(i) => Some(&i.this),
2968            Expression::Exists(e) => Some(&e.this),
2969            Expression::Ordered(o) => Some(&o.this),
2970            Expression::WindowFunction(wf) => Some(&wf.this),
2971            Expression::Cte(cte) => Some(&cte.this),
2972            Expression::Between(b) => Some(&b.this),
2973            Expression::In(i) => Some(&i.this),
2974            Expression::ReturnStmt(e) => Some(e),
2975            _ => None,
2976        }
2977    }
2978
2979    /// Returns the secondary child expression (".expression" in sqlglot).
2980    pub fn get_expression(&self) -> Option<&Expression> {
2981        match self {
2982            // Binary operations - right is "expression"
2983            Expression::And(op)
2984            | Expression::Or(op)
2985            | Expression::Add(op)
2986            | Expression::Sub(op)
2987            | Expression::Mul(op)
2988            | Expression::Div(op)
2989            | Expression::Mod(op)
2990            | Expression::Eq(op)
2991            | Expression::Neq(op)
2992            | Expression::Lt(op)
2993            | Expression::Lte(op)
2994            | Expression::Gt(op)
2995            | Expression::Gte(op)
2996            | Expression::BitwiseAnd(op)
2997            | Expression::BitwiseOr(op)
2998            | Expression::BitwiseXor(op)
2999            | Expression::Concat(op)
3000            | Expression::Adjacent(op)
3001            | Expression::TsMatch(op)
3002            | Expression::PropertyEQ(op)
3003            | Expression::ArrayContainsAll(op)
3004            | Expression::ArrayContainedBy(op)
3005            | Expression::ArrayOverlaps(op)
3006            | Expression::JSONBContainsAllTopKeys(op)
3007            | Expression::JSONBContainsAnyTopKeys(op)
3008            | Expression::JSONBDeleteAtPath(op)
3009            | Expression::ExtendsLeft(op)
3010            | Expression::ExtendsRight(op)
3011            | Expression::Is(op)
3012            | Expression::MemberOf(op)
3013            | Expression::Match(op)
3014            | Expression::NullSafeEq(op)
3015            | Expression::NullSafeNeq(op)
3016            | Expression::Glob(op)
3017            | Expression::BitwiseLeftShift(op)
3018            | Expression::BitwiseRightShift(op) => Some(&op.right),
3019            // Like operations - right is "expression"
3020            Expression::Like(op) | Expression::ILike(op) => Some(&op.right),
3021            // BinaryFunc - expression is the secondary
3022            Expression::Power(f)
3023            | Expression::NullIf(f)
3024            | Expression::IfNull(f)
3025            | Expression::Nvl(f)
3026            | Expression::Contains(f)
3027            | Expression::StartsWith(f)
3028            | Expression::EndsWith(f)
3029            | Expression::Levenshtein(f)
3030            | Expression::ModFunc(f)
3031            | Expression::IntDiv(f)
3032            | Expression::Atan2(f)
3033            | Expression::AddMonths(f)
3034            | Expression::MonthsBetween(f)
3035            | Expression::NextDay(f)
3036            | Expression::UnixToTimeStr(f)
3037            | Expression::ArrayContains(f)
3038            | Expression::ArrayPosition(f)
3039            | Expression::ArrayAppend(f)
3040            | Expression::ArrayPrepend(f)
3041            | Expression::ArrayUnion(f)
3042            | Expression::ArrayExcept(f)
3043            | Expression::ArrayRemove(f)
3044            | Expression::StarMap(f)
3045            | Expression::MapFromArrays(f)
3046            | Expression::MapContainsKey(f)
3047            | Expression::ElementAt(f)
3048            | Expression::JsonMergePatch(f)
3049            | Expression::JSONBContains(f)
3050            | Expression::JSONBExtract(f) => Some(&f.expression),
3051            _ => None,
3052        }
3053    }
3054
3055    /// Returns the list of child expressions (".expressions" in sqlglot).
3056    pub fn get_expressions(&self) -> &[Expression] {
3057        match self {
3058            Expression::Select(s) => &s.expressions,
3059            Expression::Function(f) => &f.args,
3060            Expression::AggregateFunction(f) => &f.args,
3061            Expression::From(f) => &f.expressions,
3062            Expression::GroupBy(g) => &g.expressions,
3063            Expression::In(i) => &i.expressions,
3064            Expression::Array(a) => &a.expressions,
3065            Expression::Tuple(t) => &t.expressions,
3066            Expression::Coalesce(f)
3067            | Expression::Greatest(f)
3068            | Expression::Least(f)
3069            | Expression::ArrayConcat(f)
3070            | Expression::ArrayIntersect(f)
3071            | Expression::ArrayZip(f)
3072            | Expression::MapConcat(f)
3073            | Expression::JsonArray(f) => &f.expressions,
3074            _ => &[],
3075        }
3076    }
3077
3078    /// Returns the name of this expression as a string slice.
3079    pub fn get_name(&self) -> &str {
3080        match self {
3081            Expression::Identifier(id) => &id.name,
3082            Expression::Column(col) => &col.name.name,
3083            Expression::Table(t) => &t.name.name,
3084            Expression::Literal(lit) => lit.value_str(),
3085            Expression::Star(_) => "*",
3086            Expression::Function(f) => &f.name,
3087            Expression::AggregateFunction(f) => &f.name,
3088            Expression::Alias(a) => a.this.get_name(),
3089            Expression::Boolean(b) => {
3090                if b.value {
3091                    "TRUE"
3092                } else {
3093                    "FALSE"
3094                }
3095            }
3096            Expression::Null(_) => "NULL",
3097            _ => "",
3098        }
3099    }
3100
3101    /// Returns the alias name if this expression has one.
3102    pub fn get_alias(&self) -> &str {
3103        match self {
3104            Expression::Alias(a) => &a.alias.name,
3105            Expression::Table(t) => t.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3106            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3107            _ => "",
3108        }
3109    }
3110
3111    /// Returns the output name of this expression (what it shows up as in a SELECT).
3112    pub fn get_output_name(&self) -> &str {
3113        match self {
3114            Expression::Alias(a) => &a.alias.name,
3115            Expression::Column(c) => &c.name.name,
3116            Expression::Identifier(id) => &id.name,
3117            Expression::Literal(lit) => lit.value_str(),
3118            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3119            Expression::Star(_) => "*",
3120            _ => "",
3121        }
3122    }
3123
3124    /// Returns comments attached to this expression.
3125    pub fn get_comments(&self) -> Vec<&str> {
3126        match self {
3127            Expression::Identifier(id) => id.trailing_comments.iter().map(|s| s.as_str()).collect(),
3128            Expression::Column(c) => c.trailing_comments.iter().map(|s| s.as_str()).collect(),
3129            Expression::Star(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3130            Expression::Paren(p) => p.trailing_comments.iter().map(|s| s.as_str()).collect(),
3131            Expression::Annotated(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3132            Expression::Alias(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3133            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
3134                c.trailing_comments.iter().map(|s| s.as_str()).collect()
3135            }
3136            Expression::And(op)
3137            | Expression::Or(op)
3138            | Expression::Add(op)
3139            | Expression::Sub(op)
3140            | Expression::Mul(op)
3141            | Expression::Div(op)
3142            | Expression::Mod(op)
3143            | Expression::Eq(op)
3144            | Expression::Neq(op)
3145            | Expression::Lt(op)
3146            | Expression::Lte(op)
3147            | Expression::Gt(op)
3148            | Expression::Gte(op)
3149            | Expression::Concat(op)
3150            | Expression::BitwiseAnd(op)
3151            | Expression::BitwiseOr(op)
3152            | Expression::BitwiseXor(op) => {
3153                op.trailing_comments.iter().map(|s| s.as_str()).collect()
3154            }
3155            Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(),
3156            Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3157            _ => Vec::new(),
3158        }
3159    }
3160}
3161
3162impl fmt::Display for Expression {
3163    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3164        // Basic display - full SQL generation is in generator module
3165        match self {
3166            Expression::Literal(lit) => write!(f, "{}", lit),
3167            Expression::Identifier(id) => write!(f, "{}", id),
3168            Expression::Column(col) => write!(f, "{}", col),
3169            Expression::Star(_) => write!(f, "*"),
3170            Expression::Null(_) => write!(f, "NULL"),
3171            Expression::Boolean(b) => write!(f, "{}", if b.value { "TRUE" } else { "FALSE" }),
3172            Expression::Select(_) => write!(f, "SELECT ..."),
3173            _ => write!(f, "{:?}", self),
3174        }
3175    }
3176}
3177
3178/// Represent a SQL literal value.
3179///
3180/// Numeric values are stored as their original text representation (not parsed
3181/// to `i64`/`f64`) so that precision, trailing zeros, and hex notation are
3182/// preserved across round-trips.
3183///
3184/// Dialect-specific literal forms (triple-quoted strings, dollar-quoted
3185/// strings, raw strings, etc.) each have a dedicated variant so that the
3186/// generator can emit them with the correct syntax.
3187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3188#[cfg_attr(feature = "bindings", derive(TS))]
3189#[serde(tag = "literal_type", content = "value", rename_all = "snake_case")]
3190pub enum Literal {
3191    /// Single-quoted string literal: `'hello'`
3192    String(String),
3193    /// Numeric literal, stored as the original text: `42`, `3.14`, `1e10`
3194    Number(String),
3195    /// Hex string literal: `X'FF'`
3196    HexString(String),
3197    /// Hex number: 0xA, 0xFF (BigQuery, SQLite style) - represents an integer in hex notation
3198    HexNumber(String),
3199    BitString(String),
3200    /// Byte string: b"..." (BigQuery style)
3201    ByteString(String),
3202    /// National string: N'abc'
3203    NationalString(String),
3204    /// DATE literal: DATE '2024-01-15'
3205    Date(String),
3206    /// TIME literal: TIME '10:30:00'
3207    Time(String),
3208    /// TIMESTAMP literal: TIMESTAMP '2024-01-15 10:30:00'
3209    Timestamp(String),
3210    /// DATETIME literal: DATETIME '2024-01-15 10:30:00' (BigQuery)
3211    Datetime(String),
3212    /// Triple-quoted string: """...""" or '''...'''
3213    /// Contains (content, quote_char) where quote_char is '"' or '\''
3214    TripleQuotedString(String, char),
3215    /// Escape string: E'...' (PostgreSQL)
3216    EscapeString(String),
3217    /// Dollar-quoted string: $$...$$  (PostgreSQL)
3218    DollarString(String),
3219    /// Raw string: r"..." or r'...' (BigQuery, Spark, Databricks)
3220    /// In raw strings, backslashes are literal and not escape characters.
3221    /// When converting to a regular string, backslashes must be doubled.
3222    RawString(String),
3223}
3224
3225impl Literal {
3226    /// Returns the inner value as a string slice, regardless of literal type.
3227    pub fn value_str(&self) -> &str {
3228        match self {
3229            Literal::String(s)
3230            | Literal::Number(s)
3231            | Literal::HexString(s)
3232            | Literal::HexNumber(s)
3233            | Literal::BitString(s)
3234            | Literal::ByteString(s)
3235            | Literal::NationalString(s)
3236            | Literal::Date(s)
3237            | Literal::Time(s)
3238            | Literal::Timestamp(s)
3239            | Literal::Datetime(s)
3240            | Literal::EscapeString(s)
3241            | Literal::DollarString(s)
3242            | Literal::RawString(s) => s.as_str(),
3243            Literal::TripleQuotedString(s, _) => s.as_str(),
3244        }
3245    }
3246
3247    /// Returns `true` if this is a string-type literal.
3248    pub fn is_string(&self) -> bool {
3249        matches!(
3250            self,
3251            Literal::String(_)
3252                | Literal::NationalString(_)
3253                | Literal::EscapeString(_)
3254                | Literal::DollarString(_)
3255                | Literal::RawString(_)
3256                | Literal::TripleQuotedString(_, _)
3257        )
3258    }
3259
3260    /// Returns `true` if this is a numeric literal.
3261    pub fn is_number(&self) -> bool {
3262        matches!(self, Literal::Number(_) | Literal::HexNumber(_))
3263    }
3264}
3265
3266impl fmt::Display for Literal {
3267    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3268        match self {
3269            Literal::String(s) => write!(f, "'{}'", s),
3270            Literal::Number(n) => write!(f, "{}", n),
3271            Literal::HexString(h) => write!(f, "X'{}'", h),
3272            Literal::HexNumber(h) => write!(f, "0x{}", h),
3273            Literal::BitString(b) => write!(f, "B'{}'", b),
3274            Literal::ByteString(b) => write!(f, "b'{}'", b),
3275            Literal::NationalString(s) => write!(f, "N'{}'", s),
3276            Literal::Date(d) => write!(f, "DATE '{}'", d),
3277            Literal::Time(t) => write!(f, "TIME '{}'", t),
3278            Literal::Timestamp(ts) => write!(f, "TIMESTAMP '{}'", ts),
3279            Literal::Datetime(dt) => write!(f, "DATETIME '{}'", dt),
3280            Literal::TripleQuotedString(s, q) => {
3281                write!(f, "{0}{0}{0}{1}{0}{0}{0}", q, s)
3282            }
3283            Literal::EscapeString(s) => write!(f, "E'{}'", s),
3284            Literal::DollarString(s) => write!(f, "$${}$$", s),
3285            Literal::RawString(s) => write!(f, "r'{}'", s),
3286        }
3287    }
3288}
3289
3290/// Boolean literal
3291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3292#[cfg_attr(feature = "bindings", derive(TS))]
3293pub struct BooleanLiteral {
3294    pub value: bool,
3295}
3296
3297/// NULL literal
3298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3299#[cfg_attr(feature = "bindings", derive(TS))]
3300pub struct Null;
3301
3302/// Represent a SQL identifier (table name, column name, alias, keyword-as-name, etc.).
3303///
3304/// The `quoted` flag indicates whether the identifier was originally delimited
3305/// (double-quoted, backtick-quoted, or bracket-quoted depending on the
3306/// dialect). The generator uses this flag to decide whether to emit quoting
3307/// characters.
3308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3309#[cfg_attr(feature = "bindings", derive(TS))]
3310pub struct Identifier {
3311    /// The raw text of the identifier, without any quoting characters.
3312    pub name: String,
3313    /// Whether the identifier was quoted in the source SQL.
3314    pub quoted: bool,
3315    #[serde(default)]
3316    pub trailing_comments: Vec<String>,
3317    /// Source position span (populated during parsing, None for programmatically constructed nodes)
3318    #[serde(default, skip_serializing_if = "Option::is_none")]
3319    pub span: Option<Span>,
3320}
3321
3322impl Identifier {
3323    pub fn new(name: impl Into<String>) -> Self {
3324        Self {
3325            name: name.into(),
3326            quoted: false,
3327            trailing_comments: Vec::new(),
3328            span: None,
3329        }
3330    }
3331
3332    pub fn quoted(name: impl Into<String>) -> Self {
3333        Self {
3334            name: name.into(),
3335            quoted: true,
3336            trailing_comments: Vec::new(),
3337            span: None,
3338        }
3339    }
3340
3341    pub fn empty() -> Self {
3342        Self {
3343            name: String::new(),
3344            quoted: false,
3345            trailing_comments: Vec::new(),
3346            span: None,
3347        }
3348    }
3349
3350    pub fn is_empty(&self) -> bool {
3351        self.name.is_empty()
3352    }
3353
3354    /// Set the source span on this identifier
3355    pub fn with_span(mut self, span: Span) -> Self {
3356        self.span = Some(span);
3357        self
3358    }
3359}
3360
3361impl fmt::Display for Identifier {
3362    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3363        if self.quoted {
3364            write!(f, "\"{}\"", self.name)
3365        } else {
3366            write!(f, "{}", self.name)
3367        }
3368    }
3369}
3370
3371/// Represent a column reference, optionally qualified by a table name.
3372///
3373/// Renders as `name` when unqualified, or `table.name` when qualified.
3374/// Use [`Expression::column()`] or [`Expression::qualified_column()`] for
3375/// convenient construction.
3376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3377#[cfg_attr(feature = "bindings", derive(TS))]
3378pub struct Column {
3379    /// The column name.
3380    pub name: Identifier,
3381    /// Optional table qualifier (e.g. `t` in `t.col`).
3382    pub table: Option<Identifier>,
3383    /// Oracle-style join marker (+) for outer joins
3384    #[serde(default)]
3385    pub join_mark: bool,
3386    /// Trailing comments that appeared after this column reference
3387    #[serde(default)]
3388    pub trailing_comments: Vec<String>,
3389    /// Source position span
3390    #[serde(default, skip_serializing_if = "Option::is_none")]
3391    pub span: Option<Span>,
3392    /// Inferred data type from type annotation
3393    #[serde(default, skip_serializing_if = "Option::is_none")]
3394    #[ast(skip)]
3395    pub inferred_type: Option<DataType>,
3396}
3397
3398impl fmt::Display for Column {
3399    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3400        if let Some(table) = &self.table {
3401            write!(f, "{}.{}", table, self.name)
3402        } else {
3403            write!(f, "{}", self.name)
3404        }
3405    }
3406}
3407
3408/// Represent a table reference with optional schema and catalog qualifiers.
3409///
3410/// Renders as `name`, `schema.name`, or `catalog.schema.name` depending on
3411/// which qualifiers are present. Supports aliases, column alias lists,
3412/// time-travel clauses (Snowflake, BigQuery), table hints (TSQL), and
3413/// several other dialect-specific extensions.
3414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3415#[cfg_attr(feature = "bindings", derive(TS))]
3416pub struct TableRef {
3417    /// The unqualified table name.
3418    pub name: Identifier,
3419    /// Optional schema qualifier (e.g. `public` in `public.users`).
3420    pub schema: Option<Identifier>,
3421    /// Optional catalog qualifier (e.g. `mydb` in `mydb.public.users`).
3422    pub catalog: Option<Identifier>,
3423    /// Optional table alias (e.g. `t` in `FROM users AS t`).
3424    pub alias: Option<Identifier>,
3425    /// Whether AS keyword was explicitly used for the alias
3426    #[serde(default)]
3427    pub alias_explicit_as: bool,
3428    /// Column aliases for table alias: AS t(c1, c2)
3429    #[serde(default)]
3430    pub column_aliases: Vec<Identifier>,
3431    /// Leading comments that appeared before this table reference in a FROM clause
3432    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3433    pub leading_comments: Vec<String>,
3434    /// Trailing comments that appeared after this table reference
3435    #[serde(default)]
3436    pub trailing_comments: Vec<String>,
3437    /// Snowflake time travel: BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
3438    #[serde(default)]
3439    pub when: Option<Box<HistoricalData>>,
3440    /// PostgreSQL ONLY modifier: prevents scanning child tables in inheritance hierarchy
3441    #[serde(default)]
3442    pub only: bool,
3443    /// ClickHouse FINAL modifier: forces final aggregation for MergeTree tables
3444    #[serde(default)]
3445    pub final_: bool,
3446    /// TABLESAMPLE clause attached to this table reference (DuckDB, BigQuery)
3447    #[serde(default, skip_serializing_if = "Option::is_none")]
3448    pub table_sample: Option<Box<Sample>>,
3449    /// TSQL table hints: WITH (TABLOCK, INDEX(myindex), ...)
3450    #[serde(default)]
3451    pub hints: Vec<Expression>,
3452    /// TSQL: FOR SYSTEM_TIME temporal clause
3453    /// Contains the full clause text, e.g., "FOR SYSTEM_TIME BETWEEN c AND d"
3454    #[serde(default, skip_serializing_if = "Option::is_none")]
3455    pub system_time: Option<String>,
3456    /// MySQL: PARTITION(p0, p1, ...) hint for reading from specific partitions
3457    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3458    pub partitions: Vec<Identifier>,
3459    /// Snowflake IDENTIFIER() function: dynamic table name from string/variable
3460    /// When set, this is used instead of the name field
3461    #[serde(default, skip_serializing_if = "Option::is_none")]
3462    pub identifier_func: Option<Box<Expression>>,
3463    /// Snowflake CHANGES clause: CHANGES (INFORMATION => ...) AT (...) END (...)
3464    #[serde(default, skip_serializing_if = "Option::is_none")]
3465    pub changes: Option<Box<Changes>>,
3466    /// Time travel version clause: FOR VERSION AS OF / FOR TIMESTAMP AS OF (Presto/Trino, BigQuery, Databricks)
3467    #[serde(default, skip_serializing_if = "Option::is_none")]
3468    pub version: Option<Box<Version>>,
3469    /// Source position span
3470    #[serde(default, skip_serializing_if = "Option::is_none")]
3471    pub span: Option<Span>,
3472}
3473
3474impl TableRef {
3475    pub fn new(name: impl Into<String>) -> Self {
3476        Self {
3477            name: Identifier::new(name),
3478            schema: None,
3479            catalog: None,
3480            alias: None,
3481            alias_explicit_as: false,
3482            column_aliases: Vec::new(),
3483            leading_comments: Vec::new(),
3484            trailing_comments: Vec::new(),
3485            when: None,
3486            only: false,
3487            final_: false,
3488            table_sample: None,
3489            hints: Vec::new(),
3490            system_time: None,
3491            partitions: Vec::new(),
3492            identifier_func: None,
3493            changes: None,
3494            version: None,
3495            span: None,
3496        }
3497    }
3498
3499    /// Create with a schema qualifier.
3500    pub fn new_with_schema(name: impl Into<String>, schema: impl Into<String>) -> Self {
3501        let mut t = Self::new(name);
3502        t.schema = Some(Identifier::new(schema));
3503        t
3504    }
3505
3506    /// Create with catalog and schema qualifiers.
3507    pub fn new_with_catalog(
3508        name: impl Into<String>,
3509        schema: impl Into<String>,
3510        catalog: impl Into<String>,
3511    ) -> Self {
3512        let mut t = Self::new(name);
3513        t.schema = Some(Identifier::new(schema));
3514        t.catalog = Some(Identifier::new(catalog));
3515        t
3516    }
3517
3518    /// Create from an Identifier, preserving the quoted flag
3519    pub fn from_identifier(name: Identifier) -> Self {
3520        Self {
3521            name,
3522            schema: None,
3523            catalog: None,
3524            alias: None,
3525            alias_explicit_as: false,
3526            column_aliases: Vec::new(),
3527            leading_comments: Vec::new(),
3528            trailing_comments: Vec::new(),
3529            when: None,
3530            only: false,
3531            final_: false,
3532            table_sample: None,
3533            hints: Vec::new(),
3534            system_time: None,
3535            partitions: Vec::new(),
3536            identifier_func: None,
3537            changes: None,
3538            version: None,
3539            span: None,
3540        }
3541    }
3542
3543    pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
3544        self.alias = Some(Identifier::new(alias));
3545        self
3546    }
3547
3548    pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
3549        self.schema = Some(Identifier::new(schema));
3550        self
3551    }
3552}
3553
3554/// Represent a wildcard star expression (`*`, `table.*`).
3555///
3556/// Supports the EXCEPT/EXCLUDE, REPLACE, and RENAME modifiers found in
3557/// DuckDB, BigQuery, and Snowflake (e.g. `SELECT * EXCEPT (id) FROM t`).
3558#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3559#[cfg_attr(feature = "bindings", derive(TS))]
3560pub struct Star {
3561    /// Optional table qualifier (e.g. `t` in `t.*`).
3562    pub table: Option<Identifier>,
3563    /// EXCLUDE / EXCEPT columns (DuckDB, BigQuery, Snowflake)
3564    pub except: Option<Vec<Identifier>>,
3565    /// REPLACE expressions (BigQuery, Snowflake)
3566    pub replace: Option<Vec<Alias>>,
3567    /// RENAME columns (Snowflake)
3568    pub rename: Option<Vec<(Identifier, Identifier)>>,
3569    /// Trailing comments that appeared after the star
3570    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3571    pub trailing_comments: Vec<String>,
3572    /// Source position span
3573    #[serde(default, skip_serializing_if = "Option::is_none")]
3574    pub span: Option<Span>,
3575}
3576
3577/// Represent a complete SELECT statement.
3578///
3579/// This is the most feature-rich AST node, covering the full surface area of
3580/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3581/// `Vec` are omitted from the generated SQL when absent.
3582///
3583/// # Key Fields
3584///
3585/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3586/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3587/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3588/// - `where_clause` -- the WHERE predicate.
3589/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3590/// - `having` -- HAVING predicate.
3591/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3592/// - `limit` / `offset` / `fetch` -- result set limiting.
3593/// - `with` -- Common Table Expressions (CTEs).
3594/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3595/// - `windows` -- named window definitions (WINDOW w AS ...).
3596///
3597/// Dialect-specific extensions are supported via fields like `prewhere`
3598/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3599/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3600#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3601#[cfg_attr(feature = "bindings", derive(TS))]
3602pub struct Select {
3603    /// The select-list: columns, expressions, aliases, and wildcards.
3604    pub expressions: Vec<Expression>,
3605    /// The FROM clause, containing one or more table sources.
3606    pub from: Option<From>,
3607    /// JOIN clauses applied after the FROM source.
3608    pub joins: Vec<Join>,
3609    pub lateral_views: Vec<LateralView>,
3610    /// ClickHouse PREWHERE clause
3611    #[serde(default, skip_serializing_if = "Option::is_none")]
3612    pub prewhere: Option<Expression>,
3613    pub where_clause: Option<Where>,
3614    pub group_by: Option<GroupBy>,
3615    pub having: Option<Having>,
3616    pub qualify: Option<Qualify>,
3617    pub order_by: Option<OrderBy>,
3618    pub distribute_by: Option<DistributeBy>,
3619    pub cluster_by: Option<ClusterBy>,
3620    pub sort_by: Option<SortBy>,
3621    pub limit: Option<Limit>,
3622    pub offset: Option<Offset>,
3623    /// ClickHouse LIMIT BY clause expressions
3624    #[serde(default, skip_serializing_if = "Option::is_none")]
3625    pub limit_by: Option<Vec<Expression>>,
3626    pub fetch: Option<Fetch>,
3627    pub distinct: bool,
3628    pub distinct_on: Option<Vec<Expression>>,
3629    pub top: Option<Top>,
3630    pub with: Option<With>,
3631    pub sample: Option<Sample>,
3632    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3633    #[serde(default, skip_serializing_if = "Option::is_none")]
3634    pub settings: Option<Vec<Expression>>,
3635    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3636    #[serde(default, skip_serializing_if = "Option::is_none")]
3637    pub format: Option<Expression>,
3638    pub windows: Option<Vec<NamedWindow>>,
3639    pub hint: Option<Hint>,
3640    /// Oracle CONNECT BY clause for hierarchical queries
3641    pub connect: Option<Connect>,
3642    /// SELECT ... INTO table_name for creating tables
3643    pub into: Option<SelectInto>,
3644    /// FOR UPDATE/SHARE locking clauses
3645    #[serde(default)]
3646    pub locks: Vec<Lock>,
3647    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3648    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3649    pub for_xml: Vec<Expression>,
3650    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3651    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3652    pub for_json: Vec<Expression>,
3653    /// Leading comments before the statement
3654    #[serde(default)]
3655    pub leading_comments: Vec<String>,
3656    /// Comments that appear after SELECT keyword (before expressions)
3657    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3658    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3659    pub post_select_comments: Vec<String>,
3660    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3661    #[serde(default, skip_serializing_if = "Option::is_none")]
3662    pub kind: Option<String>,
3663    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3664    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3665    pub operation_modifiers: Vec<String>,
3666    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3667    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3668    pub qualify_after_window: bool,
3669    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3670    #[serde(default, skip_serializing_if = "Option::is_none")]
3671    pub option: Option<String>,
3672    /// Redshift-style EXCLUDE clause at the end of the projection list
3673    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3674    #[serde(default, skip_serializing_if = "Option::is_none")]
3675    pub exclude: Option<Vec<Expression>>,
3676}
3677
3678impl Select {
3679    pub fn new() -> Self {
3680        Self {
3681            expressions: Vec::new(),
3682            from: None,
3683            joins: Vec::new(),
3684            lateral_views: Vec::new(),
3685            prewhere: None,
3686            where_clause: None,
3687            group_by: None,
3688            having: None,
3689            qualify: None,
3690            order_by: None,
3691            distribute_by: None,
3692            cluster_by: None,
3693            sort_by: None,
3694            limit: None,
3695            offset: None,
3696            limit_by: None,
3697            fetch: None,
3698            distinct: false,
3699            distinct_on: None,
3700            top: None,
3701            with: None,
3702            sample: None,
3703            settings: None,
3704            format: None,
3705            windows: None,
3706            hint: None,
3707            connect: None,
3708            into: None,
3709            locks: Vec::new(),
3710            for_xml: Vec::new(),
3711            for_json: Vec::new(),
3712            leading_comments: Vec::new(),
3713            post_select_comments: Vec::new(),
3714            kind: None,
3715            operation_modifiers: Vec::new(),
3716            qualify_after_window: false,
3717            option: None,
3718            exclude: None,
3719        }
3720    }
3721
3722    /// Add a column to select
3723    pub fn column(mut self, expr: Expression) -> Self {
3724        self.expressions.push(expr);
3725        self
3726    }
3727
3728    /// Set the FROM clause
3729    pub fn from(mut self, table: Expression) -> Self {
3730        self.from = Some(From {
3731            expressions: vec![table],
3732        });
3733        self
3734    }
3735
3736    /// Add a WHERE clause
3737    pub fn where_(mut self, condition: Expression) -> Self {
3738        self.where_clause = Some(Where { this: condition });
3739        self
3740    }
3741
3742    /// Set DISTINCT
3743    pub fn distinct(mut self) -> Self {
3744        self.distinct = true;
3745        self
3746    }
3747
3748    /// Add a JOIN
3749    pub fn join(mut self, join: Join) -> Self {
3750        self.joins.push(join);
3751        self
3752    }
3753
3754    /// Set ORDER BY
3755    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
3756        self.order_by = Some(OrderBy {
3757            expressions,
3758            siblings: false,
3759            comments: Vec::new(),
3760        });
3761        self
3762    }
3763
3764    /// Set LIMIT
3765    pub fn limit(mut self, n: Expression) -> Self {
3766        self.limit = Some(Limit {
3767            this: n,
3768            percent: false,
3769            comments: Vec::new(),
3770        });
3771        self
3772    }
3773
3774    /// Set OFFSET
3775    pub fn offset(mut self, n: Expression) -> Self {
3776        self.offset = Some(Offset {
3777            this: n,
3778            rows: None,
3779        });
3780        self
3781    }
3782}
3783
3784impl Default for Select {
3785    fn default() -> Self {
3786        Self::new()
3787    }
3788}
3789
3790/// Represent a UNION set operation between two query expressions.
3791///
3792/// When `all` is true, duplicate rows are preserved (UNION ALL).
3793/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
3794/// Supports DuckDB's BY NAME modifier and BigQuery's CORRESPONDING modifier.
3795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3796#[cfg_attr(feature = "bindings", derive(TS))]
3797pub struct Union {
3798    /// The left-hand query operand.
3799    pub left: Expression,
3800    /// The right-hand query operand.
3801    pub right: Expression,
3802    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
3803    pub all: bool,
3804    /// Whether DISTINCT was explicitly specified
3805    #[serde(default)]
3806    pub distinct: bool,
3807    /// Optional WITH clause
3808    pub with: Option<With>,
3809    /// ORDER BY applied to entire UNION result
3810    pub order_by: Option<OrderBy>,
3811    /// LIMIT applied to entire UNION result
3812    pub limit: Option<Box<Expression>>,
3813    /// OFFSET applied to entire UNION result
3814    pub offset: Option<Box<Expression>>,
3815    /// DISTRIBUTE BY clause (Hive/Spark)
3816    #[serde(default, skip_serializing_if = "Option::is_none")]
3817    pub distribute_by: Option<DistributeBy>,
3818    /// SORT BY clause (Hive/Spark)
3819    #[serde(default, skip_serializing_if = "Option::is_none")]
3820    pub sort_by: Option<SortBy>,
3821    /// CLUSTER BY clause (Hive/Spark)
3822    #[serde(default, skip_serializing_if = "Option::is_none")]
3823    pub cluster_by: Option<ClusterBy>,
3824    /// DuckDB BY NAME modifier
3825    #[serde(default)]
3826    pub by_name: bool,
3827    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3828    #[serde(default, skip_serializing_if = "Option::is_none")]
3829    pub side: Option<String>,
3830    /// BigQuery: Set operation kind (INNER)
3831    #[serde(default, skip_serializing_if = "Option::is_none")]
3832    pub kind: Option<String>,
3833    /// BigQuery: CORRESPONDING modifier
3834    #[serde(default)]
3835    pub corresponding: bool,
3836    /// BigQuery: STRICT modifier (before CORRESPONDING)
3837    #[serde(default)]
3838    pub strict: bool,
3839    /// BigQuery: BY (columns) after CORRESPONDING
3840    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3841    pub on_columns: Vec<Expression>,
3842}
3843
3844/// Iteratively flatten the left-recursive chain to prevent stack overflow
3845/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3846impl Drop for Union {
3847    fn drop(&mut self) {
3848        loop {
3849            if let Expression::Union(ref mut inner) = self.left {
3850                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3851                let old_left = std::mem::replace(&mut self.left, next_left);
3852                drop(old_left);
3853            } else {
3854                break;
3855            }
3856        }
3857    }
3858}
3859
3860/// Represent an INTERSECT set operation between two query expressions.
3861///
3862/// Returns only rows that appear in both operands. When `all` is true,
3863/// duplicates are preserved according to their multiplicity.
3864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3865#[cfg_attr(feature = "bindings", derive(TS))]
3866pub struct Intersect {
3867    /// The left-hand query operand.
3868    pub left: Expression,
3869    /// The right-hand query operand.
3870    pub right: Expression,
3871    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
3872    pub all: bool,
3873    /// Whether DISTINCT was explicitly specified
3874    #[serde(default)]
3875    pub distinct: bool,
3876    /// Optional WITH clause
3877    pub with: Option<With>,
3878    /// ORDER BY applied to entire INTERSECT result
3879    pub order_by: Option<OrderBy>,
3880    /// LIMIT applied to entire INTERSECT result
3881    pub limit: Option<Box<Expression>>,
3882    /// OFFSET applied to entire INTERSECT result
3883    pub offset: Option<Box<Expression>>,
3884    /// DISTRIBUTE BY clause (Hive/Spark)
3885    #[serde(default, skip_serializing_if = "Option::is_none")]
3886    pub distribute_by: Option<DistributeBy>,
3887    /// SORT BY clause (Hive/Spark)
3888    #[serde(default, skip_serializing_if = "Option::is_none")]
3889    pub sort_by: Option<SortBy>,
3890    /// CLUSTER BY clause (Hive/Spark)
3891    #[serde(default, skip_serializing_if = "Option::is_none")]
3892    pub cluster_by: Option<ClusterBy>,
3893    /// DuckDB BY NAME modifier
3894    #[serde(default)]
3895    pub by_name: bool,
3896    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3897    #[serde(default, skip_serializing_if = "Option::is_none")]
3898    pub side: Option<String>,
3899    /// BigQuery: Set operation kind (INNER)
3900    #[serde(default, skip_serializing_if = "Option::is_none")]
3901    pub kind: Option<String>,
3902    /// BigQuery: CORRESPONDING modifier
3903    #[serde(default)]
3904    pub corresponding: bool,
3905    /// BigQuery: STRICT modifier (before CORRESPONDING)
3906    #[serde(default)]
3907    pub strict: bool,
3908    /// BigQuery: BY (columns) after CORRESPONDING
3909    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3910    pub on_columns: Vec<Expression>,
3911}
3912
3913impl Drop for Intersect {
3914    fn drop(&mut self) {
3915        loop {
3916            if let Expression::Intersect(ref mut inner) = self.left {
3917                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3918                let old_left = std::mem::replace(&mut self.left, next_left);
3919                drop(old_left);
3920            } else {
3921                break;
3922            }
3923        }
3924    }
3925}
3926
3927/// Represent an EXCEPT (MINUS) set operation between two query expressions.
3928///
3929/// Returns rows from the left operand that do not appear in the right operand.
3930/// When `all` is true, duplicates are subtracted according to their multiplicity.
3931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3932#[cfg_attr(feature = "bindings", derive(TS))]
3933pub struct Except {
3934    /// The left-hand query operand.
3935    pub left: Expression,
3936    /// The right-hand query operand (rows to subtract).
3937    pub right: Expression,
3938    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
3939    pub all: bool,
3940    /// Whether DISTINCT was explicitly specified
3941    #[serde(default)]
3942    pub distinct: bool,
3943    /// Optional WITH clause
3944    pub with: Option<With>,
3945    /// ORDER BY applied to entire EXCEPT result
3946    pub order_by: Option<OrderBy>,
3947    /// LIMIT applied to entire EXCEPT result
3948    pub limit: Option<Box<Expression>>,
3949    /// OFFSET applied to entire EXCEPT result
3950    pub offset: Option<Box<Expression>>,
3951    /// DISTRIBUTE BY clause (Hive/Spark)
3952    #[serde(default, skip_serializing_if = "Option::is_none")]
3953    pub distribute_by: Option<DistributeBy>,
3954    /// SORT BY clause (Hive/Spark)
3955    #[serde(default, skip_serializing_if = "Option::is_none")]
3956    pub sort_by: Option<SortBy>,
3957    /// CLUSTER BY clause (Hive/Spark)
3958    #[serde(default, skip_serializing_if = "Option::is_none")]
3959    pub cluster_by: Option<ClusterBy>,
3960    /// DuckDB BY NAME modifier
3961    #[serde(default)]
3962    pub by_name: bool,
3963    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3964    #[serde(default, skip_serializing_if = "Option::is_none")]
3965    pub side: Option<String>,
3966    /// BigQuery: Set operation kind (INNER)
3967    #[serde(default, skip_serializing_if = "Option::is_none")]
3968    pub kind: Option<String>,
3969    /// BigQuery: CORRESPONDING modifier
3970    #[serde(default)]
3971    pub corresponding: bool,
3972    /// BigQuery: STRICT modifier (before CORRESPONDING)
3973    #[serde(default)]
3974    pub strict: bool,
3975    /// BigQuery: BY (columns) after CORRESPONDING
3976    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3977    pub on_columns: Vec<Expression>,
3978}
3979
3980impl Drop for Except {
3981    fn drop(&mut self) {
3982        loop {
3983            if let Expression::Except(ref mut inner) = self.left {
3984                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3985                let old_left = std::mem::replace(&mut self.left, next_left);
3986                drop(old_left);
3987            } else {
3988                break;
3989            }
3990        }
3991    }
3992}
3993
3994/// INTO clause for SELECT INTO statements
3995#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3996#[cfg_attr(feature = "bindings", derive(TS))]
3997pub struct SelectInto {
3998    /// Target table or variable (used when single target)
3999    pub this: Expression,
4000    /// Whether TEMPORARY keyword was used
4001    #[serde(default)]
4002    pub temporary: bool,
4003    /// Whether UNLOGGED keyword was used (PostgreSQL)
4004    #[serde(default)]
4005    pub unlogged: bool,
4006    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4007    #[serde(default)]
4008    pub bulk_collect: bool,
4009    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4010    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4011    pub expressions: Vec<Expression>,
4012}
4013
4014/// Represent a parenthesized subquery expression.
4015///
4016/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4017/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4018/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4019/// modifiers are rendered inside or outside the parentheses.
4020///
4021/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4022/// scalar subqueries in select-lists, and derived tables.
4023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4024#[cfg_attr(feature = "bindings", derive(TS))]
4025pub struct Subquery {
4026    /// The inner query expression.
4027    pub this: Expression,
4028    /// Optional alias for the derived table.
4029    pub alias: Option<Identifier>,
4030    /// Optional column aliases: AS t(c1, c2)
4031    pub column_aliases: Vec<Identifier>,
4032    /// Whether AS keyword was explicitly used for the alias.
4033    #[serde(default)]
4034    pub alias_explicit_as: bool,
4035    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4036    #[serde(skip_serializing_if = "Option::is_none", default)]
4037    pub alias_keyword: Option<String>,
4038    /// ORDER BY clause (for parenthesized queries)
4039    pub order_by: Option<OrderBy>,
4040    /// LIMIT clause
4041    pub limit: Option<Limit>,
4042    /// OFFSET clause
4043    pub offset: Option<Offset>,
4044    /// DISTRIBUTE BY clause (Hive/Spark)
4045    #[serde(default, skip_serializing_if = "Option::is_none")]
4046    pub distribute_by: Option<DistributeBy>,
4047    /// SORT BY clause (Hive/Spark)
4048    #[serde(default, skip_serializing_if = "Option::is_none")]
4049    pub sort_by: Option<SortBy>,
4050    /// CLUSTER BY clause (Hive/Spark)
4051    #[serde(default, skip_serializing_if = "Option::is_none")]
4052    pub cluster_by: Option<ClusterBy>,
4053    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4054    #[serde(default)]
4055    pub lateral: bool,
4056    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4057    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4058    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4059    #[serde(default)]
4060    pub modifiers_inside: bool,
4061    /// Trailing comments after the closing paren
4062    #[serde(default)]
4063    pub trailing_comments: Vec<String>,
4064    /// Inferred data type from type annotation
4065    #[serde(default, skip_serializing_if = "Option::is_none")]
4066    #[ast(skip)]
4067    pub inferred_type: Option<DataType>,
4068}
4069
4070/// Pipe operator expression: query |> transform
4071///
4072/// Used in DataFusion and BigQuery pipe syntax:
4073///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4074#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4075#[cfg_attr(feature = "bindings", derive(TS))]
4076pub struct PipeOperator {
4077    /// The input query/expression (left side of |>)
4078    pub this: Expression,
4079    /// The piped operation (right side of |>)
4080    pub expression: Expression,
4081}
4082
4083/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4085#[cfg_attr(feature = "bindings", derive(TS))]
4086pub struct Values {
4087    /// The rows of values
4088    pub expressions: Vec<Tuple>,
4089    /// Optional alias for the table
4090    pub alias: Option<Identifier>,
4091    /// Optional column aliases: AS t(c1, c2)
4092    pub column_aliases: Vec<Identifier>,
4093}
4094
4095/// PIVOT operation - supports both standard and DuckDB simplified syntax
4096///
4097/// Standard syntax (in FROM clause):
4098///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4099///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4100///
4101/// DuckDB simplified syntax (statement-level):
4102///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4103///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4104#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4105#[cfg_attr(feature = "bindings", derive(TS))]
4106pub struct Pivot {
4107    /// Source table/expression
4108    pub this: Expression,
4109    /// For standard PIVOT: the aggregation function(s) (first is primary)
4110    /// For DuckDB simplified: unused (use `using` instead)
4111    #[serde(default)]
4112    pub expressions: Vec<Expression>,
4113    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4114    #[serde(default)]
4115    pub fields: Vec<Expression>,
4116    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4117    #[serde(default)]
4118    pub using: Vec<Expression>,
4119    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4120    #[serde(default)]
4121    pub group: Option<Box<Expression>>,
4122    /// Whether this is an UNPIVOT (vs PIVOT)
4123    #[serde(default)]
4124    pub unpivot: bool,
4125    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4126    #[serde(default)]
4127    pub into: Option<Box<Expression>>,
4128    /// Optional alias
4129    #[serde(default)]
4130    pub alias: Option<Identifier>,
4131    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4132    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4133    pub alias_columns: Vec<Identifier>,
4134    /// Include/exclude nulls (for UNPIVOT)
4135    #[serde(default)]
4136    pub include_nulls: Option<bool>,
4137    /// Default on null value (Snowflake)
4138    #[serde(default)]
4139    pub default_on_null: Option<Box<Expression>>,
4140    /// WITH clause (CTEs)
4141    #[serde(default, skip_serializing_if = "Option::is_none")]
4142    pub with: Option<With>,
4143}
4144
4145/// UNPIVOT operation
4146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4147#[cfg_attr(feature = "bindings", derive(TS))]
4148pub struct Unpivot {
4149    pub this: Expression,
4150    pub value_column: Identifier,
4151    pub name_column: Identifier,
4152    pub columns: Vec<Expression>,
4153    pub alias: Option<Identifier>,
4154    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4155    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4156    pub alias_columns: Vec<Identifier>,
4157    /// Whether the value_column was parenthesized in the original SQL
4158    #[serde(default)]
4159    pub value_column_parenthesized: bool,
4160    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4161    #[serde(default)]
4162    pub include_nulls: Option<bool>,
4163    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4164    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4165    pub extra_value_columns: Vec<Identifier>,
4166}
4167
4168/// PIVOT alias for aliasing pivot expressions
4169/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4171#[cfg_attr(feature = "bindings", derive(TS))]
4172pub struct PivotAlias {
4173    pub this: Expression,
4174    pub alias: Expression,
4175}
4176
4177/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4179#[cfg_attr(feature = "bindings", derive(TS))]
4180pub struct PreWhere {
4181    pub this: Expression,
4182}
4183
4184/// STREAM definition (Snowflake) - for change data capture
4185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4186#[cfg_attr(feature = "bindings", derive(TS))]
4187pub struct Stream {
4188    pub this: Expression,
4189    #[serde(skip_serializing_if = "Option::is_none")]
4190    pub on: Option<Expression>,
4191    #[serde(skip_serializing_if = "Option::is_none")]
4192    pub show_initial_rows: Option<bool>,
4193}
4194
4195/// USING DATA clause for data import statements
4196#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4197#[cfg_attr(feature = "bindings", derive(TS))]
4198pub struct UsingData {
4199    pub this: Expression,
4200}
4201
4202/// XML Namespace declaration
4203#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4204#[cfg_attr(feature = "bindings", derive(TS))]
4205pub struct XmlNamespace {
4206    pub this: Expression,
4207    #[serde(skip_serializing_if = "Option::is_none")]
4208    pub alias: Option<Identifier>,
4209}
4210
4211/// ROW FORMAT clause for Hive/Spark
4212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4213#[cfg_attr(feature = "bindings", derive(TS))]
4214pub struct RowFormat {
4215    pub delimited: bool,
4216    pub fields_terminated_by: Option<String>,
4217    pub collection_items_terminated_by: Option<String>,
4218    pub map_keys_terminated_by: Option<String>,
4219    pub lines_terminated_by: Option<String>,
4220    pub null_defined_as: Option<String>,
4221}
4222
4223/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4225#[cfg_attr(feature = "bindings", derive(TS))]
4226pub struct DirectoryInsert {
4227    pub local: bool,
4228    pub path: String,
4229    pub row_format: Option<RowFormat>,
4230    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4231    #[serde(default)]
4232    pub stored_as: Option<String>,
4233}
4234
4235/// INSERT statement
4236#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4237#[cfg_attr(feature = "bindings", derive(TS))]
4238pub struct Insert {
4239    pub table: TableRef,
4240    pub columns: Vec<Identifier>,
4241    pub values: Vec<Vec<Expression>>,
4242    pub query: Option<Expression>,
4243    /// INSERT OVERWRITE for Hive/Spark
4244    pub overwrite: bool,
4245    /// PARTITION clause for Hive/Spark
4246    pub partition: Vec<(Identifier, Option<Expression>)>,
4247    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4248    #[serde(default)]
4249    pub directory: Option<DirectoryInsert>,
4250    /// RETURNING clause (PostgreSQL, SQLite)
4251    #[serde(default)]
4252    pub returning: Vec<Expression>,
4253    /// OUTPUT clause (TSQL)
4254    #[serde(default)]
4255    pub output: Option<OutputClause>,
4256    /// ON CONFLICT clause (PostgreSQL, SQLite)
4257    #[serde(default)]
4258    pub on_conflict: Option<Box<Expression>>,
4259    /// Leading comments before the statement
4260    #[serde(default)]
4261    pub leading_comments: Vec<String>,
4262    /// IF EXISTS clause (Hive)
4263    #[serde(default)]
4264    pub if_exists: bool,
4265    /// WITH clause (CTEs)
4266    #[serde(default)]
4267    pub with: Option<With>,
4268    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4269    #[serde(default)]
4270    pub ignore: bool,
4271    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4272    #[serde(default)]
4273    pub source_alias: Option<Identifier>,
4274    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4275    #[serde(default)]
4276    pub alias: Option<Identifier>,
4277    /// Whether the alias uses explicit AS keyword
4278    #[serde(default)]
4279    pub alias_explicit_as: bool,
4280    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4281    #[serde(default)]
4282    pub default_values: bool,
4283    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4284    #[serde(default)]
4285    pub by_name: bool,
4286    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4287    #[serde(default, skip_serializing_if = "Option::is_none")]
4288    pub conflict_action: Option<String>,
4289    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4290    #[serde(default)]
4291    pub is_replace: bool,
4292    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4293    #[serde(default, skip_serializing_if = "Option::is_none")]
4294    pub hint: Option<Hint>,
4295    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4296    #[serde(default)]
4297    pub replace_where: Option<Box<Expression>>,
4298    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4299    #[serde(default)]
4300    pub source: Option<Box<Expression>>,
4301    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4302    #[serde(default, skip_serializing_if = "Option::is_none")]
4303    pub function_target: Option<Box<Expression>>,
4304    /// ClickHouse: PARTITION BY expr
4305    #[serde(default, skip_serializing_if = "Option::is_none")]
4306    pub partition_by: Option<Box<Expression>>,
4307    /// ClickHouse: SETTINGS key = val, ...
4308    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4309    pub settings: Vec<Expression>,
4310}
4311
4312/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4313#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4314#[cfg_attr(feature = "bindings", derive(TS))]
4315pub struct OutputClause {
4316    /// Columns/expressions to output
4317    pub columns: Vec<Expression>,
4318    /// Optional INTO target table or table variable
4319    #[serde(default)]
4320    pub into_table: Option<Expression>,
4321}
4322
4323/// UPDATE statement
4324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4325#[cfg_attr(feature = "bindings", derive(TS))]
4326pub struct Update {
4327    pub table: TableRef,
4328    #[serde(default)]
4329    pub hint: Option<Hint>,
4330    /// Additional tables for multi-table UPDATE (MySQL syntax)
4331    #[serde(default)]
4332    pub extra_tables: Vec<TableRef>,
4333    /// JOINs attached to the table list (MySQL multi-table syntax)
4334    #[serde(default)]
4335    pub table_joins: Vec<Join>,
4336    pub set: Vec<(Identifier, Expression)>,
4337    pub from_clause: Option<From>,
4338    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4339    #[serde(default)]
4340    pub from_joins: Vec<Join>,
4341    pub where_clause: Option<Where>,
4342    /// RETURNING clause (PostgreSQL, SQLite)
4343    #[serde(default)]
4344    pub returning: Vec<Expression>,
4345    /// OUTPUT clause (TSQL)
4346    #[serde(default)]
4347    pub output: Option<OutputClause>,
4348    /// WITH clause (CTEs)
4349    #[serde(default)]
4350    pub with: Option<With>,
4351    /// Leading comments before the statement
4352    #[serde(default)]
4353    pub leading_comments: Vec<String>,
4354    /// LIMIT clause (MySQL)
4355    #[serde(default)]
4356    pub limit: Option<Expression>,
4357    /// ORDER BY clause (MySQL)
4358    #[serde(default)]
4359    pub order_by: Option<OrderBy>,
4360    /// Whether FROM clause appears before SET (Snowflake syntax)
4361    #[serde(default)]
4362    pub from_before_set: bool,
4363}
4364
4365/// DELETE statement
4366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4367#[cfg_attr(feature = "bindings", derive(TS))]
4368pub struct Delete {
4369    pub table: TableRef,
4370    #[serde(default)]
4371    pub hint: Option<Hint>,
4372    /// ClickHouse: ON CLUSTER clause for distributed DDL
4373    #[serde(default, skip_serializing_if = "Option::is_none")]
4374    pub on_cluster: Option<OnCluster>,
4375    /// Optional alias for the table
4376    pub alias: Option<Identifier>,
4377    /// Whether the alias was declared with explicit AS keyword
4378    #[serde(default)]
4379    pub alias_explicit_as: bool,
4380    /// PostgreSQL/DuckDB USING clause - additional tables to join
4381    pub using: Vec<TableRef>,
4382    pub where_clause: Option<Where>,
4383    /// OUTPUT clause (TSQL)
4384    #[serde(default)]
4385    pub output: Option<OutputClause>,
4386    /// Leading comments before the statement
4387    #[serde(default)]
4388    pub leading_comments: Vec<String>,
4389    /// WITH clause (CTEs)
4390    #[serde(default)]
4391    pub with: Option<With>,
4392    /// LIMIT clause (MySQL)
4393    #[serde(default)]
4394    pub limit: Option<Expression>,
4395    /// ORDER BY clause (MySQL)
4396    #[serde(default)]
4397    pub order_by: Option<OrderBy>,
4398    /// RETURNING clause (PostgreSQL)
4399    #[serde(default)]
4400    pub returning: Vec<Expression>,
4401    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4402    /// These are the target tables to delete from
4403    #[serde(default)]
4404    pub tables: Vec<TableRef>,
4405    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4406    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4407    #[serde(default)]
4408    pub tables_from_using: bool,
4409    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4410    #[serde(default)]
4411    pub joins: Vec<Join>,
4412    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4413    #[serde(default)]
4414    pub force_index: Option<String>,
4415    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4416    #[serde(default)]
4417    pub no_from: bool,
4418}
4419
4420/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4422#[cfg_attr(feature = "bindings", derive(TS))]
4423pub struct CopyStmt {
4424    /// Target table or query
4425    pub this: Expression,
4426    /// True for FROM (loading into table), false for TO (exporting)
4427    pub kind: bool,
4428    /// Source/destination file(s) or stage
4429    pub files: Vec<Expression>,
4430    /// Copy parameters
4431    #[serde(default)]
4432    pub params: Vec<CopyParameter>,
4433    /// Credentials for external access
4434    #[serde(default)]
4435    pub credentials: Option<Box<Credentials>>,
4436    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4437    #[serde(default)]
4438    pub is_into: bool,
4439    /// Whether parameters are wrapped in WITH (...) syntax
4440    #[serde(default)]
4441    pub with_wrapped: bool,
4442}
4443
4444/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4445#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4446#[cfg_attr(feature = "bindings", derive(TS))]
4447pub struct CopyParameter {
4448    pub name: String,
4449    pub value: Option<Expression>,
4450    pub values: Vec<Expression>,
4451    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4452    #[serde(default)]
4453    pub eq: bool,
4454}
4455
4456/// Credentials for external access (S3, Azure, etc.)
4457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4458#[cfg_attr(feature = "bindings", derive(TS))]
4459pub struct Credentials {
4460    pub credentials: Vec<(String, String)>,
4461    pub encryption: Option<String>,
4462    pub storage: Option<String>,
4463}
4464
4465/// PUT statement (Snowflake)
4466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4467#[cfg_attr(feature = "bindings", derive(TS))]
4468pub struct PutStmt {
4469    /// Source file path
4470    pub source: String,
4471    /// Whether source was quoted in the original SQL
4472    #[serde(default)]
4473    pub source_quoted: bool,
4474    /// Target stage
4475    pub target: Expression,
4476    /// PUT parameters
4477    #[serde(default)]
4478    pub params: Vec<CopyParameter>,
4479}
4480
4481/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4482#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4483#[cfg_attr(feature = "bindings", derive(TS))]
4484pub struct StageReference {
4485    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4486    pub name: String,
4487    /// Optional path within the stage (e.g., "/path/to/file.csv")
4488    #[serde(default)]
4489    pub path: Option<String>,
4490    /// Optional FILE_FORMAT parameter
4491    #[serde(default)]
4492    pub file_format: Option<Expression>,
4493    /// Optional PATTERN parameter
4494    #[serde(default)]
4495    pub pattern: Option<String>,
4496    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4497    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4498    pub quoted: bool,
4499}
4500
4501/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4503#[cfg_attr(feature = "bindings", derive(TS))]
4504pub struct HistoricalData {
4505    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4506    pub this: Box<Expression>,
4507    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4508    pub kind: String,
4509    /// The expression value (e.g., the statement ID or timestamp)
4510    pub expression: Box<Expression>,
4511}
4512
4513/// Represent an aliased expression (`expr AS name`).
4514///
4515/// Used for column aliases in select-lists, table aliases on subqueries,
4516/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4518#[cfg_attr(feature = "bindings", derive(TS))]
4519pub struct Alias {
4520    /// The expression being aliased.
4521    pub this: Expression,
4522    /// The alias name (required for simple aliases, optional when only column aliases provided)
4523    pub alias: Identifier,
4524    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4525    #[serde(default)]
4526    pub column_aliases: Vec<Identifier>,
4527    /// Whether AS keyword was explicitly used for the alias.
4528    #[serde(default)]
4529    pub alias_explicit_as: bool,
4530    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4531    #[serde(skip_serializing_if = "Option::is_none", default)]
4532    pub alias_keyword: Option<String>,
4533    /// Comments that appeared between the expression and AS keyword
4534    #[serde(default)]
4535    pub pre_alias_comments: Vec<String>,
4536    /// Trailing comments that appeared after the alias
4537    #[serde(default)]
4538    pub trailing_comments: Vec<String>,
4539    /// Inferred data type from type annotation
4540    #[serde(default, skip_serializing_if = "Option::is_none")]
4541    #[ast(skip)]
4542    pub inferred_type: Option<DataType>,
4543}
4544
4545impl Alias {
4546    /// Create a simple alias
4547    pub fn new(this: Expression, alias: Identifier) -> Self {
4548        Self {
4549            this,
4550            alias,
4551            column_aliases: Vec::new(),
4552            alias_explicit_as: false,
4553            alias_keyword: None,
4554            pre_alias_comments: Vec::new(),
4555            trailing_comments: Vec::new(),
4556            inferred_type: None,
4557        }
4558    }
4559
4560    /// Create an alias with column aliases only (no table alias name)
4561    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4562        Self {
4563            this,
4564            alias: Identifier::empty(),
4565            column_aliases,
4566            alias_explicit_as: false,
4567            alias_keyword: None,
4568            pre_alias_comments: Vec::new(),
4569            trailing_comments: Vec::new(),
4570            inferred_type: None,
4571        }
4572    }
4573}
4574
4575/// Represent a type cast expression.
4576///
4577/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4578/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4579/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4580/// CONVERSION ERROR (Oracle) clauses.
4581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4582#[cfg_attr(feature = "bindings", derive(TS))]
4583pub struct Cast {
4584    /// The expression being cast.
4585    pub this: Expression,
4586    /// The target data type.
4587    pub to: DataType,
4588    #[serde(default)]
4589    pub trailing_comments: Vec<String>,
4590    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4591    #[serde(default)]
4592    pub double_colon_syntax: bool,
4593    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4594    #[serde(skip_serializing_if = "Option::is_none", default)]
4595    pub format: Option<Box<Expression>>,
4596    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4597    #[serde(skip_serializing_if = "Option::is_none", default)]
4598    pub default: Option<Box<Expression>>,
4599    /// Inferred data type from type annotation
4600    #[serde(default, skip_serializing_if = "Option::is_none")]
4601    #[ast(skip)]
4602    pub inferred_type: Option<DataType>,
4603}
4604
4605///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4606#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4607#[cfg_attr(feature = "bindings", derive(TS))]
4608pub struct CollationExpr {
4609    pub this: Expression,
4610    pub collation: String,
4611    /// True if the collation was single-quoted in the original SQL (string literal)
4612    #[serde(default)]
4613    pub quoted: bool,
4614    /// True if the collation was double-quoted in the original SQL (identifier)
4615    #[serde(default)]
4616    pub double_quoted: bool,
4617}
4618
4619/// Represent a CASE expression (both simple and searched forms).
4620///
4621/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4622/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4623/// Each entry in `whens` is a `(condition, result)` pair.
4624#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4625#[cfg_attr(feature = "bindings", derive(TS))]
4626pub struct Case {
4627    /// The operand for simple CASE, or `None` for searched CASE.
4628    pub operand: Option<Expression>,
4629    /// Pairs of (WHEN condition, THEN result).
4630    pub whens: Vec<(Expression, Expression)>,
4631    /// Optional ELSE result.
4632    pub else_: Option<Expression>,
4633    /// Comments from the CASE keyword (emitted after END)
4634    #[serde(default)]
4635    #[serde(skip_serializing_if = "Vec::is_empty")]
4636    pub comments: Vec<String>,
4637    /// Inferred data type from type annotation
4638    #[serde(default, skip_serializing_if = "Option::is_none")]
4639    #[ast(skip)]
4640    pub inferred_type: Option<DataType>,
4641}
4642
4643/// Represent a binary operation (two operands separated by an operator).
4644///
4645/// This is the shared payload struct for all binary operator variants in the
4646/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4647/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4648/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4649/// preservation of inline comments around operators.
4650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4651#[cfg_attr(feature = "bindings", derive(TS))]
4652pub struct BinaryOp {
4653    pub left: Expression,
4654    pub right: Expression,
4655    /// Comments after the left operand (before the operator)
4656    #[serde(default)]
4657    pub left_comments: Vec<String>,
4658    /// Comments after the operator (before the right operand)
4659    #[serde(default)]
4660    pub operator_comments: Vec<String>,
4661    /// Comments after the right operand
4662    #[serde(default)]
4663    pub trailing_comments: Vec<String>,
4664    /// Inferred data type from type annotation
4665    #[serde(default, skip_serializing_if = "Option::is_none")]
4666    #[ast(skip)]
4667    pub inferred_type: Option<DataType>,
4668}
4669
4670impl BinaryOp {
4671    pub fn new(left: Expression, right: Expression) -> Self {
4672        Self {
4673            left,
4674            right,
4675            left_comments: Vec::new(),
4676            operator_comments: Vec::new(),
4677            trailing_comments: Vec::new(),
4678            inferred_type: None,
4679        }
4680    }
4681}
4682
4683/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4685#[cfg_attr(feature = "bindings", derive(TS))]
4686pub struct LikeOp {
4687    pub left: Expression,
4688    pub right: Expression,
4689    /// ESCAPE character/expression
4690    #[serde(default)]
4691    pub escape: Option<Expression>,
4692    /// Quantifier: ANY, ALL, or SOME
4693    #[serde(default)]
4694    pub quantifier: Option<String>,
4695    /// Inferred data type from type annotation
4696    #[serde(default, skip_serializing_if = "Option::is_none")]
4697    #[ast(skip)]
4698    pub inferred_type: Option<DataType>,
4699}
4700
4701impl LikeOp {
4702    pub fn new(left: Expression, right: Expression) -> Self {
4703        Self {
4704            left,
4705            right,
4706            escape: None,
4707            quantifier: None,
4708            inferred_type: None,
4709        }
4710    }
4711
4712    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4713        Self {
4714            left,
4715            right,
4716            escape: Some(escape),
4717            quantifier: None,
4718            inferred_type: None,
4719        }
4720    }
4721}
4722
4723/// Represent a unary operation (single operand with a prefix operator).
4724///
4725/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4727#[cfg_attr(feature = "bindings", derive(TS))]
4728pub struct UnaryOp {
4729    /// The operand expression.
4730    pub this: Expression,
4731    /// Inferred data type from type annotation
4732    #[serde(default, skip_serializing_if = "Option::is_none")]
4733    #[ast(skip)]
4734    pub inferred_type: Option<DataType>,
4735}
4736
4737impl UnaryOp {
4738    pub fn new(this: Expression) -> Self {
4739        Self {
4740            this,
4741            inferred_type: None,
4742        }
4743    }
4744}
4745
4746/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4747///
4748/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4749/// but not both. When `not` is true, the predicate is `NOT IN`.
4750#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4751#[cfg_attr(feature = "bindings", derive(TS))]
4752pub struct In {
4753    /// The expression being tested.
4754    pub this: Expression,
4755    /// The value list (mutually exclusive with `query`).
4756    pub expressions: Vec<Expression>,
4757    /// A subquery (mutually exclusive with `expressions`).
4758    pub query: Option<Expression>,
4759    /// Whether this is NOT IN.
4760    pub not: bool,
4761    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4762    pub global: bool,
4763    /// BigQuery: IN UNNEST(expr)
4764    #[serde(default, skip_serializing_if = "Option::is_none")]
4765    pub unnest: Option<Box<Expression>>,
4766    /// Whether the right side is a bare field reference (no parentheses).
4767    /// Matches Python sqlglot's `field` attribute on `In` expression.
4768    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4769    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4770    pub is_field: bool,
4771}
4772
4773/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4774#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4775#[cfg_attr(feature = "bindings", derive(TS))]
4776pub struct Between {
4777    /// The expression being tested.
4778    pub this: Expression,
4779    /// The lower bound.
4780    pub low: Expression,
4781    /// The upper bound.
4782    pub high: Expression,
4783    /// Whether this is NOT BETWEEN.
4784    pub not: bool,
4785    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4786    #[serde(default)]
4787    pub symmetric: Option<bool>,
4788}
4789
4790/// IS NULL predicate
4791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4792#[cfg_attr(feature = "bindings", derive(TS))]
4793pub struct IsNull {
4794    pub this: Expression,
4795    pub not: bool,
4796    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4797    #[serde(default)]
4798    pub postfix_form: bool,
4799}
4800
4801/// IS TRUE / IS FALSE predicate
4802#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4803#[cfg_attr(feature = "bindings", derive(TS))]
4804pub struct IsTrueFalse {
4805    pub this: Expression,
4806    pub not: bool,
4807}
4808
4809/// IS JSON predicate (SQL standard)
4810/// Checks if a value is valid JSON
4811#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4812#[cfg_attr(feature = "bindings", derive(TS))]
4813pub struct IsJson {
4814    pub this: Expression,
4815    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4816    pub json_type: Option<String>,
4817    /// Key uniqueness constraint
4818    pub unique_keys: Option<JsonUniqueKeys>,
4819    /// Whether IS NOT JSON
4820    pub negated: bool,
4821}
4822
4823/// JSON unique keys constraint variants
4824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4825#[cfg_attr(feature = "bindings", derive(TS))]
4826pub enum JsonUniqueKeys {
4827    /// WITH UNIQUE KEYS
4828    With,
4829    /// WITHOUT UNIQUE KEYS
4830    Without,
4831    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4832    Shorthand,
4833}
4834
4835/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4837#[cfg_attr(feature = "bindings", derive(TS))]
4838pub struct Exists {
4839    /// The subquery expression.
4840    pub this: Expression,
4841    /// Whether this is NOT EXISTS.
4842    pub not: bool,
4843}
4844
4845/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
4846///
4847/// This is the generic function node. Well-known aggregates, window functions,
4848/// and built-in functions each have their own dedicated `Expression` variants
4849/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
4850/// not recognize as built-ins are represented with this struct.
4851#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4852#[cfg_attr(feature = "bindings", derive(TS))]
4853pub struct Function {
4854    /// The function name, as originally written (may be schema-qualified).
4855    pub name: String,
4856    /// Positional arguments to the function.
4857    pub args: Vec<Expression>,
4858    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
4859    pub distinct: bool,
4860    #[serde(default)]
4861    pub trailing_comments: Vec<String>,
4862    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
4863    #[serde(default)]
4864    pub use_bracket_syntax: bool,
4865    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
4866    #[serde(default)]
4867    pub no_parens: bool,
4868    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
4869    #[serde(default)]
4870    pub quoted: bool,
4871    /// Source position span
4872    #[serde(default, skip_serializing_if = "Option::is_none")]
4873    pub span: Option<Span>,
4874    /// Inferred data type from type annotation
4875    #[serde(default, skip_serializing_if = "Option::is_none")]
4876    #[ast(skip)]
4877    pub inferred_type: Option<DataType>,
4878}
4879
4880impl Default for Function {
4881    fn default() -> Self {
4882        Self {
4883            name: String::new(),
4884            args: Vec::new(),
4885            distinct: false,
4886            trailing_comments: Vec::new(),
4887            use_bracket_syntax: false,
4888            no_parens: false,
4889            quoted: false,
4890            span: None,
4891            inferred_type: None,
4892        }
4893    }
4894}
4895
4896impl Function {
4897    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
4898        Self {
4899            name: name.into(),
4900            args,
4901            distinct: false,
4902            trailing_comments: Vec::new(),
4903            use_bracket_syntax: false,
4904            no_parens: false,
4905            quoted: false,
4906            span: None,
4907            inferred_type: None,
4908        }
4909    }
4910}
4911
4912/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
4913///
4914/// This struct is used for aggregate function calls that are not covered by
4915/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
4916/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
4917/// IGNORE NULLS / RESPECT NULLS modifiers.
4918#[derive(
4919    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
4920)]
4921#[cfg_attr(feature = "bindings", derive(TS))]
4922pub struct AggregateFunction {
4923    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
4924    pub name: String,
4925    /// Positional arguments.
4926    pub args: Vec<Expression>,
4927    /// Whether DISTINCT was specified.
4928    pub distinct: bool,
4929    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
4930    pub filter: Option<Expression>,
4931    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
4932    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4933    pub order_by: Vec<Ordered>,
4934    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
4935    #[serde(default, skip_serializing_if = "Option::is_none")]
4936    pub limit: Option<Box<Expression>>,
4937    /// IGNORE NULLS / RESPECT NULLS
4938    #[serde(default, skip_serializing_if = "Option::is_none")]
4939    pub ignore_nulls: Option<bool>,
4940    /// Inferred data type from type annotation
4941    #[serde(default, skip_serializing_if = "Option::is_none")]
4942    #[ast(skip)]
4943    pub inferred_type: Option<DataType>,
4944}
4945
4946/// Represent a window function call with its OVER clause.
4947///
4948/// The inner `this` expression is typically a window-specific expression
4949/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
4950/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
4951/// frame specification.
4952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4953#[cfg_attr(feature = "bindings", derive(TS))]
4954pub struct WindowFunction {
4955    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
4956    pub this: Expression,
4957    /// The OVER clause defining the window partitioning, ordering, and frame.
4958    pub over: Over,
4959    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
4960    #[serde(default, skip_serializing_if = "Option::is_none")]
4961    pub keep: Option<Keep>,
4962    /// Inferred data type from type annotation
4963    #[serde(default, skip_serializing_if = "Option::is_none")]
4964    #[ast(skip)]
4965    pub inferred_type: Option<DataType>,
4966}
4967
4968/// Oracle KEEP clause for aggregate functions
4969/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
4970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4971#[cfg_attr(feature = "bindings", derive(TS))]
4972pub struct Keep {
4973    /// true = FIRST, false = LAST
4974    pub first: bool,
4975    /// ORDER BY clause inside KEEP
4976    pub order_by: Vec<Ordered>,
4977}
4978
4979/// WITHIN GROUP clause (for ordered-set aggregate functions)
4980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4981#[cfg_attr(feature = "bindings", derive(TS))]
4982pub struct WithinGroup {
4983    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
4984    pub this: Expression,
4985    /// The ORDER BY clause within the group
4986    pub order_by: Vec<Ordered>,
4987}
4988
4989/// Represent the FROM clause of a SELECT statement.
4990///
4991/// Contains one or more table sources (tables, subqueries, table-valued
4992/// functions, etc.). Multiple entries represent comma-separated implicit joins.
4993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4994#[cfg_attr(feature = "bindings", derive(TS))]
4995pub struct From {
4996    /// The table source expressions.
4997    pub expressions: Vec<Expression>,
4998}
4999
5000/// Represent a JOIN clause between two table sources.
5001///
5002/// The join condition can be specified via `on` (ON predicate) or `using`
5003/// (USING column list), but not both. The `kind` field determines the join
5004/// type (INNER, LEFT, CROSS, etc.).
5005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5006#[cfg_attr(feature = "bindings", derive(TS))]
5007pub struct Join {
5008    /// The right-hand table expression being joined.
5009    pub this: Expression,
5010    /// The ON condition (mutually exclusive with `using`).
5011    pub on: Option<Expression>,
5012    /// The USING column list (mutually exclusive with `on`).
5013    pub using: Vec<Identifier>,
5014    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5015    pub kind: JoinKind,
5016    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5017    pub use_inner_keyword: bool,
5018    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5019    pub use_outer_keyword: bool,
5020    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5021    pub deferred_condition: bool,
5022    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5023    #[serde(default, skip_serializing_if = "Option::is_none")]
5024    pub join_hint: Option<String>,
5025    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5026    #[serde(default, skip_serializing_if = "Option::is_none")]
5027    pub match_condition: Option<Expression>,
5028    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5029    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5030    pub pivots: Vec<Expression>,
5031    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5032    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5033    pub comments: Vec<String>,
5034    /// Nesting group identifier for nested join pretty-printing.
5035    /// Joins in the same group were parsed together; group boundaries come from
5036    /// deferred condition resolution phases.
5037    #[serde(default)]
5038    pub nesting_group: usize,
5039    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5040    #[serde(default)]
5041    pub directed: bool,
5042}
5043
5044/// Enumerate all supported SQL join types.
5045///
5046/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5047/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5048/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5049/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5050#[derive(
5051    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5052)]
5053#[cfg_attr(feature = "bindings", derive(TS))]
5054pub enum JoinKind {
5055    Inner,
5056    Left,
5057    Right,
5058    Full,
5059    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5060    Cross,
5061    Natural,
5062    NaturalLeft,
5063    NaturalRight,
5064    NaturalFull,
5065    Semi,
5066    Anti,
5067    // Directional SEMI/ANTI joins
5068    LeftSemi,
5069    LeftAnti,
5070    RightSemi,
5071    RightAnti,
5072    // SQL Server specific
5073    CrossApply,
5074    OuterApply,
5075    // Time-series specific
5076    AsOf,
5077    AsOfLeft,
5078    AsOfRight,
5079    // Lateral join
5080    Lateral,
5081    LeftLateral,
5082    // MySQL specific
5083    Straight,
5084    // Implicit join (comma-separated tables: FROM a, b)
5085    Implicit,
5086    // ClickHouse ARRAY JOIN
5087    Array,
5088    LeftArray,
5089    // ClickHouse PASTE JOIN (positional join)
5090    Paste,
5091    // DuckDB POSITIONAL JOIN
5092    Positional,
5093}
5094
5095impl Default for JoinKind {
5096    fn default() -> Self {
5097        JoinKind::Inner
5098    }
5099}
5100
5101/// Parenthesized table expression with joins
5102/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5103#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5104#[cfg_attr(feature = "bindings", derive(TS))]
5105pub struct JoinedTable {
5106    /// The left-hand side table expression
5107    pub left: Expression,
5108    /// The joins applied to the left table
5109    pub joins: Vec<Join>,
5110    /// LATERAL VIEW clauses (Hive/Spark)
5111    pub lateral_views: Vec<LateralView>,
5112    /// Optional alias for the joined table expression
5113    pub alias: Option<Identifier>,
5114}
5115
5116/// Represent a WHERE clause containing a boolean filter predicate.
5117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5118#[cfg_attr(feature = "bindings", derive(TS))]
5119pub struct Where {
5120    /// The filter predicate expression.
5121    pub this: Expression,
5122}
5123
5124/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5125///
5126/// The `expressions` list may contain plain columns, ordinal positions,
5127/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5129#[cfg_attr(feature = "bindings", derive(TS))]
5130pub struct GroupBy {
5131    /// The grouping expressions.
5132    pub expressions: Vec<Expression>,
5133    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5134    #[serde(default)]
5135    pub all: Option<bool>,
5136    /// ClickHouse: WITH TOTALS modifier
5137    #[serde(default)]
5138    pub totals: bool,
5139    /// Leading comments that appeared before the GROUP BY keyword
5140    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5141    pub comments: Vec<String>,
5142}
5143
5144/// Represent a HAVING clause containing a predicate over aggregate results.
5145#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5146#[cfg_attr(feature = "bindings", derive(TS))]
5147pub struct Having {
5148    /// The filter predicate, typically involving aggregate functions.
5149    pub this: Expression,
5150    /// Leading comments that appeared before the HAVING keyword
5151    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5152    pub comments: Vec<String>,
5153}
5154
5155/// Represent an ORDER BY clause containing one or more sort specifications.
5156#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5157#[cfg_attr(feature = "bindings", derive(TS))]
5158pub struct OrderBy {
5159    /// The sort specifications, each with direction and null ordering.
5160    pub expressions: Vec<Ordered>,
5161    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5162    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5163    pub siblings: bool,
5164    /// Leading comments that appeared before the ORDER BY keyword
5165    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5166    pub comments: Vec<String>,
5167}
5168
5169/// Represent an expression with sort direction and null ordering.
5170///
5171/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5172/// When `desc` is false the sort is ascending. The `nulls_first` field
5173/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5174/// (database default).
5175#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5176#[cfg_attr(feature = "bindings", derive(TS))]
5177pub struct Ordered {
5178    /// The expression to sort by.
5179    pub this: Expression,
5180    /// Whether the sort direction is descending (true) or ascending (false).
5181    pub desc: bool,
5182    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5183    pub nulls_first: Option<bool>,
5184    /// Whether ASC was explicitly written (not just implied)
5185    #[serde(default)]
5186    pub explicit_asc: bool,
5187    /// ClickHouse WITH FILL clause
5188    #[serde(default, skip_serializing_if = "Option::is_none")]
5189    pub with_fill: Option<Box<WithFill>>,
5190}
5191
5192impl Ordered {
5193    pub fn asc(expr: Expression) -> Self {
5194        Self {
5195            this: expr,
5196            desc: false,
5197            nulls_first: None,
5198            explicit_asc: false,
5199            with_fill: None,
5200        }
5201    }
5202
5203    pub fn desc(expr: Expression) -> Self {
5204        Self {
5205            this: expr,
5206            desc: true,
5207            nulls_first: None,
5208            explicit_asc: false,
5209            with_fill: None,
5210        }
5211    }
5212}
5213
5214/// DISTRIBUTE BY clause (Hive/Spark)
5215/// Controls how rows are distributed across reducers
5216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5217#[cfg_attr(feature = "bindings", derive(TS))]
5218#[cfg_attr(feature = "bindings", ts(export))]
5219pub struct DistributeBy {
5220    pub expressions: Vec<Expression>,
5221}
5222
5223/// CLUSTER BY clause (Hive/Spark)
5224/// Combines DISTRIBUTE BY and SORT BY on the same columns
5225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5226#[cfg_attr(feature = "bindings", derive(TS))]
5227#[cfg_attr(feature = "bindings", ts(export))]
5228pub struct ClusterBy {
5229    pub expressions: Vec<Ordered>,
5230}
5231
5232/// SORT BY clause (Hive/Spark)
5233/// Sorts data within each reducer (local sort, not global)
5234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5235#[cfg_attr(feature = "bindings", derive(TS))]
5236#[cfg_attr(feature = "bindings", ts(export))]
5237pub struct SortBy {
5238    pub expressions: Vec<Ordered>,
5239}
5240
5241/// LATERAL VIEW clause (Hive/Spark)
5242/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5243#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5244#[cfg_attr(feature = "bindings", derive(TS))]
5245#[cfg_attr(feature = "bindings", ts(export))]
5246pub struct LateralView {
5247    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5248    pub this: Expression,
5249    /// Table alias for the generated table
5250    pub table_alias: Option<Identifier>,
5251    /// Column aliases for the generated columns
5252    pub column_aliases: Vec<Identifier>,
5253    /// OUTER keyword - preserve nulls when input is empty/null
5254    pub outer: bool,
5255}
5256
5257/// Query hint
5258#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5259#[cfg_attr(feature = "bindings", derive(TS))]
5260#[cfg_attr(feature = "bindings", ts(export))]
5261pub struct Hint {
5262    pub expressions: Vec<HintExpression>,
5263}
5264
5265/// Individual hint expression
5266#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5267#[cfg_attr(feature = "bindings", derive(TS))]
5268#[cfg_attr(feature = "bindings", ts(export))]
5269pub enum HintExpression {
5270    /// Function-style hint: USE_HASH(table)
5271    Function { name: String, args: Vec<Expression> },
5272    /// Simple identifier hint: PARALLEL
5273    Identifier(String),
5274    /// Raw hint text (unparsed)
5275    Raw(String),
5276}
5277
5278/// Pseudocolumn type
5279#[derive(
5280    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5281)]
5282#[cfg_attr(feature = "bindings", derive(TS))]
5283#[cfg_attr(feature = "bindings", ts(export))]
5284pub enum PseudocolumnType {
5285    Rownum,      // Oracle ROWNUM
5286    Rowid,       // Oracle ROWID
5287    Level,       // Oracle LEVEL (for CONNECT BY)
5288    Sysdate,     // Oracle SYSDATE
5289    ObjectId,    // Oracle OBJECT_ID
5290    ObjectValue, // Oracle OBJECT_VALUE
5291}
5292
5293impl PseudocolumnType {
5294    pub fn as_str(&self) -> &'static str {
5295        match self {
5296            PseudocolumnType::Rownum => "ROWNUM",
5297            PseudocolumnType::Rowid => "ROWID",
5298            PseudocolumnType::Level => "LEVEL",
5299            PseudocolumnType::Sysdate => "SYSDATE",
5300            PseudocolumnType::ObjectId => "OBJECT_ID",
5301            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5302        }
5303    }
5304
5305    pub fn from_str(s: &str) -> Option<Self> {
5306        match s.to_uppercase().as_str() {
5307            "ROWNUM" => Some(PseudocolumnType::Rownum),
5308            "ROWID" => Some(PseudocolumnType::Rowid),
5309            "LEVEL" => Some(PseudocolumnType::Level),
5310            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5311            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5312            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5313            _ => None,
5314        }
5315    }
5316}
5317
5318/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5319/// These are special identifiers that should not be quoted
5320#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5321#[cfg_attr(feature = "bindings", derive(TS))]
5322#[cfg_attr(feature = "bindings", ts(export))]
5323pub struct Pseudocolumn {
5324    pub kind: PseudocolumnType,
5325}
5326
5327impl Pseudocolumn {
5328    pub fn rownum() -> Self {
5329        Self {
5330            kind: PseudocolumnType::Rownum,
5331        }
5332    }
5333
5334    pub fn rowid() -> Self {
5335        Self {
5336            kind: PseudocolumnType::Rowid,
5337        }
5338    }
5339
5340    pub fn level() -> Self {
5341        Self {
5342            kind: PseudocolumnType::Level,
5343        }
5344    }
5345}
5346
5347/// Oracle CONNECT BY clause for hierarchical queries
5348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5349#[cfg_attr(feature = "bindings", derive(TS))]
5350#[cfg_attr(feature = "bindings", ts(export))]
5351pub struct Connect {
5352    /// START WITH condition (optional, can come before or after CONNECT BY)
5353    pub start: Option<Expression>,
5354    /// CONNECT BY condition (required, contains PRIOR references)
5355    pub connect: Expression,
5356    /// NOCYCLE keyword to prevent infinite loops
5357    pub nocycle: bool,
5358}
5359
5360/// Oracle PRIOR expression - references parent row's value in CONNECT BY
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 Prior {
5365    pub this: Expression,
5366}
5367
5368/// Oracle CONNECT_BY_ROOT function - returns root row's column value
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 ConnectByRoot {
5373    pub this: Expression,
5374}
5375
5376/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5377#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5378#[cfg_attr(feature = "bindings", derive(TS))]
5379#[cfg_attr(feature = "bindings", ts(export))]
5380pub struct MatchRecognize {
5381    /// Source table/expression
5382    pub this: Option<Box<Expression>>,
5383    /// PARTITION BY expressions
5384    pub partition_by: Option<Vec<Expression>>,
5385    /// ORDER BY expressions
5386    pub order_by: Option<Vec<Ordered>>,
5387    /// MEASURES definitions
5388    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5389    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5390    pub rows: Option<MatchRecognizeRows>,
5391    /// AFTER MATCH SKIP behavior
5392    pub after: Option<MatchRecognizeAfter>,
5393    /// PATTERN definition (stored as raw string for complex regex patterns)
5394    pub pattern: Option<String>,
5395    /// DEFINE clauses (pattern variable definitions)
5396    pub define: Option<Vec<(Identifier, Expression)>>,
5397    /// Optional alias for the result
5398    pub alias: Option<Identifier>,
5399    /// Whether AS keyword was explicitly present before alias
5400    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5401    pub alias_explicit_as: bool,
5402}
5403
5404/// MEASURES expression with optional RUNNING/FINAL semantics
5405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5406#[cfg_attr(feature = "bindings", derive(TS))]
5407#[cfg_attr(feature = "bindings", ts(export))]
5408pub struct MatchRecognizeMeasure {
5409    /// The measure expression
5410    pub this: Expression,
5411    /// RUNNING or FINAL semantics (Snowflake-specific)
5412    pub window_frame: Option<MatchRecognizeSemantics>,
5413}
5414
5415/// Semantics for MEASURES in MATCH_RECOGNIZE
5416#[derive(
5417    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5418)]
5419#[cfg_attr(feature = "bindings", derive(TS))]
5420#[cfg_attr(feature = "bindings", ts(export))]
5421pub enum MatchRecognizeSemantics {
5422    Running,
5423    Final,
5424}
5425
5426/// Row output semantics for MATCH_RECOGNIZE
5427#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5428#[cfg_attr(feature = "bindings", derive(TS))]
5429#[cfg_attr(feature = "bindings", ts(export))]
5430pub enum MatchRecognizeRows {
5431    OneRowPerMatch,
5432    AllRowsPerMatch,
5433    AllRowsPerMatchShowEmptyMatches,
5434    AllRowsPerMatchOmitEmptyMatches,
5435    AllRowsPerMatchWithUnmatchedRows,
5436}
5437
5438/// AFTER MATCH SKIP behavior
5439#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5440#[cfg_attr(feature = "bindings", derive(TS))]
5441#[cfg_attr(feature = "bindings", ts(export))]
5442pub enum MatchRecognizeAfter {
5443    PastLastRow,
5444    ToNextRow,
5445    ToFirst(Identifier),
5446    ToLast(Identifier),
5447}
5448
5449/// Represent a LIMIT clause that restricts the number of returned rows.
5450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5451#[cfg_attr(feature = "bindings", derive(TS))]
5452pub struct Limit {
5453    /// The limit count expression.
5454    pub this: Expression,
5455    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5456    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5457    pub percent: bool,
5458    /// Comments from before the LIMIT keyword (emitted after the limit value)
5459    #[serde(default)]
5460    #[serde(skip_serializing_if = "Vec::is_empty")]
5461    pub comments: Vec<String>,
5462}
5463
5464/// OFFSET clause
5465#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5466#[cfg_attr(feature = "bindings", derive(TS))]
5467pub struct Offset {
5468    pub this: Expression,
5469    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5470    #[serde(skip_serializing_if = "Option::is_none", default)]
5471    pub rows: Option<bool>,
5472}
5473
5474/// TOP clause (SQL Server)
5475#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5476#[cfg_attr(feature = "bindings", derive(TS))]
5477pub struct Top {
5478    pub this: Expression,
5479    pub percent: bool,
5480    pub with_ties: bool,
5481    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5482    #[serde(default)]
5483    pub parenthesized: bool,
5484}
5485
5486/// FETCH FIRST/NEXT clause (SQL standard)
5487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5488#[cfg_attr(feature = "bindings", derive(TS))]
5489pub struct Fetch {
5490    /// FIRST or NEXT
5491    pub direction: String,
5492    /// Count expression (optional)
5493    pub count: Option<Expression>,
5494    /// PERCENT modifier
5495    pub percent: bool,
5496    /// ROWS or ROW keyword present
5497    pub rows: bool,
5498    /// WITH TIES modifier
5499    pub with_ties: bool,
5500}
5501
5502/// Represent a QUALIFY clause for filtering on window function results.
5503///
5504/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5505/// typically references a window function (e.g.
5506/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5508#[cfg_attr(feature = "bindings", derive(TS))]
5509pub struct Qualify {
5510    /// The filter predicate over window function results.
5511    pub this: Expression,
5512}
5513
5514/// SAMPLE / TABLESAMPLE clause
5515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5516#[cfg_attr(feature = "bindings", derive(TS))]
5517pub struct Sample {
5518    pub method: SampleMethod,
5519    pub size: Expression,
5520    pub seed: Option<Expression>,
5521    /// ClickHouse OFFSET expression after SAMPLE size
5522    #[serde(default)]
5523    pub offset: Option<Expression>,
5524    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5525    pub unit_after_size: bool,
5526    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5527    #[serde(default)]
5528    pub use_sample_keyword: bool,
5529    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5530    #[serde(default)]
5531    pub explicit_method: bool,
5532    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5533    #[serde(default)]
5534    pub method_before_size: bool,
5535    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5536    #[serde(default)]
5537    pub use_seed_keyword: bool,
5538    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5539    pub bucket_numerator: Option<Box<Expression>>,
5540    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5541    pub bucket_denominator: Option<Box<Expression>>,
5542    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5543    pub bucket_field: Option<Box<Expression>>,
5544    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5545    #[serde(default)]
5546    pub is_using_sample: bool,
5547    /// Whether the unit was explicitly PERCENT (vs ROWS)
5548    #[serde(default)]
5549    pub is_percent: bool,
5550    /// Whether to suppress method output (for cross-dialect transpilation)
5551    #[serde(default)]
5552    pub suppress_method_output: bool,
5553}
5554
5555/// Sample method
5556#[derive(
5557    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5558)]
5559#[cfg_attr(feature = "bindings", derive(TS))]
5560pub enum SampleMethod {
5561    Bernoulli,
5562    System,
5563    Block,
5564    Row,
5565    Percent,
5566    /// Hive bucket sampling
5567    Bucket,
5568    /// DuckDB reservoir sampling
5569    Reservoir,
5570}
5571
5572/// Named window definition (WINDOW w AS (...))
5573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5574#[cfg_attr(feature = "bindings", derive(TS))]
5575pub struct NamedWindow {
5576    pub name: Identifier,
5577    pub spec: Over,
5578}
5579
5580/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5581///
5582/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5583/// that reference themselves. Each CTE is defined in the `ctes` vector and
5584/// can be referenced by name in subsequent CTEs and in the main query body.
5585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5586#[cfg_attr(feature = "bindings", derive(TS))]
5587pub struct With {
5588    /// The list of CTE definitions, in order.
5589    pub ctes: Vec<Cte>,
5590    /// Whether the WITH RECURSIVE keyword was used.
5591    pub recursive: bool,
5592    /// Leading comments before the statement
5593    #[serde(default)]
5594    pub leading_comments: Vec<String>,
5595    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5596    #[serde(default, skip_serializing_if = "Option::is_none")]
5597    pub search: Option<Box<Expression>>,
5598}
5599
5600/// Represent a single Common Table Expression definition.
5601///
5602/// A CTE has a name (`alias`), an optional column list, and a body query.
5603/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5604/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5605/// the expression comes before the alias (`alias_first`).
5606#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5607#[cfg_attr(feature = "bindings", derive(TS))]
5608pub struct Cte {
5609    /// The CTE name.
5610    pub alias: Identifier,
5611    /// The CTE body (typically a SELECT, UNION, etc.).
5612    pub this: Expression,
5613    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5614    pub columns: Vec<Identifier>,
5615    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5616    pub materialized: Option<bool>,
5617    /// USING KEY (columns) for DuckDB recursive CTEs
5618    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5619    pub key_expressions: Vec<Identifier>,
5620    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5621    #[serde(default)]
5622    pub alias_first: bool,
5623    /// Comments associated with this CTE (placed after alias name, before AS)
5624    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5625    pub comments: Vec<String>,
5626}
5627
5628/// Window specification
5629#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5630#[cfg_attr(feature = "bindings", derive(TS))]
5631pub struct WindowSpec {
5632    pub partition_by: Vec<Expression>,
5633    pub order_by: Vec<Ordered>,
5634    pub frame: Option<WindowFrame>,
5635}
5636
5637/// OVER clause
5638#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5639#[cfg_attr(feature = "bindings", derive(TS))]
5640pub struct Over {
5641    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
5642    pub window_name: Option<Identifier>,
5643    pub partition_by: Vec<Expression>,
5644    pub order_by: Vec<Ordered>,
5645    pub frame: Option<WindowFrame>,
5646    pub alias: Option<Identifier>,
5647}
5648
5649/// Window frame
5650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5651#[cfg_attr(feature = "bindings", derive(TS))]
5652pub struct WindowFrame {
5653    pub kind: WindowFrameKind,
5654    pub start: WindowFrameBound,
5655    pub end: Option<WindowFrameBound>,
5656    pub exclude: Option<WindowFrameExclude>,
5657    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
5658    #[serde(default, skip_serializing_if = "Option::is_none")]
5659    pub kind_text: Option<String>,
5660    /// Original text of the start bound side keyword (e.g. "preceding")
5661    #[serde(default, skip_serializing_if = "Option::is_none")]
5662    pub start_side_text: Option<String>,
5663    /// Original text of the end bound side keyword
5664    #[serde(default, skip_serializing_if = "Option::is_none")]
5665    pub end_side_text: Option<String>,
5666}
5667
5668#[derive(
5669    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5670)]
5671#[cfg_attr(feature = "bindings", derive(TS))]
5672pub enum WindowFrameKind {
5673    Rows,
5674    Range,
5675    Groups,
5676}
5677
5678/// EXCLUDE clause for window frames
5679#[derive(
5680    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5681)]
5682#[cfg_attr(feature = "bindings", derive(TS))]
5683pub enum WindowFrameExclude {
5684    CurrentRow,
5685    Group,
5686    Ties,
5687    NoOthers,
5688}
5689
5690#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5691#[cfg_attr(feature = "bindings", derive(TS))]
5692pub enum WindowFrameBound {
5693    CurrentRow,
5694    UnboundedPreceding,
5695    UnboundedFollowing,
5696    Preceding(Box<Expression>),
5697    Following(Box<Expression>),
5698    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
5699    BarePreceding,
5700    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
5701    BareFollowing,
5702    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
5703    Value(Box<Expression>),
5704}
5705
5706/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
5707#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5708#[cfg_attr(feature = "bindings", derive(TS))]
5709pub struct StructField {
5710    pub name: String,
5711    pub data_type: DataType,
5712    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5713    pub options: Vec<Expression>,
5714    #[serde(default, skip_serializing_if = "Option::is_none")]
5715    pub comment: Option<String>,
5716}
5717
5718impl StructField {
5719    /// Create a new struct field without options
5720    pub fn new(name: String, data_type: DataType) -> Self {
5721        Self {
5722            name,
5723            data_type,
5724            options: Vec::new(),
5725            comment: None,
5726        }
5727    }
5728
5729    /// Create a new struct field with options
5730    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
5731        Self {
5732            name,
5733            data_type,
5734            options,
5735            comment: None,
5736        }
5737    }
5738
5739    /// Create a new struct field with options and comment
5740    pub fn with_options_and_comment(
5741        name: String,
5742        data_type: DataType,
5743        options: Vec<Expression>,
5744        comment: Option<String>,
5745    ) -> Self {
5746        Self {
5747            name,
5748            data_type,
5749            options,
5750            comment,
5751        }
5752    }
5753}
5754
5755/// Oracle-specific data types whose semantics cannot be represented losslessly by the
5756/// generic [`DataType`] variants.
5757///
5758/// Keeping these types structured allows the Oracle parser to retain details such as a
5759/// negative `NUMBER` scale, `BYTE`/`CHAR` length semantics, interval precisions, and
5760/// `TIMESTAMP WITH LOCAL TIME ZONE` until the target dialect is known.
5761#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5762#[cfg_attr(feature = "bindings", derive(TS))]
5763#[serde(tag = "oracle_data_type", rename_all = "snake_case")]
5764pub enum OracleDataType {
5765    Number {
5766        precision: Option<u32>,
5767        scale: Option<i32>,
5768    },
5769    BinaryFloat,
5770    BinaryDouble,
5771    Float {
5772        precision: Option<u32>,
5773    },
5774    Character {
5775        kind: OracleCharacterKind,
5776        length: Option<u32>,
5777        semantics: Option<OracleCharacterLengthSemantics>,
5778    },
5779    Date,
5780    Timestamp {
5781        precision: Option<u32>,
5782        timezone: OracleTimestampTimeZone,
5783    },
5784    IntervalYearToMonth {
5785        year_precision: Option<u32>,
5786    },
5787    IntervalDayToSecond {
5788        day_precision: Option<u32>,
5789        fractional_seconds_precision: Option<u32>,
5790    },
5791    Clob {
5792        national: bool,
5793    },
5794    Blob,
5795    Raw {
5796        length: Option<u32>,
5797    },
5798    Long {
5799        raw: bool,
5800    },
5801    RowId,
5802}
5803
5804#[derive(
5805    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5806)]
5807#[cfg_attr(feature = "bindings", derive(TS))]
5808#[serde(rename_all = "snake_case")]
5809pub enum OracleCharacterKind {
5810    Char,
5811    VarChar,
5812    NChar,
5813    NVarChar,
5814}
5815
5816#[derive(
5817    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5818)]
5819#[cfg_attr(feature = "bindings", derive(TS))]
5820#[serde(rename_all = "snake_case")]
5821pub enum OracleCharacterLengthSemantics {
5822    Byte,
5823    Char,
5824}
5825
5826#[derive(
5827    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5828)]
5829#[cfg_attr(feature = "bindings", derive(TS))]
5830#[serde(rename_all = "snake_case")]
5831pub enum OracleTimestampTimeZone {
5832    None,
5833    WithTimeZone,
5834    WithLocalTimeZone,
5835}
5836
5837/// Enumerate all SQL data types recognized by the parser.
5838///
5839/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
5840/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
5841/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
5842///
5843/// This enum is used in CAST expressions, column definitions, function return
5844/// types, and anywhere a data type specification appears in SQL.
5845///
5846/// Types that do not match any known variant fall through to `Custom { name }`,
5847/// preserving the original type name for round-trip fidelity.
5848#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5849#[cfg_attr(feature = "bindings", derive(TS))]
5850#[serde(tag = "data_type", rename_all = "snake_case")]
5851pub enum DataType {
5852    // Numeric
5853    Boolean,
5854    TinyInt {
5855        length: Option<u32>,
5856    },
5857    SmallInt {
5858        length: Option<u32>,
5859    },
5860    /// Int type with optional length. `integer_spelling` indicates whether the original
5861    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
5862    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
5863    Int {
5864        length: Option<u32>,
5865        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5866        integer_spelling: bool,
5867    },
5868    BigInt {
5869        length: Option<u32>,
5870    },
5871    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
5872    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
5873    /// preserve the original spelling.
5874    Float {
5875        precision: Option<u32>,
5876        scale: Option<u32>,
5877        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5878        real_spelling: bool,
5879    },
5880    Double {
5881        precision: Option<u32>,
5882        scale: Option<u32>,
5883    },
5884    Decimal {
5885        precision: Option<u32>,
5886        scale: Option<u32>,
5887    },
5888    /// Structured Oracle data type retained until the target dialect is known.
5889    Oracle {
5890        oracle_type: OracleDataType,
5891    },
5892
5893    // String
5894    Char {
5895        length: Option<u32>,
5896    },
5897    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
5898    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
5899    VarChar {
5900        length: Option<u32>,
5901        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5902        parenthesized_length: bool,
5903    },
5904    /// String type with optional max length (BigQuery STRING(n))
5905    String {
5906        length: Option<u32>,
5907    },
5908    Text,
5909    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
5910    TextWithLength {
5911        length: u32,
5912    },
5913
5914    // Binary
5915    Binary {
5916        length: Option<u32>,
5917    },
5918    VarBinary {
5919        length: Option<u32>,
5920    },
5921    Blob,
5922
5923    // Bit
5924    Bit {
5925        length: Option<u32>,
5926    },
5927    VarBit {
5928        length: Option<u32>,
5929    },
5930
5931    // Date/Time
5932    Date,
5933    Time {
5934        precision: Option<u32>,
5935        #[serde(default)]
5936        timezone: bool,
5937    },
5938    Timestamp {
5939        precision: Option<u32>,
5940        timezone: bool,
5941    },
5942    Interval {
5943        unit: Option<String>,
5944        /// For range intervals like INTERVAL DAY TO HOUR
5945        #[serde(default, skip_serializing_if = "Option::is_none")]
5946        to: Option<String>,
5947    },
5948
5949    // JSON
5950    Json,
5951    JsonB,
5952
5953    // UUID
5954    Uuid,
5955
5956    // Array
5957    Array {
5958        element_type: Box<DataType>,
5959        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
5960        #[serde(default, skip_serializing_if = "Option::is_none")]
5961        dimension: Option<u32>,
5962    },
5963
5964    /// List type (Materialize): INT LIST, TEXT LIST LIST
5965    /// Uses postfix LIST syntax instead of ARRAY<T>
5966    List {
5967        element_type: Box<DataType>,
5968    },
5969
5970    // Struct/Map
5971    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
5972    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
5973    Struct {
5974        fields: Vec<StructField>,
5975        nested: bool,
5976    },
5977    Map {
5978        key_type: Box<DataType>,
5979        value_type: Box<DataType>,
5980    },
5981
5982    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
5983    Enum {
5984        values: Vec<String>,
5985        #[serde(default, skip_serializing_if = "Vec::is_empty")]
5986        assignments: Vec<Option<String>>,
5987    },
5988
5989    // Set type (MySQL): SET('a', 'b', 'c')
5990    Set {
5991        values: Vec<String>,
5992    },
5993
5994    // Union type (DuckDB): UNION(num INT, str TEXT)
5995    Union {
5996        fields: Vec<(String, DataType)>,
5997    },
5998
5999    // Vector (Snowflake / SingleStore)
6000    Vector {
6001        #[serde(default)]
6002        element_type: Option<Box<DataType>>,
6003        dimension: Option<u32>,
6004    },
6005
6006    // Object (Snowflake structured type)
6007    // fields: Vec of (field_name, field_type, not_null)
6008    Object {
6009        fields: Vec<(String, DataType, bool)>,
6010        modifier: Option<String>,
6011    },
6012
6013    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
6014    Nullable {
6015        inner: Box<DataType>,
6016    },
6017
6018    // Custom/User-defined
6019    Custom {
6020        name: String,
6021    },
6022
6023    // Spatial types
6024    Geometry {
6025        subtype: Option<String>,
6026        srid: Option<u32>,
6027    },
6028    Geography {
6029        subtype: Option<String>,
6030        srid: Option<u32>,
6031    },
6032
6033    // Character Set (for CONVERT USING in MySQL)
6034    // Renders as CHAR CHARACTER SET {name} in cast target
6035    CharacterSet {
6036        name: String,
6037    },
6038
6039    // Unknown
6040    Unknown,
6041}
6042
6043/// Array expression
6044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6045#[cfg_attr(feature = "bindings", derive(TS))]
6046#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
6047pub struct Array {
6048    pub expressions: Vec<Expression>,
6049}
6050
6051/// Struct expression
6052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6053#[cfg_attr(feature = "bindings", derive(TS))]
6054pub struct Struct {
6055    pub fields: Vec<(Option<String>, Expression)>,
6056}
6057
6058/// Tuple expression
6059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6060#[cfg_attr(feature = "bindings", derive(TS))]
6061pub struct Tuple {
6062    pub expressions: Vec<Expression>,
6063}
6064
6065/// Interval expression
6066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6067#[cfg_attr(feature = "bindings", derive(TS))]
6068pub struct Interval {
6069    /// The value expression (e.g., '1', 5, column_ref)
6070    pub this: Option<Expression>,
6071    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
6072    pub unit: Option<IntervalUnitSpec>,
6073}
6074
6075/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
6076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6077#[cfg_attr(feature = "bindings", derive(TS))]
6078#[serde(tag = "type", rename_all = "snake_case")]
6079pub enum IntervalUnitSpec {
6080    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
6081    Simple {
6082        unit: IntervalUnit,
6083        /// Whether to use plural form (e.g., DAYS vs DAY)
6084        use_plural: bool,
6085    },
6086    /// Interval span (e.g., HOUR TO SECOND)
6087    Span(IntervalSpan),
6088    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6089    /// The start and end can be expressions like function calls with precision
6090    ExprSpan(IntervalSpanExpr),
6091    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6092    Expr(Box<Expression>),
6093}
6094
6095/// Interval span for ranges like HOUR TO SECOND
6096#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6097#[cfg_attr(feature = "bindings", derive(TS))]
6098pub struct IntervalSpan {
6099    /// Start unit (e.g., HOUR)
6100    pub this: IntervalUnit,
6101    /// End unit (e.g., SECOND)
6102    pub expression: IntervalUnit,
6103}
6104
6105/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6106/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6107#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6108#[cfg_attr(feature = "bindings", derive(TS))]
6109pub struct IntervalSpanExpr {
6110    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6111    pub this: Box<Expression>,
6112    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6113    pub expression: Box<Expression>,
6114}
6115
6116#[derive(
6117    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6118)]
6119#[cfg_attr(feature = "bindings", derive(TS))]
6120pub enum IntervalUnit {
6121    Year,
6122    Quarter,
6123    Month,
6124    Week,
6125    Day,
6126    Hour,
6127    Minute,
6128    Second,
6129    Millisecond,
6130    Microsecond,
6131    Nanosecond,
6132}
6133
6134/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6136#[cfg_attr(feature = "bindings", derive(TS))]
6137pub struct Command {
6138    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6139    pub this: String,
6140}
6141
6142/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6143/// Syntax: PREPARE name [(type, ...)] AS statement
6144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6145#[cfg_attr(feature = "bindings", derive(TS))]
6146pub struct PrepareStatement {
6147    /// The prepared statement name.
6148    pub name: Identifier,
6149    /// Optional PostgreSQL parameter type list.
6150    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6151    pub parameter_types: Vec<DataType>,
6152    /// The statement to execute when the prepared statement is invoked.
6153    pub statement: Expression,
6154}
6155
6156/// T-SQL TRY/CATCH block.
6157#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6158#[cfg_attr(feature = "bindings", derive(TS))]
6159pub struct TryCatch {
6160    /// Statements inside BEGIN TRY ... END TRY.
6161    #[serde(default)]
6162    pub try_body: Vec<Expression>,
6163    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6164    #[serde(default, skip_serializing_if = "Option::is_none")]
6165    pub catch_body: Option<Vec<Expression>>,
6166}
6167
6168/// EXEC/EXECUTE statement (TSQL stored procedure call)
6169/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6171#[cfg_attr(feature = "bindings", derive(TS))]
6172pub struct ExecuteStatement {
6173    /// The procedure name (can be qualified: schema.proc_name)
6174    pub this: Expression,
6175    /// Named parameters: @param=value pairs
6176    #[serde(default)]
6177    pub parameters: Vec<ExecuteParameter>,
6178    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6179    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6180    pub arguments: Vec<Expression>,
6181    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6182    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6183    pub prepared: bool,
6184    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6185    #[serde(default, skip_serializing_if = "Option::is_none")]
6186    pub suffix: Option<String>,
6187}
6188
6189/// Named parameter in EXEC statement: @name=value
6190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6191#[cfg_attr(feature = "bindings", derive(TS))]
6192pub struct ExecuteParameter {
6193    /// Parameter name (including @)
6194    pub name: String,
6195    /// Parameter value
6196    pub value: Expression,
6197    /// Whether this is a positional parameter (no = sign)
6198    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6199    pub positional: bool,
6200    /// TSQL OUTPUT modifier on parameter
6201    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6202    pub output: bool,
6203}
6204
6205/// KILL statement (MySQL/MariaDB)
6206/// KILL [CONNECTION | QUERY] <id>
6207#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6208#[cfg_attr(feature = "bindings", derive(TS))]
6209pub struct Kill {
6210    /// The target (process ID or connection ID)
6211    pub this: Expression,
6212    /// Optional kind: "CONNECTION" or "QUERY"
6213    pub kind: Option<String>,
6214}
6215
6216/// Snowflake CREATE TASK statement
6217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6218#[cfg_attr(feature = "bindings", derive(TS))]
6219pub struct CreateTask {
6220    pub or_replace: bool,
6221    pub if_not_exists: bool,
6222    /// Task name (possibly qualified: db.schema.task)
6223    pub name: String,
6224    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6225    pub properties: String,
6226    /// The SQL statement body after AS
6227    pub body: Expression,
6228}
6229
6230/// Raw/unparsed SQL
6231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6232#[cfg_attr(feature = "bindings", derive(TS))]
6233pub struct Raw {
6234    pub sql: String,
6235}
6236
6237// ============================================================================
6238// Function expression types
6239// ============================================================================
6240
6241/// Generic unary function (takes a single argument)
6242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6243#[cfg_attr(feature = "bindings", derive(TS))]
6244pub struct UnaryFunc {
6245    pub this: Expression,
6246    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6247    #[serde(skip_serializing_if = "Option::is_none", default)]
6248    pub original_name: Option<String>,
6249    /// Inferred data type from type annotation
6250    #[serde(default, skip_serializing_if = "Option::is_none")]
6251    #[ast(skip)]
6252    pub inferred_type: Option<DataType>,
6253}
6254
6255impl UnaryFunc {
6256    /// Create a new UnaryFunc with no original_name
6257    pub fn new(this: Expression) -> Self {
6258        Self {
6259            this,
6260            original_name: None,
6261            inferred_type: None,
6262        }
6263    }
6264
6265    /// Create a new UnaryFunc with an original name for round-trip preservation
6266    pub fn with_name(this: Expression, name: String) -> Self {
6267        Self {
6268            this,
6269            original_name: Some(name),
6270            inferred_type: None,
6271        }
6272    }
6273}
6274
6275/// CHAR/CHR function with multiple args and optional USING charset
6276/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6277/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6279#[cfg_attr(feature = "bindings", derive(TS))]
6280pub struct CharFunc {
6281    pub args: Vec<Expression>,
6282    #[serde(skip_serializing_if = "Option::is_none", default)]
6283    pub charset: Option<String>,
6284    /// Original function name (CHAR or CHR), defaults to CHAR
6285    #[serde(skip_serializing_if = "Option::is_none", default)]
6286    pub name: Option<String>,
6287}
6288
6289/// Generic binary function (takes two arguments)
6290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6291#[cfg_attr(feature = "bindings", derive(TS))]
6292pub struct BinaryFunc {
6293    pub this: Expression,
6294    pub expression: Expression,
6295    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6296    #[serde(skip_serializing_if = "Option::is_none", default)]
6297    pub original_name: Option<String>,
6298    /// Inferred data type from type annotation
6299    #[serde(default, skip_serializing_if = "Option::is_none")]
6300    #[ast(skip)]
6301    pub inferred_type: Option<DataType>,
6302}
6303
6304/// Variable argument function
6305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6306#[cfg_attr(feature = "bindings", derive(TS))]
6307pub struct VarArgFunc {
6308    pub expressions: Vec<Expression>,
6309    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6310    #[serde(skip_serializing_if = "Option::is_none", default)]
6311    pub original_name: Option<String>,
6312    /// Inferred data type from type annotation
6313    #[serde(default, skip_serializing_if = "Option::is_none")]
6314    #[ast(skip)]
6315    pub inferred_type: Option<DataType>,
6316}
6317
6318/// CONCAT_WS function
6319#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6320#[cfg_attr(feature = "bindings", derive(TS))]
6321pub struct ConcatWs {
6322    pub separator: Expression,
6323    pub expressions: Vec<Expression>,
6324}
6325
6326/// SUBSTRING function
6327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6328#[cfg_attr(feature = "bindings", derive(TS))]
6329pub struct SubstringFunc {
6330    pub this: Expression,
6331    pub start: Expression,
6332    pub length: Option<Expression>,
6333    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6334    #[serde(default)]
6335    pub from_for_syntax: bool,
6336}
6337
6338/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6340#[cfg_attr(feature = "bindings", derive(TS))]
6341pub struct OverlayFunc {
6342    pub this: Expression,
6343    pub replacement: Expression,
6344    pub from: Expression,
6345    pub length: Option<Expression>,
6346}
6347
6348/// TRIM function
6349#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6350#[cfg_attr(feature = "bindings", derive(TS))]
6351pub struct TrimFunc {
6352    pub this: Expression,
6353    pub characters: Option<Expression>,
6354    pub position: TrimPosition,
6355    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6356    #[serde(default)]
6357    pub sql_standard_syntax: bool,
6358    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6359    #[serde(default)]
6360    pub position_explicit: bool,
6361}
6362
6363#[derive(
6364    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6365)]
6366#[cfg_attr(feature = "bindings", derive(TS))]
6367pub enum TrimPosition {
6368    Both,
6369    Leading,
6370    Trailing,
6371}
6372
6373/// REPLACE function
6374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6375#[cfg_attr(feature = "bindings", derive(TS))]
6376pub struct ReplaceFunc {
6377    pub this: Expression,
6378    pub old: Expression,
6379    pub new: Expression,
6380}
6381
6382/// LEFT/RIGHT function
6383#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6384#[cfg_attr(feature = "bindings", derive(TS))]
6385pub struct LeftRightFunc {
6386    pub this: Expression,
6387    pub length: Expression,
6388}
6389
6390/// REPEAT function
6391#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6392#[cfg_attr(feature = "bindings", derive(TS))]
6393pub struct RepeatFunc {
6394    pub this: Expression,
6395    pub times: Expression,
6396}
6397
6398/// LPAD/RPAD function
6399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6400#[cfg_attr(feature = "bindings", derive(TS))]
6401pub struct PadFunc {
6402    pub this: Expression,
6403    pub length: Expression,
6404    pub fill: Option<Expression>,
6405}
6406
6407/// SPLIT function
6408#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6409#[cfg_attr(feature = "bindings", derive(TS))]
6410pub struct SplitFunc {
6411    pub this: Expression,
6412    pub delimiter: Expression,
6413}
6414
6415/// REGEXP_LIKE function
6416#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6417#[cfg_attr(feature = "bindings", derive(TS))]
6418pub struct RegexpFunc {
6419    pub this: Expression,
6420    pub pattern: Expression,
6421    pub flags: Option<Expression>,
6422}
6423
6424/// REGEXP_REPLACE function
6425#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6426#[cfg_attr(feature = "bindings", derive(TS))]
6427pub struct RegexpReplaceFunc {
6428    pub this: Expression,
6429    pub pattern: Expression,
6430    pub replacement: Expression,
6431    pub flags: Option<Expression>,
6432}
6433
6434/// REGEXP_EXTRACT function
6435#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6436#[cfg_attr(feature = "bindings", derive(TS))]
6437pub struct RegexpExtractFunc {
6438    pub this: Expression,
6439    pub pattern: Expression,
6440    pub group: Option<Expression>,
6441}
6442
6443/// ROUND function
6444#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6445#[cfg_attr(feature = "bindings", derive(TS))]
6446pub struct RoundFunc {
6447    pub this: Expression,
6448    pub decimals: Option<Expression>,
6449}
6450
6451/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6453#[cfg_attr(feature = "bindings", derive(TS))]
6454pub struct FloorFunc {
6455    pub this: Expression,
6456    pub scale: Option<Expression>,
6457    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6458    #[serde(skip_serializing_if = "Option::is_none", default)]
6459    pub to: Option<Expression>,
6460}
6461
6462/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6463#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6464#[cfg_attr(feature = "bindings", derive(TS))]
6465pub struct CeilFunc {
6466    pub this: Expression,
6467    #[serde(skip_serializing_if = "Option::is_none", default)]
6468    pub decimals: Option<Expression>,
6469    /// Time unit for Druid-style CEIL(time TO unit) syntax
6470    #[serde(skip_serializing_if = "Option::is_none", default)]
6471    pub to: Option<Expression>,
6472}
6473
6474/// LOG function
6475#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6476#[cfg_attr(feature = "bindings", derive(TS))]
6477pub struct LogFunc {
6478    pub this: Expression,
6479    pub base: Option<Expression>,
6480}
6481
6482/// CURRENT_DATE (no arguments)
6483#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6484#[cfg_attr(feature = "bindings", derive(TS))]
6485pub struct CurrentDate;
6486
6487/// CURRENT_TIME
6488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6489#[cfg_attr(feature = "bindings", derive(TS))]
6490pub struct CurrentTime {
6491    pub precision: Option<u32>,
6492}
6493
6494/// CURRENT_TIMESTAMP
6495#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6496#[cfg_attr(feature = "bindings", derive(TS))]
6497pub struct CurrentTimestamp {
6498    pub precision: Option<u32>,
6499    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6500    #[serde(default)]
6501    pub sysdate: bool,
6502}
6503
6504/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6505#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6506#[cfg_attr(feature = "bindings", derive(TS))]
6507pub struct CurrentTimestampLTZ {
6508    pub precision: Option<u32>,
6509}
6510
6511/// AT TIME ZONE expression for timezone conversion
6512#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6513#[cfg_attr(feature = "bindings", derive(TS))]
6514pub struct AtTimeZone {
6515    /// The expression to convert
6516    pub this: Expression,
6517    /// The target timezone
6518    pub zone: Expression,
6519}
6520
6521/// DATE_ADD / DATE_SUB function
6522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6523#[cfg_attr(feature = "bindings", derive(TS))]
6524pub struct DateAddFunc {
6525    pub this: Expression,
6526    pub interval: Expression,
6527    pub unit: IntervalUnit,
6528}
6529
6530/// DATEDIFF function
6531#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6532#[cfg_attr(feature = "bindings", derive(TS))]
6533pub struct DateDiffFunc {
6534    pub this: Expression,
6535    pub expression: Expression,
6536    pub unit: Option<IntervalUnit>,
6537}
6538
6539/// DATE_TRUNC function
6540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6541#[cfg_attr(feature = "bindings", derive(TS))]
6542pub struct DateTruncFunc {
6543    pub this: Expression,
6544    pub unit: DateTimeField,
6545}
6546
6547/// EXTRACT function
6548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6549#[cfg_attr(feature = "bindings", derive(TS))]
6550pub struct ExtractFunc {
6551    pub this: Expression,
6552    pub field: DateTimeField,
6553}
6554
6555#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6556#[cfg_attr(feature = "bindings", derive(TS))]
6557pub enum DateTimeField {
6558    Year,
6559    Month,
6560    Day,
6561    Hour,
6562    Minute,
6563    Second,
6564    Millisecond,
6565    Microsecond,
6566    DayOfWeek,
6567    DayOfYear,
6568    Week,
6569    /// Week with a modifier like WEEK(monday), WEEK(sunday)
6570    WeekWithModifier(String),
6571    Quarter,
6572    Epoch,
6573    Timezone,
6574    TimezoneHour,
6575    TimezoneMinute,
6576    Date,
6577    Time,
6578    /// Custom datetime field for dialect-specific or arbitrary fields
6579    Custom(String),
6580}
6581
6582/// TO_DATE function
6583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6584#[cfg_attr(feature = "bindings", derive(TS))]
6585pub struct ToDateFunc {
6586    pub this: Expression,
6587    pub format: Option<Expression>,
6588}
6589
6590/// TO_TIMESTAMP function
6591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6592#[cfg_attr(feature = "bindings", derive(TS))]
6593pub struct ToTimestampFunc {
6594    pub this: Expression,
6595    pub format: Option<Expression>,
6596}
6597
6598/// IF function
6599#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6600#[cfg_attr(feature = "bindings", derive(TS))]
6601pub struct IfFunc {
6602    pub condition: Expression,
6603    pub true_value: Expression,
6604    pub false_value: Option<Expression>,
6605    /// Original function name (IF, IFF, IIF) for round-trip preservation
6606    #[serde(skip_serializing_if = "Option::is_none", default)]
6607    pub original_name: Option<String>,
6608    /// Inferred data type from type annotation
6609    #[serde(default, skip_serializing_if = "Option::is_none")]
6610    #[ast(skip)]
6611    pub inferred_type: Option<DataType>,
6612}
6613
6614/// NVL2 function
6615#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6616#[cfg_attr(feature = "bindings", derive(TS))]
6617pub struct Nvl2Func {
6618    pub this: Expression,
6619    pub true_value: Expression,
6620    pub false_value: Expression,
6621    /// Inferred data type from type annotation
6622    #[serde(default, skip_serializing_if = "Option::is_none")]
6623    #[ast(skip)]
6624    pub inferred_type: Option<DataType>,
6625}
6626
6627// ============================================================================
6628// Typed Aggregate Function types
6629// ============================================================================
6630
6631/// Generic aggregate function base type
6632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6633#[cfg_attr(feature = "bindings", derive(TS))]
6634pub struct AggFunc {
6635    pub this: Expression,
6636    pub distinct: bool,
6637    pub filter: Option<Expression>,
6638    pub order_by: Vec<Ordered>,
6639    /// Original function name (case-preserving) when parsed from SQL
6640    #[serde(skip_serializing_if = "Option::is_none", default)]
6641    pub name: Option<String>,
6642    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
6643    #[serde(skip_serializing_if = "Option::is_none", default)]
6644    pub ignore_nulls: Option<bool>,
6645    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
6646    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
6647    #[serde(skip_serializing_if = "Option::is_none", default)]
6648    pub having_max: Option<(Box<Expression>, bool)>,
6649    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
6650    #[serde(skip_serializing_if = "Option::is_none", default)]
6651    pub limit: Option<Box<Expression>>,
6652    /// Inferred data type from type annotation
6653    #[serde(default, skip_serializing_if = "Option::is_none")]
6654    #[ast(skip)]
6655    pub inferred_type: Option<DataType>,
6656}
6657
6658/// COUNT function with optional star
6659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6660#[cfg_attr(feature = "bindings", derive(TS))]
6661pub struct CountFunc {
6662    pub this: Option<Expression>,
6663    pub star: bool,
6664    pub distinct: bool,
6665    pub filter: Option<Expression>,
6666    /// IGNORE NULLS (true) or RESPECT NULLS (false)
6667    #[serde(default, skip_serializing_if = "Option::is_none")]
6668    pub ignore_nulls: Option<bool>,
6669    /// Original function name for case preservation (e.g., "count" or "COUNT")
6670    #[serde(default, skip_serializing_if = "Option::is_none")]
6671    pub original_name: Option<String>,
6672    /// Inferred data type from type annotation
6673    #[serde(default, skip_serializing_if = "Option::is_none")]
6674    #[ast(skip)]
6675    pub inferred_type: Option<DataType>,
6676}
6677
6678/// GROUP_CONCAT function (MySQL style)
6679#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6680#[cfg_attr(feature = "bindings", derive(TS))]
6681pub struct GroupConcatFunc {
6682    pub this: Expression,
6683    pub separator: Option<Expression>,
6684    pub order_by: Option<Vec<Ordered>>,
6685    pub distinct: bool,
6686    pub filter: Option<Expression>,
6687    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
6688    #[serde(default, skip_serializing_if = "Option::is_none")]
6689    pub limit: Option<Box<Expression>>,
6690    /// Inferred data type from type annotation
6691    #[serde(default, skip_serializing_if = "Option::is_none")]
6692    #[ast(skip)]
6693    pub inferred_type: Option<DataType>,
6694}
6695
6696/// STRING_AGG function (PostgreSQL/Standard SQL)
6697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6698#[cfg_attr(feature = "bindings", derive(TS))]
6699pub struct StringAggFunc {
6700    pub this: Expression,
6701    #[serde(default)]
6702    pub separator: Option<Expression>,
6703    #[serde(default)]
6704    pub order_by: Option<Vec<Ordered>>,
6705    #[serde(default)]
6706    pub distinct: bool,
6707    #[serde(default)]
6708    pub filter: Option<Expression>,
6709    /// BigQuery LIMIT inside STRING_AGG
6710    #[serde(default, skip_serializing_if = "Option::is_none")]
6711    pub limit: Option<Box<Expression>>,
6712    /// Inferred data type from type annotation
6713    #[serde(default, skip_serializing_if = "Option::is_none")]
6714    #[ast(skip)]
6715    pub inferred_type: Option<DataType>,
6716}
6717
6718/// LISTAGG function (Oracle style)
6719#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6720#[cfg_attr(feature = "bindings", derive(TS))]
6721pub struct ListAggFunc {
6722    pub this: Expression,
6723    pub separator: Option<Expression>,
6724    pub on_overflow: Option<ListAggOverflow>,
6725    pub order_by: Option<Vec<Ordered>>,
6726    pub distinct: bool,
6727    pub filter: Option<Expression>,
6728    /// Inferred data type from type annotation
6729    #[serde(default, skip_serializing_if = "Option::is_none")]
6730    #[ast(skip)]
6731    pub inferred_type: Option<DataType>,
6732}
6733
6734/// LISTAGG ON OVERFLOW behavior
6735#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6736#[cfg_attr(feature = "bindings", derive(TS))]
6737pub enum ListAggOverflow {
6738    Error,
6739    Truncate {
6740        filler: Option<Expression>,
6741        with_count: bool,
6742    },
6743}
6744
6745/// SUM_IF / COUNT_IF function
6746#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6747#[cfg_attr(feature = "bindings", derive(TS))]
6748pub struct SumIfFunc {
6749    pub this: Expression,
6750    pub condition: Expression,
6751    pub filter: Option<Expression>,
6752    /// Inferred data type from type annotation
6753    #[serde(default, skip_serializing_if = "Option::is_none")]
6754    #[ast(skip)]
6755    pub inferred_type: Option<DataType>,
6756}
6757
6758/// APPROX_PERCENTILE function
6759#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6760#[cfg_attr(feature = "bindings", derive(TS))]
6761pub struct ApproxPercentileFunc {
6762    pub this: Expression,
6763    pub percentile: Expression,
6764    pub accuracy: Option<Expression>,
6765    pub filter: Option<Expression>,
6766}
6767
6768/// PERCENTILE_CONT / PERCENTILE_DISC function
6769#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6770#[cfg_attr(feature = "bindings", derive(TS))]
6771pub struct PercentileFunc {
6772    pub this: Expression,
6773    pub percentile: Expression,
6774    pub order_by: Option<Vec<Ordered>>,
6775    pub filter: Option<Expression>,
6776}
6777
6778// ============================================================================
6779// Typed Window Function types
6780// ============================================================================
6781
6782/// ROW_NUMBER function (no arguments)
6783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6784#[cfg_attr(feature = "bindings", derive(TS))]
6785pub struct RowNumber;
6786
6787/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6789#[cfg_attr(feature = "bindings", derive(TS))]
6790pub struct Rank {
6791    /// DuckDB: RANK(ORDER BY col) - order by inside function
6792    #[serde(default, skip_serializing_if = "Option::is_none")]
6793    pub order_by: Option<Vec<Ordered>>,
6794    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6795    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6796    pub args: Vec<Expression>,
6797}
6798
6799/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
6800#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6801#[cfg_attr(feature = "bindings", derive(TS))]
6802pub struct DenseRank {
6803    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6804    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6805    pub args: Vec<Expression>,
6806}
6807
6808/// NTILE function (DuckDB allows ORDER BY inside)
6809#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6810#[cfg_attr(feature = "bindings", derive(TS))]
6811pub struct NTileFunc {
6812    /// num_buckets is optional to support Databricks NTILE() without arguments
6813    #[serde(default, skip_serializing_if = "Option::is_none")]
6814    pub num_buckets: Option<Expression>,
6815    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
6816    #[serde(default, skip_serializing_if = "Option::is_none")]
6817    pub order_by: Option<Vec<Ordered>>,
6818}
6819
6820/// LEAD / LAG function
6821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6822#[cfg_attr(feature = "bindings", derive(TS))]
6823pub struct LeadLagFunc {
6824    pub this: Expression,
6825    pub offset: Option<Expression>,
6826    pub default: Option<Expression>,
6827    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6828    #[serde(default, skip_serializing_if = "Option::is_none")]
6829    pub ignore_nulls: Option<bool>,
6830}
6831
6832/// FIRST_VALUE / LAST_VALUE function
6833#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6834#[cfg_attr(feature = "bindings", derive(TS))]
6835pub struct ValueFunc {
6836    pub this: Expression,
6837    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6838    #[serde(default, skip_serializing_if = "Option::is_none")]
6839    pub ignore_nulls: Option<bool>,
6840    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
6841    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6842    pub order_by: Vec<Ordered>,
6843}
6844
6845/// NTH_VALUE function
6846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6847#[cfg_attr(feature = "bindings", derive(TS))]
6848pub struct NthValueFunc {
6849    pub this: Expression,
6850    pub offset: Expression,
6851    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6852    #[serde(default, skip_serializing_if = "Option::is_none")]
6853    pub ignore_nulls: Option<bool>,
6854    /// Snowflake FROM FIRST / FROM LAST clause
6855    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
6856    #[serde(default, skip_serializing_if = "Option::is_none")]
6857    pub from_first: Option<bool>,
6858}
6859
6860/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6862#[cfg_attr(feature = "bindings", derive(TS))]
6863pub struct PercentRank {
6864    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
6865    #[serde(default, skip_serializing_if = "Option::is_none")]
6866    pub order_by: Option<Vec<Ordered>>,
6867    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6868    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6869    pub args: Vec<Expression>,
6870}
6871
6872/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6874#[cfg_attr(feature = "bindings", derive(TS))]
6875pub struct CumeDist {
6876    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
6877    #[serde(default, skip_serializing_if = "Option::is_none")]
6878    pub order_by: Option<Vec<Ordered>>,
6879    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6880    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6881    pub args: Vec<Expression>,
6882}
6883
6884// ============================================================================
6885// Additional String Function types
6886// ============================================================================
6887
6888/// POSITION/INSTR function
6889#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6890#[cfg_attr(feature = "bindings", derive(TS))]
6891pub struct PositionFunc {
6892    pub substring: Expression,
6893    pub string: Expression,
6894    pub start: Option<Expression>,
6895}
6896
6897// ============================================================================
6898// Additional Math Function types
6899// ============================================================================
6900
6901/// RANDOM function (no arguments)
6902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6903#[cfg_attr(feature = "bindings", derive(TS))]
6904pub struct Random;
6905
6906/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
6907#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6908#[cfg_attr(feature = "bindings", derive(TS))]
6909pub struct Rand {
6910    pub seed: Option<Box<Expression>>,
6911    /// Teradata RANDOM lower bound
6912    #[serde(default)]
6913    pub lower: Option<Box<Expression>>,
6914    /// Teradata RANDOM upper bound
6915    #[serde(default)]
6916    pub upper: Option<Box<Expression>>,
6917}
6918
6919/// TRUNCATE / TRUNC function
6920#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6921#[cfg_attr(feature = "bindings", derive(TS))]
6922pub struct TruncateFunc {
6923    pub this: Expression,
6924    pub decimals: Option<Expression>,
6925}
6926
6927/// PI function (no arguments)
6928#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6929#[cfg_attr(feature = "bindings", derive(TS))]
6930pub struct Pi;
6931
6932// ============================================================================
6933// Control Flow Function types
6934// ============================================================================
6935
6936/// DECODE function (Oracle style)
6937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6938#[cfg_attr(feature = "bindings", derive(TS))]
6939pub struct DecodeFunc {
6940    pub this: Expression,
6941    pub search_results: Vec<(Expression, Expression)>,
6942    pub default: Option<Expression>,
6943}
6944
6945// ============================================================================
6946// Additional Date/Time Function types
6947// ============================================================================
6948
6949/// DATE_FORMAT / FORMAT_DATE function
6950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6951#[cfg_attr(feature = "bindings", derive(TS))]
6952pub struct DateFormatFunc {
6953    pub this: Expression,
6954    pub format: Expression,
6955}
6956
6957/// FROM_UNIXTIME function
6958#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6959#[cfg_attr(feature = "bindings", derive(TS))]
6960pub struct FromUnixtimeFunc {
6961    pub this: Expression,
6962    pub format: Option<Expression>,
6963}
6964
6965/// UNIX_TIMESTAMP function
6966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6967#[cfg_attr(feature = "bindings", derive(TS))]
6968pub struct UnixTimestampFunc {
6969    pub this: Option<Expression>,
6970    pub format: Option<Expression>,
6971}
6972
6973/// MAKE_DATE function
6974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6975#[cfg_attr(feature = "bindings", derive(TS))]
6976pub struct MakeDateFunc {
6977    pub year: Expression,
6978    pub month: Expression,
6979    pub day: Expression,
6980}
6981
6982/// MAKE_TIMESTAMP function
6983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6984#[cfg_attr(feature = "bindings", derive(TS))]
6985pub struct MakeTimestampFunc {
6986    pub year: Expression,
6987    pub month: Expression,
6988    pub day: Expression,
6989    pub hour: Expression,
6990    pub minute: Expression,
6991    pub second: Expression,
6992    pub timezone: Option<Expression>,
6993}
6994
6995/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
6996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6997#[cfg_attr(feature = "bindings", derive(TS))]
6998pub struct LastDayFunc {
6999    pub this: Expression,
7000    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
7001    #[serde(skip_serializing_if = "Option::is_none", default)]
7002    pub unit: Option<DateTimeField>,
7003}
7004
7005// ============================================================================
7006// Array Function types
7007// ============================================================================
7008
7009/// ARRAY constructor
7010#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7011#[cfg_attr(feature = "bindings", derive(TS))]
7012pub struct ArrayConstructor {
7013    pub expressions: Vec<Expression>,
7014    pub bracket_notation: bool,
7015    /// True if LIST keyword was used instead of ARRAY (DuckDB)
7016    pub use_list_keyword: bool,
7017}
7018
7019/// ARRAY_SORT function
7020#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7021#[cfg_attr(feature = "bindings", derive(TS))]
7022pub struct ArraySortFunc {
7023    pub this: Expression,
7024    pub comparator: Option<Expression>,
7025    pub desc: bool,
7026    pub nulls_first: Option<bool>,
7027}
7028
7029/// ARRAY_JOIN / ARRAY_TO_STRING function
7030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7031#[cfg_attr(feature = "bindings", derive(TS))]
7032pub struct ArrayJoinFunc {
7033    pub this: Expression,
7034    pub separator: Expression,
7035    pub null_replacement: Option<Expression>,
7036}
7037
7038/// UNNEST function
7039#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7040#[cfg_attr(feature = "bindings", derive(TS))]
7041pub struct UnnestFunc {
7042    pub this: Expression,
7043    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
7044    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7045    pub expressions: Vec<Expression>,
7046    pub with_ordinality: bool,
7047    pub alias: Option<Identifier>,
7048    /// BigQuery: offset alias for WITH OFFSET AS <name>
7049    #[serde(default, skip_serializing_if = "Option::is_none")]
7050    pub offset_alias: Option<Identifier>,
7051    /// Inferred type of the first UNNEST output column.
7052    #[serde(default, skip_serializing_if = "Option::is_none")]
7053    #[ast(skip)]
7054    pub inferred_type: Option<DataType>,
7055}
7056
7057/// ARRAY_FILTER function (with lambda)
7058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7059#[cfg_attr(feature = "bindings", derive(TS))]
7060pub struct ArrayFilterFunc {
7061    pub this: Expression,
7062    pub filter: Expression,
7063}
7064
7065/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
7066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7067#[cfg_attr(feature = "bindings", derive(TS))]
7068pub struct ArrayTransformFunc {
7069    pub this: Expression,
7070    pub transform: Expression,
7071}
7072
7073/// SEQUENCE / GENERATE_SERIES function
7074#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7075#[cfg_attr(feature = "bindings", derive(TS))]
7076pub struct SequenceFunc {
7077    pub start: Expression,
7078    pub stop: Expression,
7079    pub step: Option<Expression>,
7080}
7081
7082// ============================================================================
7083// Struct Function types
7084// ============================================================================
7085
7086/// STRUCT constructor
7087#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7088#[cfg_attr(feature = "bindings", derive(TS))]
7089pub struct StructConstructor {
7090    pub fields: Vec<(Option<Identifier>, Expression)>,
7091}
7092
7093/// STRUCT_EXTRACT function
7094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7095#[cfg_attr(feature = "bindings", derive(TS))]
7096pub struct StructExtractFunc {
7097    pub this: Expression,
7098    pub field: Identifier,
7099}
7100
7101/// NAMED_STRUCT function
7102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7103#[cfg_attr(feature = "bindings", derive(TS))]
7104pub struct NamedStructFunc {
7105    pub pairs: Vec<(Expression, Expression)>,
7106}
7107
7108// ============================================================================
7109// Map Function types
7110// ============================================================================
7111
7112/// MAP constructor
7113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7114#[cfg_attr(feature = "bindings", derive(TS))]
7115pub struct MapConstructor {
7116    pub keys: Vec<Expression>,
7117    pub values: Vec<Expression>,
7118    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7119    #[serde(default)]
7120    pub curly_brace_syntax: bool,
7121    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7122    #[serde(default)]
7123    pub with_map_keyword: bool,
7124}
7125
7126/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7127#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7128#[cfg_attr(feature = "bindings", derive(TS))]
7129pub struct TransformFunc {
7130    pub this: Expression,
7131    pub transform: Expression,
7132}
7133
7134/// Function call with EMITS clause (Exasol)
7135/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7137#[cfg_attr(feature = "bindings", derive(TS))]
7138pub struct FunctionEmits {
7139    /// The function call expression
7140    pub this: Expression,
7141    /// The EMITS schema definition
7142    pub emits: Expression,
7143}
7144
7145// ============================================================================
7146// JSON Function types
7147// ============================================================================
7148
7149/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7150#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7151#[cfg_attr(feature = "bindings", derive(TS))]
7152pub struct JsonExtractFunc {
7153    pub this: Expression,
7154    pub path: Expression,
7155    pub returning: Option<DataType>,
7156    /// True if parsed from -> or ->> operator syntax
7157    #[serde(default)]
7158    pub arrow_syntax: bool,
7159    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7160    #[serde(default)]
7161    pub hash_arrow_syntax: bool,
7162    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7163    #[serde(default)]
7164    pub wrapper_option: Option<String>,
7165    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7166    #[serde(default)]
7167    pub quotes_option: Option<String>,
7168    /// ON SCALAR STRING flag
7169    #[serde(default)]
7170    pub on_scalar_string: bool,
7171    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7172    #[serde(default)]
7173    pub on_error: Option<String>,
7174}
7175
7176/// JSON path extraction
7177#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7178#[cfg_attr(feature = "bindings", derive(TS))]
7179pub struct JsonPathFunc {
7180    pub this: Expression,
7181    pub paths: Vec<Expression>,
7182}
7183
7184/// JSON_OBJECT function
7185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7186#[cfg_attr(feature = "bindings", derive(TS))]
7187pub struct JsonObjectFunc {
7188    pub pairs: Vec<(Expression, Expression)>,
7189    pub null_handling: Option<JsonNullHandling>,
7190    #[serde(default)]
7191    pub with_unique_keys: bool,
7192    #[serde(default)]
7193    pub returning_type: Option<DataType>,
7194    #[serde(default)]
7195    pub format_json: bool,
7196    #[serde(default)]
7197    pub encoding: Option<String>,
7198    /// For JSON_OBJECT(*) syntax
7199    #[serde(default)]
7200    pub star: bool,
7201}
7202
7203/// JSON null handling options
7204#[derive(
7205    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7206)]
7207#[cfg_attr(feature = "bindings", derive(TS))]
7208pub enum JsonNullHandling {
7209    NullOnNull,
7210    AbsentOnNull,
7211}
7212
7213/// JSON_SET / JSON_INSERT function
7214#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7215#[cfg_attr(feature = "bindings", derive(TS))]
7216pub struct JsonModifyFunc {
7217    pub this: Expression,
7218    pub path_values: Vec<(Expression, Expression)>,
7219}
7220
7221/// JSON_ARRAYAGG function
7222#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7223#[cfg_attr(feature = "bindings", derive(TS))]
7224pub struct JsonArrayAggFunc {
7225    pub this: Expression,
7226    pub order_by: Option<Vec<Ordered>>,
7227    pub null_handling: Option<JsonNullHandling>,
7228    pub filter: Option<Expression>,
7229}
7230
7231/// JSON_OBJECTAGG function
7232#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7233#[cfg_attr(feature = "bindings", derive(TS))]
7234pub struct JsonObjectAggFunc {
7235    pub key: Expression,
7236    pub value: Expression,
7237    pub null_handling: Option<JsonNullHandling>,
7238    pub filter: Option<Expression>,
7239}
7240
7241// ============================================================================
7242// Type Casting Function types
7243// ============================================================================
7244
7245/// CONVERT function (SQL Server style)
7246#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7247#[cfg_attr(feature = "bindings", derive(TS))]
7248pub struct ConvertFunc {
7249    pub this: Expression,
7250    pub to: DataType,
7251    pub style: Option<Expression>,
7252}
7253
7254// ============================================================================
7255// Additional Expression types
7256// ============================================================================
7257
7258/// Lambda expression
7259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7260#[cfg_attr(feature = "bindings", derive(TS))]
7261pub struct LambdaExpr {
7262    pub parameters: Vec<Identifier>,
7263    pub body: Expression,
7264    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7265    #[serde(default)]
7266    pub colon: bool,
7267    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7268    /// Maps parameter index to data type
7269    #[serde(default)]
7270    pub parameter_types: Vec<Option<DataType>>,
7271}
7272
7273/// Parameter (parameterized queries)
7274#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7275#[cfg_attr(feature = "bindings", derive(TS))]
7276pub struct Parameter {
7277    pub name: Option<String>,
7278    pub index: Option<u32>,
7279    pub style: ParameterStyle,
7280    /// Whether the name was quoted (e.g., @"x" vs @x)
7281    #[serde(default)]
7282    pub quoted: bool,
7283    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7284    #[serde(default)]
7285    pub string_quoted: bool,
7286    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7287    #[serde(default)]
7288    pub expression: Option<String>,
7289}
7290
7291/// Parameter placeholder styles
7292#[derive(
7293    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7294)]
7295#[cfg_attr(feature = "bindings", derive(TS))]
7296pub enum ParameterStyle {
7297    Question,     // ?
7298    Dollar,       // $1, $2
7299    DollarBrace,  // ${name} (Databricks, Hive template variables)
7300    Brace,        // {name} (Spark/Databricks widget/template variables)
7301    Colon,        // :name
7302    At,           // @name
7303    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7304    DoubleDollar, // $$name
7305    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7306}
7307
7308/// Placeholder expression
7309#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7310#[cfg_attr(feature = "bindings", derive(TS))]
7311pub struct Placeholder {
7312    pub index: Option<u32>,
7313}
7314
7315/// Named argument in function call: name => value or name := value
7316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7317#[cfg_attr(feature = "bindings", derive(TS))]
7318pub struct NamedArgument {
7319    pub name: Identifier,
7320    pub value: Expression,
7321    /// The separator used: `=>`, `:=`, or `=`
7322    pub separator: NamedArgSeparator,
7323}
7324
7325/// Separator style for named arguments
7326#[derive(
7327    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7328)]
7329#[cfg_attr(feature = "bindings", derive(TS))]
7330pub enum NamedArgSeparator {
7331    /// `=>` (standard SQL, Snowflake, BigQuery)
7332    DArrow,
7333    /// `:=` (Oracle, MySQL)
7334    ColonEq,
7335    /// `=` (simple equals, some dialects)
7336    Eq,
7337}
7338
7339/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7340/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7341#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7342#[cfg_attr(feature = "bindings", derive(TS))]
7343pub struct TableArgument {
7344    /// The keyword prefix: "TABLE" or "MODEL"
7345    pub prefix: String,
7346    /// The table/model reference expression
7347    pub this: Expression,
7348}
7349
7350/// SQL Comment preservation
7351#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7352#[cfg_attr(feature = "bindings", derive(TS))]
7353pub struct SqlComment {
7354    pub text: String,
7355    pub is_block: bool,
7356}
7357
7358// ============================================================================
7359// Additional Predicate types
7360// ============================================================================
7361
7362/// SIMILAR TO expression
7363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7364#[cfg_attr(feature = "bindings", derive(TS))]
7365pub struct SimilarToExpr {
7366    pub this: Expression,
7367    pub pattern: Expression,
7368    pub escape: Option<Expression>,
7369    pub not: bool,
7370}
7371
7372/// ANY / ALL quantified expression
7373#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7374#[cfg_attr(feature = "bindings", derive(TS))]
7375pub struct QuantifiedExpr {
7376    pub this: Expression,
7377    pub subquery: Expression,
7378    pub op: Option<QuantifiedOp>,
7379}
7380
7381/// Comparison operator for quantified expressions
7382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7383#[cfg_attr(feature = "bindings", derive(TS))]
7384pub enum QuantifiedOp {
7385    Eq,
7386    Neq,
7387    Lt,
7388    Lte,
7389    Gt,
7390    Gte,
7391}
7392
7393/// OVERLAPS expression
7394/// Supports two forms:
7395/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7396/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7397#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7398#[cfg_attr(feature = "bindings", derive(TS))]
7399pub struct OverlapsExpr {
7400    /// Left operand for simple binary form
7401    #[serde(skip_serializing_if = "Option::is_none")]
7402    pub this: Option<Expression>,
7403    /// Right operand for simple binary form
7404    #[serde(skip_serializing_if = "Option::is_none")]
7405    pub expression: Option<Expression>,
7406    /// Left range start for full ANSI form
7407    #[serde(skip_serializing_if = "Option::is_none")]
7408    pub left_start: Option<Expression>,
7409    /// Left range end for full ANSI form
7410    #[serde(skip_serializing_if = "Option::is_none")]
7411    pub left_end: Option<Expression>,
7412    /// Right range start for full ANSI form
7413    #[serde(skip_serializing_if = "Option::is_none")]
7414    pub right_start: Option<Expression>,
7415    /// Right range end for full ANSI form
7416    #[serde(skip_serializing_if = "Option::is_none")]
7417    pub right_end: Option<Expression>,
7418}
7419
7420// ============================================================================
7421// Array/Struct/Map access
7422// ============================================================================
7423
7424/// Subscript access (array[index] or map[key])
7425#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7426#[cfg_attr(feature = "bindings", derive(TS))]
7427pub struct Subscript {
7428    pub this: Expression,
7429    pub index: Expression,
7430}
7431
7432/// Dot access (struct.field)
7433#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7434#[cfg_attr(feature = "bindings", derive(TS))]
7435pub struct DotAccess {
7436    pub this: Expression,
7437    pub field: Identifier,
7438}
7439
7440/// Method call (expr.method(args))
7441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7442#[cfg_attr(feature = "bindings", derive(TS))]
7443pub struct MethodCall {
7444    pub this: Expression,
7445    pub method: Identifier,
7446    pub args: Vec<Expression>,
7447}
7448
7449/// Array slice (array[start:end])
7450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7451#[cfg_attr(feature = "bindings", derive(TS))]
7452pub struct ArraySlice {
7453    pub this: Expression,
7454    pub start: Option<Expression>,
7455    pub end: Option<Expression>,
7456}
7457
7458// ============================================================================
7459// DDL (Data Definition Language) Statements
7460// ============================================================================
7461
7462/// ON COMMIT behavior for temporary tables
7463#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7464#[cfg_attr(feature = "bindings", derive(TS))]
7465pub enum OnCommit {
7466    /// ON COMMIT PRESERVE ROWS
7467    PreserveRows,
7468    /// ON COMMIT DELETE ROWS
7469    DeleteRows,
7470}
7471
7472/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
7473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7474#[cfg_attr(feature = "bindings", derive(TS))]
7475pub struct TiDBAutoRandom {
7476    #[serde(default, skip_serializing_if = "Option::is_none")]
7477    pub shard_bits: Option<u64>,
7478    #[serde(default, skip_serializing_if = "Option::is_none")]
7479    pub range_bits: Option<u64>,
7480    /// Whether the attribute was wrapped in a TiDB executable comment.
7481    #[serde(default)]
7482    pub executable_comment: bool,
7483}
7484
7485/// A TiDB-specific table option and its source syntax.
7486#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7487#[cfg_attr(feature = "bindings", derive(TS))]
7488pub struct TiDBTableOption {
7489    pub kind: TiDBTableOptionKind,
7490    /// Whether the option was wrapped in a TiDB executable comment.
7491    #[serde(default)]
7492    pub executable_comment: bool,
7493}
7494
7495/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
7496#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7497#[cfg_attr(feature = "bindings", derive(TS))]
7498#[serde(tag = "type", rename_all = "snake_case")]
7499pub enum TiDBTableOptionKind {
7500    ShardRowIdBits {
7501        bits: u64,
7502    },
7503    PreSplitRegions {
7504        regions: u64,
7505    },
7506    AutoRandomBase {
7507        value: u64,
7508    },
7509    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
7510    PlacementPolicy {
7511        policy: Option<Identifier>,
7512    },
7513    Ttl {
7514        column: Identifier,
7515        interval: Interval,
7516        #[serde(default, skip_serializing_if = "Option::is_none")]
7517        enabled: Option<bool>,
7518    },
7519    TtlEnable {
7520        enabled: bool,
7521    },
7522    TtlJobInterval {
7523        interval: String,
7524    },
7525}
7526
7527/// CREATE TABLE statement
7528#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7529#[cfg_attr(feature = "bindings", derive(TS))]
7530pub struct CreateTable {
7531    pub name: TableRef,
7532    /// ClickHouse: ON CLUSTER clause for distributed DDL
7533    #[serde(default, skip_serializing_if = "Option::is_none")]
7534    pub on_cluster: Option<OnCluster>,
7535    pub columns: Vec<ColumnDef>,
7536    pub constraints: Vec<TableConstraint>,
7537    pub if_not_exists: bool,
7538    pub temporary: bool,
7539    pub or_replace: bool,
7540    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
7541    #[serde(default, skip_serializing_if = "Option::is_none")]
7542    pub table_modifier: Option<String>,
7543    pub as_select: Option<Expression>,
7544    /// Whether the AS SELECT was wrapped in parentheses
7545    #[serde(default)]
7546    pub as_select_parenthesized: bool,
7547    /// ON COMMIT behavior for temporary tables
7548    #[serde(default)]
7549    pub on_commit: Option<OnCommit>,
7550    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
7551    #[serde(default)]
7552    pub clone_source: Option<TableRef>,
7553    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
7554    #[serde(default, skip_serializing_if = "Option::is_none")]
7555    pub clone_at_clause: Option<Expression>,
7556    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
7557    #[serde(default)]
7558    pub is_copy: bool,
7559    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
7560    #[serde(default)]
7561    pub shallow_clone: bool,
7562    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
7563    #[serde(default)]
7564    pub deep_clone: bool,
7565    /// Leading comments before the statement
7566    #[serde(default)]
7567    pub leading_comments: Vec<String>,
7568    /// WITH properties (e.g., WITH (FORMAT='parquet'))
7569    #[serde(default)]
7570    pub with_properties: Vec<(String, String)>,
7571    /// Teradata: table options after name before columns (comma-separated)
7572    #[serde(default)]
7573    pub teradata_post_name_options: Vec<String>,
7574    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
7575    #[serde(default)]
7576    pub with_data: Option<bool>,
7577    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
7578    #[serde(default)]
7579    pub with_statistics: Option<bool>,
7580    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
7581    #[serde(default)]
7582    pub teradata_indexes: Vec<TeradataIndex>,
7583    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
7584    #[serde(default)]
7585    pub with_cte: Option<With>,
7586    /// Table properties like DEFAULT COLLATE (BigQuery)
7587    #[serde(default)]
7588    pub properties: Vec<Expression>,
7589    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
7590    #[serde(default, skip_serializing_if = "Option::is_none")]
7591    pub partition_of: Option<Expression>,
7592    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
7593    #[serde(default)]
7594    pub post_table_properties: Vec<Expression>,
7595    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
7596    #[serde(default)]
7597    pub mysql_table_options: Vec<(String, String)>,
7598    /// TiDB-specific table options after column definitions.
7599    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7600    pub tidb_table_options: Vec<TiDBTableOption>,
7601    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
7602    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7603    pub inherits: Vec<TableRef>,
7604    /// TSQL ON filegroup or ON filegroup (partition_column) clause
7605    #[serde(default, skip_serializing_if = "Option::is_none")]
7606    pub on_property: Option<OnProperty>,
7607    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
7608    #[serde(default)]
7609    pub copy_grants: bool,
7610    /// Snowflake: USING TEMPLATE expression for schema inference
7611    #[serde(default, skip_serializing_if = "Option::is_none")]
7612    pub using_template: Option<Box<Expression>>,
7613    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
7614    #[serde(default, skip_serializing_if = "Option::is_none")]
7615    pub rollup: Option<RollupProperty>,
7616    /// ClickHouse: UUID 'xxx' clause after table name
7617    #[serde(default, skip_serializing_if = "Option::is_none")]
7618    pub uuid: Option<String>,
7619    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
7620    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
7621    /// could appear in other engines.
7622    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7623    pub with_partition_columns: Vec<ColumnDef>,
7624    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
7625    /// for external tables that reference a Cloud Resource connection.
7626    #[serde(default, skip_serializing_if = "Option::is_none")]
7627    pub with_connection: Option<TableRef>,
7628}
7629
7630/// Teradata index specification for CREATE TABLE
7631#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7632#[cfg_attr(feature = "bindings", derive(TS))]
7633pub struct TeradataIndex {
7634    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
7635    pub kind: TeradataIndexKind,
7636    /// Optional index name
7637    pub name: Option<String>,
7638    /// Optional column list
7639    pub columns: Vec<String>,
7640}
7641
7642/// Kind of Teradata index
7643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7644#[cfg_attr(feature = "bindings", derive(TS))]
7645pub enum TeradataIndexKind {
7646    /// NO PRIMARY INDEX
7647    NoPrimary,
7648    /// PRIMARY INDEX
7649    Primary,
7650    /// PRIMARY AMP INDEX
7651    PrimaryAmp,
7652    /// UNIQUE INDEX
7653    Unique,
7654    /// UNIQUE PRIMARY INDEX
7655    UniquePrimary,
7656    /// INDEX (secondary, non-primary)
7657    Secondary,
7658}
7659
7660impl CreateTable {
7661    pub fn new(name: impl Into<String>) -> Self {
7662        Self {
7663            name: TableRef::new(name),
7664            on_cluster: None,
7665            columns: Vec::new(),
7666            constraints: Vec::new(),
7667            if_not_exists: false,
7668            temporary: false,
7669            or_replace: false,
7670            table_modifier: None,
7671            as_select: None,
7672            as_select_parenthesized: false,
7673            on_commit: None,
7674            clone_source: None,
7675            clone_at_clause: None,
7676            shallow_clone: false,
7677            deep_clone: false,
7678            is_copy: false,
7679            leading_comments: Vec::new(),
7680            with_properties: Vec::new(),
7681            teradata_post_name_options: Vec::new(),
7682            with_data: None,
7683            with_statistics: None,
7684            teradata_indexes: Vec::new(),
7685            with_cte: None,
7686            properties: Vec::new(),
7687            partition_of: None,
7688            post_table_properties: Vec::new(),
7689            mysql_table_options: Vec::new(),
7690            tidb_table_options: Vec::new(),
7691            inherits: Vec::new(),
7692            on_property: None,
7693            copy_grants: false,
7694            using_template: None,
7695            rollup: None,
7696            uuid: None,
7697            with_partition_columns: Vec::new(),
7698            with_connection: None,
7699        }
7700    }
7701}
7702
7703/// Sort order for PRIMARY KEY ASC/DESC
7704#[derive(
7705    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
7706)]
7707#[cfg_attr(feature = "bindings", derive(TS))]
7708pub enum SortOrder {
7709    Asc,
7710    Desc,
7711}
7712
7713/// Type of column constraint for tracking order
7714#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7715#[cfg_attr(feature = "bindings", derive(TS))]
7716pub enum ConstraintType {
7717    NotNull,
7718    Null,
7719    PrimaryKey,
7720    Unique,
7721    Default,
7722    AutoIncrement,
7723    AutoRandom,
7724    Collate,
7725    Comment,
7726    References,
7727    Check,
7728    GeneratedAsIdentity,
7729    /// Snowflake: TAG (key='value', ...)
7730    Tags,
7731    /// Computed/generated column
7732    ComputedColumn,
7733    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
7734    GeneratedAsRow,
7735    /// MySQL: ON UPDATE expression
7736    OnUpdate,
7737    /// PATH constraint for XMLTABLE/JSON_TABLE columns
7738    Path,
7739    /// Redshift: ENCODE encoding_type
7740    Encode,
7741}
7742
7743/// Column definition in CREATE TABLE
7744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7745#[cfg_attr(feature = "bindings", derive(TS))]
7746pub struct ColumnDef {
7747    pub name: Identifier,
7748    pub data_type: DataType,
7749    pub nullable: Option<bool>,
7750    pub default: Option<Expression>,
7751    pub primary_key: bool,
7752    /// Sort order for PRIMARY KEY (ASC/DESC)
7753    #[serde(default)]
7754    pub primary_key_order: Option<SortOrder>,
7755    pub unique: bool,
7756    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
7757    #[serde(default)]
7758    pub unique_nulls_not_distinct: bool,
7759    pub auto_increment: bool,
7760    /// TiDB distributed primary-key allocation attribute.
7761    #[serde(default, skip_serializing_if = "Option::is_none")]
7762    pub auto_random: Option<TiDBAutoRandom>,
7763    pub comment: Option<String>,
7764    pub constraints: Vec<ColumnConstraint>,
7765    /// Track original order of constraints for accurate regeneration
7766    #[serde(default)]
7767    pub constraint_order: Vec<ConstraintType>,
7768    /// Teradata: FORMAT 'pattern'
7769    #[serde(default)]
7770    pub format: Option<String>,
7771    /// Teradata: TITLE 'title'
7772    #[serde(default)]
7773    pub title: Option<String>,
7774    /// Teradata: INLINE LENGTH n
7775    #[serde(default)]
7776    pub inline_length: Option<u64>,
7777    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
7778    #[serde(default)]
7779    pub compress: Option<Vec<Expression>>,
7780    /// Teradata: CHARACTER SET name
7781    #[serde(default)]
7782    pub character_set: Option<String>,
7783    /// Teradata: UPPERCASE
7784    #[serde(default)]
7785    pub uppercase: bool,
7786    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
7787    #[serde(default)]
7788    pub casespecific: Option<bool>,
7789    /// Snowflake: AUTOINCREMENT START value
7790    #[serde(default)]
7791    pub auto_increment_start: Option<Box<Expression>>,
7792    /// Snowflake: AUTOINCREMENT INCREMENT value
7793    #[serde(default)]
7794    pub auto_increment_increment: Option<Box<Expression>>,
7795    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
7796    #[serde(default)]
7797    pub auto_increment_order: Option<bool>,
7798    /// MySQL: UNSIGNED modifier
7799    #[serde(default)]
7800    pub unsigned: bool,
7801    /// MySQL: ZEROFILL modifier
7802    #[serde(default)]
7803    pub zerofill: bool,
7804    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
7805    #[serde(default, skip_serializing_if = "Option::is_none")]
7806    pub on_update: Option<Expression>,
7807    /// MySQL: column VISIBLE/INVISIBLE modifier.
7808    #[serde(default, skip_serializing_if = "Option::is_none")]
7809    pub visible: Option<bool>,
7810    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
7811    #[serde(default, skip_serializing_if = "Option::is_none")]
7812    pub unique_constraint_name: Option<String>,
7813    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
7814    #[serde(default, skip_serializing_if = "Option::is_none")]
7815    pub not_null_constraint_name: Option<String>,
7816    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
7817    #[serde(default, skip_serializing_if = "Option::is_none")]
7818    pub primary_key_constraint_name: Option<String>,
7819    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
7820    #[serde(default, skip_serializing_if = "Option::is_none")]
7821    pub check_constraint_name: Option<String>,
7822    /// BigQuery: OPTIONS (key=value, ...) on column
7823    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7824    pub options: Vec<Expression>,
7825    /// SQLite: Column definition without explicit type
7826    #[serde(default)]
7827    pub no_type: bool,
7828    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
7829    #[serde(default, skip_serializing_if = "Option::is_none")]
7830    pub encoding: Option<String>,
7831    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
7832    #[serde(default, skip_serializing_if = "Option::is_none")]
7833    pub codec: Option<String>,
7834    /// ClickHouse: EPHEMERAL [expr] modifier
7835    #[serde(default, skip_serializing_if = "Option::is_none")]
7836    pub ephemeral: Option<Option<Box<Expression>>>,
7837    /// ClickHouse: MATERIALIZED expr modifier
7838    #[serde(default, skip_serializing_if = "Option::is_none")]
7839    pub materialized_expr: Option<Box<Expression>>,
7840    /// ClickHouse: ALIAS expr modifier
7841    #[serde(default, skip_serializing_if = "Option::is_none")]
7842    pub alias_expr: Option<Box<Expression>>,
7843    /// ClickHouse: TTL expr modifier on columns
7844    #[serde(default, skip_serializing_if = "Option::is_none")]
7845    pub ttl_expr: Option<Box<Expression>>,
7846    /// TSQL: NOT FOR REPLICATION
7847    #[serde(default)]
7848    pub not_for_replication: bool,
7849}
7850
7851impl ColumnDef {
7852    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
7853        Self {
7854            name: Identifier::new(name),
7855            data_type,
7856            nullable: None,
7857            default: None,
7858            primary_key: false,
7859            primary_key_order: None,
7860            unique: false,
7861            unique_nulls_not_distinct: false,
7862            auto_increment: false,
7863            auto_random: None,
7864            comment: None,
7865            constraints: Vec::new(),
7866            constraint_order: Vec::new(),
7867            format: None,
7868            title: None,
7869            inline_length: None,
7870            compress: None,
7871            character_set: None,
7872            uppercase: false,
7873            casespecific: None,
7874            auto_increment_start: None,
7875            auto_increment_increment: None,
7876            auto_increment_order: None,
7877            unsigned: false,
7878            zerofill: false,
7879            on_update: None,
7880            visible: None,
7881            unique_constraint_name: None,
7882            not_null_constraint_name: None,
7883            primary_key_constraint_name: None,
7884            check_constraint_name: None,
7885            options: Vec::new(),
7886            no_type: false,
7887            encoding: None,
7888            codec: None,
7889            ephemeral: None,
7890            materialized_expr: None,
7891            alias_expr: None,
7892            ttl_expr: None,
7893            not_for_replication: false,
7894        }
7895    }
7896}
7897
7898/// Column-level constraint
7899#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7900#[cfg_attr(feature = "bindings", derive(TS))]
7901pub enum ColumnConstraint {
7902    NotNull,
7903    Null,
7904    Unique,
7905    PrimaryKey,
7906    Default(Expression),
7907    Check(Expression),
7908    References(ForeignKeyRef),
7909    GeneratedAsIdentity(GeneratedAsIdentity),
7910    Collate(Identifier),
7911    Comment(String),
7912    /// Snowflake: TAG (key='value', ...)
7913    Tags(Tags),
7914    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
7915    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
7916    ComputedColumn(ComputedColumn),
7917    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7918    GeneratedAsRow(GeneratedAsRow),
7919    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
7920    Path(Expression),
7921}
7922
7923/// Computed/generated column constraint
7924#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7925#[cfg_attr(feature = "bindings", derive(TS))]
7926pub struct ComputedColumn {
7927    /// The expression that computes the column value
7928    pub expression: Box<Expression>,
7929    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
7930    #[serde(default)]
7931    pub persisted: bool,
7932    /// NOT NULL (TSQL computed columns)
7933    #[serde(default)]
7934    pub not_null: bool,
7935    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
7936    /// When None, defaults to dialect-appropriate output
7937    #[serde(default)]
7938    pub persistence_kind: Option<String>,
7939    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
7940    #[serde(default, skip_serializing_if = "Option::is_none")]
7941    pub data_type: Option<DataType>,
7942}
7943
7944/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7946#[cfg_attr(feature = "bindings", derive(TS))]
7947pub struct GeneratedAsRow {
7948    /// true = ROW START, false = ROW END
7949    pub start: bool,
7950    /// HIDDEN modifier
7951    #[serde(default)]
7952    pub hidden: bool,
7953}
7954
7955/// Generated identity column constraint
7956#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7957#[cfg_attr(feature = "bindings", derive(TS))]
7958pub struct GeneratedAsIdentity {
7959    /// True for ALWAYS, False for BY DEFAULT
7960    pub always: bool,
7961    /// ON NULL (only valid with BY DEFAULT)
7962    pub on_null: bool,
7963    /// START WITH value
7964    pub start: Option<Box<Expression>>,
7965    /// INCREMENT BY value
7966    pub increment: Option<Box<Expression>>,
7967    /// MINVALUE
7968    pub minvalue: Option<Box<Expression>>,
7969    /// MAXVALUE
7970    pub maxvalue: Option<Box<Expression>>,
7971    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
7972    pub cycle: Option<bool>,
7973}
7974
7975/// Constraint modifiers (shared between table-level constraints)
7976#[derive(
7977    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
7978)]
7979#[cfg_attr(feature = "bindings", derive(TS))]
7980pub struct ConstraintModifiers {
7981    /// ENFORCED / NOT ENFORCED
7982    pub enforced: Option<bool>,
7983    /// DEFERRABLE / NOT DEFERRABLE
7984    pub deferrable: Option<bool>,
7985    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
7986    pub initially_deferred: Option<bool>,
7987    /// NORELY (Oracle)
7988    pub norely: bool,
7989    /// RELY (Oracle)
7990    pub rely: bool,
7991    /// USING index type (MySQL): BTREE or HASH
7992    #[serde(default)]
7993    pub using: Option<String>,
7994    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
7995    #[serde(default)]
7996    pub using_before_columns: bool,
7997    /// MySQL index COMMENT 'text'
7998    #[serde(default, skip_serializing_if = "Option::is_none")]
7999    pub comment: Option<String>,
8000    /// MySQL index VISIBLE/INVISIBLE
8001    #[serde(default, skip_serializing_if = "Option::is_none")]
8002    pub visible: Option<bool>,
8003    /// MySQL ENGINE_ATTRIBUTE = 'value'
8004    #[serde(default, skip_serializing_if = "Option::is_none")]
8005    pub engine_attribute: Option<String>,
8006    /// MySQL WITH PARSER name
8007    #[serde(default, skip_serializing_if = "Option::is_none")]
8008    pub with_parser: Option<String>,
8009    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
8010    #[serde(default)]
8011    pub not_valid: bool,
8012    /// TSQL CLUSTERED/NONCLUSTERED modifier
8013    #[serde(default, skip_serializing_if = "Option::is_none")]
8014    pub clustered: Option<String>,
8015    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
8016    #[serde(default, skip_serializing_if = "Option::is_none")]
8017    pub on_conflict: Option<String>,
8018    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
8019    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8020    pub with_options: Vec<(String, String)>,
8021    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
8022    #[serde(default, skip_serializing_if = "Option::is_none")]
8023    pub on_filegroup: Option<Identifier>,
8024}
8025
8026/// Table-level constraint
8027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8028#[cfg_attr(feature = "bindings", derive(TS))]
8029pub enum TableConstraint {
8030    PrimaryKey {
8031        name: Option<Identifier>,
8032        columns: Vec<Identifier>,
8033        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
8034        #[serde(default)]
8035        include_columns: Vec<Identifier>,
8036        #[serde(default)]
8037        modifiers: ConstraintModifiers,
8038        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
8039        #[serde(default)]
8040        has_constraint_keyword: bool,
8041    },
8042    Unique {
8043        name: Option<Identifier>,
8044        columns: Vec<Identifier>,
8045        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
8046        #[serde(default)]
8047        columns_parenthesized: bool,
8048        #[serde(default)]
8049        modifiers: ConstraintModifiers,
8050        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
8051        #[serde(default)]
8052        has_constraint_keyword: bool,
8053        /// PostgreSQL 15+: NULLS NOT DISTINCT
8054        #[serde(default)]
8055        nulls_not_distinct: bool,
8056    },
8057    ForeignKey {
8058        name: Option<Identifier>,
8059        columns: Vec<Identifier>,
8060        #[serde(default)]
8061        references: Option<ForeignKeyRef>,
8062        /// ON DELETE action when REFERENCES is absent
8063        #[serde(default)]
8064        on_delete: Option<ReferentialAction>,
8065        /// ON UPDATE action when REFERENCES is absent
8066        #[serde(default)]
8067        on_update: Option<ReferentialAction>,
8068        #[serde(default)]
8069        modifiers: ConstraintModifiers,
8070    },
8071    Check {
8072        name: Option<Identifier>,
8073        expression: Expression,
8074        #[serde(default)]
8075        modifiers: ConstraintModifiers,
8076    },
8077    /// ClickHouse ASSUME constraint (query optimization assumption)
8078    Assume {
8079        name: Option<Identifier>,
8080        expression: Expression,
8081    },
8082    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
8083    Default {
8084        name: Option<Identifier>,
8085        expression: Expression,
8086        column: Identifier,
8087    },
8088    /// INDEX / KEY constraint (MySQL)
8089    Index {
8090        name: Option<Identifier>,
8091        columns: Vec<Identifier>,
8092        /// Expression-capable index key parts. This is used when an index contains
8093        /// functional key parts that cannot be represented by `columns`.
8094        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8095        key_parts: Vec<IndexKeyPart>,
8096        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8097        #[serde(default)]
8098        kind: Option<String>,
8099        #[serde(default)]
8100        modifiers: ConstraintModifiers,
8101        /// True if KEY keyword was used instead of INDEX
8102        #[serde(default)]
8103        use_key_keyword: bool,
8104        /// ClickHouse: indexed expression (instead of columns)
8105        #[serde(default, skip_serializing_if = "Option::is_none")]
8106        expression: Option<Box<Expression>>,
8107        /// ClickHouse: TYPE type_func(args)
8108        #[serde(default, skip_serializing_if = "Option::is_none")]
8109        index_type: Option<Box<Expression>>,
8110        /// ClickHouse: GRANULARITY n
8111        #[serde(default, skip_serializing_if = "Option::is_none")]
8112        granularity: Option<Box<Expression>>,
8113    },
8114    /// ClickHouse PROJECTION definition
8115    Projection {
8116        name: Identifier,
8117        expression: Expression,
8118    },
8119    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8120    Like {
8121        source: TableRef,
8122        /// Options as (INCLUDING|EXCLUDING, property) pairs
8123        options: Vec<(LikeOptionAction, String)>,
8124    },
8125    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8126    PeriodForSystemTime {
8127        start_col: Identifier,
8128        end_col: Identifier,
8129    },
8130    /// PostgreSQL EXCLUDE constraint
8131    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8132    Exclude {
8133        name: Option<Identifier>,
8134        /// Index access method (gist, btree, etc.)
8135        #[serde(default)]
8136        using: Option<String>,
8137        /// Elements: (expression, operator) pairs
8138        elements: Vec<ExcludeElement>,
8139        /// INCLUDE columns
8140        #[serde(default)]
8141        include_columns: Vec<Identifier>,
8142        /// WHERE predicate
8143        #[serde(default)]
8144        where_clause: Option<Box<Expression>>,
8145        /// WITH (storage_parameters)
8146        #[serde(default)]
8147        with_params: Vec<(String, String)>,
8148        /// USING INDEX TABLESPACE tablespace_name
8149        #[serde(default)]
8150        using_index_tablespace: Option<String>,
8151        #[serde(default)]
8152        modifiers: ConstraintModifiers,
8153    },
8154    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8155    Tags(Tags),
8156    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8157    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8158    /// for all deferrable constraints in the table
8159    InitiallyDeferred {
8160        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8161        deferred: bool,
8162    },
8163}
8164
8165/// Element in an EXCLUDE constraint: expression WITH operator
8166#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8167#[cfg_attr(feature = "bindings", derive(TS))]
8168pub struct ExcludeElement {
8169    /// The column expression (may include operator class, ordering, nulls)
8170    pub expression: String,
8171    /// The operator (e.g., &&, =)
8172    pub operator: String,
8173}
8174
8175/// Action for LIKE clause options
8176#[derive(
8177    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8178)]
8179#[cfg_attr(feature = "bindings", derive(TS))]
8180pub enum LikeOptionAction {
8181    Including,
8182    Excluding,
8183}
8184
8185/// MATCH type for foreign keys
8186#[derive(
8187    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8188)]
8189#[cfg_attr(feature = "bindings", derive(TS))]
8190pub enum MatchType {
8191    Full,
8192    Partial,
8193    Simple,
8194}
8195
8196/// Foreign key reference
8197#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8198#[cfg_attr(feature = "bindings", derive(TS))]
8199pub struct ForeignKeyRef {
8200    pub table: TableRef,
8201    pub columns: Vec<Identifier>,
8202    pub on_delete: Option<ReferentialAction>,
8203    pub on_update: Option<ReferentialAction>,
8204    /// True if ON UPDATE appears before ON DELETE in the original SQL
8205    #[serde(default)]
8206    pub on_update_first: bool,
8207    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8208    #[serde(default)]
8209    pub match_type: Option<MatchType>,
8210    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8211    #[serde(default)]
8212    pub match_after_actions: bool,
8213    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8214    #[serde(default)]
8215    pub constraint_name: Option<String>,
8216    /// DEFERRABLE / NOT DEFERRABLE
8217    #[serde(default)]
8218    pub deferrable: Option<bool>,
8219    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8220    #[serde(default)]
8221    pub has_foreign_key_keywords: bool,
8222}
8223
8224/// Referential action for foreign keys
8225#[derive(
8226    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8227)]
8228#[cfg_attr(feature = "bindings", derive(TS))]
8229pub enum ReferentialAction {
8230    Cascade,
8231    SetNull,
8232    SetDefault,
8233    Restrict,
8234    NoAction,
8235}
8236
8237/// DROP TABLE statement
8238#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8239#[cfg_attr(feature = "bindings", derive(TS))]
8240pub struct DropTable {
8241    pub names: Vec<TableRef>,
8242    pub if_exists: bool,
8243    pub cascade: bool,
8244    /// Oracle: CASCADE CONSTRAINTS
8245    #[serde(default)]
8246    pub cascade_constraints: bool,
8247    /// Oracle: PURGE
8248    #[serde(default)]
8249    pub purge: bool,
8250    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8251    #[serde(default)]
8252    pub leading_comments: Vec<String>,
8253    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8254    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8255    #[serde(default, skip_serializing_if = "Option::is_none")]
8256    pub object_id_args: Option<String>,
8257    /// ClickHouse: SYNC modifier
8258    #[serde(default)]
8259    pub sync: bool,
8260    /// Snowflake: DROP ICEBERG TABLE
8261    #[serde(default)]
8262    pub iceberg: bool,
8263    /// RESTRICT modifier (opposite of CASCADE)
8264    #[serde(default)]
8265    pub restrict: bool,
8266}
8267
8268impl DropTable {
8269    pub fn new(name: impl Into<String>) -> Self {
8270        Self {
8271            names: vec![TableRef::new(name)],
8272            if_exists: false,
8273            cascade: false,
8274            cascade_constraints: false,
8275            purge: false,
8276            leading_comments: Vec::new(),
8277            object_id_args: None,
8278            sync: false,
8279            iceberg: false,
8280            restrict: false,
8281        }
8282    }
8283}
8284
8285/// UNDROP object statement (Snowflake, ClickHouse)
8286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8287#[cfg_attr(feature = "bindings", derive(TS))]
8288pub struct Undrop {
8289    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8290    pub kind: String,
8291    /// The object name
8292    pub name: TableRef,
8293    /// IF EXISTS clause
8294    #[serde(default)]
8295    pub if_exists: bool,
8296    /// Snowflake: optional RENAME TO target
8297    #[serde(default, skip_serializing_if = "Option::is_none")]
8298    pub rename_to: Option<TableRef>,
8299}
8300
8301/// Partition scope for a TiDB `SPLIT TABLE` statement.
8302#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8303#[cfg_attr(feature = "bindings", derive(TS))]
8304#[serde(tag = "type", rename_all = "snake_case")]
8305pub enum SplitTablePartitionScope {
8306    Table,
8307    AllPartitions,
8308    Partitions { names: Vec<Identifier> },
8309}
8310
8311/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8313#[cfg_attr(feature = "bindings", derive(TS))]
8314#[serde(tag = "type", rename_all = "snake_case")]
8315pub enum SplitTableMode {
8316    Between {
8317        lower: Vec<Expression>,
8318        upper: Vec<Expression>,
8319        regions: u64,
8320    },
8321    By {
8322        points: Vec<Vec<Expression>>,
8323    },
8324}
8325
8326/// TiDB `SPLIT [PARTITION] TABLE` statement.
8327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8328#[cfg_attr(feature = "bindings", derive(TS))]
8329pub struct SplitTable {
8330    pub table: TableRef,
8331    pub partition_scope: SplitTablePartitionScope,
8332    #[serde(default, skip_serializing_if = "Option::is_none")]
8333    pub index: Option<Identifier>,
8334    pub mode: SplitTableMode,
8335}
8336
8337/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
8338#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8339#[cfg_attr(feature = "bindings", derive(TS))]
8340pub struct FlashbackTable {
8341    pub table: TableRef,
8342    #[serde(default, skip_serializing_if = "Option::is_none")]
8343    pub rename_to: Option<Identifier>,
8344}
8345
8346/// ALTER TABLE statement
8347#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8348#[cfg_attr(feature = "bindings", derive(TS))]
8349pub struct AlterTable {
8350    pub name: TableRef,
8351    pub actions: Vec<AlterTableAction>,
8352    /// IF EXISTS clause
8353    #[serde(default)]
8354    pub if_exists: bool,
8355    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8356    #[serde(default, skip_serializing_if = "Option::is_none")]
8357    pub algorithm: Option<String>,
8358    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8359    #[serde(default, skip_serializing_if = "Option::is_none")]
8360    pub lock: Option<String>,
8361    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8362    #[serde(default, skip_serializing_if = "Option::is_none")]
8363    pub with_check: Option<String>,
8364    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8365    #[serde(default, skip_serializing_if = "Option::is_none")]
8366    pub partition: Option<Vec<(Identifier, Expression)>>,
8367    /// ClickHouse: ON CLUSTER clause for distributed DDL
8368    #[serde(default, skip_serializing_if = "Option::is_none")]
8369    pub on_cluster: Option<OnCluster>,
8370    /// Snowflake: ALTER ICEBERG TABLE
8371    #[serde(default, skip_serializing_if = "Option::is_none")]
8372    pub table_modifier: Option<String>,
8373}
8374
8375impl AlterTable {
8376    pub fn new(name: impl Into<String>) -> Self {
8377        Self {
8378            name: TableRef::new(name),
8379            actions: Vec::new(),
8380            if_exists: false,
8381            algorithm: None,
8382            lock: None,
8383            with_check: None,
8384            partition: None,
8385            on_cluster: None,
8386            table_modifier: None,
8387        }
8388    }
8389}
8390
8391/// Column position for ADD COLUMN (MySQL/MariaDB)
8392#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8393#[cfg_attr(feature = "bindings", derive(TS))]
8394pub enum ColumnPosition {
8395    First,
8396    After(Identifier),
8397}
8398
8399/// Actions for ALTER TABLE
8400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8401#[cfg_attr(feature = "bindings", derive(TS))]
8402pub enum AlterTableAction {
8403    AddColumn {
8404        column: ColumnDef,
8405        if_not_exists: bool,
8406        position: Option<ColumnPosition>,
8407    },
8408    DropColumn {
8409        name: Identifier,
8410        if_exists: bool,
8411        cascade: bool,
8412    },
8413    RenameColumn {
8414        old_name: Identifier,
8415        new_name: Identifier,
8416        if_exists: bool,
8417    },
8418    AlterColumn {
8419        name: Identifier,
8420        action: AlterColumnAction,
8421        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8422        #[serde(default)]
8423        use_modify_keyword: bool,
8424    },
8425    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
8426    ModifyColumn {
8427        column: ColumnDef,
8428        if_exists: bool,
8429        position: Option<ColumnPosition>,
8430    },
8431    RenameTable(TableRef),
8432    AddConstraint(TableConstraint),
8433    DropConstraint {
8434        name: Identifier,
8435        if_exists: bool,
8436    },
8437    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8438    DropForeignKey {
8439        name: Identifier,
8440    },
8441    /// DROP PARTITION action (Hive/BigQuery)
8442    DropPartition {
8443        /// List of partitions to drop (each partition is a list of key=value pairs)
8444        partitions: Vec<Vec<(Identifier, Expression)>>,
8445        if_exists: bool,
8446    },
8447    /// ADD PARTITION action (Hive/Spark)
8448    AddPartition {
8449        /// The partition expression
8450        partition: Expression,
8451        if_not_exists: bool,
8452        location: Option<Expression>,
8453    },
8454    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8455    Delete {
8456        where_clause: Expression,
8457    },
8458    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8459    SwapWith(TableRef),
8460    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8461    SetProperty {
8462        properties: Vec<(String, Expression)>,
8463    },
8464    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8465    UnsetProperty {
8466        properties: Vec<String>,
8467    },
8468    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8469    ClusterBy {
8470        expressions: Vec<Expression>,
8471    },
8472    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8473    SetTag {
8474        expressions: Vec<(String, Expression)>,
8475    },
8476    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8477    UnsetTag {
8478        names: Vec<String>,
8479    },
8480    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8481    SetOptions {
8482        expressions: Vec<Expression>,
8483    },
8484    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8485    AlterIndex {
8486        name: Identifier,
8487        visible: bool,
8488    },
8489    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8490    SetAttribute {
8491        attribute: String,
8492    },
8493    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8494    SetStageFileFormat {
8495        options: Option<Expression>,
8496    },
8497    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8498    SetStageCopyOptions {
8499        options: Option<Expression>,
8500    },
8501    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8502    AddColumns {
8503        columns: Vec<ColumnDef>,
8504        cascade: bool,
8505    },
8506    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8507    DropColumns {
8508        names: Vec<Identifier>,
8509    },
8510    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8511    /// In SingleStore, data_type can be omitted for simple column renames
8512    ChangeColumn {
8513        old_name: Identifier,
8514        new_name: Identifier,
8515        #[serde(default, skip_serializing_if = "Option::is_none")]
8516        data_type: Option<DataType>,
8517        comment: Option<String>,
8518        #[serde(default)]
8519        cascade: bool,
8520    },
8521    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
8522    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
8523    AlterSortKey {
8524        /// AUTO or NONE keyword
8525        this: Option<String>,
8526        /// Column list for (col1, col2) syntax
8527        expressions: Vec<Expression>,
8528        /// Whether COMPOUND keyword was present
8529        compound: bool,
8530    },
8531    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
8532    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
8533    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
8534    AlterDistStyle {
8535        /// Distribution style: ALL, EVEN, AUTO, or KEY
8536        style: String,
8537        /// DISTKEY column (only when style is KEY)
8538        distkey: Option<Identifier>,
8539    },
8540    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
8541    SetTableProperties {
8542        properties: Vec<(Expression, Expression)>,
8543    },
8544    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
8545    SetLocation {
8546        location: String,
8547    },
8548    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
8549    SetFileFormat {
8550        format: String,
8551    },
8552    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
8553    ReplacePartition {
8554        partition: Expression,
8555        source: Option<Box<Expression>>,
8556    },
8557    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
8558    SetTiDBTableOption {
8559        option: TiDBTableOption,
8560        #[serde(default)]
8561        force: bool,
8562    },
8563    /// TiDB `REMOVE TTL`.
8564    RemoveTiDBTtl {
8565        #[serde(default)]
8566        executable_comment: bool,
8567    },
8568    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
8569    Raw {
8570        sql: String,
8571    },
8572}
8573
8574/// Actions for ALTER COLUMN
8575#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8576#[cfg_attr(feature = "bindings", derive(TS))]
8577pub enum AlterColumnAction {
8578    SetDataType {
8579        data_type: DataType,
8580        /// USING expression for type conversion (PostgreSQL)
8581        using: Option<Expression>,
8582        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
8583        #[serde(default, skip_serializing_if = "Option::is_none")]
8584        collate: Option<String>,
8585    },
8586    SetDefault(Expression),
8587    DropDefault,
8588    SetNotNull,
8589    DropNotNull,
8590    /// Set column comment
8591    Comment(String),
8592    /// MySQL: SET VISIBLE
8593    SetVisible,
8594    /// MySQL: SET INVISIBLE
8595    SetInvisible,
8596}
8597
8598/// CREATE INDEX statement
8599#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8600#[cfg_attr(feature = "bindings", derive(TS))]
8601pub struct CreateIndex {
8602    pub name: Identifier,
8603    pub table: TableRef,
8604    pub columns: Vec<IndexColumn>,
8605    /// Expression-capable index key parts. This is used when an index contains
8606    /// functional key parts that cannot be represented by `columns`.
8607    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8608    pub key_parts: Vec<IndexKeyPart>,
8609    pub unique: bool,
8610    pub if_not_exists: bool,
8611    pub using: Option<String>,
8612    /// TSQL CLUSTERED/NONCLUSTERED modifier
8613    #[serde(default)]
8614    pub clustered: Option<String>,
8615    /// PostgreSQL CONCURRENTLY modifier
8616    #[serde(default)]
8617    pub concurrently: bool,
8618    /// PostgreSQL WHERE clause for partial indexes
8619    #[serde(default)]
8620    pub where_clause: Option<Box<Expression>>,
8621    /// PostgreSQL INCLUDE columns
8622    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8623    pub include_columns: Vec<Identifier>,
8624    /// TSQL WITH options (e.g., allow_page_locks=on)
8625    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8626    pub with_options: Vec<(String, String)>,
8627    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
8628    #[serde(default)]
8629    pub on_filegroup: Option<String>,
8630}
8631
8632impl CreateIndex {
8633    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
8634        Self {
8635            name: Identifier::new(name),
8636            table: TableRef::new(table),
8637            columns: Vec::new(),
8638            key_parts: Vec::new(),
8639            unique: false,
8640            if_not_exists: false,
8641            using: None,
8642            clustered: None,
8643            concurrently: false,
8644            where_clause: None,
8645            include_columns: Vec::new(),
8646            with_options: Vec::new(),
8647            on_filegroup: None,
8648        }
8649    }
8650}
8651
8652/// Index column specification
8653#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8654#[cfg_attr(feature = "bindings", derive(TS))]
8655pub struct IndexColumn {
8656    pub column: Identifier,
8657    pub desc: bool,
8658    /// Explicit ASC keyword was present
8659    #[serde(default)]
8660    pub asc: bool,
8661    pub nulls_first: Option<bool>,
8662    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
8663    #[serde(default, skip_serializing_if = "Option::is_none")]
8664    pub opclass: Option<String>,
8665}
8666
8667/// An expression-capable index key part.
8668#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8669#[cfg_attr(feature = "bindings", derive(TS))]
8670pub struct IndexKeyPart {
8671    pub expression: Box<Expression>,
8672    /// MySQL column prefix length, for example the `16` in `name(16)`.
8673    #[serde(default, skip_serializing_if = "Option::is_none")]
8674    pub prefix_length: Option<String>,
8675    pub desc: bool,
8676    /// Explicit ASC keyword was present.
8677    #[serde(default)]
8678    pub asc: bool,
8679    pub nulls_first: Option<bool>,
8680    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops).
8681    #[serde(default, skip_serializing_if = "Option::is_none")]
8682    pub opclass: Option<String>,
8683}
8684
8685/// DROP INDEX statement
8686#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8687#[cfg_attr(feature = "bindings", derive(TS))]
8688pub struct DropIndex {
8689    pub name: TableRef,
8690    pub table: Option<TableRef>,
8691    pub if_exists: bool,
8692    /// PostgreSQL CONCURRENTLY modifier
8693    #[serde(default)]
8694    pub concurrently: bool,
8695}
8696
8697impl DropIndex {
8698    pub fn new(name: impl Into<String>) -> Self {
8699        Self {
8700            name: TableRef::new(name),
8701            table: None,
8702            if_exists: false,
8703            concurrently: false,
8704        }
8705    }
8706}
8707
8708/// View column definition with optional COMMENT and OPTIONS (BigQuery)
8709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8710#[cfg_attr(feature = "bindings", derive(TS))]
8711pub struct ViewColumn {
8712    pub name: Identifier,
8713    pub comment: Option<String>,
8714    /// BigQuery: OPTIONS (key=value, ...) on column
8715    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8716    pub options: Vec<Expression>,
8717}
8718
8719impl ViewColumn {
8720    pub fn new(name: impl Into<String>) -> Self {
8721        Self {
8722            name: Identifier::new(name),
8723            comment: None,
8724            options: Vec::new(),
8725        }
8726    }
8727
8728    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
8729        Self {
8730            name: Identifier::new(name),
8731            comment: Some(comment.into()),
8732            options: Vec::new(),
8733        }
8734    }
8735}
8736
8737/// CREATE VIEW statement
8738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8739#[cfg_attr(feature = "bindings", derive(TS))]
8740pub struct CreateView {
8741    pub name: TableRef,
8742    pub columns: Vec<ViewColumn>,
8743    pub query: Expression,
8744    pub or_replace: bool,
8745    /// TSQL: CREATE OR ALTER
8746    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
8747    pub or_alter: bool,
8748    pub if_not_exists: bool,
8749    pub materialized: bool,
8750    pub temporary: bool,
8751    /// Snowflake: SECURE VIEW
8752    #[serde(default)]
8753    pub secure: bool,
8754    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
8755    #[serde(skip_serializing_if = "Option::is_none")]
8756    pub algorithm: Option<String>,
8757    /// MySQL: DEFINER=user@host
8758    #[serde(skip_serializing_if = "Option::is_none")]
8759    pub definer: Option<String>,
8760    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
8761    #[serde(skip_serializing_if = "Option::is_none")]
8762    pub security: Option<FunctionSecurity>,
8763    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
8764    #[serde(default = "default_true")]
8765    pub security_sql_style: bool,
8766    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
8767    #[serde(default)]
8768    pub security_after_name: bool,
8769    /// Whether the query was parenthesized: AS (SELECT ...)
8770    #[serde(default)]
8771    pub query_parenthesized: bool,
8772    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
8773    #[serde(skip_serializing_if = "Option::is_none")]
8774    pub locking_mode: Option<String>,
8775    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
8776    #[serde(skip_serializing_if = "Option::is_none")]
8777    pub locking_access: Option<String>,
8778    /// Snowflake: COPY GRANTS
8779    #[serde(default)]
8780    pub copy_grants: bool,
8781    /// Snowflake: COMMENT = 'text'
8782    #[serde(skip_serializing_if = "Option::is_none", default)]
8783    pub comment: Option<String>,
8784    /// Snowflake: WITH ROW ACCESS POLICY ... clause
8785    #[serde(skip_serializing_if = "Option::is_none", default)]
8786    pub row_access_policy: Option<String>,
8787    /// Snowflake: TAG (name='value', ...)
8788    #[serde(default)]
8789    pub tags: Vec<(String, String)>,
8790    /// BigQuery: OPTIONS (key=value, ...)
8791    #[serde(default)]
8792    pub options: Vec<Expression>,
8793    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
8794    #[serde(skip_serializing_if = "Option::is_none", default)]
8795    pub build: Option<String>,
8796    /// Doris: REFRESH property for materialized views
8797    #[serde(skip_serializing_if = "Option::is_none", default)]
8798    pub refresh: Option<Box<RefreshTriggerProperty>>,
8799    /// Doris: Schema with typed column definitions for materialized views
8800    /// This is used instead of `columns` when the view has typed column definitions
8801    #[serde(skip_serializing_if = "Option::is_none", default)]
8802    pub schema: Option<Box<Schema>>,
8803    /// Doris: KEY (columns) for materialized views
8804    #[serde(skip_serializing_if = "Option::is_none", default)]
8805    pub unique_key: Option<Box<UniqueKeyProperty>>,
8806    /// Redshift: WITH NO SCHEMA BINDING
8807    #[serde(default)]
8808    pub no_schema_binding: bool,
8809    /// Redshift: AUTO REFRESH YES|NO for materialized views
8810    #[serde(skip_serializing_if = "Option::is_none", default)]
8811    pub auto_refresh: Option<bool>,
8812    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
8813    #[serde(skip_serializing_if = "Option::is_none", default)]
8814    pub clickhouse_population: Option<String>,
8815    /// ClickHouse: ON CLUSTER clause
8816    #[serde(default, skip_serializing_if = "Option::is_none")]
8817    pub on_cluster: Option<OnCluster>,
8818    /// ClickHouse: TO destination_table
8819    #[serde(default, skip_serializing_if = "Option::is_none")]
8820    pub to_table: Option<TableRef>,
8821    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
8822    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8823    pub table_properties: Vec<Expression>,
8824}
8825
8826impl CreateView {
8827    pub fn new(name: impl Into<String>, query: Expression) -> Self {
8828        Self {
8829            name: TableRef::new(name),
8830            columns: Vec::new(),
8831            query,
8832            or_replace: false,
8833            or_alter: false,
8834            if_not_exists: false,
8835            materialized: false,
8836            temporary: false,
8837            secure: false,
8838            algorithm: None,
8839            definer: None,
8840            security: None,
8841            security_sql_style: true,
8842            security_after_name: false,
8843            query_parenthesized: false,
8844            locking_mode: None,
8845            locking_access: None,
8846            copy_grants: false,
8847            comment: None,
8848            row_access_policy: None,
8849            tags: Vec::new(),
8850            options: Vec::new(),
8851            build: None,
8852            refresh: None,
8853            schema: None,
8854            unique_key: None,
8855            no_schema_binding: false,
8856            auto_refresh: None,
8857            clickhouse_population: None,
8858            on_cluster: None,
8859            to_table: None,
8860            table_properties: Vec::new(),
8861        }
8862    }
8863}
8864
8865/// DROP VIEW statement
8866#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8867#[cfg_attr(feature = "bindings", derive(TS))]
8868pub struct DropView {
8869    pub name: TableRef,
8870    pub if_exists: bool,
8871    pub materialized: bool,
8872}
8873
8874impl DropView {
8875    pub fn new(name: impl Into<String>) -> Self {
8876        Self {
8877            name: TableRef::new(name),
8878            if_exists: false,
8879            materialized: false,
8880        }
8881    }
8882}
8883
8884/// TRUNCATE TABLE statement
8885#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8886#[cfg_attr(feature = "bindings", derive(TS))]
8887pub struct Truncate {
8888    /// Target of TRUNCATE (TABLE vs DATABASE)
8889    #[serde(default)]
8890    pub target: TruncateTarget,
8891    /// IF EXISTS clause
8892    #[serde(default)]
8893    pub if_exists: bool,
8894    pub table: TableRef,
8895    /// ClickHouse: ON CLUSTER clause for distributed DDL
8896    #[serde(default, skip_serializing_if = "Option::is_none")]
8897    pub on_cluster: Option<OnCluster>,
8898    pub cascade: bool,
8899    /// Additional tables for multi-table TRUNCATE
8900    #[serde(default)]
8901    pub extra_tables: Vec<TruncateTableEntry>,
8902    /// RESTART IDENTITY or CONTINUE IDENTITY
8903    #[serde(default)]
8904    pub identity: Option<TruncateIdentity>,
8905    /// RESTRICT option (alternative to CASCADE)
8906    #[serde(default)]
8907    pub restrict: bool,
8908    /// Hive PARTITION clause: PARTITION(key=value, ...)
8909    #[serde(default, skip_serializing_if = "Option::is_none")]
8910    pub partition: Option<Box<Expression>>,
8911}
8912
8913/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
8914#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8915#[cfg_attr(feature = "bindings", derive(TS))]
8916pub struct TruncateTableEntry {
8917    pub table: TableRef,
8918    /// Whether the table has a * suffix (inherit children)
8919    #[serde(default)]
8920    pub star: bool,
8921}
8922
8923/// TRUNCATE target type
8924#[derive(
8925    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8926)]
8927#[cfg_attr(feature = "bindings", derive(TS))]
8928pub enum TruncateTarget {
8929    Table,
8930    Database,
8931}
8932
8933impl Default for TruncateTarget {
8934    fn default() -> Self {
8935        TruncateTarget::Table
8936    }
8937}
8938
8939/// TRUNCATE identity option
8940#[derive(
8941    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8942)]
8943#[cfg_attr(feature = "bindings", derive(TS))]
8944pub enum TruncateIdentity {
8945    Restart,
8946    Continue,
8947}
8948
8949impl Truncate {
8950    pub fn new(table: impl Into<String>) -> Self {
8951        Self {
8952            target: TruncateTarget::Table,
8953            if_exists: false,
8954            table: TableRef::new(table),
8955            on_cluster: None,
8956            cascade: false,
8957            extra_tables: Vec::new(),
8958            identity: None,
8959            restrict: false,
8960            partition: None,
8961        }
8962    }
8963}
8964
8965/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
8966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8967#[cfg_attr(feature = "bindings", derive(TS))]
8968pub struct Use {
8969    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
8970    pub kind: Option<UseKind>,
8971    /// The name of the object
8972    pub this: Identifier,
8973}
8974
8975/// Kind of USE statement
8976#[derive(
8977    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8978)]
8979#[cfg_attr(feature = "bindings", derive(TS))]
8980pub enum UseKind {
8981    Database,
8982    Schema,
8983    Role,
8984    Warehouse,
8985    Catalog,
8986    /// Snowflake: USE SECONDARY ROLES ALL|NONE
8987    SecondaryRoles,
8988}
8989
8990/// SET variable statement
8991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8992#[cfg_attr(feature = "bindings", derive(TS))]
8993pub struct SetStatement {
8994    /// The items being set
8995    pub items: Vec<SetItem>,
8996}
8997
8998/// A single SET item (variable assignment)
8999#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9000#[cfg_attr(feature = "bindings", derive(TS))]
9001pub struct SetItem {
9002    /// The variable name
9003    pub name: Expression,
9004    /// The value to set
9005    pub value: Expression,
9006    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
9007    pub kind: Option<String>,
9008    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
9009    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9010    pub no_equals: bool,
9011}
9012
9013/// CACHE TABLE statement (Spark)
9014#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9015#[cfg_attr(feature = "bindings", derive(TS))]
9016pub struct Cache {
9017    /// The table to cache
9018    pub table: Identifier,
9019    /// LAZY keyword - defer caching until first use
9020    pub lazy: bool,
9021    /// Optional OPTIONS clause (key-value pairs)
9022    pub options: Vec<(Expression, Expression)>,
9023    /// Optional AS clause with query
9024    pub query: Option<Expression>,
9025}
9026
9027/// UNCACHE TABLE statement (Spark)
9028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9029#[cfg_attr(feature = "bindings", derive(TS))]
9030pub struct Uncache {
9031    /// The table to uncache
9032    pub table: Identifier,
9033    /// IF EXISTS clause
9034    pub if_exists: bool,
9035}
9036
9037/// LOAD DATA statement (Hive)
9038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9039#[cfg_attr(feature = "bindings", derive(TS))]
9040pub struct LoadData {
9041    /// LOCAL keyword - load from local filesystem
9042    pub local: bool,
9043    /// The path to load data from (INPATH value)
9044    pub inpath: String,
9045    /// Whether to overwrite existing data
9046    pub overwrite: bool,
9047    /// The target table
9048    pub table: Expression,
9049    /// Optional PARTITION clause with key-value pairs
9050    pub partition: Vec<(Identifier, Expression)>,
9051    /// Optional INPUTFORMAT clause
9052    pub input_format: Option<String>,
9053    /// Optional SERDE clause
9054    pub serde: Option<String>,
9055}
9056
9057/// PRAGMA statement (SQLite)
9058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9059#[cfg_attr(feature = "bindings", derive(TS))]
9060pub struct Pragma {
9061    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
9062    pub schema: Option<Identifier>,
9063    /// The pragma name
9064    pub name: Identifier,
9065    /// Optional value for assignment (PRAGMA name = value)
9066    pub value: Option<Expression>,
9067    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
9068    pub args: Vec<Expression>,
9069    /// Whether this pragma should be generated using assignment syntax.
9070    #[serde(default)]
9071    pub use_assignment_syntax: bool,
9072}
9073
9074/// A privilege with optional column list for GRANT/REVOKE
9075/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
9076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9077#[cfg_attr(feature = "bindings", derive(TS))]
9078pub struct Privilege {
9079    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
9080    pub name: String,
9081    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
9082    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9083    pub columns: Vec<String>,
9084}
9085
9086/// Principal in GRANT/REVOKE (user, role, etc.)
9087#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9088#[cfg_attr(feature = "bindings", derive(TS))]
9089pub struct GrantPrincipal {
9090    /// The name of the principal
9091    pub name: Identifier,
9092    /// Whether prefixed with ROLE keyword
9093    pub is_role: bool,
9094    /// Whether prefixed with GROUP keyword (Redshift)
9095    #[serde(default)]
9096    pub is_group: bool,
9097    /// Whether prefixed with SHARE keyword (Snowflake)
9098    #[serde(default)]
9099    pub is_share: bool,
9100}
9101
9102/// GRANT statement
9103#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9104#[cfg_attr(feature = "bindings", derive(TS))]
9105pub struct Grant {
9106    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
9107    pub privileges: Vec<Privilege>,
9108    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9109    pub kind: Option<String>,
9110    /// The object to grant on
9111    pub securable: Identifier,
9112    /// Function parameter types (for FUNCTION kind)
9113    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9114    pub function_params: Vec<String>,
9115    /// The grantees
9116    pub principals: Vec<GrantPrincipal>,
9117    /// WITH GRANT OPTION
9118    pub grant_option: bool,
9119    /// TSQL: AS principal (the grantor role)
9120    #[serde(default, skip_serializing_if = "Option::is_none")]
9121    pub as_principal: Option<Identifier>,
9122}
9123
9124/// REVOKE statement
9125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9126#[cfg_attr(feature = "bindings", derive(TS))]
9127pub struct Revoke {
9128    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9129    pub privileges: Vec<Privilege>,
9130    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9131    pub kind: Option<String>,
9132    /// The object to revoke from
9133    pub securable: Identifier,
9134    /// Function parameter types (for FUNCTION kind)
9135    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9136    pub function_params: Vec<String>,
9137    /// The grantees
9138    pub principals: Vec<GrantPrincipal>,
9139    /// GRANT OPTION FOR
9140    pub grant_option: bool,
9141    /// CASCADE
9142    pub cascade: bool,
9143    /// RESTRICT
9144    #[serde(default)]
9145    pub restrict: bool,
9146}
9147
9148/// COMMENT ON statement
9149#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9150#[cfg_attr(feature = "bindings", derive(TS))]
9151pub struct Comment {
9152    /// The object being commented on
9153    pub this: Expression,
9154    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9155    pub kind: String,
9156    /// The comment text expression
9157    pub expression: Expression,
9158    /// IF EXISTS clause
9159    pub exists: bool,
9160    /// MATERIALIZED keyword
9161    pub materialized: bool,
9162}
9163
9164// ============================================================================
9165// Phase 4: Additional DDL Statements
9166// ============================================================================
9167
9168/// ALTER VIEW statement
9169#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9170#[cfg_attr(feature = "bindings", derive(TS))]
9171pub struct AlterView {
9172    pub name: TableRef,
9173    pub actions: Vec<AlterViewAction>,
9174    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9175    #[serde(default, skip_serializing_if = "Option::is_none")]
9176    pub algorithm: Option<String>,
9177    /// MySQL: DEFINER = 'user'@'host'
9178    #[serde(default, skip_serializing_if = "Option::is_none")]
9179    pub definer: Option<String>,
9180    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9181    #[serde(default, skip_serializing_if = "Option::is_none")]
9182    pub sql_security: Option<String>,
9183    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9184    #[serde(default, skip_serializing_if = "Option::is_none")]
9185    pub with_option: Option<String>,
9186    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9187    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9188    pub columns: Vec<ViewColumn>,
9189}
9190
9191/// Actions for ALTER VIEW
9192#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9193#[cfg_attr(feature = "bindings", derive(TS))]
9194pub enum AlterViewAction {
9195    /// Rename the view
9196    Rename(TableRef),
9197    /// Change owner
9198    OwnerTo(Identifier),
9199    /// Set schema
9200    SetSchema(Identifier),
9201    /// Set authorization (Trino/Presto)
9202    SetAuthorization(String),
9203    /// Alter column
9204    AlterColumn {
9205        name: Identifier,
9206        action: AlterColumnAction,
9207    },
9208    /// Redefine view as query (SELECT, UNION, etc.)
9209    AsSelect(Box<Expression>),
9210    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9211    SetTblproperties(Vec<(String, String)>),
9212    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9213    UnsetTblproperties(Vec<String>),
9214}
9215
9216impl AlterView {
9217    pub fn new(name: impl Into<String>) -> Self {
9218        Self {
9219            name: TableRef::new(name),
9220            actions: Vec::new(),
9221            algorithm: None,
9222            definer: None,
9223            sql_security: None,
9224            with_option: None,
9225            columns: Vec::new(),
9226        }
9227    }
9228}
9229
9230/// ALTER INDEX statement
9231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9232#[cfg_attr(feature = "bindings", derive(TS))]
9233pub struct AlterIndex {
9234    pub name: Identifier,
9235    pub table: Option<TableRef>,
9236    pub actions: Vec<AlterIndexAction>,
9237}
9238
9239/// Actions for ALTER INDEX
9240#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9241#[cfg_attr(feature = "bindings", derive(TS))]
9242pub enum AlterIndexAction {
9243    /// Rename the index
9244    Rename(Identifier),
9245    /// Set tablespace
9246    SetTablespace(Identifier),
9247    /// Set visibility (MySQL)
9248    Visible(bool),
9249}
9250
9251impl AlterIndex {
9252    pub fn new(name: impl Into<String>) -> Self {
9253        Self {
9254            name: Identifier::new(name),
9255            table: None,
9256            actions: Vec::new(),
9257        }
9258    }
9259}
9260
9261/// CREATE SCHEMA statement
9262#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9263#[cfg_attr(feature = "bindings", derive(TS))]
9264pub struct CreateSchema {
9265    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9266    pub name: Vec<Identifier>,
9267    pub if_not_exists: bool,
9268    pub authorization: Option<Identifier>,
9269    /// CLONE source parts, possibly dot-qualified
9270    #[serde(default)]
9271    pub clone_from: Option<Vec<Identifier>>,
9272    /// AT/BEFORE clause for time travel (Snowflake)
9273    #[serde(default)]
9274    pub at_clause: Option<Expression>,
9275    /// Schema properties like DEFAULT COLLATE
9276    #[serde(default)]
9277    pub properties: Vec<Expression>,
9278    /// Leading comments before the statement
9279    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9280    pub leading_comments: Vec<String>,
9281}
9282
9283impl CreateSchema {
9284    pub fn new(name: impl Into<String>) -> Self {
9285        Self {
9286            name: vec![Identifier::new(name)],
9287            if_not_exists: false,
9288            authorization: None,
9289            clone_from: None,
9290            at_clause: None,
9291            properties: Vec::new(),
9292            leading_comments: Vec::new(),
9293        }
9294    }
9295}
9296
9297/// DROP SCHEMA statement
9298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9299#[cfg_attr(feature = "bindings", derive(TS))]
9300pub struct DropSchema {
9301    pub name: Identifier,
9302    pub if_exists: bool,
9303    pub cascade: bool,
9304}
9305
9306impl DropSchema {
9307    pub fn new(name: impl Into<String>) -> Self {
9308        Self {
9309            name: Identifier::new(name),
9310            if_exists: false,
9311            cascade: false,
9312        }
9313    }
9314}
9315
9316/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9317#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9318#[cfg_attr(feature = "bindings", derive(TS))]
9319pub struct DropNamespace {
9320    pub name: Identifier,
9321    pub if_exists: bool,
9322    pub cascade: bool,
9323}
9324
9325impl DropNamespace {
9326    pub fn new(name: impl Into<String>) -> Self {
9327        Self {
9328            name: Identifier::new(name),
9329            if_exists: false,
9330            cascade: false,
9331        }
9332    }
9333}
9334
9335/// CREATE DATABASE statement
9336#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9337#[cfg_attr(feature = "bindings", derive(TS))]
9338pub struct CreateDatabase {
9339    pub name: Identifier,
9340    pub if_not_exists: bool,
9341    pub options: Vec<DatabaseOption>,
9342    /// Snowflake CLONE source
9343    #[serde(default)]
9344    pub clone_from: Option<Identifier>,
9345    /// AT/BEFORE clause for time travel (Snowflake)
9346    #[serde(default)]
9347    pub at_clause: Option<Expression>,
9348}
9349
9350/// Database option
9351#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9352#[cfg_attr(feature = "bindings", derive(TS))]
9353pub enum DatabaseOption {
9354    CharacterSet(String),
9355    Collate(String),
9356    Owner(Identifier),
9357    Template(Identifier),
9358    Encoding(String),
9359    Location(String),
9360}
9361
9362impl CreateDatabase {
9363    pub fn new(name: impl Into<String>) -> Self {
9364        Self {
9365            name: Identifier::new(name),
9366            if_not_exists: false,
9367            options: Vec::new(),
9368            clone_from: None,
9369            at_clause: None,
9370        }
9371    }
9372}
9373
9374/// DROP DATABASE statement
9375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9376#[cfg_attr(feature = "bindings", derive(TS))]
9377pub struct DropDatabase {
9378    pub name: Identifier,
9379    pub if_exists: bool,
9380    /// ClickHouse: SYNC modifier
9381    #[serde(default)]
9382    pub sync: bool,
9383}
9384
9385impl DropDatabase {
9386    pub fn new(name: impl Into<String>) -> Self {
9387        Self {
9388            name: Identifier::new(name),
9389            if_exists: false,
9390            sync: false,
9391        }
9392    }
9393}
9394
9395/// CREATE FUNCTION statement
9396#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9397#[cfg_attr(feature = "bindings", derive(TS))]
9398pub struct CreateFunction {
9399    pub name: TableRef,
9400    pub parameters: Vec<FunctionParameter>,
9401    pub return_type: Option<DataType>,
9402    pub body: Option<FunctionBody>,
9403    pub or_replace: bool,
9404    /// TSQL: CREATE OR ALTER
9405    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9406    pub or_alter: bool,
9407    pub if_not_exists: bool,
9408    pub temporary: bool,
9409    pub language: Option<String>,
9410    pub deterministic: Option<bool>,
9411    pub returns_null_on_null_input: Option<bool>,
9412    pub security: Option<FunctionSecurity>,
9413    /// Whether parentheses were present in the original syntax
9414    #[serde(default = "default_true")]
9415    pub has_parens: bool,
9416    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9417    #[serde(default)]
9418    pub sql_data_access: Option<SqlDataAccess>,
9419    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9420    #[serde(default, skip_serializing_if = "Option::is_none")]
9421    pub returns_table_body: Option<String>,
9422    /// True if LANGUAGE clause appears before RETURNS clause
9423    #[serde(default)]
9424    pub language_first: bool,
9425    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9426    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9427    pub set_options: Vec<FunctionSetOption>,
9428    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9429    #[serde(default)]
9430    pub strict: bool,
9431    /// BigQuery: OPTIONS (key=value, ...)
9432    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9433    pub options: Vec<Expression>,
9434    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9435    #[serde(default)]
9436    pub is_table_function: bool,
9437    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9438    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9439    pub property_order: Vec<FunctionPropertyKind>,
9440    /// Hive: USING JAR|FILE|ARCHIVE '...'
9441    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9442    pub using_resources: Vec<FunctionUsingResource>,
9443    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9444    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9445    pub environment: Vec<Expression>,
9446    /// HANDLER 'handler_function' clause (Databricks)
9447    #[serde(default, skip_serializing_if = "Option::is_none")]
9448    pub handler: Option<String>,
9449    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9450    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9451    pub handler_uses_eq: bool,
9452    /// Snowflake: RUNTIME_VERSION='3.11'
9453    #[serde(default, skip_serializing_if = "Option::is_none")]
9454    pub runtime_version: Option<String>,
9455    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9456    #[serde(default, skip_serializing_if = "Option::is_none")]
9457    pub packages: Option<Vec<String>>,
9458    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9459    #[serde(default, skip_serializing_if = "Option::is_none")]
9460    pub parameter_style: Option<String>,
9461}
9462
9463/// A SET option in CREATE FUNCTION (PostgreSQL)
9464#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9465#[cfg_attr(feature = "bindings", derive(TS))]
9466pub struct FunctionSetOption {
9467    pub name: String,
9468    pub value: FunctionSetValue,
9469}
9470
9471/// The value of a SET option
9472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9473#[cfg_attr(feature = "bindings", derive(TS))]
9474pub enum FunctionSetValue {
9475    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9476    Value { value: String, use_to: bool },
9477    /// SET key FROM CURRENT
9478    FromCurrent,
9479}
9480
9481/// SQL data access characteristics for functions
9482#[derive(
9483    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9484)]
9485#[cfg_attr(feature = "bindings", derive(TS))]
9486pub enum SqlDataAccess {
9487    /// NO SQL
9488    NoSql,
9489    /// CONTAINS SQL
9490    ContainsSql,
9491    /// READS SQL DATA
9492    ReadsSqlData,
9493    /// MODIFIES SQL DATA
9494    ModifiesSqlData,
9495}
9496
9497/// Types of properties in CREATE FUNCTION for tracking their original order
9498#[derive(
9499    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9500)]
9501#[cfg_attr(feature = "bindings", derive(TS))]
9502pub enum FunctionPropertyKind {
9503    /// SET option
9504    Set,
9505    /// AS body
9506    As,
9507    /// Hive: USING JAR|FILE|ARCHIVE ...
9508    Using,
9509    /// LANGUAGE clause
9510    Language,
9511    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9512    Determinism,
9513    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
9514    NullInput,
9515    /// SECURITY DEFINER/INVOKER
9516    Security,
9517    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
9518    SqlDataAccess,
9519    /// OPTIONS clause (BigQuery)
9520    Options,
9521    /// ENVIRONMENT clause (Databricks)
9522    Environment,
9523    /// HANDLER clause (Databricks)
9524    Handler,
9525    /// Snowflake: RUNTIME_VERSION='...'
9526    RuntimeVersion,
9527    /// Snowflake: PACKAGES=(...)
9528    Packages,
9529    /// PARAMETER STYLE clause (Databricks)
9530    ParameterStyle,
9531}
9532
9533/// Hive CREATE FUNCTION resource in a USING clause
9534#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9535#[cfg_attr(feature = "bindings", derive(TS))]
9536pub struct FunctionUsingResource {
9537    pub kind: String,
9538    pub uri: String,
9539}
9540
9541/// Function parameter
9542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9543#[cfg_attr(feature = "bindings", derive(TS))]
9544pub struct FunctionParameter {
9545    pub name: Option<Identifier>,
9546    pub data_type: DataType,
9547    pub mode: Option<ParameterMode>,
9548    pub default: Option<Expression>,
9549    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
9550    #[serde(default, skip_serializing_if = "Option::is_none")]
9551    pub mode_text: Option<String>,
9552}
9553
9554/// Parameter mode (IN, OUT, INOUT, VARIADIC)
9555#[derive(
9556    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9557)]
9558#[cfg_attr(feature = "bindings", derive(TS))]
9559pub enum ParameterMode {
9560    In,
9561    Out,
9562    InOut,
9563    Variadic,
9564}
9565
9566/// Function body
9567#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9568#[cfg_attr(feature = "bindings", derive(TS))]
9569pub enum FunctionBody {
9570    /// AS $$ ... $$ (dollar-quoted)
9571    Block(String),
9572    /// AS 'string' (single-quoted string literal body)
9573    StringLiteral(String),
9574    /// AS 'expression'
9575    Expression(Expression),
9576    /// EXTERNAL NAME 'library'
9577    External(String),
9578    /// RETURN expression
9579    Return(Expression),
9580    /// BEGIN ... END block with parsed statements
9581    Statements(Vec<Expression>),
9582    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
9583    /// Stores (content, optional_tag)
9584    DollarQuoted {
9585        content: String,
9586        tag: Option<String>,
9587    },
9588    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
9589    RawBlock(String),
9590}
9591
9592/// Function security (DEFINER, INVOKER, or NONE)
9593#[derive(
9594    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9595)]
9596#[cfg_attr(feature = "bindings", derive(TS))]
9597pub enum FunctionSecurity {
9598    Definer,
9599    Invoker,
9600    /// StarRocks/MySQL: SECURITY NONE
9601    None,
9602}
9603
9604impl CreateFunction {
9605    pub fn new(name: impl Into<String>) -> Self {
9606        Self {
9607            name: TableRef::new(name),
9608            parameters: Vec::new(),
9609            return_type: None,
9610            body: None,
9611            or_replace: false,
9612            or_alter: false,
9613            if_not_exists: false,
9614            temporary: false,
9615            language: None,
9616            deterministic: None,
9617            returns_null_on_null_input: None,
9618            security: None,
9619            has_parens: true,
9620            sql_data_access: None,
9621            returns_table_body: None,
9622            language_first: false,
9623            set_options: Vec::new(),
9624            strict: false,
9625            options: Vec::new(),
9626            is_table_function: false,
9627            property_order: Vec::new(),
9628            using_resources: Vec::new(),
9629            environment: Vec::new(),
9630            handler: None,
9631            handler_uses_eq: false,
9632            runtime_version: None,
9633            packages: None,
9634            parameter_style: None,
9635        }
9636    }
9637}
9638
9639/// DROP FUNCTION statement
9640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9641#[cfg_attr(feature = "bindings", derive(TS))]
9642pub struct DropFunction {
9643    pub name: TableRef,
9644    pub parameters: Option<Vec<DataType>>,
9645    pub if_exists: bool,
9646    pub cascade: bool,
9647}
9648
9649impl DropFunction {
9650    pub fn new(name: impl Into<String>) -> Self {
9651        Self {
9652            name: TableRef::new(name),
9653            parameters: None,
9654            if_exists: false,
9655            cascade: false,
9656        }
9657    }
9658}
9659
9660/// CREATE PROCEDURE statement
9661#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9662#[cfg_attr(feature = "bindings", derive(TS))]
9663pub struct CreateProcedure {
9664    pub name: TableRef,
9665    pub parameters: Vec<FunctionParameter>,
9666    pub body: Option<FunctionBody>,
9667    pub or_replace: bool,
9668    /// TSQL: CREATE OR ALTER
9669    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9670    pub or_alter: bool,
9671    pub if_not_exists: bool,
9672    pub language: Option<String>,
9673    pub security: Option<FunctionSecurity>,
9674    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
9675    #[serde(default)]
9676    pub return_type: Option<DataType>,
9677    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
9678    #[serde(default)]
9679    pub execute_as: Option<String>,
9680    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
9681    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9682    pub with_options: Vec<String>,
9683    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
9684    #[serde(default = "default_true", skip_serializing_if = "is_true")]
9685    pub has_parens: bool,
9686    /// Whether the short form PROC was used (instead of PROCEDURE)
9687    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9688    pub use_proc_keyword: bool,
9689}
9690
9691impl CreateProcedure {
9692    pub fn new(name: impl Into<String>) -> Self {
9693        Self {
9694            name: TableRef::new(name),
9695            parameters: Vec::new(),
9696            body: None,
9697            or_replace: false,
9698            or_alter: false,
9699            if_not_exists: false,
9700            language: None,
9701            security: None,
9702            return_type: None,
9703            execute_as: None,
9704            with_options: Vec::new(),
9705            has_parens: true,
9706            use_proc_keyword: false,
9707        }
9708    }
9709}
9710
9711/// DROP PROCEDURE statement
9712#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9713#[cfg_attr(feature = "bindings", derive(TS))]
9714pub struct DropProcedure {
9715    pub name: TableRef,
9716    pub parameters: Option<Vec<DataType>>,
9717    pub if_exists: bool,
9718    pub cascade: bool,
9719}
9720
9721impl DropProcedure {
9722    pub fn new(name: impl Into<String>) -> Self {
9723        Self {
9724            name: TableRef::new(name),
9725            parameters: None,
9726            if_exists: false,
9727            cascade: false,
9728        }
9729    }
9730}
9731
9732/// Sequence property tag for ordering
9733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9734#[cfg_attr(feature = "bindings", derive(TS))]
9735pub enum SeqPropKind {
9736    Start,
9737    Increment,
9738    Minvalue,
9739    Maxvalue,
9740    Cache,
9741    NoCache,
9742    Cycle,
9743    NoCycle,
9744    OwnedBy,
9745    Order,
9746    NoOrder,
9747    Comment,
9748    /// SHARING=<value> (Oracle)
9749    Sharing,
9750    /// KEEP (Oracle)
9751    Keep,
9752    /// NOKEEP (Oracle)
9753    NoKeep,
9754    /// SCALE [EXTEND|NOEXTEND] (Oracle)
9755    Scale,
9756    /// NOSCALE (Oracle)
9757    NoScale,
9758    /// SHARD [EXTEND|NOEXTEND] (Oracle)
9759    Shard,
9760    /// NOSHARD (Oracle)
9761    NoShard,
9762    /// SESSION (Oracle)
9763    Session,
9764    /// GLOBAL (Oracle)
9765    Global,
9766    /// NOCACHE (single word, Oracle)
9767    NoCacheWord,
9768    /// NOCYCLE (single word, Oracle)
9769    NoCycleWord,
9770    /// NOMINVALUE (single word, Oracle)
9771    NoMinvalueWord,
9772    /// NOMAXVALUE (single word, Oracle)
9773    NoMaxvalueWord,
9774}
9775
9776/// CREATE SYNONYM statement (TSQL)
9777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9778#[cfg_attr(feature = "bindings", derive(TS))]
9779pub struct CreateSynonym {
9780    /// The synonym name (can be qualified: schema.synonym_name)
9781    pub name: TableRef,
9782    /// The target object the synonym refers to
9783    pub target: TableRef,
9784}
9785
9786/// CREATE SEQUENCE statement
9787#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9788#[cfg_attr(feature = "bindings", derive(TS))]
9789pub struct CreateSequence {
9790    pub name: TableRef,
9791    pub if_not_exists: bool,
9792    pub temporary: bool,
9793    #[serde(default)]
9794    pub or_replace: bool,
9795    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
9796    #[serde(default, skip_serializing_if = "Option::is_none")]
9797    pub as_type: Option<DataType>,
9798    pub increment: Option<i64>,
9799    pub minvalue: Option<SequenceBound>,
9800    pub maxvalue: Option<SequenceBound>,
9801    pub start: Option<i64>,
9802    pub cache: Option<i64>,
9803    pub cycle: bool,
9804    pub owned_by: Option<TableRef>,
9805    /// Whether OWNED BY NONE was specified
9806    #[serde(default)]
9807    pub owned_by_none: bool,
9808    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
9809    #[serde(default)]
9810    pub order: Option<bool>,
9811    /// Snowflake: COMMENT = 'value'
9812    #[serde(default)]
9813    pub comment: Option<String>,
9814    /// SHARING=<value> (Oracle)
9815    #[serde(default, skip_serializing_if = "Option::is_none")]
9816    pub sharing: Option<String>,
9817    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
9818    #[serde(default, skip_serializing_if = "Option::is_none")]
9819    pub scale_modifier: Option<String>,
9820    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
9821    #[serde(default, skip_serializing_if = "Option::is_none")]
9822    pub shard_modifier: Option<String>,
9823    /// Tracks the order in which properties appeared in the source
9824    #[serde(default)]
9825    pub property_order: Vec<SeqPropKind>,
9826}
9827
9828/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
9829#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9830#[cfg_attr(feature = "bindings", derive(TS))]
9831pub enum SequenceBound {
9832    Value(i64),
9833    None,
9834}
9835
9836impl CreateSequence {
9837    pub fn new(name: impl Into<String>) -> Self {
9838        Self {
9839            name: TableRef::new(name),
9840            if_not_exists: false,
9841            temporary: false,
9842            or_replace: false,
9843            as_type: None,
9844            increment: None,
9845            minvalue: None,
9846            maxvalue: None,
9847            start: None,
9848            cache: None,
9849            cycle: false,
9850            owned_by: None,
9851            owned_by_none: false,
9852            order: None,
9853            comment: None,
9854            sharing: None,
9855            scale_modifier: None,
9856            shard_modifier: None,
9857            property_order: Vec::new(),
9858        }
9859    }
9860}
9861
9862/// DROP SEQUENCE statement
9863#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9864#[cfg_attr(feature = "bindings", derive(TS))]
9865pub struct DropSequence {
9866    pub name: TableRef,
9867    pub if_exists: bool,
9868    pub cascade: bool,
9869}
9870
9871impl DropSequence {
9872    pub fn new(name: impl Into<String>) -> Self {
9873        Self {
9874            name: TableRef::new(name),
9875            if_exists: false,
9876            cascade: false,
9877        }
9878    }
9879}
9880
9881/// ALTER SEQUENCE statement
9882#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9883#[cfg_attr(feature = "bindings", derive(TS))]
9884pub struct AlterSequence {
9885    pub name: TableRef,
9886    pub if_exists: bool,
9887    pub increment: Option<i64>,
9888    pub minvalue: Option<SequenceBound>,
9889    pub maxvalue: Option<SequenceBound>,
9890    pub start: Option<i64>,
9891    pub restart: Option<Option<i64>>,
9892    pub cache: Option<i64>,
9893    pub cycle: Option<bool>,
9894    pub owned_by: Option<Option<TableRef>>,
9895}
9896
9897impl AlterSequence {
9898    pub fn new(name: impl Into<String>) -> Self {
9899        Self {
9900            name: TableRef::new(name),
9901            if_exists: false,
9902            increment: None,
9903            minvalue: None,
9904            maxvalue: None,
9905            start: None,
9906            restart: None,
9907            cache: None,
9908            cycle: None,
9909            owned_by: None,
9910        }
9911    }
9912}
9913
9914/// CREATE TRIGGER statement
9915#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9916#[cfg_attr(feature = "bindings", derive(TS))]
9917pub struct CreateTrigger {
9918    pub name: Identifier,
9919    pub table: TableRef,
9920    pub timing: TriggerTiming,
9921    pub events: Vec<TriggerEvent>,
9922    #[serde(default, skip_serializing_if = "Option::is_none")]
9923    pub for_each: Option<TriggerForEach>,
9924    pub when: Option<Expression>,
9925    /// Whether the WHEN clause was parenthesized in the original SQL
9926    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9927    pub when_paren: bool,
9928    pub body: TriggerBody,
9929    pub or_replace: bool,
9930    /// TSQL: CREATE OR ALTER
9931    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9932    pub or_alter: bool,
9933    pub constraint: bool,
9934    pub deferrable: Option<bool>,
9935    pub initially_deferred: Option<bool>,
9936    pub referencing: Option<TriggerReferencing>,
9937}
9938
9939/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
9940#[derive(
9941    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9942)]
9943#[cfg_attr(feature = "bindings", derive(TS))]
9944pub enum TriggerTiming {
9945    Before,
9946    After,
9947    InsteadOf,
9948}
9949
9950/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
9951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9952#[cfg_attr(feature = "bindings", derive(TS))]
9953pub enum TriggerEvent {
9954    Insert,
9955    Update(Option<Vec<Identifier>>),
9956    Delete,
9957    Truncate,
9958}
9959
9960/// Trigger FOR EACH clause
9961#[derive(
9962    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9963)]
9964#[cfg_attr(feature = "bindings", derive(TS))]
9965pub enum TriggerForEach {
9966    Row,
9967    Statement,
9968}
9969
9970/// Trigger body
9971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9972#[cfg_attr(feature = "bindings", derive(TS))]
9973pub enum TriggerBody {
9974    /// EXECUTE FUNCTION/PROCEDURE name(args)
9975    Execute {
9976        function: TableRef,
9977        args: Vec<Expression>,
9978    },
9979    /// BEGIN ... END block
9980    Block(String),
9981}
9982
9983/// Trigger REFERENCING clause
9984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9985#[cfg_attr(feature = "bindings", derive(TS))]
9986pub struct TriggerReferencing {
9987    pub old_table: Option<Identifier>,
9988    pub new_table: Option<Identifier>,
9989    pub old_row: Option<Identifier>,
9990    pub new_row: Option<Identifier>,
9991}
9992
9993impl CreateTrigger {
9994    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
9995        Self {
9996            name: Identifier::new(name),
9997            table: TableRef::new(table),
9998            timing: TriggerTiming::Before,
9999            events: Vec::new(),
10000            for_each: Some(TriggerForEach::Row),
10001            when: None,
10002            when_paren: false,
10003            body: TriggerBody::Execute {
10004                function: TableRef::new(""),
10005                args: Vec::new(),
10006            },
10007            or_replace: false,
10008            or_alter: false,
10009            constraint: false,
10010            deferrable: None,
10011            initially_deferred: None,
10012            referencing: None,
10013        }
10014    }
10015}
10016
10017/// DROP TRIGGER statement
10018#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10019#[cfg_attr(feature = "bindings", derive(TS))]
10020pub struct DropTrigger {
10021    pub name: Identifier,
10022    pub table: Option<TableRef>,
10023    pub if_exists: bool,
10024    pub cascade: bool,
10025}
10026
10027impl DropTrigger {
10028    pub fn new(name: impl Into<String>) -> Self {
10029        Self {
10030            name: Identifier::new(name),
10031            table: None,
10032            if_exists: false,
10033            cascade: false,
10034        }
10035    }
10036}
10037
10038/// CREATE TYPE statement
10039#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10040#[cfg_attr(feature = "bindings", derive(TS))]
10041pub struct CreateType {
10042    pub name: TableRef,
10043    pub definition: TypeDefinition,
10044    pub if_not_exists: bool,
10045}
10046
10047/// Type definition
10048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10049#[cfg_attr(feature = "bindings", derive(TS))]
10050pub enum TypeDefinition {
10051    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
10052    Enum(Vec<String>),
10053    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
10054    Composite(Vec<TypeAttribute>),
10055    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
10056    Range {
10057        subtype: DataType,
10058        subtype_diff: Option<String>,
10059        canonical: Option<String>,
10060    },
10061    /// Base type (for advanced usage)
10062    Base {
10063        input: String,
10064        output: String,
10065        internallength: Option<i32>,
10066    },
10067    /// Domain type
10068    Domain {
10069        base_type: DataType,
10070        default: Option<Expression>,
10071        constraints: Vec<DomainConstraint>,
10072    },
10073}
10074
10075/// Type attribute for composite types
10076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10077#[cfg_attr(feature = "bindings", derive(TS))]
10078pub struct TypeAttribute {
10079    pub name: Identifier,
10080    pub data_type: DataType,
10081    pub collate: Option<Identifier>,
10082}
10083
10084/// Domain constraint
10085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10086#[cfg_attr(feature = "bindings", derive(TS))]
10087pub struct DomainConstraint {
10088    pub name: Option<Identifier>,
10089    pub check: Expression,
10090}
10091
10092impl CreateType {
10093    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
10094        Self {
10095            name: TableRef::new(name),
10096            definition: TypeDefinition::Enum(values),
10097            if_not_exists: false,
10098        }
10099    }
10100
10101    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
10102        Self {
10103            name: TableRef::new(name),
10104            definition: TypeDefinition::Composite(attributes),
10105            if_not_exists: false,
10106        }
10107    }
10108}
10109
10110/// DROP TYPE statement
10111#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10112#[cfg_attr(feature = "bindings", derive(TS))]
10113pub struct DropType {
10114    pub name: TableRef,
10115    pub if_exists: bool,
10116    pub cascade: bool,
10117}
10118
10119impl DropType {
10120    pub fn new(name: impl Into<String>) -> Self {
10121        Self {
10122            name: TableRef::new(name),
10123            if_exists: false,
10124            cascade: false,
10125        }
10126    }
10127}
10128
10129/// DESCRIBE statement - shows table structure or query plan
10130#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10131#[cfg_attr(feature = "bindings", derive(TS))]
10132pub struct Describe {
10133    /// The target to describe (table name or query)
10134    pub target: Expression,
10135    /// EXTENDED format
10136    pub extended: bool,
10137    /// FORMATTED format
10138    pub formatted: bool,
10139    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10140    #[serde(default)]
10141    pub kind: Option<String>,
10142    /// Properties like type=stage
10143    #[serde(default)]
10144    pub properties: Vec<(String, String)>,
10145    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10146    #[serde(default, skip_serializing_if = "Option::is_none")]
10147    pub style: Option<String>,
10148    /// Partition specification for DESCRIBE PARTITION
10149    #[serde(default)]
10150    pub partition: Option<Box<Expression>>,
10151    /// Leading comments before the statement
10152    #[serde(default)]
10153    pub leading_comments: Vec<String>,
10154    /// AS JSON suffix (Databricks)
10155    #[serde(default)]
10156    pub as_json: bool,
10157    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10158    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10159    pub params: Vec<String>,
10160}
10161
10162impl Describe {
10163    pub fn new(target: Expression) -> Self {
10164        Self {
10165            target,
10166            extended: false,
10167            formatted: false,
10168            kind: None,
10169            properties: Vec::new(),
10170            style: None,
10171            partition: None,
10172            leading_comments: Vec::new(),
10173            as_json: false,
10174            params: Vec::new(),
10175        }
10176    }
10177}
10178
10179/// SHOW statement - displays database objects
10180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10181#[cfg_attr(feature = "bindings", derive(TS))]
10182pub struct Show {
10183    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10184    pub this: String,
10185    /// Whether TERSE was specified
10186    #[serde(default)]
10187    pub terse: bool,
10188    /// Whether HISTORY was specified
10189    #[serde(default)]
10190    pub history: bool,
10191    /// LIKE pattern
10192    pub like: Option<Expression>,
10193    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10194    pub scope_kind: Option<String>,
10195    /// IN scope object
10196    pub scope: Option<Expression>,
10197    /// STARTS WITH pattern
10198    pub starts_with: Option<Expression>,
10199    /// LIMIT clause
10200    pub limit: Option<Box<Limit>>,
10201    /// FROM clause (for specific object)
10202    pub from: Option<Expression>,
10203    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10204    #[serde(default, skip_serializing_if = "Option::is_none")]
10205    pub where_clause: Option<Expression>,
10206    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10207    #[serde(default, skip_serializing_if = "Option::is_none")]
10208    pub for_target: Option<Expression>,
10209    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10210    #[serde(default, skip_serializing_if = "Option::is_none")]
10211    pub db: Option<Expression>,
10212    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10213    #[serde(default, skip_serializing_if = "Option::is_none")]
10214    pub target: Option<Expression>,
10215    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10216    #[serde(default, skip_serializing_if = "Option::is_none")]
10217    pub mutex: Option<bool>,
10218    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10219    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10220    pub privileges: Vec<String>,
10221}
10222
10223impl Show {
10224    pub fn new(this: impl Into<String>) -> Self {
10225        Self {
10226            this: this.into(),
10227            terse: false,
10228            history: false,
10229            like: None,
10230            scope_kind: None,
10231            scope: None,
10232            starts_with: None,
10233            limit: None,
10234            from: None,
10235            where_clause: None,
10236            for_target: None,
10237            db: None,
10238            target: None,
10239            mutex: None,
10240            privileges: Vec::new(),
10241        }
10242    }
10243}
10244
10245/// Represent an explicit parenthesized expression for grouping precedence.
10246///
10247/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10248/// correctly instead of being flattened to `a + b * c`.
10249#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10250#[cfg_attr(feature = "bindings", derive(TS))]
10251pub struct Paren {
10252    /// The inner expression wrapped by parentheses.
10253    pub this: Expression,
10254    #[serde(default)]
10255    pub trailing_comments: Vec<String>,
10256}
10257
10258/// Expression annotated with trailing comments (for round-trip preservation)
10259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10260#[cfg_attr(feature = "bindings", derive(TS))]
10261pub struct Annotated {
10262    pub this: Expression,
10263    pub trailing_comments: Vec<String>,
10264}
10265
10266// === BATCH GENERATED STRUCT DEFINITIONS ===
10267// Generated from Python sqlglot expressions.py
10268
10269/// Refresh
10270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10271#[cfg_attr(feature = "bindings", derive(TS))]
10272pub struct Refresh {
10273    pub this: Box<Expression>,
10274    pub kind: String,
10275}
10276
10277/// LockingStatement
10278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10279#[cfg_attr(feature = "bindings", derive(TS))]
10280pub struct LockingStatement {
10281    pub this: Box<Expression>,
10282    pub expression: Box<Expression>,
10283}
10284
10285/// SequenceProperties
10286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10287#[cfg_attr(feature = "bindings", derive(TS))]
10288pub struct SequenceProperties {
10289    #[serde(default)]
10290    pub increment: Option<Box<Expression>>,
10291    #[serde(default)]
10292    pub minvalue: Option<Box<Expression>>,
10293    #[serde(default)]
10294    pub maxvalue: Option<Box<Expression>>,
10295    #[serde(default)]
10296    pub cache: Option<Box<Expression>>,
10297    #[serde(default)]
10298    pub start: Option<Box<Expression>>,
10299    #[serde(default)]
10300    pub owned: Option<Box<Expression>>,
10301    #[serde(default)]
10302    pub options: Vec<Expression>,
10303}
10304
10305/// TruncateTable
10306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10307#[cfg_attr(feature = "bindings", derive(TS))]
10308pub struct TruncateTable {
10309    #[serde(default)]
10310    pub expressions: Vec<Expression>,
10311    #[serde(default)]
10312    pub is_database: Option<Box<Expression>>,
10313    #[serde(default)]
10314    pub exists: bool,
10315    #[serde(default)]
10316    pub only: Option<Box<Expression>>,
10317    #[serde(default)]
10318    pub cluster: Option<Box<Expression>>,
10319    #[serde(default)]
10320    pub identity: Option<Box<Expression>>,
10321    #[serde(default)]
10322    pub option: Option<Box<Expression>>,
10323    #[serde(default)]
10324    pub partition: Option<Box<Expression>>,
10325}
10326
10327/// Clone
10328#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10329#[cfg_attr(feature = "bindings", derive(TS))]
10330pub struct Clone {
10331    pub this: Box<Expression>,
10332    #[serde(default)]
10333    pub shallow: Option<Box<Expression>>,
10334    #[serde(default)]
10335    pub copy: Option<Box<Expression>>,
10336}
10337
10338/// Attach
10339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10340#[cfg_attr(feature = "bindings", derive(TS))]
10341pub struct Attach {
10342    pub this: Box<Expression>,
10343    #[serde(default)]
10344    pub exists: bool,
10345    #[serde(default)]
10346    pub expressions: Vec<Expression>,
10347}
10348
10349/// Detach
10350#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10351#[cfg_attr(feature = "bindings", derive(TS))]
10352pub struct Detach {
10353    pub this: Box<Expression>,
10354    #[serde(default)]
10355    pub exists: bool,
10356}
10357
10358/// Install
10359#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10360#[cfg_attr(feature = "bindings", derive(TS))]
10361pub struct Install {
10362    pub this: Box<Expression>,
10363    #[serde(default)]
10364    pub from_: Option<Box<Expression>>,
10365    #[serde(default)]
10366    pub force: Option<Box<Expression>>,
10367}
10368
10369/// Summarize
10370#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10371#[cfg_attr(feature = "bindings", derive(TS))]
10372pub struct Summarize {
10373    pub this: Box<Expression>,
10374    #[serde(default)]
10375    pub table: Option<Box<Expression>>,
10376}
10377
10378/// Declare
10379#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10380#[cfg_attr(feature = "bindings", derive(TS))]
10381pub struct Declare {
10382    #[serde(default)]
10383    pub expressions: Vec<Expression>,
10384    #[serde(default)]
10385    pub replace: bool,
10386}
10387
10388/// DeclareItem
10389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10390#[cfg_attr(feature = "bindings", derive(TS))]
10391pub struct DeclareItem {
10392    pub this: Box<Expression>,
10393    #[serde(default)]
10394    pub kind: Option<String>,
10395    #[serde(default)]
10396    pub default: Option<Box<Expression>>,
10397    #[serde(default)]
10398    pub has_as: bool,
10399    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10400    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10401    pub additional_names: Vec<Expression>,
10402}
10403
10404/// Set
10405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10406#[cfg_attr(feature = "bindings", derive(TS))]
10407pub struct Set {
10408    #[serde(default)]
10409    pub expressions: Vec<Expression>,
10410    #[serde(default)]
10411    pub unset: Option<Box<Expression>>,
10412    #[serde(default)]
10413    pub tag: Option<Box<Expression>>,
10414}
10415
10416/// Heredoc
10417#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10418#[cfg_attr(feature = "bindings", derive(TS))]
10419pub struct Heredoc {
10420    pub this: Box<Expression>,
10421    #[serde(default)]
10422    pub tag: Option<Box<Expression>>,
10423}
10424
10425/// QueryBand
10426#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10427#[cfg_attr(feature = "bindings", derive(TS))]
10428pub struct QueryBand {
10429    pub this: Box<Expression>,
10430    #[serde(default)]
10431    pub scope: Option<Box<Expression>>,
10432    #[serde(default)]
10433    pub update: Option<Box<Expression>>,
10434}
10435
10436/// UserDefinedFunction
10437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10438#[cfg_attr(feature = "bindings", derive(TS))]
10439pub struct UserDefinedFunction {
10440    pub this: Box<Expression>,
10441    #[serde(default)]
10442    pub expressions: Vec<Expression>,
10443    #[serde(default)]
10444    pub wrapped: Option<Box<Expression>>,
10445}
10446
10447/// RecursiveWithSearch
10448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10449#[cfg_attr(feature = "bindings", derive(TS))]
10450pub struct RecursiveWithSearch {
10451    pub kind: String,
10452    pub this: Box<Expression>,
10453    pub expression: Box<Expression>,
10454    #[serde(default)]
10455    pub using: Option<Box<Expression>>,
10456}
10457
10458/// ProjectionDef
10459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10460#[cfg_attr(feature = "bindings", derive(TS))]
10461pub struct ProjectionDef {
10462    pub this: Box<Expression>,
10463    pub expression: Box<Expression>,
10464}
10465
10466/// TableAlias
10467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10468#[cfg_attr(feature = "bindings", derive(TS))]
10469pub struct TableAlias {
10470    #[serde(default)]
10471    pub this: Option<Box<Expression>>,
10472    #[serde(default)]
10473    pub columns: Vec<Expression>,
10474}
10475
10476/// ByteString
10477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10478#[cfg_attr(feature = "bindings", derive(TS))]
10479pub struct ByteString {
10480    pub this: Box<Expression>,
10481    #[serde(default)]
10482    pub is_bytes: Option<Box<Expression>>,
10483}
10484
10485/// HexStringExpr - Hex string expression (not literal)
10486/// BigQuery: converts to FROM_HEX(this)
10487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10488#[cfg_attr(feature = "bindings", derive(TS))]
10489pub struct HexStringExpr {
10490    pub this: Box<Expression>,
10491    #[serde(default)]
10492    pub is_integer: Option<bool>,
10493}
10494
10495/// UnicodeString
10496#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10497#[cfg_attr(feature = "bindings", derive(TS))]
10498pub struct UnicodeString {
10499    pub this: Box<Expression>,
10500    #[serde(default)]
10501    pub escape: Option<Box<Expression>>,
10502}
10503
10504/// AlterColumn
10505#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10506#[cfg_attr(feature = "bindings", derive(TS))]
10507pub struct AlterColumn {
10508    pub this: Box<Expression>,
10509    #[serde(default)]
10510    pub dtype: Option<Box<Expression>>,
10511    #[serde(default)]
10512    pub collate: Option<Box<Expression>>,
10513    #[serde(default)]
10514    pub using: Option<Box<Expression>>,
10515    #[serde(default)]
10516    pub default: Option<Box<Expression>>,
10517    #[serde(default)]
10518    pub drop: Option<Box<Expression>>,
10519    #[serde(default)]
10520    pub comment: Option<Box<Expression>>,
10521    #[serde(default)]
10522    pub allow_null: Option<Box<Expression>>,
10523    #[serde(default)]
10524    pub visible: Option<Box<Expression>>,
10525    #[serde(default)]
10526    pub rename_to: Option<Box<Expression>>,
10527}
10528
10529/// AlterSortKey
10530#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10531#[cfg_attr(feature = "bindings", derive(TS))]
10532pub struct AlterSortKey {
10533    #[serde(default)]
10534    pub this: Option<Box<Expression>>,
10535    #[serde(default)]
10536    pub expressions: Vec<Expression>,
10537    #[serde(default)]
10538    pub compound: Option<Box<Expression>>,
10539}
10540
10541/// AlterSet
10542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10543#[cfg_attr(feature = "bindings", derive(TS))]
10544pub struct AlterSet {
10545    #[serde(default)]
10546    pub expressions: Vec<Expression>,
10547    #[serde(default)]
10548    pub option: Option<Box<Expression>>,
10549    #[serde(default)]
10550    pub tablespace: Option<Box<Expression>>,
10551    #[serde(default)]
10552    pub access_method: Option<Box<Expression>>,
10553    #[serde(default)]
10554    pub file_format: Option<Box<Expression>>,
10555    #[serde(default)]
10556    pub copy_options: Option<Box<Expression>>,
10557    #[serde(default)]
10558    pub tag: Option<Box<Expression>>,
10559    #[serde(default)]
10560    pub location: Option<Box<Expression>>,
10561    #[serde(default)]
10562    pub serde: Option<Box<Expression>>,
10563}
10564
10565/// RenameColumn
10566#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10567#[cfg_attr(feature = "bindings", derive(TS))]
10568pub struct RenameColumn {
10569    pub this: Box<Expression>,
10570    #[serde(default)]
10571    pub to: Option<Box<Expression>>,
10572    #[serde(default)]
10573    pub exists: bool,
10574}
10575
10576/// Comprehension
10577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10578#[cfg_attr(feature = "bindings", derive(TS))]
10579pub struct Comprehension {
10580    pub this: Box<Expression>,
10581    pub expression: Box<Expression>,
10582    #[serde(default)]
10583    pub position: Option<Box<Expression>>,
10584    #[serde(default)]
10585    pub iterator: Option<Box<Expression>>,
10586    #[serde(default)]
10587    pub condition: Option<Box<Expression>>,
10588}
10589
10590/// MergeTreeTTLAction
10591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10592#[cfg_attr(feature = "bindings", derive(TS))]
10593pub struct MergeTreeTTLAction {
10594    pub this: Box<Expression>,
10595    #[serde(default)]
10596    pub delete: Option<Box<Expression>>,
10597    #[serde(default)]
10598    pub recompress: Option<Box<Expression>>,
10599    #[serde(default)]
10600    pub to_disk: Option<Box<Expression>>,
10601    #[serde(default)]
10602    pub to_volume: Option<Box<Expression>>,
10603}
10604
10605/// MergeTreeTTL
10606#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10607#[cfg_attr(feature = "bindings", derive(TS))]
10608pub struct MergeTreeTTL {
10609    #[serde(default)]
10610    pub expressions: Vec<Expression>,
10611    #[serde(default)]
10612    pub where_: Option<Box<Expression>>,
10613    #[serde(default)]
10614    pub group: Option<Box<Expression>>,
10615    #[serde(default)]
10616    pub aggregates: Option<Box<Expression>>,
10617}
10618
10619/// IndexConstraintOption
10620#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10621#[cfg_attr(feature = "bindings", derive(TS))]
10622pub struct IndexConstraintOption {
10623    #[serde(default)]
10624    pub key_block_size: Option<Box<Expression>>,
10625    #[serde(default)]
10626    pub using: Option<Box<Expression>>,
10627    #[serde(default)]
10628    pub parser: Option<Box<Expression>>,
10629    #[serde(default)]
10630    pub comment: Option<Box<Expression>>,
10631    #[serde(default)]
10632    pub visible: Option<Box<Expression>>,
10633    #[serde(default)]
10634    pub engine_attr: Option<Box<Expression>>,
10635    #[serde(default)]
10636    pub secondary_engine_attr: Option<Box<Expression>>,
10637}
10638
10639/// PeriodForSystemTimeConstraint
10640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10641#[cfg_attr(feature = "bindings", derive(TS))]
10642pub struct PeriodForSystemTimeConstraint {
10643    pub this: Box<Expression>,
10644    pub expression: Box<Expression>,
10645}
10646
10647/// CaseSpecificColumnConstraint
10648#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10649#[cfg_attr(feature = "bindings", derive(TS))]
10650pub struct CaseSpecificColumnConstraint {
10651    #[serde(default)]
10652    pub not_: Option<Box<Expression>>,
10653}
10654
10655/// CharacterSetColumnConstraint
10656#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10657#[cfg_attr(feature = "bindings", derive(TS))]
10658pub struct CharacterSetColumnConstraint {
10659    pub this: Box<Expression>,
10660}
10661
10662/// CheckColumnConstraint
10663#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10664#[cfg_attr(feature = "bindings", derive(TS))]
10665pub struct CheckColumnConstraint {
10666    pub this: Box<Expression>,
10667    #[serde(default)]
10668    pub enforced: Option<Box<Expression>>,
10669}
10670
10671/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
10672#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10673#[cfg_attr(feature = "bindings", derive(TS))]
10674pub struct AssumeColumnConstraint {
10675    pub this: Box<Expression>,
10676}
10677
10678/// CompressColumnConstraint
10679#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10680#[cfg_attr(feature = "bindings", derive(TS))]
10681pub struct CompressColumnConstraint {
10682    #[serde(default)]
10683    pub this: Option<Box<Expression>>,
10684}
10685
10686/// DateFormatColumnConstraint
10687#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10688#[cfg_attr(feature = "bindings", derive(TS))]
10689pub struct DateFormatColumnConstraint {
10690    pub this: Box<Expression>,
10691}
10692
10693/// EphemeralColumnConstraint
10694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10695#[cfg_attr(feature = "bindings", derive(TS))]
10696pub struct EphemeralColumnConstraint {
10697    #[serde(default)]
10698    pub this: Option<Box<Expression>>,
10699}
10700
10701/// WithOperator
10702#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10703#[cfg_attr(feature = "bindings", derive(TS))]
10704pub struct WithOperator {
10705    pub this: Box<Expression>,
10706    pub op: String,
10707}
10708
10709/// GeneratedAsIdentityColumnConstraint
10710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10711#[cfg_attr(feature = "bindings", derive(TS))]
10712pub struct GeneratedAsIdentityColumnConstraint {
10713    #[serde(default)]
10714    pub this: Option<Box<Expression>>,
10715    #[serde(default)]
10716    pub expression: Option<Box<Expression>>,
10717    #[serde(default)]
10718    pub on_null: Option<Box<Expression>>,
10719    #[serde(default)]
10720    pub start: Option<Box<Expression>>,
10721    #[serde(default)]
10722    pub increment: Option<Box<Expression>>,
10723    #[serde(default)]
10724    pub minvalue: Option<Box<Expression>>,
10725    #[serde(default)]
10726    pub maxvalue: Option<Box<Expression>>,
10727    #[serde(default)]
10728    pub cycle: Option<Box<Expression>>,
10729    #[serde(default)]
10730    pub order: Option<Box<Expression>>,
10731}
10732
10733/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
10734/// TSQL: outputs "IDENTITY"
10735#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10736#[cfg_attr(feature = "bindings", derive(TS))]
10737pub struct AutoIncrementColumnConstraint;
10738
10739/// CommentColumnConstraint - Column comment marker
10740#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10741#[cfg_attr(feature = "bindings", derive(TS))]
10742pub struct CommentColumnConstraint;
10743
10744/// GeneratedAsRowColumnConstraint
10745#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10746#[cfg_attr(feature = "bindings", derive(TS))]
10747pub struct GeneratedAsRowColumnConstraint {
10748    #[serde(default)]
10749    pub start: Option<Box<Expression>>,
10750    #[serde(default)]
10751    pub hidden: Option<Box<Expression>>,
10752}
10753
10754/// IndexColumnConstraint
10755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10756#[cfg_attr(feature = "bindings", derive(TS))]
10757pub struct IndexColumnConstraint {
10758    #[serde(default)]
10759    pub this: Option<Box<Expression>>,
10760    #[serde(default)]
10761    pub expressions: Vec<Expression>,
10762    #[serde(default)]
10763    pub kind: Option<String>,
10764    #[serde(default)]
10765    pub index_type: Option<Box<Expression>>,
10766    #[serde(default)]
10767    pub options: Vec<Expression>,
10768    #[serde(default)]
10769    pub expression: Option<Box<Expression>>,
10770    #[serde(default)]
10771    pub granularity: Option<Box<Expression>>,
10772}
10773
10774/// MaskingPolicyColumnConstraint
10775#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10776#[cfg_attr(feature = "bindings", derive(TS))]
10777pub struct MaskingPolicyColumnConstraint {
10778    pub this: Box<Expression>,
10779    #[serde(default)]
10780    pub expressions: Vec<Expression>,
10781}
10782
10783/// NotNullColumnConstraint
10784#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10785#[cfg_attr(feature = "bindings", derive(TS))]
10786pub struct NotNullColumnConstraint {
10787    #[serde(default)]
10788    pub allow_null: Option<Box<Expression>>,
10789}
10790
10791/// DefaultColumnConstraint - DEFAULT value for a column
10792#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10793#[cfg_attr(feature = "bindings", derive(TS))]
10794pub struct DefaultColumnConstraint {
10795    pub this: Box<Expression>,
10796    /// TSQL: DEFAULT value FOR column (table-level default constraint)
10797    #[serde(default, skip_serializing_if = "Option::is_none")]
10798    pub for_column: Option<Identifier>,
10799}
10800
10801/// PrimaryKeyColumnConstraint
10802#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10803#[cfg_attr(feature = "bindings", derive(TS))]
10804pub struct PrimaryKeyColumnConstraint {
10805    #[serde(default)]
10806    pub desc: Option<Box<Expression>>,
10807    #[serde(default)]
10808    pub options: Vec<Expression>,
10809}
10810
10811/// UniqueColumnConstraint
10812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10813#[cfg_attr(feature = "bindings", derive(TS))]
10814pub struct UniqueColumnConstraint {
10815    #[serde(default)]
10816    pub this: Option<Box<Expression>>,
10817    #[serde(default)]
10818    pub index_type: Option<Box<Expression>>,
10819    #[serde(default)]
10820    pub on_conflict: Option<Box<Expression>>,
10821    #[serde(default)]
10822    pub nulls: Option<Box<Expression>>,
10823    #[serde(default)]
10824    pub options: Vec<Expression>,
10825}
10826
10827/// WatermarkColumnConstraint
10828#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10829#[cfg_attr(feature = "bindings", derive(TS))]
10830pub struct WatermarkColumnConstraint {
10831    pub this: Box<Expression>,
10832    pub expression: Box<Expression>,
10833}
10834
10835/// ComputedColumnConstraint
10836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10837#[cfg_attr(feature = "bindings", derive(TS))]
10838pub struct ComputedColumnConstraint {
10839    pub this: Box<Expression>,
10840    #[serde(default)]
10841    pub persisted: Option<Box<Expression>>,
10842    #[serde(default)]
10843    pub not_null: Option<Box<Expression>>,
10844    #[serde(default)]
10845    pub data_type: Option<Box<Expression>>,
10846}
10847
10848/// InOutColumnConstraint
10849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10850#[cfg_attr(feature = "bindings", derive(TS))]
10851pub struct InOutColumnConstraint {
10852    #[serde(default)]
10853    pub input_: Option<Box<Expression>>,
10854    #[serde(default)]
10855    pub output: Option<Box<Expression>>,
10856}
10857
10858/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
10859#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10860#[cfg_attr(feature = "bindings", derive(TS))]
10861pub struct PathColumnConstraint {
10862    pub this: Box<Expression>,
10863}
10864
10865/// Constraint
10866#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10867#[cfg_attr(feature = "bindings", derive(TS))]
10868pub struct Constraint {
10869    pub this: Box<Expression>,
10870    #[serde(default)]
10871    pub expressions: Vec<Expression>,
10872}
10873
10874/// Export
10875#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10876#[cfg_attr(feature = "bindings", derive(TS))]
10877pub struct Export {
10878    pub this: Box<Expression>,
10879    #[serde(default)]
10880    pub connection: Option<Box<Expression>>,
10881    #[serde(default)]
10882    pub options: Vec<Expression>,
10883}
10884
10885/// Filter
10886#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10887#[cfg_attr(feature = "bindings", derive(TS))]
10888pub struct Filter {
10889    pub this: Box<Expression>,
10890    pub expression: Box<Expression>,
10891}
10892
10893/// Changes
10894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10895#[cfg_attr(feature = "bindings", derive(TS))]
10896pub struct Changes {
10897    #[serde(default)]
10898    pub information: Option<Box<Expression>>,
10899    #[serde(default)]
10900    pub at_before: Option<Box<Expression>>,
10901    #[serde(default)]
10902    pub end: Option<Box<Expression>>,
10903}
10904
10905/// Directory
10906#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10907#[cfg_attr(feature = "bindings", derive(TS))]
10908pub struct Directory {
10909    pub this: Box<Expression>,
10910    #[serde(default)]
10911    pub local: Option<Box<Expression>>,
10912    #[serde(default)]
10913    pub row_format: Option<Box<Expression>>,
10914}
10915
10916/// ForeignKey
10917#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10918#[cfg_attr(feature = "bindings", derive(TS))]
10919pub struct ForeignKey {
10920    #[serde(default)]
10921    pub expressions: Vec<Expression>,
10922    #[serde(default)]
10923    pub reference: Option<Box<Expression>>,
10924    #[serde(default)]
10925    pub delete: Option<Box<Expression>>,
10926    #[serde(default)]
10927    pub update: Option<Box<Expression>>,
10928    #[serde(default)]
10929    pub options: Vec<Expression>,
10930}
10931
10932/// ColumnPrefix
10933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10934#[cfg_attr(feature = "bindings", derive(TS))]
10935pub struct ColumnPrefix {
10936    pub this: Box<Expression>,
10937    pub expression: Box<Expression>,
10938}
10939
10940/// PrimaryKey
10941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10942#[cfg_attr(feature = "bindings", derive(TS))]
10943pub struct PrimaryKey {
10944    #[serde(default)]
10945    pub this: Option<Box<Expression>>,
10946    #[serde(default)]
10947    pub expressions: Vec<Expression>,
10948    #[serde(default)]
10949    pub options: Vec<Expression>,
10950    #[serde(default)]
10951    pub include: Option<Box<Expression>>,
10952}
10953
10954/// Into
10955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10956#[cfg_attr(feature = "bindings", derive(TS))]
10957pub struct IntoClause {
10958    #[serde(default)]
10959    pub this: Option<Box<Expression>>,
10960    #[serde(default)]
10961    pub temporary: bool,
10962    #[serde(default)]
10963    pub unlogged: Option<Box<Expression>>,
10964    #[serde(default)]
10965    pub bulk_collect: Option<Box<Expression>>,
10966    #[serde(default)]
10967    pub expressions: Vec<Expression>,
10968}
10969
10970/// JoinHint
10971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10972#[cfg_attr(feature = "bindings", derive(TS))]
10973pub struct JoinHint {
10974    pub this: Box<Expression>,
10975    #[serde(default)]
10976    pub expressions: Vec<Expression>,
10977}
10978
10979/// Opclass
10980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10981#[cfg_attr(feature = "bindings", derive(TS))]
10982pub struct Opclass {
10983    pub this: Box<Expression>,
10984    pub expression: Box<Expression>,
10985}
10986
10987/// Index
10988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10989#[cfg_attr(feature = "bindings", derive(TS))]
10990pub struct Index {
10991    #[serde(default)]
10992    pub this: Option<Box<Expression>>,
10993    #[serde(default)]
10994    pub table: Option<Box<Expression>>,
10995    #[serde(default)]
10996    pub unique: bool,
10997    #[serde(default)]
10998    pub primary: Option<Box<Expression>>,
10999    #[serde(default)]
11000    pub amp: Option<Box<Expression>>,
11001    #[serde(default)]
11002    pub params: Vec<Expression>,
11003}
11004
11005/// IndexParameters
11006#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11007#[cfg_attr(feature = "bindings", derive(TS))]
11008pub struct IndexParameters {
11009    #[serde(default)]
11010    pub using: Option<Box<Expression>>,
11011    #[serde(default)]
11012    pub include: Option<Box<Expression>>,
11013    #[serde(default)]
11014    pub columns: Vec<Expression>,
11015    #[serde(default)]
11016    pub with_storage: Option<Box<Expression>>,
11017    #[serde(default)]
11018    pub partition_by: Option<Box<Expression>>,
11019    #[serde(default)]
11020    pub tablespace: Option<Box<Expression>>,
11021    #[serde(default)]
11022    pub where_: Option<Box<Expression>>,
11023    #[serde(default)]
11024    pub on: Option<Box<Expression>>,
11025}
11026
11027/// ConditionalInsert
11028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11029#[cfg_attr(feature = "bindings", derive(TS))]
11030pub struct ConditionalInsert {
11031    pub this: Box<Expression>,
11032    #[serde(default)]
11033    pub expression: Option<Box<Expression>>,
11034    #[serde(default)]
11035    pub else_: Option<Box<Expression>>,
11036}
11037
11038/// MultitableInserts
11039#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11040#[cfg_attr(feature = "bindings", derive(TS))]
11041pub struct MultitableInserts {
11042    #[serde(default)]
11043    pub expressions: Vec<Expression>,
11044    pub kind: String,
11045    #[serde(default)]
11046    pub source: Option<Box<Expression>>,
11047    /// Leading comments before the statement
11048    #[serde(default)]
11049    pub leading_comments: Vec<String>,
11050    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
11051    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11052    pub overwrite: bool,
11053}
11054
11055/// OnConflict
11056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11057#[cfg_attr(feature = "bindings", derive(TS))]
11058pub struct OnConflict {
11059    #[serde(default)]
11060    pub duplicate: Option<Box<Expression>>,
11061    #[serde(default)]
11062    pub expressions: Vec<Expression>,
11063    #[serde(default)]
11064    pub action: Option<Box<Expression>>,
11065    #[serde(default)]
11066    pub conflict_keys: Option<Box<Expression>>,
11067    #[serde(default)]
11068    pub index_predicate: Option<Box<Expression>>,
11069    #[serde(default)]
11070    pub constraint: Option<Box<Expression>>,
11071    #[serde(default)]
11072    pub where_: Option<Box<Expression>>,
11073}
11074
11075/// OnCondition
11076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11077#[cfg_attr(feature = "bindings", derive(TS))]
11078pub struct OnCondition {
11079    #[serde(default)]
11080    pub error: Option<Box<Expression>>,
11081    #[serde(default)]
11082    pub empty: Option<Box<Expression>>,
11083    #[serde(default)]
11084    pub null: Option<Box<Expression>>,
11085}
11086
11087/// Returning
11088#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11089#[cfg_attr(feature = "bindings", derive(TS))]
11090pub struct Returning {
11091    #[serde(default)]
11092    pub expressions: Vec<Expression>,
11093    #[serde(default)]
11094    pub into: Option<Box<Expression>>,
11095}
11096
11097/// Introducer
11098#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11099#[cfg_attr(feature = "bindings", derive(TS))]
11100pub struct Introducer {
11101    pub this: Box<Expression>,
11102    pub expression: Box<Expression>,
11103}
11104
11105/// PartitionRange
11106#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11107#[cfg_attr(feature = "bindings", derive(TS))]
11108pub struct PartitionRange {
11109    pub this: Box<Expression>,
11110    #[serde(default)]
11111    pub expression: Option<Box<Expression>>,
11112    #[serde(default)]
11113    pub expressions: Vec<Expression>,
11114}
11115
11116/// Group
11117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11118#[cfg_attr(feature = "bindings", derive(TS))]
11119pub struct Group {
11120    #[serde(default)]
11121    pub expressions: Vec<Expression>,
11122    #[serde(default)]
11123    pub grouping_sets: Option<Box<Expression>>,
11124    #[serde(default)]
11125    pub cube: Option<Box<Expression>>,
11126    #[serde(default)]
11127    pub rollup: Option<Box<Expression>>,
11128    #[serde(default)]
11129    pub totals: Option<Box<Expression>>,
11130    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11131    #[serde(default)]
11132    pub all: Option<bool>,
11133}
11134
11135/// Cube
11136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11137#[cfg_attr(feature = "bindings", derive(TS))]
11138pub struct Cube {
11139    #[serde(default)]
11140    pub expressions: Vec<Expression>,
11141}
11142
11143/// Rollup
11144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11145#[cfg_attr(feature = "bindings", derive(TS))]
11146pub struct Rollup {
11147    #[serde(default)]
11148    pub expressions: Vec<Expression>,
11149}
11150
11151/// GroupingSets
11152#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11153#[cfg_attr(feature = "bindings", derive(TS))]
11154pub struct GroupingSets {
11155    #[serde(default)]
11156    pub expressions: Vec<Expression>,
11157}
11158
11159/// LimitOptions
11160#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11161#[cfg_attr(feature = "bindings", derive(TS))]
11162pub struct LimitOptions {
11163    #[serde(default)]
11164    pub percent: Option<Box<Expression>>,
11165    #[serde(default)]
11166    pub rows: Option<Box<Expression>>,
11167    #[serde(default)]
11168    pub with_ties: Option<Box<Expression>>,
11169}
11170
11171/// Lateral
11172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11173#[cfg_attr(feature = "bindings", derive(TS))]
11174pub struct Lateral {
11175    pub this: Box<Expression>,
11176    #[serde(default)]
11177    pub view: Option<Box<Expression>>,
11178    #[serde(default)]
11179    pub outer: Option<Box<Expression>>,
11180    #[serde(default)]
11181    pub alias: Option<String>,
11182    /// Whether the alias was originally quoted (backtick/double-quote)
11183    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11184    pub alias_quoted: bool,
11185    #[serde(default)]
11186    pub cross_apply: Option<Box<Expression>>,
11187    #[serde(default)]
11188    pub ordinality: Option<Box<Expression>>,
11189    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11190    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11191    pub column_aliases: Vec<String>,
11192}
11193
11194/// TableFromRows
11195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11196#[cfg_attr(feature = "bindings", derive(TS))]
11197pub struct TableFromRows {
11198    pub this: Box<Expression>,
11199    #[serde(default)]
11200    pub alias: Option<String>,
11201    #[serde(default)]
11202    pub joins: Vec<Expression>,
11203    #[serde(default)]
11204    pub pivots: Option<Box<Expression>>,
11205    #[serde(default)]
11206    pub sample: Option<Box<Expression>>,
11207}
11208
11209/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11210/// Used for set-returning functions with typed column definitions
11211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11212#[cfg_attr(feature = "bindings", derive(TS))]
11213pub struct RowsFrom {
11214    /// List of function expressions, each potentially with an alias and typed columns
11215    pub expressions: Vec<Expression>,
11216    /// WITH ORDINALITY modifier
11217    #[serde(default)]
11218    pub ordinality: bool,
11219    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11220    #[serde(default)]
11221    pub alias: Option<Box<Expression>>,
11222}
11223
11224/// WithFill
11225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11226#[cfg_attr(feature = "bindings", derive(TS))]
11227pub struct WithFill {
11228    #[serde(default)]
11229    pub from_: Option<Box<Expression>>,
11230    #[serde(default)]
11231    pub to: Option<Box<Expression>>,
11232    #[serde(default)]
11233    pub step: Option<Box<Expression>>,
11234    #[serde(default)]
11235    pub staleness: Option<Box<Expression>>,
11236    #[serde(default)]
11237    pub interpolate: Option<Box<Expression>>,
11238}
11239
11240/// Property
11241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11242#[cfg_attr(feature = "bindings", derive(TS))]
11243pub struct Property {
11244    pub this: Box<Expression>,
11245    #[serde(default)]
11246    pub value: Option<Box<Expression>>,
11247}
11248
11249/// GrantPrivilege
11250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11251#[cfg_attr(feature = "bindings", derive(TS))]
11252pub struct GrantPrivilege {
11253    pub this: Box<Expression>,
11254    #[serde(default)]
11255    pub expressions: Vec<Expression>,
11256}
11257
11258/// AllowedValuesProperty
11259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11260#[cfg_attr(feature = "bindings", derive(TS))]
11261pub struct AllowedValuesProperty {
11262    #[serde(default)]
11263    pub expressions: Vec<Expression>,
11264}
11265
11266/// AlgorithmProperty
11267#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11268#[cfg_attr(feature = "bindings", derive(TS))]
11269pub struct AlgorithmProperty {
11270    pub this: Box<Expression>,
11271}
11272
11273/// AutoIncrementProperty
11274#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11275#[cfg_attr(feature = "bindings", derive(TS))]
11276pub struct AutoIncrementProperty {
11277    pub this: Box<Expression>,
11278}
11279
11280/// AutoRefreshProperty
11281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11282#[cfg_attr(feature = "bindings", derive(TS))]
11283pub struct AutoRefreshProperty {
11284    pub this: Box<Expression>,
11285}
11286
11287/// BackupProperty
11288#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11289#[cfg_attr(feature = "bindings", derive(TS))]
11290pub struct BackupProperty {
11291    pub this: Box<Expression>,
11292}
11293
11294/// BuildProperty
11295#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11296#[cfg_attr(feature = "bindings", derive(TS))]
11297pub struct BuildProperty {
11298    pub this: Box<Expression>,
11299}
11300
11301/// BlockCompressionProperty
11302#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11303#[cfg_attr(feature = "bindings", derive(TS))]
11304pub struct BlockCompressionProperty {
11305    #[serde(default)]
11306    pub autotemp: Option<Box<Expression>>,
11307    #[serde(default)]
11308    pub always: Option<Box<Expression>>,
11309    #[serde(default)]
11310    pub default: Option<Box<Expression>>,
11311    #[serde(default)]
11312    pub manual: Option<Box<Expression>>,
11313    #[serde(default)]
11314    pub never: Option<Box<Expression>>,
11315}
11316
11317/// CharacterSetProperty
11318#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11319#[cfg_attr(feature = "bindings", derive(TS))]
11320pub struct CharacterSetProperty {
11321    pub this: Box<Expression>,
11322    #[serde(default)]
11323    pub default: Option<Box<Expression>>,
11324}
11325
11326/// ChecksumProperty
11327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11328#[cfg_attr(feature = "bindings", derive(TS))]
11329pub struct ChecksumProperty {
11330    #[serde(default)]
11331    pub on: Option<Box<Expression>>,
11332    #[serde(default)]
11333    pub default: Option<Box<Expression>>,
11334}
11335
11336/// CollateProperty
11337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11338#[cfg_attr(feature = "bindings", derive(TS))]
11339pub struct CollateProperty {
11340    pub this: Box<Expression>,
11341    #[serde(default)]
11342    pub default: Option<Box<Expression>>,
11343}
11344
11345/// DataBlocksizeProperty
11346#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11347#[cfg_attr(feature = "bindings", derive(TS))]
11348pub struct DataBlocksizeProperty {
11349    #[serde(default)]
11350    pub size: Option<i64>,
11351    #[serde(default)]
11352    pub units: Option<Box<Expression>>,
11353    #[serde(default)]
11354    pub minimum: Option<Box<Expression>>,
11355    #[serde(default)]
11356    pub maximum: Option<Box<Expression>>,
11357    #[serde(default)]
11358    pub default: Option<Box<Expression>>,
11359}
11360
11361/// DataDeletionProperty
11362#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11363#[cfg_attr(feature = "bindings", derive(TS))]
11364pub struct DataDeletionProperty {
11365    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11366    #[ast(skip)]
11367    pub on: Box<Expression>,
11368    #[serde(default)]
11369    pub filter_column: Option<Box<Expression>>,
11370    #[serde(default)]
11371    pub retention_period: Option<Box<Expression>>,
11372}
11373
11374/// DefinerProperty
11375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11376#[cfg_attr(feature = "bindings", derive(TS))]
11377pub struct DefinerProperty {
11378    pub this: Box<Expression>,
11379}
11380
11381/// DistKeyProperty
11382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11383#[cfg_attr(feature = "bindings", derive(TS))]
11384pub struct DistKeyProperty {
11385    pub this: Box<Expression>,
11386}
11387
11388/// DistributedByProperty
11389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11390#[cfg_attr(feature = "bindings", derive(TS))]
11391pub struct DistributedByProperty {
11392    #[serde(default)]
11393    pub expressions: Vec<Expression>,
11394    pub kind: String,
11395    #[serde(default)]
11396    pub buckets: Option<Box<Expression>>,
11397    #[serde(default)]
11398    pub order: Option<Box<Expression>>,
11399}
11400
11401/// DistStyleProperty
11402#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11403#[cfg_attr(feature = "bindings", derive(TS))]
11404pub struct DistStyleProperty {
11405    pub this: Box<Expression>,
11406}
11407
11408/// DuplicateKeyProperty
11409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11410#[cfg_attr(feature = "bindings", derive(TS))]
11411pub struct DuplicateKeyProperty {
11412    #[serde(default)]
11413    pub expressions: Vec<Expression>,
11414}
11415
11416/// EngineProperty
11417#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11418#[cfg_attr(feature = "bindings", derive(TS))]
11419pub struct EngineProperty {
11420    pub this: Box<Expression>,
11421}
11422
11423/// ToTableProperty
11424#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11425#[cfg_attr(feature = "bindings", derive(TS))]
11426pub struct ToTableProperty {
11427    pub this: Box<Expression>,
11428}
11429
11430/// ExecuteAsProperty
11431#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11432#[cfg_attr(feature = "bindings", derive(TS))]
11433pub struct ExecuteAsProperty {
11434    pub this: Box<Expression>,
11435}
11436
11437/// ExternalProperty
11438#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11439#[cfg_attr(feature = "bindings", derive(TS))]
11440pub struct ExternalProperty {
11441    #[serde(default)]
11442    pub this: Option<Box<Expression>>,
11443}
11444
11445/// FallbackProperty
11446#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11447#[cfg_attr(feature = "bindings", derive(TS))]
11448pub struct FallbackProperty {
11449    #[serde(default)]
11450    pub no: Option<Box<Expression>>,
11451    #[serde(default)]
11452    pub protection: Option<Box<Expression>>,
11453}
11454
11455/// FileFormatProperty
11456#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11457#[cfg_attr(feature = "bindings", derive(TS))]
11458pub struct FileFormatProperty {
11459    #[serde(default)]
11460    pub this: Option<Box<Expression>>,
11461    #[serde(default)]
11462    pub expressions: Vec<Expression>,
11463    #[serde(default)]
11464    pub hive_format: Option<Box<Expression>>,
11465}
11466
11467/// CredentialsProperty
11468#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11469#[cfg_attr(feature = "bindings", derive(TS))]
11470pub struct CredentialsProperty {
11471    #[serde(default)]
11472    pub expressions: Vec<Expression>,
11473}
11474
11475/// FreespaceProperty
11476#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11477#[cfg_attr(feature = "bindings", derive(TS))]
11478pub struct FreespaceProperty {
11479    pub this: Box<Expression>,
11480    #[serde(default)]
11481    pub percent: Option<Box<Expression>>,
11482}
11483
11484/// InheritsProperty
11485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11486#[cfg_attr(feature = "bindings", derive(TS))]
11487pub struct InheritsProperty {
11488    #[serde(default)]
11489    pub expressions: Vec<Expression>,
11490}
11491
11492/// InputModelProperty
11493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11494#[cfg_attr(feature = "bindings", derive(TS))]
11495pub struct InputModelProperty {
11496    pub this: Box<Expression>,
11497}
11498
11499/// OutputModelProperty
11500#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11501#[cfg_attr(feature = "bindings", derive(TS))]
11502pub struct OutputModelProperty {
11503    pub this: Box<Expression>,
11504}
11505
11506/// IsolatedLoadingProperty
11507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11508#[cfg_attr(feature = "bindings", derive(TS))]
11509pub struct IsolatedLoadingProperty {
11510    #[serde(default)]
11511    pub no: Option<Box<Expression>>,
11512    #[serde(default)]
11513    pub concurrent: Option<Box<Expression>>,
11514    #[serde(default)]
11515    pub target: Option<Box<Expression>>,
11516}
11517
11518/// JournalProperty
11519#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11520#[cfg_attr(feature = "bindings", derive(TS))]
11521pub struct JournalProperty {
11522    #[serde(default)]
11523    pub no: Option<Box<Expression>>,
11524    #[serde(default)]
11525    pub dual: Option<Box<Expression>>,
11526    #[serde(default)]
11527    pub before: Option<Box<Expression>>,
11528    #[serde(default)]
11529    pub local: Option<Box<Expression>>,
11530    #[serde(default)]
11531    pub after: Option<Box<Expression>>,
11532}
11533
11534/// LanguageProperty
11535#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11536#[cfg_attr(feature = "bindings", derive(TS))]
11537pub struct LanguageProperty {
11538    pub this: Box<Expression>,
11539}
11540
11541/// EnviromentProperty
11542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11543#[cfg_attr(feature = "bindings", derive(TS))]
11544pub struct EnviromentProperty {
11545    #[serde(default)]
11546    pub expressions: Vec<Expression>,
11547}
11548
11549/// ClusteredByProperty
11550#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11551#[cfg_attr(feature = "bindings", derive(TS))]
11552pub struct ClusteredByProperty {
11553    #[serde(default)]
11554    pub expressions: Vec<Expression>,
11555    #[serde(default)]
11556    pub sorted_by: Option<Box<Expression>>,
11557    #[serde(default)]
11558    pub buckets: Option<Box<Expression>>,
11559}
11560
11561/// DictProperty
11562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11563#[cfg_attr(feature = "bindings", derive(TS))]
11564pub struct DictProperty {
11565    pub this: Box<Expression>,
11566    pub kind: String,
11567    #[serde(default)]
11568    pub settings: Option<Box<Expression>>,
11569}
11570
11571/// DictRange
11572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11573#[cfg_attr(feature = "bindings", derive(TS))]
11574pub struct DictRange {
11575    pub this: Box<Expression>,
11576    #[serde(default)]
11577    pub min: Option<Box<Expression>>,
11578    #[serde(default)]
11579    pub max: Option<Box<Expression>>,
11580}
11581
11582/// OnCluster
11583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11584#[cfg_attr(feature = "bindings", derive(TS))]
11585pub struct OnCluster {
11586    pub this: Box<Expression>,
11587}
11588
11589/// LikeProperty
11590#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11591#[cfg_attr(feature = "bindings", derive(TS))]
11592pub struct LikeProperty {
11593    pub this: Box<Expression>,
11594    #[serde(default)]
11595    pub expressions: Vec<Expression>,
11596}
11597
11598/// LocationProperty
11599#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11600#[cfg_attr(feature = "bindings", derive(TS))]
11601pub struct LocationProperty {
11602    pub this: Box<Expression>,
11603}
11604
11605/// LockProperty
11606#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11607#[cfg_attr(feature = "bindings", derive(TS))]
11608pub struct LockProperty {
11609    pub this: Box<Expression>,
11610}
11611
11612/// LockingProperty
11613#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11614#[cfg_attr(feature = "bindings", derive(TS))]
11615pub struct LockingProperty {
11616    #[serde(default)]
11617    pub this: Option<Box<Expression>>,
11618    pub kind: String,
11619    #[serde(default)]
11620    pub for_or_in: Option<Box<Expression>>,
11621    #[serde(default)]
11622    pub lock_type: Option<Box<Expression>>,
11623    #[serde(default)]
11624    pub override_: Option<Box<Expression>>,
11625}
11626
11627/// LogProperty
11628#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11629#[cfg_attr(feature = "bindings", derive(TS))]
11630pub struct LogProperty {
11631    #[serde(default)]
11632    pub no: Option<Box<Expression>>,
11633}
11634
11635/// MaterializedProperty
11636#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11637#[cfg_attr(feature = "bindings", derive(TS))]
11638pub struct MaterializedProperty {
11639    #[serde(default)]
11640    pub this: Option<Box<Expression>>,
11641}
11642
11643/// MergeBlockRatioProperty
11644#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11645#[cfg_attr(feature = "bindings", derive(TS))]
11646pub struct MergeBlockRatioProperty {
11647    #[serde(default)]
11648    pub this: Option<Box<Expression>>,
11649    #[serde(default)]
11650    pub no: Option<Box<Expression>>,
11651    #[serde(default)]
11652    pub default: Option<Box<Expression>>,
11653    #[serde(default)]
11654    pub percent: Option<Box<Expression>>,
11655}
11656
11657/// OnProperty
11658#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11659#[cfg_attr(feature = "bindings", derive(TS))]
11660pub struct OnProperty {
11661    pub this: Box<Expression>,
11662}
11663
11664/// OnCommitProperty
11665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11666#[cfg_attr(feature = "bindings", derive(TS))]
11667pub struct OnCommitProperty {
11668    #[serde(default)]
11669    pub delete: Option<Box<Expression>>,
11670}
11671
11672/// PartitionedByProperty
11673#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11674#[cfg_attr(feature = "bindings", derive(TS))]
11675pub struct PartitionedByProperty {
11676    pub this: Box<Expression>,
11677}
11678
11679/// BigQuery PARTITION BY property in CREATE TABLE statements.
11680#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11681#[cfg_attr(feature = "bindings", derive(TS))]
11682pub struct PartitionByProperty {
11683    #[serde(default)]
11684    pub expressions: Vec<Expression>,
11685}
11686
11687/// PartitionedByBucket
11688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11689#[cfg_attr(feature = "bindings", derive(TS))]
11690pub struct PartitionedByBucket {
11691    pub this: Box<Expression>,
11692    pub expression: Box<Expression>,
11693}
11694
11695/// BigQuery CLUSTER BY property in CREATE TABLE statements.
11696#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11697#[cfg_attr(feature = "bindings", derive(TS))]
11698pub struct ClusterByColumnsProperty {
11699    #[serde(default)]
11700    pub columns: Vec<Identifier>,
11701}
11702
11703/// PartitionByTruncate
11704#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11705#[cfg_attr(feature = "bindings", derive(TS))]
11706pub struct PartitionByTruncate {
11707    pub this: Box<Expression>,
11708    pub expression: Box<Expression>,
11709}
11710
11711/// PartitionByRangeProperty
11712#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11713#[cfg_attr(feature = "bindings", derive(TS))]
11714pub struct PartitionByRangeProperty {
11715    #[serde(default)]
11716    pub partition_expressions: Option<Box<Expression>>,
11717    #[serde(default)]
11718    pub create_expressions: Option<Box<Expression>>,
11719}
11720
11721/// PartitionByRangePropertyDynamic
11722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11723#[cfg_attr(feature = "bindings", derive(TS))]
11724pub struct PartitionByRangePropertyDynamic {
11725    #[serde(default)]
11726    pub this: Option<Box<Expression>>,
11727    #[serde(default)]
11728    pub start: Option<Box<Expression>>,
11729    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
11730    #[serde(default)]
11731    pub use_start_end: bool,
11732    #[serde(default)]
11733    pub end: Option<Box<Expression>>,
11734    #[serde(default)]
11735    pub every: Option<Box<Expression>>,
11736}
11737
11738/// PartitionByListProperty
11739#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11740#[cfg_attr(feature = "bindings", derive(TS))]
11741pub struct PartitionByListProperty {
11742    #[serde(default)]
11743    pub partition_expressions: Option<Box<Expression>>,
11744    #[serde(default)]
11745    pub create_expressions: Option<Box<Expression>>,
11746}
11747
11748/// PartitionList
11749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11750#[cfg_attr(feature = "bindings", derive(TS))]
11751pub struct PartitionList {
11752    pub this: Box<Expression>,
11753    #[serde(default)]
11754    pub expressions: Vec<Expression>,
11755}
11756
11757/// Partition - represents PARTITION/SUBPARTITION clause
11758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11759#[cfg_attr(feature = "bindings", derive(TS))]
11760pub struct Partition {
11761    pub expressions: Vec<Expression>,
11762    #[serde(default)]
11763    pub subpartition: bool,
11764}
11765
11766/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
11767/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
11768#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11769#[cfg_attr(feature = "bindings", derive(TS))]
11770pub struct RefreshTriggerProperty {
11771    /// Method: COMPLETE or AUTO
11772    pub method: String,
11773    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
11774    #[serde(default)]
11775    pub kind: Option<String>,
11776    /// For SCHEDULE: EVERY n (the number)
11777    #[serde(default)]
11778    pub every: Option<Box<Expression>>,
11779    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
11780    #[serde(default)]
11781    pub unit: Option<String>,
11782    /// For SCHEDULE: STARTS 'datetime'
11783    #[serde(default)]
11784    pub starts: Option<Box<Expression>>,
11785}
11786
11787/// UniqueKeyProperty
11788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11789#[cfg_attr(feature = "bindings", derive(TS))]
11790pub struct UniqueKeyProperty {
11791    #[serde(default)]
11792    pub expressions: Vec<Expression>,
11793}
11794
11795/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
11796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11797#[cfg_attr(feature = "bindings", derive(TS))]
11798pub struct RollupProperty {
11799    pub expressions: Vec<RollupIndex>,
11800}
11801
11802/// RollupIndex - A single rollup index: name(col1, col2)
11803#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11804#[cfg_attr(feature = "bindings", derive(TS))]
11805pub struct RollupIndex {
11806    pub name: Identifier,
11807    pub expressions: Vec<Identifier>,
11808}
11809
11810/// PartitionBoundSpec
11811#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11812#[cfg_attr(feature = "bindings", derive(TS))]
11813pub struct PartitionBoundSpec {
11814    #[serde(default)]
11815    pub this: Option<Box<Expression>>,
11816    #[serde(default)]
11817    pub expression: Option<Box<Expression>>,
11818    #[serde(default)]
11819    pub from_expressions: Option<Box<Expression>>,
11820    #[serde(default)]
11821    pub to_expressions: Option<Box<Expression>>,
11822}
11823
11824/// PartitionedOfProperty
11825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11826#[cfg_attr(feature = "bindings", derive(TS))]
11827pub struct PartitionedOfProperty {
11828    pub this: Box<Expression>,
11829    pub expression: Box<Expression>,
11830}
11831
11832/// RemoteWithConnectionModelProperty
11833#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11834#[cfg_attr(feature = "bindings", derive(TS))]
11835pub struct RemoteWithConnectionModelProperty {
11836    pub this: Box<Expression>,
11837}
11838
11839/// ReturnsProperty
11840#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11841#[cfg_attr(feature = "bindings", derive(TS))]
11842pub struct ReturnsProperty {
11843    #[serde(default)]
11844    pub this: Option<Box<Expression>>,
11845    #[serde(default)]
11846    pub is_table: Option<Box<Expression>>,
11847    #[serde(default)]
11848    pub table: Option<Box<Expression>>,
11849    #[serde(default)]
11850    pub null: Option<Box<Expression>>,
11851}
11852
11853/// RowFormatProperty
11854#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11855#[cfg_attr(feature = "bindings", derive(TS))]
11856pub struct RowFormatProperty {
11857    pub this: Box<Expression>,
11858}
11859
11860/// RowFormatDelimitedProperty
11861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11862#[cfg_attr(feature = "bindings", derive(TS))]
11863pub struct RowFormatDelimitedProperty {
11864    #[serde(default)]
11865    pub fields: Option<Box<Expression>>,
11866    #[serde(default)]
11867    pub escaped: Option<Box<Expression>>,
11868    #[serde(default)]
11869    pub collection_items: Option<Box<Expression>>,
11870    #[serde(default)]
11871    pub map_keys: Option<Box<Expression>>,
11872    #[serde(default)]
11873    pub lines: Option<Box<Expression>>,
11874    #[serde(default)]
11875    pub null: Option<Box<Expression>>,
11876    #[serde(default)]
11877    pub serde: Option<Box<Expression>>,
11878}
11879
11880/// RowFormatSerdeProperty
11881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11882#[cfg_attr(feature = "bindings", derive(TS))]
11883pub struct RowFormatSerdeProperty {
11884    pub this: Box<Expression>,
11885    #[serde(default)]
11886    pub serde_properties: Option<Box<Expression>>,
11887}
11888
11889/// QueryTransform
11890#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11891#[cfg_attr(feature = "bindings", derive(TS))]
11892pub struct QueryTransform {
11893    #[serde(default)]
11894    pub expressions: Vec<Expression>,
11895    #[serde(default)]
11896    pub command_script: Option<Box<Expression>>,
11897    #[serde(default)]
11898    pub schema: Option<Box<Expression>>,
11899    #[serde(default)]
11900    pub row_format_before: Option<Box<Expression>>,
11901    #[serde(default)]
11902    pub record_writer: Option<Box<Expression>>,
11903    #[serde(default)]
11904    pub row_format_after: Option<Box<Expression>>,
11905    #[serde(default)]
11906    pub record_reader: Option<Box<Expression>>,
11907}
11908
11909/// SampleProperty
11910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11911#[cfg_attr(feature = "bindings", derive(TS))]
11912pub struct SampleProperty {
11913    pub this: Box<Expression>,
11914}
11915
11916/// SecurityProperty
11917#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11918#[cfg_attr(feature = "bindings", derive(TS))]
11919pub struct SecurityProperty {
11920    pub this: Box<Expression>,
11921}
11922
11923/// SchemaCommentProperty
11924#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11925#[cfg_attr(feature = "bindings", derive(TS))]
11926pub struct SchemaCommentProperty {
11927    pub this: Box<Expression>,
11928}
11929
11930/// SemanticView
11931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11932#[cfg_attr(feature = "bindings", derive(TS))]
11933pub struct SemanticView {
11934    pub this: Box<Expression>,
11935    #[serde(default)]
11936    pub metrics: Option<Box<Expression>>,
11937    #[serde(default)]
11938    pub dimensions: Option<Box<Expression>>,
11939    #[serde(default)]
11940    pub facts: Option<Box<Expression>>,
11941    #[serde(default)]
11942    pub where_: Option<Box<Expression>>,
11943}
11944
11945/// SerdeProperties
11946#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11947#[cfg_attr(feature = "bindings", derive(TS))]
11948pub struct SerdeProperties {
11949    #[serde(default)]
11950    pub expressions: Vec<Expression>,
11951    #[serde(default)]
11952    pub with_: Option<Box<Expression>>,
11953}
11954
11955/// SetProperty
11956#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11957#[cfg_attr(feature = "bindings", derive(TS))]
11958pub struct SetProperty {
11959    #[serde(default)]
11960    pub multi: Option<Box<Expression>>,
11961}
11962
11963/// SharingProperty
11964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11965#[cfg_attr(feature = "bindings", derive(TS))]
11966pub struct SharingProperty {
11967    #[serde(default)]
11968    pub this: Option<Box<Expression>>,
11969}
11970
11971/// SetConfigProperty
11972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11973#[cfg_attr(feature = "bindings", derive(TS))]
11974pub struct SetConfigProperty {
11975    pub this: Box<Expression>,
11976}
11977
11978/// SettingsProperty
11979#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11980#[cfg_attr(feature = "bindings", derive(TS))]
11981pub struct SettingsProperty {
11982    #[serde(default)]
11983    pub expressions: Vec<Expression>,
11984}
11985
11986/// SortKeyProperty
11987#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11988#[cfg_attr(feature = "bindings", derive(TS))]
11989pub struct SortKeyProperty {
11990    pub this: Box<Expression>,
11991    #[serde(default)]
11992    pub compound: Option<Box<Expression>>,
11993}
11994
11995/// SqlReadWriteProperty
11996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11997#[cfg_attr(feature = "bindings", derive(TS))]
11998pub struct SqlReadWriteProperty {
11999    pub this: Box<Expression>,
12000}
12001
12002/// SqlSecurityProperty
12003#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12004#[cfg_attr(feature = "bindings", derive(TS))]
12005pub struct SqlSecurityProperty {
12006    pub this: Box<Expression>,
12007}
12008
12009/// StabilityProperty
12010#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12011#[cfg_attr(feature = "bindings", derive(TS))]
12012pub struct StabilityProperty {
12013    pub this: Box<Expression>,
12014}
12015
12016/// StorageHandlerProperty
12017#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12018#[cfg_attr(feature = "bindings", derive(TS))]
12019pub struct StorageHandlerProperty {
12020    pub this: Box<Expression>,
12021}
12022
12023/// TemporaryProperty
12024#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12025#[cfg_attr(feature = "bindings", derive(TS))]
12026pub struct TemporaryProperty {
12027    #[serde(default)]
12028    pub this: Option<Box<Expression>>,
12029}
12030
12031/// Tags
12032#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12033#[cfg_attr(feature = "bindings", derive(TS))]
12034pub struct Tags {
12035    #[serde(default)]
12036    pub expressions: Vec<Expression>,
12037}
12038
12039/// TransformModelProperty
12040#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12041#[cfg_attr(feature = "bindings", derive(TS))]
12042pub struct TransformModelProperty {
12043    #[serde(default)]
12044    pub expressions: Vec<Expression>,
12045}
12046
12047/// TransientProperty
12048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12049#[cfg_attr(feature = "bindings", derive(TS))]
12050pub struct TransientProperty {
12051    #[serde(default)]
12052    pub this: Option<Box<Expression>>,
12053}
12054
12055/// UsingTemplateProperty
12056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12057#[cfg_attr(feature = "bindings", derive(TS))]
12058pub struct UsingTemplateProperty {
12059    pub this: Box<Expression>,
12060}
12061
12062/// ViewAttributeProperty
12063#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12064#[cfg_attr(feature = "bindings", derive(TS))]
12065pub struct ViewAttributeProperty {
12066    pub this: Box<Expression>,
12067}
12068
12069/// VolatileProperty
12070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12071#[cfg_attr(feature = "bindings", derive(TS))]
12072pub struct VolatileProperty {
12073    #[serde(default)]
12074    pub this: Option<Box<Expression>>,
12075}
12076
12077/// WithDataProperty
12078#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12079#[cfg_attr(feature = "bindings", derive(TS))]
12080pub struct WithDataProperty {
12081    #[serde(default)]
12082    pub no: Option<Box<Expression>>,
12083    #[serde(default)]
12084    pub statistics: Option<Box<Expression>>,
12085}
12086
12087/// WithJournalTableProperty
12088#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12089#[cfg_attr(feature = "bindings", derive(TS))]
12090pub struct WithJournalTableProperty {
12091    pub this: Box<Expression>,
12092}
12093
12094/// WithSchemaBindingProperty
12095#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12096#[cfg_attr(feature = "bindings", derive(TS))]
12097pub struct WithSchemaBindingProperty {
12098    pub this: Box<Expression>,
12099}
12100
12101/// WithSystemVersioningProperty
12102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12103#[cfg_attr(feature = "bindings", derive(TS))]
12104pub struct WithSystemVersioningProperty {
12105    #[serde(default)]
12106    pub on: Option<Box<Expression>>,
12107    #[serde(default)]
12108    pub this: Option<Box<Expression>>,
12109    #[serde(default)]
12110    pub data_consistency: Option<Box<Expression>>,
12111    #[serde(default)]
12112    pub retention_period: Option<Box<Expression>>,
12113    #[serde(default)]
12114    pub with_: Option<Box<Expression>>,
12115}
12116
12117/// WithProcedureOptions
12118#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12119#[cfg_attr(feature = "bindings", derive(TS))]
12120pub struct WithProcedureOptions {
12121    #[serde(default)]
12122    pub expressions: Vec<Expression>,
12123}
12124
12125/// EncodeProperty
12126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12127#[cfg_attr(feature = "bindings", derive(TS))]
12128pub struct EncodeProperty {
12129    pub this: Box<Expression>,
12130    #[serde(default)]
12131    pub properties: Vec<Expression>,
12132    #[serde(default)]
12133    pub key: Option<Box<Expression>>,
12134}
12135
12136/// IncludeProperty
12137#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12138#[cfg_attr(feature = "bindings", derive(TS))]
12139pub struct IncludeProperty {
12140    pub this: Box<Expression>,
12141    #[serde(default)]
12142    pub alias: Option<String>,
12143    #[serde(default)]
12144    pub column_def: Option<Box<Expression>>,
12145}
12146
12147/// Properties
12148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12149#[cfg_attr(feature = "bindings", derive(TS))]
12150pub struct Properties {
12151    #[serde(default)]
12152    pub expressions: Vec<Expression>,
12153}
12154
12155/// Key/value pair in a BigQuery OPTIONS (...) clause.
12156#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12157#[cfg_attr(feature = "bindings", derive(TS))]
12158pub struct OptionEntry {
12159    pub key: Identifier,
12160    pub value: Expression,
12161}
12162
12163/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12164#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12165#[cfg_attr(feature = "bindings", derive(TS))]
12166pub struct OptionsProperty {
12167    #[serde(default)]
12168    pub entries: Vec<OptionEntry>,
12169}
12170
12171/// InputOutputFormat
12172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12173#[cfg_attr(feature = "bindings", derive(TS))]
12174pub struct InputOutputFormat {
12175    #[serde(default)]
12176    pub input_format: Option<Box<Expression>>,
12177    #[serde(default)]
12178    pub output_format: Option<Box<Expression>>,
12179}
12180
12181/// Reference
12182#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12183#[cfg_attr(feature = "bindings", derive(TS))]
12184pub struct Reference {
12185    pub this: Box<Expression>,
12186    #[serde(default)]
12187    pub expressions: Vec<Expression>,
12188    #[serde(default)]
12189    pub options: Vec<Expression>,
12190}
12191
12192/// QueryOption
12193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12194#[cfg_attr(feature = "bindings", derive(TS))]
12195pub struct QueryOption {
12196    pub this: Box<Expression>,
12197    #[serde(default)]
12198    pub expression: Option<Box<Expression>>,
12199}
12200
12201/// WithTableHint
12202#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12203#[cfg_attr(feature = "bindings", derive(TS))]
12204pub struct WithTableHint {
12205    #[serde(default)]
12206    pub expressions: Vec<Expression>,
12207}
12208
12209/// IndexTableHint
12210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12211#[cfg_attr(feature = "bindings", derive(TS))]
12212pub struct IndexTableHint {
12213    pub this: Box<Expression>,
12214    #[serde(default)]
12215    pub expressions: Vec<Expression>,
12216    #[serde(default)]
12217    pub target: Option<Box<Expression>>,
12218}
12219
12220/// Get
12221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12222#[cfg_attr(feature = "bindings", derive(TS))]
12223pub struct Get {
12224    pub this: Box<Expression>,
12225    #[serde(default)]
12226    pub target: Option<Box<Expression>>,
12227    #[serde(default)]
12228    pub properties: Vec<Expression>,
12229}
12230
12231/// SetOperation
12232#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12233#[cfg_attr(feature = "bindings", derive(TS))]
12234pub struct SetOperation {
12235    #[serde(default)]
12236    pub with_: Option<Box<Expression>>,
12237    pub this: Box<Expression>,
12238    pub expression: Box<Expression>,
12239    #[serde(default)]
12240    pub distinct: bool,
12241    #[serde(default)]
12242    pub by_name: Option<Box<Expression>>,
12243    #[serde(default)]
12244    pub side: Option<Box<Expression>>,
12245    #[serde(default)]
12246    pub kind: Option<String>,
12247    #[serde(default)]
12248    pub on: Option<Box<Expression>>,
12249}
12250
12251/// Var - Simple variable reference (for SQL variables, keywords as values)
12252#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12253#[cfg_attr(feature = "bindings", derive(TS))]
12254pub struct Var {
12255    pub this: String,
12256}
12257
12258/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12260#[cfg_attr(feature = "bindings", derive(TS))]
12261pub struct Variadic {
12262    pub this: Box<Expression>,
12263}
12264
12265/// Version
12266#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12267#[cfg_attr(feature = "bindings", derive(TS))]
12268pub struct Version {
12269    pub this: Box<Expression>,
12270    pub kind: String,
12271    #[serde(default)]
12272    pub expression: Option<Box<Expression>>,
12273}
12274
12275/// Schema
12276#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12277#[cfg_attr(feature = "bindings", derive(TS))]
12278pub struct Schema {
12279    #[serde(default)]
12280    pub this: Option<Box<Expression>>,
12281    #[serde(default)]
12282    pub expressions: Vec<Expression>,
12283}
12284
12285/// Lock
12286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12287#[cfg_attr(feature = "bindings", derive(TS))]
12288pub struct Lock {
12289    #[serde(default)]
12290    pub update: Option<Box<Expression>>,
12291    #[serde(default)]
12292    pub expressions: Vec<Expression>,
12293    #[serde(default)]
12294    pub wait: Option<Box<Expression>>,
12295    #[serde(default)]
12296    pub key: Option<Box<Expression>>,
12297}
12298
12299/// TableSample - wraps an expression with a TABLESAMPLE clause
12300/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12301#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12302#[cfg_attr(feature = "bindings", derive(TS))]
12303pub struct TableSample {
12304    /// The expression being sampled (subquery, function, etc.)
12305    #[serde(default, skip_serializing_if = "Option::is_none")]
12306    pub this: Option<Box<Expression>>,
12307    /// The sample specification
12308    #[serde(default, skip_serializing_if = "Option::is_none")]
12309    pub sample: Option<Box<Sample>>,
12310    #[serde(default)]
12311    pub expressions: Vec<Expression>,
12312    #[serde(default)]
12313    pub method: Option<String>,
12314    #[serde(default)]
12315    pub bucket_numerator: Option<Box<Expression>>,
12316    #[serde(default)]
12317    pub bucket_denominator: Option<Box<Expression>>,
12318    #[serde(default)]
12319    pub bucket_field: Option<Box<Expression>>,
12320    #[serde(default)]
12321    pub percent: Option<Box<Expression>>,
12322    #[serde(default)]
12323    pub rows: Option<Box<Expression>>,
12324    #[serde(default)]
12325    pub size: Option<i64>,
12326    #[serde(default)]
12327    pub seed: Option<Box<Expression>>,
12328}
12329
12330/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12332#[cfg_attr(feature = "bindings", derive(TS))]
12333pub struct Tag {
12334    #[serde(default)]
12335    pub this: Option<Box<Expression>>,
12336    #[serde(default)]
12337    pub prefix: Option<Box<Expression>>,
12338    #[serde(default)]
12339    pub postfix: Option<Box<Expression>>,
12340}
12341
12342/// UnpivotColumns
12343#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12344#[cfg_attr(feature = "bindings", derive(TS))]
12345pub struct UnpivotColumns {
12346    pub this: Box<Expression>,
12347    #[serde(default)]
12348    pub expressions: Vec<Expression>,
12349}
12350
12351/// SessionParameter
12352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12353#[cfg_attr(feature = "bindings", derive(TS))]
12354pub struct SessionParameter {
12355    pub this: Box<Expression>,
12356    #[serde(default)]
12357    pub kind: Option<String>,
12358}
12359
12360/// PseudoType
12361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12362#[cfg_attr(feature = "bindings", derive(TS))]
12363pub struct PseudoType {
12364    pub this: Box<Expression>,
12365}
12366
12367/// ObjectIdentifier
12368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12369#[cfg_attr(feature = "bindings", derive(TS))]
12370pub struct ObjectIdentifier {
12371    pub this: Box<Expression>,
12372}
12373
12374/// Transaction
12375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12376#[cfg_attr(feature = "bindings", derive(TS))]
12377pub struct Transaction {
12378    #[serde(default)]
12379    pub this: Option<Box<Expression>>,
12380    #[serde(default)]
12381    pub modes: Option<Box<Expression>>,
12382    #[serde(default)]
12383    pub mark: Option<Box<Expression>>,
12384}
12385
12386/// Commit
12387#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12388#[cfg_attr(feature = "bindings", derive(TS))]
12389pub struct Commit {
12390    #[serde(default)]
12391    pub chain: Option<Box<Expression>>,
12392    #[serde(default)]
12393    pub this: Option<Box<Expression>>,
12394    #[serde(default)]
12395    pub durability: Option<Box<Expression>>,
12396}
12397
12398/// Rollback
12399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12400#[cfg_attr(feature = "bindings", derive(TS))]
12401pub struct Rollback {
12402    #[serde(default)]
12403    pub savepoint: Option<Box<Expression>>,
12404    #[serde(default)]
12405    pub this: Option<Box<Expression>>,
12406}
12407
12408/// AlterSession
12409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12410#[cfg_attr(feature = "bindings", derive(TS))]
12411pub struct AlterSession {
12412    #[serde(default)]
12413    pub expressions: Vec<Expression>,
12414    #[serde(default)]
12415    pub unset: Option<Box<Expression>>,
12416}
12417
12418/// Analyze
12419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12420#[cfg_attr(feature = "bindings", derive(TS))]
12421pub struct Analyze {
12422    #[serde(default)]
12423    pub kind: Option<String>,
12424    #[serde(default)]
12425    pub this: Option<Box<Expression>>,
12426    #[serde(default)]
12427    pub options: Vec<Expression>,
12428    #[serde(default)]
12429    pub mode: Option<Box<Expression>>,
12430    #[serde(default)]
12431    pub partition: Option<Box<Expression>>,
12432    #[serde(default)]
12433    pub expression: Option<Box<Expression>>,
12434    #[serde(default)]
12435    pub properties: Vec<Expression>,
12436    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12437    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12438    pub columns: Vec<String>,
12439}
12440
12441/// AnalyzeStatistics
12442#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12443#[cfg_attr(feature = "bindings", derive(TS))]
12444pub struct AnalyzeStatistics {
12445    pub kind: String,
12446    #[serde(default)]
12447    pub option: Option<Box<Expression>>,
12448    #[serde(default)]
12449    pub this: Option<Box<Expression>>,
12450    #[serde(default)]
12451    pub expressions: Vec<Expression>,
12452}
12453
12454/// AnalyzeHistogram
12455#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12456#[cfg_attr(feature = "bindings", derive(TS))]
12457pub struct AnalyzeHistogram {
12458    pub this: Box<Expression>,
12459    #[serde(default)]
12460    pub expressions: Vec<Expression>,
12461    #[serde(default)]
12462    pub expression: Option<Box<Expression>>,
12463    #[serde(default)]
12464    pub update_options: Option<Box<Expression>>,
12465}
12466
12467/// AnalyzeSample
12468#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12469#[cfg_attr(feature = "bindings", derive(TS))]
12470pub struct AnalyzeSample {
12471    pub kind: String,
12472    #[serde(default)]
12473    pub sample: Option<Box<Expression>>,
12474}
12475
12476/// AnalyzeListChainedRows
12477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12478#[cfg_attr(feature = "bindings", derive(TS))]
12479pub struct AnalyzeListChainedRows {
12480    #[serde(default)]
12481    pub expression: Option<Box<Expression>>,
12482}
12483
12484/// AnalyzeDelete
12485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12486#[cfg_attr(feature = "bindings", derive(TS))]
12487pub struct AnalyzeDelete {
12488    #[serde(default)]
12489    pub kind: Option<String>,
12490}
12491
12492/// AnalyzeWith
12493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12494#[cfg_attr(feature = "bindings", derive(TS))]
12495pub struct AnalyzeWith {
12496    #[serde(default)]
12497    pub expressions: Vec<Expression>,
12498}
12499
12500/// AnalyzeValidate
12501#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12502#[cfg_attr(feature = "bindings", derive(TS))]
12503pub struct AnalyzeValidate {
12504    pub kind: String,
12505    #[serde(default)]
12506    pub this: Option<Box<Expression>>,
12507    #[serde(default)]
12508    pub expression: Option<Box<Expression>>,
12509}
12510
12511/// AddPartition
12512#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12513#[cfg_attr(feature = "bindings", derive(TS))]
12514pub struct AddPartition {
12515    pub this: Box<Expression>,
12516    #[serde(default)]
12517    pub exists: bool,
12518    #[serde(default)]
12519    pub location: Option<Box<Expression>>,
12520}
12521
12522/// AttachOption
12523#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12524#[cfg_attr(feature = "bindings", derive(TS))]
12525pub struct AttachOption {
12526    pub this: Box<Expression>,
12527    #[serde(default)]
12528    pub expression: Option<Box<Expression>>,
12529}
12530
12531/// DropPartition
12532#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12533#[cfg_attr(feature = "bindings", derive(TS))]
12534pub struct DropPartition {
12535    #[serde(default)]
12536    pub expressions: Vec<Expression>,
12537    #[serde(default)]
12538    pub exists: bool,
12539}
12540
12541/// ReplacePartition
12542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12543#[cfg_attr(feature = "bindings", derive(TS))]
12544pub struct ReplacePartition {
12545    pub expression: Box<Expression>,
12546    #[serde(default)]
12547    pub source: Option<Box<Expression>>,
12548}
12549
12550/// DPipe
12551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12552#[cfg_attr(feature = "bindings", derive(TS))]
12553pub struct DPipe {
12554    pub this: Box<Expression>,
12555    pub expression: Box<Expression>,
12556    #[serde(default)]
12557    pub safe: Option<Box<Expression>>,
12558}
12559
12560/// Operator
12561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12562#[cfg_attr(feature = "bindings", derive(TS))]
12563pub struct Operator {
12564    pub this: Box<Expression>,
12565    #[serde(default)]
12566    pub operator: Option<Box<Expression>>,
12567    pub expression: Box<Expression>,
12568    /// Comments between OPERATOR() and the RHS expression
12569    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12570    pub comments: Vec<String>,
12571}
12572
12573/// PivotAny
12574#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12575#[cfg_attr(feature = "bindings", derive(TS))]
12576pub struct PivotAny {
12577    #[serde(default)]
12578    pub this: Option<Box<Expression>>,
12579}
12580
12581/// Aliases
12582#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12583#[cfg_attr(feature = "bindings", derive(TS))]
12584pub struct Aliases {
12585    pub this: Box<Expression>,
12586    #[serde(default)]
12587    pub expressions: Vec<Expression>,
12588}
12589
12590/// AtIndex
12591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12592#[cfg_attr(feature = "bindings", derive(TS))]
12593pub struct AtIndex {
12594    pub this: Box<Expression>,
12595    pub expression: Box<Expression>,
12596}
12597
12598/// FromTimeZone
12599#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12600#[cfg_attr(feature = "bindings", derive(TS))]
12601pub struct FromTimeZone {
12602    pub this: Box<Expression>,
12603    #[serde(default)]
12604    pub zone: Option<Box<Expression>>,
12605}
12606
12607/// Format override for a column in Teradata
12608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12609#[cfg_attr(feature = "bindings", derive(TS))]
12610pub struct FormatPhrase {
12611    pub this: Box<Expression>,
12612    pub format: String,
12613}
12614
12615/// ForIn
12616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12617#[cfg_attr(feature = "bindings", derive(TS))]
12618pub struct ForIn {
12619    pub this: Box<Expression>,
12620    pub expression: Box<Expression>,
12621}
12622
12623/// Automatically converts unit arg into a var.
12624#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12625#[cfg_attr(feature = "bindings", derive(TS))]
12626pub struct TimeUnit {
12627    #[serde(default)]
12628    pub unit: Option<String>,
12629}
12630
12631/// IntervalOp
12632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12633#[cfg_attr(feature = "bindings", derive(TS))]
12634pub struct IntervalOp {
12635    #[serde(default)]
12636    pub unit: Option<String>,
12637    pub expression: Box<Expression>,
12638}
12639
12640/// HavingMax
12641#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12642#[cfg_attr(feature = "bindings", derive(TS))]
12643pub struct HavingMax {
12644    pub this: Box<Expression>,
12645    pub expression: Box<Expression>,
12646    #[serde(default)]
12647    pub max: Option<Box<Expression>>,
12648}
12649
12650/// CosineDistance
12651#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12652#[cfg_attr(feature = "bindings", derive(TS))]
12653pub struct CosineDistance {
12654    pub this: Box<Expression>,
12655    pub expression: Box<Expression>,
12656}
12657
12658/// DotProduct
12659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12660#[cfg_attr(feature = "bindings", derive(TS))]
12661pub struct DotProduct {
12662    pub this: Box<Expression>,
12663    pub expression: Box<Expression>,
12664}
12665
12666/// EuclideanDistance
12667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12668#[cfg_attr(feature = "bindings", derive(TS))]
12669pub struct EuclideanDistance {
12670    pub this: Box<Expression>,
12671    pub expression: Box<Expression>,
12672}
12673
12674/// ManhattanDistance
12675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12676#[cfg_attr(feature = "bindings", derive(TS))]
12677pub struct ManhattanDistance {
12678    pub this: Box<Expression>,
12679    pub expression: Box<Expression>,
12680}
12681
12682/// JarowinklerSimilarity
12683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12684#[cfg_attr(feature = "bindings", derive(TS))]
12685pub struct JarowinklerSimilarity {
12686    pub this: Box<Expression>,
12687    pub expression: Box<Expression>,
12688}
12689
12690/// Booland
12691#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12692#[cfg_attr(feature = "bindings", derive(TS))]
12693pub struct Booland {
12694    pub this: Box<Expression>,
12695    pub expression: Box<Expression>,
12696}
12697
12698/// Boolor
12699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12700#[cfg_attr(feature = "bindings", derive(TS))]
12701pub struct Boolor {
12702    pub this: Box<Expression>,
12703    pub expression: Box<Expression>,
12704}
12705
12706/// ParameterizedAgg
12707#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12708#[cfg_attr(feature = "bindings", derive(TS))]
12709pub struct ParameterizedAgg {
12710    pub this: Box<Expression>,
12711    #[serde(default)]
12712    pub expressions: Vec<Expression>,
12713    #[serde(default)]
12714    pub params: Vec<Expression>,
12715}
12716
12717/// ArgMax
12718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12719#[cfg_attr(feature = "bindings", derive(TS))]
12720pub struct ArgMax {
12721    pub this: Box<Expression>,
12722    pub expression: Box<Expression>,
12723    #[serde(default)]
12724    pub count: Option<Box<Expression>>,
12725}
12726
12727/// ArgMin
12728#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12729#[cfg_attr(feature = "bindings", derive(TS))]
12730pub struct ArgMin {
12731    pub this: Box<Expression>,
12732    pub expression: Box<Expression>,
12733    #[serde(default)]
12734    pub count: Option<Box<Expression>>,
12735}
12736
12737/// ApproxTopK
12738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12739#[cfg_attr(feature = "bindings", derive(TS))]
12740pub struct ApproxTopK {
12741    pub this: Box<Expression>,
12742    #[serde(default)]
12743    pub expression: Option<Box<Expression>>,
12744    #[serde(default)]
12745    pub counters: Option<Box<Expression>>,
12746}
12747
12748/// ApproxTopKAccumulate
12749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12750#[cfg_attr(feature = "bindings", derive(TS))]
12751pub struct ApproxTopKAccumulate {
12752    pub this: Box<Expression>,
12753    #[serde(default)]
12754    pub expression: Option<Box<Expression>>,
12755}
12756
12757/// ApproxTopKCombine
12758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12759#[cfg_attr(feature = "bindings", derive(TS))]
12760pub struct ApproxTopKCombine {
12761    pub this: Box<Expression>,
12762    #[serde(default)]
12763    pub expression: Option<Box<Expression>>,
12764}
12765
12766/// ApproxTopKEstimate
12767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12768#[cfg_attr(feature = "bindings", derive(TS))]
12769pub struct ApproxTopKEstimate {
12770    pub this: Box<Expression>,
12771    #[serde(default)]
12772    pub expression: Option<Box<Expression>>,
12773}
12774
12775/// ApproxTopSum
12776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12777#[cfg_attr(feature = "bindings", derive(TS))]
12778pub struct ApproxTopSum {
12779    pub this: Box<Expression>,
12780    pub expression: Box<Expression>,
12781    #[serde(default)]
12782    pub count: Option<Box<Expression>>,
12783}
12784
12785/// ApproxQuantiles
12786#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12787#[cfg_attr(feature = "bindings", derive(TS))]
12788pub struct ApproxQuantiles {
12789    pub this: Box<Expression>,
12790    #[serde(default)]
12791    pub expression: Option<Box<Expression>>,
12792}
12793
12794/// Minhash
12795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12796#[cfg_attr(feature = "bindings", derive(TS))]
12797pub struct Minhash {
12798    pub this: Box<Expression>,
12799    #[serde(default)]
12800    pub expressions: Vec<Expression>,
12801}
12802
12803/// FarmFingerprint
12804#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12805#[cfg_attr(feature = "bindings", derive(TS))]
12806pub struct FarmFingerprint {
12807    #[serde(default)]
12808    pub expressions: Vec<Expression>,
12809}
12810
12811/// Float64
12812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12813#[cfg_attr(feature = "bindings", derive(TS))]
12814pub struct Float64 {
12815    pub this: Box<Expression>,
12816    #[serde(default)]
12817    pub expression: Option<Box<Expression>>,
12818}
12819
12820/// Transform
12821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12822#[cfg_attr(feature = "bindings", derive(TS))]
12823pub struct Transform {
12824    pub this: Box<Expression>,
12825    pub expression: Box<Expression>,
12826}
12827
12828/// Translate
12829#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12830#[cfg_attr(feature = "bindings", derive(TS))]
12831pub struct Translate {
12832    pub this: Box<Expression>,
12833    #[serde(default)]
12834    pub from_: Option<Box<Expression>>,
12835    #[serde(default)]
12836    pub to: Option<Box<Expression>>,
12837}
12838
12839/// Grouping
12840#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12841#[cfg_attr(feature = "bindings", derive(TS))]
12842pub struct Grouping {
12843    #[serde(default)]
12844    pub expressions: Vec<Expression>,
12845}
12846
12847/// GroupingId
12848#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12849#[cfg_attr(feature = "bindings", derive(TS))]
12850pub struct GroupingId {
12851    #[serde(default)]
12852    pub expressions: Vec<Expression>,
12853}
12854
12855/// Anonymous
12856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12857#[cfg_attr(feature = "bindings", derive(TS))]
12858pub struct Anonymous {
12859    pub this: Box<Expression>,
12860    #[serde(default)]
12861    pub expressions: Vec<Expression>,
12862}
12863
12864/// AnonymousAggFunc
12865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12866#[cfg_attr(feature = "bindings", derive(TS))]
12867pub struct AnonymousAggFunc {
12868    pub this: Box<Expression>,
12869    #[serde(default)]
12870    pub expressions: Vec<Expression>,
12871}
12872
12873/// CombinedAggFunc
12874#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12875#[cfg_attr(feature = "bindings", derive(TS))]
12876pub struct CombinedAggFunc {
12877    pub this: Box<Expression>,
12878    #[serde(default)]
12879    pub expressions: Vec<Expression>,
12880}
12881
12882/// CombinedParameterizedAgg
12883#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12884#[cfg_attr(feature = "bindings", derive(TS))]
12885pub struct CombinedParameterizedAgg {
12886    pub this: Box<Expression>,
12887    #[serde(default)]
12888    pub expressions: Vec<Expression>,
12889    #[serde(default)]
12890    pub params: Vec<Expression>,
12891}
12892
12893/// HashAgg
12894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12895#[cfg_attr(feature = "bindings", derive(TS))]
12896pub struct HashAgg {
12897    pub this: Box<Expression>,
12898    #[serde(default)]
12899    pub expressions: Vec<Expression>,
12900}
12901
12902/// Hll
12903#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12904#[cfg_attr(feature = "bindings", derive(TS))]
12905pub struct Hll {
12906    pub this: Box<Expression>,
12907    #[serde(default)]
12908    pub expressions: Vec<Expression>,
12909}
12910
12911/// Apply
12912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12913#[cfg_attr(feature = "bindings", derive(TS))]
12914pub struct Apply {
12915    pub this: Box<Expression>,
12916    pub expression: Box<Expression>,
12917}
12918
12919/// ToBoolean
12920#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12921#[cfg_attr(feature = "bindings", derive(TS))]
12922pub struct ToBoolean {
12923    pub this: Box<Expression>,
12924    #[serde(default)]
12925    pub safe: Option<Box<Expression>>,
12926}
12927
12928/// List
12929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12930#[cfg_attr(feature = "bindings", derive(TS))]
12931pub struct List {
12932    #[serde(default)]
12933    pub expressions: Vec<Expression>,
12934}
12935
12936/// ToMap - Materialize-style map constructor
12937/// Can hold either:
12938/// - A SELECT subquery (MAP(SELECT 'a', 1))
12939/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
12940#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12941#[cfg_attr(feature = "bindings", derive(TS))]
12942pub struct ToMap {
12943    /// Either a Select subquery or a Struct containing PropertyEQ entries
12944    pub this: Box<Expression>,
12945}
12946
12947/// Pad
12948#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12949#[cfg_attr(feature = "bindings", derive(TS))]
12950pub struct Pad {
12951    pub this: Box<Expression>,
12952    pub expression: Box<Expression>,
12953    #[serde(default)]
12954    pub fill_pattern: Option<Box<Expression>>,
12955    #[serde(default)]
12956    pub is_left: Option<Box<Expression>>,
12957}
12958
12959/// ToChar
12960#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12961#[cfg_attr(feature = "bindings", derive(TS))]
12962pub struct ToChar {
12963    pub this: Box<Expression>,
12964    #[serde(default)]
12965    pub format: Option<String>,
12966    #[serde(default)]
12967    pub nlsparam: Option<Box<Expression>>,
12968    #[serde(default)]
12969    pub is_numeric: Option<Box<Expression>>,
12970}
12971
12972/// StringFunc - String type conversion function (BigQuery STRING)
12973#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12974#[cfg_attr(feature = "bindings", derive(TS))]
12975pub struct StringFunc {
12976    pub this: Box<Expression>,
12977    #[serde(default)]
12978    pub zone: Option<Box<Expression>>,
12979}
12980
12981/// ToNumber
12982#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12983#[cfg_attr(feature = "bindings", derive(TS))]
12984pub struct ToNumber {
12985    pub this: Box<Expression>,
12986    #[serde(default)]
12987    pub format: Option<Box<Expression>>,
12988    #[serde(default)]
12989    pub nlsparam: Option<Box<Expression>>,
12990    #[serde(default)]
12991    pub precision: Option<Box<Expression>>,
12992    #[serde(default)]
12993    pub scale: Option<Box<Expression>>,
12994    #[serde(default)]
12995    pub safe: Option<Box<Expression>>,
12996    #[serde(default)]
12997    pub safe_name: Option<Box<Expression>>,
12998}
12999
13000/// ToDouble
13001#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13002#[cfg_attr(feature = "bindings", derive(TS))]
13003pub struct ToDouble {
13004    pub this: Box<Expression>,
13005    #[serde(default)]
13006    pub format: Option<String>,
13007    #[serde(default)]
13008    pub safe: Option<Box<Expression>>,
13009}
13010
13011/// ToDecfloat
13012#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13013#[cfg_attr(feature = "bindings", derive(TS))]
13014pub struct ToDecfloat {
13015    pub this: Box<Expression>,
13016    #[serde(default)]
13017    pub format: Option<String>,
13018}
13019
13020/// TryToDecfloat
13021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13022#[cfg_attr(feature = "bindings", derive(TS))]
13023pub struct TryToDecfloat {
13024    pub this: Box<Expression>,
13025    #[serde(default)]
13026    pub format: Option<String>,
13027}
13028
13029/// ToFile
13030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13031#[cfg_attr(feature = "bindings", derive(TS))]
13032pub struct ToFile {
13033    pub this: Box<Expression>,
13034    #[serde(default)]
13035    pub path: Option<Box<Expression>>,
13036    #[serde(default)]
13037    pub safe: Option<Box<Expression>>,
13038}
13039
13040/// Columns
13041#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13042#[cfg_attr(feature = "bindings", derive(TS))]
13043pub struct Columns {
13044    pub this: Box<Expression>,
13045    #[serde(default)]
13046    pub unpack: Option<Box<Expression>>,
13047}
13048
13049/// ConvertToCharset
13050#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13051#[cfg_attr(feature = "bindings", derive(TS))]
13052pub struct ConvertToCharset {
13053    pub this: Box<Expression>,
13054    #[serde(default)]
13055    pub dest: Option<Box<Expression>>,
13056    #[serde(default)]
13057    pub source: Option<Box<Expression>>,
13058}
13059
13060/// ConvertTimezone
13061#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13062#[cfg_attr(feature = "bindings", derive(TS))]
13063pub struct ConvertTimezone {
13064    #[serde(default)]
13065    pub source_tz: Option<Box<Expression>>,
13066    #[serde(default)]
13067    pub target_tz: Option<Box<Expression>>,
13068    #[serde(default)]
13069    pub timestamp: Option<Box<Expression>>,
13070    #[serde(default)]
13071    pub options: Vec<Expression>,
13072}
13073
13074/// GenerateSeries
13075#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13076#[cfg_attr(feature = "bindings", derive(TS))]
13077pub struct GenerateSeries {
13078    #[serde(default)]
13079    pub start: Option<Box<Expression>>,
13080    #[serde(default)]
13081    pub end: Option<Box<Expression>>,
13082    #[serde(default)]
13083    pub step: Option<Box<Expression>>,
13084    #[serde(default)]
13085    pub is_end_exclusive: Option<Box<Expression>>,
13086}
13087
13088/// AIAgg
13089#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13090#[cfg_attr(feature = "bindings", derive(TS))]
13091pub struct AIAgg {
13092    pub this: Box<Expression>,
13093    pub expression: Box<Expression>,
13094}
13095
13096/// AIClassify
13097#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13098#[cfg_attr(feature = "bindings", derive(TS))]
13099pub struct AIClassify {
13100    pub this: Box<Expression>,
13101    #[serde(default)]
13102    pub categories: Option<Box<Expression>>,
13103    #[serde(default)]
13104    pub config: Option<Box<Expression>>,
13105}
13106
13107/// ArrayAll
13108#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13109#[cfg_attr(feature = "bindings", derive(TS))]
13110pub struct ArrayAll {
13111    pub this: Box<Expression>,
13112    pub expression: Box<Expression>,
13113}
13114
13115/// ArrayAny
13116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13117#[cfg_attr(feature = "bindings", derive(TS))]
13118pub struct ArrayAny {
13119    pub this: Box<Expression>,
13120    pub expression: Box<Expression>,
13121}
13122
13123/// ArrayConstructCompact
13124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13125#[cfg_attr(feature = "bindings", derive(TS))]
13126pub struct ArrayConstructCompact {
13127    #[serde(default)]
13128    pub expressions: Vec<Expression>,
13129}
13130
13131/// StPoint
13132#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13133#[cfg_attr(feature = "bindings", derive(TS))]
13134pub struct StPoint {
13135    pub this: Box<Expression>,
13136    pub expression: Box<Expression>,
13137    #[serde(default)]
13138    pub null: Option<Box<Expression>>,
13139}
13140
13141/// StDistance
13142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13143#[cfg_attr(feature = "bindings", derive(TS))]
13144pub struct StDistance {
13145    pub this: Box<Expression>,
13146    pub expression: Box<Expression>,
13147    #[serde(default)]
13148    pub use_spheroid: Option<Box<Expression>>,
13149}
13150
13151/// StringToArray
13152#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13153#[cfg_attr(feature = "bindings", derive(TS))]
13154pub struct StringToArray {
13155    pub this: Box<Expression>,
13156    #[serde(default)]
13157    pub expression: Option<Box<Expression>>,
13158    #[serde(default)]
13159    pub null: Option<Box<Expression>>,
13160}
13161
13162/// ArraySum
13163#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13164#[cfg_attr(feature = "bindings", derive(TS))]
13165pub struct ArraySum {
13166    pub this: Box<Expression>,
13167    #[serde(default)]
13168    pub expression: Option<Box<Expression>>,
13169}
13170
13171/// ObjectAgg
13172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13173#[cfg_attr(feature = "bindings", derive(TS))]
13174pub struct ObjectAgg {
13175    pub this: Box<Expression>,
13176    pub expression: Box<Expression>,
13177}
13178
13179/// CastToStrType
13180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13181#[cfg_attr(feature = "bindings", derive(TS))]
13182pub struct CastToStrType {
13183    pub this: Box<Expression>,
13184    #[serde(default)]
13185    pub to: Option<Box<Expression>>,
13186}
13187
13188/// CheckJson
13189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13190#[cfg_attr(feature = "bindings", derive(TS))]
13191pub struct CheckJson {
13192    pub this: Box<Expression>,
13193}
13194
13195/// CheckXml
13196#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13197#[cfg_attr(feature = "bindings", derive(TS))]
13198pub struct CheckXml {
13199    pub this: Box<Expression>,
13200    #[serde(default)]
13201    pub disable_auto_convert: Option<Box<Expression>>,
13202}
13203
13204/// TranslateCharacters
13205#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13206#[cfg_attr(feature = "bindings", derive(TS))]
13207pub struct TranslateCharacters {
13208    pub this: Box<Expression>,
13209    pub expression: Box<Expression>,
13210    #[serde(default)]
13211    pub with_error: Option<Box<Expression>>,
13212}
13213
13214/// CurrentSchemas
13215#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13216#[cfg_attr(feature = "bindings", derive(TS))]
13217pub struct CurrentSchemas {
13218    #[serde(default)]
13219    pub this: Option<Box<Expression>>,
13220}
13221
13222/// CurrentDatetime
13223#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13224#[cfg_attr(feature = "bindings", derive(TS))]
13225pub struct CurrentDatetime {
13226    #[serde(default)]
13227    pub this: Option<Box<Expression>>,
13228}
13229
13230/// Localtime
13231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13232#[cfg_attr(feature = "bindings", derive(TS))]
13233pub struct Localtime {
13234    #[serde(default)]
13235    pub this: Option<Box<Expression>>,
13236}
13237
13238/// Localtimestamp
13239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13240#[cfg_attr(feature = "bindings", derive(TS))]
13241pub struct Localtimestamp {
13242    #[serde(default)]
13243    pub this: Option<Box<Expression>>,
13244}
13245
13246/// Systimestamp
13247#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13248#[cfg_attr(feature = "bindings", derive(TS))]
13249pub struct Systimestamp {
13250    #[serde(default)]
13251    pub this: Option<Box<Expression>>,
13252}
13253
13254/// CurrentSchema
13255#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13256#[cfg_attr(feature = "bindings", derive(TS))]
13257pub struct CurrentSchema {
13258    #[serde(default)]
13259    pub this: Option<Box<Expression>>,
13260}
13261
13262/// CurrentUser
13263#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13264#[cfg_attr(feature = "bindings", derive(TS))]
13265pub struct CurrentUser {
13266    #[serde(default)]
13267    pub this: Option<Box<Expression>>,
13268}
13269
13270/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13271#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13272#[cfg_attr(feature = "bindings", derive(TS))]
13273pub struct SessionUser;
13274
13275/// JSONPathRoot - Represents $ in JSON path expressions
13276#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13277#[cfg_attr(feature = "bindings", derive(TS))]
13278pub struct JSONPathRoot;
13279
13280/// UtcTime
13281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13282#[cfg_attr(feature = "bindings", derive(TS))]
13283pub struct UtcTime {
13284    #[serde(default)]
13285    pub this: Option<Box<Expression>>,
13286}
13287
13288/// UtcTimestamp
13289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13290#[cfg_attr(feature = "bindings", derive(TS))]
13291pub struct UtcTimestamp {
13292    #[serde(default)]
13293    pub this: Option<Box<Expression>>,
13294}
13295
13296/// TimestampFunc - TIMESTAMP constructor function
13297#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13298#[cfg_attr(feature = "bindings", derive(TS))]
13299pub struct TimestampFunc {
13300    #[serde(default)]
13301    pub this: Option<Box<Expression>>,
13302    #[serde(default)]
13303    pub zone: Option<Box<Expression>>,
13304    #[serde(default)]
13305    pub with_tz: Option<bool>,
13306    #[serde(default)]
13307    pub safe: Option<bool>,
13308}
13309
13310/// DateBin
13311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13312#[cfg_attr(feature = "bindings", derive(TS))]
13313pub struct DateBin {
13314    pub this: Box<Expression>,
13315    pub expression: Box<Expression>,
13316    #[serde(default)]
13317    pub unit: Option<String>,
13318    #[serde(default)]
13319    pub zone: Option<Box<Expression>>,
13320    #[serde(default)]
13321    pub origin: Option<Box<Expression>>,
13322}
13323
13324/// Datetime
13325#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13326#[cfg_attr(feature = "bindings", derive(TS))]
13327pub struct Datetime {
13328    pub this: Box<Expression>,
13329    #[serde(default)]
13330    pub expression: Option<Box<Expression>>,
13331}
13332
13333/// DatetimeAdd
13334#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13335#[cfg_attr(feature = "bindings", derive(TS))]
13336pub struct DatetimeAdd {
13337    pub this: Box<Expression>,
13338    pub expression: Box<Expression>,
13339    #[serde(default)]
13340    pub unit: Option<String>,
13341}
13342
13343/// DatetimeSub
13344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13345#[cfg_attr(feature = "bindings", derive(TS))]
13346pub struct DatetimeSub {
13347    pub this: Box<Expression>,
13348    pub expression: Box<Expression>,
13349    #[serde(default)]
13350    pub unit: Option<String>,
13351}
13352
13353/// DatetimeDiff
13354#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13355#[cfg_attr(feature = "bindings", derive(TS))]
13356pub struct DatetimeDiff {
13357    pub this: Box<Expression>,
13358    pub expression: Box<Expression>,
13359    #[serde(default)]
13360    pub unit: Option<String>,
13361}
13362
13363/// DatetimeTrunc
13364#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13365#[cfg_attr(feature = "bindings", derive(TS))]
13366pub struct DatetimeTrunc {
13367    pub this: Box<Expression>,
13368    pub unit: String,
13369    #[serde(default)]
13370    pub zone: Option<Box<Expression>>,
13371}
13372
13373/// Dayname
13374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13375#[cfg_attr(feature = "bindings", derive(TS))]
13376pub struct Dayname {
13377    pub this: Box<Expression>,
13378    #[serde(default)]
13379    pub abbreviated: Option<Box<Expression>>,
13380}
13381
13382/// MakeInterval
13383#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13384#[cfg_attr(feature = "bindings", derive(TS))]
13385pub struct MakeInterval {
13386    #[serde(default)]
13387    pub year: Option<Box<Expression>>,
13388    #[serde(default)]
13389    pub month: Option<Box<Expression>>,
13390    #[serde(default)]
13391    pub week: Option<Box<Expression>>,
13392    #[serde(default)]
13393    pub day: Option<Box<Expression>>,
13394    #[serde(default)]
13395    pub hour: Option<Box<Expression>>,
13396    #[serde(default)]
13397    pub minute: Option<Box<Expression>>,
13398    #[serde(default)]
13399    pub second: Option<Box<Expression>>,
13400}
13401
13402/// PreviousDay
13403#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13404#[cfg_attr(feature = "bindings", derive(TS))]
13405pub struct PreviousDay {
13406    pub this: Box<Expression>,
13407    pub expression: Box<Expression>,
13408}
13409
13410/// Elt
13411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13412#[cfg_attr(feature = "bindings", derive(TS))]
13413pub struct Elt {
13414    pub this: Box<Expression>,
13415    #[serde(default)]
13416    pub expressions: Vec<Expression>,
13417}
13418
13419/// TimestampAdd
13420#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13421#[cfg_attr(feature = "bindings", derive(TS))]
13422pub struct TimestampAdd {
13423    pub this: Box<Expression>,
13424    pub expression: Box<Expression>,
13425    #[serde(default)]
13426    pub unit: Option<String>,
13427}
13428
13429/// TimestampSub
13430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13431#[cfg_attr(feature = "bindings", derive(TS))]
13432pub struct TimestampSub {
13433    pub this: Box<Expression>,
13434    pub expression: Box<Expression>,
13435    #[serde(default)]
13436    pub unit: Option<String>,
13437}
13438
13439/// TimestampDiff
13440#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13441#[cfg_attr(feature = "bindings", derive(TS))]
13442pub struct TimestampDiff {
13443    pub this: Box<Expression>,
13444    pub expression: Box<Expression>,
13445    #[serde(default)]
13446    pub unit: Option<String>,
13447}
13448
13449/// TimeSlice
13450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13451#[cfg_attr(feature = "bindings", derive(TS))]
13452pub struct TimeSlice {
13453    pub this: Box<Expression>,
13454    pub expression: Box<Expression>,
13455    pub unit: String,
13456    #[serde(default)]
13457    pub kind: Option<String>,
13458}
13459
13460/// TimeAdd
13461#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13462#[cfg_attr(feature = "bindings", derive(TS))]
13463pub struct TimeAdd {
13464    pub this: Box<Expression>,
13465    pub expression: Box<Expression>,
13466    #[serde(default)]
13467    pub unit: Option<String>,
13468}
13469
13470/// TimeSub
13471#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13472#[cfg_attr(feature = "bindings", derive(TS))]
13473pub struct TimeSub {
13474    pub this: Box<Expression>,
13475    pub expression: Box<Expression>,
13476    #[serde(default)]
13477    pub unit: Option<String>,
13478}
13479
13480/// TimeDiff
13481#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13482#[cfg_attr(feature = "bindings", derive(TS))]
13483pub struct TimeDiff {
13484    pub this: Box<Expression>,
13485    pub expression: Box<Expression>,
13486    #[serde(default)]
13487    pub unit: Option<String>,
13488}
13489
13490/// TimeTrunc
13491#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13492#[cfg_attr(feature = "bindings", derive(TS))]
13493pub struct TimeTrunc {
13494    pub this: Box<Expression>,
13495    pub unit: String,
13496    #[serde(default)]
13497    pub zone: Option<Box<Expression>>,
13498}
13499
13500/// DateFromParts
13501#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13502#[cfg_attr(feature = "bindings", derive(TS))]
13503pub struct DateFromParts {
13504    #[serde(default)]
13505    pub year: Option<Box<Expression>>,
13506    #[serde(default)]
13507    pub month: Option<Box<Expression>>,
13508    #[serde(default)]
13509    pub day: Option<Box<Expression>>,
13510    #[serde(default)]
13511    pub allow_overflow: Option<Box<Expression>>,
13512}
13513
13514/// TimeFromParts
13515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13516#[cfg_attr(feature = "bindings", derive(TS))]
13517pub struct TimeFromParts {
13518    #[serde(default)]
13519    pub hour: Option<Box<Expression>>,
13520    #[serde(default)]
13521    pub min: Option<Box<Expression>>,
13522    #[serde(default)]
13523    pub sec: Option<Box<Expression>>,
13524    #[serde(default)]
13525    pub nano: Option<Box<Expression>>,
13526    #[serde(default)]
13527    pub fractions: Option<Box<Expression>>,
13528    #[serde(default)]
13529    pub precision: Option<i64>,
13530}
13531
13532/// DecodeCase
13533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13534#[cfg_attr(feature = "bindings", derive(TS))]
13535pub struct DecodeCase {
13536    #[serde(default)]
13537    pub expressions: Vec<Expression>,
13538}
13539
13540/// Decrypt
13541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13542#[cfg_attr(feature = "bindings", derive(TS))]
13543pub struct Decrypt {
13544    pub this: Box<Expression>,
13545    #[serde(default)]
13546    pub passphrase: Option<Box<Expression>>,
13547    #[serde(default)]
13548    pub aad: Option<Box<Expression>>,
13549    #[serde(default)]
13550    pub encryption_method: Option<Box<Expression>>,
13551    #[serde(default)]
13552    pub safe: Option<Box<Expression>>,
13553}
13554
13555/// DecryptRaw
13556#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13557#[cfg_attr(feature = "bindings", derive(TS))]
13558pub struct DecryptRaw {
13559    pub this: Box<Expression>,
13560    #[serde(default)]
13561    pub key: Option<Box<Expression>>,
13562    #[serde(default)]
13563    pub iv: Option<Box<Expression>>,
13564    #[serde(default)]
13565    pub aad: Option<Box<Expression>>,
13566    #[serde(default)]
13567    pub encryption_method: Option<Box<Expression>>,
13568    #[serde(default)]
13569    pub aead: Option<Box<Expression>>,
13570    #[serde(default)]
13571    pub safe: Option<Box<Expression>>,
13572}
13573
13574/// Encode
13575#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13576#[cfg_attr(feature = "bindings", derive(TS))]
13577pub struct Encode {
13578    pub this: Box<Expression>,
13579    #[serde(default)]
13580    pub charset: Option<Box<Expression>>,
13581}
13582
13583/// Encrypt
13584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13585#[cfg_attr(feature = "bindings", derive(TS))]
13586pub struct Encrypt {
13587    pub this: Box<Expression>,
13588    #[serde(default)]
13589    pub passphrase: Option<Box<Expression>>,
13590    #[serde(default)]
13591    pub aad: Option<Box<Expression>>,
13592    #[serde(default)]
13593    pub encryption_method: Option<Box<Expression>>,
13594}
13595
13596/// EncryptRaw
13597#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13598#[cfg_attr(feature = "bindings", derive(TS))]
13599pub struct EncryptRaw {
13600    pub this: Box<Expression>,
13601    #[serde(default)]
13602    pub key: Option<Box<Expression>>,
13603    #[serde(default)]
13604    pub iv: Option<Box<Expression>>,
13605    #[serde(default)]
13606    pub aad: Option<Box<Expression>>,
13607    #[serde(default)]
13608    pub encryption_method: Option<Box<Expression>>,
13609}
13610
13611/// EqualNull
13612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13613#[cfg_attr(feature = "bindings", derive(TS))]
13614pub struct EqualNull {
13615    pub this: Box<Expression>,
13616    pub expression: Box<Expression>,
13617}
13618
13619/// ToBinary
13620#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13621#[cfg_attr(feature = "bindings", derive(TS))]
13622pub struct ToBinary {
13623    pub this: Box<Expression>,
13624    #[serde(default)]
13625    pub format: Option<String>,
13626    #[serde(default)]
13627    pub safe: Option<Box<Expression>>,
13628}
13629
13630/// Base64DecodeBinary
13631#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13632#[cfg_attr(feature = "bindings", derive(TS))]
13633pub struct Base64DecodeBinary {
13634    pub this: Box<Expression>,
13635    #[serde(default)]
13636    pub alphabet: Option<Box<Expression>>,
13637}
13638
13639/// Base64DecodeString
13640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13641#[cfg_attr(feature = "bindings", derive(TS))]
13642pub struct Base64DecodeString {
13643    pub this: Box<Expression>,
13644    #[serde(default)]
13645    pub alphabet: Option<Box<Expression>>,
13646}
13647
13648/// Base64Encode
13649#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13650#[cfg_attr(feature = "bindings", derive(TS))]
13651pub struct Base64Encode {
13652    pub this: Box<Expression>,
13653    #[serde(default)]
13654    pub max_line_length: Option<Box<Expression>>,
13655    #[serde(default)]
13656    pub alphabet: Option<Box<Expression>>,
13657}
13658
13659/// TryBase64DecodeBinary
13660#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13661#[cfg_attr(feature = "bindings", derive(TS))]
13662pub struct TryBase64DecodeBinary {
13663    pub this: Box<Expression>,
13664    #[serde(default)]
13665    pub alphabet: Option<Box<Expression>>,
13666}
13667
13668/// TryBase64DecodeString
13669#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13670#[cfg_attr(feature = "bindings", derive(TS))]
13671pub struct TryBase64DecodeString {
13672    pub this: Box<Expression>,
13673    #[serde(default)]
13674    pub alphabet: Option<Box<Expression>>,
13675}
13676
13677/// GapFill
13678#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13679#[cfg_attr(feature = "bindings", derive(TS))]
13680pub struct GapFill {
13681    pub this: Box<Expression>,
13682    #[serde(default)]
13683    pub ts_column: Option<Box<Expression>>,
13684    #[serde(default)]
13685    pub bucket_width: Option<Box<Expression>>,
13686    #[serde(default)]
13687    pub partitioning_columns: Option<Box<Expression>>,
13688    #[serde(default)]
13689    pub value_columns: Option<Box<Expression>>,
13690    #[serde(default)]
13691    pub origin: Option<Box<Expression>>,
13692    #[serde(default)]
13693    pub ignore_nulls: Option<Box<Expression>>,
13694}
13695
13696/// GenerateDateArray
13697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13698#[cfg_attr(feature = "bindings", derive(TS))]
13699pub struct GenerateDateArray {
13700    #[serde(default)]
13701    pub start: Option<Box<Expression>>,
13702    #[serde(default)]
13703    pub end: Option<Box<Expression>>,
13704    #[serde(default)]
13705    pub step: Option<Box<Expression>>,
13706}
13707
13708/// GenerateTimestampArray
13709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13710#[cfg_attr(feature = "bindings", derive(TS))]
13711pub struct GenerateTimestampArray {
13712    #[serde(default)]
13713    pub start: Option<Box<Expression>>,
13714    #[serde(default)]
13715    pub end: Option<Box<Expression>>,
13716    #[serde(default)]
13717    pub step: Option<Box<Expression>>,
13718}
13719
13720/// GetExtract
13721#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13722#[cfg_attr(feature = "bindings", derive(TS))]
13723pub struct GetExtract {
13724    pub this: Box<Expression>,
13725    pub expression: Box<Expression>,
13726}
13727
13728/// Getbit
13729#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13730#[cfg_attr(feature = "bindings", derive(TS))]
13731pub struct Getbit {
13732    pub this: Box<Expression>,
13733    pub expression: Box<Expression>,
13734    #[serde(default)]
13735    pub zero_is_msb: Option<Box<Expression>>,
13736}
13737
13738/// OverflowTruncateBehavior
13739#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13740#[cfg_attr(feature = "bindings", derive(TS))]
13741pub struct OverflowTruncateBehavior {
13742    #[serde(default)]
13743    pub this: Option<Box<Expression>>,
13744    #[serde(default)]
13745    pub with_count: Option<Box<Expression>>,
13746}
13747
13748/// HexEncode
13749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13750#[cfg_attr(feature = "bindings", derive(TS))]
13751pub struct HexEncode {
13752    pub this: Box<Expression>,
13753    #[serde(default)]
13754    pub case: Option<Box<Expression>>,
13755}
13756
13757/// Compress
13758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13759#[cfg_attr(feature = "bindings", derive(TS))]
13760pub struct Compress {
13761    pub this: Box<Expression>,
13762    #[serde(default)]
13763    pub method: Option<String>,
13764}
13765
13766/// DecompressBinary
13767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13768#[cfg_attr(feature = "bindings", derive(TS))]
13769pub struct DecompressBinary {
13770    pub this: Box<Expression>,
13771    pub method: String,
13772}
13773
13774/// DecompressString
13775#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13776#[cfg_attr(feature = "bindings", derive(TS))]
13777pub struct DecompressString {
13778    pub this: Box<Expression>,
13779    pub method: String,
13780}
13781
13782/// Xor
13783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13784#[cfg_attr(feature = "bindings", derive(TS))]
13785pub struct Xor {
13786    #[serde(default)]
13787    pub this: Option<Box<Expression>>,
13788    #[serde(default)]
13789    pub expression: Option<Box<Expression>>,
13790    #[serde(default)]
13791    pub expressions: Vec<Expression>,
13792}
13793
13794/// Nullif
13795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13796#[cfg_attr(feature = "bindings", derive(TS))]
13797pub struct Nullif {
13798    pub this: Box<Expression>,
13799    pub expression: Box<Expression>,
13800}
13801
13802/// JSON
13803#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13804#[cfg_attr(feature = "bindings", derive(TS))]
13805pub struct JSON {
13806    #[serde(default)]
13807    pub this: Option<Box<Expression>>,
13808    #[serde(default)]
13809    pub with_: Option<Box<Expression>>,
13810    #[serde(default)]
13811    pub unique: bool,
13812}
13813
13814/// JSONPath
13815#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13816#[cfg_attr(feature = "bindings", derive(TS))]
13817pub struct JSONPath {
13818    #[serde(default)]
13819    pub expressions: Vec<Expression>,
13820    #[serde(default)]
13821    pub escape: Option<Box<Expression>>,
13822}
13823
13824/// JSONPathFilter
13825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13826#[cfg_attr(feature = "bindings", derive(TS))]
13827pub struct JSONPathFilter {
13828    pub this: Box<Expression>,
13829}
13830
13831/// JSONPathKey
13832#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13833#[cfg_attr(feature = "bindings", derive(TS))]
13834pub struct JSONPathKey {
13835    pub this: Box<Expression>,
13836}
13837
13838/// JSONPathRecursive
13839#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13840#[cfg_attr(feature = "bindings", derive(TS))]
13841pub struct JSONPathRecursive {
13842    #[serde(default)]
13843    pub this: Option<Box<Expression>>,
13844}
13845
13846/// JSONPathScript
13847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13848#[cfg_attr(feature = "bindings", derive(TS))]
13849pub struct JSONPathScript {
13850    pub this: Box<Expression>,
13851}
13852
13853/// JSONPathSlice
13854#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13855#[cfg_attr(feature = "bindings", derive(TS))]
13856pub struct JSONPathSlice {
13857    #[serde(default)]
13858    pub start: Option<Box<Expression>>,
13859    #[serde(default)]
13860    pub end: Option<Box<Expression>>,
13861    #[serde(default)]
13862    pub step: Option<Box<Expression>>,
13863}
13864
13865/// JSONPathSelector
13866#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13867#[cfg_attr(feature = "bindings", derive(TS))]
13868pub struct JSONPathSelector {
13869    pub this: Box<Expression>,
13870}
13871
13872/// JSONPathSubscript
13873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13874#[cfg_attr(feature = "bindings", derive(TS))]
13875pub struct JSONPathSubscript {
13876    pub this: Box<Expression>,
13877}
13878
13879/// JSONPathUnion
13880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13881#[cfg_attr(feature = "bindings", derive(TS))]
13882pub struct JSONPathUnion {
13883    #[serde(default)]
13884    pub expressions: Vec<Expression>,
13885}
13886
13887/// Format
13888#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13889#[cfg_attr(feature = "bindings", derive(TS))]
13890pub struct Format {
13891    pub this: Box<Expression>,
13892    #[serde(default)]
13893    pub expressions: Vec<Expression>,
13894}
13895
13896/// JSONKeys
13897#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13898#[cfg_attr(feature = "bindings", derive(TS))]
13899pub struct JSONKeys {
13900    pub this: Box<Expression>,
13901    #[serde(default)]
13902    pub expression: Option<Box<Expression>>,
13903    #[serde(default)]
13904    pub expressions: Vec<Expression>,
13905}
13906
13907/// JSONKeyValue
13908#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13909#[cfg_attr(feature = "bindings", derive(TS))]
13910pub struct JSONKeyValue {
13911    pub this: Box<Expression>,
13912    pub expression: Box<Expression>,
13913}
13914
13915/// JSONKeysAtDepth
13916#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13917#[cfg_attr(feature = "bindings", derive(TS))]
13918pub struct JSONKeysAtDepth {
13919    pub this: Box<Expression>,
13920    #[serde(default)]
13921    pub expression: Option<Box<Expression>>,
13922    #[serde(default)]
13923    pub mode: Option<Box<Expression>>,
13924}
13925
13926/// JSONObject
13927#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13928#[cfg_attr(feature = "bindings", derive(TS))]
13929pub struct JSONObject {
13930    #[serde(default)]
13931    pub expressions: Vec<Expression>,
13932    #[serde(default)]
13933    pub null_handling: Option<Box<Expression>>,
13934    #[serde(default)]
13935    pub unique_keys: Option<Box<Expression>>,
13936    #[serde(default)]
13937    pub return_type: Option<Box<Expression>>,
13938    #[serde(default)]
13939    pub encoding: Option<Box<Expression>>,
13940}
13941
13942/// JSONObjectAgg
13943#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13944#[cfg_attr(feature = "bindings", derive(TS))]
13945pub struct JSONObjectAgg {
13946    #[serde(default)]
13947    pub expressions: Vec<Expression>,
13948    #[serde(default)]
13949    pub null_handling: Option<Box<Expression>>,
13950    #[serde(default)]
13951    pub unique_keys: Option<Box<Expression>>,
13952    #[serde(default)]
13953    pub return_type: Option<Box<Expression>>,
13954    #[serde(default)]
13955    pub encoding: Option<Box<Expression>>,
13956}
13957
13958/// JSONBObjectAgg
13959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13960#[cfg_attr(feature = "bindings", derive(TS))]
13961pub struct JSONBObjectAgg {
13962    pub this: Box<Expression>,
13963    pub expression: Box<Expression>,
13964}
13965
13966/// JSONArray
13967#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13968#[cfg_attr(feature = "bindings", derive(TS))]
13969pub struct JSONArray {
13970    #[serde(default)]
13971    pub expressions: Vec<Expression>,
13972    #[serde(default)]
13973    pub null_handling: Option<Box<Expression>>,
13974    #[serde(default)]
13975    pub return_type: Option<Box<Expression>>,
13976    #[serde(default)]
13977    pub strict: Option<Box<Expression>>,
13978}
13979
13980/// JSONArrayAgg
13981#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13982#[cfg_attr(feature = "bindings", derive(TS))]
13983pub struct JSONArrayAgg {
13984    pub this: Box<Expression>,
13985    #[serde(default)]
13986    pub order: Option<Box<Expression>>,
13987    #[serde(default)]
13988    pub null_handling: Option<Box<Expression>>,
13989    #[serde(default)]
13990    pub return_type: Option<Box<Expression>>,
13991    #[serde(default)]
13992    pub strict: Option<Box<Expression>>,
13993}
13994
13995/// JSONExists
13996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13997#[cfg_attr(feature = "bindings", derive(TS))]
13998pub struct JSONExists {
13999    pub this: Box<Expression>,
14000    #[serde(default)]
14001    pub path: Option<Box<Expression>>,
14002    #[serde(default)]
14003    pub passing: Option<Box<Expression>>,
14004    #[serde(default)]
14005    pub on_condition: Option<Box<Expression>>,
14006    #[serde(default)]
14007    pub from_dcolonqmark: Option<Box<Expression>>,
14008}
14009
14010/// JSONColumnDef
14011#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14012#[cfg_attr(feature = "bindings", derive(TS))]
14013pub struct JSONColumnDef {
14014    #[serde(default)]
14015    pub this: Option<Box<Expression>>,
14016    #[serde(default)]
14017    pub kind: Option<String>,
14018    #[serde(default)]
14019    pub format_json: bool,
14020    #[serde(default)]
14021    pub path: Option<Box<Expression>>,
14022    #[serde(default)]
14023    pub nested_schema: Option<Box<Expression>>,
14024    #[serde(default)]
14025    pub ordinality: Option<Box<Expression>>,
14026}
14027
14028/// JSONSchema
14029#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14030#[cfg_attr(feature = "bindings", derive(TS))]
14031pub struct JSONSchema {
14032    #[serde(default)]
14033    pub expressions: Vec<Expression>,
14034}
14035
14036/// JSONSet
14037#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14038#[cfg_attr(feature = "bindings", derive(TS))]
14039pub struct JSONSet {
14040    pub this: Box<Expression>,
14041    #[serde(default)]
14042    pub expressions: Vec<Expression>,
14043}
14044
14045/// JSONStripNulls
14046#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14047#[cfg_attr(feature = "bindings", derive(TS))]
14048pub struct JSONStripNulls {
14049    pub this: Box<Expression>,
14050    #[serde(default)]
14051    pub expression: Option<Box<Expression>>,
14052    #[serde(default)]
14053    pub include_arrays: Option<Box<Expression>>,
14054    #[serde(default)]
14055    pub remove_empty: Option<Box<Expression>>,
14056}
14057
14058/// JSONValue
14059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14060#[cfg_attr(feature = "bindings", derive(TS))]
14061pub struct JSONValue {
14062    pub this: Box<Expression>,
14063    #[serde(default)]
14064    pub path: Option<Box<Expression>>,
14065    #[serde(default)]
14066    pub returning: Option<Box<Expression>>,
14067    #[serde(default)]
14068    pub on_condition: Option<Box<Expression>>,
14069}
14070
14071/// JSONValueArray
14072#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14073#[cfg_attr(feature = "bindings", derive(TS))]
14074pub struct JSONValueArray {
14075    pub this: Box<Expression>,
14076    #[serde(default)]
14077    pub expression: Option<Box<Expression>>,
14078}
14079
14080/// JSONRemove
14081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14082#[cfg_attr(feature = "bindings", derive(TS))]
14083pub struct JSONRemove {
14084    pub this: Box<Expression>,
14085    #[serde(default)]
14086    pub expressions: Vec<Expression>,
14087}
14088
14089/// JSONTable
14090#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14091#[cfg_attr(feature = "bindings", derive(TS))]
14092pub struct JSONTable {
14093    pub this: Box<Expression>,
14094    #[serde(default)]
14095    pub schema: Option<Box<Expression>>,
14096    #[serde(default)]
14097    pub path: Option<Box<Expression>>,
14098    #[serde(default)]
14099    pub error_handling: Option<Box<Expression>>,
14100    #[serde(default)]
14101    pub empty_handling: Option<Box<Expression>>,
14102}
14103
14104/// JSONType
14105#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14106#[cfg_attr(feature = "bindings", derive(TS))]
14107pub struct JSONType {
14108    pub this: Box<Expression>,
14109    #[serde(default)]
14110    pub expression: Option<Box<Expression>>,
14111}
14112
14113/// ObjectInsert
14114#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14115#[cfg_attr(feature = "bindings", derive(TS))]
14116pub struct ObjectInsert {
14117    pub this: Box<Expression>,
14118    #[serde(default)]
14119    pub key: Option<Box<Expression>>,
14120    #[serde(default)]
14121    pub value: Option<Box<Expression>>,
14122    #[serde(default)]
14123    pub update_flag: Option<Box<Expression>>,
14124}
14125
14126/// OpenJSONColumnDef
14127#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14128#[cfg_attr(feature = "bindings", derive(TS))]
14129pub struct OpenJSONColumnDef {
14130    pub this: Box<Expression>,
14131    pub kind: String,
14132    #[serde(default)]
14133    pub path: Option<Box<Expression>>,
14134    #[serde(default)]
14135    pub as_json: Option<Box<Expression>>,
14136    /// The parsed data type for proper generation
14137    #[serde(default, skip_serializing_if = "Option::is_none")]
14138    pub data_type: Option<DataType>,
14139}
14140
14141/// OpenJSON
14142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14143#[cfg_attr(feature = "bindings", derive(TS))]
14144pub struct OpenJSON {
14145    pub this: Box<Expression>,
14146    #[serde(default)]
14147    pub path: Option<Box<Expression>>,
14148    #[serde(default)]
14149    pub expressions: Vec<Expression>,
14150}
14151
14152/// JSONBExists
14153#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14154#[cfg_attr(feature = "bindings", derive(TS))]
14155pub struct JSONBExists {
14156    pub this: Box<Expression>,
14157    #[serde(default)]
14158    pub path: Option<Box<Expression>>,
14159}
14160
14161/// JSONCast
14162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14163#[cfg_attr(feature = "bindings", derive(TS))]
14164pub struct JSONCast {
14165    pub this: Box<Expression>,
14166    pub to: DataType,
14167}
14168
14169/// JSONExtract
14170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14171#[cfg_attr(feature = "bindings", derive(TS))]
14172pub struct JSONExtract {
14173    pub this: Box<Expression>,
14174    pub expression: Box<Expression>,
14175    #[serde(default)]
14176    pub only_json_types: Option<Box<Expression>>,
14177    #[serde(default)]
14178    pub expressions: Vec<Expression>,
14179    #[serde(default)]
14180    pub variant_extract: Option<Box<Expression>>,
14181    #[serde(default)]
14182    pub json_query: Option<Box<Expression>>,
14183    #[serde(default)]
14184    pub option: Option<Box<Expression>>,
14185    #[serde(default)]
14186    pub quote: Option<Box<Expression>>,
14187    #[serde(default)]
14188    pub on_condition: Option<Box<Expression>>,
14189    #[serde(default)]
14190    pub requires_json: Option<Box<Expression>>,
14191}
14192
14193/// JSONExtractQuote
14194#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14195#[cfg_attr(feature = "bindings", derive(TS))]
14196pub struct JSONExtractQuote {
14197    #[serde(default)]
14198    pub option: Option<Box<Expression>>,
14199    #[serde(default)]
14200    pub scalar: Option<Box<Expression>>,
14201}
14202
14203/// JSONExtractArray
14204#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14205#[cfg_attr(feature = "bindings", derive(TS))]
14206pub struct JSONExtractArray {
14207    pub this: Box<Expression>,
14208    #[serde(default)]
14209    pub expression: Option<Box<Expression>>,
14210}
14211
14212/// JSONExtractScalar
14213#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14214#[cfg_attr(feature = "bindings", derive(TS))]
14215pub struct JSONExtractScalar {
14216    pub this: Box<Expression>,
14217    pub expression: Box<Expression>,
14218    #[serde(default)]
14219    pub only_json_types: Option<Box<Expression>>,
14220    #[serde(default)]
14221    pub expressions: Vec<Expression>,
14222    #[serde(default)]
14223    pub json_type: Option<Box<Expression>>,
14224    #[serde(default)]
14225    pub scalar_only: Option<Box<Expression>>,
14226}
14227
14228/// JSONBExtractScalar
14229#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14230#[cfg_attr(feature = "bindings", derive(TS))]
14231pub struct JSONBExtractScalar {
14232    pub this: Box<Expression>,
14233    pub expression: Box<Expression>,
14234    #[serde(default)]
14235    pub json_type: Option<Box<Expression>>,
14236}
14237
14238/// JSONFormat
14239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14240#[cfg_attr(feature = "bindings", derive(TS))]
14241pub struct JSONFormat {
14242    #[serde(default)]
14243    pub this: Option<Box<Expression>>,
14244    #[serde(default)]
14245    pub options: Vec<Expression>,
14246    #[serde(default)]
14247    pub is_json: Option<Box<Expression>>,
14248    #[serde(default)]
14249    pub to_json: Option<Box<Expression>>,
14250}
14251
14252/// JSONArrayAppend
14253#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14254#[cfg_attr(feature = "bindings", derive(TS))]
14255pub struct JSONArrayAppend {
14256    pub this: Box<Expression>,
14257    #[serde(default)]
14258    pub expressions: Vec<Expression>,
14259}
14260
14261/// JSONArrayContains
14262#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14263#[cfg_attr(feature = "bindings", derive(TS))]
14264pub struct JSONArrayContains {
14265    pub this: Box<Expression>,
14266    pub expression: Box<Expression>,
14267    #[serde(default)]
14268    pub json_type: Option<Box<Expression>>,
14269}
14270
14271/// JSONArrayInsert
14272#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14273#[cfg_attr(feature = "bindings", derive(TS))]
14274pub struct JSONArrayInsert {
14275    pub this: Box<Expression>,
14276    #[serde(default)]
14277    pub expressions: Vec<Expression>,
14278}
14279
14280/// ParseJSON
14281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14282#[cfg_attr(feature = "bindings", derive(TS))]
14283pub struct ParseJSON {
14284    pub this: Box<Expression>,
14285    #[serde(default)]
14286    pub expression: Option<Box<Expression>>,
14287    #[serde(default)]
14288    pub safe: Option<Box<Expression>>,
14289}
14290
14291/// ParseUrl
14292#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14293#[cfg_attr(feature = "bindings", derive(TS))]
14294pub struct ParseUrl {
14295    pub this: Box<Expression>,
14296    #[serde(default)]
14297    pub part_to_extract: Option<Box<Expression>>,
14298    #[serde(default)]
14299    pub key: Option<Box<Expression>>,
14300    #[serde(default)]
14301    pub permissive: Option<Box<Expression>>,
14302}
14303
14304/// ParseIp
14305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14306#[cfg_attr(feature = "bindings", derive(TS))]
14307pub struct ParseIp {
14308    pub this: Box<Expression>,
14309    #[serde(default)]
14310    pub type_: Option<Box<Expression>>,
14311    #[serde(default)]
14312    pub permissive: Option<Box<Expression>>,
14313}
14314
14315/// ParseTime
14316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14317#[cfg_attr(feature = "bindings", derive(TS))]
14318pub struct ParseTime {
14319    pub this: Box<Expression>,
14320    pub format: String,
14321}
14322
14323/// ParseDatetime
14324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14325#[cfg_attr(feature = "bindings", derive(TS))]
14326pub struct ParseDatetime {
14327    pub this: Box<Expression>,
14328    #[serde(default)]
14329    pub format: Option<String>,
14330    #[serde(default)]
14331    pub zone: Option<Box<Expression>>,
14332}
14333
14334/// Map
14335#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14336#[cfg_attr(feature = "bindings", derive(TS))]
14337pub struct Map {
14338    #[serde(default)]
14339    pub keys: Vec<Expression>,
14340    #[serde(default)]
14341    pub values: Vec<Expression>,
14342}
14343
14344/// MapCat
14345#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14346#[cfg_attr(feature = "bindings", derive(TS))]
14347pub struct MapCat {
14348    pub this: Box<Expression>,
14349    pub expression: Box<Expression>,
14350}
14351
14352/// MapDelete
14353#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14354#[cfg_attr(feature = "bindings", derive(TS))]
14355pub struct MapDelete {
14356    pub this: Box<Expression>,
14357    #[serde(default)]
14358    pub expressions: Vec<Expression>,
14359}
14360
14361/// MapInsert
14362#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14363#[cfg_attr(feature = "bindings", derive(TS))]
14364pub struct MapInsert {
14365    pub this: Box<Expression>,
14366    #[serde(default)]
14367    pub key: Option<Box<Expression>>,
14368    #[serde(default)]
14369    pub value: Option<Box<Expression>>,
14370    #[serde(default)]
14371    pub update_flag: Option<Box<Expression>>,
14372}
14373
14374/// MapPick
14375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14376#[cfg_attr(feature = "bindings", derive(TS))]
14377pub struct MapPick {
14378    pub this: Box<Expression>,
14379    #[serde(default)]
14380    pub expressions: Vec<Expression>,
14381}
14382
14383/// ScopeResolution
14384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14385#[cfg_attr(feature = "bindings", derive(TS))]
14386pub struct ScopeResolution {
14387    #[serde(default)]
14388    pub this: Option<Box<Expression>>,
14389    pub expression: Box<Expression>,
14390}
14391
14392/// Slice
14393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14394#[cfg_attr(feature = "bindings", derive(TS))]
14395pub struct Slice {
14396    #[serde(default)]
14397    pub this: Option<Box<Expression>>,
14398    #[serde(default)]
14399    pub expression: Option<Box<Expression>>,
14400    #[serde(default)]
14401    pub step: Option<Box<Expression>>,
14402}
14403
14404/// VarMap
14405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14406#[cfg_attr(feature = "bindings", derive(TS))]
14407pub struct VarMap {
14408    #[serde(default)]
14409    pub keys: Vec<Expression>,
14410    #[serde(default)]
14411    pub values: Vec<Expression>,
14412}
14413
14414/// MatchAgainst
14415#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14416#[cfg_attr(feature = "bindings", derive(TS))]
14417pub struct MatchAgainst {
14418    pub this: Box<Expression>,
14419    #[serde(default)]
14420    pub expressions: Vec<Expression>,
14421    #[serde(default)]
14422    pub modifier: Option<Box<Expression>>,
14423}
14424
14425/// MD5Digest
14426#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14427#[cfg_attr(feature = "bindings", derive(TS))]
14428pub struct MD5Digest {
14429    pub this: Box<Expression>,
14430    #[serde(default)]
14431    pub expressions: Vec<Expression>,
14432}
14433
14434/// Monthname
14435#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14436#[cfg_attr(feature = "bindings", derive(TS))]
14437pub struct Monthname {
14438    pub this: Box<Expression>,
14439    #[serde(default)]
14440    pub abbreviated: Option<Box<Expression>>,
14441}
14442
14443/// Ntile
14444#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14445#[cfg_attr(feature = "bindings", derive(TS))]
14446pub struct Ntile {
14447    #[serde(default)]
14448    pub this: Option<Box<Expression>>,
14449}
14450
14451/// Normalize
14452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14453#[cfg_attr(feature = "bindings", derive(TS))]
14454pub struct Normalize {
14455    pub this: Box<Expression>,
14456    #[serde(default)]
14457    pub form: Option<Box<Expression>>,
14458    #[serde(default)]
14459    pub is_casefold: Option<Box<Expression>>,
14460}
14461
14462/// Normal
14463#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14464#[cfg_attr(feature = "bindings", derive(TS))]
14465pub struct Normal {
14466    pub this: Box<Expression>,
14467    #[serde(default)]
14468    pub stddev: Option<Box<Expression>>,
14469    #[serde(default)]
14470    pub gen: Option<Box<Expression>>,
14471}
14472
14473/// Predict
14474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14475#[cfg_attr(feature = "bindings", derive(TS))]
14476pub struct Predict {
14477    pub this: Box<Expression>,
14478    pub expression: Box<Expression>,
14479    #[serde(default)]
14480    pub params_struct: Option<Box<Expression>>,
14481}
14482
14483/// MLTranslate
14484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14485#[cfg_attr(feature = "bindings", derive(TS))]
14486pub struct MLTranslate {
14487    pub this: Box<Expression>,
14488    pub expression: Box<Expression>,
14489    #[serde(default)]
14490    pub params_struct: Option<Box<Expression>>,
14491}
14492
14493/// FeaturesAtTime
14494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14495#[cfg_attr(feature = "bindings", derive(TS))]
14496pub struct FeaturesAtTime {
14497    pub this: Box<Expression>,
14498    #[serde(default)]
14499    pub time: Option<Box<Expression>>,
14500    #[serde(default)]
14501    pub num_rows: Option<Box<Expression>>,
14502    #[serde(default)]
14503    pub ignore_feature_nulls: Option<Box<Expression>>,
14504}
14505
14506/// GenerateEmbedding
14507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14508#[cfg_attr(feature = "bindings", derive(TS))]
14509pub struct GenerateEmbedding {
14510    pub this: Box<Expression>,
14511    pub expression: Box<Expression>,
14512    #[serde(default)]
14513    pub params_struct: Option<Box<Expression>>,
14514    #[serde(default)]
14515    pub is_text: Option<Box<Expression>>,
14516}
14517
14518/// MLForecast
14519#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14520#[cfg_attr(feature = "bindings", derive(TS))]
14521pub struct MLForecast {
14522    pub this: Box<Expression>,
14523    #[serde(default)]
14524    pub expression: Option<Box<Expression>>,
14525    #[serde(default)]
14526    pub params_struct: Option<Box<Expression>>,
14527}
14528
14529/// ModelAttribute
14530#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14531#[cfg_attr(feature = "bindings", derive(TS))]
14532pub struct ModelAttribute {
14533    pub this: Box<Expression>,
14534    pub expression: Box<Expression>,
14535}
14536
14537/// VectorSearch
14538#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14539#[cfg_attr(feature = "bindings", derive(TS))]
14540pub struct VectorSearch {
14541    pub this: Box<Expression>,
14542    #[serde(default)]
14543    pub column_to_search: Option<Box<Expression>>,
14544    #[serde(default)]
14545    pub query_table: Option<Box<Expression>>,
14546    #[serde(default)]
14547    pub query_column_to_search: Option<Box<Expression>>,
14548    #[serde(default)]
14549    pub top_k: Option<Box<Expression>>,
14550    #[serde(default)]
14551    pub distance_type: Option<Box<Expression>>,
14552    #[serde(default)]
14553    pub options: Vec<Expression>,
14554}
14555
14556/// Quantile
14557#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14558#[cfg_attr(feature = "bindings", derive(TS))]
14559pub struct Quantile {
14560    pub this: Box<Expression>,
14561    #[serde(default)]
14562    pub quantile: Option<Box<Expression>>,
14563}
14564
14565/// ApproxQuantile
14566#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14567#[cfg_attr(feature = "bindings", derive(TS))]
14568pub struct ApproxQuantile {
14569    pub this: Box<Expression>,
14570    #[serde(default)]
14571    pub quantile: Option<Box<Expression>>,
14572    #[serde(default)]
14573    pub accuracy: Option<Box<Expression>>,
14574    #[serde(default)]
14575    pub weight: Option<Box<Expression>>,
14576    #[serde(default)]
14577    pub error_tolerance: Option<Box<Expression>>,
14578}
14579
14580/// ApproxPercentileEstimate
14581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14582#[cfg_attr(feature = "bindings", derive(TS))]
14583pub struct ApproxPercentileEstimate {
14584    pub this: Box<Expression>,
14585    #[serde(default)]
14586    pub percentile: Option<Box<Expression>>,
14587}
14588
14589/// Randn
14590#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14591#[cfg_attr(feature = "bindings", derive(TS))]
14592pub struct Randn {
14593    #[serde(default)]
14594    pub this: Option<Box<Expression>>,
14595}
14596
14597/// Randstr
14598#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14599#[cfg_attr(feature = "bindings", derive(TS))]
14600pub struct Randstr {
14601    pub this: Box<Expression>,
14602    #[serde(default)]
14603    pub generator: Option<Box<Expression>>,
14604}
14605
14606/// RangeN
14607#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14608#[cfg_attr(feature = "bindings", derive(TS))]
14609pub struct RangeN {
14610    pub this: Box<Expression>,
14611    #[serde(default)]
14612    pub expressions: Vec<Expression>,
14613    #[serde(default)]
14614    pub each: Option<Box<Expression>>,
14615}
14616
14617/// RangeBucket
14618#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14619#[cfg_attr(feature = "bindings", derive(TS))]
14620pub struct RangeBucket {
14621    pub this: Box<Expression>,
14622    pub expression: Box<Expression>,
14623}
14624
14625/// ReadCSV
14626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14627#[cfg_attr(feature = "bindings", derive(TS))]
14628pub struct ReadCSV {
14629    pub this: Box<Expression>,
14630    #[serde(default)]
14631    pub expressions: Vec<Expression>,
14632}
14633
14634/// ReadParquet
14635#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14636#[cfg_attr(feature = "bindings", derive(TS))]
14637pub struct ReadParquet {
14638    #[serde(default)]
14639    pub expressions: Vec<Expression>,
14640}
14641
14642/// Reduce
14643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14644#[cfg_attr(feature = "bindings", derive(TS))]
14645pub struct Reduce {
14646    pub this: Box<Expression>,
14647    #[serde(default)]
14648    pub initial: Option<Box<Expression>>,
14649    #[serde(default)]
14650    pub merge: Option<Box<Expression>>,
14651    #[serde(default)]
14652    pub finish: Option<Box<Expression>>,
14653}
14654
14655/// RegexpExtractAll
14656#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14657#[cfg_attr(feature = "bindings", derive(TS))]
14658pub struct RegexpExtractAll {
14659    pub this: Box<Expression>,
14660    pub expression: Box<Expression>,
14661    #[serde(default)]
14662    pub group: Option<Box<Expression>>,
14663    #[serde(default)]
14664    pub parameters: Option<Box<Expression>>,
14665    #[serde(default)]
14666    pub position: Option<Box<Expression>>,
14667    #[serde(default)]
14668    pub occurrence: Option<Box<Expression>>,
14669}
14670
14671/// RegexpILike
14672#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14673#[cfg_attr(feature = "bindings", derive(TS))]
14674pub struct RegexpILike {
14675    pub this: Box<Expression>,
14676    pub expression: Box<Expression>,
14677    #[serde(default)]
14678    pub flag: Option<Box<Expression>>,
14679}
14680
14681/// RegexpFullMatch
14682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14683#[cfg_attr(feature = "bindings", derive(TS))]
14684pub struct RegexpFullMatch {
14685    pub this: Box<Expression>,
14686    pub expression: Box<Expression>,
14687    #[serde(default)]
14688    pub options: Vec<Expression>,
14689}
14690
14691/// RegexpInstr
14692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14693#[cfg_attr(feature = "bindings", derive(TS))]
14694pub struct RegexpInstr {
14695    pub this: Box<Expression>,
14696    pub expression: Box<Expression>,
14697    #[serde(default)]
14698    pub position: Option<Box<Expression>>,
14699    #[serde(default)]
14700    pub occurrence: Option<Box<Expression>>,
14701    #[serde(default)]
14702    pub option: Option<Box<Expression>>,
14703    #[serde(default)]
14704    pub parameters: Option<Box<Expression>>,
14705    #[serde(default)]
14706    pub group: Option<Box<Expression>>,
14707}
14708
14709/// RegexpSplit
14710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14711#[cfg_attr(feature = "bindings", derive(TS))]
14712pub struct RegexpSplit {
14713    pub this: Box<Expression>,
14714    pub expression: Box<Expression>,
14715    #[serde(default)]
14716    pub limit: Option<Box<Expression>>,
14717}
14718
14719/// RegexpCount
14720#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14721#[cfg_attr(feature = "bindings", derive(TS))]
14722pub struct RegexpCount {
14723    pub this: Box<Expression>,
14724    pub expression: Box<Expression>,
14725    #[serde(default)]
14726    pub position: Option<Box<Expression>>,
14727    #[serde(default)]
14728    pub parameters: Option<Box<Expression>>,
14729}
14730
14731/// RegrValx
14732#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14733#[cfg_attr(feature = "bindings", derive(TS))]
14734pub struct RegrValx {
14735    pub this: Box<Expression>,
14736    pub expression: Box<Expression>,
14737}
14738
14739/// RegrValy
14740#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14741#[cfg_attr(feature = "bindings", derive(TS))]
14742pub struct RegrValy {
14743    pub this: Box<Expression>,
14744    pub expression: Box<Expression>,
14745}
14746
14747/// RegrAvgy
14748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14749#[cfg_attr(feature = "bindings", derive(TS))]
14750pub struct RegrAvgy {
14751    pub this: Box<Expression>,
14752    pub expression: Box<Expression>,
14753}
14754
14755/// RegrAvgx
14756#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14757#[cfg_attr(feature = "bindings", derive(TS))]
14758pub struct RegrAvgx {
14759    pub this: Box<Expression>,
14760    pub expression: Box<Expression>,
14761}
14762
14763/// RegrCount
14764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14765#[cfg_attr(feature = "bindings", derive(TS))]
14766pub struct RegrCount {
14767    pub this: Box<Expression>,
14768    pub expression: Box<Expression>,
14769}
14770
14771/// RegrIntercept
14772#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14773#[cfg_attr(feature = "bindings", derive(TS))]
14774pub struct RegrIntercept {
14775    pub this: Box<Expression>,
14776    pub expression: Box<Expression>,
14777}
14778
14779/// RegrR2
14780#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14781#[cfg_attr(feature = "bindings", derive(TS))]
14782pub struct RegrR2 {
14783    pub this: Box<Expression>,
14784    pub expression: Box<Expression>,
14785}
14786
14787/// RegrSxx
14788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14789#[cfg_attr(feature = "bindings", derive(TS))]
14790pub struct RegrSxx {
14791    pub this: Box<Expression>,
14792    pub expression: Box<Expression>,
14793}
14794
14795/// RegrSxy
14796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14797#[cfg_attr(feature = "bindings", derive(TS))]
14798pub struct RegrSxy {
14799    pub this: Box<Expression>,
14800    pub expression: Box<Expression>,
14801}
14802
14803/// RegrSyy
14804#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14805#[cfg_attr(feature = "bindings", derive(TS))]
14806pub struct RegrSyy {
14807    pub this: Box<Expression>,
14808    pub expression: Box<Expression>,
14809}
14810
14811/// RegrSlope
14812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14813#[cfg_attr(feature = "bindings", derive(TS))]
14814pub struct RegrSlope {
14815    pub this: Box<Expression>,
14816    pub expression: Box<Expression>,
14817}
14818
14819/// SafeAdd
14820#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14821#[cfg_attr(feature = "bindings", derive(TS))]
14822pub struct SafeAdd {
14823    pub this: Box<Expression>,
14824    pub expression: Box<Expression>,
14825}
14826
14827/// SafeDivide
14828#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14829#[cfg_attr(feature = "bindings", derive(TS))]
14830pub struct SafeDivide {
14831    pub this: Box<Expression>,
14832    pub expression: Box<Expression>,
14833}
14834
14835/// SafeMultiply
14836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14837#[cfg_attr(feature = "bindings", derive(TS))]
14838pub struct SafeMultiply {
14839    pub this: Box<Expression>,
14840    pub expression: Box<Expression>,
14841}
14842
14843/// SafeSubtract
14844#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14845#[cfg_attr(feature = "bindings", derive(TS))]
14846pub struct SafeSubtract {
14847    pub this: Box<Expression>,
14848    pub expression: Box<Expression>,
14849}
14850
14851/// SHA2
14852#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14853#[cfg_attr(feature = "bindings", derive(TS))]
14854pub struct SHA2 {
14855    pub this: Box<Expression>,
14856    #[serde(default)]
14857    pub length: Option<i64>,
14858}
14859
14860/// SHA2Digest
14861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14862#[cfg_attr(feature = "bindings", derive(TS))]
14863pub struct SHA2Digest {
14864    pub this: Box<Expression>,
14865    #[serde(default)]
14866    pub length: Option<i64>,
14867}
14868
14869/// SortArray
14870#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14871#[cfg_attr(feature = "bindings", derive(TS))]
14872pub struct SortArray {
14873    pub this: Box<Expression>,
14874    #[serde(default)]
14875    pub asc: Option<Box<Expression>>,
14876    #[serde(default)]
14877    pub nulls_first: Option<Box<Expression>>,
14878}
14879
14880/// SplitPart
14881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14882#[cfg_attr(feature = "bindings", derive(TS))]
14883pub struct SplitPart {
14884    pub this: Box<Expression>,
14885    #[serde(default)]
14886    pub delimiter: Option<Box<Expression>>,
14887    #[serde(default)]
14888    pub part_index: Option<Box<Expression>>,
14889}
14890
14891/// SUBSTRING_INDEX(str, delim, count)
14892#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14893#[cfg_attr(feature = "bindings", derive(TS))]
14894pub struct SubstringIndex {
14895    pub this: Box<Expression>,
14896    #[serde(default)]
14897    pub delimiter: Option<Box<Expression>>,
14898    #[serde(default)]
14899    pub count: Option<Box<Expression>>,
14900}
14901
14902/// StandardHash
14903#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14904#[cfg_attr(feature = "bindings", derive(TS))]
14905pub struct StandardHash {
14906    pub this: Box<Expression>,
14907    #[serde(default)]
14908    pub expression: Option<Box<Expression>>,
14909}
14910
14911/// StrPosition
14912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14913#[cfg_attr(feature = "bindings", derive(TS))]
14914pub struct StrPosition {
14915    pub this: Box<Expression>,
14916    #[serde(default)]
14917    pub substr: Option<Box<Expression>>,
14918    #[serde(default)]
14919    pub position: Option<Box<Expression>>,
14920    #[serde(default)]
14921    pub occurrence: Option<Box<Expression>>,
14922}
14923
14924/// Search
14925#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14926#[cfg_attr(feature = "bindings", derive(TS))]
14927pub struct Search {
14928    pub this: Box<Expression>,
14929    pub expression: Box<Expression>,
14930    #[serde(default)]
14931    pub json_scope: Option<Box<Expression>>,
14932    #[serde(default)]
14933    pub analyzer: Option<Box<Expression>>,
14934    #[serde(default)]
14935    pub analyzer_options: Option<Box<Expression>>,
14936    #[serde(default)]
14937    pub search_mode: Option<Box<Expression>>,
14938}
14939
14940/// SearchIp
14941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14942#[cfg_attr(feature = "bindings", derive(TS))]
14943pub struct SearchIp {
14944    pub this: Box<Expression>,
14945    pub expression: Box<Expression>,
14946}
14947
14948/// StrToDate
14949#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14950#[cfg_attr(feature = "bindings", derive(TS))]
14951pub struct StrToDate {
14952    pub this: Box<Expression>,
14953    #[serde(default)]
14954    pub format: Option<String>,
14955    #[serde(default)]
14956    pub safe: Option<Box<Expression>>,
14957}
14958
14959/// StrToTime
14960#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14961#[cfg_attr(feature = "bindings", derive(TS))]
14962pub struct StrToTime {
14963    pub this: Box<Expression>,
14964    pub format: String,
14965    #[serde(default)]
14966    pub zone: Option<Box<Expression>>,
14967    #[serde(default)]
14968    pub safe: Option<Box<Expression>>,
14969    #[serde(default)]
14970    pub target_type: Option<Box<Expression>>,
14971}
14972
14973/// StrToUnix
14974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14975#[cfg_attr(feature = "bindings", derive(TS))]
14976pub struct StrToUnix {
14977    #[serde(default)]
14978    pub this: Option<Box<Expression>>,
14979    #[serde(default)]
14980    pub format: Option<String>,
14981}
14982
14983/// StrToMap
14984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14985#[cfg_attr(feature = "bindings", derive(TS))]
14986pub struct StrToMap {
14987    pub this: Box<Expression>,
14988    #[serde(default)]
14989    pub pair_delim: Option<Box<Expression>>,
14990    #[serde(default)]
14991    pub key_value_delim: Option<Box<Expression>>,
14992    #[serde(default)]
14993    pub duplicate_resolution_callback: Option<Box<Expression>>,
14994}
14995
14996/// NumberToStr
14997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14998#[cfg_attr(feature = "bindings", derive(TS))]
14999pub struct NumberToStr {
15000    pub this: Box<Expression>,
15001    pub format: String,
15002    #[serde(default)]
15003    pub culture: Option<Box<Expression>>,
15004}
15005
15006/// FromBase
15007#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15008#[cfg_attr(feature = "bindings", derive(TS))]
15009pub struct FromBase {
15010    pub this: Box<Expression>,
15011    pub expression: Box<Expression>,
15012}
15013
15014/// Stuff
15015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15016#[cfg_attr(feature = "bindings", derive(TS))]
15017pub struct Stuff {
15018    pub this: Box<Expression>,
15019    #[serde(default)]
15020    pub start: Option<Box<Expression>>,
15021    #[serde(default)]
15022    pub length: Option<i64>,
15023    pub expression: Box<Expression>,
15024}
15025
15026/// TimeToStr
15027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15028#[cfg_attr(feature = "bindings", derive(TS))]
15029pub struct TimeToStr {
15030    pub this: Box<Expression>,
15031    pub format: String,
15032    #[serde(default)]
15033    pub culture: Option<Box<Expression>>,
15034    #[serde(default)]
15035    pub zone: Option<Box<Expression>>,
15036}
15037
15038/// TimeStrToTime
15039#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15040#[cfg_attr(feature = "bindings", derive(TS))]
15041pub struct TimeStrToTime {
15042    pub this: Box<Expression>,
15043    #[serde(default)]
15044    pub zone: Option<Box<Expression>>,
15045}
15046
15047/// TsOrDsAdd
15048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15049#[cfg_attr(feature = "bindings", derive(TS))]
15050pub struct TsOrDsAdd {
15051    pub this: Box<Expression>,
15052    pub expression: Box<Expression>,
15053    #[serde(default)]
15054    pub unit: Option<String>,
15055    #[serde(default)]
15056    pub return_type: Option<Box<Expression>>,
15057}
15058
15059/// TsOrDsDiff
15060#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15061#[cfg_attr(feature = "bindings", derive(TS))]
15062pub struct TsOrDsDiff {
15063    pub this: Box<Expression>,
15064    pub expression: Box<Expression>,
15065    #[serde(default)]
15066    pub unit: Option<String>,
15067}
15068
15069/// TsOrDsToDate
15070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15071#[cfg_attr(feature = "bindings", derive(TS))]
15072pub struct TsOrDsToDate {
15073    pub this: Box<Expression>,
15074    #[serde(default)]
15075    pub format: Option<String>,
15076    #[serde(default)]
15077    pub safe: Option<Box<Expression>>,
15078}
15079
15080/// TsOrDsToTime
15081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15082#[cfg_attr(feature = "bindings", derive(TS))]
15083pub struct TsOrDsToTime {
15084    pub this: Box<Expression>,
15085    #[serde(default)]
15086    pub format: Option<String>,
15087    #[serde(default)]
15088    pub safe: Option<Box<Expression>>,
15089}
15090
15091/// Unhex
15092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15093#[cfg_attr(feature = "bindings", derive(TS))]
15094pub struct Unhex {
15095    pub this: Box<Expression>,
15096    #[serde(default)]
15097    pub expression: Option<Box<Expression>>,
15098}
15099
15100/// Uniform
15101#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15102#[cfg_attr(feature = "bindings", derive(TS))]
15103pub struct Uniform {
15104    pub this: Box<Expression>,
15105    pub expression: Box<Expression>,
15106    #[serde(default)]
15107    pub gen: Option<Box<Expression>>,
15108    #[serde(default)]
15109    pub seed: Option<Box<Expression>>,
15110}
15111
15112/// UnixToStr
15113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15114#[cfg_attr(feature = "bindings", derive(TS))]
15115pub struct UnixToStr {
15116    pub this: Box<Expression>,
15117    #[serde(default)]
15118    pub format: Option<String>,
15119}
15120
15121/// UnixToTime
15122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15123#[cfg_attr(feature = "bindings", derive(TS))]
15124pub struct UnixToTime {
15125    pub this: Box<Expression>,
15126    #[serde(default)]
15127    pub scale: Option<i64>,
15128    #[serde(default)]
15129    pub zone: Option<Box<Expression>>,
15130    #[serde(default)]
15131    pub hours: Option<Box<Expression>>,
15132    #[serde(default)]
15133    pub minutes: Option<Box<Expression>>,
15134    #[serde(default)]
15135    pub format: Option<String>,
15136    #[serde(default)]
15137    pub target_type: Option<Box<Expression>>,
15138}
15139
15140/// Uuid
15141#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15142#[cfg_attr(feature = "bindings", derive(TS))]
15143pub struct Uuid {
15144    #[serde(default)]
15145    pub this: Option<Box<Expression>>,
15146    #[serde(default)]
15147    pub name: Option<String>,
15148    #[serde(default)]
15149    pub is_string: Option<Box<Expression>>,
15150}
15151
15152/// TimestampFromParts
15153#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15154#[cfg_attr(feature = "bindings", derive(TS))]
15155pub struct TimestampFromParts {
15156    #[serde(default)]
15157    pub zone: Option<Box<Expression>>,
15158    #[serde(default)]
15159    pub milli: Option<Box<Expression>>,
15160    #[serde(default)]
15161    pub this: Option<Box<Expression>>,
15162    #[serde(default)]
15163    pub expression: Option<Box<Expression>>,
15164}
15165
15166/// TimestampTzFromParts
15167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15168#[cfg_attr(feature = "bindings", derive(TS))]
15169pub struct TimestampTzFromParts {
15170    #[serde(default)]
15171    pub zone: Option<Box<Expression>>,
15172}
15173
15174/// Corr
15175#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15176#[cfg_attr(feature = "bindings", derive(TS))]
15177pub struct Corr {
15178    pub this: Box<Expression>,
15179    pub expression: Box<Expression>,
15180    #[serde(default)]
15181    pub null_on_zero_variance: Option<Box<Expression>>,
15182}
15183
15184/// WidthBucket
15185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15186#[cfg_attr(feature = "bindings", derive(TS))]
15187pub struct WidthBucket {
15188    pub this: Box<Expression>,
15189    #[serde(default)]
15190    pub min_value: Option<Box<Expression>>,
15191    #[serde(default)]
15192    pub max_value: Option<Box<Expression>>,
15193    #[serde(default)]
15194    pub num_buckets: Option<Box<Expression>>,
15195    #[serde(default)]
15196    pub threshold: Option<Box<Expression>>,
15197}
15198
15199/// CovarSamp
15200#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15201#[cfg_attr(feature = "bindings", derive(TS))]
15202pub struct CovarSamp {
15203    pub this: Box<Expression>,
15204    pub expression: Box<Expression>,
15205}
15206
15207/// CovarPop
15208#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15209#[cfg_attr(feature = "bindings", derive(TS))]
15210pub struct CovarPop {
15211    pub this: Box<Expression>,
15212    pub expression: Box<Expression>,
15213}
15214
15215/// Week
15216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15217#[cfg_attr(feature = "bindings", derive(TS))]
15218pub struct Week {
15219    pub this: Box<Expression>,
15220    #[serde(default)]
15221    pub mode: Option<Box<Expression>>,
15222}
15223
15224/// XMLElement
15225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15226#[cfg_attr(feature = "bindings", derive(TS))]
15227pub struct XMLElement {
15228    pub this: Box<Expression>,
15229    #[serde(default)]
15230    pub expressions: Vec<Expression>,
15231    #[serde(default)]
15232    pub evalname: Option<Box<Expression>>,
15233}
15234
15235/// XMLGet
15236#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15237#[cfg_attr(feature = "bindings", derive(TS))]
15238pub struct XMLGet {
15239    pub this: Box<Expression>,
15240    pub expression: Box<Expression>,
15241    #[serde(default)]
15242    pub instance: Option<Box<Expression>>,
15243}
15244
15245/// XMLTable
15246#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15247#[cfg_attr(feature = "bindings", derive(TS))]
15248pub struct XMLTable {
15249    pub this: Box<Expression>,
15250    #[serde(default)]
15251    pub namespaces: Option<Box<Expression>>,
15252    #[serde(default)]
15253    pub passing: Option<Box<Expression>>,
15254    #[serde(default)]
15255    pub columns: Vec<Expression>,
15256    #[serde(default)]
15257    pub by_ref: Option<Box<Expression>>,
15258}
15259
15260/// XMLKeyValueOption
15261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15262#[cfg_attr(feature = "bindings", derive(TS))]
15263pub struct XMLKeyValueOption {
15264    pub this: Box<Expression>,
15265    #[serde(default)]
15266    pub expression: Option<Box<Expression>>,
15267}
15268
15269/// Zipf
15270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15271#[cfg_attr(feature = "bindings", derive(TS))]
15272pub struct Zipf {
15273    pub this: Box<Expression>,
15274    #[serde(default)]
15275    pub elementcount: Option<Box<Expression>>,
15276    #[serde(default)]
15277    pub gen: Option<Box<Expression>>,
15278}
15279
15280/// Merge
15281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15282#[cfg_attr(feature = "bindings", derive(TS))]
15283pub struct Merge {
15284    pub this: Box<Expression>,
15285    pub using: Box<Expression>,
15286    #[serde(default)]
15287    pub on: Option<Box<Expression>>,
15288    #[serde(default)]
15289    pub using_cond: Option<Box<Expression>>,
15290    #[serde(default)]
15291    pub whens: Option<Box<Expression>>,
15292    #[serde(default)]
15293    pub with_: Option<Box<Expression>>,
15294    #[serde(default)]
15295    pub returning: Option<Box<Expression>>,
15296}
15297
15298/// When
15299#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15300#[cfg_attr(feature = "bindings", derive(TS))]
15301pub struct When {
15302    #[serde(default)]
15303    pub matched: Option<Box<Expression>>,
15304    #[serde(default)]
15305    pub source: Option<Box<Expression>>,
15306    #[serde(default)]
15307    pub condition: Option<Box<Expression>>,
15308    pub then: Box<Expression>,
15309}
15310
15311/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15313#[cfg_attr(feature = "bindings", derive(TS))]
15314pub struct Whens {
15315    #[serde(default)]
15316    pub expressions: Vec<Expression>,
15317}
15318
15319/// NextValueFor
15320#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15321#[cfg_attr(feature = "bindings", derive(TS))]
15322pub struct NextValueFor {
15323    pub this: Box<Expression>,
15324    #[serde(default)]
15325    pub order: Option<Box<Expression>>,
15326}
15327
15328#[cfg(test)]
15329mod tests {
15330    use super::*;
15331
15332    #[test]
15333    #[cfg(feature = "bindings")]
15334    fn export_typescript_types() {
15335        // This test exports TypeScript types to the generated directory
15336        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
15337        Expression::export_all(&ts_rs::Config::default())
15338            .expect("Failed to export Expression types");
15339    }
15340
15341    #[test]
15342    fn test_simple_select_builder() {
15343        let select = Select::new()
15344            .column(Expression::star())
15345            .from(Expression::Table(Box::new(TableRef::new("users"))));
15346
15347        assert_eq!(select.expressions.len(), 1);
15348        assert!(select.from.is_some());
15349    }
15350
15351    #[test]
15352    fn test_expression_alias() {
15353        let expr = Expression::column("id").alias("user_id");
15354
15355        match expr {
15356            Expression::Alias(a) => {
15357                assert_eq!(a.alias.name, "user_id");
15358            }
15359            _ => panic!("Expected Alias"),
15360        }
15361    }
15362
15363    #[test]
15364    fn test_literal_creation() {
15365        let num = Expression::number(42);
15366        let str = Expression::string("hello");
15367
15368        match num {
15369            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
15370                let Literal::Number(n) = lit.as_ref() else {
15371                    unreachable!()
15372                };
15373                assert_eq!(n, "42")
15374            }
15375            _ => panic!("Expected Number"),
15376        }
15377
15378        match str {
15379            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
15380                let Literal::String(s) = lit.as_ref() else {
15381                    unreachable!()
15382                };
15383                assert_eq!(s, "hello")
15384            }
15385            _ => panic!("Expected String"),
15386        }
15387    }
15388
15389    #[test]
15390    fn test_expression_sql() {
15391        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
15392        assert_eq!(expr.sql(), "SELECT 1 + 2");
15393    }
15394
15395    #[test]
15396    fn test_expression_sql_for() {
15397        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
15398        let sql = expr.sql_for(crate::DialectType::Generic);
15399        // Generic mode normalizes IF() to CASE WHEN
15400        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
15401    }
15402}