Skip to main content

polyglot_sql/
expressions.rs

1//! SQL Expression AST (Abstract Syntax Tree).
2//!
3//! This module defines all the AST node types used to represent parsed SQL
4//! statements and expressions. The design follows Python sqlglot's expression
5//! hierarchy, ported to a Rust enum-based AST.
6//!
7//! # Architecture
8//!
9//! The central type is [`Expression`], a large tagged enum with one variant per
10//! SQL construct. Inner structs carry the fields for each variant. Most
11//! heap-allocated variants are wrapped in `Box` to keep the enum size small.
12//!
13//! # Variant Groups
14//!
15//! | Group | Examples | Purpose |
16//! |---|---|---|
17//! | **Queries** | `Select`, `Union`, `Intersect`, `Except`, `Subquery` | Top-level query structures |
18//! | **DML** | `Insert`, `Update`, `Delete`, `Merge`, `Copy` | Data manipulation |
19//! | **DDL** | `CreateTable`, `AlterTable`, `DropView`, `CreateIndex` | Schema definition |
20//! | **Clauses** | `From`, `Join`, `Where`, `GroupBy`, `OrderBy`, `With` | Query clauses |
21//! | **Operators** | `And`, `Or`, `Add`, `Eq`, `Like`, `Not` | Binary and unary operations |
22//! | **Functions** | `Function`, `AggregateFunction`, `WindowFunction`, `Count`, `Sum` | Scalar, aggregate, and window functions |
23//! | **Literals** | `Literal`, `Boolean`, `Null`, `Interval` | Constant values |
24//! | **Types** | `DataType`, `Cast`, `TryCast`, `SafeCast` | Data types and casts |
25//! | **Identifiers** | `Identifier`, `Column`, `Table`, `Star` | Name references |
26//!
27//! # SQL Generation
28//!
29//! Every `Expression` can be rendered back to SQL via [`Expression::sql()`]
30//! (generic dialect) or [`Expression::sql_for()`] (specific dialect). The
31//! actual generation logic lives in the `generator` module.
32
33use crate::tokens::Span;
34use serde::{Deserialize, Serialize};
35use std::fmt;
36#[cfg(feature = "bindings")]
37use ts_rs::TS;
38
39/// Helper function for serde default value
40fn default_true() -> bool {
41    true
42}
43
44fn is_true(v: &bool) -> bool {
45    *v
46}
47
48/// Represent any SQL expression or statement as a single, recursive AST node.
49///
50/// `Expression` is the root type of the polyglot AST. Every parsed SQL
51/// construct -- from a simple integer literal to a multi-CTE query with
52/// window functions -- is represented as a variant of this enum.
53///
54/// Variants are organized into logical groups (see the module-level docs).
55/// Most non-trivial variants box their payload so that `size_of::<Expression>()`
56/// stays small (currently two words: tag + pointer).
57///
58/// # Constructing Expressions
59///
60/// Use the convenience constructors on `impl Expression` for common cases:
61///
62/// ```rust,ignore
63/// use polyglot_sql::expressions::Expression;
64///
65/// let col  = Expression::column("id");
66/// let lit  = Expression::number(42);
67/// let star = Expression::star();
68/// ```
69///
70/// # Generating SQL
71///
72/// ```rust,ignore
73/// let expr = Expression::column("name");
74/// assert_eq!(expr.sql(), "name");
75/// ```
76#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
77#[cfg_attr(feature = "bindings", derive(TS))]
78#[serde(rename_all = "snake_case")]
79#[cfg_attr(feature = "bindings", ts(export))]
80pub enum Expression {
81    // Literals
82    Literal(Box<Literal>),
83    Boolean(BooleanLiteral),
84    Null(Null),
85
86    // Identifiers
87    Identifier(Identifier),
88    Column(Box<Column>),
89    Table(Box<TableRef>),
90    Star(Star),
91    /// Snowflake braced wildcard syntax: {*}, {tbl.*}, {* EXCLUDE (...)}, {* ILIKE '...'}
92    BracedWildcard(Box<Expression>),
93
94    // Queries
95    Select(Box<Select>),
96    Union(Box<Union>),
97    Intersect(Box<Intersect>),
98    Except(Box<Except>),
99    Subquery(Box<Subquery>),
100    PipeOperator(Box<PipeOperator>),
101    Pivot(Box<Pivot>),
102    PivotAlias(Box<PivotAlias>),
103    Unpivot(Box<Unpivot>),
104    Values(Box<Values>),
105    PreWhere(Box<PreWhere>),
106    Stream(Box<Stream>),
107    UsingData(Box<UsingData>),
108    XmlNamespace(Box<XmlNamespace>),
109
110    // DML
111    Insert(Box<Insert>),
112    Update(Box<Update>),
113    Delete(Box<Delete>),
114    Copy(Box<CopyStmt>),
115    Put(Box<PutStmt>),
116    StageReference(Box<StageReference>),
117    TryCatch(Box<TryCatch>),
118
119    // Expressions
120    Alias(Box<Alias>),
121    Cast(Box<Cast>),
122    Collation(Box<CollationExpr>),
123    Case(Box<Case>),
124
125    // Binary operations
126    And(Box<BinaryOp>),
127    Or(Box<BinaryOp>),
128    Add(Box<BinaryOp>),
129    Sub(Box<BinaryOp>),
130    Mul(Box<BinaryOp>),
131    Div(Box<BinaryOp>),
132    Mod(Box<BinaryOp>),
133    Eq(Box<BinaryOp>),
134    Neq(Box<BinaryOp>),
135    Lt(Box<BinaryOp>),
136    Lte(Box<BinaryOp>),
137    Gt(Box<BinaryOp>),
138    Gte(Box<BinaryOp>),
139    Like(Box<LikeOp>),
140    ILike(Box<LikeOp>),
141    /// SQLite MATCH operator (FTS)
142    Match(Box<BinaryOp>),
143    BitwiseAnd(Box<BinaryOp>),
144    BitwiseOr(Box<BinaryOp>),
145    BitwiseXor(Box<BinaryOp>),
146    Concat(Box<BinaryOp>),
147    Adjacent(Box<BinaryOp>),   // PostgreSQL range adjacency operator (-|-)
148    TsMatch(Box<BinaryOp>),    // PostgreSQL text search match operator (@@)
149    PropertyEQ(Box<BinaryOp>), // := assignment operator (MySQL @var := val, DuckDB named args)
150
151    // PostgreSQL array/JSONB operators
152    ArrayContainsAll(Box<BinaryOp>), // @> operator (array contains all)
153    ArrayContainedBy(Box<BinaryOp>), // <@ operator (array contained by)
154    ArrayOverlaps(Box<BinaryOp>),    // && operator (array overlaps)
155    JSONBContainsAllTopKeys(Box<BinaryOp>), // ?& operator (JSONB contains all keys)
156    JSONBContainsAnyTopKeys(Box<BinaryOp>), // ?| operator (JSONB contains any key)
157    JSONBDeleteAtPath(Box<BinaryOp>), // #- operator (JSONB delete at path)
158    ExtendsLeft(Box<BinaryOp>),      // &< operator (PostgreSQL range extends left)
159    ExtendsRight(Box<BinaryOp>),     // &> operator (PostgreSQL range extends right)
160
161    // Unary operations
162    Not(Box<UnaryOp>),
163    Neg(Box<UnaryOp>),
164    BitwiseNot(Box<UnaryOp>),
165
166    // Predicates
167    In(Box<In>),
168    Between(Box<Between>),
169    IsNull(Box<IsNull>),
170    IsTrue(Box<IsTrueFalse>),
171    IsFalse(Box<IsTrueFalse>),
172    IsJson(Box<IsJson>),
173    Is(Box<BinaryOp>), // General IS expression (e.g., a IS ?)
174    Exists(Box<Exists>),
175    /// MySQL MEMBER OF operator: expr MEMBER OF(json_array)
176    MemberOf(Box<BinaryOp>),
177
178    // Functions
179    Function(Box<Function>),
180    AggregateFunction(Box<AggregateFunction>),
181    WindowFunction(Box<WindowFunction>),
182
183    // Clauses
184    From(Box<From>),
185    Join(Box<Join>),
186    JoinedTable(Box<JoinedTable>),
187    Where(Box<Where>),
188    GroupBy(Box<GroupBy>),
189    Having(Box<Having>),
190    OrderBy(Box<OrderBy>),
191    Limit(Box<Limit>),
192    Offset(Box<Offset>),
193    Qualify(Box<Qualify>),
194    With(Box<With>),
195    Cte(Box<Cte>),
196    DistributeBy(Box<DistributeBy>),
197    ClusterBy(Box<ClusterBy>),
198    SortBy(Box<SortBy>),
199    LateralView(Box<LateralView>),
200    Hint(Box<Hint>),
201    Pseudocolumn(Pseudocolumn),
202
203    // Oracle hierarchical queries (CONNECT BY)
204    Connect(Box<Connect>),
205    Prior(Box<Prior>),
206    ConnectByRoot(Box<ConnectByRoot>),
207
208    // Pattern matching (MATCH_RECOGNIZE)
209    MatchRecognize(Box<MatchRecognize>),
210
211    // Order expressions
212    Ordered(Box<Ordered>),
213
214    // Window specifications
215    Window(Box<WindowSpec>),
216    Over(Box<Over>),
217    WithinGroup(Box<WithinGroup>),
218
219    // Data types
220    DataType(DataType),
221
222    // Arrays and structs
223    Array(Box<Array>),
224    Struct(Box<Struct>),
225    Tuple(Box<Tuple>),
226
227    // Interval
228    Interval(Box<Interval>),
229
230    // String functions
231    ConcatWs(Box<ConcatWs>),
232    Substring(Box<SubstringFunc>),
233    Upper(Box<UnaryFunc>),
234    Lower(Box<UnaryFunc>),
235    Length(Box<UnaryFunc>),
236    Trim(Box<TrimFunc>),
237    LTrim(Box<UnaryFunc>),
238    RTrim(Box<UnaryFunc>),
239    Replace(Box<ReplaceFunc>),
240    Reverse(Box<UnaryFunc>),
241    Left(Box<LeftRightFunc>),
242    Right(Box<LeftRightFunc>),
243    Repeat(Box<RepeatFunc>),
244    Lpad(Box<PadFunc>),
245    Rpad(Box<PadFunc>),
246    Split(Box<SplitFunc>),
247    RegexpLike(Box<RegexpFunc>),
248    RegexpReplace(Box<RegexpReplaceFunc>),
249    RegexpExtract(Box<RegexpExtractFunc>),
250    Overlay(Box<OverlayFunc>),
251
252    // Math functions
253    Abs(Box<UnaryFunc>),
254    Round(Box<RoundFunc>),
255    Floor(Box<FloorFunc>),
256    Ceil(Box<CeilFunc>),
257    Power(Box<BinaryFunc>),
258    Sqrt(Box<UnaryFunc>),
259    Cbrt(Box<UnaryFunc>),
260    Ln(Box<UnaryFunc>),
261    Log(Box<LogFunc>),
262    Exp(Box<UnaryFunc>),
263    Sign(Box<UnaryFunc>),
264    Greatest(Box<VarArgFunc>),
265    Least(Box<VarArgFunc>),
266
267    // Date/time functions
268    CurrentDate(CurrentDate),
269    CurrentTime(CurrentTime),
270    CurrentTimestamp(CurrentTimestamp),
271    CurrentTimestampLTZ(CurrentTimestampLTZ),
272    AtTimeZone(Box<AtTimeZone>),
273    DateAdd(Box<DateAddFunc>),
274    DateSub(Box<DateAddFunc>),
275    DateDiff(Box<DateDiffFunc>),
276    DateTrunc(Box<DateTruncFunc>),
277    Extract(Box<ExtractFunc>),
278    ToDate(Box<ToDateFunc>),
279    ToTimestamp(Box<ToTimestampFunc>),
280    Date(Box<UnaryFunc>),
281    Time(Box<UnaryFunc>),
282    DateFromUnixDate(Box<UnaryFunc>),
283    UnixDate(Box<UnaryFunc>),
284    UnixSeconds(Box<UnaryFunc>),
285    UnixMillis(Box<UnaryFunc>),
286    UnixMicros(Box<UnaryFunc>),
287    UnixToTimeStr(Box<BinaryFunc>),
288    TimeStrToDate(Box<UnaryFunc>),
289    DateToDi(Box<UnaryFunc>),
290    DiToDate(Box<UnaryFunc>),
291    TsOrDiToDi(Box<UnaryFunc>),
292    TsOrDsToDatetime(Box<UnaryFunc>),
293    TsOrDsToTimestamp(Box<UnaryFunc>),
294    YearOfWeek(Box<UnaryFunc>),
295    YearOfWeekIso(Box<UnaryFunc>),
296
297    // Control flow functions
298    Coalesce(Box<VarArgFunc>),
299    NullIf(Box<BinaryFunc>),
300    IfFunc(Box<IfFunc>),
301    IfNull(Box<BinaryFunc>),
302    Nvl(Box<BinaryFunc>),
303    Nvl2(Box<Nvl2Func>),
304
305    // Type conversion
306    TryCast(Box<Cast>),
307    SafeCast(Box<Cast>),
308
309    // Typed aggregate functions
310    Count(Box<CountFunc>),
311    Sum(Box<AggFunc>),
312    Avg(Box<AggFunc>),
313    Min(Box<AggFunc>),
314    Max(Box<AggFunc>),
315    GroupConcat(Box<GroupConcatFunc>),
316    StringAgg(Box<StringAggFunc>),
317    ListAgg(Box<ListAggFunc>),
318    ArrayAgg(Box<AggFunc>),
319    CountIf(Box<AggFunc>),
320    SumIf(Box<SumIfFunc>),
321    Stddev(Box<AggFunc>),
322    StddevPop(Box<AggFunc>),
323    StddevSamp(Box<AggFunc>),
324    Variance(Box<AggFunc>),
325    VarPop(Box<AggFunc>),
326    VarSamp(Box<AggFunc>),
327    Median(Box<AggFunc>),
328    Mode(Box<AggFunc>),
329    First(Box<AggFunc>),
330    Last(Box<AggFunc>),
331    AnyValue(Box<AggFunc>),
332    ApproxDistinct(Box<AggFunc>),
333    ApproxCountDistinct(Box<AggFunc>),
334    ApproxPercentile(Box<ApproxPercentileFunc>),
335    Percentile(Box<PercentileFunc>),
336    LogicalAnd(Box<AggFunc>),
337    LogicalOr(Box<AggFunc>),
338    Skewness(Box<AggFunc>),
339    BitwiseCount(Box<UnaryFunc>),
340    ArrayConcatAgg(Box<AggFunc>),
341    ArrayUniqueAgg(Box<AggFunc>),
342    BoolXorAgg(Box<AggFunc>),
343
344    // Typed window functions
345    RowNumber(RowNumber),
346    Rank(Rank),
347    DenseRank(DenseRank),
348    NTile(Box<NTileFunc>),
349    Lead(Box<LeadLagFunc>),
350    Lag(Box<LeadLagFunc>),
351    FirstValue(Box<ValueFunc>),
352    LastValue(Box<ValueFunc>),
353    NthValue(Box<NthValueFunc>),
354    PercentRank(PercentRank),
355    CumeDist(CumeDist),
356    PercentileCont(Box<PercentileFunc>),
357    PercentileDisc(Box<PercentileFunc>),
358
359    // Additional string functions
360    Contains(Box<BinaryFunc>),
361    StartsWith(Box<BinaryFunc>),
362    EndsWith(Box<BinaryFunc>),
363    Position(Box<PositionFunc>),
364    Initcap(Box<UnaryFunc>),
365    Ascii(Box<UnaryFunc>),
366    Chr(Box<UnaryFunc>),
367    /// MySQL CHAR function with multiple args and optional USING charset
368    CharFunc(Box<CharFunc>),
369    Soundex(Box<UnaryFunc>),
370    Levenshtein(Box<BinaryFunc>),
371    ByteLength(Box<UnaryFunc>),
372    Hex(Box<UnaryFunc>),
373    LowerHex(Box<UnaryFunc>),
374    Unicode(Box<UnaryFunc>),
375
376    // Additional math functions
377    ModFunc(Box<BinaryFunc>),
378    Random(Random),
379    Rand(Box<Rand>),
380    TruncFunc(Box<TruncateFunc>),
381    Pi(Pi),
382    Radians(Box<UnaryFunc>),
383    Degrees(Box<UnaryFunc>),
384    Sin(Box<UnaryFunc>),
385    Cos(Box<UnaryFunc>),
386    Tan(Box<UnaryFunc>),
387    Asin(Box<UnaryFunc>),
388    Acos(Box<UnaryFunc>),
389    Atan(Box<UnaryFunc>),
390    Atan2(Box<BinaryFunc>),
391    IsNan(Box<UnaryFunc>),
392    IsInf(Box<UnaryFunc>),
393    IntDiv(Box<BinaryFunc>),
394
395    // Control flow
396    Decode(Box<DecodeFunc>),
397
398    // Additional date/time functions
399    DateFormat(Box<DateFormatFunc>),
400    FormatDate(Box<DateFormatFunc>),
401    Year(Box<UnaryFunc>),
402    Month(Box<UnaryFunc>),
403    Day(Box<UnaryFunc>),
404    Hour(Box<UnaryFunc>),
405    Minute(Box<UnaryFunc>),
406    Second(Box<UnaryFunc>),
407    DayOfWeek(Box<UnaryFunc>),
408    DayOfWeekIso(Box<UnaryFunc>),
409    DayOfMonth(Box<UnaryFunc>),
410    DayOfYear(Box<UnaryFunc>),
411    WeekOfYear(Box<UnaryFunc>),
412    Quarter(Box<UnaryFunc>),
413    AddMonths(Box<BinaryFunc>),
414    MonthsBetween(Box<BinaryFunc>),
415    LastDay(Box<LastDayFunc>),
416    NextDay(Box<BinaryFunc>),
417    Epoch(Box<UnaryFunc>),
418    EpochMs(Box<UnaryFunc>),
419    FromUnixtime(Box<FromUnixtimeFunc>),
420    UnixTimestamp(Box<UnixTimestampFunc>),
421    MakeDate(Box<MakeDateFunc>),
422    MakeTimestamp(Box<MakeTimestampFunc>),
423    TimestampTrunc(Box<DateTruncFunc>),
424    TimeStrToUnix(Box<UnaryFunc>),
425
426    // Session/User functions
427    SessionUser(SessionUser),
428
429    // Hash/Crypto functions
430    SHA(Box<UnaryFunc>),
431    SHA1Digest(Box<UnaryFunc>),
432
433    // Time conversion functions
434    TimeToUnix(Box<UnaryFunc>),
435
436    // Array functions
437    ArrayFunc(Box<ArrayConstructor>),
438    ArrayLength(Box<UnaryFunc>),
439    ArraySize(Box<UnaryFunc>),
440    Cardinality(Box<UnaryFunc>),
441    ArrayContains(Box<BinaryFunc>),
442    ArrayPosition(Box<BinaryFunc>),
443    ArrayAppend(Box<BinaryFunc>),
444    ArrayPrepend(Box<BinaryFunc>),
445    ArrayConcat(Box<VarArgFunc>),
446    ArraySort(Box<ArraySortFunc>),
447    ArrayReverse(Box<UnaryFunc>),
448    ArrayDistinct(Box<UnaryFunc>),
449    ArrayJoin(Box<ArrayJoinFunc>),
450    ArrayToString(Box<ArrayJoinFunc>),
451    Unnest(Box<UnnestFunc>),
452    Explode(Box<UnaryFunc>),
453    ExplodeOuter(Box<UnaryFunc>),
454    ArrayFilter(Box<ArrayFilterFunc>),
455    ArrayTransform(Box<ArrayTransformFunc>),
456    ArrayFlatten(Box<UnaryFunc>),
457    ArrayCompact(Box<UnaryFunc>),
458    ArrayIntersect(Box<VarArgFunc>),
459    ArrayUnion(Box<BinaryFunc>),
460    ArrayExcept(Box<BinaryFunc>),
461    ArrayRemove(Box<BinaryFunc>),
462    ArrayZip(Box<VarArgFunc>),
463    Sequence(Box<SequenceFunc>),
464    Generate(Box<SequenceFunc>),
465    ExplodingGenerateSeries(Box<SequenceFunc>),
466    ToArray(Box<UnaryFunc>),
467    StarMap(Box<BinaryFunc>),
468
469    // Struct functions
470    StructFunc(Box<StructConstructor>),
471    StructExtract(Box<StructExtractFunc>),
472    NamedStruct(Box<NamedStructFunc>),
473
474    // Map functions
475    MapFunc(Box<MapConstructor>),
476    MapFromEntries(Box<UnaryFunc>),
477    MapFromArrays(Box<BinaryFunc>),
478    MapKeys(Box<UnaryFunc>),
479    MapValues(Box<UnaryFunc>),
480    MapContainsKey(Box<BinaryFunc>),
481    MapConcat(Box<VarArgFunc>),
482    ElementAt(Box<BinaryFunc>),
483    TransformKeys(Box<TransformFunc>),
484    TransformValues(Box<TransformFunc>),
485
486    // Exasol: function call with EMITS clause
487    FunctionEmits(Box<FunctionEmits>),
488
489    // JSON functions
490    JsonExtract(Box<JsonExtractFunc>),
491    JsonExtractScalar(Box<JsonExtractFunc>),
492    JsonExtractPath(Box<JsonPathFunc>),
493    JsonArray(Box<VarArgFunc>),
494    JsonObject(Box<JsonObjectFunc>),
495    JsonQuery(Box<JsonExtractFunc>),
496    JsonValue(Box<JsonExtractFunc>),
497    JsonArrayLength(Box<UnaryFunc>),
498    JsonKeys(Box<UnaryFunc>),
499    JsonType(Box<UnaryFunc>),
500    ParseJson(Box<UnaryFunc>),
501    ToJson(Box<UnaryFunc>),
502    JsonSet(Box<JsonModifyFunc>),
503    JsonInsert(Box<JsonModifyFunc>),
504    JsonRemove(Box<JsonPathFunc>),
505    JsonMergePatch(Box<BinaryFunc>),
506    JsonArrayAgg(Box<JsonArrayAggFunc>),
507    JsonObjectAgg(Box<JsonObjectAggFunc>),
508
509    // Type casting/conversion
510    Convert(Box<ConvertFunc>),
511    Typeof(Box<UnaryFunc>),
512
513    // Additional expressions
514    Lambda(Box<LambdaExpr>),
515    Parameter(Box<Parameter>),
516    Placeholder(Placeholder),
517    NamedArgument(Box<NamedArgument>),
518    /// TABLE ref or MODEL ref used as a function argument (BigQuery)
519    /// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
520    TableArgument(Box<TableArgument>),
521    SqlComment(Box<SqlComment>),
522
523    // Additional predicates
524    NullSafeEq(Box<BinaryOp>),
525    NullSafeNeq(Box<BinaryOp>),
526    Glob(Box<BinaryOp>),
527    SimilarTo(Box<SimilarToExpr>),
528    Any(Box<QuantifiedExpr>),
529    All(Box<QuantifiedExpr>),
530    Overlaps(Box<OverlapsExpr>),
531
532    // Bitwise operations
533    BitwiseLeftShift(Box<BinaryOp>),
534    BitwiseRightShift(Box<BinaryOp>),
535    BitwiseAndAgg(Box<AggFunc>),
536    BitwiseOrAgg(Box<AggFunc>),
537    BitwiseXorAgg(Box<AggFunc>),
538
539    // Array/struct/map access
540    Subscript(Box<Subscript>),
541    Dot(Box<DotAccess>),
542    MethodCall(Box<MethodCall>),
543    ArraySlice(Box<ArraySlice>),
544
545    // DDL statements
546    CreateTable(Box<CreateTable>),
547    DropTable(Box<DropTable>),
548    Undrop(Box<Undrop>),
549    AlterTable(Box<AlterTable>),
550    SplitTable(Box<SplitTable>),
551    FlashbackTable(Box<FlashbackTable>),
552    CreateIndex(Box<CreateIndex>),
553    DropIndex(Box<DropIndex>),
554    CreateView(Box<CreateView>),
555    DropView(Box<DropView>),
556    AlterView(Box<AlterView>),
557    AlterIndex(Box<AlterIndex>),
558    Truncate(Box<Truncate>),
559    Use(Box<Use>),
560    Cache(Box<Cache>),
561    Uncache(Box<Uncache>),
562    LoadData(Box<LoadData>),
563    Pragma(Box<Pragma>),
564    Grant(Box<Grant>),
565    Revoke(Box<Revoke>),
566    Comment(Box<Comment>),
567    SetStatement(Box<SetStatement>),
568    // Phase 4: Additional DDL statements
569    CreateSchema(Box<CreateSchema>),
570    DropSchema(Box<DropSchema>),
571    DropNamespace(Box<DropNamespace>),
572    CreateDatabase(Box<CreateDatabase>),
573    DropDatabase(Box<DropDatabase>),
574    CreateFunction(Box<CreateFunction>),
575    DropFunction(Box<DropFunction>),
576    CreateProcedure(Box<CreateProcedure>),
577    DropProcedure(Box<DropProcedure>),
578    CreateSequence(Box<CreateSequence>),
579    CreateSynonym(Box<CreateSynonym>),
580    DropSequence(Box<DropSequence>),
581    AlterSequence(Box<AlterSequence>),
582    CreateTrigger(Box<CreateTrigger>),
583    DropTrigger(Box<DropTrigger>),
584    CreateType(Box<CreateType>),
585    DropType(Box<DropType>),
586    Describe(Box<Describe>),
587    Show(Box<Show>),
588
589    // Transaction and other commands
590    Command(Box<Command>),
591    Kill(Box<Kill>),
592    /// PREPARE statement (PostgreSQL/generic prepared statement definition)
593    Prepare(Box<PrepareStatement>),
594    /// EXEC/EXECUTE statement (TSQL stored procedure call)
595    Execute(Box<ExecuteStatement>),
596
597    /// Snowflake CREATE TASK statement
598    CreateTask(Box<CreateTask>),
599
600    // Placeholder for unparsed/raw SQL
601    Raw(Raw),
602
603    // Paren for grouping
604    Paren(Box<Paren>),
605
606    // Expression with trailing comments (for round-trip preservation)
607    Annotated(Box<Annotated>),
608
609    // === BATCH GENERATED EXPRESSION TYPES ===
610    // Generated from Python sqlglot expressions.py
611    Refresh(Box<Refresh>),
612    LockingStatement(Box<LockingStatement>),
613    SequenceProperties(Box<SequenceProperties>),
614    TruncateTable(Box<TruncateTable>),
615    Clone(Box<Clone>),
616    Attach(Box<Attach>),
617    Detach(Box<Detach>),
618    Install(Box<Install>),
619    Summarize(Box<Summarize>),
620    Declare(Box<Declare>),
621    DeclareItem(Box<DeclareItem>),
622    Set(Box<Set>),
623    Heredoc(Box<Heredoc>),
624    SetItem(Box<SetItem>),
625    QueryBand(Box<QueryBand>),
626    UserDefinedFunction(Box<UserDefinedFunction>),
627    RecursiveWithSearch(Box<RecursiveWithSearch>),
628    ProjectionDef(Box<ProjectionDef>),
629    TableAlias(Box<TableAlias>),
630    ByteString(Box<ByteString>),
631    HexStringExpr(Box<HexStringExpr>),
632    UnicodeString(Box<UnicodeString>),
633    ColumnPosition(Box<ColumnPosition>),
634    ColumnDef(Box<ColumnDef>),
635    AlterColumn(Box<AlterColumn>),
636    AlterSortKey(Box<AlterSortKey>),
637    AlterSet(Box<AlterSet>),
638    RenameColumn(Box<RenameColumn>),
639    Comprehension(Box<Comprehension>),
640    MergeTreeTTLAction(Box<MergeTreeTTLAction>),
641    MergeTreeTTL(Box<MergeTreeTTL>),
642    IndexConstraintOption(Box<IndexConstraintOption>),
643    ColumnConstraint(Box<ColumnConstraint>),
644    PeriodForSystemTimeConstraint(Box<PeriodForSystemTimeConstraint>),
645    CaseSpecificColumnConstraint(Box<CaseSpecificColumnConstraint>),
646    CharacterSetColumnConstraint(Box<CharacterSetColumnConstraint>),
647    CheckColumnConstraint(Box<CheckColumnConstraint>),
648    AssumeColumnConstraint(Box<AssumeColumnConstraint>),
649    CompressColumnConstraint(Box<CompressColumnConstraint>),
650    DateFormatColumnConstraint(Box<DateFormatColumnConstraint>),
651    EphemeralColumnConstraint(Box<EphemeralColumnConstraint>),
652    WithOperator(Box<WithOperator>),
653    GeneratedAsIdentityColumnConstraint(Box<GeneratedAsIdentityColumnConstraint>),
654    AutoIncrementColumnConstraint(AutoIncrementColumnConstraint),
655    CommentColumnConstraint(CommentColumnConstraint),
656    GeneratedAsRowColumnConstraint(Box<GeneratedAsRowColumnConstraint>),
657    IndexColumnConstraint(Box<IndexColumnConstraint>),
658    MaskingPolicyColumnConstraint(Box<MaskingPolicyColumnConstraint>),
659    NotNullColumnConstraint(Box<NotNullColumnConstraint>),
660    PrimaryKeyColumnConstraint(Box<PrimaryKeyColumnConstraint>),
661    UniqueColumnConstraint(Box<UniqueColumnConstraint>),
662    WatermarkColumnConstraint(Box<WatermarkColumnConstraint>),
663    ComputedColumnConstraint(Box<ComputedColumnConstraint>),
664    InOutColumnConstraint(Box<InOutColumnConstraint>),
665    DefaultColumnConstraint(Box<DefaultColumnConstraint>),
666    PathColumnConstraint(Box<PathColumnConstraint>),
667    Constraint(Box<Constraint>),
668    Export(Box<Export>),
669    Filter(Box<Filter>),
670    Changes(Box<Changes>),
671    CopyParameter(Box<CopyParameter>),
672    Credentials(Box<Credentials>),
673    Directory(Box<Directory>),
674    ForeignKey(Box<ForeignKey>),
675    ColumnPrefix(Box<ColumnPrefix>),
676    PrimaryKey(Box<PrimaryKey>),
677    IntoClause(Box<IntoClause>),
678    JoinHint(Box<JoinHint>),
679    Opclass(Box<Opclass>),
680    Index(Box<Index>),
681    IndexParameters(Box<IndexParameters>),
682    ConditionalInsert(Box<ConditionalInsert>),
683    MultitableInserts(Box<MultitableInserts>),
684    OnConflict(Box<OnConflict>),
685    OnCondition(Box<OnCondition>),
686    Returning(Box<Returning>),
687    Introducer(Box<Introducer>),
688    PartitionRange(Box<PartitionRange>),
689    Fetch(Box<Fetch>),
690    Group(Box<Group>),
691    Cube(Box<Cube>),
692    Rollup(Box<Rollup>),
693    GroupingSets(Box<GroupingSets>),
694    LimitOptions(Box<LimitOptions>),
695    Lateral(Box<Lateral>),
696    TableFromRows(Box<TableFromRows>),
697    RowsFrom(Box<RowsFrom>),
698    MatchRecognizeMeasure(Box<MatchRecognizeMeasure>),
699    WithFill(Box<WithFill>),
700    Property(Box<Property>),
701    GrantPrivilege(Box<GrantPrivilege>),
702    GrantPrincipal(Box<GrantPrincipal>),
703    AllowedValuesProperty(Box<AllowedValuesProperty>),
704    AlgorithmProperty(Box<AlgorithmProperty>),
705    AutoIncrementProperty(Box<AutoIncrementProperty>),
706    AutoRefreshProperty(Box<AutoRefreshProperty>),
707    BackupProperty(Box<BackupProperty>),
708    BuildProperty(Box<BuildProperty>),
709    BlockCompressionProperty(Box<BlockCompressionProperty>),
710    CharacterSetProperty(Box<CharacterSetProperty>),
711    ChecksumProperty(Box<ChecksumProperty>),
712    CollateProperty(Box<CollateProperty>),
713    DataBlocksizeProperty(Box<DataBlocksizeProperty>),
714    DataDeletionProperty(Box<DataDeletionProperty>),
715    DefinerProperty(Box<DefinerProperty>),
716    DistKeyProperty(Box<DistKeyProperty>),
717    DistributedByProperty(Box<DistributedByProperty>),
718    DistStyleProperty(Box<DistStyleProperty>),
719    DuplicateKeyProperty(Box<DuplicateKeyProperty>),
720    EngineProperty(Box<EngineProperty>),
721    ToTableProperty(Box<ToTableProperty>),
722    ExecuteAsProperty(Box<ExecuteAsProperty>),
723    ExternalProperty(Box<ExternalProperty>),
724    FallbackProperty(Box<FallbackProperty>),
725    FileFormatProperty(Box<FileFormatProperty>),
726    CredentialsProperty(Box<CredentialsProperty>),
727    FreespaceProperty(Box<FreespaceProperty>),
728    InheritsProperty(Box<InheritsProperty>),
729    InputModelProperty(Box<InputModelProperty>),
730    OutputModelProperty(Box<OutputModelProperty>),
731    IsolatedLoadingProperty(Box<IsolatedLoadingProperty>),
732    JournalProperty(Box<JournalProperty>),
733    LanguageProperty(Box<LanguageProperty>),
734    EnviromentProperty(Box<EnviromentProperty>),
735    ClusteredByProperty(Box<ClusteredByProperty>),
736    DictProperty(Box<DictProperty>),
737    DictRange(Box<DictRange>),
738    OnCluster(Box<OnCluster>),
739    LikeProperty(Box<LikeProperty>),
740    LocationProperty(Box<LocationProperty>),
741    LockProperty(Box<LockProperty>),
742    LockingProperty(Box<LockingProperty>),
743    LogProperty(Box<LogProperty>),
744    MaterializedProperty(Box<MaterializedProperty>),
745    MergeBlockRatioProperty(Box<MergeBlockRatioProperty>),
746    OnProperty(Box<OnProperty>),
747    OnCommitProperty(Box<OnCommitProperty>),
748    PartitionedByProperty(Box<PartitionedByProperty>),
749    PartitionByProperty(Box<PartitionByProperty>),
750    PartitionedByBucket(Box<PartitionedByBucket>),
751    ClusterByColumnsProperty(Box<ClusterByColumnsProperty>),
752    PartitionByTruncate(Box<PartitionByTruncate>),
753    PartitionByRangeProperty(Box<PartitionByRangeProperty>),
754    PartitionByRangePropertyDynamic(Box<PartitionByRangePropertyDynamic>),
755    PartitionByListProperty(Box<PartitionByListProperty>),
756    PartitionList(Box<PartitionList>),
757    Partition(Box<Partition>),
758    RefreshTriggerProperty(Box<RefreshTriggerProperty>),
759    UniqueKeyProperty(Box<UniqueKeyProperty>),
760    RollupProperty(Box<RollupProperty>),
761    PartitionBoundSpec(Box<PartitionBoundSpec>),
762    PartitionedOfProperty(Box<PartitionedOfProperty>),
763    RemoteWithConnectionModelProperty(Box<RemoteWithConnectionModelProperty>),
764    ReturnsProperty(Box<ReturnsProperty>),
765    RowFormatProperty(Box<RowFormatProperty>),
766    RowFormatDelimitedProperty(Box<RowFormatDelimitedProperty>),
767    RowFormatSerdeProperty(Box<RowFormatSerdeProperty>),
768    QueryTransform(Box<QueryTransform>),
769    SampleProperty(Box<SampleProperty>),
770    SecurityProperty(Box<SecurityProperty>),
771    SchemaCommentProperty(Box<SchemaCommentProperty>),
772    SemanticView(Box<SemanticView>),
773    SerdeProperties(Box<SerdeProperties>),
774    SetProperty(Box<SetProperty>),
775    SharingProperty(Box<SharingProperty>),
776    SetConfigProperty(Box<SetConfigProperty>),
777    SettingsProperty(Box<SettingsProperty>),
778    SortKeyProperty(Box<SortKeyProperty>),
779    SqlReadWriteProperty(Box<SqlReadWriteProperty>),
780    SqlSecurityProperty(Box<SqlSecurityProperty>),
781    StabilityProperty(Box<StabilityProperty>),
782    StorageHandlerProperty(Box<StorageHandlerProperty>),
783    TemporaryProperty(Box<TemporaryProperty>),
784    Tags(Box<Tags>),
785    TransformModelProperty(Box<TransformModelProperty>),
786    TransientProperty(Box<TransientProperty>),
787    UsingTemplateProperty(Box<UsingTemplateProperty>),
788    ViewAttributeProperty(Box<ViewAttributeProperty>),
789    VolatileProperty(Box<VolatileProperty>),
790    WithDataProperty(Box<WithDataProperty>),
791    WithJournalTableProperty(Box<WithJournalTableProperty>),
792    WithSchemaBindingProperty(Box<WithSchemaBindingProperty>),
793    WithSystemVersioningProperty(Box<WithSystemVersioningProperty>),
794    WithProcedureOptions(Box<WithProcedureOptions>),
795    EncodeProperty(Box<EncodeProperty>),
796    IncludeProperty(Box<IncludeProperty>),
797    Properties(Box<Properties>),
798    OptionsProperty(Box<OptionsProperty>),
799    InputOutputFormat(Box<InputOutputFormat>),
800    Reference(Box<Reference>),
801    QueryOption(Box<QueryOption>),
802    WithTableHint(Box<WithTableHint>),
803    IndexTableHint(Box<IndexTableHint>),
804    HistoricalData(Box<HistoricalData>),
805    Get(Box<Get>),
806    SetOperation(Box<SetOperation>),
807    Var(Box<Var>),
808    Variadic(Box<Variadic>),
809    Version(Box<Version>),
810    Schema(Box<Schema>),
811    Lock(Box<Lock>),
812    TableSample(Box<TableSample>),
813    Tag(Box<Tag>),
814    UnpivotColumns(Box<UnpivotColumns>),
815    WindowSpec(Box<WindowSpec>),
816    SessionParameter(Box<SessionParameter>),
817    PseudoType(Box<PseudoType>),
818    ObjectIdentifier(Box<ObjectIdentifier>),
819    Transaction(Box<Transaction>),
820    Commit(Box<Commit>),
821    Rollback(Box<Rollback>),
822    AlterSession(Box<AlterSession>),
823    Analyze(Box<Analyze>),
824    AnalyzeStatistics(Box<AnalyzeStatistics>),
825    AnalyzeHistogram(Box<AnalyzeHistogram>),
826    AnalyzeSample(Box<AnalyzeSample>),
827    AnalyzeListChainedRows(Box<AnalyzeListChainedRows>),
828    AnalyzeDelete(Box<AnalyzeDelete>),
829    AnalyzeWith(Box<AnalyzeWith>),
830    AnalyzeValidate(Box<AnalyzeValidate>),
831    AddPartition(Box<AddPartition>),
832    AttachOption(Box<AttachOption>),
833    DropPartition(Box<DropPartition>),
834    ReplacePartition(Box<ReplacePartition>),
835    DPipe(Box<DPipe>),
836    Operator(Box<Operator>),
837    PivotAny(Box<PivotAny>),
838    Aliases(Box<Aliases>),
839    AtIndex(Box<AtIndex>),
840    FromTimeZone(Box<FromTimeZone>),
841    FormatPhrase(Box<FormatPhrase>),
842    ForIn(Box<ForIn>),
843    TimeUnit(Box<TimeUnit>),
844    IntervalOp(Box<IntervalOp>),
845    IntervalSpan(Box<IntervalSpan>),
846    HavingMax(Box<HavingMax>),
847    CosineDistance(Box<CosineDistance>),
848    DotProduct(Box<DotProduct>),
849    EuclideanDistance(Box<EuclideanDistance>),
850    ManhattanDistance(Box<ManhattanDistance>),
851    JarowinklerSimilarity(Box<JarowinklerSimilarity>),
852    Booland(Box<Booland>),
853    Boolor(Box<Boolor>),
854    ParameterizedAgg(Box<ParameterizedAgg>),
855    ArgMax(Box<ArgMax>),
856    ArgMin(Box<ArgMin>),
857    ApproxTopK(Box<ApproxTopK>),
858    ApproxTopKAccumulate(Box<ApproxTopKAccumulate>),
859    ApproxTopKCombine(Box<ApproxTopKCombine>),
860    ApproxTopKEstimate(Box<ApproxTopKEstimate>),
861    ApproxTopSum(Box<ApproxTopSum>),
862    ApproxQuantiles(Box<ApproxQuantiles>),
863    Minhash(Box<Minhash>),
864    FarmFingerprint(Box<FarmFingerprint>),
865    Float64(Box<Float64>),
866    Transform(Box<Transform>),
867    Translate(Box<Translate>),
868    Grouping(Box<Grouping>),
869    GroupingId(Box<GroupingId>),
870    Anonymous(Box<Anonymous>),
871    AnonymousAggFunc(Box<AnonymousAggFunc>),
872    CombinedAggFunc(Box<CombinedAggFunc>),
873    CombinedParameterizedAgg(Box<CombinedParameterizedAgg>),
874    HashAgg(Box<HashAgg>),
875    Hll(Box<Hll>),
876    Apply(Box<Apply>),
877    ToBoolean(Box<ToBoolean>),
878    List(Box<List>),
879    ToMap(Box<ToMap>),
880    Pad(Box<Pad>),
881    ToChar(Box<ToChar>),
882    ToNumber(Box<ToNumber>),
883    ToDouble(Box<ToDouble>),
884    Int64(Box<UnaryFunc>),
885    StringFunc(Box<StringFunc>),
886    ToDecfloat(Box<ToDecfloat>),
887    TryToDecfloat(Box<TryToDecfloat>),
888    ToFile(Box<ToFile>),
889    Columns(Box<Columns>),
890    ConvertToCharset(Box<ConvertToCharset>),
891    ConvertTimezone(Box<ConvertTimezone>),
892    GenerateSeries(Box<GenerateSeries>),
893    AIAgg(Box<AIAgg>),
894    AIClassify(Box<AIClassify>),
895    ArrayAll(Box<ArrayAll>),
896    ArrayAny(Box<ArrayAny>),
897    ArrayConstructCompact(Box<ArrayConstructCompact>),
898    StPoint(Box<StPoint>),
899    StDistance(Box<StDistance>),
900    StringToArray(Box<StringToArray>),
901    ArraySum(Box<ArraySum>),
902    ObjectAgg(Box<ObjectAgg>),
903    CastToStrType(Box<CastToStrType>),
904    CheckJson(Box<CheckJson>),
905    CheckXml(Box<CheckXml>),
906    TranslateCharacters(Box<TranslateCharacters>),
907    CurrentSchemas(Box<CurrentSchemas>),
908    CurrentDatetime(Box<CurrentDatetime>),
909    Localtime(Box<Localtime>),
910    Localtimestamp(Box<Localtimestamp>),
911    Systimestamp(Box<Systimestamp>),
912    CurrentSchema(Box<CurrentSchema>),
913    CurrentUser(Box<CurrentUser>),
914    UtcTime(Box<UtcTime>),
915    UtcTimestamp(Box<UtcTimestamp>),
916    Timestamp(Box<TimestampFunc>),
917    DateBin(Box<DateBin>),
918    Datetime(Box<Datetime>),
919    DatetimeAdd(Box<DatetimeAdd>),
920    DatetimeSub(Box<DatetimeSub>),
921    DatetimeDiff(Box<DatetimeDiff>),
922    DatetimeTrunc(Box<DatetimeTrunc>),
923    Dayname(Box<Dayname>),
924    MakeInterval(Box<MakeInterval>),
925    PreviousDay(Box<PreviousDay>),
926    Elt(Box<Elt>),
927    TimestampAdd(Box<TimestampAdd>),
928    TimestampSub(Box<TimestampSub>),
929    TimestampDiff(Box<TimestampDiff>),
930    TimeSlice(Box<TimeSlice>),
931    TimeAdd(Box<TimeAdd>),
932    TimeSub(Box<TimeSub>),
933    TimeDiff(Box<TimeDiff>),
934    TimeTrunc(Box<TimeTrunc>),
935    DateFromParts(Box<DateFromParts>),
936    TimeFromParts(Box<TimeFromParts>),
937    DecodeCase(Box<DecodeCase>),
938    Decrypt(Box<Decrypt>),
939    DecryptRaw(Box<DecryptRaw>),
940    Encode(Box<Encode>),
941    Encrypt(Box<Encrypt>),
942    EncryptRaw(Box<EncryptRaw>),
943    EqualNull(Box<EqualNull>),
944    ToBinary(Box<ToBinary>),
945    Base64DecodeBinary(Box<Base64DecodeBinary>),
946    Base64DecodeString(Box<Base64DecodeString>),
947    Base64Encode(Box<Base64Encode>),
948    TryBase64DecodeBinary(Box<TryBase64DecodeBinary>),
949    TryBase64DecodeString(Box<TryBase64DecodeString>),
950    GapFill(Box<GapFill>),
951    GenerateDateArray(Box<GenerateDateArray>),
952    GenerateTimestampArray(Box<GenerateTimestampArray>),
953    GetExtract(Box<GetExtract>),
954    Getbit(Box<Getbit>),
955    OverflowTruncateBehavior(Box<OverflowTruncateBehavior>),
956    HexEncode(Box<HexEncode>),
957    Compress(Box<Compress>),
958    DecompressBinary(Box<DecompressBinary>),
959    DecompressString(Box<DecompressString>),
960    Xor(Box<Xor>),
961    Nullif(Box<Nullif>),
962    JSON(Box<JSON>),
963    JSONPath(Box<JSONPath>),
964    JSONPathFilter(Box<JSONPathFilter>),
965    JSONPathKey(Box<JSONPathKey>),
966    JSONPathRecursive(Box<JSONPathRecursive>),
967    JSONPathScript(Box<JSONPathScript>),
968    JSONPathSlice(Box<JSONPathSlice>),
969    JSONPathSelector(Box<JSONPathSelector>),
970    JSONPathSubscript(Box<JSONPathSubscript>),
971    JSONPathUnion(Box<JSONPathUnion>),
972    Format(Box<Format>),
973    JSONKeys(Box<JSONKeys>),
974    JSONKeyValue(Box<JSONKeyValue>),
975    JSONKeysAtDepth(Box<JSONKeysAtDepth>),
976    JSONObject(Box<JSONObject>),
977    JSONObjectAgg(Box<JSONObjectAgg>),
978    JSONBObjectAgg(Box<JSONBObjectAgg>),
979    JSONArray(Box<JSONArray>),
980    JSONArrayAgg(Box<JSONArrayAgg>),
981    JSONExists(Box<JSONExists>),
982    JSONColumnDef(Box<JSONColumnDef>),
983    JSONSchema(Box<JSONSchema>),
984    JSONSet(Box<JSONSet>),
985    JSONStripNulls(Box<JSONStripNulls>),
986    JSONValue(Box<JSONValue>),
987    JSONValueArray(Box<JSONValueArray>),
988    JSONRemove(Box<JSONRemove>),
989    JSONTable(Box<JSONTable>),
990    JSONType(Box<JSONType>),
991    ObjectInsert(Box<ObjectInsert>),
992    OpenJSONColumnDef(Box<OpenJSONColumnDef>),
993    OpenJSON(Box<OpenJSON>),
994    JSONBExists(Box<JSONBExists>),
995    JSONBContains(Box<BinaryFunc>),
996    JSONBExtract(Box<BinaryFunc>),
997    JSONCast(Box<JSONCast>),
998    JSONExtract(Box<JSONExtract>),
999    JSONExtractQuote(Box<JSONExtractQuote>),
1000    JSONExtractArray(Box<JSONExtractArray>),
1001    JSONExtractScalar(Box<JSONExtractScalar>),
1002    JSONBExtractScalar(Box<JSONBExtractScalar>),
1003    JSONFormat(Box<JSONFormat>),
1004    JSONBool(Box<UnaryFunc>),
1005    JSONPathRoot(JSONPathRoot),
1006    JSONArrayAppend(Box<JSONArrayAppend>),
1007    JSONArrayContains(Box<JSONArrayContains>),
1008    JSONArrayInsert(Box<JSONArrayInsert>),
1009    ParseJSON(Box<ParseJSON>),
1010    ParseUrl(Box<ParseUrl>),
1011    ParseIp(Box<ParseIp>),
1012    ParseTime(Box<ParseTime>),
1013    ParseDatetime(Box<ParseDatetime>),
1014    Map(Box<Map>),
1015    MapCat(Box<MapCat>),
1016    MapDelete(Box<MapDelete>),
1017    MapInsert(Box<MapInsert>),
1018    MapPick(Box<MapPick>),
1019    ScopeResolution(Box<ScopeResolution>),
1020    Slice(Box<Slice>),
1021    VarMap(Box<VarMap>),
1022    MatchAgainst(Box<MatchAgainst>),
1023    MD5Digest(Box<MD5Digest>),
1024    MD5NumberLower64(Box<UnaryFunc>),
1025    MD5NumberUpper64(Box<UnaryFunc>),
1026    Monthname(Box<Monthname>),
1027    Ntile(Box<Ntile>),
1028    Normalize(Box<Normalize>),
1029    Normal(Box<Normal>),
1030    Predict(Box<Predict>),
1031    MLTranslate(Box<MLTranslate>),
1032    FeaturesAtTime(Box<FeaturesAtTime>),
1033    GenerateEmbedding(Box<GenerateEmbedding>),
1034    MLForecast(Box<MLForecast>),
1035    ModelAttribute(Box<ModelAttribute>),
1036    VectorSearch(Box<VectorSearch>),
1037    Quantile(Box<Quantile>),
1038    ApproxQuantile(Box<ApproxQuantile>),
1039    ApproxPercentileEstimate(Box<ApproxPercentileEstimate>),
1040    Randn(Box<Randn>),
1041    Randstr(Box<Randstr>),
1042    RangeN(Box<RangeN>),
1043    RangeBucket(Box<RangeBucket>),
1044    ReadCSV(Box<ReadCSV>),
1045    ReadParquet(Box<ReadParquet>),
1046    Reduce(Box<Reduce>),
1047    RegexpExtractAll(Box<RegexpExtractAll>),
1048    RegexpILike(Box<RegexpILike>),
1049    RegexpFullMatch(Box<RegexpFullMatch>),
1050    RegexpInstr(Box<RegexpInstr>),
1051    RegexpSplit(Box<RegexpSplit>),
1052    RegexpCount(Box<RegexpCount>),
1053    RegrValx(Box<RegrValx>),
1054    RegrValy(Box<RegrValy>),
1055    RegrAvgy(Box<RegrAvgy>),
1056    RegrAvgx(Box<RegrAvgx>),
1057    RegrCount(Box<RegrCount>),
1058    RegrIntercept(Box<RegrIntercept>),
1059    RegrR2(Box<RegrR2>),
1060    RegrSxx(Box<RegrSxx>),
1061    RegrSxy(Box<RegrSxy>),
1062    RegrSyy(Box<RegrSyy>),
1063    RegrSlope(Box<RegrSlope>),
1064    SafeAdd(Box<SafeAdd>),
1065    SafeDivide(Box<SafeDivide>),
1066    SafeMultiply(Box<SafeMultiply>),
1067    SafeSubtract(Box<SafeSubtract>),
1068    SHA2(Box<SHA2>),
1069    SHA2Digest(Box<SHA2Digest>),
1070    SortArray(Box<SortArray>),
1071    SplitPart(Box<SplitPart>),
1072    SubstringIndex(Box<SubstringIndex>),
1073    StandardHash(Box<StandardHash>),
1074    StrPosition(Box<StrPosition>),
1075    Search(Box<Search>),
1076    SearchIp(Box<SearchIp>),
1077    StrToDate(Box<StrToDate>),
1078    DateStrToDate(Box<UnaryFunc>),
1079    DateToDateStr(Box<UnaryFunc>),
1080    StrToTime(Box<StrToTime>),
1081    StrToUnix(Box<StrToUnix>),
1082    StrToMap(Box<StrToMap>),
1083    NumberToStr(Box<NumberToStr>),
1084    FromBase(Box<FromBase>),
1085    Stuff(Box<Stuff>),
1086    TimeToStr(Box<TimeToStr>),
1087    TimeStrToTime(Box<TimeStrToTime>),
1088    TsOrDsAdd(Box<TsOrDsAdd>),
1089    TsOrDsDiff(Box<TsOrDsDiff>),
1090    TsOrDsToDate(Box<TsOrDsToDate>),
1091    TsOrDsToTime(Box<TsOrDsToTime>),
1092    Unhex(Box<Unhex>),
1093    Uniform(Box<Uniform>),
1094    UnixToStr(Box<UnixToStr>),
1095    UnixToTime(Box<UnixToTime>),
1096    Uuid(Box<Uuid>),
1097    TimestampFromParts(Box<TimestampFromParts>),
1098    TimestampTzFromParts(Box<TimestampTzFromParts>),
1099    Corr(Box<Corr>),
1100    WidthBucket(Box<WidthBucket>),
1101    CovarSamp(Box<CovarSamp>),
1102    CovarPop(Box<CovarPop>),
1103    Week(Box<Week>),
1104    XMLElement(Box<XMLElement>),
1105    XMLGet(Box<XMLGet>),
1106    XMLTable(Box<XMLTable>),
1107    XMLKeyValueOption(Box<XMLKeyValueOption>),
1108    Zipf(Box<Zipf>),
1109    Merge(Box<Merge>),
1110    When(Box<When>),
1111    Whens(Box<Whens>),
1112    NextValueFor(Box<NextValueFor>),
1113    /// RETURN statement (DuckDB stored procedures)
1114    ReturnStmt(Box<Expression>),
1115}
1116
1117impl Expression {
1118    /// Create a `Column` variant, boxing the value automatically.
1119    #[inline]
1120    pub fn boxed_column(col: Column) -> Self {
1121        Expression::Column(Box::new(col))
1122    }
1123
1124    /// Create a `Table` variant, boxing the value automatically.
1125    #[inline]
1126    pub fn boxed_table(t: TableRef) -> Self {
1127        Expression::Table(Box::new(t))
1128    }
1129
1130    /// Returns `true` if this expression is a valid top-level SQL statement.
1131    ///
1132    /// Bare expressions like identifiers, literals, and function calls are not
1133    /// valid statements. This is used by `validate()` to reject inputs like
1134    /// `SELECT scooby dooby doo` which the parser splits into `SELECT scooby AS dooby`
1135    /// plus the bare identifier `doo`.
1136    pub fn is_statement(&self) -> bool {
1137        match self {
1138            // Queries
1139            Expression::Select(_)
1140            | Expression::Union(_)
1141            | Expression::Intersect(_)
1142            | Expression::Except(_)
1143            | Expression::Subquery(_)
1144            | Expression::Values(_)
1145            | Expression::PipeOperator(_)
1146
1147            // DML
1148            | Expression::Insert(_)
1149            | Expression::Update(_)
1150            | Expression::Delete(_)
1151            | Expression::Copy(_)
1152            | Expression::Put(_)
1153            | Expression::Merge(_)
1154            | Expression::TryCatch(_)
1155
1156            // DDL
1157            | Expression::CreateTable(_)
1158            | Expression::DropTable(_)
1159            | Expression::Undrop(_)
1160            | Expression::AlterTable(_)
1161            | Expression::SplitTable(_)
1162            | Expression::FlashbackTable(_)
1163            | Expression::CreateIndex(_)
1164            | Expression::DropIndex(_)
1165            | Expression::CreateView(_)
1166            | Expression::DropView(_)
1167            | Expression::AlterView(_)
1168            | Expression::AlterIndex(_)
1169            | Expression::Truncate(_)
1170            | Expression::TruncateTable(_)
1171            | Expression::CreateSchema(_)
1172            | Expression::DropSchema(_)
1173            | Expression::DropNamespace(_)
1174            | Expression::CreateDatabase(_)
1175            | Expression::DropDatabase(_)
1176            | Expression::CreateFunction(_)
1177            | Expression::DropFunction(_)
1178            | Expression::CreateProcedure(_)
1179            | Expression::DropProcedure(_)
1180            | Expression::CreateSequence(_)
1181            | Expression::CreateSynonym(_)
1182            | Expression::DropSequence(_)
1183            | Expression::AlterSequence(_)
1184            | Expression::CreateTrigger(_)
1185            | Expression::DropTrigger(_)
1186            | Expression::CreateType(_)
1187            | Expression::DropType(_)
1188            | Expression::Comment(_)
1189
1190            // Session/Transaction/Control
1191            | Expression::Use(_)
1192            | Expression::Set(_)
1193            | Expression::SetStatement(_)
1194            | Expression::Transaction(_)
1195            | Expression::Commit(_)
1196            | Expression::Rollback(_)
1197            | Expression::Grant(_)
1198            | Expression::Revoke(_)
1199            | Expression::Cache(_)
1200            | Expression::Uncache(_)
1201            | Expression::LoadData(_)
1202            | Expression::Pragma(_)
1203            | Expression::Describe(_)
1204            | Expression::Show(_)
1205            | Expression::Kill(_)
1206            | Expression::Prepare(_)
1207            | Expression::Execute(_)
1208            | Expression::Declare(_)
1209            | Expression::Refresh(_)
1210            | Expression::AlterSession(_)
1211            | Expression::LockingStatement(_)
1212
1213            // Analyze
1214            | Expression::Analyze(_)
1215            | Expression::AnalyzeStatistics(_)
1216            | Expression::AnalyzeHistogram(_)
1217            | Expression::AnalyzeSample(_)
1218            | Expression::AnalyzeListChainedRows(_)
1219            | Expression::AnalyzeDelete(_)
1220
1221            // Attach/Detach/Install/Summarize
1222            | Expression::Attach(_)
1223            | Expression::Detach(_)
1224            | Expression::Install(_)
1225            | Expression::Summarize(_)
1226
1227            // Pivot at statement level
1228            | Expression::Pivot(_)
1229            | Expression::Unpivot(_)
1230
1231            // Command (raw/unparsed statements)
1232            | Expression::Command(_)
1233            | Expression::Raw(_)
1234            | Expression::CreateTask(_)
1235
1236            // Return statement
1237            | Expression::ReturnStmt(_) => true,
1238
1239            // Annotated wraps another expression with comments — check inner
1240            Expression::Annotated(a) => a.this.is_statement(),
1241
1242            // Alias at top level can wrap a statement (e.g., parenthesized subquery with alias)
1243            Expression::Alias(a) => a.this.is_statement(),
1244
1245            // Everything else (identifiers, literals, operators, functions, etc.)
1246            _ => false,
1247        }
1248    }
1249
1250    /// Create a literal number expression from an integer.
1251    pub fn number(n: i64) -> Self {
1252        Expression::Literal(Box::new(Literal::Number(n.to_string())))
1253    }
1254
1255    /// Create a single-quoted literal string expression.
1256    pub fn string(s: impl Into<String>) -> Self {
1257        Expression::Literal(Box::new(Literal::String(s.into())))
1258    }
1259
1260    /// Create a literal number expression from a float.
1261    pub fn float(f: f64) -> Self {
1262        Expression::Literal(Box::new(Literal::Number(f.to_string())))
1263    }
1264
1265    /// Get the inferred type annotation, if present.
1266    ///
1267    /// For value-producing expressions with an `inferred_type` field, returns
1268    /// the stored type. For literals and boolean constants, computes the type
1269    /// on the fly from the variant. For DDL/clause expressions, returns `None`.
1270    pub fn inferred_type(&self) -> Option<&DataType> {
1271        match self {
1272            // Structs with inferred_type field
1273            Expression::And(op)
1274            | Expression::Or(op)
1275            | Expression::Add(op)
1276            | Expression::Sub(op)
1277            | Expression::Mul(op)
1278            | Expression::Div(op)
1279            | Expression::Mod(op)
1280            | Expression::Eq(op)
1281            | Expression::Neq(op)
1282            | Expression::Lt(op)
1283            | Expression::Lte(op)
1284            | Expression::Gt(op)
1285            | Expression::Gte(op)
1286            | Expression::Concat(op)
1287            | Expression::BitwiseAnd(op)
1288            | Expression::BitwiseOr(op)
1289            | Expression::BitwiseXor(op)
1290            | Expression::Adjacent(op)
1291            | Expression::TsMatch(op)
1292            | Expression::PropertyEQ(op)
1293            | Expression::ArrayContainsAll(op)
1294            | Expression::ArrayContainedBy(op)
1295            | Expression::ArrayOverlaps(op)
1296            | Expression::JSONBContainsAllTopKeys(op)
1297            | Expression::JSONBContainsAnyTopKeys(op)
1298            | Expression::JSONBDeleteAtPath(op)
1299            | Expression::ExtendsLeft(op)
1300            | Expression::ExtendsRight(op)
1301            | Expression::Is(op)
1302            | Expression::MemberOf(op)
1303            | Expression::Match(op)
1304            | Expression::NullSafeEq(op)
1305            | Expression::NullSafeNeq(op)
1306            | Expression::Glob(op)
1307            | Expression::BitwiseLeftShift(op)
1308            | Expression::BitwiseRightShift(op) => op.inferred_type.as_ref(),
1309
1310            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1311                op.inferred_type.as_ref()
1312            }
1313
1314            Expression::Like(op) | Expression::ILike(op) => op.inferred_type.as_ref(),
1315
1316            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1317                c.inferred_type.as_ref()
1318            }
1319
1320            Expression::Column(c) => c.inferred_type.as_ref(),
1321            Expression::Dot(dot) => dot.inferred_type.as_ref(),
1322            Expression::Function(f) => f.inferred_type.as_ref(),
1323            Expression::AggregateFunction(f) => f.inferred_type.as_ref(),
1324            Expression::WindowFunction(f) => f.inferred_type.as_ref(),
1325            Expression::Case(c) => c.inferred_type.as_ref(),
1326            Expression::Subquery(s) => s.inferred_type.as_ref(),
1327            Expression::Alias(a) => a.inferred_type.as_ref(),
1328            Expression::Unnest(u) => u.inferred_type.as_ref(),
1329            Expression::IfFunc(f) => f.inferred_type.as_ref(),
1330            Expression::Nvl2(f) => f.inferred_type.as_ref(),
1331            Expression::Count(f) => f.inferred_type.as_ref(),
1332            Expression::GroupConcat(f) => f.inferred_type.as_ref(),
1333            Expression::StringAgg(f) => f.inferred_type.as_ref(),
1334            Expression::ListAgg(f) => f.inferred_type.as_ref(),
1335            Expression::SumIf(f) => f.inferred_type.as_ref(),
1336
1337            // UnaryFunc variants
1338            Expression::Upper(f)
1339            | Expression::Lower(f)
1340            | Expression::Length(f)
1341            | Expression::LTrim(f)
1342            | Expression::RTrim(f)
1343            | Expression::Reverse(f)
1344            | Expression::Abs(f)
1345            | Expression::Sqrt(f)
1346            | Expression::Cbrt(f)
1347            | Expression::Ln(f)
1348            | Expression::Exp(f)
1349            | Expression::Sign(f)
1350            | Expression::Date(f)
1351            | Expression::Time(f)
1352            | Expression::Initcap(f)
1353            | Expression::Ascii(f)
1354            | Expression::Chr(f)
1355            | Expression::Soundex(f)
1356            | Expression::ByteLength(f)
1357            | Expression::Hex(f)
1358            | Expression::LowerHex(f)
1359            | Expression::Unicode(f)
1360            | Expression::Typeof(f)
1361            | Expression::Explode(f)
1362            | Expression::ExplodeOuter(f)
1363            | Expression::MapFromEntries(f)
1364            | Expression::MapKeys(f)
1365            | Expression::MapValues(f)
1366            | Expression::ArrayLength(f)
1367            | Expression::ArraySize(f)
1368            | Expression::Cardinality(f)
1369            | Expression::ArrayReverse(f)
1370            | Expression::ArrayDistinct(f)
1371            | Expression::ArrayFlatten(f)
1372            | Expression::ArrayCompact(f)
1373            | Expression::ToArray(f)
1374            | Expression::JsonArrayLength(f)
1375            | Expression::JsonKeys(f)
1376            | Expression::JsonType(f)
1377            | Expression::ParseJson(f)
1378            | Expression::ToJson(f)
1379            | Expression::Radians(f)
1380            | Expression::Degrees(f)
1381            | Expression::Sin(f)
1382            | Expression::Cos(f)
1383            | Expression::Tan(f)
1384            | Expression::Asin(f)
1385            | Expression::Acos(f)
1386            | Expression::Atan(f)
1387            | Expression::IsNan(f)
1388            | Expression::IsInf(f)
1389            | Expression::Year(f)
1390            | Expression::Month(f)
1391            | Expression::Day(f)
1392            | Expression::Hour(f)
1393            | Expression::Minute(f)
1394            | Expression::Second(f)
1395            | Expression::DayOfWeek(f)
1396            | Expression::DayOfWeekIso(f)
1397            | Expression::DayOfMonth(f)
1398            | Expression::DayOfYear(f)
1399            | Expression::WeekOfYear(f)
1400            | Expression::Quarter(f)
1401            | Expression::Epoch(f)
1402            | Expression::EpochMs(f)
1403            | Expression::BitwiseCount(f)
1404            | Expression::DateFromUnixDate(f)
1405            | Expression::UnixDate(f)
1406            | Expression::UnixSeconds(f)
1407            | Expression::UnixMillis(f)
1408            | Expression::UnixMicros(f)
1409            | Expression::TimeStrToDate(f)
1410            | Expression::DateToDi(f)
1411            | Expression::DiToDate(f)
1412            | Expression::TsOrDiToDi(f)
1413            | Expression::TsOrDsToDatetime(f)
1414            | Expression::TsOrDsToTimestamp(f)
1415            | Expression::YearOfWeek(f)
1416            | Expression::YearOfWeekIso(f)
1417            | Expression::SHA(f)
1418            | Expression::SHA1Digest(f)
1419            | Expression::TimeToUnix(f)
1420            | Expression::TimeStrToUnix(f) => f.inferred_type.as_ref(),
1421
1422            // BinaryFunc variants
1423            Expression::Power(f)
1424            | Expression::NullIf(f)
1425            | Expression::IfNull(f)
1426            | Expression::Nvl(f)
1427            | Expression::Contains(f)
1428            | Expression::StartsWith(f)
1429            | Expression::EndsWith(f)
1430            | Expression::Levenshtein(f)
1431            | Expression::ModFunc(f)
1432            | Expression::IntDiv(f)
1433            | Expression::Atan2(f)
1434            | Expression::AddMonths(f)
1435            | Expression::MonthsBetween(f)
1436            | Expression::NextDay(f)
1437            | Expression::UnixToTimeStr(f)
1438            | Expression::ArrayContains(f)
1439            | Expression::ArrayPosition(f)
1440            | Expression::ArrayAppend(f)
1441            | Expression::ArrayPrepend(f)
1442            | Expression::ArrayUnion(f)
1443            | Expression::ArrayExcept(f)
1444            | Expression::ArrayRemove(f)
1445            | Expression::StarMap(f)
1446            | Expression::MapFromArrays(f)
1447            | Expression::MapContainsKey(f)
1448            | Expression::ElementAt(f)
1449            | Expression::JsonMergePatch(f) => f.inferred_type.as_ref(),
1450
1451            // VarArgFunc variants
1452            Expression::Coalesce(f)
1453            | Expression::Greatest(f)
1454            | Expression::Least(f)
1455            | Expression::ArrayConcat(f)
1456            | Expression::ArrayIntersect(f)
1457            | Expression::ArrayZip(f)
1458            | Expression::MapConcat(f)
1459            | Expression::JsonArray(f) => f.inferred_type.as_ref(),
1460
1461            // AggFunc variants
1462            Expression::Sum(f)
1463            | Expression::Avg(f)
1464            | Expression::Min(f)
1465            | Expression::Max(f)
1466            | Expression::ArrayAgg(f)
1467            | Expression::CountIf(f)
1468            | Expression::Stddev(f)
1469            | Expression::StddevPop(f)
1470            | Expression::StddevSamp(f)
1471            | Expression::Variance(f)
1472            | Expression::VarPop(f)
1473            | Expression::VarSamp(f)
1474            | Expression::Median(f)
1475            | Expression::Mode(f)
1476            | Expression::First(f)
1477            | Expression::Last(f)
1478            | Expression::AnyValue(f)
1479            | Expression::ApproxDistinct(f)
1480            | Expression::ApproxCountDistinct(f)
1481            | Expression::LogicalAnd(f)
1482            | Expression::LogicalOr(f)
1483            | Expression::Skewness(f)
1484            | Expression::ArrayConcatAgg(f)
1485            | Expression::ArrayUniqueAgg(f)
1486            | Expression::BoolXorAgg(f)
1487            | Expression::BitwiseAndAgg(f)
1488            | Expression::BitwiseOrAgg(f)
1489            | Expression::BitwiseXorAgg(f) => f.inferred_type.as_ref(),
1490
1491            // Everything else: no inferred_type field
1492            _ => None,
1493        }
1494    }
1495
1496    /// Set the inferred type annotation on this expression.
1497    ///
1498    /// Only has an effect on value-producing expressions with an `inferred_type`
1499    /// field. For other expression types, this is a no-op.
1500    pub fn set_inferred_type(&mut self, dt: DataType) {
1501        match self {
1502            Expression::And(op)
1503            | Expression::Or(op)
1504            | Expression::Add(op)
1505            | Expression::Sub(op)
1506            | Expression::Mul(op)
1507            | Expression::Div(op)
1508            | Expression::Mod(op)
1509            | Expression::Eq(op)
1510            | Expression::Neq(op)
1511            | Expression::Lt(op)
1512            | Expression::Lte(op)
1513            | Expression::Gt(op)
1514            | Expression::Gte(op)
1515            | Expression::Concat(op)
1516            | Expression::BitwiseAnd(op)
1517            | Expression::BitwiseOr(op)
1518            | Expression::BitwiseXor(op)
1519            | Expression::Adjacent(op)
1520            | Expression::TsMatch(op)
1521            | Expression::PropertyEQ(op)
1522            | Expression::ArrayContainsAll(op)
1523            | Expression::ArrayContainedBy(op)
1524            | Expression::ArrayOverlaps(op)
1525            | Expression::JSONBContainsAllTopKeys(op)
1526            | Expression::JSONBContainsAnyTopKeys(op)
1527            | Expression::JSONBDeleteAtPath(op)
1528            | Expression::ExtendsLeft(op)
1529            | Expression::ExtendsRight(op)
1530            | Expression::Is(op)
1531            | Expression::MemberOf(op)
1532            | Expression::Match(op)
1533            | Expression::NullSafeEq(op)
1534            | Expression::NullSafeNeq(op)
1535            | Expression::Glob(op)
1536            | Expression::BitwiseLeftShift(op)
1537            | Expression::BitwiseRightShift(op) => op.inferred_type = Some(dt),
1538
1539            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1540                op.inferred_type = Some(dt)
1541            }
1542
1543            Expression::Like(op) | Expression::ILike(op) => op.inferred_type = Some(dt),
1544
1545            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1546                c.inferred_type = Some(dt)
1547            }
1548
1549            Expression::Column(c) => c.inferred_type = Some(dt),
1550            Expression::Dot(dot) => dot.inferred_type = Some(dt),
1551            Expression::Function(f) => f.inferred_type = Some(dt),
1552            Expression::AggregateFunction(f) => f.inferred_type = Some(dt),
1553            Expression::WindowFunction(f) => f.inferred_type = Some(dt),
1554            Expression::Case(c) => c.inferred_type = Some(dt),
1555            Expression::Subquery(s) => s.inferred_type = Some(dt),
1556            Expression::Alias(a) => a.inferred_type = Some(dt),
1557            Expression::Unnest(u) => u.inferred_type = Some(dt),
1558            Expression::IfFunc(f) => f.inferred_type = Some(dt),
1559            Expression::Nvl2(f) => f.inferred_type = Some(dt),
1560            Expression::Count(f) => f.inferred_type = Some(dt),
1561            Expression::GroupConcat(f) => f.inferred_type = Some(dt),
1562            Expression::StringAgg(f) => f.inferred_type = Some(dt),
1563            Expression::ListAgg(f) => f.inferred_type = Some(dt),
1564            Expression::SumIf(f) => f.inferred_type = Some(dt),
1565
1566            // UnaryFunc variants
1567            Expression::Upper(f)
1568            | Expression::Lower(f)
1569            | Expression::Length(f)
1570            | Expression::LTrim(f)
1571            | Expression::RTrim(f)
1572            | Expression::Reverse(f)
1573            | Expression::Abs(f)
1574            | Expression::Sqrt(f)
1575            | Expression::Cbrt(f)
1576            | Expression::Ln(f)
1577            | Expression::Exp(f)
1578            | Expression::Sign(f)
1579            | Expression::Date(f)
1580            | Expression::Time(f)
1581            | Expression::Initcap(f)
1582            | Expression::Ascii(f)
1583            | Expression::Chr(f)
1584            | Expression::Soundex(f)
1585            | Expression::ByteLength(f)
1586            | Expression::Hex(f)
1587            | Expression::LowerHex(f)
1588            | Expression::Unicode(f)
1589            | Expression::Typeof(f)
1590            | Expression::Explode(f)
1591            | Expression::ExplodeOuter(f)
1592            | Expression::MapFromEntries(f)
1593            | Expression::MapKeys(f)
1594            | Expression::MapValues(f)
1595            | Expression::ArrayLength(f)
1596            | Expression::ArraySize(f)
1597            | Expression::Cardinality(f)
1598            | Expression::ArrayReverse(f)
1599            | Expression::ArrayDistinct(f)
1600            | Expression::ArrayFlatten(f)
1601            | Expression::ArrayCompact(f)
1602            | Expression::ToArray(f)
1603            | Expression::JsonArrayLength(f)
1604            | Expression::JsonKeys(f)
1605            | Expression::JsonType(f)
1606            | Expression::ParseJson(f)
1607            | Expression::ToJson(f)
1608            | Expression::Radians(f)
1609            | Expression::Degrees(f)
1610            | Expression::Sin(f)
1611            | Expression::Cos(f)
1612            | Expression::Tan(f)
1613            | Expression::Asin(f)
1614            | Expression::Acos(f)
1615            | Expression::Atan(f)
1616            | Expression::IsNan(f)
1617            | Expression::IsInf(f)
1618            | Expression::Year(f)
1619            | Expression::Month(f)
1620            | Expression::Day(f)
1621            | Expression::Hour(f)
1622            | Expression::Minute(f)
1623            | Expression::Second(f)
1624            | Expression::DayOfWeek(f)
1625            | Expression::DayOfWeekIso(f)
1626            | Expression::DayOfMonth(f)
1627            | Expression::DayOfYear(f)
1628            | Expression::WeekOfYear(f)
1629            | Expression::Quarter(f)
1630            | Expression::Epoch(f)
1631            | Expression::EpochMs(f)
1632            | Expression::BitwiseCount(f)
1633            | Expression::DateFromUnixDate(f)
1634            | Expression::UnixDate(f)
1635            | Expression::UnixSeconds(f)
1636            | Expression::UnixMillis(f)
1637            | Expression::UnixMicros(f)
1638            | Expression::TimeStrToDate(f)
1639            | Expression::DateToDi(f)
1640            | Expression::DiToDate(f)
1641            | Expression::TsOrDiToDi(f)
1642            | Expression::TsOrDsToDatetime(f)
1643            | Expression::TsOrDsToTimestamp(f)
1644            | Expression::YearOfWeek(f)
1645            | Expression::YearOfWeekIso(f)
1646            | Expression::SHA(f)
1647            | Expression::SHA1Digest(f)
1648            | Expression::TimeToUnix(f)
1649            | Expression::TimeStrToUnix(f) => f.inferred_type = Some(dt),
1650
1651            // BinaryFunc variants
1652            Expression::Power(f)
1653            | Expression::NullIf(f)
1654            | Expression::IfNull(f)
1655            | Expression::Nvl(f)
1656            | Expression::Contains(f)
1657            | Expression::StartsWith(f)
1658            | Expression::EndsWith(f)
1659            | Expression::Levenshtein(f)
1660            | Expression::ModFunc(f)
1661            | Expression::IntDiv(f)
1662            | Expression::Atan2(f)
1663            | Expression::AddMonths(f)
1664            | Expression::MonthsBetween(f)
1665            | Expression::NextDay(f)
1666            | Expression::UnixToTimeStr(f)
1667            | Expression::ArrayContains(f)
1668            | Expression::ArrayPosition(f)
1669            | Expression::ArrayAppend(f)
1670            | Expression::ArrayPrepend(f)
1671            | Expression::ArrayUnion(f)
1672            | Expression::ArrayExcept(f)
1673            | Expression::ArrayRemove(f)
1674            | Expression::StarMap(f)
1675            | Expression::MapFromArrays(f)
1676            | Expression::MapContainsKey(f)
1677            | Expression::ElementAt(f)
1678            | Expression::JsonMergePatch(f) => f.inferred_type = Some(dt),
1679
1680            // VarArgFunc variants
1681            Expression::Coalesce(f)
1682            | Expression::Greatest(f)
1683            | Expression::Least(f)
1684            | Expression::ArrayConcat(f)
1685            | Expression::ArrayIntersect(f)
1686            | Expression::ArrayZip(f)
1687            | Expression::MapConcat(f)
1688            | Expression::JsonArray(f) => f.inferred_type = Some(dt),
1689
1690            // AggFunc variants
1691            Expression::Sum(f)
1692            | Expression::Avg(f)
1693            | Expression::Min(f)
1694            | Expression::Max(f)
1695            | Expression::ArrayAgg(f)
1696            | Expression::CountIf(f)
1697            | Expression::Stddev(f)
1698            | Expression::StddevPop(f)
1699            | Expression::StddevSamp(f)
1700            | Expression::Variance(f)
1701            | Expression::VarPop(f)
1702            | Expression::VarSamp(f)
1703            | Expression::Median(f)
1704            | Expression::Mode(f)
1705            | Expression::First(f)
1706            | Expression::Last(f)
1707            | Expression::AnyValue(f)
1708            | Expression::ApproxDistinct(f)
1709            | Expression::ApproxCountDistinct(f)
1710            | Expression::LogicalAnd(f)
1711            | Expression::LogicalOr(f)
1712            | Expression::Skewness(f)
1713            | Expression::ArrayConcatAgg(f)
1714            | Expression::ArrayUniqueAgg(f)
1715            | Expression::BoolXorAgg(f)
1716            | Expression::BitwiseAndAgg(f)
1717            | Expression::BitwiseOrAgg(f)
1718            | Expression::BitwiseXorAgg(f) => f.inferred_type = Some(dt),
1719
1720            // Expressions without inferred_type field - no-op
1721            _ => {}
1722        }
1723    }
1724
1725    /// Create an unqualified column reference (e.g. `name`).
1726    pub fn column(name: impl Into<String>) -> Self {
1727        Expression::Column(Box::new(Column {
1728            name: Identifier::new(name),
1729            table: None,
1730            join_mark: false,
1731            trailing_comments: Vec::new(),
1732            span: None,
1733            inferred_type: None,
1734        }))
1735    }
1736
1737    /// Create a qualified column reference (`table.column`).
1738    pub fn qualified_column(table: impl Into<String>, column: impl Into<String>) -> Self {
1739        Expression::Column(Box::new(Column {
1740            name: Identifier::new(column),
1741            table: Some(Identifier::new(table)),
1742            join_mark: false,
1743            trailing_comments: Vec::new(),
1744            span: None,
1745            inferred_type: None,
1746        }))
1747    }
1748
1749    /// Create a bare identifier expression (not a column reference).
1750    pub fn identifier(name: impl Into<String>) -> Self {
1751        Expression::Identifier(Identifier::new(name))
1752    }
1753
1754    /// Create a NULL expression
1755    pub fn null() -> Self {
1756        Expression::Null(Null)
1757    }
1758
1759    /// Create a TRUE expression
1760    pub fn true_() -> Self {
1761        Expression::Boolean(BooleanLiteral { value: true })
1762    }
1763
1764    /// Create a FALSE expression
1765    pub fn false_() -> Self {
1766        Expression::Boolean(BooleanLiteral { value: false })
1767    }
1768
1769    /// Create a wildcard star (`*`) expression with no EXCEPT/REPLACE/RENAME modifiers.
1770    pub fn star() -> Self {
1771        Expression::Star(Star {
1772            table: None,
1773            except: None,
1774            replace: None,
1775            rename: None,
1776            trailing_comments: Vec::new(),
1777            span: None,
1778        })
1779    }
1780
1781    /// Wrap this expression in an `AS` alias (e.g. `expr AS name`).
1782    pub fn alias(self, name: impl Into<String>) -> Self {
1783        Expression::Alias(Box::new(Alias::new(self, Identifier::new(name))))
1784    }
1785
1786    /// Check if this is a SELECT expression
1787    pub fn is_select(&self) -> bool {
1788        matches!(self, Expression::Select(_))
1789    }
1790
1791    /// Try to get as a Select
1792    pub fn as_select(&self) -> Option<&Select> {
1793        match self {
1794            Expression::Select(s) => Some(s),
1795            _ => None,
1796        }
1797    }
1798
1799    /// Try to get as a mutable Select
1800    pub fn as_select_mut(&mut self) -> Option<&mut Select> {
1801        match self {
1802            Expression::Select(s) => Some(s),
1803            _ => None,
1804        }
1805    }
1806
1807    /// Generate a SQL string for this expression using the generic (dialect-agnostic) generator.
1808    ///
1809    /// Returns an empty string if generation fails. For dialect-specific output,
1810    /// use [`sql_for()`](Self::sql_for) instead.
1811    #[cfg(feature = "generate")]
1812    pub fn sql(&self) -> String {
1813        crate::generator::Generator::sql(self).unwrap_or_default()
1814    }
1815
1816    /// Generate a SQL string for this expression targeting a specific dialect.
1817    ///
1818    /// Dialect-specific rules (identifier quoting, function names, type mappings,
1819    /// syntax variations) are applied automatically.  Returns an empty string if
1820    /// generation fails.
1821    #[cfg(feature = "generate")]
1822    pub fn sql_for(&self, dialect: crate::dialects::DialectType) -> String {
1823        crate::generate(self, dialect).unwrap_or_default()
1824    }
1825}
1826
1827// === Python API accessor methods ===
1828
1829impl Expression {
1830    /// Returns the serde-compatible snake_case variant name without serialization.
1831    /// This is much faster than serializing to JSON and extracting the key.
1832    pub fn variant_name(&self) -> &'static str {
1833        match self {
1834            Expression::Literal(_) => "literal",
1835            Expression::Boolean(_) => "boolean",
1836            Expression::Null(_) => "null",
1837            Expression::Identifier(_) => "identifier",
1838            Expression::Column(_) => "column",
1839            Expression::Table(_) => "table",
1840            Expression::Star(_) => "star",
1841            Expression::BracedWildcard(_) => "braced_wildcard",
1842            Expression::Select(_) => "select",
1843            Expression::Union(_) => "union",
1844            Expression::Intersect(_) => "intersect",
1845            Expression::Except(_) => "except",
1846            Expression::Subquery(_) => "subquery",
1847            Expression::PipeOperator(_) => "pipe_operator",
1848            Expression::Pivot(_) => "pivot",
1849            Expression::PivotAlias(_) => "pivot_alias",
1850            Expression::Unpivot(_) => "unpivot",
1851            Expression::Values(_) => "values",
1852            Expression::PreWhere(_) => "pre_where",
1853            Expression::Stream(_) => "stream",
1854            Expression::UsingData(_) => "using_data",
1855            Expression::XmlNamespace(_) => "xml_namespace",
1856            Expression::Insert(_) => "insert",
1857            Expression::Update(_) => "update",
1858            Expression::Delete(_) => "delete",
1859            Expression::Copy(_) => "copy",
1860            Expression::Put(_) => "put",
1861            Expression::StageReference(_) => "stage_reference",
1862            Expression::Alias(_) => "alias",
1863            Expression::Cast(_) => "cast",
1864            Expression::Collation(_) => "collation",
1865            Expression::Case(_) => "case",
1866            Expression::And(_) => "and",
1867            Expression::Or(_) => "or",
1868            Expression::Add(_) => "add",
1869            Expression::Sub(_) => "sub",
1870            Expression::Mul(_) => "mul",
1871            Expression::Div(_) => "div",
1872            Expression::Mod(_) => "mod",
1873            Expression::Eq(_) => "eq",
1874            Expression::Neq(_) => "neq",
1875            Expression::Lt(_) => "lt",
1876            Expression::Lte(_) => "lte",
1877            Expression::Gt(_) => "gt",
1878            Expression::Gte(_) => "gte",
1879            Expression::Like(_) => "like",
1880            Expression::ILike(_) => "i_like",
1881            Expression::Match(_) => "match",
1882            Expression::BitwiseAnd(_) => "bitwise_and",
1883            Expression::BitwiseOr(_) => "bitwise_or",
1884            Expression::BitwiseXor(_) => "bitwise_xor",
1885            Expression::Concat(_) => "concat",
1886            Expression::Adjacent(_) => "adjacent",
1887            Expression::TsMatch(_) => "ts_match",
1888            Expression::PropertyEQ(_) => "property_e_q",
1889            Expression::ArrayContainsAll(_) => "array_contains_all",
1890            Expression::ArrayContainedBy(_) => "array_contained_by",
1891            Expression::ArrayOverlaps(_) => "array_overlaps",
1892            Expression::JSONBContainsAllTopKeys(_) => "j_s_o_n_b_contains_all_top_keys",
1893            Expression::JSONBContainsAnyTopKeys(_) => "j_s_o_n_b_contains_any_top_keys",
1894            Expression::JSONBDeleteAtPath(_) => "j_s_o_n_b_delete_at_path",
1895            Expression::ExtendsLeft(_) => "extends_left",
1896            Expression::ExtendsRight(_) => "extends_right",
1897            Expression::Not(_) => "not",
1898            Expression::Neg(_) => "neg",
1899            Expression::BitwiseNot(_) => "bitwise_not",
1900            Expression::In(_) => "in",
1901            Expression::Between(_) => "between",
1902            Expression::IsNull(_) => "is_null",
1903            Expression::IsTrue(_) => "is_true",
1904            Expression::IsFalse(_) => "is_false",
1905            Expression::IsJson(_) => "is_json",
1906            Expression::Is(_) => "is",
1907            Expression::Exists(_) => "exists",
1908            Expression::MemberOf(_) => "member_of",
1909            Expression::Function(_) => "function",
1910            Expression::AggregateFunction(_) => "aggregate_function",
1911            Expression::WindowFunction(_) => "window_function",
1912            Expression::From(_) => "from",
1913            Expression::Join(_) => "join",
1914            Expression::JoinedTable(_) => "joined_table",
1915            Expression::Where(_) => "where",
1916            Expression::GroupBy(_) => "group_by",
1917            Expression::Having(_) => "having",
1918            Expression::OrderBy(_) => "order_by",
1919            Expression::Limit(_) => "limit",
1920            Expression::Offset(_) => "offset",
1921            Expression::Qualify(_) => "qualify",
1922            Expression::With(_) => "with",
1923            Expression::Cte(_) => "cte",
1924            Expression::DistributeBy(_) => "distribute_by",
1925            Expression::ClusterBy(_) => "cluster_by",
1926            Expression::SortBy(_) => "sort_by",
1927            Expression::LateralView(_) => "lateral_view",
1928            Expression::Hint(_) => "hint",
1929            Expression::Pseudocolumn(_) => "pseudocolumn",
1930            Expression::Connect(_) => "connect",
1931            Expression::Prior(_) => "prior",
1932            Expression::ConnectByRoot(_) => "connect_by_root",
1933            Expression::MatchRecognize(_) => "match_recognize",
1934            Expression::Ordered(_) => "ordered",
1935            Expression::Window(_) => "window",
1936            Expression::Over(_) => "over",
1937            Expression::WithinGroup(_) => "within_group",
1938            Expression::DataType(_) => "data_type",
1939            Expression::Array(_) => "array",
1940            Expression::Struct(_) => "struct",
1941            Expression::Tuple(_) => "tuple",
1942            Expression::Interval(_) => "interval",
1943            Expression::ConcatWs(_) => "concat_ws",
1944            Expression::Substring(_) => "substring",
1945            Expression::Upper(_) => "upper",
1946            Expression::Lower(_) => "lower",
1947            Expression::Length(_) => "length",
1948            Expression::Trim(_) => "trim",
1949            Expression::LTrim(_) => "l_trim",
1950            Expression::RTrim(_) => "r_trim",
1951            Expression::Replace(_) => "replace",
1952            Expression::Reverse(_) => "reverse",
1953            Expression::Left(_) => "left",
1954            Expression::Right(_) => "right",
1955            Expression::Repeat(_) => "repeat",
1956            Expression::Lpad(_) => "lpad",
1957            Expression::Rpad(_) => "rpad",
1958            Expression::Split(_) => "split",
1959            Expression::RegexpLike(_) => "regexp_like",
1960            Expression::RegexpReplace(_) => "regexp_replace",
1961            Expression::RegexpExtract(_) => "regexp_extract",
1962            Expression::Overlay(_) => "overlay",
1963            Expression::Abs(_) => "abs",
1964            Expression::Round(_) => "round",
1965            Expression::Floor(_) => "floor",
1966            Expression::Ceil(_) => "ceil",
1967            Expression::Power(_) => "power",
1968            Expression::Sqrt(_) => "sqrt",
1969            Expression::Cbrt(_) => "cbrt",
1970            Expression::Ln(_) => "ln",
1971            Expression::Log(_) => "log",
1972            Expression::Exp(_) => "exp",
1973            Expression::Sign(_) => "sign",
1974            Expression::Greatest(_) => "greatest",
1975            Expression::Least(_) => "least",
1976            Expression::CurrentDate(_) => "current_date",
1977            Expression::CurrentTime(_) => "current_time",
1978            Expression::CurrentTimestamp(_) => "current_timestamp",
1979            Expression::CurrentTimestampLTZ(_) => "current_timestamp_l_t_z",
1980            Expression::AtTimeZone(_) => "at_time_zone",
1981            Expression::DateAdd(_) => "date_add",
1982            Expression::DateSub(_) => "date_sub",
1983            Expression::DateDiff(_) => "date_diff",
1984            Expression::DateTrunc(_) => "date_trunc",
1985            Expression::Extract(_) => "extract",
1986            Expression::ToDate(_) => "to_date",
1987            Expression::ToTimestamp(_) => "to_timestamp",
1988            Expression::Date(_) => "date",
1989            Expression::Time(_) => "time",
1990            Expression::DateFromUnixDate(_) => "date_from_unix_date",
1991            Expression::UnixDate(_) => "unix_date",
1992            Expression::UnixSeconds(_) => "unix_seconds",
1993            Expression::UnixMillis(_) => "unix_millis",
1994            Expression::UnixMicros(_) => "unix_micros",
1995            Expression::UnixToTimeStr(_) => "unix_to_time_str",
1996            Expression::TimeStrToDate(_) => "time_str_to_date",
1997            Expression::DateToDi(_) => "date_to_di",
1998            Expression::DiToDate(_) => "di_to_date",
1999            Expression::TsOrDiToDi(_) => "ts_or_di_to_di",
2000            Expression::TsOrDsToDatetime(_) => "ts_or_ds_to_datetime",
2001            Expression::TsOrDsToTimestamp(_) => "ts_or_ds_to_timestamp",
2002            Expression::YearOfWeek(_) => "year_of_week",
2003            Expression::YearOfWeekIso(_) => "year_of_week_iso",
2004            Expression::Coalesce(_) => "coalesce",
2005            Expression::NullIf(_) => "null_if",
2006            Expression::IfFunc(_) => "if_func",
2007            Expression::IfNull(_) => "if_null",
2008            Expression::Nvl(_) => "nvl",
2009            Expression::Nvl2(_) => "nvl2",
2010            Expression::TryCast(_) => "try_cast",
2011            Expression::SafeCast(_) => "safe_cast",
2012            Expression::Count(_) => "count",
2013            Expression::Sum(_) => "sum",
2014            Expression::Avg(_) => "avg",
2015            Expression::Min(_) => "min",
2016            Expression::Max(_) => "max",
2017            Expression::GroupConcat(_) => "group_concat",
2018            Expression::StringAgg(_) => "string_agg",
2019            Expression::ListAgg(_) => "list_agg",
2020            Expression::ArrayAgg(_) => "array_agg",
2021            Expression::CountIf(_) => "count_if",
2022            Expression::SumIf(_) => "sum_if",
2023            Expression::Stddev(_) => "stddev",
2024            Expression::StddevPop(_) => "stddev_pop",
2025            Expression::StddevSamp(_) => "stddev_samp",
2026            Expression::Variance(_) => "variance",
2027            Expression::VarPop(_) => "var_pop",
2028            Expression::VarSamp(_) => "var_samp",
2029            Expression::Median(_) => "median",
2030            Expression::Mode(_) => "mode",
2031            Expression::First(_) => "first",
2032            Expression::Last(_) => "last",
2033            Expression::AnyValue(_) => "any_value",
2034            Expression::ApproxDistinct(_) => "approx_distinct",
2035            Expression::ApproxCountDistinct(_) => "approx_count_distinct",
2036            Expression::ApproxPercentile(_) => "approx_percentile",
2037            Expression::Percentile(_) => "percentile",
2038            Expression::LogicalAnd(_) => "logical_and",
2039            Expression::LogicalOr(_) => "logical_or",
2040            Expression::Skewness(_) => "skewness",
2041            Expression::BitwiseCount(_) => "bitwise_count",
2042            Expression::ArrayConcatAgg(_) => "array_concat_agg",
2043            Expression::ArrayUniqueAgg(_) => "array_unique_agg",
2044            Expression::BoolXorAgg(_) => "bool_xor_agg",
2045            Expression::RowNumber(_) => "row_number",
2046            Expression::Rank(_) => "rank",
2047            Expression::DenseRank(_) => "dense_rank",
2048            Expression::NTile(_) => "n_tile",
2049            Expression::Lead(_) => "lead",
2050            Expression::Lag(_) => "lag",
2051            Expression::FirstValue(_) => "first_value",
2052            Expression::LastValue(_) => "last_value",
2053            Expression::NthValue(_) => "nth_value",
2054            Expression::PercentRank(_) => "percent_rank",
2055            Expression::CumeDist(_) => "cume_dist",
2056            Expression::PercentileCont(_) => "percentile_cont",
2057            Expression::PercentileDisc(_) => "percentile_disc",
2058            Expression::Contains(_) => "contains",
2059            Expression::StartsWith(_) => "starts_with",
2060            Expression::EndsWith(_) => "ends_with",
2061            Expression::Position(_) => "position",
2062            Expression::Initcap(_) => "initcap",
2063            Expression::Ascii(_) => "ascii",
2064            Expression::Chr(_) => "chr",
2065            Expression::CharFunc(_) => "char_func",
2066            Expression::Soundex(_) => "soundex",
2067            Expression::Levenshtein(_) => "levenshtein",
2068            Expression::ByteLength(_) => "byte_length",
2069            Expression::Hex(_) => "hex",
2070            Expression::LowerHex(_) => "lower_hex",
2071            Expression::Unicode(_) => "unicode",
2072            Expression::ModFunc(_) => "mod_func",
2073            Expression::Random(_) => "random",
2074            Expression::Rand(_) => "rand",
2075            Expression::TruncFunc(_) => "trunc_func",
2076            Expression::Pi(_) => "pi",
2077            Expression::Radians(_) => "radians",
2078            Expression::Degrees(_) => "degrees",
2079            Expression::Sin(_) => "sin",
2080            Expression::Cos(_) => "cos",
2081            Expression::Tan(_) => "tan",
2082            Expression::Asin(_) => "asin",
2083            Expression::Acos(_) => "acos",
2084            Expression::Atan(_) => "atan",
2085            Expression::Atan2(_) => "atan2",
2086            Expression::IsNan(_) => "is_nan",
2087            Expression::IsInf(_) => "is_inf",
2088            Expression::IntDiv(_) => "int_div",
2089            Expression::Decode(_) => "decode",
2090            Expression::DateFormat(_) => "date_format",
2091            Expression::FormatDate(_) => "format_date",
2092            Expression::Year(_) => "year",
2093            Expression::Month(_) => "month",
2094            Expression::Day(_) => "day",
2095            Expression::Hour(_) => "hour",
2096            Expression::Minute(_) => "minute",
2097            Expression::Second(_) => "second",
2098            Expression::DayOfWeek(_) => "day_of_week",
2099            Expression::DayOfWeekIso(_) => "day_of_week_iso",
2100            Expression::DayOfMonth(_) => "day_of_month",
2101            Expression::DayOfYear(_) => "day_of_year",
2102            Expression::WeekOfYear(_) => "week_of_year",
2103            Expression::Quarter(_) => "quarter",
2104            Expression::AddMonths(_) => "add_months",
2105            Expression::MonthsBetween(_) => "months_between",
2106            Expression::LastDay(_) => "last_day",
2107            Expression::NextDay(_) => "next_day",
2108            Expression::Epoch(_) => "epoch",
2109            Expression::EpochMs(_) => "epoch_ms",
2110            Expression::FromUnixtime(_) => "from_unixtime",
2111            Expression::UnixTimestamp(_) => "unix_timestamp",
2112            Expression::MakeDate(_) => "make_date",
2113            Expression::MakeTimestamp(_) => "make_timestamp",
2114            Expression::TimestampTrunc(_) => "timestamp_trunc",
2115            Expression::TimeStrToUnix(_) => "time_str_to_unix",
2116            Expression::SessionUser(_) => "session_user",
2117            Expression::SHA(_) => "s_h_a",
2118            Expression::SHA1Digest(_) => "s_h_a1_digest",
2119            Expression::TimeToUnix(_) => "time_to_unix",
2120            Expression::ArrayFunc(_) => "array_func",
2121            Expression::ArrayLength(_) => "array_length",
2122            Expression::ArraySize(_) => "array_size",
2123            Expression::Cardinality(_) => "cardinality",
2124            Expression::ArrayContains(_) => "array_contains",
2125            Expression::ArrayPosition(_) => "array_position",
2126            Expression::ArrayAppend(_) => "array_append",
2127            Expression::ArrayPrepend(_) => "array_prepend",
2128            Expression::ArrayConcat(_) => "array_concat",
2129            Expression::ArraySort(_) => "array_sort",
2130            Expression::ArrayReverse(_) => "array_reverse",
2131            Expression::ArrayDistinct(_) => "array_distinct",
2132            Expression::ArrayJoin(_) => "array_join",
2133            Expression::ArrayToString(_) => "array_to_string",
2134            Expression::Unnest(_) => "unnest",
2135            Expression::Explode(_) => "explode",
2136            Expression::ExplodeOuter(_) => "explode_outer",
2137            Expression::ArrayFilter(_) => "array_filter",
2138            Expression::ArrayTransform(_) => "array_transform",
2139            Expression::ArrayFlatten(_) => "array_flatten",
2140            Expression::ArrayCompact(_) => "array_compact",
2141            Expression::ArrayIntersect(_) => "array_intersect",
2142            Expression::ArrayUnion(_) => "array_union",
2143            Expression::ArrayExcept(_) => "array_except",
2144            Expression::ArrayRemove(_) => "array_remove",
2145            Expression::ArrayZip(_) => "array_zip",
2146            Expression::Sequence(_) => "sequence",
2147            Expression::Generate(_) => "generate",
2148            Expression::ExplodingGenerateSeries(_) => "exploding_generate_series",
2149            Expression::ToArray(_) => "to_array",
2150            Expression::StarMap(_) => "star_map",
2151            Expression::StructFunc(_) => "struct_func",
2152            Expression::StructExtract(_) => "struct_extract",
2153            Expression::NamedStruct(_) => "named_struct",
2154            Expression::MapFunc(_) => "map_func",
2155            Expression::MapFromEntries(_) => "map_from_entries",
2156            Expression::MapFromArrays(_) => "map_from_arrays",
2157            Expression::MapKeys(_) => "map_keys",
2158            Expression::MapValues(_) => "map_values",
2159            Expression::MapContainsKey(_) => "map_contains_key",
2160            Expression::MapConcat(_) => "map_concat",
2161            Expression::ElementAt(_) => "element_at",
2162            Expression::TransformKeys(_) => "transform_keys",
2163            Expression::TransformValues(_) => "transform_values",
2164            Expression::FunctionEmits(_) => "function_emits",
2165            Expression::JsonExtract(_) => "json_extract",
2166            Expression::JsonExtractScalar(_) => "json_extract_scalar",
2167            Expression::JsonExtractPath(_) => "json_extract_path",
2168            Expression::JsonArray(_) => "json_array",
2169            Expression::JsonObject(_) => "json_object",
2170            Expression::JsonQuery(_) => "json_query",
2171            Expression::JsonValue(_) => "json_value",
2172            Expression::JsonArrayLength(_) => "json_array_length",
2173            Expression::JsonKeys(_) => "json_keys",
2174            Expression::JsonType(_) => "json_type",
2175            Expression::ParseJson(_) => "parse_json",
2176            Expression::ToJson(_) => "to_json",
2177            Expression::JsonSet(_) => "json_set",
2178            Expression::JsonInsert(_) => "json_insert",
2179            Expression::JsonRemove(_) => "json_remove",
2180            Expression::JsonMergePatch(_) => "json_merge_patch",
2181            Expression::JsonArrayAgg(_) => "json_array_agg",
2182            Expression::JsonObjectAgg(_) => "json_object_agg",
2183            Expression::Convert(_) => "convert",
2184            Expression::Typeof(_) => "typeof",
2185            Expression::Lambda(_) => "lambda",
2186            Expression::Parameter(_) => "parameter",
2187            Expression::Placeholder(_) => "placeholder",
2188            Expression::NamedArgument(_) => "named_argument",
2189            Expression::TableArgument(_) => "table_argument",
2190            Expression::SqlComment(_) => "sql_comment",
2191            Expression::NullSafeEq(_) => "null_safe_eq",
2192            Expression::NullSafeNeq(_) => "null_safe_neq",
2193            Expression::Glob(_) => "glob",
2194            Expression::SimilarTo(_) => "similar_to",
2195            Expression::Any(_) => "any",
2196            Expression::All(_) => "all",
2197            Expression::Overlaps(_) => "overlaps",
2198            Expression::BitwiseLeftShift(_) => "bitwise_left_shift",
2199            Expression::BitwiseRightShift(_) => "bitwise_right_shift",
2200            Expression::BitwiseAndAgg(_) => "bitwise_and_agg",
2201            Expression::BitwiseOrAgg(_) => "bitwise_or_agg",
2202            Expression::BitwiseXorAgg(_) => "bitwise_xor_agg",
2203            Expression::Subscript(_) => "subscript",
2204            Expression::Dot(_) => "dot",
2205            Expression::MethodCall(_) => "method_call",
2206            Expression::ArraySlice(_) => "array_slice",
2207            Expression::CreateTable(_) => "create_table",
2208            Expression::DropTable(_) => "drop_table",
2209            Expression::Undrop(_) => "undrop",
2210            Expression::AlterTable(_) => "alter_table",
2211            Expression::SplitTable(_) => "split_table",
2212            Expression::FlashbackTable(_) => "flashback_table",
2213            Expression::CreateIndex(_) => "create_index",
2214            Expression::DropIndex(_) => "drop_index",
2215            Expression::CreateView(_) => "create_view",
2216            Expression::DropView(_) => "drop_view",
2217            Expression::AlterView(_) => "alter_view",
2218            Expression::AlterIndex(_) => "alter_index",
2219            Expression::Truncate(_) => "truncate",
2220            Expression::Use(_) => "use",
2221            Expression::Cache(_) => "cache",
2222            Expression::Uncache(_) => "uncache",
2223            Expression::LoadData(_) => "load_data",
2224            Expression::Pragma(_) => "pragma",
2225            Expression::Grant(_) => "grant",
2226            Expression::Revoke(_) => "revoke",
2227            Expression::Comment(_) => "comment",
2228            Expression::SetStatement(_) => "set_statement",
2229            Expression::CreateSchema(_) => "create_schema",
2230            Expression::DropSchema(_) => "drop_schema",
2231            Expression::DropNamespace(_) => "drop_namespace",
2232            Expression::CreateDatabase(_) => "create_database",
2233            Expression::DropDatabase(_) => "drop_database",
2234            Expression::CreateFunction(_) => "create_function",
2235            Expression::DropFunction(_) => "drop_function",
2236            Expression::CreateProcedure(_) => "create_procedure",
2237            Expression::DropProcedure(_) => "drop_procedure",
2238            Expression::CreateSequence(_) => "create_sequence",
2239            Expression::CreateSynonym(_) => "create_synonym",
2240            Expression::DropSequence(_) => "drop_sequence",
2241            Expression::AlterSequence(_) => "alter_sequence",
2242            Expression::CreateTrigger(_) => "create_trigger",
2243            Expression::DropTrigger(_) => "drop_trigger",
2244            Expression::CreateType(_) => "create_type",
2245            Expression::DropType(_) => "drop_type",
2246            Expression::Describe(_) => "describe",
2247            Expression::Show(_) => "show",
2248            Expression::Command(_) => "command",
2249            Expression::TryCatch(_) => "try_catch",
2250            Expression::Kill(_) => "kill",
2251            Expression::Prepare(_) => "prepare",
2252            Expression::Execute(_) => "execute",
2253            Expression::Raw(_) => "raw",
2254            Expression::CreateTask(_) => "create_task",
2255            Expression::Paren(_) => "paren",
2256            Expression::Annotated(_) => "annotated",
2257            Expression::Refresh(_) => "refresh",
2258            Expression::LockingStatement(_) => "locking_statement",
2259            Expression::SequenceProperties(_) => "sequence_properties",
2260            Expression::TruncateTable(_) => "truncate_table",
2261            Expression::Clone(_) => "clone",
2262            Expression::Attach(_) => "attach",
2263            Expression::Detach(_) => "detach",
2264            Expression::Install(_) => "install",
2265            Expression::Summarize(_) => "summarize",
2266            Expression::Declare(_) => "declare",
2267            Expression::DeclareItem(_) => "declare_item",
2268            Expression::Set(_) => "set",
2269            Expression::Heredoc(_) => "heredoc",
2270            Expression::SetItem(_) => "set_item",
2271            Expression::QueryBand(_) => "query_band",
2272            Expression::UserDefinedFunction(_) => "user_defined_function",
2273            Expression::RecursiveWithSearch(_) => "recursive_with_search",
2274            Expression::ProjectionDef(_) => "projection_def",
2275            Expression::TableAlias(_) => "table_alias",
2276            Expression::ByteString(_) => "byte_string",
2277            Expression::HexStringExpr(_) => "hex_string_expr",
2278            Expression::UnicodeString(_) => "unicode_string",
2279            Expression::ColumnPosition(_) => "column_position",
2280            Expression::ColumnDef(_) => "column_def",
2281            Expression::AlterColumn(_) => "alter_column",
2282            Expression::AlterSortKey(_) => "alter_sort_key",
2283            Expression::AlterSet(_) => "alter_set",
2284            Expression::RenameColumn(_) => "rename_column",
2285            Expression::Comprehension(_) => "comprehension",
2286            Expression::MergeTreeTTLAction(_) => "merge_tree_t_t_l_action",
2287            Expression::MergeTreeTTL(_) => "merge_tree_t_t_l",
2288            Expression::IndexConstraintOption(_) => "index_constraint_option",
2289            Expression::ColumnConstraint(_) => "column_constraint",
2290            Expression::PeriodForSystemTimeConstraint(_) => "period_for_system_time_constraint",
2291            Expression::CaseSpecificColumnConstraint(_) => "case_specific_column_constraint",
2292            Expression::CharacterSetColumnConstraint(_) => "character_set_column_constraint",
2293            Expression::CheckColumnConstraint(_) => "check_column_constraint",
2294            Expression::AssumeColumnConstraint(_) => "assume_column_constraint",
2295            Expression::CompressColumnConstraint(_) => "compress_column_constraint",
2296            Expression::DateFormatColumnConstraint(_) => "date_format_column_constraint",
2297            Expression::EphemeralColumnConstraint(_) => "ephemeral_column_constraint",
2298            Expression::WithOperator(_) => "with_operator",
2299            Expression::GeneratedAsIdentityColumnConstraint(_) => {
2300                "generated_as_identity_column_constraint"
2301            }
2302            Expression::AutoIncrementColumnConstraint(_) => "auto_increment_column_constraint",
2303            Expression::CommentColumnConstraint(_) => "comment_column_constraint",
2304            Expression::GeneratedAsRowColumnConstraint(_) => "generated_as_row_column_constraint",
2305            Expression::IndexColumnConstraint(_) => "index_column_constraint",
2306            Expression::MaskingPolicyColumnConstraint(_) => "masking_policy_column_constraint",
2307            Expression::NotNullColumnConstraint(_) => "not_null_column_constraint",
2308            Expression::PrimaryKeyColumnConstraint(_) => "primary_key_column_constraint",
2309            Expression::UniqueColumnConstraint(_) => "unique_column_constraint",
2310            Expression::WatermarkColumnConstraint(_) => "watermark_column_constraint",
2311            Expression::ComputedColumnConstraint(_) => "computed_column_constraint",
2312            Expression::InOutColumnConstraint(_) => "in_out_column_constraint",
2313            Expression::DefaultColumnConstraint(_) => "default_column_constraint",
2314            Expression::PathColumnConstraint(_) => "path_column_constraint",
2315            Expression::Constraint(_) => "constraint",
2316            Expression::Export(_) => "export",
2317            Expression::Filter(_) => "filter",
2318            Expression::Changes(_) => "changes",
2319            Expression::CopyParameter(_) => "copy_parameter",
2320            Expression::Credentials(_) => "credentials",
2321            Expression::Directory(_) => "directory",
2322            Expression::ForeignKey(_) => "foreign_key",
2323            Expression::ColumnPrefix(_) => "column_prefix",
2324            Expression::PrimaryKey(_) => "primary_key",
2325            Expression::IntoClause(_) => "into_clause",
2326            Expression::JoinHint(_) => "join_hint",
2327            Expression::Opclass(_) => "opclass",
2328            Expression::Index(_) => "index",
2329            Expression::IndexParameters(_) => "index_parameters",
2330            Expression::ConditionalInsert(_) => "conditional_insert",
2331            Expression::MultitableInserts(_) => "multitable_inserts",
2332            Expression::OnConflict(_) => "on_conflict",
2333            Expression::OnCondition(_) => "on_condition",
2334            Expression::Returning(_) => "returning",
2335            Expression::Introducer(_) => "introducer",
2336            Expression::PartitionRange(_) => "partition_range",
2337            Expression::Fetch(_) => "fetch",
2338            Expression::Group(_) => "group",
2339            Expression::Cube(_) => "cube",
2340            Expression::Rollup(_) => "rollup",
2341            Expression::GroupingSets(_) => "grouping_sets",
2342            Expression::LimitOptions(_) => "limit_options",
2343            Expression::Lateral(_) => "lateral",
2344            Expression::TableFromRows(_) => "table_from_rows",
2345            Expression::RowsFrom(_) => "rows_from",
2346            Expression::MatchRecognizeMeasure(_) => "match_recognize_measure",
2347            Expression::WithFill(_) => "with_fill",
2348            Expression::Property(_) => "property",
2349            Expression::GrantPrivilege(_) => "grant_privilege",
2350            Expression::GrantPrincipal(_) => "grant_principal",
2351            Expression::AllowedValuesProperty(_) => "allowed_values_property",
2352            Expression::AlgorithmProperty(_) => "algorithm_property",
2353            Expression::AutoIncrementProperty(_) => "auto_increment_property",
2354            Expression::AutoRefreshProperty(_) => "auto_refresh_property",
2355            Expression::BackupProperty(_) => "backup_property",
2356            Expression::BuildProperty(_) => "build_property",
2357            Expression::BlockCompressionProperty(_) => "block_compression_property",
2358            Expression::CharacterSetProperty(_) => "character_set_property",
2359            Expression::ChecksumProperty(_) => "checksum_property",
2360            Expression::CollateProperty(_) => "collate_property",
2361            Expression::DataBlocksizeProperty(_) => "data_blocksize_property",
2362            Expression::DataDeletionProperty(_) => "data_deletion_property",
2363            Expression::DefinerProperty(_) => "definer_property",
2364            Expression::DistKeyProperty(_) => "dist_key_property",
2365            Expression::DistributedByProperty(_) => "distributed_by_property",
2366            Expression::DistStyleProperty(_) => "dist_style_property",
2367            Expression::DuplicateKeyProperty(_) => "duplicate_key_property",
2368            Expression::EngineProperty(_) => "engine_property",
2369            Expression::ToTableProperty(_) => "to_table_property",
2370            Expression::ExecuteAsProperty(_) => "execute_as_property",
2371            Expression::ExternalProperty(_) => "external_property",
2372            Expression::FallbackProperty(_) => "fallback_property",
2373            Expression::FileFormatProperty(_) => "file_format_property",
2374            Expression::CredentialsProperty(_) => "credentials_property",
2375            Expression::FreespaceProperty(_) => "freespace_property",
2376            Expression::InheritsProperty(_) => "inherits_property",
2377            Expression::InputModelProperty(_) => "input_model_property",
2378            Expression::OutputModelProperty(_) => "output_model_property",
2379            Expression::IsolatedLoadingProperty(_) => "isolated_loading_property",
2380            Expression::JournalProperty(_) => "journal_property",
2381            Expression::LanguageProperty(_) => "language_property",
2382            Expression::EnviromentProperty(_) => "enviroment_property",
2383            Expression::ClusteredByProperty(_) => "clustered_by_property",
2384            Expression::DictProperty(_) => "dict_property",
2385            Expression::DictRange(_) => "dict_range",
2386            Expression::OnCluster(_) => "on_cluster",
2387            Expression::LikeProperty(_) => "like_property",
2388            Expression::LocationProperty(_) => "location_property",
2389            Expression::LockProperty(_) => "lock_property",
2390            Expression::LockingProperty(_) => "locking_property",
2391            Expression::LogProperty(_) => "log_property",
2392            Expression::MaterializedProperty(_) => "materialized_property",
2393            Expression::MergeBlockRatioProperty(_) => "merge_block_ratio_property",
2394            Expression::OnProperty(_) => "on_property",
2395            Expression::OnCommitProperty(_) => "on_commit_property",
2396            Expression::PartitionedByProperty(_) => "partitioned_by_property",
2397            Expression::PartitionByProperty(_) => "partition_by_property",
2398            Expression::PartitionedByBucket(_) => "partitioned_by_bucket",
2399            Expression::ClusterByColumnsProperty(_) => "cluster_by_columns_property",
2400            Expression::PartitionByTruncate(_) => "partition_by_truncate",
2401            Expression::PartitionByRangeProperty(_) => "partition_by_range_property",
2402            Expression::PartitionByRangePropertyDynamic(_) => "partition_by_range_property_dynamic",
2403            Expression::PartitionByListProperty(_) => "partition_by_list_property",
2404            Expression::PartitionList(_) => "partition_list",
2405            Expression::Partition(_) => "partition",
2406            Expression::RefreshTriggerProperty(_) => "refresh_trigger_property",
2407            Expression::UniqueKeyProperty(_) => "unique_key_property",
2408            Expression::RollupProperty(_) => "rollup_property",
2409            Expression::PartitionBoundSpec(_) => "partition_bound_spec",
2410            Expression::PartitionedOfProperty(_) => "partitioned_of_property",
2411            Expression::RemoteWithConnectionModelProperty(_) => {
2412                "remote_with_connection_model_property"
2413            }
2414            Expression::ReturnsProperty(_) => "returns_property",
2415            Expression::RowFormatProperty(_) => "row_format_property",
2416            Expression::RowFormatDelimitedProperty(_) => "row_format_delimited_property",
2417            Expression::RowFormatSerdeProperty(_) => "row_format_serde_property",
2418            Expression::QueryTransform(_) => "query_transform",
2419            Expression::SampleProperty(_) => "sample_property",
2420            Expression::SecurityProperty(_) => "security_property",
2421            Expression::SchemaCommentProperty(_) => "schema_comment_property",
2422            Expression::SemanticView(_) => "semantic_view",
2423            Expression::SerdeProperties(_) => "serde_properties",
2424            Expression::SetProperty(_) => "set_property",
2425            Expression::SharingProperty(_) => "sharing_property",
2426            Expression::SetConfigProperty(_) => "set_config_property",
2427            Expression::SettingsProperty(_) => "settings_property",
2428            Expression::SortKeyProperty(_) => "sort_key_property",
2429            Expression::SqlReadWriteProperty(_) => "sql_read_write_property",
2430            Expression::SqlSecurityProperty(_) => "sql_security_property",
2431            Expression::StabilityProperty(_) => "stability_property",
2432            Expression::StorageHandlerProperty(_) => "storage_handler_property",
2433            Expression::TemporaryProperty(_) => "temporary_property",
2434            Expression::Tags(_) => "tags",
2435            Expression::TransformModelProperty(_) => "transform_model_property",
2436            Expression::TransientProperty(_) => "transient_property",
2437            Expression::UsingTemplateProperty(_) => "using_template_property",
2438            Expression::ViewAttributeProperty(_) => "view_attribute_property",
2439            Expression::VolatileProperty(_) => "volatile_property",
2440            Expression::WithDataProperty(_) => "with_data_property",
2441            Expression::WithJournalTableProperty(_) => "with_journal_table_property",
2442            Expression::WithSchemaBindingProperty(_) => "with_schema_binding_property",
2443            Expression::WithSystemVersioningProperty(_) => "with_system_versioning_property",
2444            Expression::WithProcedureOptions(_) => "with_procedure_options",
2445            Expression::EncodeProperty(_) => "encode_property",
2446            Expression::IncludeProperty(_) => "include_property",
2447            Expression::Properties(_) => "properties",
2448            Expression::OptionsProperty(_) => "options_property",
2449            Expression::InputOutputFormat(_) => "input_output_format",
2450            Expression::Reference(_) => "reference",
2451            Expression::QueryOption(_) => "query_option",
2452            Expression::WithTableHint(_) => "with_table_hint",
2453            Expression::IndexTableHint(_) => "index_table_hint",
2454            Expression::HistoricalData(_) => "historical_data",
2455            Expression::Get(_) => "get",
2456            Expression::SetOperation(_) => "set_operation",
2457            Expression::Var(_) => "var",
2458            Expression::Variadic(_) => "variadic",
2459            Expression::Version(_) => "version",
2460            Expression::Schema(_) => "schema",
2461            Expression::Lock(_) => "lock",
2462            Expression::TableSample(_) => "table_sample",
2463            Expression::Tag(_) => "tag",
2464            Expression::UnpivotColumns(_) => "unpivot_columns",
2465            Expression::WindowSpec(_) => "window_spec",
2466            Expression::SessionParameter(_) => "session_parameter",
2467            Expression::PseudoType(_) => "pseudo_type",
2468            Expression::ObjectIdentifier(_) => "object_identifier",
2469            Expression::Transaction(_) => "transaction",
2470            Expression::Commit(_) => "commit",
2471            Expression::Rollback(_) => "rollback",
2472            Expression::AlterSession(_) => "alter_session",
2473            Expression::Analyze(_) => "analyze",
2474            Expression::AnalyzeStatistics(_) => "analyze_statistics",
2475            Expression::AnalyzeHistogram(_) => "analyze_histogram",
2476            Expression::AnalyzeSample(_) => "analyze_sample",
2477            Expression::AnalyzeListChainedRows(_) => "analyze_list_chained_rows",
2478            Expression::AnalyzeDelete(_) => "analyze_delete",
2479            Expression::AnalyzeWith(_) => "analyze_with",
2480            Expression::AnalyzeValidate(_) => "analyze_validate",
2481            Expression::AddPartition(_) => "add_partition",
2482            Expression::AttachOption(_) => "attach_option",
2483            Expression::DropPartition(_) => "drop_partition",
2484            Expression::ReplacePartition(_) => "replace_partition",
2485            Expression::DPipe(_) => "d_pipe",
2486            Expression::Operator(_) => "operator",
2487            Expression::PivotAny(_) => "pivot_any",
2488            Expression::Aliases(_) => "aliases",
2489            Expression::AtIndex(_) => "at_index",
2490            Expression::FromTimeZone(_) => "from_time_zone",
2491            Expression::FormatPhrase(_) => "format_phrase",
2492            Expression::ForIn(_) => "for_in",
2493            Expression::TimeUnit(_) => "time_unit",
2494            Expression::IntervalOp(_) => "interval_op",
2495            Expression::IntervalSpan(_) => "interval_span",
2496            Expression::HavingMax(_) => "having_max",
2497            Expression::CosineDistance(_) => "cosine_distance",
2498            Expression::DotProduct(_) => "dot_product",
2499            Expression::EuclideanDistance(_) => "euclidean_distance",
2500            Expression::ManhattanDistance(_) => "manhattan_distance",
2501            Expression::JarowinklerSimilarity(_) => "jarowinkler_similarity",
2502            Expression::Booland(_) => "booland",
2503            Expression::Boolor(_) => "boolor",
2504            Expression::ParameterizedAgg(_) => "parameterized_agg",
2505            Expression::ArgMax(_) => "arg_max",
2506            Expression::ArgMin(_) => "arg_min",
2507            Expression::ApproxTopK(_) => "approx_top_k",
2508            Expression::ApproxTopKAccumulate(_) => "approx_top_k_accumulate",
2509            Expression::ApproxTopKCombine(_) => "approx_top_k_combine",
2510            Expression::ApproxTopKEstimate(_) => "approx_top_k_estimate",
2511            Expression::ApproxTopSum(_) => "approx_top_sum",
2512            Expression::ApproxQuantiles(_) => "approx_quantiles",
2513            Expression::Minhash(_) => "minhash",
2514            Expression::FarmFingerprint(_) => "farm_fingerprint",
2515            Expression::Float64(_) => "float64",
2516            Expression::Transform(_) => "transform",
2517            Expression::Translate(_) => "translate",
2518            Expression::Grouping(_) => "grouping",
2519            Expression::GroupingId(_) => "grouping_id",
2520            Expression::Anonymous(_) => "anonymous",
2521            Expression::AnonymousAggFunc(_) => "anonymous_agg_func",
2522            Expression::CombinedAggFunc(_) => "combined_agg_func",
2523            Expression::CombinedParameterizedAgg(_) => "combined_parameterized_agg",
2524            Expression::HashAgg(_) => "hash_agg",
2525            Expression::Hll(_) => "hll",
2526            Expression::Apply(_) => "apply",
2527            Expression::ToBoolean(_) => "to_boolean",
2528            Expression::List(_) => "list",
2529            Expression::ToMap(_) => "to_map",
2530            Expression::Pad(_) => "pad",
2531            Expression::ToChar(_) => "to_char",
2532            Expression::ToNumber(_) => "to_number",
2533            Expression::ToDouble(_) => "to_double",
2534            Expression::Int64(_) => "int64",
2535            Expression::StringFunc(_) => "string_func",
2536            Expression::ToDecfloat(_) => "to_decfloat",
2537            Expression::TryToDecfloat(_) => "try_to_decfloat",
2538            Expression::ToFile(_) => "to_file",
2539            Expression::Columns(_) => "columns",
2540            Expression::ConvertToCharset(_) => "convert_to_charset",
2541            Expression::ConvertTimezone(_) => "convert_timezone",
2542            Expression::GenerateSeries(_) => "generate_series",
2543            Expression::AIAgg(_) => "a_i_agg",
2544            Expression::AIClassify(_) => "a_i_classify",
2545            Expression::ArrayAll(_) => "array_all",
2546            Expression::ArrayAny(_) => "array_any",
2547            Expression::ArrayConstructCompact(_) => "array_construct_compact",
2548            Expression::StPoint(_) => "st_point",
2549            Expression::StDistance(_) => "st_distance",
2550            Expression::StringToArray(_) => "string_to_array",
2551            Expression::ArraySum(_) => "array_sum",
2552            Expression::ObjectAgg(_) => "object_agg",
2553            Expression::CastToStrType(_) => "cast_to_str_type",
2554            Expression::CheckJson(_) => "check_json",
2555            Expression::CheckXml(_) => "check_xml",
2556            Expression::TranslateCharacters(_) => "translate_characters",
2557            Expression::CurrentSchemas(_) => "current_schemas",
2558            Expression::CurrentDatetime(_) => "current_datetime",
2559            Expression::Localtime(_) => "localtime",
2560            Expression::Localtimestamp(_) => "localtimestamp",
2561            Expression::Systimestamp(_) => "systimestamp",
2562            Expression::CurrentSchema(_) => "current_schema",
2563            Expression::CurrentUser(_) => "current_user",
2564            Expression::UtcTime(_) => "utc_time",
2565            Expression::UtcTimestamp(_) => "utc_timestamp",
2566            Expression::Timestamp(_) => "timestamp",
2567            Expression::DateBin(_) => "date_bin",
2568            Expression::Datetime(_) => "datetime",
2569            Expression::DatetimeAdd(_) => "datetime_add",
2570            Expression::DatetimeSub(_) => "datetime_sub",
2571            Expression::DatetimeDiff(_) => "datetime_diff",
2572            Expression::DatetimeTrunc(_) => "datetime_trunc",
2573            Expression::Dayname(_) => "dayname",
2574            Expression::MakeInterval(_) => "make_interval",
2575            Expression::PreviousDay(_) => "previous_day",
2576            Expression::Elt(_) => "elt",
2577            Expression::TimestampAdd(_) => "timestamp_add",
2578            Expression::TimestampSub(_) => "timestamp_sub",
2579            Expression::TimestampDiff(_) => "timestamp_diff",
2580            Expression::TimeSlice(_) => "time_slice",
2581            Expression::TimeAdd(_) => "time_add",
2582            Expression::TimeSub(_) => "time_sub",
2583            Expression::TimeDiff(_) => "time_diff",
2584            Expression::TimeTrunc(_) => "time_trunc",
2585            Expression::DateFromParts(_) => "date_from_parts",
2586            Expression::TimeFromParts(_) => "time_from_parts",
2587            Expression::DecodeCase(_) => "decode_case",
2588            Expression::Decrypt(_) => "decrypt",
2589            Expression::DecryptRaw(_) => "decrypt_raw",
2590            Expression::Encode(_) => "encode",
2591            Expression::Encrypt(_) => "encrypt",
2592            Expression::EncryptRaw(_) => "encrypt_raw",
2593            Expression::EqualNull(_) => "equal_null",
2594            Expression::ToBinary(_) => "to_binary",
2595            Expression::Base64DecodeBinary(_) => "base64_decode_binary",
2596            Expression::Base64DecodeString(_) => "base64_decode_string",
2597            Expression::Base64Encode(_) => "base64_encode",
2598            Expression::TryBase64DecodeBinary(_) => "try_base64_decode_binary",
2599            Expression::TryBase64DecodeString(_) => "try_base64_decode_string",
2600            Expression::GapFill(_) => "gap_fill",
2601            Expression::GenerateDateArray(_) => "generate_date_array",
2602            Expression::GenerateTimestampArray(_) => "generate_timestamp_array",
2603            Expression::GetExtract(_) => "get_extract",
2604            Expression::Getbit(_) => "getbit",
2605            Expression::OverflowTruncateBehavior(_) => "overflow_truncate_behavior",
2606            Expression::HexEncode(_) => "hex_encode",
2607            Expression::Compress(_) => "compress",
2608            Expression::DecompressBinary(_) => "decompress_binary",
2609            Expression::DecompressString(_) => "decompress_string",
2610            Expression::Xor(_) => "xor",
2611            Expression::Nullif(_) => "nullif",
2612            Expression::JSON(_) => "j_s_o_n",
2613            Expression::JSONPath(_) => "j_s_o_n_path",
2614            Expression::JSONPathFilter(_) => "j_s_o_n_path_filter",
2615            Expression::JSONPathKey(_) => "j_s_o_n_path_key",
2616            Expression::JSONPathRecursive(_) => "j_s_o_n_path_recursive",
2617            Expression::JSONPathScript(_) => "j_s_o_n_path_script",
2618            Expression::JSONPathSlice(_) => "j_s_o_n_path_slice",
2619            Expression::JSONPathSelector(_) => "j_s_o_n_path_selector",
2620            Expression::JSONPathSubscript(_) => "j_s_o_n_path_subscript",
2621            Expression::JSONPathUnion(_) => "j_s_o_n_path_union",
2622            Expression::Format(_) => "format",
2623            Expression::JSONKeys(_) => "j_s_o_n_keys",
2624            Expression::JSONKeyValue(_) => "j_s_o_n_key_value",
2625            Expression::JSONKeysAtDepth(_) => "j_s_o_n_keys_at_depth",
2626            Expression::JSONObject(_) => "j_s_o_n_object",
2627            Expression::JSONObjectAgg(_) => "j_s_o_n_object_agg",
2628            Expression::JSONBObjectAgg(_) => "j_s_o_n_b_object_agg",
2629            Expression::JSONArray(_) => "j_s_o_n_array",
2630            Expression::JSONArrayAgg(_) => "j_s_o_n_array_agg",
2631            Expression::JSONExists(_) => "j_s_o_n_exists",
2632            Expression::JSONColumnDef(_) => "j_s_o_n_column_def",
2633            Expression::JSONSchema(_) => "j_s_o_n_schema",
2634            Expression::JSONSet(_) => "j_s_o_n_set",
2635            Expression::JSONStripNulls(_) => "j_s_o_n_strip_nulls",
2636            Expression::JSONValue(_) => "j_s_o_n_value",
2637            Expression::JSONValueArray(_) => "j_s_o_n_value_array",
2638            Expression::JSONRemove(_) => "j_s_o_n_remove",
2639            Expression::JSONTable(_) => "j_s_o_n_table",
2640            Expression::JSONType(_) => "j_s_o_n_type",
2641            Expression::ObjectInsert(_) => "object_insert",
2642            Expression::OpenJSONColumnDef(_) => "open_j_s_o_n_column_def",
2643            Expression::OpenJSON(_) => "open_j_s_o_n",
2644            Expression::JSONBExists(_) => "j_s_o_n_b_exists",
2645            Expression::JSONBContains(_) => "j_s_o_n_b_contains",
2646            Expression::JSONBExtract(_) => "j_s_o_n_b_extract",
2647            Expression::JSONCast(_) => "j_s_o_n_cast",
2648            Expression::JSONExtract(_) => "j_s_o_n_extract",
2649            Expression::JSONExtractQuote(_) => "j_s_o_n_extract_quote",
2650            Expression::JSONExtractArray(_) => "j_s_o_n_extract_array",
2651            Expression::JSONExtractScalar(_) => "j_s_o_n_extract_scalar",
2652            Expression::JSONBExtractScalar(_) => "j_s_o_n_b_extract_scalar",
2653            Expression::JSONFormat(_) => "j_s_o_n_format",
2654            Expression::JSONBool(_) => "j_s_o_n_bool",
2655            Expression::JSONPathRoot(_) => "j_s_o_n_path_root",
2656            Expression::JSONArrayAppend(_) => "j_s_o_n_array_append",
2657            Expression::JSONArrayContains(_) => "j_s_o_n_array_contains",
2658            Expression::JSONArrayInsert(_) => "j_s_o_n_array_insert",
2659            Expression::ParseJSON(_) => "parse_j_s_o_n",
2660            Expression::ParseUrl(_) => "parse_url",
2661            Expression::ParseIp(_) => "parse_ip",
2662            Expression::ParseTime(_) => "parse_time",
2663            Expression::ParseDatetime(_) => "parse_datetime",
2664            Expression::Map(_) => "map",
2665            Expression::MapCat(_) => "map_cat",
2666            Expression::MapDelete(_) => "map_delete",
2667            Expression::MapInsert(_) => "map_insert",
2668            Expression::MapPick(_) => "map_pick",
2669            Expression::ScopeResolution(_) => "scope_resolution",
2670            Expression::Slice(_) => "slice",
2671            Expression::VarMap(_) => "var_map",
2672            Expression::MatchAgainst(_) => "match_against",
2673            Expression::MD5Digest(_) => "m_d5_digest",
2674            Expression::MD5NumberLower64(_) => "m_d5_number_lower64",
2675            Expression::MD5NumberUpper64(_) => "m_d5_number_upper64",
2676            Expression::Monthname(_) => "monthname",
2677            Expression::Ntile(_) => "ntile",
2678            Expression::Normalize(_) => "normalize",
2679            Expression::Normal(_) => "normal",
2680            Expression::Predict(_) => "predict",
2681            Expression::MLTranslate(_) => "m_l_translate",
2682            Expression::FeaturesAtTime(_) => "features_at_time",
2683            Expression::GenerateEmbedding(_) => "generate_embedding",
2684            Expression::MLForecast(_) => "m_l_forecast",
2685            Expression::ModelAttribute(_) => "model_attribute",
2686            Expression::VectorSearch(_) => "vector_search",
2687            Expression::Quantile(_) => "quantile",
2688            Expression::ApproxQuantile(_) => "approx_quantile",
2689            Expression::ApproxPercentileEstimate(_) => "approx_percentile_estimate",
2690            Expression::Randn(_) => "randn",
2691            Expression::Randstr(_) => "randstr",
2692            Expression::RangeN(_) => "range_n",
2693            Expression::RangeBucket(_) => "range_bucket",
2694            Expression::ReadCSV(_) => "read_c_s_v",
2695            Expression::ReadParquet(_) => "read_parquet",
2696            Expression::Reduce(_) => "reduce",
2697            Expression::RegexpExtractAll(_) => "regexp_extract_all",
2698            Expression::RegexpILike(_) => "regexp_i_like",
2699            Expression::RegexpFullMatch(_) => "regexp_full_match",
2700            Expression::RegexpInstr(_) => "regexp_instr",
2701            Expression::RegexpSplit(_) => "regexp_split",
2702            Expression::RegexpCount(_) => "regexp_count",
2703            Expression::RegrValx(_) => "regr_valx",
2704            Expression::RegrValy(_) => "regr_valy",
2705            Expression::RegrAvgy(_) => "regr_avgy",
2706            Expression::RegrAvgx(_) => "regr_avgx",
2707            Expression::RegrCount(_) => "regr_count",
2708            Expression::RegrIntercept(_) => "regr_intercept",
2709            Expression::RegrR2(_) => "regr_r2",
2710            Expression::RegrSxx(_) => "regr_sxx",
2711            Expression::RegrSxy(_) => "regr_sxy",
2712            Expression::RegrSyy(_) => "regr_syy",
2713            Expression::RegrSlope(_) => "regr_slope",
2714            Expression::SafeAdd(_) => "safe_add",
2715            Expression::SafeDivide(_) => "safe_divide",
2716            Expression::SafeMultiply(_) => "safe_multiply",
2717            Expression::SafeSubtract(_) => "safe_subtract",
2718            Expression::SHA2(_) => "s_h_a2",
2719            Expression::SHA2Digest(_) => "s_h_a2_digest",
2720            Expression::SortArray(_) => "sort_array",
2721            Expression::SplitPart(_) => "split_part",
2722            Expression::SubstringIndex(_) => "substring_index",
2723            Expression::StandardHash(_) => "standard_hash",
2724            Expression::StrPosition(_) => "str_position",
2725            Expression::Search(_) => "search",
2726            Expression::SearchIp(_) => "search_ip",
2727            Expression::StrToDate(_) => "str_to_date",
2728            Expression::DateStrToDate(_) => "date_str_to_date",
2729            Expression::DateToDateStr(_) => "date_to_date_str",
2730            Expression::StrToTime(_) => "str_to_time",
2731            Expression::StrToUnix(_) => "str_to_unix",
2732            Expression::StrToMap(_) => "str_to_map",
2733            Expression::NumberToStr(_) => "number_to_str",
2734            Expression::FromBase(_) => "from_base",
2735            Expression::Stuff(_) => "stuff",
2736            Expression::TimeToStr(_) => "time_to_str",
2737            Expression::TimeStrToTime(_) => "time_str_to_time",
2738            Expression::TsOrDsAdd(_) => "ts_or_ds_add",
2739            Expression::TsOrDsDiff(_) => "ts_or_ds_diff",
2740            Expression::TsOrDsToDate(_) => "ts_or_ds_to_date",
2741            Expression::TsOrDsToTime(_) => "ts_or_ds_to_time",
2742            Expression::Unhex(_) => "unhex",
2743            Expression::Uniform(_) => "uniform",
2744            Expression::UnixToStr(_) => "unix_to_str",
2745            Expression::UnixToTime(_) => "unix_to_time",
2746            Expression::Uuid(_) => "uuid",
2747            Expression::TimestampFromParts(_) => "timestamp_from_parts",
2748            Expression::TimestampTzFromParts(_) => "timestamp_tz_from_parts",
2749            Expression::Corr(_) => "corr",
2750            Expression::WidthBucket(_) => "width_bucket",
2751            Expression::CovarSamp(_) => "covar_samp",
2752            Expression::CovarPop(_) => "covar_pop",
2753            Expression::Week(_) => "week",
2754            Expression::XMLElement(_) => "x_m_l_element",
2755            Expression::XMLGet(_) => "x_m_l_get",
2756            Expression::XMLTable(_) => "x_m_l_table",
2757            Expression::XMLKeyValueOption(_) => "x_m_l_key_value_option",
2758            Expression::Zipf(_) => "zipf",
2759            Expression::Merge(_) => "merge",
2760            Expression::When(_) => "when",
2761            Expression::Whens(_) => "whens",
2762            Expression::NextValueFor(_) => "next_value_for",
2763            Expression::ReturnStmt(_) => "return_stmt",
2764        }
2765    }
2766
2767    /// Returns the primary child expression (".this" in sqlglot).
2768    pub fn get_this(&self) -> Option<&Expression> {
2769        match self {
2770            // Unary ops
2771            Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this),
2772            // UnaryFunc variants
2773            Expression::Upper(f)
2774            | Expression::Lower(f)
2775            | Expression::Length(f)
2776            | Expression::LTrim(f)
2777            | Expression::RTrim(f)
2778            | Expression::Reverse(f)
2779            | Expression::Abs(f)
2780            | Expression::Sqrt(f)
2781            | Expression::Cbrt(f)
2782            | Expression::Ln(f)
2783            | Expression::Exp(f)
2784            | Expression::Sign(f)
2785            | Expression::Date(f)
2786            | Expression::Time(f)
2787            | Expression::Initcap(f)
2788            | Expression::Ascii(f)
2789            | Expression::Chr(f)
2790            | Expression::Soundex(f)
2791            | Expression::ByteLength(f)
2792            | Expression::Hex(f)
2793            | Expression::LowerHex(f)
2794            | Expression::Unicode(f)
2795            | Expression::Typeof(f)
2796            | Expression::Explode(f)
2797            | Expression::ExplodeOuter(f)
2798            | Expression::MapFromEntries(f)
2799            | Expression::MapKeys(f)
2800            | Expression::MapValues(f)
2801            | Expression::ArrayLength(f)
2802            | Expression::ArraySize(f)
2803            | Expression::Cardinality(f)
2804            | Expression::ArrayReverse(f)
2805            | Expression::ArrayDistinct(f)
2806            | Expression::ArrayFlatten(f)
2807            | Expression::ArrayCompact(f)
2808            | Expression::ToArray(f)
2809            | Expression::JsonArrayLength(f)
2810            | Expression::JsonKeys(f)
2811            | Expression::JsonType(f)
2812            | Expression::ParseJson(f)
2813            | Expression::ToJson(f)
2814            | Expression::Radians(f)
2815            | Expression::Degrees(f)
2816            | Expression::Sin(f)
2817            | Expression::Cos(f)
2818            | Expression::Tan(f)
2819            | Expression::Asin(f)
2820            | Expression::Acos(f)
2821            | Expression::Atan(f)
2822            | Expression::IsNan(f)
2823            | Expression::IsInf(f)
2824            | Expression::Year(f)
2825            | Expression::Month(f)
2826            | Expression::Day(f)
2827            | Expression::Hour(f)
2828            | Expression::Minute(f)
2829            | Expression::Second(f)
2830            | Expression::DayOfWeek(f)
2831            | Expression::DayOfWeekIso(f)
2832            | Expression::DayOfMonth(f)
2833            | Expression::DayOfYear(f)
2834            | Expression::WeekOfYear(f)
2835            | Expression::Quarter(f)
2836            | Expression::Epoch(f)
2837            | Expression::EpochMs(f)
2838            | Expression::BitwiseCount(f)
2839            | Expression::DateFromUnixDate(f)
2840            | Expression::UnixDate(f)
2841            | Expression::UnixSeconds(f)
2842            | Expression::UnixMillis(f)
2843            | Expression::UnixMicros(f)
2844            | Expression::TimeStrToDate(f)
2845            | Expression::DateToDi(f)
2846            | Expression::DiToDate(f)
2847            | Expression::TsOrDiToDi(f)
2848            | Expression::TsOrDsToDatetime(f)
2849            | Expression::TsOrDsToTimestamp(f)
2850            | Expression::YearOfWeek(f)
2851            | Expression::YearOfWeekIso(f)
2852            | Expression::SHA(f)
2853            | Expression::SHA1Digest(f)
2854            | Expression::TimeToUnix(f)
2855            | Expression::TimeStrToUnix(f)
2856            | Expression::Int64(f)
2857            | Expression::JSONBool(f)
2858            | Expression::MD5NumberLower64(f)
2859            | Expression::MD5NumberUpper64(f)
2860            | Expression::DateStrToDate(f)
2861            | Expression::DateToDateStr(f) => Some(&f.this),
2862            // BinaryFunc - this is the primary child
2863            Expression::Power(f)
2864            | Expression::NullIf(f)
2865            | Expression::IfNull(f)
2866            | Expression::Nvl(f)
2867            | Expression::Contains(f)
2868            | Expression::StartsWith(f)
2869            | Expression::EndsWith(f)
2870            | Expression::Levenshtein(f)
2871            | Expression::ModFunc(f)
2872            | Expression::IntDiv(f)
2873            | Expression::Atan2(f)
2874            | Expression::AddMonths(f)
2875            | Expression::MonthsBetween(f)
2876            | Expression::NextDay(f)
2877            | Expression::UnixToTimeStr(f)
2878            | Expression::ArrayContains(f)
2879            | Expression::ArrayPosition(f)
2880            | Expression::ArrayAppend(f)
2881            | Expression::ArrayPrepend(f)
2882            | Expression::ArrayUnion(f)
2883            | Expression::ArrayExcept(f)
2884            | Expression::ArrayRemove(f)
2885            | Expression::StarMap(f)
2886            | Expression::MapFromArrays(f)
2887            | Expression::MapContainsKey(f)
2888            | Expression::ElementAt(f)
2889            | Expression::JsonMergePatch(f)
2890            | Expression::JSONBContains(f)
2891            | Expression::JSONBExtract(f) => Some(&f.this),
2892            // AggFunc - this is the primary child
2893            Expression::Sum(af)
2894            | Expression::Avg(af)
2895            | Expression::Min(af)
2896            | Expression::Max(af)
2897            | Expression::ArrayAgg(af)
2898            | Expression::CountIf(af)
2899            | Expression::Stddev(af)
2900            | Expression::StddevPop(af)
2901            | Expression::StddevSamp(af)
2902            | Expression::Variance(af)
2903            | Expression::VarPop(af)
2904            | Expression::VarSamp(af)
2905            | Expression::Median(af)
2906            | Expression::Mode(af)
2907            | Expression::First(af)
2908            | Expression::Last(af)
2909            | Expression::AnyValue(af)
2910            | Expression::ApproxDistinct(af)
2911            | Expression::ApproxCountDistinct(af)
2912            | Expression::LogicalAnd(af)
2913            | Expression::LogicalOr(af)
2914            | Expression::Skewness(af)
2915            | Expression::ArrayConcatAgg(af)
2916            | Expression::ArrayUniqueAgg(af)
2917            | Expression::BoolXorAgg(af)
2918            | Expression::BitwiseAndAgg(af)
2919            | Expression::BitwiseOrAgg(af)
2920            | Expression::BitwiseXorAgg(af) => Some(&af.this),
2921            // Binary operations - left is "this" in sqlglot
2922            Expression::And(op)
2923            | Expression::Or(op)
2924            | Expression::Add(op)
2925            | Expression::Sub(op)
2926            | Expression::Mul(op)
2927            | Expression::Div(op)
2928            | Expression::Mod(op)
2929            | Expression::Eq(op)
2930            | Expression::Neq(op)
2931            | Expression::Lt(op)
2932            | Expression::Lte(op)
2933            | Expression::Gt(op)
2934            | Expression::Gte(op)
2935            | Expression::BitwiseAnd(op)
2936            | Expression::BitwiseOr(op)
2937            | Expression::BitwiseXor(op)
2938            | Expression::Concat(op)
2939            | Expression::Adjacent(op)
2940            | Expression::TsMatch(op)
2941            | Expression::PropertyEQ(op)
2942            | Expression::ArrayContainsAll(op)
2943            | Expression::ArrayContainedBy(op)
2944            | Expression::ArrayOverlaps(op)
2945            | Expression::JSONBContainsAllTopKeys(op)
2946            | Expression::JSONBContainsAnyTopKeys(op)
2947            | Expression::JSONBDeleteAtPath(op)
2948            | Expression::ExtendsLeft(op)
2949            | Expression::ExtendsRight(op)
2950            | Expression::Is(op)
2951            | Expression::MemberOf(op)
2952            | Expression::Match(op)
2953            | Expression::NullSafeEq(op)
2954            | Expression::NullSafeNeq(op)
2955            | Expression::Glob(op)
2956            | Expression::BitwiseLeftShift(op)
2957            | Expression::BitwiseRightShift(op) => Some(&op.left),
2958            // Like operations - left is "this"
2959            Expression::Like(op) | Expression::ILike(op) => Some(&op.left),
2960            // Structural types with .this
2961            Expression::Alias(a) => Some(&a.this),
2962            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => Some(&c.this),
2963            Expression::Paren(p) => Some(&p.this),
2964            Expression::Annotated(a) => Some(&a.this),
2965            Expression::Subquery(s) => Some(&s.this),
2966            Expression::Where(w) => Some(&w.this),
2967            Expression::Having(h) => Some(&h.this),
2968            Expression::Qualify(q) => Some(&q.this),
2969            Expression::IsNull(i) => Some(&i.this),
2970            Expression::Exists(e) => Some(&e.this),
2971            Expression::Ordered(o) => Some(&o.this),
2972            Expression::WindowFunction(wf) => Some(&wf.this),
2973            Expression::Cte(cte) => Some(&cte.this),
2974            Expression::Between(b) => Some(&b.this),
2975            Expression::In(i) => Some(&i.this),
2976            Expression::ReturnStmt(e) => Some(e),
2977            _ => None,
2978        }
2979    }
2980
2981    /// Returns the secondary child expression (".expression" in sqlglot).
2982    pub fn get_expression(&self) -> Option<&Expression> {
2983        match self {
2984            // Binary operations - right is "expression"
2985            Expression::And(op)
2986            | Expression::Or(op)
2987            | Expression::Add(op)
2988            | Expression::Sub(op)
2989            | Expression::Mul(op)
2990            | Expression::Div(op)
2991            | Expression::Mod(op)
2992            | Expression::Eq(op)
2993            | Expression::Neq(op)
2994            | Expression::Lt(op)
2995            | Expression::Lte(op)
2996            | Expression::Gt(op)
2997            | Expression::Gte(op)
2998            | Expression::BitwiseAnd(op)
2999            | Expression::BitwiseOr(op)
3000            | Expression::BitwiseXor(op)
3001            | Expression::Concat(op)
3002            | Expression::Adjacent(op)
3003            | Expression::TsMatch(op)
3004            | Expression::PropertyEQ(op)
3005            | Expression::ArrayContainsAll(op)
3006            | Expression::ArrayContainedBy(op)
3007            | Expression::ArrayOverlaps(op)
3008            | Expression::JSONBContainsAllTopKeys(op)
3009            | Expression::JSONBContainsAnyTopKeys(op)
3010            | Expression::JSONBDeleteAtPath(op)
3011            | Expression::ExtendsLeft(op)
3012            | Expression::ExtendsRight(op)
3013            | Expression::Is(op)
3014            | Expression::MemberOf(op)
3015            | Expression::Match(op)
3016            | Expression::NullSafeEq(op)
3017            | Expression::NullSafeNeq(op)
3018            | Expression::Glob(op)
3019            | Expression::BitwiseLeftShift(op)
3020            | Expression::BitwiseRightShift(op) => Some(&op.right),
3021            // Like operations - right is "expression"
3022            Expression::Like(op) | Expression::ILike(op) => Some(&op.right),
3023            // BinaryFunc - expression is the secondary
3024            Expression::Power(f)
3025            | Expression::NullIf(f)
3026            | Expression::IfNull(f)
3027            | Expression::Nvl(f)
3028            | Expression::Contains(f)
3029            | Expression::StartsWith(f)
3030            | Expression::EndsWith(f)
3031            | Expression::Levenshtein(f)
3032            | Expression::ModFunc(f)
3033            | Expression::IntDiv(f)
3034            | Expression::Atan2(f)
3035            | Expression::AddMonths(f)
3036            | Expression::MonthsBetween(f)
3037            | Expression::NextDay(f)
3038            | Expression::UnixToTimeStr(f)
3039            | Expression::ArrayContains(f)
3040            | Expression::ArrayPosition(f)
3041            | Expression::ArrayAppend(f)
3042            | Expression::ArrayPrepend(f)
3043            | Expression::ArrayUnion(f)
3044            | Expression::ArrayExcept(f)
3045            | Expression::ArrayRemove(f)
3046            | Expression::StarMap(f)
3047            | Expression::MapFromArrays(f)
3048            | Expression::MapContainsKey(f)
3049            | Expression::ElementAt(f)
3050            | Expression::JsonMergePatch(f)
3051            | Expression::JSONBContains(f)
3052            | Expression::JSONBExtract(f) => Some(&f.expression),
3053            _ => None,
3054        }
3055    }
3056
3057    /// Returns the list of child expressions (".expressions" in sqlglot).
3058    pub fn get_expressions(&self) -> &[Expression] {
3059        match self {
3060            Expression::Select(s) => &s.expressions,
3061            Expression::Function(f) => &f.args,
3062            Expression::AggregateFunction(f) => &f.args,
3063            Expression::From(f) => &f.expressions,
3064            Expression::GroupBy(g) => &g.expressions,
3065            Expression::In(i) => &i.expressions,
3066            Expression::Array(a) => &a.expressions,
3067            Expression::Tuple(t) => &t.expressions,
3068            Expression::Coalesce(f)
3069            | Expression::Greatest(f)
3070            | Expression::Least(f)
3071            | Expression::ArrayConcat(f)
3072            | Expression::ArrayIntersect(f)
3073            | Expression::ArrayZip(f)
3074            | Expression::MapConcat(f)
3075            | Expression::JsonArray(f) => &f.expressions,
3076            _ => &[],
3077        }
3078    }
3079
3080    /// Returns the name of this expression as a string slice.
3081    pub fn get_name(&self) -> &str {
3082        match self {
3083            Expression::Identifier(id) => &id.name,
3084            Expression::Column(col) => &col.name.name,
3085            Expression::Table(t) => &t.name.name,
3086            Expression::Literal(lit) => lit.value_str(),
3087            Expression::Star(_) => "*",
3088            Expression::Function(f) => &f.name,
3089            Expression::AggregateFunction(f) => &f.name,
3090            Expression::Alias(a) => a.this.get_name(),
3091            Expression::Boolean(b) => {
3092                if b.value {
3093                    "TRUE"
3094                } else {
3095                    "FALSE"
3096                }
3097            }
3098            Expression::Null(_) => "NULL",
3099            _ => "",
3100        }
3101    }
3102
3103    /// Returns the alias name if this expression has one.
3104    pub fn get_alias(&self) -> &str {
3105        match self {
3106            Expression::Alias(a) => &a.alias.name,
3107            Expression::Table(t) => t.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3108            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3109            _ => "",
3110        }
3111    }
3112
3113    /// Returns the output name of this expression (what it shows up as in a SELECT).
3114    pub fn get_output_name(&self) -> &str {
3115        match self {
3116            Expression::Alias(a) => &a.alias.name,
3117            Expression::Column(c) => &c.name.name,
3118            Expression::Identifier(id) => &id.name,
3119            Expression::Literal(lit) => lit.value_str(),
3120            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3121            Expression::Star(_) => "*",
3122            _ => "",
3123        }
3124    }
3125
3126    /// Returns comments attached to this expression.
3127    pub fn get_comments(&self) -> Vec<&str> {
3128        match self {
3129            Expression::Identifier(id) => id.trailing_comments.iter().map(|s| s.as_str()).collect(),
3130            Expression::Column(c) => c.trailing_comments.iter().map(|s| s.as_str()).collect(),
3131            Expression::Star(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3132            Expression::Paren(p) => p.trailing_comments.iter().map(|s| s.as_str()).collect(),
3133            Expression::Annotated(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3134            Expression::Alias(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3135            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
3136                c.trailing_comments.iter().map(|s| s.as_str()).collect()
3137            }
3138            Expression::And(op)
3139            | Expression::Or(op)
3140            | Expression::Add(op)
3141            | Expression::Sub(op)
3142            | Expression::Mul(op)
3143            | Expression::Div(op)
3144            | Expression::Mod(op)
3145            | Expression::Eq(op)
3146            | Expression::Neq(op)
3147            | Expression::Lt(op)
3148            | Expression::Lte(op)
3149            | Expression::Gt(op)
3150            | Expression::Gte(op)
3151            | Expression::Concat(op)
3152            | Expression::BitwiseAnd(op)
3153            | Expression::BitwiseOr(op)
3154            | Expression::BitwiseXor(op) => {
3155                op.trailing_comments.iter().map(|s| s.as_str()).collect()
3156            }
3157            Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(),
3158            Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3159            _ => Vec::new(),
3160        }
3161    }
3162}
3163
3164impl fmt::Display for Expression {
3165    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3166        // Basic display - full SQL generation is in generator module
3167        match self {
3168            Expression::Literal(lit) => write!(f, "{}", lit),
3169            Expression::Identifier(id) => write!(f, "{}", id),
3170            Expression::Column(col) => write!(f, "{}", col),
3171            Expression::Star(_) => write!(f, "*"),
3172            Expression::Null(_) => write!(f, "NULL"),
3173            Expression::Boolean(b) => write!(f, "{}", if b.value { "TRUE" } else { "FALSE" }),
3174            Expression::Select(_) => write!(f, "SELECT ..."),
3175            _ => write!(f, "{:?}", self),
3176        }
3177    }
3178}
3179
3180/// Represent a SQL literal value.
3181///
3182/// Numeric values are stored as their original text representation (not parsed
3183/// to `i64`/`f64`) so that precision, trailing zeros, and hex notation are
3184/// preserved across round-trips.
3185///
3186/// Dialect-specific literal forms (triple-quoted strings, dollar-quoted
3187/// strings, raw strings, etc.) each have a dedicated variant so that the
3188/// generator can emit them with the correct syntax.
3189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3190#[cfg_attr(feature = "bindings", derive(TS))]
3191#[serde(tag = "literal_type", content = "value", rename_all = "snake_case")]
3192pub enum Literal {
3193    /// Single-quoted string literal: `'hello'`
3194    String(String),
3195    /// Numeric literal, stored as the original text: `42`, `3.14`, `1e10`
3196    Number(String),
3197    /// Hex string literal: `X'FF'`
3198    HexString(String),
3199    /// Hex number: 0xA, 0xFF (BigQuery, SQLite style) - represents an integer in hex notation
3200    HexNumber(String),
3201    BitString(String),
3202    /// Byte string: b"..." (BigQuery style)
3203    ByteString(String),
3204    /// National string: N'abc'
3205    NationalString(String),
3206    /// DATE literal: DATE '2024-01-15'
3207    Date(String),
3208    /// TIME literal: TIME '10:30:00'
3209    Time(String),
3210    /// TIMESTAMP literal: TIMESTAMP '2024-01-15 10:30:00'
3211    Timestamp(String),
3212    /// DATETIME literal: DATETIME '2024-01-15 10:30:00' (BigQuery)
3213    Datetime(String),
3214    /// Triple-quoted string: """...""" or '''...'''
3215    /// Contains (content, quote_char) where quote_char is '"' or '\''
3216    TripleQuotedString(String, char),
3217    /// Escape string: E'...' (PostgreSQL)
3218    EscapeString(String),
3219    /// Dollar-quoted string: $$...$$  (PostgreSQL)
3220    DollarString(String),
3221    /// Raw string: r"..." or r'...' (BigQuery, Spark, Databricks)
3222    /// In raw strings, backslashes are literal and not escape characters.
3223    /// When converting to a regular string, backslashes must be doubled.
3224    RawString(String),
3225}
3226
3227impl Literal {
3228    /// Returns the inner value as a string slice, regardless of literal type.
3229    pub fn value_str(&self) -> &str {
3230        match self {
3231            Literal::String(s)
3232            | Literal::Number(s)
3233            | Literal::HexString(s)
3234            | Literal::HexNumber(s)
3235            | Literal::BitString(s)
3236            | Literal::ByteString(s)
3237            | Literal::NationalString(s)
3238            | Literal::Date(s)
3239            | Literal::Time(s)
3240            | Literal::Timestamp(s)
3241            | Literal::Datetime(s)
3242            | Literal::EscapeString(s)
3243            | Literal::DollarString(s)
3244            | Literal::RawString(s) => s.as_str(),
3245            Literal::TripleQuotedString(s, _) => s.as_str(),
3246        }
3247    }
3248
3249    /// Returns `true` if this is a string-type literal.
3250    pub fn is_string(&self) -> bool {
3251        matches!(
3252            self,
3253            Literal::String(_)
3254                | Literal::NationalString(_)
3255                | Literal::EscapeString(_)
3256                | Literal::DollarString(_)
3257                | Literal::RawString(_)
3258                | Literal::TripleQuotedString(_, _)
3259        )
3260    }
3261
3262    /// Returns `true` if this is a numeric literal.
3263    pub fn is_number(&self) -> bool {
3264        matches!(self, Literal::Number(_) | Literal::HexNumber(_))
3265    }
3266}
3267
3268impl fmt::Display for Literal {
3269    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3270        match self {
3271            Literal::String(s) => write!(f, "'{}'", s),
3272            Literal::Number(n) => write!(f, "{}", n),
3273            Literal::HexString(h) => write!(f, "X'{}'", h),
3274            Literal::HexNumber(h) => write!(f, "0x{}", h),
3275            Literal::BitString(b) => write!(f, "B'{}'", b),
3276            Literal::ByteString(b) => write!(f, "b'{}'", b),
3277            Literal::NationalString(s) => write!(f, "N'{}'", s),
3278            Literal::Date(d) => write!(f, "DATE '{}'", d),
3279            Literal::Time(t) => write!(f, "TIME '{}'", t),
3280            Literal::Timestamp(ts) => write!(f, "TIMESTAMP '{}'", ts),
3281            Literal::Datetime(dt) => write!(f, "DATETIME '{}'", dt),
3282            Literal::TripleQuotedString(s, q) => {
3283                write!(f, "{0}{0}{0}{1}{0}{0}{0}", q, s)
3284            }
3285            Literal::EscapeString(s) => write!(f, "E'{}'", s),
3286            Literal::DollarString(s) => write!(f, "$${}$$", s),
3287            Literal::RawString(s) => write!(f, "r'{}'", s),
3288        }
3289    }
3290}
3291
3292/// Boolean literal
3293#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3294#[cfg_attr(feature = "bindings", derive(TS))]
3295pub struct BooleanLiteral {
3296    pub value: bool,
3297}
3298
3299/// NULL literal
3300#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3301#[cfg_attr(feature = "bindings", derive(TS))]
3302pub struct Null;
3303
3304/// Represent a SQL identifier (table name, column name, alias, keyword-as-name, etc.).
3305///
3306/// The `quoted` flag indicates whether the identifier was originally delimited
3307/// (double-quoted, backtick-quoted, or bracket-quoted depending on the
3308/// dialect). The generator uses this flag to decide whether to emit quoting
3309/// characters.
3310#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3311#[cfg_attr(feature = "bindings", derive(TS))]
3312pub struct Identifier {
3313    /// The raw text of the identifier, without any quoting characters.
3314    pub name: String,
3315    /// Whether the identifier was quoted in the source SQL.
3316    pub quoted: bool,
3317    #[serde(default)]
3318    pub trailing_comments: Vec<String>,
3319    /// Source position span (populated during parsing, None for programmatically constructed nodes)
3320    #[serde(default, skip_serializing_if = "Option::is_none")]
3321    pub span: Option<Span>,
3322}
3323
3324impl Identifier {
3325    pub fn new(name: impl Into<String>) -> Self {
3326        Self {
3327            name: name.into(),
3328            quoted: false,
3329            trailing_comments: Vec::new(),
3330            span: None,
3331        }
3332    }
3333
3334    pub fn quoted(name: impl Into<String>) -> Self {
3335        Self {
3336            name: name.into(),
3337            quoted: true,
3338            trailing_comments: Vec::new(),
3339            span: None,
3340        }
3341    }
3342
3343    pub fn empty() -> Self {
3344        Self {
3345            name: String::new(),
3346            quoted: false,
3347            trailing_comments: Vec::new(),
3348            span: None,
3349        }
3350    }
3351
3352    pub fn is_empty(&self) -> bool {
3353        self.name.is_empty()
3354    }
3355
3356    /// Set the source span on this identifier
3357    pub fn with_span(mut self, span: Span) -> Self {
3358        self.span = Some(span);
3359        self
3360    }
3361}
3362
3363impl fmt::Display for Identifier {
3364    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3365        if self.quoted {
3366            write!(f, "\"{}\"", self.name)
3367        } else {
3368            write!(f, "{}", self.name)
3369        }
3370    }
3371}
3372
3373/// Represent a column reference, optionally qualified by a table name.
3374///
3375/// Renders as `name` when unqualified, or `table.name` when qualified.
3376/// Use [`Expression::column()`] or [`Expression::qualified_column()`] for
3377/// convenient construction.
3378#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3379#[cfg_attr(feature = "bindings", derive(TS))]
3380pub struct Column {
3381    /// The column name.
3382    pub name: Identifier,
3383    /// Optional table qualifier (e.g. `t` in `t.col`).
3384    pub table: Option<Identifier>,
3385    /// Oracle-style join marker (+) for outer joins
3386    #[serde(default)]
3387    pub join_mark: bool,
3388    /// Trailing comments that appeared after this column reference
3389    #[serde(default)]
3390    pub trailing_comments: Vec<String>,
3391    /// Source position span
3392    #[serde(default, skip_serializing_if = "Option::is_none")]
3393    pub span: Option<Span>,
3394    /// Inferred data type from type annotation
3395    #[serde(default, skip_serializing_if = "Option::is_none")]
3396    #[ast(skip)]
3397    pub inferred_type: Option<DataType>,
3398}
3399
3400impl fmt::Display for Column {
3401    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3402        if let Some(table) = &self.table {
3403            write!(f, "{}.{}", table, self.name)
3404        } else {
3405            write!(f, "{}", self.name)
3406        }
3407    }
3408}
3409
3410/// Represent a table reference with optional schema and catalog qualifiers.
3411///
3412/// Renders as `name`, `schema.name`, or `catalog.schema.name` depending on
3413/// which qualifiers are present. Supports aliases, column alias lists,
3414/// time-travel clauses (Snowflake, BigQuery), table hints (TSQL), and
3415/// several other dialect-specific extensions.
3416#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3417#[cfg_attr(feature = "bindings", derive(TS))]
3418pub struct TableRef {
3419    /// The unqualified table name.
3420    pub name: Identifier,
3421    /// Optional schema qualifier (e.g. `public` in `public.users`).
3422    pub schema: Option<Identifier>,
3423    /// Optional catalog qualifier (e.g. `mydb` in `mydb.public.users`).
3424    pub catalog: Option<Identifier>,
3425    /// Optional table alias (e.g. `t` in `FROM users AS t`).
3426    pub alias: Option<Identifier>,
3427    /// Whether AS keyword was explicitly used for the alias
3428    #[serde(default)]
3429    pub alias_explicit_as: bool,
3430    /// Column aliases for table alias: AS t(c1, c2)
3431    #[serde(default)]
3432    pub column_aliases: Vec<Identifier>,
3433    /// Leading comments that appeared before this table reference in a FROM clause
3434    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3435    pub leading_comments: Vec<String>,
3436    /// Trailing comments that appeared after this table reference
3437    #[serde(default)]
3438    pub trailing_comments: Vec<String>,
3439    /// Snowflake time travel: BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
3440    #[serde(default)]
3441    pub when: Option<Box<HistoricalData>>,
3442    /// PostgreSQL ONLY modifier: prevents scanning child tables in inheritance hierarchy
3443    #[serde(default)]
3444    pub only: bool,
3445    /// ClickHouse FINAL modifier: forces final aggregation for MergeTree tables
3446    #[serde(default)]
3447    pub final_: bool,
3448    /// TABLESAMPLE clause attached to this table reference (DuckDB, BigQuery)
3449    #[serde(default, skip_serializing_if = "Option::is_none")]
3450    pub table_sample: Option<Box<Sample>>,
3451    /// TSQL table hints: WITH (TABLOCK, INDEX(myindex), ...)
3452    #[serde(default)]
3453    pub hints: Vec<Expression>,
3454    /// TSQL: FOR SYSTEM_TIME temporal clause
3455    /// Contains the full clause text, e.g., "FOR SYSTEM_TIME BETWEEN c AND d"
3456    #[serde(default, skip_serializing_if = "Option::is_none")]
3457    pub system_time: Option<String>,
3458    /// MySQL: PARTITION(p0, p1, ...) hint for reading from specific partitions
3459    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3460    pub partitions: Vec<Identifier>,
3461    /// Snowflake IDENTIFIER() function: dynamic table name from string/variable
3462    /// When set, this is used instead of the name field
3463    #[serde(default, skip_serializing_if = "Option::is_none")]
3464    pub identifier_func: Option<Box<Expression>>,
3465    /// Snowflake CHANGES clause: CHANGES (INFORMATION => ...) AT (...) END (...)
3466    #[serde(default, skip_serializing_if = "Option::is_none")]
3467    pub changes: Option<Box<Changes>>,
3468    /// Time travel version clause: FOR VERSION AS OF / FOR TIMESTAMP AS OF (Presto/Trino, BigQuery, Databricks)
3469    #[serde(default, skip_serializing_if = "Option::is_none")]
3470    pub version: Option<Box<Version>>,
3471    /// Source position span
3472    #[serde(default, skip_serializing_if = "Option::is_none")]
3473    pub span: Option<Span>,
3474}
3475
3476impl TableRef {
3477    pub fn new(name: impl Into<String>) -> Self {
3478        Self {
3479            name: Identifier::new(name),
3480            schema: None,
3481            catalog: None,
3482            alias: None,
3483            alias_explicit_as: false,
3484            column_aliases: Vec::new(),
3485            leading_comments: Vec::new(),
3486            trailing_comments: Vec::new(),
3487            when: None,
3488            only: false,
3489            final_: false,
3490            table_sample: None,
3491            hints: Vec::new(),
3492            system_time: None,
3493            partitions: Vec::new(),
3494            identifier_func: None,
3495            changes: None,
3496            version: None,
3497            span: None,
3498        }
3499    }
3500
3501    /// Create with a schema qualifier.
3502    pub fn new_with_schema(name: impl Into<String>, schema: impl Into<String>) -> Self {
3503        let mut t = Self::new(name);
3504        t.schema = Some(Identifier::new(schema));
3505        t
3506    }
3507
3508    /// Create with catalog and schema qualifiers.
3509    pub fn new_with_catalog(
3510        name: impl Into<String>,
3511        schema: impl Into<String>,
3512        catalog: impl Into<String>,
3513    ) -> Self {
3514        let mut t = Self::new(name);
3515        t.schema = Some(Identifier::new(schema));
3516        t.catalog = Some(Identifier::new(catalog));
3517        t
3518    }
3519
3520    /// Create from an Identifier, preserving the quoted flag
3521    pub fn from_identifier(name: Identifier) -> Self {
3522        Self {
3523            name,
3524            schema: None,
3525            catalog: None,
3526            alias: None,
3527            alias_explicit_as: false,
3528            column_aliases: Vec::new(),
3529            leading_comments: Vec::new(),
3530            trailing_comments: Vec::new(),
3531            when: None,
3532            only: false,
3533            final_: false,
3534            table_sample: None,
3535            hints: Vec::new(),
3536            system_time: None,
3537            partitions: Vec::new(),
3538            identifier_func: None,
3539            changes: None,
3540            version: None,
3541            span: None,
3542        }
3543    }
3544
3545    pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
3546        self.alias = Some(Identifier::new(alias));
3547        self
3548    }
3549
3550    pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
3551        self.schema = Some(Identifier::new(schema));
3552        self
3553    }
3554}
3555
3556/// Represent a wildcard star expression (`*`, `table.*`).
3557///
3558/// Supports the EXCEPT/EXCLUDE, REPLACE, and RENAME modifiers found in
3559/// DuckDB, BigQuery, and Snowflake (e.g. `SELECT * EXCEPT (id) FROM t`).
3560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3561#[cfg_attr(feature = "bindings", derive(TS))]
3562pub struct Star {
3563    /// Optional table qualifier (e.g. `t` in `t.*`).
3564    pub table: Option<Identifier>,
3565    /// EXCLUDE / EXCEPT columns (DuckDB, BigQuery, Snowflake)
3566    pub except: Option<Vec<Identifier>>,
3567    /// REPLACE expressions (BigQuery, Snowflake)
3568    pub replace: Option<Vec<Alias>>,
3569    /// RENAME columns (Snowflake)
3570    pub rename: Option<Vec<(Identifier, Identifier)>>,
3571    /// Trailing comments that appeared after the star
3572    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3573    pub trailing_comments: Vec<String>,
3574    /// Source position span
3575    #[serde(default, skip_serializing_if = "Option::is_none")]
3576    pub span: Option<Span>,
3577}
3578
3579/// Represent a complete SELECT statement.
3580///
3581/// This is the most feature-rich AST node, covering the full surface area of
3582/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3583/// `Vec` are omitted from the generated SQL when absent.
3584///
3585/// # Key Fields
3586///
3587/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3588/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3589/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3590/// - `where_clause` -- the WHERE predicate.
3591/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3592/// - `having` -- HAVING predicate.
3593/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3594/// - `limit` / `offset` / `fetch` -- result set limiting.
3595/// - `with` -- Common Table Expressions (CTEs).
3596/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3597/// - `windows` -- named window definitions (WINDOW w AS ...).
3598///
3599/// Dialect-specific extensions are supported via fields like `prewhere`
3600/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3601/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3602#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3603#[cfg_attr(feature = "bindings", derive(TS))]
3604pub struct Select {
3605    /// The select-list: columns, expressions, aliases, and wildcards.
3606    pub expressions: Vec<Expression>,
3607    /// The FROM clause, containing one or more table sources.
3608    pub from: Option<From>,
3609    /// JOIN clauses applied after the FROM source.
3610    pub joins: Vec<Join>,
3611    pub lateral_views: Vec<LateralView>,
3612    /// ClickHouse PREWHERE clause
3613    #[serde(default, skip_serializing_if = "Option::is_none")]
3614    pub prewhere: Option<Expression>,
3615    pub where_clause: Option<Where>,
3616    pub group_by: Option<GroupBy>,
3617    pub having: Option<Having>,
3618    pub qualify: Option<Qualify>,
3619    pub order_by: Option<OrderBy>,
3620    pub distribute_by: Option<DistributeBy>,
3621    pub cluster_by: Option<ClusterBy>,
3622    pub sort_by: Option<SortBy>,
3623    pub limit: Option<Limit>,
3624    pub offset: Option<Offset>,
3625    /// ClickHouse LIMIT BY clause expressions
3626    #[serde(default, skip_serializing_if = "Option::is_none")]
3627    pub limit_by: Option<Vec<Expression>>,
3628    pub fetch: Option<Fetch>,
3629    pub distinct: bool,
3630    pub distinct_on: Option<Vec<Expression>>,
3631    pub top: Option<Top>,
3632    pub with: Option<With>,
3633    pub sample: Option<Sample>,
3634    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3635    #[serde(default, skip_serializing_if = "Option::is_none")]
3636    pub settings: Option<Vec<Expression>>,
3637    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3638    #[serde(default, skip_serializing_if = "Option::is_none")]
3639    pub format: Option<Expression>,
3640    pub windows: Option<Vec<NamedWindow>>,
3641    pub hint: Option<Hint>,
3642    /// Oracle CONNECT BY clause for hierarchical queries
3643    pub connect: Option<Connect>,
3644    /// SELECT ... INTO table_name for creating tables
3645    pub into: Option<SelectInto>,
3646    /// FOR UPDATE/SHARE locking clauses
3647    #[serde(default)]
3648    pub locks: Vec<Lock>,
3649    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3650    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3651    pub for_xml: Vec<Expression>,
3652    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3653    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3654    pub for_json: Vec<Expression>,
3655    /// Leading comments before the statement
3656    #[serde(default)]
3657    pub leading_comments: Vec<String>,
3658    /// Comments that appear after SELECT keyword (before expressions)
3659    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3660    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3661    pub post_select_comments: Vec<String>,
3662    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3663    #[serde(default, skip_serializing_if = "Option::is_none")]
3664    pub kind: Option<String>,
3665    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3666    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3667    pub operation_modifiers: Vec<String>,
3668    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3669    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3670    pub qualify_after_window: bool,
3671    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3672    #[serde(default, skip_serializing_if = "Option::is_none")]
3673    pub option: Option<String>,
3674    /// Redshift-style EXCLUDE clause at the end of the projection list
3675    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3676    #[serde(default, skip_serializing_if = "Option::is_none")]
3677    pub exclude: Option<Vec<Expression>>,
3678}
3679
3680impl Select {
3681    pub fn new() -> Self {
3682        Self {
3683            expressions: Vec::new(),
3684            from: None,
3685            joins: Vec::new(),
3686            lateral_views: Vec::new(),
3687            prewhere: None,
3688            where_clause: None,
3689            group_by: None,
3690            having: None,
3691            qualify: None,
3692            order_by: None,
3693            distribute_by: None,
3694            cluster_by: None,
3695            sort_by: None,
3696            limit: None,
3697            offset: None,
3698            limit_by: None,
3699            fetch: None,
3700            distinct: false,
3701            distinct_on: None,
3702            top: None,
3703            with: None,
3704            sample: None,
3705            settings: None,
3706            format: None,
3707            windows: None,
3708            hint: None,
3709            connect: None,
3710            into: None,
3711            locks: Vec::new(),
3712            for_xml: Vec::new(),
3713            for_json: Vec::new(),
3714            leading_comments: Vec::new(),
3715            post_select_comments: Vec::new(),
3716            kind: None,
3717            operation_modifiers: Vec::new(),
3718            qualify_after_window: false,
3719            option: None,
3720            exclude: None,
3721        }
3722    }
3723
3724    /// Add a column to select
3725    pub fn column(mut self, expr: Expression) -> Self {
3726        self.expressions.push(expr);
3727        self
3728    }
3729
3730    /// Set the FROM clause
3731    pub fn from(mut self, table: Expression) -> Self {
3732        self.from = Some(From {
3733            expressions: vec![table],
3734        });
3735        self
3736    }
3737
3738    /// Add a WHERE clause
3739    pub fn where_(mut self, condition: Expression) -> Self {
3740        self.where_clause = Some(Where { this: condition });
3741        self
3742    }
3743
3744    /// Set DISTINCT
3745    pub fn distinct(mut self) -> Self {
3746        self.distinct = true;
3747        self
3748    }
3749
3750    /// Add a JOIN
3751    pub fn join(mut self, join: Join) -> Self {
3752        self.joins.push(join);
3753        self
3754    }
3755
3756    /// Set ORDER BY
3757    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
3758        self.order_by = Some(OrderBy {
3759            expressions,
3760            siblings: false,
3761            comments: Vec::new(),
3762        });
3763        self
3764    }
3765
3766    /// Set LIMIT
3767    pub fn limit(mut self, n: Expression) -> Self {
3768        self.limit = Some(Limit {
3769            this: n,
3770            percent: false,
3771            comments: Vec::new(),
3772        });
3773        self
3774    }
3775
3776    /// Set OFFSET
3777    pub fn offset(mut self, n: Expression) -> Self {
3778        self.offset = Some(Offset {
3779            this: n,
3780            rows: None,
3781        });
3782        self
3783    }
3784}
3785
3786impl Default for Select {
3787    fn default() -> Self {
3788        Self::new()
3789    }
3790}
3791
3792/// Represent a UNION set operation between two query expressions.
3793///
3794/// When `all` is true, duplicate rows are preserved (UNION ALL).
3795/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
3796/// Supports DuckDB/Snowflake BY NAME and BigQuery BY NAME/CORRESPONDING modifiers.
3797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3798#[cfg_attr(feature = "bindings", derive(TS))]
3799pub struct Union {
3800    /// The left-hand query operand.
3801    pub left: Expression,
3802    /// The right-hand query operand.
3803    pub right: Expression,
3804    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
3805    pub all: bool,
3806    /// Whether DISTINCT was explicitly specified
3807    #[serde(default)]
3808    pub distinct: bool,
3809    /// Optional WITH clause
3810    pub with: Option<With>,
3811    /// ORDER BY applied to entire UNION result
3812    pub order_by: Option<OrderBy>,
3813    /// LIMIT applied to entire UNION result
3814    pub limit: Option<Box<Expression>>,
3815    /// OFFSET applied to entire UNION result
3816    pub offset: Option<Box<Expression>>,
3817    /// DISTRIBUTE BY clause (Hive/Spark)
3818    #[serde(default, skip_serializing_if = "Option::is_none")]
3819    pub distribute_by: Option<DistributeBy>,
3820    /// SORT BY clause (Hive/Spark)
3821    #[serde(default, skip_serializing_if = "Option::is_none")]
3822    pub sort_by: Option<SortBy>,
3823    /// CLUSTER BY clause (Hive/Spark)
3824    #[serde(default, skip_serializing_if = "Option::is_none")]
3825    pub cluster_by: Option<ClusterBy>,
3826    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3827    #[serde(default)]
3828    pub by_name: bool,
3829    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3830    #[serde(default, skip_serializing_if = "Option::is_none")]
3831    pub side: Option<String>,
3832    /// BigQuery: Set operation kind (INNER)
3833    #[serde(default, skip_serializing_if = "Option::is_none")]
3834    pub kind: Option<String>,
3835    /// BigQuery: CORRESPONDING modifier
3836    #[serde(default)]
3837    pub corresponding: bool,
3838    /// BigQuery: STRICT modifier (before CORRESPONDING)
3839    #[serde(default)]
3840    pub strict: bool,
3841    /// BigQuery: BY (columns) after CORRESPONDING
3842    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3843    pub on_columns: Vec<Expression>,
3844}
3845
3846/// Iteratively flatten the left-recursive chain to prevent stack overflow
3847/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3848impl Drop for Union {
3849    fn drop(&mut self) {
3850        loop {
3851            if let Expression::Union(ref mut inner) = self.left {
3852                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3853                let old_left = std::mem::replace(&mut self.left, next_left);
3854                drop(old_left);
3855            } else {
3856                break;
3857            }
3858        }
3859    }
3860}
3861
3862/// Represent an INTERSECT set operation between two query expressions.
3863///
3864/// Returns only rows that appear in both operands. When `all` is true,
3865/// duplicates are preserved according to their multiplicity.
3866#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3867#[cfg_attr(feature = "bindings", derive(TS))]
3868pub struct Intersect {
3869    /// The left-hand query operand.
3870    pub left: Expression,
3871    /// The right-hand query operand.
3872    pub right: Expression,
3873    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
3874    pub all: bool,
3875    /// Whether DISTINCT was explicitly specified
3876    #[serde(default)]
3877    pub distinct: bool,
3878    /// Optional WITH clause
3879    pub with: Option<With>,
3880    /// ORDER BY applied to entire INTERSECT result
3881    pub order_by: Option<OrderBy>,
3882    /// LIMIT applied to entire INTERSECT result
3883    pub limit: Option<Box<Expression>>,
3884    /// OFFSET applied to entire INTERSECT result
3885    pub offset: Option<Box<Expression>>,
3886    /// DISTRIBUTE BY clause (Hive/Spark)
3887    #[serde(default, skip_serializing_if = "Option::is_none")]
3888    pub distribute_by: Option<DistributeBy>,
3889    /// SORT BY clause (Hive/Spark)
3890    #[serde(default, skip_serializing_if = "Option::is_none")]
3891    pub sort_by: Option<SortBy>,
3892    /// CLUSTER BY clause (Hive/Spark)
3893    #[serde(default, skip_serializing_if = "Option::is_none")]
3894    pub cluster_by: Option<ClusterBy>,
3895    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3896    #[serde(default)]
3897    pub by_name: bool,
3898    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3899    #[serde(default, skip_serializing_if = "Option::is_none")]
3900    pub side: Option<String>,
3901    /// BigQuery: Set operation kind (INNER)
3902    #[serde(default, skip_serializing_if = "Option::is_none")]
3903    pub kind: Option<String>,
3904    /// BigQuery: CORRESPONDING modifier
3905    #[serde(default)]
3906    pub corresponding: bool,
3907    /// BigQuery: STRICT modifier (before CORRESPONDING)
3908    #[serde(default)]
3909    pub strict: bool,
3910    /// BigQuery: BY (columns) after CORRESPONDING
3911    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3912    pub on_columns: Vec<Expression>,
3913}
3914
3915impl Drop for Intersect {
3916    fn drop(&mut self) {
3917        loop {
3918            if let Expression::Intersect(ref mut inner) = self.left {
3919                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3920                let old_left = std::mem::replace(&mut self.left, next_left);
3921                drop(old_left);
3922            } else {
3923                break;
3924            }
3925        }
3926    }
3927}
3928
3929/// Represent an EXCEPT (MINUS) set operation between two query expressions.
3930///
3931/// Returns rows from the left operand that do not appear in the right operand.
3932/// When `all` is true, duplicates are subtracted according to their multiplicity.
3933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3934#[cfg_attr(feature = "bindings", derive(TS))]
3935pub struct Except {
3936    /// The left-hand query operand.
3937    pub left: Expression,
3938    /// The right-hand query operand (rows to subtract).
3939    pub right: Expression,
3940    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
3941    pub all: bool,
3942    /// Whether DISTINCT was explicitly specified
3943    #[serde(default)]
3944    pub distinct: bool,
3945    /// Optional WITH clause
3946    pub with: Option<With>,
3947    /// ORDER BY applied to entire EXCEPT result
3948    pub order_by: Option<OrderBy>,
3949    /// LIMIT applied to entire EXCEPT result
3950    pub limit: Option<Box<Expression>>,
3951    /// OFFSET applied to entire EXCEPT result
3952    pub offset: Option<Box<Expression>>,
3953    /// DISTRIBUTE BY clause (Hive/Spark)
3954    #[serde(default, skip_serializing_if = "Option::is_none")]
3955    pub distribute_by: Option<DistributeBy>,
3956    /// SORT BY clause (Hive/Spark)
3957    #[serde(default, skip_serializing_if = "Option::is_none")]
3958    pub sort_by: Option<SortBy>,
3959    /// CLUSTER BY clause (Hive/Spark)
3960    #[serde(default, skip_serializing_if = "Option::is_none")]
3961    pub cluster_by: Option<ClusterBy>,
3962    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3963    #[serde(default)]
3964    pub by_name: bool,
3965    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3966    #[serde(default, skip_serializing_if = "Option::is_none")]
3967    pub side: Option<String>,
3968    /// BigQuery: Set operation kind (INNER)
3969    #[serde(default, skip_serializing_if = "Option::is_none")]
3970    pub kind: Option<String>,
3971    /// BigQuery: CORRESPONDING modifier
3972    #[serde(default)]
3973    pub corresponding: bool,
3974    /// BigQuery: STRICT modifier (before CORRESPONDING)
3975    #[serde(default)]
3976    pub strict: bool,
3977    /// BigQuery: BY (columns) after CORRESPONDING
3978    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3979    pub on_columns: Vec<Expression>,
3980}
3981
3982impl Drop for Except {
3983    fn drop(&mut self) {
3984        loop {
3985            if let Expression::Except(ref mut inner) = self.left {
3986                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3987                let old_left = std::mem::replace(&mut self.left, next_left);
3988                drop(old_left);
3989            } else {
3990                break;
3991            }
3992        }
3993    }
3994}
3995
3996/// INTO clause for SELECT INTO statements
3997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3998#[cfg_attr(feature = "bindings", derive(TS))]
3999pub struct SelectInto {
4000    /// Target table or variable (used when single target)
4001    pub this: Expression,
4002    /// Whether TEMPORARY keyword was used
4003    #[serde(default)]
4004    pub temporary: bool,
4005    /// Whether UNLOGGED keyword was used (PostgreSQL)
4006    #[serde(default)]
4007    pub unlogged: bool,
4008    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4009    #[serde(default)]
4010    pub bulk_collect: bool,
4011    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4012    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4013    pub expressions: Vec<Expression>,
4014}
4015
4016/// Represent a parenthesized subquery expression.
4017///
4018/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4019/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4020/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4021/// modifiers are rendered inside or outside the parentheses.
4022///
4023/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4024/// scalar subqueries in select-lists, and derived tables.
4025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4026#[cfg_attr(feature = "bindings", derive(TS))]
4027pub struct Subquery {
4028    /// The inner query expression.
4029    pub this: Expression,
4030    /// Optional alias for the derived table.
4031    pub alias: Option<Identifier>,
4032    /// Optional column aliases: AS t(c1, c2)
4033    pub column_aliases: Vec<Identifier>,
4034    /// Whether AS keyword was explicitly used for the alias.
4035    #[serde(default)]
4036    pub alias_explicit_as: bool,
4037    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4038    #[serde(skip_serializing_if = "Option::is_none", default)]
4039    pub alias_keyword: Option<String>,
4040    /// ORDER BY clause (for parenthesized queries)
4041    pub order_by: Option<OrderBy>,
4042    /// LIMIT clause
4043    pub limit: Option<Limit>,
4044    /// OFFSET clause
4045    pub offset: Option<Offset>,
4046    /// DISTRIBUTE BY clause (Hive/Spark)
4047    #[serde(default, skip_serializing_if = "Option::is_none")]
4048    pub distribute_by: Option<DistributeBy>,
4049    /// SORT BY clause (Hive/Spark)
4050    #[serde(default, skip_serializing_if = "Option::is_none")]
4051    pub sort_by: Option<SortBy>,
4052    /// CLUSTER BY clause (Hive/Spark)
4053    #[serde(default, skip_serializing_if = "Option::is_none")]
4054    pub cluster_by: Option<ClusterBy>,
4055    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4056    #[serde(default)]
4057    pub lateral: bool,
4058    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4059    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4060    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4061    #[serde(default)]
4062    pub modifiers_inside: bool,
4063    /// Trailing comments after the closing paren
4064    #[serde(default)]
4065    pub trailing_comments: Vec<String>,
4066    /// Inferred data type from type annotation
4067    #[serde(default, skip_serializing_if = "Option::is_none")]
4068    #[ast(skip)]
4069    pub inferred_type: Option<DataType>,
4070}
4071
4072/// Pipe operator expression: query |> transform
4073///
4074/// Used in DataFusion and BigQuery pipe syntax:
4075///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4077#[cfg_attr(feature = "bindings", derive(TS))]
4078pub struct PipeOperator {
4079    /// The input query/expression (left side of |>)
4080    pub this: Expression,
4081    /// The piped operation (right side of |>)
4082    pub expression: Expression,
4083}
4084
4085/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4087#[cfg_attr(feature = "bindings", derive(TS))]
4088pub struct Values {
4089    /// The rows of values
4090    pub expressions: Vec<Tuple>,
4091    /// Optional alias for the table
4092    pub alias: Option<Identifier>,
4093    /// Optional column aliases: AS t(c1, c2)
4094    pub column_aliases: Vec<Identifier>,
4095}
4096
4097/// PIVOT operation - supports both standard and DuckDB simplified syntax
4098///
4099/// Standard syntax (in FROM clause):
4100///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4101///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4102///
4103/// DuckDB simplified syntax (statement-level):
4104///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4105///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4106#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4107#[cfg_attr(feature = "bindings", derive(TS))]
4108pub struct Pivot {
4109    /// Source table/expression
4110    pub this: Expression,
4111    /// For standard PIVOT: the aggregation function(s) (first is primary)
4112    /// For DuckDB simplified: unused (use `using` instead)
4113    #[serde(default)]
4114    pub expressions: Vec<Expression>,
4115    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4116    #[serde(default)]
4117    pub fields: Vec<Expression>,
4118    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4119    #[serde(default)]
4120    pub using: Vec<Expression>,
4121    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4122    #[serde(default)]
4123    pub group: Option<Box<Expression>>,
4124    /// Whether this is an UNPIVOT (vs PIVOT)
4125    #[serde(default)]
4126    pub unpivot: bool,
4127    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4128    #[serde(default)]
4129    pub into: Option<Box<Expression>>,
4130    /// Optional alias
4131    #[serde(default)]
4132    pub alias: Option<Identifier>,
4133    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4134    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4135    pub alias_columns: Vec<Identifier>,
4136    /// Include/exclude nulls (for UNPIVOT)
4137    #[serde(default)]
4138    pub include_nulls: Option<bool>,
4139    /// Default on null value (Snowflake)
4140    #[serde(default)]
4141    pub default_on_null: Option<Box<Expression>>,
4142    /// WITH clause (CTEs)
4143    #[serde(default, skip_serializing_if = "Option::is_none")]
4144    pub with: Option<With>,
4145}
4146
4147/// UNPIVOT operation
4148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4149#[cfg_attr(feature = "bindings", derive(TS))]
4150pub struct Unpivot {
4151    pub this: Expression,
4152    pub value_column: Identifier,
4153    pub name_column: Identifier,
4154    pub columns: Vec<Expression>,
4155    pub alias: Option<Identifier>,
4156    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4157    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4158    pub alias_columns: Vec<Identifier>,
4159    /// Whether the value_column was parenthesized in the original SQL
4160    #[serde(default)]
4161    pub value_column_parenthesized: bool,
4162    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4163    #[serde(default)]
4164    pub include_nulls: Option<bool>,
4165    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4166    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4167    pub extra_value_columns: Vec<Identifier>,
4168}
4169
4170/// PIVOT alias for aliasing pivot expressions
4171/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4173#[cfg_attr(feature = "bindings", derive(TS))]
4174pub struct PivotAlias {
4175    pub this: Expression,
4176    pub alias: Expression,
4177}
4178
4179/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4181#[cfg_attr(feature = "bindings", derive(TS))]
4182pub struct PreWhere {
4183    pub this: Expression,
4184}
4185
4186/// STREAM definition (Snowflake) - for change data capture
4187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4188#[cfg_attr(feature = "bindings", derive(TS))]
4189pub struct Stream {
4190    pub this: Expression,
4191    #[serde(skip_serializing_if = "Option::is_none")]
4192    pub on: Option<Expression>,
4193    #[serde(skip_serializing_if = "Option::is_none")]
4194    pub show_initial_rows: Option<bool>,
4195}
4196
4197/// USING DATA clause for data import statements
4198#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4199#[cfg_attr(feature = "bindings", derive(TS))]
4200pub struct UsingData {
4201    pub this: Expression,
4202}
4203
4204/// XML Namespace declaration
4205#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4206#[cfg_attr(feature = "bindings", derive(TS))]
4207pub struct XmlNamespace {
4208    pub this: Expression,
4209    #[serde(skip_serializing_if = "Option::is_none")]
4210    pub alias: Option<Identifier>,
4211}
4212
4213/// ROW FORMAT clause for Hive/Spark
4214#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4215#[cfg_attr(feature = "bindings", derive(TS))]
4216pub struct RowFormat {
4217    pub delimited: bool,
4218    pub fields_terminated_by: Option<String>,
4219    pub collection_items_terminated_by: Option<String>,
4220    pub map_keys_terminated_by: Option<String>,
4221    pub lines_terminated_by: Option<String>,
4222    pub null_defined_as: Option<String>,
4223}
4224
4225/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4227#[cfg_attr(feature = "bindings", derive(TS))]
4228pub struct DirectoryInsert {
4229    pub local: bool,
4230    pub path: String,
4231    pub row_format: Option<RowFormat>,
4232    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4233    #[serde(default)]
4234    pub stored_as: Option<String>,
4235}
4236
4237/// INSERT statement
4238#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4239#[cfg_attr(feature = "bindings", derive(TS))]
4240pub struct Insert {
4241    pub table: TableRef,
4242    pub columns: Vec<Identifier>,
4243    pub values: Vec<Vec<Expression>>,
4244    pub query: Option<Expression>,
4245    /// INSERT OVERWRITE for Hive/Spark
4246    pub overwrite: bool,
4247    /// PARTITION clause for Hive/Spark
4248    pub partition: Vec<(Identifier, Option<Expression>)>,
4249    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4250    #[serde(default)]
4251    pub directory: Option<DirectoryInsert>,
4252    /// RETURNING clause (PostgreSQL, SQLite)
4253    #[serde(default)]
4254    pub returning: Vec<Expression>,
4255    /// OUTPUT clause (TSQL)
4256    #[serde(default)]
4257    pub output: Option<OutputClause>,
4258    /// ON CONFLICT clause (PostgreSQL, SQLite)
4259    #[serde(default)]
4260    pub on_conflict: Option<Box<Expression>>,
4261    /// Leading comments before the statement
4262    #[serde(default)]
4263    pub leading_comments: Vec<String>,
4264    /// IF EXISTS clause (Hive)
4265    #[serde(default)]
4266    pub if_exists: bool,
4267    /// WITH clause (CTEs)
4268    #[serde(default)]
4269    pub with: Option<With>,
4270    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4271    #[serde(default)]
4272    pub ignore: bool,
4273    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4274    #[serde(default)]
4275    pub source_alias: Option<Identifier>,
4276    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4277    #[serde(default)]
4278    pub alias: Option<Identifier>,
4279    /// Whether the alias uses explicit AS keyword
4280    #[serde(default)]
4281    pub alias_explicit_as: bool,
4282    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4283    #[serde(default)]
4284    pub default_values: bool,
4285    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4286    #[serde(default)]
4287    pub by_name: bool,
4288    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4289    #[serde(default, skip_serializing_if = "Option::is_none")]
4290    pub conflict_action: Option<String>,
4291    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4292    #[serde(default)]
4293    pub is_replace: bool,
4294    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4295    #[serde(default, skip_serializing_if = "Option::is_none")]
4296    pub hint: Option<Hint>,
4297    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4298    #[serde(default)]
4299    pub replace_where: Option<Box<Expression>>,
4300    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4301    #[serde(default)]
4302    pub source: Option<Box<Expression>>,
4303    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4304    #[serde(default, skip_serializing_if = "Option::is_none")]
4305    pub function_target: Option<Box<Expression>>,
4306    /// ClickHouse: PARTITION BY expr
4307    #[serde(default, skip_serializing_if = "Option::is_none")]
4308    pub partition_by: Option<Box<Expression>>,
4309    /// ClickHouse: SETTINGS key = val, ...
4310    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4311    pub settings: Vec<Expression>,
4312}
4313
4314/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4316#[cfg_attr(feature = "bindings", derive(TS))]
4317pub struct OutputClause {
4318    /// Columns/expressions to output
4319    pub columns: Vec<Expression>,
4320    /// Optional INTO target table or table variable
4321    #[serde(default)]
4322    pub into_table: Option<Expression>,
4323}
4324
4325/// UPDATE statement
4326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4327#[cfg_attr(feature = "bindings", derive(TS))]
4328pub struct Update {
4329    pub table: TableRef,
4330    #[serde(default)]
4331    pub hint: Option<Hint>,
4332    /// Additional tables for multi-table UPDATE (MySQL syntax)
4333    #[serde(default)]
4334    pub extra_tables: Vec<TableRef>,
4335    /// JOINs attached to the table list (MySQL multi-table syntax)
4336    #[serde(default)]
4337    pub table_joins: Vec<Join>,
4338    pub set: Vec<(Identifier, Expression)>,
4339    pub from_clause: Option<From>,
4340    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4341    #[serde(default)]
4342    pub from_joins: Vec<Join>,
4343    pub where_clause: Option<Where>,
4344    /// RETURNING clause (PostgreSQL, SQLite)
4345    #[serde(default)]
4346    pub returning: Vec<Expression>,
4347    /// OUTPUT clause (TSQL)
4348    #[serde(default)]
4349    pub output: Option<OutputClause>,
4350    /// WITH clause (CTEs)
4351    #[serde(default)]
4352    pub with: Option<With>,
4353    /// Leading comments before the statement
4354    #[serde(default)]
4355    pub leading_comments: Vec<String>,
4356    /// LIMIT clause (MySQL)
4357    #[serde(default)]
4358    pub limit: Option<Expression>,
4359    /// ORDER BY clause (MySQL)
4360    #[serde(default)]
4361    pub order_by: Option<OrderBy>,
4362    /// Whether FROM clause appears before SET (Snowflake syntax)
4363    #[serde(default)]
4364    pub from_before_set: bool,
4365}
4366
4367/// DELETE statement
4368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4369#[cfg_attr(feature = "bindings", derive(TS))]
4370pub struct Delete {
4371    pub table: TableRef,
4372    #[serde(default)]
4373    pub hint: Option<Hint>,
4374    /// ClickHouse: ON CLUSTER clause for distributed DDL
4375    #[serde(default, skip_serializing_if = "Option::is_none")]
4376    pub on_cluster: Option<OnCluster>,
4377    /// Optional alias for the table
4378    pub alias: Option<Identifier>,
4379    /// Whether the alias was declared with explicit AS keyword
4380    #[serde(default)]
4381    pub alias_explicit_as: bool,
4382    /// PostgreSQL/DuckDB USING clause - additional tables to join
4383    pub using: Vec<TableRef>,
4384    pub where_clause: Option<Where>,
4385    /// OUTPUT clause (TSQL)
4386    #[serde(default)]
4387    pub output: Option<OutputClause>,
4388    /// Leading comments before the statement
4389    #[serde(default)]
4390    pub leading_comments: Vec<String>,
4391    /// WITH clause (CTEs)
4392    #[serde(default)]
4393    pub with: Option<With>,
4394    /// LIMIT clause (MySQL)
4395    #[serde(default)]
4396    pub limit: Option<Expression>,
4397    /// ORDER BY clause (MySQL)
4398    #[serde(default)]
4399    pub order_by: Option<OrderBy>,
4400    /// RETURNING clause (PostgreSQL)
4401    #[serde(default)]
4402    pub returning: Vec<Expression>,
4403    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4404    /// These are the target tables to delete from
4405    #[serde(default)]
4406    pub tables: Vec<TableRef>,
4407    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4408    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4409    #[serde(default)]
4410    pub tables_from_using: bool,
4411    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4412    #[serde(default)]
4413    pub joins: Vec<Join>,
4414    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4415    #[serde(default)]
4416    pub force_index: Option<String>,
4417    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4418    #[serde(default)]
4419    pub no_from: bool,
4420}
4421
4422/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4424#[cfg_attr(feature = "bindings", derive(TS))]
4425pub struct CopyStmt {
4426    /// Target table or query
4427    pub this: Expression,
4428    /// True for FROM (loading into table), false for TO (exporting)
4429    pub kind: bool,
4430    /// Source/destination file(s) or stage
4431    pub files: Vec<Expression>,
4432    /// Copy parameters
4433    #[serde(default)]
4434    pub params: Vec<CopyParameter>,
4435    /// Credentials for external access
4436    #[serde(default)]
4437    pub credentials: Option<Box<Credentials>>,
4438    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4439    #[serde(default)]
4440    pub is_into: bool,
4441    /// Whether parameters are wrapped in WITH (...) syntax
4442    #[serde(default)]
4443    pub with_wrapped: bool,
4444}
4445
4446/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4448#[cfg_attr(feature = "bindings", derive(TS))]
4449pub struct CopyParameter {
4450    pub name: String,
4451    pub value: Option<Expression>,
4452    pub values: Vec<Expression>,
4453    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4454    #[serde(default)]
4455    pub eq: bool,
4456}
4457
4458/// Credentials for external access (S3, Azure, etc.)
4459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4460#[cfg_attr(feature = "bindings", derive(TS))]
4461pub struct Credentials {
4462    pub credentials: Vec<(String, String)>,
4463    pub encryption: Option<String>,
4464    pub storage: Option<String>,
4465}
4466
4467/// PUT statement (Snowflake)
4468#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4469#[cfg_attr(feature = "bindings", derive(TS))]
4470pub struct PutStmt {
4471    /// Source file path
4472    pub source: String,
4473    /// Whether source was quoted in the original SQL
4474    #[serde(default)]
4475    pub source_quoted: bool,
4476    /// Target stage
4477    pub target: Expression,
4478    /// PUT parameters
4479    #[serde(default)]
4480    pub params: Vec<CopyParameter>,
4481}
4482
4483/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4485#[cfg_attr(feature = "bindings", derive(TS))]
4486pub struct StageReference {
4487    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4488    pub name: String,
4489    /// Optional path within the stage (e.g., "/path/to/file.csv")
4490    #[serde(default)]
4491    pub path: Option<String>,
4492    /// Optional FILE_FORMAT parameter
4493    #[serde(default)]
4494    pub file_format: Option<Expression>,
4495    /// Optional PATTERN parameter
4496    #[serde(default)]
4497    pub pattern: Option<String>,
4498    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4499    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4500    pub quoted: bool,
4501}
4502
4503/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4505#[cfg_attr(feature = "bindings", derive(TS))]
4506pub struct HistoricalData {
4507    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4508    pub this: Box<Expression>,
4509    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4510    pub kind: String,
4511    /// The expression value (e.g., the statement ID or timestamp)
4512    pub expression: Box<Expression>,
4513}
4514
4515/// Represent an aliased expression (`expr AS name`).
4516///
4517/// Used for column aliases in select-lists, table aliases on subqueries,
4518/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4519#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4520#[cfg_attr(feature = "bindings", derive(TS))]
4521pub struct Alias {
4522    /// The expression being aliased.
4523    pub this: Expression,
4524    /// The alias name (required for simple aliases, optional when only column aliases provided)
4525    pub alias: Identifier,
4526    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4527    #[serde(default)]
4528    pub column_aliases: Vec<Identifier>,
4529    /// Whether AS keyword was explicitly used for the alias.
4530    #[serde(default)]
4531    pub alias_explicit_as: bool,
4532    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4533    #[serde(skip_serializing_if = "Option::is_none", default)]
4534    pub alias_keyword: Option<String>,
4535    /// Comments that appeared between the expression and AS keyword
4536    #[serde(default)]
4537    pub pre_alias_comments: Vec<String>,
4538    /// Trailing comments that appeared after the alias
4539    #[serde(default)]
4540    pub trailing_comments: Vec<String>,
4541    /// Inferred data type from type annotation
4542    #[serde(default, skip_serializing_if = "Option::is_none")]
4543    #[ast(skip)]
4544    pub inferred_type: Option<DataType>,
4545}
4546
4547impl Alias {
4548    /// Create a simple alias
4549    pub fn new(this: Expression, alias: Identifier) -> Self {
4550        Self {
4551            this,
4552            alias,
4553            column_aliases: Vec::new(),
4554            alias_explicit_as: false,
4555            alias_keyword: None,
4556            pre_alias_comments: Vec::new(),
4557            trailing_comments: Vec::new(),
4558            inferred_type: None,
4559        }
4560    }
4561
4562    /// Create an alias with column aliases only (no table alias name)
4563    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4564        Self {
4565            this,
4566            alias: Identifier::empty(),
4567            column_aliases,
4568            alias_explicit_as: false,
4569            alias_keyword: None,
4570            pre_alias_comments: Vec::new(),
4571            trailing_comments: Vec::new(),
4572            inferred_type: None,
4573        }
4574    }
4575}
4576
4577/// Represent a type cast expression.
4578///
4579/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4580/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4581/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4582/// CONVERSION ERROR (Oracle) clauses.
4583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4584#[cfg_attr(feature = "bindings", derive(TS))]
4585pub struct Cast {
4586    /// The expression being cast.
4587    pub this: Expression,
4588    /// The target data type.
4589    pub to: DataType,
4590    #[serde(default)]
4591    pub trailing_comments: Vec<String>,
4592    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4593    #[serde(default)]
4594    pub double_colon_syntax: bool,
4595    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4596    #[serde(skip_serializing_if = "Option::is_none", default)]
4597    pub format: Option<Box<Expression>>,
4598    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4599    #[serde(skip_serializing_if = "Option::is_none", default)]
4600    pub default: Option<Box<Expression>>,
4601    /// Inferred data type from type annotation
4602    #[serde(default, skip_serializing_if = "Option::is_none")]
4603    #[ast(skip)]
4604    pub inferred_type: Option<DataType>,
4605}
4606
4607///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4609#[cfg_attr(feature = "bindings", derive(TS))]
4610pub struct CollationExpr {
4611    pub this: Expression,
4612    pub collation: String,
4613    /// True if the collation was single-quoted in the original SQL (string literal)
4614    #[serde(default)]
4615    pub quoted: bool,
4616    /// True if the collation was double-quoted in the original SQL (identifier)
4617    #[serde(default)]
4618    pub double_quoted: bool,
4619}
4620
4621/// Represent a CASE expression (both simple and searched forms).
4622///
4623/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4624/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4625/// Each entry in `whens` is a `(condition, result)` pair.
4626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4627#[cfg_attr(feature = "bindings", derive(TS))]
4628pub struct Case {
4629    /// The operand for simple CASE, or `None` for searched CASE.
4630    pub operand: Option<Expression>,
4631    /// Pairs of (WHEN condition, THEN result).
4632    pub whens: Vec<(Expression, Expression)>,
4633    /// Optional ELSE result.
4634    pub else_: Option<Expression>,
4635    /// Comments from the CASE keyword (emitted after END)
4636    #[serde(default)]
4637    #[serde(skip_serializing_if = "Vec::is_empty")]
4638    pub comments: Vec<String>,
4639    /// Inferred data type from type annotation
4640    #[serde(default, skip_serializing_if = "Option::is_none")]
4641    #[ast(skip)]
4642    pub inferred_type: Option<DataType>,
4643}
4644
4645/// Represent a binary operation (two operands separated by an operator).
4646///
4647/// This is the shared payload struct for all binary operator variants in the
4648/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4649/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4650/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4651/// preservation of inline comments around operators.
4652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4653#[cfg_attr(feature = "bindings", derive(TS))]
4654pub struct BinaryOp {
4655    pub left: Expression,
4656    pub right: Expression,
4657    /// Comments after the left operand (before the operator)
4658    #[serde(default)]
4659    pub left_comments: Vec<String>,
4660    /// Comments after the operator (before the right operand)
4661    #[serde(default)]
4662    pub operator_comments: Vec<String>,
4663    /// Comments after the right operand
4664    #[serde(default)]
4665    pub trailing_comments: Vec<String>,
4666    /// Inferred data type from type annotation
4667    #[serde(default, skip_serializing_if = "Option::is_none")]
4668    #[ast(skip)]
4669    pub inferred_type: Option<DataType>,
4670}
4671
4672impl BinaryOp {
4673    pub fn new(left: Expression, right: Expression) -> Self {
4674        Self {
4675            left,
4676            right,
4677            left_comments: Vec::new(),
4678            operator_comments: Vec::new(),
4679            trailing_comments: Vec::new(),
4680            inferred_type: None,
4681        }
4682    }
4683}
4684
4685/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4686#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4687#[cfg_attr(feature = "bindings", derive(TS))]
4688pub struct LikeOp {
4689    pub left: Expression,
4690    pub right: Expression,
4691    /// ESCAPE character/expression
4692    #[serde(default)]
4693    pub escape: Option<Expression>,
4694    /// Quantifier: ANY, ALL, or SOME
4695    #[serde(default)]
4696    pub quantifier: Option<String>,
4697    /// Inferred data type from type annotation
4698    #[serde(default, skip_serializing_if = "Option::is_none")]
4699    #[ast(skip)]
4700    pub inferred_type: Option<DataType>,
4701}
4702
4703impl LikeOp {
4704    pub fn new(left: Expression, right: Expression) -> Self {
4705        Self {
4706            left,
4707            right,
4708            escape: None,
4709            quantifier: None,
4710            inferred_type: None,
4711        }
4712    }
4713
4714    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4715        Self {
4716            left,
4717            right,
4718            escape: Some(escape),
4719            quantifier: None,
4720            inferred_type: None,
4721        }
4722    }
4723}
4724
4725/// Represent a unary operation (single operand with a prefix operator).
4726///
4727/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4728#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4729#[cfg_attr(feature = "bindings", derive(TS))]
4730pub struct UnaryOp {
4731    /// The operand expression.
4732    pub this: Expression,
4733    /// Inferred data type from type annotation
4734    #[serde(default, skip_serializing_if = "Option::is_none")]
4735    #[ast(skip)]
4736    pub inferred_type: Option<DataType>,
4737}
4738
4739impl UnaryOp {
4740    pub fn new(this: Expression) -> Self {
4741        Self {
4742            this,
4743            inferred_type: None,
4744        }
4745    }
4746}
4747
4748/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4749///
4750/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4751/// but not both. When `not` is true, the predicate is `NOT IN`.
4752#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4753#[cfg_attr(feature = "bindings", derive(TS))]
4754pub struct In {
4755    /// The expression being tested.
4756    pub this: Expression,
4757    /// The value list (mutually exclusive with `query`).
4758    pub expressions: Vec<Expression>,
4759    /// A subquery (mutually exclusive with `expressions`).
4760    pub query: Option<Expression>,
4761    /// Whether this is NOT IN.
4762    pub not: bool,
4763    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4764    pub global: bool,
4765    /// BigQuery: IN UNNEST(expr)
4766    #[serde(default, skip_serializing_if = "Option::is_none")]
4767    pub unnest: Option<Box<Expression>>,
4768    /// Whether the right side is a bare field reference (no parentheses).
4769    /// Matches Python sqlglot's `field` attribute on `In` expression.
4770    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4771    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4772    pub is_field: bool,
4773}
4774
4775/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4777#[cfg_attr(feature = "bindings", derive(TS))]
4778pub struct Between {
4779    /// The expression being tested.
4780    pub this: Expression,
4781    /// The lower bound.
4782    pub low: Expression,
4783    /// The upper bound.
4784    pub high: Expression,
4785    /// Whether this is NOT BETWEEN.
4786    pub not: bool,
4787    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4788    #[serde(default)]
4789    pub symmetric: Option<bool>,
4790}
4791
4792/// IS NULL predicate
4793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4794#[cfg_attr(feature = "bindings", derive(TS))]
4795pub struct IsNull {
4796    pub this: Expression,
4797    pub not: bool,
4798    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4799    #[serde(default)]
4800    pub postfix_form: bool,
4801}
4802
4803/// IS TRUE / IS FALSE predicate
4804#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4805#[cfg_attr(feature = "bindings", derive(TS))]
4806pub struct IsTrueFalse {
4807    pub this: Expression,
4808    pub not: bool,
4809}
4810
4811/// IS JSON predicate (SQL standard)
4812/// Checks if a value is valid JSON
4813#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4814#[cfg_attr(feature = "bindings", derive(TS))]
4815pub struct IsJson {
4816    pub this: Expression,
4817    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4818    pub json_type: Option<String>,
4819    /// Key uniqueness constraint
4820    pub unique_keys: Option<JsonUniqueKeys>,
4821    /// Whether IS NOT JSON
4822    pub negated: bool,
4823}
4824
4825/// JSON unique keys constraint variants
4826#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4827#[cfg_attr(feature = "bindings", derive(TS))]
4828pub enum JsonUniqueKeys {
4829    /// WITH UNIQUE KEYS
4830    With,
4831    /// WITHOUT UNIQUE KEYS
4832    Without,
4833    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4834    Shorthand,
4835}
4836
4837/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4839#[cfg_attr(feature = "bindings", derive(TS))]
4840pub struct Exists {
4841    /// The subquery expression.
4842    pub this: Expression,
4843    /// Whether this is NOT EXISTS.
4844    pub not: bool,
4845}
4846
4847/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
4848///
4849/// This is the generic function node. Well-known aggregates, window functions,
4850/// and built-in functions each have their own dedicated `Expression` variants
4851/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
4852/// not recognize as built-ins are represented with this struct.
4853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4854#[cfg_attr(feature = "bindings", derive(TS))]
4855pub struct Function {
4856    /// The function name, as originally written (may be schema-qualified).
4857    pub name: String,
4858    /// Positional arguments to the function.
4859    pub args: Vec<Expression>,
4860    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
4861    pub distinct: bool,
4862    #[serde(default)]
4863    pub trailing_comments: Vec<String>,
4864    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
4865    #[serde(default)]
4866    pub use_bracket_syntax: bool,
4867    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
4868    #[serde(default)]
4869    pub no_parens: bool,
4870    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
4871    #[serde(default)]
4872    pub quoted: bool,
4873    /// Source position span
4874    #[serde(default, skip_serializing_if = "Option::is_none")]
4875    pub span: Option<Span>,
4876    /// Inferred data type from type annotation
4877    #[serde(default, skip_serializing_if = "Option::is_none")]
4878    #[ast(skip)]
4879    pub inferred_type: Option<DataType>,
4880}
4881
4882impl Default for Function {
4883    fn default() -> Self {
4884        Self {
4885            name: String::new(),
4886            args: Vec::new(),
4887            distinct: false,
4888            trailing_comments: Vec::new(),
4889            use_bracket_syntax: false,
4890            no_parens: false,
4891            quoted: false,
4892            span: None,
4893            inferred_type: None,
4894        }
4895    }
4896}
4897
4898impl Function {
4899    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
4900        Self {
4901            name: name.into(),
4902            args,
4903            distinct: false,
4904            trailing_comments: Vec::new(),
4905            use_bracket_syntax: false,
4906            no_parens: false,
4907            quoted: false,
4908            span: None,
4909            inferred_type: None,
4910        }
4911    }
4912}
4913
4914/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
4915///
4916/// This struct is used for aggregate function calls that are not covered by
4917/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
4918/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
4919/// IGNORE NULLS / RESPECT NULLS modifiers.
4920#[derive(
4921    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
4922)]
4923#[cfg_attr(feature = "bindings", derive(TS))]
4924pub struct AggregateFunction {
4925    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
4926    pub name: String,
4927    /// Positional arguments.
4928    pub args: Vec<Expression>,
4929    /// Whether DISTINCT was specified.
4930    pub distinct: bool,
4931    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
4932    pub filter: Option<Expression>,
4933    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
4934    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4935    pub order_by: Vec<Ordered>,
4936    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
4937    #[serde(default, skip_serializing_if = "Option::is_none")]
4938    pub limit: Option<Box<Expression>>,
4939    /// IGNORE NULLS / RESPECT NULLS
4940    #[serde(default, skip_serializing_if = "Option::is_none")]
4941    pub ignore_nulls: Option<bool>,
4942    /// Inferred data type from type annotation
4943    #[serde(default, skip_serializing_if = "Option::is_none")]
4944    #[ast(skip)]
4945    pub inferred_type: Option<DataType>,
4946}
4947
4948/// Represent a window function call with its OVER clause.
4949///
4950/// The inner `this` expression is typically a window-specific expression
4951/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
4952/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
4953/// frame specification.
4954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4955#[cfg_attr(feature = "bindings", derive(TS))]
4956pub struct WindowFunction {
4957    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
4958    pub this: Expression,
4959    /// The OVER clause defining the window partitioning, ordering, and frame.
4960    pub over: Over,
4961    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
4962    #[serde(default, skip_serializing_if = "Option::is_none")]
4963    pub keep: Option<Keep>,
4964    /// Inferred data type from type annotation
4965    #[serde(default, skip_serializing_if = "Option::is_none")]
4966    #[ast(skip)]
4967    pub inferred_type: Option<DataType>,
4968}
4969
4970/// Oracle KEEP clause for aggregate functions
4971/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
4972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4973#[cfg_attr(feature = "bindings", derive(TS))]
4974pub struct Keep {
4975    /// true = FIRST, false = LAST
4976    pub first: bool,
4977    /// ORDER BY clause inside KEEP
4978    pub order_by: Vec<Ordered>,
4979}
4980
4981/// WITHIN GROUP clause (for ordered-set aggregate functions)
4982#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4983#[cfg_attr(feature = "bindings", derive(TS))]
4984pub struct WithinGroup {
4985    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
4986    pub this: Expression,
4987    /// The ORDER BY clause within the group
4988    pub order_by: Vec<Ordered>,
4989}
4990
4991/// Represent the FROM clause of a SELECT statement.
4992///
4993/// Contains one or more table sources (tables, subqueries, table-valued
4994/// functions, etc.). Multiple entries represent comma-separated implicit joins.
4995#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4996#[cfg_attr(feature = "bindings", derive(TS))]
4997pub struct From {
4998    /// The table source expressions.
4999    pub expressions: Vec<Expression>,
5000}
5001
5002/// Represent a JOIN clause between two table sources.
5003///
5004/// The join condition can be specified via `on` (ON predicate) or `using`
5005/// (USING column list), but not both. The `kind` field determines the join
5006/// type (INNER, LEFT, CROSS, etc.).
5007#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5008#[cfg_attr(feature = "bindings", derive(TS))]
5009pub struct Join {
5010    /// The right-hand table expression being joined.
5011    pub this: Expression,
5012    /// The ON condition (mutually exclusive with `using`).
5013    pub on: Option<Expression>,
5014    /// The USING column list (mutually exclusive with `on`).
5015    pub using: Vec<Identifier>,
5016    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5017    pub kind: JoinKind,
5018    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5019    pub use_inner_keyword: bool,
5020    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5021    pub use_outer_keyword: bool,
5022    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5023    pub deferred_condition: bool,
5024    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5025    #[serde(default, skip_serializing_if = "Option::is_none")]
5026    pub join_hint: Option<String>,
5027    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5028    #[serde(default, skip_serializing_if = "Option::is_none")]
5029    pub match_condition: Option<Expression>,
5030    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5031    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5032    pub pivots: Vec<Expression>,
5033    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5034    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5035    pub comments: Vec<String>,
5036    /// Nesting group identifier for nested join pretty-printing.
5037    /// Joins in the same group were parsed together; group boundaries come from
5038    /// deferred condition resolution phases.
5039    #[serde(default)]
5040    pub nesting_group: usize,
5041    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5042    #[serde(default)]
5043    pub directed: bool,
5044}
5045
5046/// Enumerate all supported SQL join types.
5047///
5048/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5049/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5050/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5051/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5052#[derive(
5053    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5054)]
5055#[cfg_attr(feature = "bindings", derive(TS))]
5056pub enum JoinKind {
5057    Inner,
5058    Left,
5059    Right,
5060    Full,
5061    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5062    Cross,
5063    Natural,
5064    NaturalLeft,
5065    NaturalRight,
5066    NaturalFull,
5067    Semi,
5068    Anti,
5069    // Directional SEMI/ANTI joins
5070    LeftSemi,
5071    LeftAnti,
5072    RightSemi,
5073    RightAnti,
5074    // SQL Server specific
5075    CrossApply,
5076    OuterApply,
5077    // Time-series specific
5078    AsOf,
5079    AsOfLeft,
5080    AsOfRight,
5081    // Lateral join
5082    Lateral,
5083    LeftLateral,
5084    // MySQL specific
5085    Straight,
5086    // Implicit join (comma-separated tables: FROM a, b)
5087    Implicit,
5088    // ClickHouse ARRAY JOIN
5089    Array,
5090    LeftArray,
5091    // ClickHouse PASTE JOIN (positional join)
5092    Paste,
5093    // DuckDB POSITIONAL JOIN
5094    Positional,
5095}
5096
5097impl Default for JoinKind {
5098    fn default() -> Self {
5099        JoinKind::Inner
5100    }
5101}
5102
5103/// Parenthesized table expression with joins
5104/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5105#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5106#[cfg_attr(feature = "bindings", derive(TS))]
5107pub struct JoinedTable {
5108    /// The left-hand side table expression
5109    pub left: Expression,
5110    /// The joins applied to the left table
5111    pub joins: Vec<Join>,
5112    /// LATERAL VIEW clauses (Hive/Spark)
5113    pub lateral_views: Vec<LateralView>,
5114    /// Optional alias for the joined table expression
5115    pub alias: Option<Identifier>,
5116}
5117
5118/// Represent a WHERE clause containing a boolean filter predicate.
5119#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5120#[cfg_attr(feature = "bindings", derive(TS))]
5121pub struct Where {
5122    /// The filter predicate expression.
5123    pub this: Expression,
5124}
5125
5126/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5127///
5128/// The `expressions` list may contain plain columns, ordinal positions,
5129/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5130#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5131#[cfg_attr(feature = "bindings", derive(TS))]
5132pub struct GroupBy {
5133    /// The grouping expressions.
5134    pub expressions: Vec<Expression>,
5135    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5136    #[serde(default)]
5137    pub all: Option<bool>,
5138    /// ClickHouse: WITH TOTALS modifier
5139    #[serde(default)]
5140    pub totals: bool,
5141    /// Leading comments that appeared before the GROUP BY keyword
5142    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5143    pub comments: Vec<String>,
5144}
5145
5146/// Represent a HAVING clause containing a predicate over aggregate results.
5147#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5148#[cfg_attr(feature = "bindings", derive(TS))]
5149pub struct Having {
5150    /// The filter predicate, typically involving aggregate functions.
5151    pub this: Expression,
5152    /// Leading comments that appeared before the HAVING keyword
5153    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5154    pub comments: Vec<String>,
5155}
5156
5157/// Represent an ORDER BY clause containing one or more sort specifications.
5158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5159#[cfg_attr(feature = "bindings", derive(TS))]
5160pub struct OrderBy {
5161    /// The sort specifications, each with direction and null ordering.
5162    pub expressions: Vec<Ordered>,
5163    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5164    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5165    pub siblings: bool,
5166    /// Leading comments that appeared before the ORDER BY keyword
5167    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5168    pub comments: Vec<String>,
5169}
5170
5171/// Represent an expression with sort direction and null ordering.
5172///
5173/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5174/// When `desc` is false the sort is ascending. The `nulls_first` field
5175/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5176/// (database default).
5177#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5178#[cfg_attr(feature = "bindings", derive(TS))]
5179pub struct Ordered {
5180    /// The expression to sort by.
5181    pub this: Expression,
5182    /// Whether the sort direction is descending (true) or ascending (false).
5183    pub desc: bool,
5184    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5185    pub nulls_first: Option<bool>,
5186    /// Whether ASC was explicitly written (not just implied)
5187    #[serde(default)]
5188    pub explicit_asc: bool,
5189    /// ClickHouse WITH FILL clause
5190    #[serde(default, skip_serializing_if = "Option::is_none")]
5191    pub with_fill: Option<Box<WithFill>>,
5192}
5193
5194impl Ordered {
5195    pub fn asc(expr: Expression) -> Self {
5196        Self {
5197            this: expr,
5198            desc: false,
5199            nulls_first: None,
5200            explicit_asc: false,
5201            with_fill: None,
5202        }
5203    }
5204
5205    pub fn desc(expr: Expression) -> Self {
5206        Self {
5207            this: expr,
5208            desc: true,
5209            nulls_first: None,
5210            explicit_asc: false,
5211            with_fill: None,
5212        }
5213    }
5214}
5215
5216/// DISTRIBUTE BY clause (Hive/Spark)
5217/// Controls how rows are distributed across reducers
5218#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5219#[cfg_attr(feature = "bindings", derive(TS))]
5220#[cfg_attr(feature = "bindings", ts(export))]
5221pub struct DistributeBy {
5222    pub expressions: Vec<Expression>,
5223}
5224
5225/// CLUSTER BY clause (Hive/Spark)
5226/// Combines DISTRIBUTE BY and SORT BY on the same columns
5227#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5228#[cfg_attr(feature = "bindings", derive(TS))]
5229#[cfg_attr(feature = "bindings", ts(export))]
5230pub struct ClusterBy {
5231    pub expressions: Vec<Ordered>,
5232}
5233
5234/// SORT BY clause (Hive/Spark)
5235/// Sorts data within each reducer (local sort, not global)
5236#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5237#[cfg_attr(feature = "bindings", derive(TS))]
5238#[cfg_attr(feature = "bindings", ts(export))]
5239pub struct SortBy {
5240    pub expressions: Vec<Ordered>,
5241}
5242
5243/// LATERAL VIEW clause (Hive/Spark)
5244/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5246#[cfg_attr(feature = "bindings", derive(TS))]
5247#[cfg_attr(feature = "bindings", ts(export))]
5248pub struct LateralView {
5249    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5250    pub this: Expression,
5251    /// Table alias for the generated table
5252    pub table_alias: Option<Identifier>,
5253    /// Column aliases for the generated columns
5254    pub column_aliases: Vec<Identifier>,
5255    /// OUTER keyword - preserve nulls when input is empty/null
5256    pub outer: bool,
5257}
5258
5259/// Query hint
5260#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5261#[cfg_attr(feature = "bindings", derive(TS))]
5262#[cfg_attr(feature = "bindings", ts(export))]
5263pub struct Hint {
5264    pub expressions: Vec<HintExpression>,
5265}
5266
5267/// Individual hint expression
5268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5269#[cfg_attr(feature = "bindings", derive(TS))]
5270#[cfg_attr(feature = "bindings", ts(export))]
5271pub enum HintExpression {
5272    /// Function-style hint: USE_HASH(table)
5273    Function { name: String, args: Vec<Expression> },
5274    /// Simple identifier hint: PARALLEL
5275    Identifier(String),
5276    /// Raw hint text (unparsed)
5277    Raw(String),
5278}
5279
5280/// Pseudocolumn type
5281#[derive(
5282    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5283)]
5284#[cfg_attr(feature = "bindings", derive(TS))]
5285#[cfg_attr(feature = "bindings", ts(export))]
5286pub enum PseudocolumnType {
5287    Rownum,      // Oracle ROWNUM
5288    Rowid,       // Oracle ROWID
5289    Level,       // Oracle LEVEL (for CONNECT BY)
5290    Sysdate,     // Oracle SYSDATE
5291    ObjectId,    // Oracle OBJECT_ID
5292    ObjectValue, // Oracle OBJECT_VALUE
5293}
5294
5295impl PseudocolumnType {
5296    pub fn as_str(&self) -> &'static str {
5297        match self {
5298            PseudocolumnType::Rownum => "ROWNUM",
5299            PseudocolumnType::Rowid => "ROWID",
5300            PseudocolumnType::Level => "LEVEL",
5301            PseudocolumnType::Sysdate => "SYSDATE",
5302            PseudocolumnType::ObjectId => "OBJECT_ID",
5303            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5304        }
5305    }
5306
5307    pub fn from_str(s: &str) -> Option<Self> {
5308        match s.to_uppercase().as_str() {
5309            "ROWNUM" => Some(PseudocolumnType::Rownum),
5310            "ROWID" => Some(PseudocolumnType::Rowid),
5311            "LEVEL" => Some(PseudocolumnType::Level),
5312            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5313            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5314            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5315            _ => None,
5316        }
5317    }
5318}
5319
5320/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5321/// These are special identifiers that should not be quoted
5322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5323#[cfg_attr(feature = "bindings", derive(TS))]
5324#[cfg_attr(feature = "bindings", ts(export))]
5325pub struct Pseudocolumn {
5326    pub kind: PseudocolumnType,
5327}
5328
5329impl Pseudocolumn {
5330    pub fn rownum() -> Self {
5331        Self {
5332            kind: PseudocolumnType::Rownum,
5333        }
5334    }
5335
5336    pub fn rowid() -> Self {
5337        Self {
5338            kind: PseudocolumnType::Rowid,
5339        }
5340    }
5341
5342    pub fn level() -> Self {
5343        Self {
5344            kind: PseudocolumnType::Level,
5345        }
5346    }
5347}
5348
5349/// Oracle CONNECT BY clause for hierarchical queries
5350#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5351#[cfg_attr(feature = "bindings", derive(TS))]
5352#[cfg_attr(feature = "bindings", ts(export))]
5353pub struct Connect {
5354    /// START WITH condition (optional, can come before or after CONNECT BY)
5355    pub start: Option<Expression>,
5356    /// CONNECT BY condition (required, contains PRIOR references)
5357    pub connect: Expression,
5358    /// NOCYCLE keyword to prevent infinite loops
5359    pub nocycle: bool,
5360}
5361
5362/// Oracle PRIOR expression - references parent row's value in CONNECT BY
5363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5364#[cfg_attr(feature = "bindings", derive(TS))]
5365#[cfg_attr(feature = "bindings", ts(export))]
5366pub struct Prior {
5367    pub this: Expression,
5368}
5369
5370/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5372#[cfg_attr(feature = "bindings", derive(TS))]
5373#[cfg_attr(feature = "bindings", ts(export))]
5374pub struct ConnectByRoot {
5375    pub this: Expression,
5376}
5377
5378/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5379#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5380#[cfg_attr(feature = "bindings", derive(TS))]
5381#[cfg_attr(feature = "bindings", ts(export))]
5382pub struct MatchRecognize {
5383    /// Source table/expression
5384    pub this: Option<Box<Expression>>,
5385    /// PARTITION BY expressions
5386    pub partition_by: Option<Vec<Expression>>,
5387    /// ORDER BY expressions
5388    pub order_by: Option<Vec<Ordered>>,
5389    /// MEASURES definitions
5390    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5391    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5392    pub rows: Option<MatchRecognizeRows>,
5393    /// AFTER MATCH SKIP behavior
5394    pub after: Option<MatchRecognizeAfter>,
5395    /// PATTERN definition (stored as raw string for complex regex patterns)
5396    pub pattern: Option<String>,
5397    /// DEFINE clauses (pattern variable definitions)
5398    pub define: Option<Vec<(Identifier, Expression)>>,
5399    /// Optional alias for the result
5400    pub alias: Option<Identifier>,
5401    /// Whether AS keyword was explicitly present before alias
5402    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5403    pub alias_explicit_as: bool,
5404}
5405
5406/// MEASURES expression with optional RUNNING/FINAL semantics
5407#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5408#[cfg_attr(feature = "bindings", derive(TS))]
5409#[cfg_attr(feature = "bindings", ts(export))]
5410pub struct MatchRecognizeMeasure {
5411    /// The measure expression
5412    pub this: Expression,
5413    /// RUNNING or FINAL semantics (Snowflake-specific)
5414    pub window_frame: Option<MatchRecognizeSemantics>,
5415}
5416
5417/// Semantics for MEASURES in MATCH_RECOGNIZE
5418#[derive(
5419    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5420)]
5421#[cfg_attr(feature = "bindings", derive(TS))]
5422#[cfg_attr(feature = "bindings", ts(export))]
5423pub enum MatchRecognizeSemantics {
5424    Running,
5425    Final,
5426}
5427
5428/// Row output semantics for MATCH_RECOGNIZE
5429#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5430#[cfg_attr(feature = "bindings", derive(TS))]
5431#[cfg_attr(feature = "bindings", ts(export))]
5432pub enum MatchRecognizeRows {
5433    OneRowPerMatch,
5434    AllRowsPerMatch,
5435    AllRowsPerMatchShowEmptyMatches,
5436    AllRowsPerMatchOmitEmptyMatches,
5437    AllRowsPerMatchWithUnmatchedRows,
5438}
5439
5440/// AFTER MATCH SKIP behavior
5441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5442#[cfg_attr(feature = "bindings", derive(TS))]
5443#[cfg_attr(feature = "bindings", ts(export))]
5444pub enum MatchRecognizeAfter {
5445    PastLastRow,
5446    ToNextRow,
5447    ToFirst(Identifier),
5448    ToLast(Identifier),
5449}
5450
5451/// Represent a LIMIT clause that restricts the number of returned rows.
5452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5453#[cfg_attr(feature = "bindings", derive(TS))]
5454pub struct Limit {
5455    /// The limit count expression.
5456    pub this: Expression,
5457    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5458    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5459    pub percent: bool,
5460    /// Comments from before the LIMIT keyword (emitted after the limit value)
5461    #[serde(default)]
5462    #[serde(skip_serializing_if = "Vec::is_empty")]
5463    pub comments: Vec<String>,
5464}
5465
5466/// OFFSET clause
5467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5468#[cfg_attr(feature = "bindings", derive(TS))]
5469pub struct Offset {
5470    pub this: Expression,
5471    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5472    #[serde(skip_serializing_if = "Option::is_none", default)]
5473    pub rows: Option<bool>,
5474}
5475
5476/// TOP clause (SQL Server)
5477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5478#[cfg_attr(feature = "bindings", derive(TS))]
5479pub struct Top {
5480    pub this: Expression,
5481    pub percent: bool,
5482    pub with_ties: bool,
5483    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5484    #[serde(default)]
5485    pub parenthesized: bool,
5486}
5487
5488/// FETCH FIRST/NEXT clause (SQL standard)
5489#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5490#[cfg_attr(feature = "bindings", derive(TS))]
5491pub struct Fetch {
5492    /// FIRST or NEXT
5493    pub direction: String,
5494    /// Count expression (optional)
5495    pub count: Option<Expression>,
5496    /// PERCENT modifier
5497    pub percent: bool,
5498    /// ROWS or ROW keyword present
5499    pub rows: bool,
5500    /// WITH TIES modifier
5501    pub with_ties: bool,
5502}
5503
5504/// Represent a QUALIFY clause for filtering on window function results.
5505///
5506/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5507/// typically references a window function (e.g.
5508/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5510#[cfg_attr(feature = "bindings", derive(TS))]
5511pub struct Qualify {
5512    /// The filter predicate over window function results.
5513    pub this: Expression,
5514}
5515
5516/// SAMPLE / TABLESAMPLE clause
5517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5518#[cfg_attr(feature = "bindings", derive(TS))]
5519pub struct Sample {
5520    pub method: SampleMethod,
5521    pub size: Expression,
5522    pub seed: Option<Expression>,
5523    /// ClickHouse OFFSET expression after SAMPLE size
5524    #[serde(default)]
5525    pub offset: Option<Expression>,
5526    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5527    pub unit_after_size: bool,
5528    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5529    #[serde(default)]
5530    pub use_sample_keyword: bool,
5531    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5532    #[serde(default)]
5533    pub explicit_method: bool,
5534    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5535    #[serde(default)]
5536    pub method_before_size: bool,
5537    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5538    #[serde(default)]
5539    pub use_seed_keyword: bool,
5540    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5541    pub bucket_numerator: Option<Box<Expression>>,
5542    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5543    pub bucket_denominator: Option<Box<Expression>>,
5544    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5545    pub bucket_field: Option<Box<Expression>>,
5546    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5547    #[serde(default)]
5548    pub is_using_sample: bool,
5549    /// Whether the unit was explicitly PERCENT (vs ROWS)
5550    #[serde(default)]
5551    pub is_percent: bool,
5552    /// Whether to suppress method output (for cross-dialect transpilation)
5553    #[serde(default)]
5554    pub suppress_method_output: bool,
5555}
5556
5557/// Sample method
5558#[derive(
5559    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5560)]
5561#[cfg_attr(feature = "bindings", derive(TS))]
5562pub enum SampleMethod {
5563    Bernoulli,
5564    System,
5565    Block,
5566    Row,
5567    Percent,
5568    /// Hive bucket sampling
5569    Bucket,
5570    /// DuckDB reservoir sampling
5571    Reservoir,
5572}
5573
5574/// Named window definition (WINDOW w AS (...))
5575#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5576#[cfg_attr(feature = "bindings", derive(TS))]
5577pub struct NamedWindow {
5578    pub name: Identifier,
5579    pub spec: Over,
5580}
5581
5582/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5583///
5584/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5585/// that reference themselves. Each CTE is defined in the `ctes` vector and
5586/// can be referenced by name in subsequent CTEs and in the main query body.
5587#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5588#[cfg_attr(feature = "bindings", derive(TS))]
5589pub struct With {
5590    /// The list of CTE definitions, in order.
5591    pub ctes: Vec<Cte>,
5592    /// Whether the WITH RECURSIVE keyword was used.
5593    pub recursive: bool,
5594    /// Leading comments before the statement
5595    #[serde(default)]
5596    pub leading_comments: Vec<String>,
5597    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5598    #[serde(default, skip_serializing_if = "Option::is_none")]
5599    pub search: Option<Box<Expression>>,
5600}
5601
5602/// Represent a single Common Table Expression definition.
5603///
5604/// A CTE has a name (`alias`), an optional column list, and a body query.
5605/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5606/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5607/// the expression comes before the alias (`alias_first`).
5608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5609#[cfg_attr(feature = "bindings", derive(TS))]
5610pub struct Cte {
5611    /// The CTE name.
5612    pub alias: Identifier,
5613    /// The CTE body (typically a SELECT, UNION, etc.).
5614    pub this: Expression,
5615    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5616    pub columns: Vec<Identifier>,
5617    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5618    pub materialized: Option<bool>,
5619    /// USING KEY (columns) for DuckDB recursive CTEs
5620    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5621    pub key_expressions: Vec<Identifier>,
5622    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5623    #[serde(default)]
5624    pub alias_first: bool,
5625    /// Comments associated with this CTE (placed after alias name, before AS)
5626    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5627    pub comments: Vec<String>,
5628}
5629
5630/// Window specification
5631#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5632#[cfg_attr(feature = "bindings", derive(TS))]
5633pub struct WindowSpec {
5634    pub partition_by: Vec<Expression>,
5635    pub order_by: Vec<Ordered>,
5636    pub frame: Option<WindowFrame>,
5637}
5638
5639/// OVER clause
5640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5641#[cfg_attr(feature = "bindings", derive(TS))]
5642pub struct Over {
5643    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
5644    pub window_name: Option<Identifier>,
5645    pub partition_by: Vec<Expression>,
5646    pub order_by: Vec<Ordered>,
5647    pub frame: Option<WindowFrame>,
5648    pub alias: Option<Identifier>,
5649}
5650
5651/// Window frame
5652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5653#[cfg_attr(feature = "bindings", derive(TS))]
5654pub struct WindowFrame {
5655    pub kind: WindowFrameKind,
5656    pub start: WindowFrameBound,
5657    pub end: Option<WindowFrameBound>,
5658    pub exclude: Option<WindowFrameExclude>,
5659    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
5660    #[serde(default, skip_serializing_if = "Option::is_none")]
5661    pub kind_text: Option<String>,
5662    /// Original text of the start bound side keyword (e.g. "preceding")
5663    #[serde(default, skip_serializing_if = "Option::is_none")]
5664    pub start_side_text: Option<String>,
5665    /// Original text of the end bound side keyword
5666    #[serde(default, skip_serializing_if = "Option::is_none")]
5667    pub end_side_text: Option<String>,
5668}
5669
5670#[derive(
5671    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5672)]
5673#[cfg_attr(feature = "bindings", derive(TS))]
5674pub enum WindowFrameKind {
5675    Rows,
5676    Range,
5677    Groups,
5678}
5679
5680/// EXCLUDE clause for window frames
5681#[derive(
5682    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5683)]
5684#[cfg_attr(feature = "bindings", derive(TS))]
5685pub enum WindowFrameExclude {
5686    CurrentRow,
5687    Group,
5688    Ties,
5689    NoOthers,
5690}
5691
5692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5693#[cfg_attr(feature = "bindings", derive(TS))]
5694pub enum WindowFrameBound {
5695    CurrentRow,
5696    UnboundedPreceding,
5697    UnboundedFollowing,
5698    Preceding(Box<Expression>),
5699    Following(Box<Expression>),
5700    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
5701    BarePreceding,
5702    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
5703    BareFollowing,
5704    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
5705    Value(Box<Expression>),
5706}
5707
5708/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
5709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5710#[cfg_attr(feature = "bindings", derive(TS))]
5711pub struct StructField {
5712    pub name: String,
5713    pub data_type: DataType,
5714    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5715    pub options: Vec<Expression>,
5716    #[serde(default, skip_serializing_if = "Option::is_none")]
5717    pub comment: Option<String>,
5718}
5719
5720impl StructField {
5721    /// Create a new struct field without options
5722    pub fn new(name: String, data_type: DataType) -> Self {
5723        Self {
5724            name,
5725            data_type,
5726            options: Vec::new(),
5727            comment: None,
5728        }
5729    }
5730
5731    /// Create a new struct field with options
5732    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
5733        Self {
5734            name,
5735            data_type,
5736            options,
5737            comment: None,
5738        }
5739    }
5740
5741    /// Create a new struct field with options and comment
5742    pub fn with_options_and_comment(
5743        name: String,
5744        data_type: DataType,
5745        options: Vec<Expression>,
5746        comment: Option<String>,
5747    ) -> Self {
5748        Self {
5749            name,
5750            data_type,
5751            options,
5752            comment,
5753        }
5754    }
5755}
5756
5757/// Oracle-specific data types whose semantics cannot be represented losslessly by the
5758/// generic [`DataType`] variants.
5759///
5760/// Keeping these types structured allows the Oracle parser to retain details such as a
5761/// negative `NUMBER` scale, `BYTE`/`CHAR` length semantics, interval precisions, and
5762/// `TIMESTAMP WITH LOCAL TIME ZONE` until the target dialect is known.
5763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5764#[cfg_attr(feature = "bindings", derive(TS))]
5765#[serde(tag = "oracle_data_type", rename_all = "snake_case")]
5766pub enum OracleDataType {
5767    Number {
5768        precision: Option<u32>,
5769        scale: Option<i32>,
5770    },
5771    BinaryFloat,
5772    BinaryDouble,
5773    Float {
5774        precision: Option<u32>,
5775    },
5776    Character {
5777        kind: OracleCharacterKind,
5778        length: Option<u32>,
5779        semantics: Option<OracleCharacterLengthSemantics>,
5780    },
5781    Date,
5782    Timestamp {
5783        precision: Option<u32>,
5784        timezone: OracleTimestampTimeZone,
5785    },
5786    IntervalYearToMonth {
5787        year_precision: Option<u32>,
5788    },
5789    IntervalDayToSecond {
5790        day_precision: Option<u32>,
5791        fractional_seconds_precision: Option<u32>,
5792    },
5793    Clob {
5794        national: bool,
5795    },
5796    Blob,
5797    Raw {
5798        length: Option<u32>,
5799    },
5800    Long {
5801        raw: bool,
5802    },
5803    RowId,
5804}
5805
5806#[derive(
5807    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5808)]
5809#[cfg_attr(feature = "bindings", derive(TS))]
5810#[serde(rename_all = "snake_case")]
5811pub enum OracleCharacterKind {
5812    Char,
5813    VarChar,
5814    NChar,
5815    NVarChar,
5816}
5817
5818#[derive(
5819    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5820)]
5821#[cfg_attr(feature = "bindings", derive(TS))]
5822#[serde(rename_all = "snake_case")]
5823pub enum OracleCharacterLengthSemantics {
5824    Byte,
5825    Char,
5826}
5827
5828#[derive(
5829    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5830)]
5831#[cfg_attr(feature = "bindings", derive(TS))]
5832#[serde(rename_all = "snake_case")]
5833pub enum OracleTimestampTimeZone {
5834    None,
5835    WithTimeZone,
5836    WithLocalTimeZone,
5837}
5838
5839/// Enumerate all SQL data types recognized by the parser.
5840///
5841/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
5842/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
5843/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
5844///
5845/// This enum is used in CAST expressions, column definitions, function return
5846/// types, and anywhere a data type specification appears in SQL.
5847///
5848/// Types that do not match any known variant fall through to `Custom { name }`,
5849/// preserving the original type name for round-trip fidelity.
5850#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5851#[cfg_attr(feature = "bindings", derive(TS))]
5852#[serde(tag = "data_type", rename_all = "snake_case")]
5853pub enum DataType {
5854    // Numeric
5855    Boolean,
5856    TinyInt {
5857        length: Option<u32>,
5858    },
5859    SmallInt {
5860        length: Option<u32>,
5861    },
5862    /// Int type with optional length. `integer_spelling` indicates whether the original
5863    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
5864    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
5865    Int {
5866        length: Option<u32>,
5867        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5868        integer_spelling: bool,
5869    },
5870    BigInt {
5871        length: Option<u32>,
5872    },
5873    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
5874    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
5875    /// preserve the original spelling.
5876    Float {
5877        precision: Option<u32>,
5878        scale: Option<u32>,
5879        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5880        real_spelling: bool,
5881    },
5882    Double {
5883        precision: Option<u32>,
5884        scale: Option<u32>,
5885    },
5886    Decimal {
5887        precision: Option<u32>,
5888        scale: Option<u32>,
5889    },
5890    /// Structured Oracle data type retained until the target dialect is known.
5891    Oracle {
5892        oracle_type: OracleDataType,
5893    },
5894
5895    // String
5896    Char {
5897        length: Option<u32>,
5898    },
5899    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
5900    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
5901    VarChar {
5902        length: Option<u32>,
5903        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5904        parenthesized_length: bool,
5905    },
5906    /// String type with optional max length (BigQuery STRING(n))
5907    String {
5908        length: Option<u32>,
5909    },
5910    Text,
5911    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
5912    TextWithLength {
5913        length: u32,
5914    },
5915
5916    // Binary
5917    Binary {
5918        length: Option<u32>,
5919    },
5920    VarBinary {
5921        length: Option<u32>,
5922    },
5923    Blob,
5924
5925    // Bit
5926    Bit {
5927        length: Option<u32>,
5928    },
5929    VarBit {
5930        length: Option<u32>,
5931    },
5932
5933    // Date/Time
5934    Date,
5935    Time {
5936        precision: Option<u32>,
5937        #[serde(default)]
5938        timezone: bool,
5939    },
5940    Timestamp {
5941        precision: Option<u32>,
5942        timezone: bool,
5943    },
5944    Interval {
5945        unit: Option<String>,
5946        /// For range intervals like INTERVAL DAY TO HOUR
5947        #[serde(default, skip_serializing_if = "Option::is_none")]
5948        to: Option<String>,
5949    },
5950
5951    // JSON
5952    Json,
5953    JsonB,
5954
5955    // UUID
5956    Uuid,
5957
5958    // Array
5959    Array {
5960        element_type: Box<DataType>,
5961        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
5962        #[serde(default, skip_serializing_if = "Option::is_none")]
5963        dimension: Option<u32>,
5964    },
5965
5966    /// List type (Materialize): INT LIST, TEXT LIST LIST
5967    /// Uses postfix LIST syntax instead of ARRAY<T>
5968    List {
5969        element_type: Box<DataType>,
5970    },
5971
5972    // Struct/Map
5973    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
5974    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
5975    Struct {
5976        fields: Vec<StructField>,
5977        nested: bool,
5978    },
5979    Map {
5980        key_type: Box<DataType>,
5981        value_type: Box<DataType>,
5982    },
5983
5984    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
5985    Enum {
5986        values: Vec<String>,
5987        #[serde(default, skip_serializing_if = "Vec::is_empty")]
5988        assignments: Vec<Option<String>>,
5989    },
5990
5991    // Set type (MySQL): SET('a', 'b', 'c')
5992    Set {
5993        values: Vec<String>,
5994    },
5995
5996    // Union type (DuckDB): UNION(num INT, str TEXT)
5997    Union {
5998        fields: Vec<(String, DataType)>,
5999    },
6000
6001    // Vector (Snowflake / SingleStore)
6002    Vector {
6003        #[serde(default)]
6004        element_type: Option<Box<DataType>>,
6005        dimension: Option<u32>,
6006    },
6007
6008    // Object (Snowflake structured type)
6009    // fields: Vec of (field_name, field_type, not_null)
6010    Object {
6011        fields: Vec<(String, DataType, bool)>,
6012        modifier: Option<String>,
6013    },
6014
6015    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
6016    Nullable {
6017        inner: Box<DataType>,
6018    },
6019
6020    // Custom/User-defined
6021    Custom {
6022        name: String,
6023    },
6024
6025    // Spatial types
6026    Geometry {
6027        subtype: Option<String>,
6028        srid: Option<u32>,
6029    },
6030    Geography {
6031        subtype: Option<String>,
6032        srid: Option<u32>,
6033    },
6034
6035    // Character Set (for CONVERT USING in MySQL)
6036    // Renders as CHAR CHARACTER SET {name} in cast target
6037    CharacterSet {
6038        name: String,
6039    },
6040
6041    // Unknown
6042    Unknown,
6043}
6044
6045/// Array expression
6046#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6047#[cfg_attr(feature = "bindings", derive(TS))]
6048#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
6049pub struct Array {
6050    pub expressions: Vec<Expression>,
6051}
6052
6053/// Struct expression
6054#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6055#[cfg_attr(feature = "bindings", derive(TS))]
6056pub struct Struct {
6057    pub fields: Vec<(Option<String>, Expression)>,
6058}
6059
6060/// Tuple expression
6061#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6062#[cfg_attr(feature = "bindings", derive(TS))]
6063pub struct Tuple {
6064    pub expressions: Vec<Expression>,
6065}
6066
6067/// Interval expression
6068#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6069#[cfg_attr(feature = "bindings", derive(TS))]
6070pub struct Interval {
6071    /// The value expression (e.g., '1', 5, column_ref)
6072    pub this: Option<Expression>,
6073    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
6074    pub unit: Option<IntervalUnitSpec>,
6075}
6076
6077/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
6078#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6079#[cfg_attr(feature = "bindings", derive(TS))]
6080#[serde(tag = "type", rename_all = "snake_case")]
6081pub enum IntervalUnitSpec {
6082    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
6083    Simple {
6084        unit: IntervalUnit,
6085        /// Whether to use plural form (e.g., DAYS vs DAY)
6086        use_plural: bool,
6087    },
6088    /// Interval span (e.g., HOUR TO SECOND)
6089    Span(IntervalSpan),
6090    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6091    /// The start and end can be expressions like function calls with precision
6092    ExprSpan(IntervalSpanExpr),
6093    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6094    Expr(Box<Expression>),
6095}
6096
6097/// Interval span for ranges like HOUR TO SECOND
6098#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6099#[cfg_attr(feature = "bindings", derive(TS))]
6100pub struct IntervalSpan {
6101    /// Start unit (e.g., HOUR)
6102    pub this: IntervalUnit,
6103    /// End unit (e.g., SECOND)
6104    pub expression: IntervalUnit,
6105}
6106
6107/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6108/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6110#[cfg_attr(feature = "bindings", derive(TS))]
6111pub struct IntervalSpanExpr {
6112    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6113    pub this: Box<Expression>,
6114    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6115    pub expression: Box<Expression>,
6116}
6117
6118#[derive(
6119    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6120)]
6121#[cfg_attr(feature = "bindings", derive(TS))]
6122pub enum IntervalUnit {
6123    Year,
6124    Quarter,
6125    Month,
6126    Week,
6127    Day,
6128    Hour,
6129    Minute,
6130    Second,
6131    Millisecond,
6132    Microsecond,
6133    Nanosecond,
6134}
6135
6136/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6137#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6138#[cfg_attr(feature = "bindings", derive(TS))]
6139pub struct Command {
6140    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6141    pub this: String,
6142}
6143
6144/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6145/// Syntax: PREPARE name [(type, ...)] AS statement
6146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6147#[cfg_attr(feature = "bindings", derive(TS))]
6148pub struct PrepareStatement {
6149    /// The prepared statement name.
6150    pub name: Identifier,
6151    /// Optional PostgreSQL parameter type list.
6152    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6153    pub parameter_types: Vec<DataType>,
6154    /// The statement to execute when the prepared statement is invoked.
6155    pub statement: Expression,
6156}
6157
6158/// T-SQL TRY/CATCH block.
6159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6160#[cfg_attr(feature = "bindings", derive(TS))]
6161pub struct TryCatch {
6162    /// Statements inside BEGIN TRY ... END TRY.
6163    #[serde(default)]
6164    pub try_body: Vec<Expression>,
6165    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6166    #[serde(default, skip_serializing_if = "Option::is_none")]
6167    pub catch_body: Option<Vec<Expression>>,
6168}
6169
6170/// EXEC/EXECUTE statement (TSQL stored procedure call)
6171/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6173#[cfg_attr(feature = "bindings", derive(TS))]
6174pub struct ExecuteStatement {
6175    /// The procedure name (can be qualified: schema.proc_name)
6176    pub this: Expression,
6177    /// Optional T-SQL return-status variable (`EXECUTE @status = procedure`).
6178    #[serde(default, skip_serializing_if = "Option::is_none")]
6179    pub return_status: Option<String>,
6180    /// Named parameters: @param=value pairs
6181    #[serde(default)]
6182    pub parameters: Vec<ExecuteParameter>,
6183    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6184    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6185    pub arguments: Vec<Expression>,
6186    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6187    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6188    pub prepared: bool,
6189    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6190    #[serde(default, skip_serializing_if = "Option::is_none")]
6191    pub suffix: Option<String>,
6192}
6193
6194/// Named parameter in EXEC statement: @name=value
6195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6196#[cfg_attr(feature = "bindings", derive(TS))]
6197pub struct ExecuteParameter {
6198    /// Parameter name (including @)
6199    pub name: String,
6200    /// Parameter value
6201    pub value: Expression,
6202    /// Whether this is a positional parameter (no = sign)
6203    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6204    pub positional: bool,
6205    /// TSQL OUTPUT modifier on parameter
6206    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6207    pub output: bool,
6208}
6209
6210/// KILL statement (MySQL/MariaDB)
6211/// KILL [CONNECTION | QUERY] <id>
6212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6213#[cfg_attr(feature = "bindings", derive(TS))]
6214pub struct Kill {
6215    /// The target (process ID or connection ID)
6216    pub this: Expression,
6217    /// Optional kind: "CONNECTION" or "QUERY"
6218    pub kind: Option<String>,
6219}
6220
6221/// Snowflake CREATE TASK statement
6222#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6223#[cfg_attr(feature = "bindings", derive(TS))]
6224pub struct CreateTask {
6225    pub or_replace: bool,
6226    pub if_not_exists: bool,
6227    /// Task name (possibly qualified: db.schema.task)
6228    pub name: String,
6229    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6230    pub properties: String,
6231    /// The SQL statement body after AS
6232    pub body: Expression,
6233}
6234
6235/// Raw/unparsed SQL
6236#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6237#[cfg_attr(feature = "bindings", derive(TS))]
6238pub struct Raw {
6239    pub sql: String,
6240}
6241
6242// ============================================================================
6243// Function expression types
6244// ============================================================================
6245
6246/// Generic unary function (takes a single argument)
6247#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6248#[cfg_attr(feature = "bindings", derive(TS))]
6249pub struct UnaryFunc {
6250    pub this: Expression,
6251    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6252    #[serde(skip_serializing_if = "Option::is_none", default)]
6253    pub original_name: Option<String>,
6254    /// Inferred data type from type annotation
6255    #[serde(default, skip_serializing_if = "Option::is_none")]
6256    #[ast(skip)]
6257    pub inferred_type: Option<DataType>,
6258}
6259
6260impl UnaryFunc {
6261    /// Create a new UnaryFunc with no original_name
6262    pub fn new(this: Expression) -> Self {
6263        Self {
6264            this,
6265            original_name: None,
6266            inferred_type: None,
6267        }
6268    }
6269
6270    /// Create a new UnaryFunc with an original name for round-trip preservation
6271    pub fn with_name(this: Expression, name: String) -> Self {
6272        Self {
6273            this,
6274            original_name: Some(name),
6275            inferred_type: None,
6276        }
6277    }
6278}
6279
6280/// CHAR/CHR function with multiple args and optional USING charset
6281/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6282/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6283#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6284#[cfg_attr(feature = "bindings", derive(TS))]
6285pub struct CharFunc {
6286    pub args: Vec<Expression>,
6287    #[serde(skip_serializing_if = "Option::is_none", default)]
6288    pub charset: Option<String>,
6289    /// Original function name (CHAR or CHR), defaults to CHAR
6290    #[serde(skip_serializing_if = "Option::is_none", default)]
6291    pub name: Option<String>,
6292}
6293
6294/// Generic binary function (takes two arguments)
6295#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6296#[cfg_attr(feature = "bindings", derive(TS))]
6297pub struct BinaryFunc {
6298    pub this: Expression,
6299    pub expression: Expression,
6300    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6301    #[serde(skip_serializing_if = "Option::is_none", default)]
6302    pub original_name: Option<String>,
6303    /// Inferred data type from type annotation
6304    #[serde(default, skip_serializing_if = "Option::is_none")]
6305    #[ast(skip)]
6306    pub inferred_type: Option<DataType>,
6307}
6308
6309/// Variable argument function
6310#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6311#[cfg_attr(feature = "bindings", derive(TS))]
6312pub struct VarArgFunc {
6313    pub expressions: Vec<Expression>,
6314    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6315    #[serde(skip_serializing_if = "Option::is_none", default)]
6316    pub original_name: Option<String>,
6317    /// Inferred data type from type annotation
6318    #[serde(default, skip_serializing_if = "Option::is_none")]
6319    #[ast(skip)]
6320    pub inferred_type: Option<DataType>,
6321}
6322
6323/// CONCAT_WS function
6324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6325#[cfg_attr(feature = "bindings", derive(TS))]
6326pub struct ConcatWs {
6327    pub separator: Expression,
6328    pub expressions: Vec<Expression>,
6329}
6330
6331/// SUBSTRING function
6332#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6333#[cfg_attr(feature = "bindings", derive(TS))]
6334pub struct SubstringFunc {
6335    pub this: Expression,
6336    pub start: Expression,
6337    pub length: Option<Expression>,
6338    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6339    #[serde(default)]
6340    pub from_for_syntax: bool,
6341}
6342
6343/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6345#[cfg_attr(feature = "bindings", derive(TS))]
6346pub struct OverlayFunc {
6347    pub this: Expression,
6348    pub replacement: Expression,
6349    pub from: Expression,
6350    pub length: Option<Expression>,
6351}
6352
6353/// TRIM function
6354#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6355#[cfg_attr(feature = "bindings", derive(TS))]
6356pub struct TrimFunc {
6357    pub this: Expression,
6358    pub characters: Option<Expression>,
6359    pub position: TrimPosition,
6360    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6361    #[serde(default)]
6362    pub sql_standard_syntax: bool,
6363    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6364    #[serde(default)]
6365    pub position_explicit: bool,
6366}
6367
6368#[derive(
6369    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6370)]
6371#[cfg_attr(feature = "bindings", derive(TS))]
6372pub enum TrimPosition {
6373    Both,
6374    Leading,
6375    Trailing,
6376}
6377
6378/// REPLACE function
6379#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6380#[cfg_attr(feature = "bindings", derive(TS))]
6381pub struct ReplaceFunc {
6382    pub this: Expression,
6383    pub old: Expression,
6384    pub new: Expression,
6385}
6386
6387/// LEFT/RIGHT function
6388#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6389#[cfg_attr(feature = "bindings", derive(TS))]
6390pub struct LeftRightFunc {
6391    pub this: Expression,
6392    pub length: Expression,
6393}
6394
6395/// REPEAT function
6396#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6397#[cfg_attr(feature = "bindings", derive(TS))]
6398pub struct RepeatFunc {
6399    pub this: Expression,
6400    pub times: Expression,
6401}
6402
6403/// LPAD/RPAD function
6404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6405#[cfg_attr(feature = "bindings", derive(TS))]
6406pub struct PadFunc {
6407    pub this: Expression,
6408    pub length: Expression,
6409    pub fill: Option<Expression>,
6410}
6411
6412/// SPLIT function
6413#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6414#[cfg_attr(feature = "bindings", derive(TS))]
6415pub struct SplitFunc {
6416    pub this: Expression,
6417    pub delimiter: Expression,
6418}
6419
6420/// REGEXP_LIKE function
6421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6422#[cfg_attr(feature = "bindings", derive(TS))]
6423pub struct RegexpFunc {
6424    pub this: Expression,
6425    pub pattern: Expression,
6426    pub flags: Option<Expression>,
6427}
6428
6429/// REGEXP_REPLACE function
6430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6431#[cfg_attr(feature = "bindings", derive(TS))]
6432pub struct RegexpReplaceFunc {
6433    pub this: Expression,
6434    pub pattern: Expression,
6435    pub replacement: Expression,
6436    pub flags: Option<Expression>,
6437}
6438
6439/// REGEXP_EXTRACT function
6440#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6441#[cfg_attr(feature = "bindings", derive(TS))]
6442pub struct RegexpExtractFunc {
6443    pub this: Expression,
6444    pub pattern: Expression,
6445    pub group: Option<Expression>,
6446}
6447
6448/// ROUND function
6449#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6450#[cfg_attr(feature = "bindings", derive(TS))]
6451pub struct RoundFunc {
6452    pub this: Expression,
6453    pub decimals: Option<Expression>,
6454}
6455
6456/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6458#[cfg_attr(feature = "bindings", derive(TS))]
6459pub struct FloorFunc {
6460    pub this: Expression,
6461    pub scale: Option<Expression>,
6462    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6463    #[serde(skip_serializing_if = "Option::is_none", default)]
6464    pub to: Option<Expression>,
6465}
6466
6467/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6468#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6469#[cfg_attr(feature = "bindings", derive(TS))]
6470pub struct CeilFunc {
6471    pub this: Expression,
6472    #[serde(skip_serializing_if = "Option::is_none", default)]
6473    pub decimals: Option<Expression>,
6474    /// Time unit for Druid-style CEIL(time TO unit) syntax
6475    #[serde(skip_serializing_if = "Option::is_none", default)]
6476    pub to: Option<Expression>,
6477}
6478
6479/// LOG function
6480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6481#[cfg_attr(feature = "bindings", derive(TS))]
6482pub struct LogFunc {
6483    pub this: Expression,
6484    pub base: Option<Expression>,
6485}
6486
6487/// CURRENT_DATE (no arguments)
6488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6489#[cfg_attr(feature = "bindings", derive(TS))]
6490pub struct CurrentDate;
6491
6492/// CURRENT_TIME
6493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6494#[cfg_attr(feature = "bindings", derive(TS))]
6495pub struct CurrentTime {
6496    pub precision: Option<u32>,
6497}
6498
6499/// CURRENT_TIMESTAMP
6500#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6501#[cfg_attr(feature = "bindings", derive(TS))]
6502pub struct CurrentTimestamp {
6503    pub precision: Option<u32>,
6504    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6505    #[serde(default)]
6506    pub sysdate: bool,
6507}
6508
6509/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6510#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6511#[cfg_attr(feature = "bindings", derive(TS))]
6512pub struct CurrentTimestampLTZ {
6513    pub precision: Option<u32>,
6514}
6515
6516/// AT TIME ZONE expression for timezone conversion
6517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6518#[cfg_attr(feature = "bindings", derive(TS))]
6519pub struct AtTimeZone {
6520    /// The expression to convert
6521    pub this: Expression,
6522    /// The target timezone
6523    pub zone: Expression,
6524}
6525
6526/// DATE_ADD / DATE_SUB function
6527#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6528#[cfg_attr(feature = "bindings", derive(TS))]
6529pub struct DateAddFunc {
6530    pub this: Expression,
6531    pub interval: Expression,
6532    pub unit: IntervalUnit,
6533}
6534
6535/// DATEDIFF function
6536#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6537#[cfg_attr(feature = "bindings", derive(TS))]
6538pub struct DateDiffFunc {
6539    pub this: Expression,
6540    pub expression: Expression,
6541    pub unit: Option<IntervalUnit>,
6542}
6543
6544/// DATE_TRUNC function
6545#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6546#[cfg_attr(feature = "bindings", derive(TS))]
6547pub struct DateTruncFunc {
6548    pub this: Expression,
6549    pub unit: DateTimeField,
6550}
6551
6552/// EXTRACT function
6553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6554#[cfg_attr(feature = "bindings", derive(TS))]
6555pub struct ExtractFunc {
6556    pub this: Expression,
6557    pub field: DateTimeField,
6558}
6559
6560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6561#[cfg_attr(feature = "bindings", derive(TS))]
6562pub enum DateTimeField {
6563    Year,
6564    Month,
6565    Day,
6566    Hour,
6567    Minute,
6568    Second,
6569    Millisecond,
6570    Microsecond,
6571    DayOfWeek,
6572    DayOfYear,
6573    Week,
6574    /// Week with a modifier like WEEK(monday), WEEK(sunday)
6575    WeekWithModifier(String),
6576    Quarter,
6577    Epoch,
6578    Timezone,
6579    TimezoneHour,
6580    TimezoneMinute,
6581    Date,
6582    Time,
6583    /// Custom datetime field for dialect-specific or arbitrary fields
6584    Custom(String),
6585}
6586
6587/// TO_DATE function
6588#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6589#[cfg_attr(feature = "bindings", derive(TS))]
6590pub struct ToDateFunc {
6591    pub this: Expression,
6592    pub format: Option<Expression>,
6593}
6594
6595/// TO_TIMESTAMP function
6596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6597#[cfg_attr(feature = "bindings", derive(TS))]
6598pub struct ToTimestampFunc {
6599    pub this: Expression,
6600    pub format: Option<Expression>,
6601}
6602
6603/// IF function
6604#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6605#[cfg_attr(feature = "bindings", derive(TS))]
6606pub struct IfFunc {
6607    pub condition: Expression,
6608    pub true_value: Expression,
6609    pub false_value: Option<Expression>,
6610    /// Original function name (IF, IFF, IIF) for round-trip preservation
6611    #[serde(skip_serializing_if = "Option::is_none", default)]
6612    pub original_name: Option<String>,
6613    /// Inferred data type from type annotation
6614    #[serde(default, skip_serializing_if = "Option::is_none")]
6615    #[ast(skip)]
6616    pub inferred_type: Option<DataType>,
6617}
6618
6619/// NVL2 function
6620#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6621#[cfg_attr(feature = "bindings", derive(TS))]
6622pub struct Nvl2Func {
6623    pub this: Expression,
6624    pub true_value: Expression,
6625    pub false_value: Expression,
6626    /// Inferred data type from type annotation
6627    #[serde(default, skip_serializing_if = "Option::is_none")]
6628    #[ast(skip)]
6629    pub inferred_type: Option<DataType>,
6630}
6631
6632// ============================================================================
6633// Typed Aggregate Function types
6634// ============================================================================
6635
6636/// Generic aggregate function base type
6637#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6638#[cfg_attr(feature = "bindings", derive(TS))]
6639pub struct AggFunc {
6640    pub this: Expression,
6641    pub distinct: bool,
6642    pub filter: Option<Expression>,
6643    pub order_by: Vec<Ordered>,
6644    /// Original function name (case-preserving) when parsed from SQL
6645    #[serde(skip_serializing_if = "Option::is_none", default)]
6646    pub name: Option<String>,
6647    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
6648    #[serde(skip_serializing_if = "Option::is_none", default)]
6649    pub ignore_nulls: Option<bool>,
6650    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
6651    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
6652    #[serde(skip_serializing_if = "Option::is_none", default)]
6653    pub having_max: Option<(Box<Expression>, bool)>,
6654    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
6655    #[serde(skip_serializing_if = "Option::is_none", default)]
6656    pub limit: Option<Box<Expression>>,
6657    /// Inferred data type from type annotation
6658    #[serde(default, skip_serializing_if = "Option::is_none")]
6659    #[ast(skip)]
6660    pub inferred_type: Option<DataType>,
6661}
6662
6663/// COUNT function with optional star
6664#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6665#[cfg_attr(feature = "bindings", derive(TS))]
6666pub struct CountFunc {
6667    pub this: Option<Expression>,
6668    pub star: bool,
6669    pub distinct: bool,
6670    pub filter: Option<Expression>,
6671    /// IGNORE NULLS (true) or RESPECT NULLS (false)
6672    #[serde(default, skip_serializing_if = "Option::is_none")]
6673    pub ignore_nulls: Option<bool>,
6674    /// Original function name for case preservation (e.g., "count" or "COUNT")
6675    #[serde(default, skip_serializing_if = "Option::is_none")]
6676    pub original_name: Option<String>,
6677    /// Inferred data type from type annotation
6678    #[serde(default, skip_serializing_if = "Option::is_none")]
6679    #[ast(skip)]
6680    pub inferred_type: Option<DataType>,
6681}
6682
6683/// GROUP_CONCAT function (MySQL style)
6684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6685#[cfg_attr(feature = "bindings", derive(TS))]
6686pub struct GroupConcatFunc {
6687    pub this: Expression,
6688    pub separator: Option<Expression>,
6689    pub order_by: Option<Vec<Ordered>>,
6690    pub distinct: bool,
6691    pub filter: Option<Expression>,
6692    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
6693    #[serde(default, skip_serializing_if = "Option::is_none")]
6694    pub limit: Option<Box<Expression>>,
6695    /// Inferred data type from type annotation
6696    #[serde(default, skip_serializing_if = "Option::is_none")]
6697    #[ast(skip)]
6698    pub inferred_type: Option<DataType>,
6699}
6700
6701/// STRING_AGG function (PostgreSQL/Standard SQL)
6702#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6703#[cfg_attr(feature = "bindings", derive(TS))]
6704pub struct StringAggFunc {
6705    pub this: Expression,
6706    #[serde(default)]
6707    pub separator: Option<Expression>,
6708    #[serde(default)]
6709    pub order_by: Option<Vec<Ordered>>,
6710    #[serde(default)]
6711    pub distinct: bool,
6712    #[serde(default)]
6713    pub filter: Option<Expression>,
6714    /// BigQuery LIMIT inside STRING_AGG
6715    #[serde(default, skip_serializing_if = "Option::is_none")]
6716    pub limit: Option<Box<Expression>>,
6717    /// Inferred data type from type annotation
6718    #[serde(default, skip_serializing_if = "Option::is_none")]
6719    #[ast(skip)]
6720    pub inferred_type: Option<DataType>,
6721}
6722
6723/// LISTAGG function (Oracle style)
6724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6725#[cfg_attr(feature = "bindings", derive(TS))]
6726pub struct ListAggFunc {
6727    pub this: Expression,
6728    pub separator: Option<Expression>,
6729    pub on_overflow: Option<ListAggOverflow>,
6730    pub order_by: Option<Vec<Ordered>>,
6731    pub distinct: bool,
6732    pub filter: Option<Expression>,
6733    /// Inferred data type from type annotation
6734    #[serde(default, skip_serializing_if = "Option::is_none")]
6735    #[ast(skip)]
6736    pub inferred_type: Option<DataType>,
6737}
6738
6739/// LISTAGG ON OVERFLOW behavior
6740#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6741#[cfg_attr(feature = "bindings", derive(TS))]
6742pub enum ListAggOverflow {
6743    Error,
6744    Truncate {
6745        filler: Option<Expression>,
6746        with_count: bool,
6747    },
6748}
6749
6750/// SUM_IF / COUNT_IF function
6751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6752#[cfg_attr(feature = "bindings", derive(TS))]
6753pub struct SumIfFunc {
6754    pub this: Expression,
6755    pub condition: Expression,
6756    pub filter: Option<Expression>,
6757    /// Inferred data type from type annotation
6758    #[serde(default, skip_serializing_if = "Option::is_none")]
6759    #[ast(skip)]
6760    pub inferred_type: Option<DataType>,
6761}
6762
6763/// APPROX_PERCENTILE function
6764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6765#[cfg_attr(feature = "bindings", derive(TS))]
6766pub struct ApproxPercentileFunc {
6767    pub this: Expression,
6768    pub percentile: Expression,
6769    pub accuracy: Option<Expression>,
6770    pub filter: Option<Expression>,
6771}
6772
6773/// PERCENTILE_CONT / PERCENTILE_DISC function
6774#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6775#[cfg_attr(feature = "bindings", derive(TS))]
6776pub struct PercentileFunc {
6777    pub this: Expression,
6778    pub percentile: Expression,
6779    pub order_by: Option<Vec<Ordered>>,
6780    pub filter: Option<Expression>,
6781}
6782
6783// ============================================================================
6784// Typed Window Function types
6785// ============================================================================
6786
6787/// ROW_NUMBER function (no arguments)
6788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6789#[cfg_attr(feature = "bindings", derive(TS))]
6790pub struct RowNumber;
6791
6792/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6794#[cfg_attr(feature = "bindings", derive(TS))]
6795pub struct Rank {
6796    /// DuckDB: RANK(ORDER BY col) - order by inside function
6797    #[serde(default, skip_serializing_if = "Option::is_none")]
6798    pub order_by: Option<Vec<Ordered>>,
6799    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6800    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6801    pub args: Vec<Expression>,
6802}
6803
6804/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
6805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6806#[cfg_attr(feature = "bindings", derive(TS))]
6807pub struct DenseRank {
6808    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6809    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6810    pub args: Vec<Expression>,
6811}
6812
6813/// NTILE function (DuckDB allows ORDER BY inside)
6814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6815#[cfg_attr(feature = "bindings", derive(TS))]
6816pub struct NTileFunc {
6817    /// num_buckets is optional to support Databricks NTILE() without arguments
6818    #[serde(default, skip_serializing_if = "Option::is_none")]
6819    pub num_buckets: Option<Expression>,
6820    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
6821    #[serde(default, skip_serializing_if = "Option::is_none")]
6822    pub order_by: Option<Vec<Ordered>>,
6823}
6824
6825/// LEAD / LAG function
6826#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6827#[cfg_attr(feature = "bindings", derive(TS))]
6828pub struct LeadLagFunc {
6829    pub this: Expression,
6830    pub offset: Option<Expression>,
6831    pub default: Option<Expression>,
6832    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6833    #[serde(default, skip_serializing_if = "Option::is_none")]
6834    pub ignore_nulls: Option<bool>,
6835}
6836
6837/// FIRST_VALUE / LAST_VALUE function
6838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6839#[cfg_attr(feature = "bindings", derive(TS))]
6840pub struct ValueFunc {
6841    pub this: Expression,
6842    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6843    #[serde(default, skip_serializing_if = "Option::is_none")]
6844    pub ignore_nulls: Option<bool>,
6845    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
6846    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6847    pub order_by: Vec<Ordered>,
6848}
6849
6850/// NTH_VALUE function
6851#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6852#[cfg_attr(feature = "bindings", derive(TS))]
6853pub struct NthValueFunc {
6854    pub this: Expression,
6855    pub offset: Expression,
6856    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6857    #[serde(default, skip_serializing_if = "Option::is_none")]
6858    pub ignore_nulls: Option<bool>,
6859    /// Snowflake FROM FIRST / FROM LAST clause
6860    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
6861    #[serde(default, skip_serializing_if = "Option::is_none")]
6862    pub from_first: Option<bool>,
6863}
6864
6865/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6866#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6867#[cfg_attr(feature = "bindings", derive(TS))]
6868pub struct PercentRank {
6869    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
6870    #[serde(default, skip_serializing_if = "Option::is_none")]
6871    pub order_by: Option<Vec<Ordered>>,
6872    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6873    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6874    pub args: Vec<Expression>,
6875}
6876
6877/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6878#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6879#[cfg_attr(feature = "bindings", derive(TS))]
6880pub struct CumeDist {
6881    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
6882    #[serde(default, skip_serializing_if = "Option::is_none")]
6883    pub order_by: Option<Vec<Ordered>>,
6884    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6885    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6886    pub args: Vec<Expression>,
6887}
6888
6889// ============================================================================
6890// Additional String Function types
6891// ============================================================================
6892
6893/// POSITION/INSTR function
6894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6895#[cfg_attr(feature = "bindings", derive(TS))]
6896pub struct PositionFunc {
6897    pub substring: Expression,
6898    pub string: Expression,
6899    pub start: Option<Expression>,
6900}
6901
6902// ============================================================================
6903// Additional Math Function types
6904// ============================================================================
6905
6906/// RANDOM function (no arguments)
6907#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6908#[cfg_attr(feature = "bindings", derive(TS))]
6909pub struct Random;
6910
6911/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
6912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6913#[cfg_attr(feature = "bindings", derive(TS))]
6914pub struct Rand {
6915    pub seed: Option<Box<Expression>>,
6916    /// Teradata RANDOM lower bound
6917    #[serde(default)]
6918    pub lower: Option<Box<Expression>>,
6919    /// Teradata RANDOM upper bound
6920    #[serde(default)]
6921    pub upper: Option<Box<Expression>>,
6922}
6923
6924/// TRUNCATE / TRUNC function
6925#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6926#[cfg_attr(feature = "bindings", derive(TS))]
6927pub struct TruncateFunc {
6928    pub this: Expression,
6929    pub decimals: Option<Expression>,
6930}
6931
6932/// PI function (no arguments)
6933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6934#[cfg_attr(feature = "bindings", derive(TS))]
6935pub struct Pi;
6936
6937// ============================================================================
6938// Control Flow Function types
6939// ============================================================================
6940
6941/// DECODE function (Oracle style)
6942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6943#[cfg_attr(feature = "bindings", derive(TS))]
6944pub struct DecodeFunc {
6945    pub this: Expression,
6946    pub search_results: Vec<(Expression, Expression)>,
6947    pub default: Option<Expression>,
6948}
6949
6950// ============================================================================
6951// Additional Date/Time Function types
6952// ============================================================================
6953
6954/// DATE_FORMAT / FORMAT_DATE function
6955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6956#[cfg_attr(feature = "bindings", derive(TS))]
6957pub struct DateFormatFunc {
6958    pub this: Expression,
6959    pub format: Expression,
6960}
6961
6962/// FROM_UNIXTIME function
6963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6964#[cfg_attr(feature = "bindings", derive(TS))]
6965pub struct FromUnixtimeFunc {
6966    pub this: Expression,
6967    pub format: Option<Expression>,
6968}
6969
6970/// UNIX_TIMESTAMP function
6971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6972#[cfg_attr(feature = "bindings", derive(TS))]
6973pub struct UnixTimestampFunc {
6974    pub this: Option<Expression>,
6975    pub format: Option<Expression>,
6976}
6977
6978/// MAKE_DATE function
6979#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6980#[cfg_attr(feature = "bindings", derive(TS))]
6981pub struct MakeDateFunc {
6982    pub year: Expression,
6983    pub month: Expression,
6984    pub day: Expression,
6985}
6986
6987/// MAKE_TIMESTAMP function
6988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6989#[cfg_attr(feature = "bindings", derive(TS))]
6990pub struct MakeTimestampFunc {
6991    pub year: Expression,
6992    pub month: Expression,
6993    pub day: Expression,
6994    pub hour: Expression,
6995    pub minute: Expression,
6996    pub second: Expression,
6997    pub timezone: Option<Expression>,
6998}
6999
7000/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
7001#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7002#[cfg_attr(feature = "bindings", derive(TS))]
7003pub struct LastDayFunc {
7004    pub this: Expression,
7005    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
7006    #[serde(skip_serializing_if = "Option::is_none", default)]
7007    pub unit: Option<DateTimeField>,
7008}
7009
7010// ============================================================================
7011// Array Function types
7012// ============================================================================
7013
7014/// ARRAY constructor
7015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7016#[cfg_attr(feature = "bindings", derive(TS))]
7017pub struct ArrayConstructor {
7018    pub expressions: Vec<Expression>,
7019    pub bracket_notation: bool,
7020    /// True if LIST keyword was used instead of ARRAY (DuckDB)
7021    pub use_list_keyword: bool,
7022}
7023
7024/// ARRAY_SORT function
7025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7026#[cfg_attr(feature = "bindings", derive(TS))]
7027pub struct ArraySortFunc {
7028    pub this: Expression,
7029    pub comparator: Option<Expression>,
7030    pub desc: bool,
7031    pub nulls_first: Option<bool>,
7032}
7033
7034/// ARRAY_JOIN / ARRAY_TO_STRING function
7035#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7036#[cfg_attr(feature = "bindings", derive(TS))]
7037pub struct ArrayJoinFunc {
7038    pub this: Expression,
7039    pub separator: Expression,
7040    pub null_replacement: Option<Expression>,
7041}
7042
7043/// UNNEST function
7044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7045#[cfg_attr(feature = "bindings", derive(TS))]
7046pub struct UnnestFunc {
7047    pub this: Expression,
7048    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
7049    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7050    pub expressions: Vec<Expression>,
7051    pub with_ordinality: bool,
7052    pub alias: Option<Identifier>,
7053    /// BigQuery: offset alias for WITH OFFSET AS <name>
7054    #[serde(default, skip_serializing_if = "Option::is_none")]
7055    pub offset_alias: Option<Identifier>,
7056    /// Inferred type of the first UNNEST output column.
7057    #[serde(default, skip_serializing_if = "Option::is_none")]
7058    #[ast(skip)]
7059    pub inferred_type: Option<DataType>,
7060}
7061
7062/// ARRAY_FILTER function (with lambda)
7063#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7064#[cfg_attr(feature = "bindings", derive(TS))]
7065pub struct ArrayFilterFunc {
7066    pub this: Expression,
7067    pub filter: Expression,
7068}
7069
7070/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
7071#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7072#[cfg_attr(feature = "bindings", derive(TS))]
7073pub struct ArrayTransformFunc {
7074    pub this: Expression,
7075    pub transform: Expression,
7076}
7077
7078/// SEQUENCE / GENERATE_SERIES function
7079#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7080#[cfg_attr(feature = "bindings", derive(TS))]
7081pub struct SequenceFunc {
7082    pub start: Expression,
7083    pub stop: Expression,
7084    pub step: Option<Expression>,
7085}
7086
7087// ============================================================================
7088// Struct Function types
7089// ============================================================================
7090
7091/// STRUCT constructor
7092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7093#[cfg_attr(feature = "bindings", derive(TS))]
7094pub struct StructConstructor {
7095    pub fields: Vec<(Option<Identifier>, Expression)>,
7096}
7097
7098/// STRUCT_EXTRACT function
7099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7100#[cfg_attr(feature = "bindings", derive(TS))]
7101pub struct StructExtractFunc {
7102    pub this: Expression,
7103    pub field: Identifier,
7104}
7105
7106/// NAMED_STRUCT function
7107#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7108#[cfg_attr(feature = "bindings", derive(TS))]
7109pub struct NamedStructFunc {
7110    pub pairs: Vec<(Expression, Expression)>,
7111}
7112
7113// ============================================================================
7114// Map Function types
7115// ============================================================================
7116
7117/// MAP constructor
7118#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7119#[cfg_attr(feature = "bindings", derive(TS))]
7120pub struct MapConstructor {
7121    pub keys: Vec<Expression>,
7122    pub values: Vec<Expression>,
7123    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7124    #[serde(default)]
7125    pub curly_brace_syntax: bool,
7126    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7127    #[serde(default)]
7128    pub with_map_keyword: bool,
7129}
7130
7131/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7132#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7133#[cfg_attr(feature = "bindings", derive(TS))]
7134pub struct TransformFunc {
7135    pub this: Expression,
7136    pub transform: Expression,
7137}
7138
7139/// Function call with EMITS clause (Exasol)
7140/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7141#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7142#[cfg_attr(feature = "bindings", derive(TS))]
7143pub struct FunctionEmits {
7144    /// The function call expression
7145    pub this: Expression,
7146    /// The EMITS schema definition
7147    pub emits: Expression,
7148}
7149
7150// ============================================================================
7151// JSON Function types
7152// ============================================================================
7153
7154/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7155#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7156#[cfg_attr(feature = "bindings", derive(TS))]
7157pub struct JsonExtractFunc {
7158    pub this: Expression,
7159    pub path: Expression,
7160    pub returning: Option<DataType>,
7161    /// True if parsed from -> or ->> operator syntax
7162    #[serde(default)]
7163    pub arrow_syntax: bool,
7164    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7165    #[serde(default)]
7166    pub hash_arrow_syntax: bool,
7167    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7168    #[serde(default)]
7169    pub wrapper_option: Option<String>,
7170    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7171    #[serde(default)]
7172    pub quotes_option: Option<String>,
7173    /// ON SCALAR STRING flag
7174    #[serde(default)]
7175    pub on_scalar_string: bool,
7176    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7177    #[serde(default)]
7178    pub on_error: Option<String>,
7179}
7180
7181/// JSON path extraction
7182#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7183#[cfg_attr(feature = "bindings", derive(TS))]
7184pub struct JsonPathFunc {
7185    pub this: Expression,
7186    pub paths: Vec<Expression>,
7187}
7188
7189/// JSON_OBJECT function
7190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7191#[cfg_attr(feature = "bindings", derive(TS))]
7192pub struct JsonObjectFunc {
7193    pub pairs: Vec<(Expression, Expression)>,
7194    pub null_handling: Option<JsonNullHandling>,
7195    #[serde(default)]
7196    pub with_unique_keys: bool,
7197    #[serde(default)]
7198    pub returning_type: Option<DataType>,
7199    #[serde(default)]
7200    pub format_json: bool,
7201    #[serde(default)]
7202    pub encoding: Option<String>,
7203    /// For JSON_OBJECT(*) syntax
7204    #[serde(default)]
7205    pub star: bool,
7206}
7207
7208/// JSON null handling options
7209#[derive(
7210    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7211)]
7212#[cfg_attr(feature = "bindings", derive(TS))]
7213pub enum JsonNullHandling {
7214    NullOnNull,
7215    AbsentOnNull,
7216}
7217
7218/// JSON_SET / JSON_INSERT function
7219#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7220#[cfg_attr(feature = "bindings", derive(TS))]
7221pub struct JsonModifyFunc {
7222    pub this: Expression,
7223    pub path_values: Vec<(Expression, Expression)>,
7224}
7225
7226/// JSON_ARRAYAGG function
7227#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7228#[cfg_attr(feature = "bindings", derive(TS))]
7229pub struct JsonArrayAggFunc {
7230    pub this: Expression,
7231    pub order_by: Option<Vec<Ordered>>,
7232    pub null_handling: Option<JsonNullHandling>,
7233    pub filter: Option<Expression>,
7234}
7235
7236/// JSON_OBJECTAGG function
7237#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7238#[cfg_attr(feature = "bindings", derive(TS))]
7239pub struct JsonObjectAggFunc {
7240    pub key: Expression,
7241    pub value: Expression,
7242    pub null_handling: Option<JsonNullHandling>,
7243    pub filter: Option<Expression>,
7244}
7245
7246// ============================================================================
7247// Type Casting Function types
7248// ============================================================================
7249
7250/// CONVERT function (SQL Server style)
7251#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7252#[cfg_attr(feature = "bindings", derive(TS))]
7253pub struct ConvertFunc {
7254    pub this: Expression,
7255    pub to: DataType,
7256    pub style: Option<Expression>,
7257}
7258
7259// ============================================================================
7260// Additional Expression types
7261// ============================================================================
7262
7263/// Lambda expression
7264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7265#[cfg_attr(feature = "bindings", derive(TS))]
7266pub struct LambdaExpr {
7267    pub parameters: Vec<Identifier>,
7268    pub body: Expression,
7269    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7270    #[serde(default)]
7271    pub colon: bool,
7272    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7273    /// Maps parameter index to data type
7274    #[serde(default)]
7275    pub parameter_types: Vec<Option<DataType>>,
7276}
7277
7278/// Parameter (parameterized queries)
7279#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7280#[cfg_attr(feature = "bindings", derive(TS))]
7281pub struct Parameter {
7282    pub name: Option<String>,
7283    pub index: Option<u32>,
7284    pub style: ParameterStyle,
7285    /// Whether the name was quoted (e.g., @"x" vs @x)
7286    #[serde(default)]
7287    pub quoted: bool,
7288    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7289    #[serde(default)]
7290    pub string_quoted: bool,
7291    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7292    #[serde(default)]
7293    pub expression: Option<String>,
7294}
7295
7296/// Parameter placeholder styles
7297#[derive(
7298    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7299)]
7300#[cfg_attr(feature = "bindings", derive(TS))]
7301pub enum ParameterStyle {
7302    Question,     // ?
7303    Dollar,       // $1, $2
7304    DollarBrace,  // ${name} (Databricks, Hive template variables)
7305    Brace,        // {name} (Spark/Databricks widget/template variables)
7306    Colon,        // :name
7307    At,           // @name
7308    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7309    DoubleDollar, // $$name
7310    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7311}
7312
7313/// Placeholder expression
7314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7315#[cfg_attr(feature = "bindings", derive(TS))]
7316pub struct Placeholder {
7317    pub index: Option<u32>,
7318}
7319
7320/// Named argument in function call: name => value or name := value
7321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7322#[cfg_attr(feature = "bindings", derive(TS))]
7323pub struct NamedArgument {
7324    pub name: Identifier,
7325    pub value: Expression,
7326    /// The separator used: `=>`, `:=`, or `=`
7327    pub separator: NamedArgSeparator,
7328}
7329
7330/// Separator style for named arguments
7331#[derive(
7332    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7333)]
7334#[cfg_attr(feature = "bindings", derive(TS))]
7335pub enum NamedArgSeparator {
7336    /// `=>` (standard SQL, Snowflake, BigQuery)
7337    DArrow,
7338    /// `:=` (Oracle, MySQL)
7339    ColonEq,
7340    /// `=` (simple equals, some dialects)
7341    Eq,
7342}
7343
7344/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7345/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7346#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7347#[cfg_attr(feature = "bindings", derive(TS))]
7348pub struct TableArgument {
7349    /// The keyword prefix: "TABLE" or "MODEL"
7350    pub prefix: String,
7351    /// The table/model reference expression
7352    pub this: Expression,
7353}
7354
7355/// SQL Comment preservation
7356#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7357#[cfg_attr(feature = "bindings", derive(TS))]
7358pub struct SqlComment {
7359    pub text: String,
7360    pub is_block: bool,
7361}
7362
7363// ============================================================================
7364// Additional Predicate types
7365// ============================================================================
7366
7367/// SIMILAR TO expression
7368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7369#[cfg_attr(feature = "bindings", derive(TS))]
7370pub struct SimilarToExpr {
7371    pub this: Expression,
7372    pub pattern: Expression,
7373    pub escape: Option<Expression>,
7374    pub not: bool,
7375}
7376
7377/// ANY / ALL quantified expression
7378#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7379#[cfg_attr(feature = "bindings", derive(TS))]
7380pub struct QuantifiedExpr {
7381    pub this: Expression,
7382    pub subquery: Expression,
7383    pub op: Option<QuantifiedOp>,
7384}
7385
7386/// Comparison operator for quantified expressions
7387#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7388#[cfg_attr(feature = "bindings", derive(TS))]
7389pub enum QuantifiedOp {
7390    Eq,
7391    Neq,
7392    Lt,
7393    Lte,
7394    Gt,
7395    Gte,
7396}
7397
7398/// OVERLAPS expression
7399/// Supports two forms:
7400/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7401/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7402#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7403#[cfg_attr(feature = "bindings", derive(TS))]
7404pub struct OverlapsExpr {
7405    /// Left operand for simple binary form
7406    #[serde(skip_serializing_if = "Option::is_none")]
7407    pub this: Option<Expression>,
7408    /// Right operand for simple binary form
7409    #[serde(skip_serializing_if = "Option::is_none")]
7410    pub expression: Option<Expression>,
7411    /// Left range start for full ANSI form
7412    #[serde(skip_serializing_if = "Option::is_none")]
7413    pub left_start: Option<Expression>,
7414    /// Left range end for full ANSI form
7415    #[serde(skip_serializing_if = "Option::is_none")]
7416    pub left_end: Option<Expression>,
7417    /// Right range start for full ANSI form
7418    #[serde(skip_serializing_if = "Option::is_none")]
7419    pub right_start: Option<Expression>,
7420    /// Right range end for full ANSI form
7421    #[serde(skip_serializing_if = "Option::is_none")]
7422    pub right_end: Option<Expression>,
7423}
7424
7425// ============================================================================
7426// Array/Struct/Map access
7427// ============================================================================
7428
7429/// Subscript access (array[index] or map[key])
7430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7431#[cfg_attr(feature = "bindings", derive(TS))]
7432pub struct Subscript {
7433    pub this: Expression,
7434    pub index: Expression,
7435}
7436
7437/// Dot access (struct.field)
7438#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7439#[cfg_attr(feature = "bindings", derive(TS))]
7440pub struct DotAccess {
7441    pub this: Expression,
7442    pub field: Identifier,
7443    #[serde(default, skip_serializing_if = "Option::is_none")]
7444    pub inferred_type: Option<DataType>,
7445}
7446
7447/// Method call (expr.method(args))
7448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7449#[cfg_attr(feature = "bindings", derive(TS))]
7450pub struct MethodCall {
7451    pub this: Expression,
7452    pub method: Identifier,
7453    pub args: Vec<Expression>,
7454}
7455
7456/// Array slice (array[start:end])
7457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7458#[cfg_attr(feature = "bindings", derive(TS))]
7459pub struct ArraySlice {
7460    pub this: Expression,
7461    pub start: Option<Expression>,
7462    pub end: Option<Expression>,
7463}
7464
7465// ============================================================================
7466// DDL (Data Definition Language) Statements
7467// ============================================================================
7468
7469/// ON COMMIT behavior for temporary tables
7470#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7471#[cfg_attr(feature = "bindings", derive(TS))]
7472pub enum OnCommit {
7473    /// ON COMMIT PRESERVE ROWS
7474    PreserveRows,
7475    /// ON COMMIT DELETE ROWS
7476    DeleteRows,
7477}
7478
7479/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
7480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7481#[cfg_attr(feature = "bindings", derive(TS))]
7482pub struct TiDBAutoRandom {
7483    #[serde(default, skip_serializing_if = "Option::is_none")]
7484    pub shard_bits: Option<u64>,
7485    #[serde(default, skip_serializing_if = "Option::is_none")]
7486    pub range_bits: Option<u64>,
7487    /// Whether the attribute was wrapped in a TiDB executable comment.
7488    #[serde(default)]
7489    pub executable_comment: bool,
7490}
7491
7492/// A TiDB-specific table option and its source syntax.
7493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7494#[cfg_attr(feature = "bindings", derive(TS))]
7495pub struct TiDBTableOption {
7496    pub kind: TiDBTableOptionKind,
7497    /// Whether the option was wrapped in a TiDB executable comment.
7498    #[serde(default)]
7499    pub executable_comment: bool,
7500}
7501
7502/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
7503#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7504#[cfg_attr(feature = "bindings", derive(TS))]
7505#[serde(tag = "type", rename_all = "snake_case")]
7506pub enum TiDBTableOptionKind {
7507    ShardRowIdBits {
7508        bits: u64,
7509    },
7510    PreSplitRegions {
7511        regions: u64,
7512    },
7513    AutoRandomBase {
7514        value: u64,
7515    },
7516    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
7517    PlacementPolicy {
7518        policy: Option<Identifier>,
7519    },
7520    Ttl {
7521        column: Identifier,
7522        interval: Interval,
7523        #[serde(default, skip_serializing_if = "Option::is_none")]
7524        enabled: Option<bool>,
7525    },
7526    TtlEnable {
7527        enabled: bool,
7528    },
7529    TtlJobInterval {
7530        interval: String,
7531    },
7532}
7533
7534/// CREATE TABLE statement
7535#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7536#[cfg_attr(feature = "bindings", derive(TS))]
7537pub struct CreateTable {
7538    pub name: TableRef,
7539    /// ClickHouse: ON CLUSTER clause for distributed DDL
7540    #[serde(default, skip_serializing_if = "Option::is_none")]
7541    pub on_cluster: Option<OnCluster>,
7542    pub columns: Vec<ColumnDef>,
7543    pub constraints: Vec<TableConstraint>,
7544    pub if_not_exists: bool,
7545    pub temporary: bool,
7546    pub or_replace: bool,
7547    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
7548    #[serde(default, skip_serializing_if = "Option::is_none")]
7549    pub table_modifier: Option<String>,
7550    pub as_select: Option<Expression>,
7551    /// Whether the AS SELECT was wrapped in parentheses
7552    #[serde(default)]
7553    pub as_select_parenthesized: bool,
7554    /// ON COMMIT behavior for temporary tables
7555    #[serde(default)]
7556    pub on_commit: Option<OnCommit>,
7557    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
7558    #[serde(default)]
7559    pub clone_source: Option<TableRef>,
7560    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
7561    #[serde(default, skip_serializing_if = "Option::is_none")]
7562    pub clone_at_clause: Option<Expression>,
7563    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
7564    #[serde(default)]
7565    pub is_copy: bool,
7566    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
7567    #[serde(default)]
7568    pub shallow_clone: bool,
7569    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
7570    #[serde(default)]
7571    pub deep_clone: bool,
7572    /// Leading comments before the statement
7573    #[serde(default)]
7574    pub leading_comments: Vec<String>,
7575    /// WITH properties (e.g., WITH (FORMAT='parquet'))
7576    #[serde(default)]
7577    pub with_properties: Vec<(String, String)>,
7578    /// Teradata: table options after name before columns (comma-separated)
7579    #[serde(default)]
7580    pub teradata_post_name_options: Vec<String>,
7581    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
7582    #[serde(default)]
7583    pub with_data: Option<bool>,
7584    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
7585    #[serde(default)]
7586    pub with_statistics: Option<bool>,
7587    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
7588    #[serde(default)]
7589    pub teradata_indexes: Vec<TeradataIndex>,
7590    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
7591    #[serde(default)]
7592    pub with_cte: Option<With>,
7593    /// Table properties like DEFAULT COLLATE (BigQuery)
7594    #[serde(default)]
7595    pub properties: Vec<Expression>,
7596    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
7597    #[serde(default, skip_serializing_if = "Option::is_none")]
7598    pub partition_of: Option<Expression>,
7599    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
7600    #[serde(default)]
7601    pub post_table_properties: Vec<Expression>,
7602    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
7603    #[serde(default)]
7604    pub mysql_table_options: Vec<(String, String)>,
7605    /// TiDB-specific table options after column definitions.
7606    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7607    pub tidb_table_options: Vec<TiDBTableOption>,
7608    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
7609    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7610    pub inherits: Vec<TableRef>,
7611    /// TSQL ON filegroup or ON filegroup (partition_column) clause
7612    #[serde(default, skip_serializing_if = "Option::is_none")]
7613    pub on_property: Option<OnProperty>,
7614    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
7615    #[serde(default)]
7616    pub copy_grants: bool,
7617    /// Snowflake: USING TEMPLATE expression for schema inference
7618    #[serde(default, skip_serializing_if = "Option::is_none")]
7619    pub using_template: Option<Box<Expression>>,
7620    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
7621    #[serde(default, skip_serializing_if = "Option::is_none")]
7622    pub rollup: Option<RollupProperty>,
7623    /// ClickHouse: UUID 'xxx' clause after table name
7624    #[serde(default, skip_serializing_if = "Option::is_none")]
7625    pub uuid: Option<String>,
7626    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
7627    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
7628    /// could appear in other engines.
7629    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7630    pub with_partition_columns: Vec<ColumnDef>,
7631    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
7632    /// for external tables that reference a Cloud Resource connection.
7633    #[serde(default, skip_serializing_if = "Option::is_none")]
7634    pub with_connection: Option<TableRef>,
7635}
7636
7637/// Teradata index specification for CREATE TABLE
7638#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7639#[cfg_attr(feature = "bindings", derive(TS))]
7640pub struct TeradataIndex {
7641    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
7642    pub kind: TeradataIndexKind,
7643    /// Optional index name
7644    pub name: Option<String>,
7645    /// Optional column list
7646    pub columns: Vec<String>,
7647}
7648
7649/// Kind of Teradata index
7650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7651#[cfg_attr(feature = "bindings", derive(TS))]
7652pub enum TeradataIndexKind {
7653    /// NO PRIMARY INDEX
7654    NoPrimary,
7655    /// PRIMARY INDEX
7656    Primary,
7657    /// PRIMARY AMP INDEX
7658    PrimaryAmp,
7659    /// UNIQUE INDEX
7660    Unique,
7661    /// UNIQUE PRIMARY INDEX
7662    UniquePrimary,
7663    /// INDEX (secondary, non-primary)
7664    Secondary,
7665}
7666
7667impl CreateTable {
7668    pub fn new(name: impl Into<String>) -> Self {
7669        Self {
7670            name: TableRef::new(name),
7671            on_cluster: None,
7672            columns: Vec::new(),
7673            constraints: Vec::new(),
7674            if_not_exists: false,
7675            temporary: false,
7676            or_replace: false,
7677            table_modifier: None,
7678            as_select: None,
7679            as_select_parenthesized: false,
7680            on_commit: None,
7681            clone_source: None,
7682            clone_at_clause: None,
7683            shallow_clone: false,
7684            deep_clone: false,
7685            is_copy: false,
7686            leading_comments: Vec::new(),
7687            with_properties: Vec::new(),
7688            teradata_post_name_options: Vec::new(),
7689            with_data: None,
7690            with_statistics: None,
7691            teradata_indexes: Vec::new(),
7692            with_cte: None,
7693            properties: Vec::new(),
7694            partition_of: None,
7695            post_table_properties: Vec::new(),
7696            mysql_table_options: Vec::new(),
7697            tidb_table_options: Vec::new(),
7698            inherits: Vec::new(),
7699            on_property: None,
7700            copy_grants: false,
7701            using_template: None,
7702            rollup: None,
7703            uuid: None,
7704            with_partition_columns: Vec::new(),
7705            with_connection: None,
7706        }
7707    }
7708}
7709
7710/// Sort order for PRIMARY KEY ASC/DESC
7711#[derive(
7712    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
7713)]
7714#[cfg_attr(feature = "bindings", derive(TS))]
7715pub enum SortOrder {
7716    Asc,
7717    Desc,
7718}
7719
7720/// Type of column constraint for tracking order
7721#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7722#[cfg_attr(feature = "bindings", derive(TS))]
7723pub enum ConstraintType {
7724    NotNull,
7725    Null,
7726    PrimaryKey,
7727    Unique,
7728    Default,
7729    AutoIncrement,
7730    AutoRandom,
7731    Collate,
7732    Comment,
7733    References,
7734    Check,
7735    GeneratedAsIdentity,
7736    /// Snowflake: TAG (key='value', ...)
7737    Tags,
7738    /// Computed/generated column
7739    ComputedColumn,
7740    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
7741    GeneratedAsRow,
7742    /// MySQL: ON UPDATE expression
7743    OnUpdate,
7744    /// PATH constraint for XMLTABLE/JSON_TABLE columns
7745    Path,
7746    /// Redshift: ENCODE encoding_type
7747    Encode,
7748}
7749
7750/// Column definition in CREATE TABLE
7751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7752#[cfg_attr(feature = "bindings", derive(TS))]
7753pub struct ColumnDef {
7754    pub name: Identifier,
7755    pub data_type: DataType,
7756    pub nullable: Option<bool>,
7757    pub default: Option<Expression>,
7758    pub primary_key: bool,
7759    /// Sort order for PRIMARY KEY (ASC/DESC)
7760    #[serde(default)]
7761    pub primary_key_order: Option<SortOrder>,
7762    pub unique: bool,
7763    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
7764    #[serde(default)]
7765    pub unique_nulls_not_distinct: bool,
7766    pub auto_increment: bool,
7767    /// TiDB distributed primary-key allocation attribute.
7768    #[serde(default, skip_serializing_if = "Option::is_none")]
7769    pub auto_random: Option<TiDBAutoRandom>,
7770    pub comment: Option<String>,
7771    pub constraints: Vec<ColumnConstraint>,
7772    /// Track original order of constraints for accurate regeneration
7773    #[serde(default)]
7774    pub constraint_order: Vec<ConstraintType>,
7775    /// Teradata: FORMAT 'pattern'
7776    #[serde(default)]
7777    pub format: Option<String>,
7778    /// Teradata: TITLE 'title'
7779    #[serde(default)]
7780    pub title: Option<String>,
7781    /// Teradata: INLINE LENGTH n
7782    #[serde(default)]
7783    pub inline_length: Option<u64>,
7784    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
7785    #[serde(default)]
7786    pub compress: Option<Vec<Expression>>,
7787    /// Teradata: CHARACTER SET name
7788    #[serde(default)]
7789    pub character_set: Option<String>,
7790    /// Teradata: UPPERCASE
7791    #[serde(default)]
7792    pub uppercase: bool,
7793    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
7794    #[serde(default)]
7795    pub casespecific: Option<bool>,
7796    /// Snowflake: AUTOINCREMENT START value
7797    #[serde(default)]
7798    pub auto_increment_start: Option<Box<Expression>>,
7799    /// Snowflake: AUTOINCREMENT INCREMENT value
7800    #[serde(default)]
7801    pub auto_increment_increment: Option<Box<Expression>>,
7802    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
7803    #[serde(default)]
7804    pub auto_increment_order: Option<bool>,
7805    /// MySQL: UNSIGNED modifier
7806    #[serde(default)]
7807    pub unsigned: bool,
7808    /// MySQL: ZEROFILL modifier
7809    #[serde(default)]
7810    pub zerofill: bool,
7811    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
7812    #[serde(default, skip_serializing_if = "Option::is_none")]
7813    pub on_update: Option<Expression>,
7814    /// MySQL: column VISIBLE/INVISIBLE modifier.
7815    #[serde(default, skip_serializing_if = "Option::is_none")]
7816    pub visible: Option<bool>,
7817    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
7818    #[serde(default, skip_serializing_if = "Option::is_none")]
7819    pub unique_constraint_name: Option<String>,
7820    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
7821    #[serde(default, skip_serializing_if = "Option::is_none")]
7822    pub not_null_constraint_name: Option<String>,
7823    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
7824    #[serde(default, skip_serializing_if = "Option::is_none")]
7825    pub primary_key_constraint_name: Option<String>,
7826    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
7827    #[serde(default, skip_serializing_if = "Option::is_none")]
7828    pub check_constraint_name: Option<String>,
7829    /// BigQuery: OPTIONS (key=value, ...) on column
7830    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7831    pub options: Vec<Expression>,
7832    /// SQLite: Column definition without explicit type
7833    #[serde(default)]
7834    pub no_type: bool,
7835    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
7836    #[serde(default, skip_serializing_if = "Option::is_none")]
7837    pub encoding: Option<String>,
7838    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
7839    #[serde(default, skip_serializing_if = "Option::is_none")]
7840    pub codec: Option<String>,
7841    /// ClickHouse: EPHEMERAL [expr] modifier
7842    #[serde(default, skip_serializing_if = "Option::is_none")]
7843    pub ephemeral: Option<Option<Box<Expression>>>,
7844    /// ClickHouse: MATERIALIZED expr modifier
7845    #[serde(default, skip_serializing_if = "Option::is_none")]
7846    pub materialized_expr: Option<Box<Expression>>,
7847    /// ClickHouse: ALIAS expr modifier
7848    #[serde(default, skip_serializing_if = "Option::is_none")]
7849    pub alias_expr: Option<Box<Expression>>,
7850    /// ClickHouse: TTL expr modifier on columns
7851    #[serde(default, skip_serializing_if = "Option::is_none")]
7852    pub ttl_expr: Option<Box<Expression>>,
7853    /// TSQL: NOT FOR REPLICATION
7854    #[serde(default)]
7855    pub not_for_replication: bool,
7856}
7857
7858impl ColumnDef {
7859    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
7860        Self {
7861            name: Identifier::new(name),
7862            data_type,
7863            nullable: None,
7864            default: None,
7865            primary_key: false,
7866            primary_key_order: None,
7867            unique: false,
7868            unique_nulls_not_distinct: false,
7869            auto_increment: false,
7870            auto_random: None,
7871            comment: None,
7872            constraints: Vec::new(),
7873            constraint_order: Vec::new(),
7874            format: None,
7875            title: None,
7876            inline_length: None,
7877            compress: None,
7878            character_set: None,
7879            uppercase: false,
7880            casespecific: None,
7881            auto_increment_start: None,
7882            auto_increment_increment: None,
7883            auto_increment_order: None,
7884            unsigned: false,
7885            zerofill: false,
7886            on_update: None,
7887            visible: None,
7888            unique_constraint_name: None,
7889            not_null_constraint_name: None,
7890            primary_key_constraint_name: None,
7891            check_constraint_name: None,
7892            options: Vec::new(),
7893            no_type: false,
7894            encoding: None,
7895            codec: None,
7896            ephemeral: None,
7897            materialized_expr: None,
7898            alias_expr: None,
7899            ttl_expr: None,
7900            not_for_replication: false,
7901        }
7902    }
7903}
7904
7905/// Column-level constraint
7906#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7907#[cfg_attr(feature = "bindings", derive(TS))]
7908pub enum ColumnConstraint {
7909    NotNull,
7910    Null,
7911    Unique,
7912    PrimaryKey,
7913    Default(Expression),
7914    Check(Expression),
7915    References(ForeignKeyRef),
7916    GeneratedAsIdentity(GeneratedAsIdentity),
7917    Collate(Identifier),
7918    Comment(String),
7919    /// Snowflake: TAG (key='value', ...)
7920    Tags(Tags),
7921    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
7922    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
7923    ComputedColumn(ComputedColumn),
7924    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7925    GeneratedAsRow(GeneratedAsRow),
7926    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
7927    Path(Expression),
7928}
7929
7930/// Computed/generated column constraint
7931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7932#[cfg_attr(feature = "bindings", derive(TS))]
7933pub struct ComputedColumn {
7934    /// The expression that computes the column value
7935    pub expression: Box<Expression>,
7936    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
7937    #[serde(default)]
7938    pub persisted: bool,
7939    /// NOT NULL (TSQL computed columns)
7940    #[serde(default)]
7941    pub not_null: bool,
7942    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
7943    /// When None, defaults to dialect-appropriate output
7944    #[serde(default)]
7945    pub persistence_kind: Option<String>,
7946    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
7947    #[serde(default, skip_serializing_if = "Option::is_none")]
7948    pub data_type: Option<DataType>,
7949}
7950
7951/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7953#[cfg_attr(feature = "bindings", derive(TS))]
7954pub struct GeneratedAsRow {
7955    /// true = ROW START, false = ROW END
7956    pub start: bool,
7957    /// HIDDEN modifier
7958    #[serde(default)]
7959    pub hidden: bool,
7960}
7961
7962/// Generated identity column constraint
7963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7964#[cfg_attr(feature = "bindings", derive(TS))]
7965pub struct GeneratedAsIdentity {
7966    /// True for ALWAYS, False for BY DEFAULT
7967    pub always: bool,
7968    /// ON NULL (only valid with BY DEFAULT)
7969    pub on_null: bool,
7970    /// START WITH value
7971    pub start: Option<Box<Expression>>,
7972    /// INCREMENT BY value
7973    pub increment: Option<Box<Expression>>,
7974    /// MINVALUE
7975    pub minvalue: Option<Box<Expression>>,
7976    /// MAXVALUE
7977    pub maxvalue: Option<Box<Expression>>,
7978    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
7979    pub cycle: Option<bool>,
7980}
7981
7982/// Constraint modifiers (shared between table-level constraints)
7983#[derive(
7984    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
7985)]
7986#[cfg_attr(feature = "bindings", derive(TS))]
7987pub struct ConstraintModifiers {
7988    /// ENFORCED / NOT ENFORCED
7989    pub enforced: Option<bool>,
7990    /// DEFERRABLE / NOT DEFERRABLE
7991    pub deferrable: Option<bool>,
7992    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
7993    pub initially_deferred: Option<bool>,
7994    /// NORELY (Oracle)
7995    pub norely: bool,
7996    /// RELY (Oracle)
7997    pub rely: bool,
7998    /// USING index type (MySQL): BTREE or HASH
7999    #[serde(default)]
8000    pub using: Option<String>,
8001    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
8002    #[serde(default)]
8003    pub using_before_columns: bool,
8004    /// MySQL index COMMENT 'text'
8005    #[serde(default, skip_serializing_if = "Option::is_none")]
8006    pub comment: Option<String>,
8007    /// MySQL index VISIBLE/INVISIBLE
8008    #[serde(default, skip_serializing_if = "Option::is_none")]
8009    pub visible: Option<bool>,
8010    /// MySQL ENGINE_ATTRIBUTE = 'value'
8011    #[serde(default, skip_serializing_if = "Option::is_none")]
8012    pub engine_attribute: Option<String>,
8013    /// MySQL WITH PARSER name
8014    #[serde(default, skip_serializing_if = "Option::is_none")]
8015    pub with_parser: Option<String>,
8016    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
8017    #[serde(default)]
8018    pub not_valid: bool,
8019    /// TSQL CLUSTERED/NONCLUSTERED modifier
8020    #[serde(default, skip_serializing_if = "Option::is_none")]
8021    pub clustered: Option<String>,
8022    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
8023    #[serde(default, skip_serializing_if = "Option::is_none")]
8024    pub on_conflict: Option<String>,
8025    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
8026    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8027    pub with_options: Vec<(String, String)>,
8028    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
8029    #[serde(default, skip_serializing_if = "Option::is_none")]
8030    pub on_filegroup: Option<Identifier>,
8031}
8032
8033/// Table-level constraint
8034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8035#[cfg_attr(feature = "bindings", derive(TS))]
8036pub enum TableConstraint {
8037    PrimaryKey {
8038        name: Option<Identifier>,
8039        columns: Vec<Identifier>,
8040        /// Databricks primary-key columns marked with the TIMESERIES attribute.
8041        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8042        timeseries_columns: Vec<Identifier>,
8043        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
8044        #[serde(default)]
8045        include_columns: Vec<Identifier>,
8046        #[serde(default)]
8047        modifiers: ConstraintModifiers,
8048        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
8049        #[serde(default)]
8050        has_constraint_keyword: bool,
8051    },
8052    Unique {
8053        name: Option<Identifier>,
8054        columns: Vec<Identifier>,
8055        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
8056        #[serde(default)]
8057        columns_parenthesized: bool,
8058        #[serde(default)]
8059        modifiers: ConstraintModifiers,
8060        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
8061        #[serde(default)]
8062        has_constraint_keyword: bool,
8063        /// PostgreSQL 15+: NULLS NOT DISTINCT
8064        #[serde(default)]
8065        nulls_not_distinct: bool,
8066    },
8067    ForeignKey {
8068        name: Option<Identifier>,
8069        columns: Vec<Identifier>,
8070        #[serde(default)]
8071        references: Option<ForeignKeyRef>,
8072        /// ON DELETE action when REFERENCES is absent
8073        #[serde(default)]
8074        on_delete: Option<ReferentialAction>,
8075        /// ON UPDATE action when REFERENCES is absent
8076        #[serde(default)]
8077        on_update: Option<ReferentialAction>,
8078        #[serde(default)]
8079        modifiers: ConstraintModifiers,
8080    },
8081    Check {
8082        name: Option<Identifier>,
8083        expression: Expression,
8084        #[serde(default)]
8085        modifiers: ConstraintModifiers,
8086    },
8087    /// ClickHouse ASSUME constraint (query optimization assumption)
8088    Assume {
8089        name: Option<Identifier>,
8090        expression: Expression,
8091    },
8092    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
8093    Default {
8094        name: Option<Identifier>,
8095        expression: Expression,
8096        column: Identifier,
8097    },
8098    /// INDEX / KEY constraint (MySQL)
8099    Index {
8100        name: Option<Identifier>,
8101        columns: Vec<Identifier>,
8102        /// Expression-capable index key parts. This is used when an index contains
8103        /// functional key parts that cannot be represented by `columns`.
8104        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8105        key_parts: Vec<IndexKeyPart>,
8106        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8107        #[serde(default)]
8108        kind: Option<String>,
8109        #[serde(default)]
8110        modifiers: ConstraintModifiers,
8111        /// True if KEY keyword was used instead of INDEX
8112        #[serde(default)]
8113        use_key_keyword: bool,
8114        /// ClickHouse: indexed expression (instead of columns)
8115        #[serde(default, skip_serializing_if = "Option::is_none")]
8116        expression: Option<Box<Expression>>,
8117        /// ClickHouse: TYPE type_func(args)
8118        #[serde(default, skip_serializing_if = "Option::is_none")]
8119        index_type: Option<Box<Expression>>,
8120        /// ClickHouse: GRANULARITY n
8121        #[serde(default, skip_serializing_if = "Option::is_none")]
8122        granularity: Option<Box<Expression>>,
8123    },
8124    /// ClickHouse PROJECTION definition
8125    Projection {
8126        name: Identifier,
8127        expression: Expression,
8128    },
8129    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8130    Like {
8131        source: TableRef,
8132        /// Options as (INCLUDING|EXCLUDING, property) pairs
8133        options: Vec<(LikeOptionAction, String)>,
8134    },
8135    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8136    PeriodForSystemTime {
8137        start_col: Identifier,
8138        end_col: Identifier,
8139    },
8140    /// PostgreSQL EXCLUDE constraint
8141    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8142    Exclude {
8143        name: Option<Identifier>,
8144        /// Index access method (gist, btree, etc.)
8145        #[serde(default)]
8146        using: Option<String>,
8147        /// Elements: (expression, operator) pairs
8148        elements: Vec<ExcludeElement>,
8149        /// INCLUDE columns
8150        #[serde(default)]
8151        include_columns: Vec<Identifier>,
8152        /// WHERE predicate
8153        #[serde(default)]
8154        where_clause: Option<Box<Expression>>,
8155        /// WITH (storage_parameters)
8156        #[serde(default)]
8157        with_params: Vec<(String, String)>,
8158        /// USING INDEX TABLESPACE tablespace_name
8159        #[serde(default)]
8160        using_index_tablespace: Option<String>,
8161        #[serde(default)]
8162        modifiers: ConstraintModifiers,
8163    },
8164    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8165    Tags(Tags),
8166    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8167    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8168    /// for all deferrable constraints in the table
8169    InitiallyDeferred {
8170        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8171        deferred: bool,
8172    },
8173}
8174
8175/// Element in an EXCLUDE constraint: expression WITH operator
8176#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8177#[cfg_attr(feature = "bindings", derive(TS))]
8178pub struct ExcludeElement {
8179    /// The column expression (may include operator class, ordering, nulls)
8180    pub expression: String,
8181    /// The operator (e.g., &&, =)
8182    pub operator: String,
8183}
8184
8185/// Action for LIKE clause options
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 LikeOptionAction {
8191    Including,
8192    Excluding,
8193}
8194
8195/// MATCH type for foreign keys
8196#[derive(
8197    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8198)]
8199#[cfg_attr(feature = "bindings", derive(TS))]
8200pub enum MatchType {
8201    Full,
8202    Partial,
8203    Simple,
8204}
8205
8206/// Foreign key reference
8207#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8208#[cfg_attr(feature = "bindings", derive(TS))]
8209pub struct ForeignKeyRef {
8210    pub table: TableRef,
8211    pub columns: Vec<Identifier>,
8212    pub on_delete: Option<ReferentialAction>,
8213    pub on_update: Option<ReferentialAction>,
8214    /// True if ON UPDATE appears before ON DELETE in the original SQL
8215    #[serde(default)]
8216    pub on_update_first: bool,
8217    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8218    #[serde(default)]
8219    pub match_type: Option<MatchType>,
8220    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8221    #[serde(default)]
8222    pub match_after_actions: bool,
8223    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8224    #[serde(default)]
8225    pub constraint_name: Option<String>,
8226    /// DEFERRABLE / NOT DEFERRABLE
8227    #[serde(default)]
8228    pub deferrable: Option<bool>,
8229    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8230    #[serde(default)]
8231    pub has_foreign_key_keywords: bool,
8232}
8233
8234/// Referential action for foreign keys
8235#[derive(
8236    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8237)]
8238#[cfg_attr(feature = "bindings", derive(TS))]
8239pub enum ReferentialAction {
8240    Cascade,
8241    SetNull,
8242    SetDefault,
8243    Restrict,
8244    NoAction,
8245}
8246
8247/// DROP TABLE statement
8248#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8249#[cfg_attr(feature = "bindings", derive(TS))]
8250pub struct DropTable {
8251    pub names: Vec<TableRef>,
8252    pub if_exists: bool,
8253    pub cascade: bool,
8254    /// Oracle: CASCADE CONSTRAINTS
8255    #[serde(default)]
8256    pub cascade_constraints: bool,
8257    /// Oracle: PURGE
8258    #[serde(default)]
8259    pub purge: bool,
8260    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8261    #[serde(default)]
8262    pub leading_comments: Vec<String>,
8263    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8264    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8265    #[serde(default, skip_serializing_if = "Option::is_none")]
8266    pub object_id_args: Option<String>,
8267    /// ClickHouse: SYNC modifier
8268    #[serde(default)]
8269    pub sync: bool,
8270    /// Snowflake: DROP ICEBERG TABLE
8271    #[serde(default)]
8272    pub iceberg: bool,
8273    /// RESTRICT modifier (opposite of CASCADE)
8274    #[serde(default)]
8275    pub restrict: bool,
8276}
8277
8278impl DropTable {
8279    pub fn new(name: impl Into<String>) -> Self {
8280        Self {
8281            names: vec![TableRef::new(name)],
8282            if_exists: false,
8283            cascade: false,
8284            cascade_constraints: false,
8285            purge: false,
8286            leading_comments: Vec::new(),
8287            object_id_args: None,
8288            sync: false,
8289            iceberg: false,
8290            restrict: false,
8291        }
8292    }
8293}
8294
8295/// UNDROP object statement (Snowflake, ClickHouse)
8296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8297#[cfg_attr(feature = "bindings", derive(TS))]
8298pub struct Undrop {
8299    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8300    pub kind: String,
8301    /// The object name
8302    pub name: TableRef,
8303    /// IF EXISTS clause
8304    #[serde(default)]
8305    pub if_exists: bool,
8306    /// Snowflake: optional RENAME TO target
8307    #[serde(default, skip_serializing_if = "Option::is_none")]
8308    pub rename_to: Option<TableRef>,
8309}
8310
8311/// Partition scope 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 SplitTablePartitionScope {
8316    Table,
8317    AllPartitions,
8318    Partitions { names: Vec<Identifier> },
8319}
8320
8321/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8323#[cfg_attr(feature = "bindings", derive(TS))]
8324#[serde(tag = "type", rename_all = "snake_case")]
8325pub enum SplitTableMode {
8326    Between {
8327        lower: Vec<Expression>,
8328        upper: Vec<Expression>,
8329        regions: u64,
8330    },
8331    By {
8332        points: Vec<Vec<Expression>>,
8333    },
8334}
8335
8336/// TiDB `SPLIT [PARTITION] TABLE` statement.
8337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8338#[cfg_attr(feature = "bindings", derive(TS))]
8339pub struct SplitTable {
8340    pub table: TableRef,
8341    pub partition_scope: SplitTablePartitionScope,
8342    #[serde(default, skip_serializing_if = "Option::is_none")]
8343    pub index: Option<Identifier>,
8344    pub mode: SplitTableMode,
8345}
8346
8347/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
8348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8349#[cfg_attr(feature = "bindings", derive(TS))]
8350pub struct FlashbackTable {
8351    pub table: TableRef,
8352    #[serde(default, skip_serializing_if = "Option::is_none")]
8353    pub rename_to: Option<Identifier>,
8354}
8355
8356/// ALTER TABLE statement
8357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8358#[cfg_attr(feature = "bindings", derive(TS))]
8359pub struct AlterTable {
8360    pub name: TableRef,
8361    pub actions: Vec<AlterTableAction>,
8362    /// IF EXISTS clause
8363    #[serde(default)]
8364    pub if_exists: bool,
8365    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8366    #[serde(default, skip_serializing_if = "Option::is_none")]
8367    pub algorithm: Option<String>,
8368    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8369    #[serde(default, skip_serializing_if = "Option::is_none")]
8370    pub lock: Option<String>,
8371    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8372    #[serde(default, skip_serializing_if = "Option::is_none")]
8373    pub with_check: Option<String>,
8374    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8375    #[serde(default, skip_serializing_if = "Option::is_none")]
8376    pub partition: Option<Vec<(Identifier, Expression)>>,
8377    /// ClickHouse: ON CLUSTER clause for distributed DDL
8378    #[serde(default, skip_serializing_if = "Option::is_none")]
8379    pub on_cluster: Option<OnCluster>,
8380    /// Snowflake: ALTER ICEBERG TABLE
8381    #[serde(default, skip_serializing_if = "Option::is_none")]
8382    pub table_modifier: Option<String>,
8383}
8384
8385impl AlterTable {
8386    pub fn new(name: impl Into<String>) -> Self {
8387        Self {
8388            name: TableRef::new(name),
8389            actions: Vec::new(),
8390            if_exists: false,
8391            algorithm: None,
8392            lock: None,
8393            with_check: None,
8394            partition: None,
8395            on_cluster: None,
8396            table_modifier: None,
8397        }
8398    }
8399}
8400
8401/// Column position for ADD COLUMN (MySQL/MariaDB)
8402#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8403#[cfg_attr(feature = "bindings", derive(TS))]
8404pub enum ColumnPosition {
8405    First,
8406    After(Identifier),
8407}
8408
8409/// Actions for ALTER TABLE
8410#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8411#[cfg_attr(feature = "bindings", derive(TS))]
8412pub enum AlterTableAction {
8413    AddColumn {
8414        column: ColumnDef,
8415        if_not_exists: bool,
8416        position: Option<ColumnPosition>,
8417    },
8418    DropColumn {
8419        name: Identifier,
8420        if_exists: bool,
8421        cascade: bool,
8422    },
8423    RenameColumn {
8424        old_name: Identifier,
8425        new_name: Identifier,
8426        if_exists: bool,
8427    },
8428    AlterColumn {
8429        name: Identifier,
8430        action: AlterColumnAction,
8431        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8432        #[serde(default)]
8433        use_modify_keyword: bool,
8434    },
8435    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
8436    ModifyColumn {
8437        column: ColumnDef,
8438        if_exists: bool,
8439        position: Option<ColumnPosition>,
8440    },
8441    RenameTable(TableRef),
8442    AddConstraint(TableConstraint),
8443    DropConstraint {
8444        name: Identifier,
8445        if_exists: bool,
8446    },
8447    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8448    DropForeignKey {
8449        name: Identifier,
8450    },
8451    /// DROP PARTITION action (Hive/BigQuery)
8452    DropPartition {
8453        /// List of partitions to drop (each partition is a list of key=value pairs)
8454        partitions: Vec<Vec<(Identifier, Expression)>>,
8455        if_exists: bool,
8456    },
8457    /// ADD PARTITION action (Hive/Spark)
8458    AddPartition {
8459        /// The partition expression
8460        partition: Expression,
8461        if_not_exists: bool,
8462        location: Option<Expression>,
8463    },
8464    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8465    Delete {
8466        where_clause: Expression,
8467    },
8468    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8469    SwapWith(TableRef),
8470    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8471    SetProperty {
8472        properties: Vec<(String, Expression)>,
8473    },
8474    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8475    UnsetProperty {
8476        properties: Vec<String>,
8477    },
8478    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8479    ClusterBy {
8480        expressions: Vec<Expression>,
8481    },
8482    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8483    SetTag {
8484        expressions: Vec<(String, Expression)>,
8485    },
8486    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8487    UnsetTag {
8488        names: Vec<String>,
8489    },
8490    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8491    SetOptions {
8492        expressions: Vec<Expression>,
8493    },
8494    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8495    AlterIndex {
8496        name: Identifier,
8497        visible: bool,
8498    },
8499    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8500    SetAttribute {
8501        attribute: String,
8502    },
8503    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8504    SetStageFileFormat {
8505        options: Option<Expression>,
8506    },
8507    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8508    SetStageCopyOptions {
8509        options: Option<Expression>,
8510    },
8511    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8512    AddColumns {
8513        columns: Vec<ColumnDef>,
8514        cascade: bool,
8515    },
8516    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8517    DropColumns {
8518        names: Vec<Identifier>,
8519    },
8520    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8521    /// In SingleStore, data_type can be omitted for simple column renames
8522    ChangeColumn {
8523        old_name: Identifier,
8524        new_name: Identifier,
8525        #[serde(default, skip_serializing_if = "Option::is_none")]
8526        data_type: Option<DataType>,
8527        comment: Option<String>,
8528        #[serde(default)]
8529        cascade: bool,
8530    },
8531    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
8532    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
8533    AlterSortKey {
8534        /// AUTO or NONE keyword
8535        this: Option<String>,
8536        /// Column list for (col1, col2) syntax
8537        expressions: Vec<Expression>,
8538        /// Whether COMPOUND keyword was present
8539        compound: bool,
8540    },
8541    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
8542    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
8543    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
8544    AlterDistStyle {
8545        /// Distribution style: ALL, EVEN, AUTO, or KEY
8546        style: String,
8547        /// DISTKEY column (only when style is KEY)
8548        distkey: Option<Identifier>,
8549    },
8550    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
8551    SetTableProperties {
8552        properties: Vec<(Expression, Expression)>,
8553    },
8554    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
8555    SetLocation {
8556        location: String,
8557    },
8558    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
8559    SetFileFormat {
8560        format: String,
8561    },
8562    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
8563    ReplacePartition {
8564        partition: Expression,
8565        source: Option<Box<Expression>>,
8566    },
8567    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
8568    SetTiDBTableOption {
8569        option: TiDBTableOption,
8570        #[serde(default)]
8571        force: bool,
8572    },
8573    /// TiDB `REMOVE TTL`.
8574    RemoveTiDBTtl {
8575        #[serde(default)]
8576        executable_comment: bool,
8577    },
8578    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
8579    Raw {
8580        sql: String,
8581    },
8582}
8583
8584/// Actions for ALTER COLUMN
8585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8586#[cfg_attr(feature = "bindings", derive(TS))]
8587pub enum AlterColumnAction {
8588    SetDataType {
8589        data_type: DataType,
8590        /// USING expression for type conversion (PostgreSQL)
8591        using: Option<Expression>,
8592        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
8593        #[serde(default, skip_serializing_if = "Option::is_none")]
8594        collate: Option<String>,
8595    },
8596    SetDefault(Expression),
8597    DropDefault,
8598    SetNotNull,
8599    DropNotNull,
8600    /// Set column comment
8601    Comment(String),
8602    /// MySQL: SET VISIBLE
8603    SetVisible,
8604    /// MySQL: SET INVISIBLE
8605    SetInvisible,
8606}
8607
8608/// CREATE INDEX statement
8609#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8610#[cfg_attr(feature = "bindings", derive(TS))]
8611pub struct CreateIndex {
8612    pub name: Identifier,
8613    pub table: TableRef,
8614    pub columns: Vec<IndexColumn>,
8615    /// Expression-capable index key parts. This is used when an index contains
8616    /// functional key parts that cannot be represented by `columns`.
8617    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8618    pub key_parts: Vec<IndexKeyPart>,
8619    pub unique: bool,
8620    pub if_not_exists: bool,
8621    pub using: Option<String>,
8622    /// TSQL CLUSTERED/NONCLUSTERED modifier
8623    #[serde(default)]
8624    pub clustered: Option<String>,
8625    /// PostgreSQL CONCURRENTLY modifier
8626    #[serde(default)]
8627    pub concurrently: bool,
8628    /// PostgreSQL WHERE clause for partial indexes
8629    #[serde(default)]
8630    pub where_clause: Option<Box<Expression>>,
8631    /// PostgreSQL INCLUDE columns
8632    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8633    pub include_columns: Vec<Identifier>,
8634    /// TSQL WITH options (e.g., allow_page_locks=on)
8635    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8636    pub with_options: Vec<(String, String)>,
8637    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
8638    #[serde(default)]
8639    pub on_filegroup: Option<String>,
8640}
8641
8642impl CreateIndex {
8643    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
8644        Self {
8645            name: Identifier::new(name),
8646            table: TableRef::new(table),
8647            columns: Vec::new(),
8648            key_parts: Vec::new(),
8649            unique: false,
8650            if_not_exists: false,
8651            using: None,
8652            clustered: None,
8653            concurrently: false,
8654            where_clause: None,
8655            include_columns: Vec::new(),
8656            with_options: Vec::new(),
8657            on_filegroup: None,
8658        }
8659    }
8660}
8661
8662/// Index column specification
8663#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8664#[cfg_attr(feature = "bindings", derive(TS))]
8665pub struct IndexColumn {
8666    pub column: Identifier,
8667    pub desc: bool,
8668    /// Explicit ASC keyword was present
8669    #[serde(default)]
8670    pub asc: bool,
8671    pub nulls_first: Option<bool>,
8672    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
8673    #[serde(default, skip_serializing_if = "Option::is_none")]
8674    pub opclass: Option<String>,
8675}
8676
8677/// An expression-capable index key part.
8678#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8679#[cfg_attr(feature = "bindings", derive(TS))]
8680pub struct IndexKeyPart {
8681    pub expression: Box<Expression>,
8682    /// MySQL column prefix length, for example the `16` in `name(16)`.
8683    #[serde(default, skip_serializing_if = "Option::is_none")]
8684    pub prefix_length: Option<String>,
8685    pub desc: bool,
8686    /// Explicit ASC keyword was present.
8687    #[serde(default)]
8688    pub asc: bool,
8689    pub nulls_first: Option<bool>,
8690    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops).
8691    #[serde(default, skip_serializing_if = "Option::is_none")]
8692    pub opclass: Option<String>,
8693}
8694
8695/// DROP INDEX statement
8696#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8697#[cfg_attr(feature = "bindings", derive(TS))]
8698pub struct DropIndex {
8699    pub name: TableRef,
8700    pub table: Option<TableRef>,
8701    pub if_exists: bool,
8702    /// PostgreSQL CONCURRENTLY modifier
8703    #[serde(default)]
8704    pub concurrently: bool,
8705}
8706
8707impl DropIndex {
8708    pub fn new(name: impl Into<String>) -> Self {
8709        Self {
8710            name: TableRef::new(name),
8711            table: None,
8712            if_exists: false,
8713            concurrently: false,
8714        }
8715    }
8716}
8717
8718/// View column definition with optional COMMENT and OPTIONS (BigQuery)
8719#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8720#[cfg_attr(feature = "bindings", derive(TS))]
8721pub struct ViewColumn {
8722    pub name: Identifier,
8723    pub comment: Option<String>,
8724    /// BigQuery: OPTIONS (key=value, ...) on column
8725    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8726    pub options: Vec<Expression>,
8727}
8728
8729impl ViewColumn {
8730    pub fn new(name: impl Into<String>) -> Self {
8731        Self {
8732            name: Identifier::new(name),
8733            comment: None,
8734            options: Vec::new(),
8735        }
8736    }
8737
8738    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
8739        Self {
8740            name: Identifier::new(name),
8741            comment: Some(comment.into()),
8742            options: Vec::new(),
8743        }
8744    }
8745}
8746
8747/// CREATE VIEW statement
8748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8749#[cfg_attr(feature = "bindings", derive(TS))]
8750pub struct CreateView {
8751    pub name: TableRef,
8752    pub columns: Vec<ViewColumn>,
8753    pub query: Expression,
8754    pub or_replace: bool,
8755    /// TSQL: CREATE OR ALTER
8756    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
8757    pub or_alter: bool,
8758    pub if_not_exists: bool,
8759    pub materialized: bool,
8760    pub temporary: bool,
8761    /// Snowflake: SECURE VIEW
8762    #[serde(default)]
8763    pub secure: bool,
8764    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
8765    #[serde(skip_serializing_if = "Option::is_none")]
8766    pub algorithm: Option<String>,
8767    /// MySQL: DEFINER=user@host
8768    #[serde(skip_serializing_if = "Option::is_none")]
8769    pub definer: Option<String>,
8770    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
8771    #[serde(skip_serializing_if = "Option::is_none")]
8772    pub security: Option<FunctionSecurity>,
8773    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
8774    #[serde(default = "default_true")]
8775    pub security_sql_style: bool,
8776    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
8777    #[serde(default)]
8778    pub security_after_name: bool,
8779    /// Whether the query was parenthesized: AS (SELECT ...)
8780    #[serde(default)]
8781    pub query_parenthesized: bool,
8782    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
8783    #[serde(skip_serializing_if = "Option::is_none")]
8784    pub locking_mode: Option<String>,
8785    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
8786    #[serde(skip_serializing_if = "Option::is_none")]
8787    pub locking_access: Option<String>,
8788    /// Snowflake: COPY GRANTS
8789    #[serde(default)]
8790    pub copy_grants: bool,
8791    /// Snowflake: COMMENT = 'text'
8792    #[serde(skip_serializing_if = "Option::is_none", default)]
8793    pub comment: Option<String>,
8794    /// Snowflake: WITH ROW ACCESS POLICY ... clause
8795    #[serde(skip_serializing_if = "Option::is_none", default)]
8796    pub row_access_policy: Option<String>,
8797    /// Snowflake: TAG (name='value', ...)
8798    #[serde(default)]
8799    pub tags: Vec<(String, String)>,
8800    /// BigQuery: OPTIONS (key=value, ...)
8801    #[serde(default)]
8802    pub options: Vec<Expression>,
8803    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
8804    #[serde(skip_serializing_if = "Option::is_none", default)]
8805    pub build: Option<String>,
8806    /// Doris: REFRESH property for materialized views
8807    #[serde(skip_serializing_if = "Option::is_none", default)]
8808    pub refresh: Option<Box<RefreshTriggerProperty>>,
8809    /// Doris: Schema with typed column definitions for materialized views
8810    /// This is used instead of `columns` when the view has typed column definitions
8811    #[serde(skip_serializing_if = "Option::is_none", default)]
8812    pub schema: Option<Box<Schema>>,
8813    /// Doris: KEY (columns) for materialized views
8814    #[serde(skip_serializing_if = "Option::is_none", default)]
8815    pub unique_key: Option<Box<UniqueKeyProperty>>,
8816    /// Redshift: WITH NO SCHEMA BINDING
8817    #[serde(default)]
8818    pub no_schema_binding: bool,
8819    /// Redshift: AUTO REFRESH YES|NO for materialized views
8820    #[serde(skip_serializing_if = "Option::is_none", default)]
8821    pub auto_refresh: Option<bool>,
8822    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
8823    #[serde(skip_serializing_if = "Option::is_none", default)]
8824    pub clickhouse_population: Option<String>,
8825    /// ClickHouse: ON CLUSTER clause
8826    #[serde(default, skip_serializing_if = "Option::is_none")]
8827    pub on_cluster: Option<OnCluster>,
8828    /// ClickHouse: TO destination_table
8829    #[serde(default, skip_serializing_if = "Option::is_none")]
8830    pub to_table: Option<TableRef>,
8831    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
8832    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8833    pub table_properties: Vec<Expression>,
8834}
8835
8836impl CreateView {
8837    pub fn new(name: impl Into<String>, query: Expression) -> Self {
8838        Self {
8839            name: TableRef::new(name),
8840            columns: Vec::new(),
8841            query,
8842            or_replace: false,
8843            or_alter: false,
8844            if_not_exists: false,
8845            materialized: false,
8846            temporary: false,
8847            secure: false,
8848            algorithm: None,
8849            definer: None,
8850            security: None,
8851            security_sql_style: true,
8852            security_after_name: false,
8853            query_parenthesized: false,
8854            locking_mode: None,
8855            locking_access: None,
8856            copy_grants: false,
8857            comment: None,
8858            row_access_policy: None,
8859            tags: Vec::new(),
8860            options: Vec::new(),
8861            build: None,
8862            refresh: None,
8863            schema: None,
8864            unique_key: None,
8865            no_schema_binding: false,
8866            auto_refresh: None,
8867            clickhouse_population: None,
8868            on_cluster: None,
8869            to_table: None,
8870            table_properties: Vec::new(),
8871        }
8872    }
8873}
8874
8875/// DROP VIEW statement
8876#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8877#[cfg_attr(feature = "bindings", derive(TS))]
8878pub struct DropView {
8879    pub name: TableRef,
8880    pub if_exists: bool,
8881    pub materialized: bool,
8882}
8883
8884impl DropView {
8885    pub fn new(name: impl Into<String>) -> Self {
8886        Self {
8887            name: TableRef::new(name),
8888            if_exists: false,
8889            materialized: false,
8890        }
8891    }
8892}
8893
8894/// TRUNCATE TABLE statement
8895#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8896#[cfg_attr(feature = "bindings", derive(TS))]
8897pub struct Truncate {
8898    /// Target of TRUNCATE (TABLE vs DATABASE)
8899    #[serde(default)]
8900    pub target: TruncateTarget,
8901    /// IF EXISTS clause
8902    #[serde(default)]
8903    pub if_exists: bool,
8904    pub table: TableRef,
8905    /// ClickHouse: ON CLUSTER clause for distributed DDL
8906    #[serde(default, skip_serializing_if = "Option::is_none")]
8907    pub on_cluster: Option<OnCluster>,
8908    pub cascade: bool,
8909    /// Additional tables for multi-table TRUNCATE
8910    #[serde(default)]
8911    pub extra_tables: Vec<TruncateTableEntry>,
8912    /// RESTART IDENTITY or CONTINUE IDENTITY
8913    #[serde(default)]
8914    pub identity: Option<TruncateIdentity>,
8915    /// RESTRICT option (alternative to CASCADE)
8916    #[serde(default)]
8917    pub restrict: bool,
8918    /// Hive PARTITION clause: PARTITION(key=value, ...)
8919    #[serde(default, skip_serializing_if = "Option::is_none")]
8920    pub partition: Option<Box<Expression>>,
8921}
8922
8923/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
8924#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8925#[cfg_attr(feature = "bindings", derive(TS))]
8926pub struct TruncateTableEntry {
8927    pub table: TableRef,
8928    /// Whether the table has a * suffix (inherit children)
8929    #[serde(default)]
8930    pub star: bool,
8931}
8932
8933/// TRUNCATE target type
8934#[derive(
8935    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8936)]
8937#[cfg_attr(feature = "bindings", derive(TS))]
8938pub enum TruncateTarget {
8939    Table,
8940    Database,
8941}
8942
8943impl Default for TruncateTarget {
8944    fn default() -> Self {
8945        TruncateTarget::Table
8946    }
8947}
8948
8949/// TRUNCATE identity option
8950#[derive(
8951    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8952)]
8953#[cfg_attr(feature = "bindings", derive(TS))]
8954pub enum TruncateIdentity {
8955    Restart,
8956    Continue,
8957}
8958
8959impl Truncate {
8960    pub fn new(table: impl Into<String>) -> Self {
8961        Self {
8962            target: TruncateTarget::Table,
8963            if_exists: false,
8964            table: TableRef::new(table),
8965            on_cluster: None,
8966            cascade: false,
8967            extra_tables: Vec::new(),
8968            identity: None,
8969            restrict: false,
8970            partition: None,
8971        }
8972    }
8973}
8974
8975/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
8976#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8977#[cfg_attr(feature = "bindings", derive(TS))]
8978pub struct Use {
8979    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
8980    pub kind: Option<UseKind>,
8981    /// The name of the object
8982    pub this: Identifier,
8983}
8984
8985/// Kind of USE statement
8986#[derive(
8987    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8988)]
8989#[cfg_attr(feature = "bindings", derive(TS))]
8990pub enum UseKind {
8991    Database,
8992    Schema,
8993    Role,
8994    Warehouse,
8995    Catalog,
8996    /// Snowflake: USE SECONDARY ROLES ALL|NONE
8997    SecondaryRoles,
8998}
8999
9000/// SET variable statement
9001#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9002#[cfg_attr(feature = "bindings", derive(TS))]
9003pub struct SetStatement {
9004    /// The items being set
9005    pub items: Vec<SetItem>,
9006}
9007
9008/// A single SET item (variable assignment)
9009#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9010#[cfg_attr(feature = "bindings", derive(TS))]
9011pub struct SetItem {
9012    /// The variable name
9013    pub name: Expression,
9014    /// The value to set
9015    pub value: Expression,
9016    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
9017    pub kind: Option<String>,
9018    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
9019    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9020    pub no_equals: bool,
9021}
9022
9023/// CACHE TABLE statement (Spark)
9024#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9025#[cfg_attr(feature = "bindings", derive(TS))]
9026pub struct Cache {
9027    /// The table to cache
9028    pub table: Identifier,
9029    /// LAZY keyword - defer caching until first use
9030    pub lazy: bool,
9031    /// Optional OPTIONS clause (key-value pairs)
9032    pub options: Vec<(Expression, Expression)>,
9033    /// Optional AS clause with query
9034    pub query: Option<Expression>,
9035}
9036
9037/// UNCACHE TABLE statement (Spark)
9038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9039#[cfg_attr(feature = "bindings", derive(TS))]
9040pub struct Uncache {
9041    /// The table to uncache
9042    pub table: Identifier,
9043    /// IF EXISTS clause
9044    pub if_exists: bool,
9045}
9046
9047/// LOAD DATA statement (Hive)
9048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9049#[cfg_attr(feature = "bindings", derive(TS))]
9050pub struct LoadData {
9051    /// LOCAL keyword - load from local filesystem
9052    pub local: bool,
9053    /// The path to load data from (INPATH value)
9054    pub inpath: String,
9055    /// Whether to overwrite existing data
9056    pub overwrite: bool,
9057    /// The target table
9058    pub table: Expression,
9059    /// Optional PARTITION clause with key-value pairs
9060    pub partition: Vec<(Identifier, Expression)>,
9061    /// Optional INPUTFORMAT clause
9062    pub input_format: Option<String>,
9063    /// Optional SERDE clause
9064    pub serde: Option<String>,
9065}
9066
9067/// PRAGMA statement (SQLite)
9068#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9069#[cfg_attr(feature = "bindings", derive(TS))]
9070pub struct Pragma {
9071    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
9072    pub schema: Option<Identifier>,
9073    /// The pragma name
9074    pub name: Identifier,
9075    /// Optional value for assignment (PRAGMA name = value)
9076    pub value: Option<Expression>,
9077    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
9078    pub args: Vec<Expression>,
9079    /// Whether this pragma should be generated using assignment syntax.
9080    #[serde(default)]
9081    pub use_assignment_syntax: bool,
9082}
9083
9084/// A privilege with optional column list for GRANT/REVOKE
9085/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
9086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9087#[cfg_attr(feature = "bindings", derive(TS))]
9088pub struct Privilege {
9089    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
9090    pub name: String,
9091    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
9092    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9093    pub columns: Vec<String>,
9094}
9095
9096/// Principal in GRANT/REVOKE (user, role, etc.)
9097#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9098#[cfg_attr(feature = "bindings", derive(TS))]
9099pub struct GrantPrincipal {
9100    /// The name of the principal
9101    pub name: Identifier,
9102    /// Whether prefixed with ROLE keyword
9103    pub is_role: bool,
9104    /// Whether prefixed with GROUP keyword (Redshift)
9105    #[serde(default)]
9106    pub is_group: bool,
9107    /// Whether prefixed with SHARE keyword (Snowflake)
9108    #[serde(default)]
9109    pub is_share: bool,
9110}
9111
9112/// GRANT statement
9113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9114#[cfg_attr(feature = "bindings", derive(TS))]
9115pub struct Grant {
9116    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
9117    pub privileges: Vec<Privilege>,
9118    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9119    pub kind: Option<String>,
9120    /// The object to grant on
9121    pub securable: Identifier,
9122    /// Function parameter types (for FUNCTION kind)
9123    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9124    pub function_params: Vec<String>,
9125    /// The grantees
9126    pub principals: Vec<GrantPrincipal>,
9127    /// WITH GRANT OPTION
9128    pub grant_option: bool,
9129    /// TSQL: AS principal (the grantor role)
9130    #[serde(default, skip_serializing_if = "Option::is_none")]
9131    pub as_principal: Option<Identifier>,
9132}
9133
9134/// REVOKE statement
9135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9136#[cfg_attr(feature = "bindings", derive(TS))]
9137pub struct Revoke {
9138    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9139    pub privileges: Vec<Privilege>,
9140    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9141    pub kind: Option<String>,
9142    /// The object to revoke from
9143    pub securable: Identifier,
9144    /// Function parameter types (for FUNCTION kind)
9145    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9146    pub function_params: Vec<String>,
9147    /// The grantees
9148    pub principals: Vec<GrantPrincipal>,
9149    /// GRANT OPTION FOR
9150    pub grant_option: bool,
9151    /// CASCADE
9152    pub cascade: bool,
9153    /// RESTRICT
9154    #[serde(default)]
9155    pub restrict: bool,
9156}
9157
9158/// COMMENT ON statement
9159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9160#[cfg_attr(feature = "bindings", derive(TS))]
9161pub struct Comment {
9162    /// The object being commented on
9163    pub this: Expression,
9164    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9165    pub kind: String,
9166    /// The comment text expression
9167    pub expression: Expression,
9168    /// IF EXISTS clause
9169    pub exists: bool,
9170    /// MATERIALIZED keyword
9171    pub materialized: bool,
9172}
9173
9174// ============================================================================
9175// Phase 4: Additional DDL Statements
9176// ============================================================================
9177
9178/// ALTER VIEW statement
9179#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9180#[cfg_attr(feature = "bindings", derive(TS))]
9181pub struct AlterView {
9182    pub name: TableRef,
9183    pub actions: Vec<AlterViewAction>,
9184    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9185    #[serde(default, skip_serializing_if = "Option::is_none")]
9186    pub algorithm: Option<String>,
9187    /// MySQL: DEFINER = 'user'@'host'
9188    #[serde(default, skip_serializing_if = "Option::is_none")]
9189    pub definer: Option<String>,
9190    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9191    #[serde(default, skip_serializing_if = "Option::is_none")]
9192    pub sql_security: Option<String>,
9193    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9194    #[serde(default, skip_serializing_if = "Option::is_none")]
9195    pub with_option: Option<String>,
9196    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9197    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9198    pub columns: Vec<ViewColumn>,
9199}
9200
9201/// Actions for ALTER VIEW
9202#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9203#[cfg_attr(feature = "bindings", derive(TS))]
9204pub enum AlterViewAction {
9205    /// Rename the view
9206    Rename(TableRef),
9207    /// Change owner
9208    OwnerTo(Identifier),
9209    /// Set schema
9210    SetSchema(Identifier),
9211    /// Set authorization (Trino/Presto)
9212    SetAuthorization(String),
9213    /// Alter column
9214    AlterColumn {
9215        name: Identifier,
9216        action: AlterColumnAction,
9217    },
9218    /// Redefine view as query (SELECT, UNION, etc.)
9219    AsSelect(Box<Expression>),
9220    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9221    SetTblproperties(Vec<(String, String)>),
9222    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9223    UnsetTblproperties(Vec<String>),
9224}
9225
9226impl AlterView {
9227    pub fn new(name: impl Into<String>) -> Self {
9228        Self {
9229            name: TableRef::new(name),
9230            actions: Vec::new(),
9231            algorithm: None,
9232            definer: None,
9233            sql_security: None,
9234            with_option: None,
9235            columns: Vec::new(),
9236        }
9237    }
9238}
9239
9240/// ALTER INDEX statement
9241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9242#[cfg_attr(feature = "bindings", derive(TS))]
9243pub struct AlterIndex {
9244    pub name: Identifier,
9245    pub table: Option<TableRef>,
9246    pub actions: Vec<AlterIndexAction>,
9247}
9248
9249/// Actions for ALTER INDEX
9250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9251#[cfg_attr(feature = "bindings", derive(TS))]
9252pub enum AlterIndexAction {
9253    /// Rename the index
9254    Rename(Identifier),
9255    /// Set tablespace
9256    SetTablespace(Identifier),
9257    /// Set visibility (MySQL)
9258    Visible(bool),
9259}
9260
9261impl AlterIndex {
9262    pub fn new(name: impl Into<String>) -> Self {
9263        Self {
9264            name: Identifier::new(name),
9265            table: None,
9266            actions: Vec::new(),
9267        }
9268    }
9269}
9270
9271/// CREATE SCHEMA statement
9272#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9273#[cfg_attr(feature = "bindings", derive(TS))]
9274pub struct CreateSchema {
9275    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9276    pub name: Vec<Identifier>,
9277    pub if_not_exists: bool,
9278    pub authorization: Option<Identifier>,
9279    /// CLONE source parts, possibly dot-qualified
9280    #[serde(default)]
9281    pub clone_from: Option<Vec<Identifier>>,
9282    /// AT/BEFORE clause for time travel (Snowflake)
9283    #[serde(default)]
9284    pub at_clause: Option<Expression>,
9285    /// Schema properties like DEFAULT COLLATE
9286    #[serde(default)]
9287    pub properties: Vec<Expression>,
9288    /// Leading comments before the statement
9289    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9290    pub leading_comments: Vec<String>,
9291}
9292
9293impl CreateSchema {
9294    pub fn new(name: impl Into<String>) -> Self {
9295        Self {
9296            name: vec![Identifier::new(name)],
9297            if_not_exists: false,
9298            authorization: None,
9299            clone_from: None,
9300            at_clause: None,
9301            properties: Vec::new(),
9302            leading_comments: Vec::new(),
9303        }
9304    }
9305}
9306
9307/// DROP SCHEMA statement
9308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9309#[cfg_attr(feature = "bindings", derive(TS))]
9310pub struct DropSchema {
9311    pub name: Identifier,
9312    pub if_exists: bool,
9313    pub cascade: bool,
9314}
9315
9316impl DropSchema {
9317    pub fn new(name: impl Into<String>) -> Self {
9318        Self {
9319            name: Identifier::new(name),
9320            if_exists: false,
9321            cascade: false,
9322        }
9323    }
9324}
9325
9326/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9328#[cfg_attr(feature = "bindings", derive(TS))]
9329pub struct DropNamespace {
9330    pub name: Identifier,
9331    pub if_exists: bool,
9332    pub cascade: bool,
9333}
9334
9335impl DropNamespace {
9336    pub fn new(name: impl Into<String>) -> Self {
9337        Self {
9338            name: Identifier::new(name),
9339            if_exists: false,
9340            cascade: false,
9341        }
9342    }
9343}
9344
9345/// CREATE DATABASE statement
9346#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9347#[cfg_attr(feature = "bindings", derive(TS))]
9348pub struct CreateDatabase {
9349    pub name: Identifier,
9350    pub if_not_exists: bool,
9351    pub options: Vec<DatabaseOption>,
9352    /// Snowflake CLONE source
9353    #[serde(default)]
9354    pub clone_from: Option<Identifier>,
9355    /// AT/BEFORE clause for time travel (Snowflake)
9356    #[serde(default)]
9357    pub at_clause: Option<Expression>,
9358}
9359
9360/// Database option
9361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9362#[cfg_attr(feature = "bindings", derive(TS))]
9363pub enum DatabaseOption {
9364    CharacterSet(String),
9365    Collate(String),
9366    Owner(Identifier),
9367    Template(Identifier),
9368    Encoding(String),
9369    Location(String),
9370}
9371
9372impl CreateDatabase {
9373    pub fn new(name: impl Into<String>) -> Self {
9374        Self {
9375            name: Identifier::new(name),
9376            if_not_exists: false,
9377            options: Vec::new(),
9378            clone_from: None,
9379            at_clause: None,
9380        }
9381    }
9382}
9383
9384/// DROP DATABASE statement
9385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9386#[cfg_attr(feature = "bindings", derive(TS))]
9387pub struct DropDatabase {
9388    pub name: Identifier,
9389    pub if_exists: bool,
9390    /// ClickHouse: SYNC modifier
9391    #[serde(default)]
9392    pub sync: bool,
9393}
9394
9395impl DropDatabase {
9396    pub fn new(name: impl Into<String>) -> Self {
9397        Self {
9398            name: Identifier::new(name),
9399            if_exists: false,
9400            sync: false,
9401        }
9402    }
9403}
9404
9405/// CREATE FUNCTION statement
9406#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9407#[cfg_attr(feature = "bindings", derive(TS))]
9408pub struct CreateFunction {
9409    pub name: TableRef,
9410    pub parameters: Vec<FunctionParameter>,
9411    pub return_type: Option<DataType>,
9412    pub body: Option<FunctionBody>,
9413    pub or_replace: bool,
9414    /// TSQL: CREATE OR ALTER
9415    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9416    pub or_alter: bool,
9417    pub if_not_exists: bool,
9418    pub temporary: bool,
9419    pub language: Option<String>,
9420    pub deterministic: Option<bool>,
9421    pub returns_null_on_null_input: Option<bool>,
9422    pub security: Option<FunctionSecurity>,
9423    /// Whether parentheses were present in the original syntax
9424    #[serde(default = "default_true")]
9425    pub has_parens: bool,
9426    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9427    #[serde(default)]
9428    pub sql_data_access: Option<SqlDataAccess>,
9429    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9430    #[serde(default, skip_serializing_if = "Option::is_none")]
9431    pub returns_table_body: Option<String>,
9432    /// True if LANGUAGE clause appears before RETURNS clause
9433    #[serde(default)]
9434    pub language_first: bool,
9435    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9436    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9437    pub set_options: Vec<FunctionSetOption>,
9438    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9439    #[serde(default)]
9440    pub strict: bool,
9441    /// BigQuery: OPTIONS (key=value, ...)
9442    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9443    pub options: Vec<Expression>,
9444    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9445    #[serde(default)]
9446    pub is_table_function: bool,
9447    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9448    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9449    pub property_order: Vec<FunctionPropertyKind>,
9450    /// Hive: USING JAR|FILE|ARCHIVE '...'
9451    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9452    pub using_resources: Vec<FunctionUsingResource>,
9453    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9454    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9455    pub environment: Vec<Expression>,
9456    /// HANDLER 'handler_function' clause (Databricks)
9457    #[serde(default, skip_serializing_if = "Option::is_none")]
9458    pub handler: Option<String>,
9459    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9460    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9461    pub handler_uses_eq: bool,
9462    /// Snowflake: RUNTIME_VERSION='3.11'
9463    #[serde(default, skip_serializing_if = "Option::is_none")]
9464    pub runtime_version: Option<String>,
9465    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9466    #[serde(default, skip_serializing_if = "Option::is_none")]
9467    pub packages: Option<Vec<String>>,
9468    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9469    #[serde(default, skip_serializing_if = "Option::is_none")]
9470    pub parameter_style: Option<String>,
9471}
9472
9473/// A SET option in CREATE FUNCTION (PostgreSQL)
9474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9475#[cfg_attr(feature = "bindings", derive(TS))]
9476pub struct FunctionSetOption {
9477    pub name: String,
9478    pub value: FunctionSetValue,
9479}
9480
9481/// The value of a SET option
9482#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9483#[cfg_attr(feature = "bindings", derive(TS))]
9484pub enum FunctionSetValue {
9485    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9486    Value { value: String, use_to: bool },
9487    /// SET key FROM CURRENT
9488    FromCurrent,
9489}
9490
9491/// SQL data access characteristics for functions
9492#[derive(
9493    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9494)]
9495#[cfg_attr(feature = "bindings", derive(TS))]
9496pub enum SqlDataAccess {
9497    /// NO SQL
9498    NoSql,
9499    /// CONTAINS SQL
9500    ContainsSql,
9501    /// READS SQL DATA
9502    ReadsSqlData,
9503    /// MODIFIES SQL DATA
9504    ModifiesSqlData,
9505}
9506
9507/// Types of properties in CREATE FUNCTION for tracking their original order
9508#[derive(
9509    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9510)]
9511#[cfg_attr(feature = "bindings", derive(TS))]
9512pub enum FunctionPropertyKind {
9513    /// SET option
9514    Set,
9515    /// AS body
9516    As,
9517    /// Hive: USING JAR|FILE|ARCHIVE ...
9518    Using,
9519    /// LANGUAGE clause
9520    Language,
9521    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9522    Determinism,
9523    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
9524    NullInput,
9525    /// SECURITY DEFINER/INVOKER
9526    Security,
9527    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
9528    SqlDataAccess,
9529    /// OPTIONS clause (BigQuery)
9530    Options,
9531    /// ENVIRONMENT clause (Databricks)
9532    Environment,
9533    /// HANDLER clause (Databricks)
9534    Handler,
9535    /// Snowflake: RUNTIME_VERSION='...'
9536    RuntimeVersion,
9537    /// Snowflake: PACKAGES=(...)
9538    Packages,
9539    /// PARAMETER STYLE clause (Databricks)
9540    ParameterStyle,
9541}
9542
9543/// Hive CREATE FUNCTION resource in a USING clause
9544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9545#[cfg_attr(feature = "bindings", derive(TS))]
9546pub struct FunctionUsingResource {
9547    pub kind: String,
9548    pub uri: String,
9549}
9550
9551/// Function parameter
9552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9553#[cfg_attr(feature = "bindings", derive(TS))]
9554pub struct FunctionParameter {
9555    pub name: Option<Identifier>,
9556    pub data_type: DataType,
9557    pub mode: Option<ParameterMode>,
9558    pub default: Option<Expression>,
9559    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
9560    #[serde(default, skip_serializing_if = "Option::is_none")]
9561    pub mode_text: Option<String>,
9562}
9563
9564/// Parameter mode (IN, OUT, INOUT, VARIADIC)
9565#[derive(
9566    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9567)]
9568#[cfg_attr(feature = "bindings", derive(TS))]
9569pub enum ParameterMode {
9570    In,
9571    Out,
9572    InOut,
9573    Variadic,
9574}
9575
9576/// Function body
9577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9578#[cfg_attr(feature = "bindings", derive(TS))]
9579pub enum FunctionBody {
9580    /// AS $$ ... $$ (dollar-quoted)
9581    Block(String),
9582    /// AS 'string' (single-quoted string literal body)
9583    StringLiteral(String),
9584    /// AS 'expression'
9585    Expression(Expression),
9586    /// EXTERNAL NAME 'library'
9587    External(String),
9588    /// RETURN expression
9589    Return(Expression),
9590    /// BEGIN ... END block with parsed statements
9591    Statements(Vec<Expression>),
9592    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
9593    /// Stores (content, optional_tag)
9594    DollarQuoted {
9595        content: String,
9596        tag: Option<String>,
9597    },
9598    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
9599    RawBlock(String),
9600}
9601
9602/// Function security (DEFINER, INVOKER, or NONE)
9603#[derive(
9604    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9605)]
9606#[cfg_attr(feature = "bindings", derive(TS))]
9607pub enum FunctionSecurity {
9608    Definer,
9609    Invoker,
9610    /// StarRocks/MySQL: SECURITY NONE
9611    None,
9612}
9613
9614impl CreateFunction {
9615    pub fn new(name: impl Into<String>) -> Self {
9616        Self {
9617            name: TableRef::new(name),
9618            parameters: Vec::new(),
9619            return_type: None,
9620            body: None,
9621            or_replace: false,
9622            or_alter: false,
9623            if_not_exists: false,
9624            temporary: false,
9625            language: None,
9626            deterministic: None,
9627            returns_null_on_null_input: None,
9628            security: None,
9629            has_parens: true,
9630            sql_data_access: None,
9631            returns_table_body: None,
9632            language_first: false,
9633            set_options: Vec::new(),
9634            strict: false,
9635            options: Vec::new(),
9636            is_table_function: false,
9637            property_order: Vec::new(),
9638            using_resources: Vec::new(),
9639            environment: Vec::new(),
9640            handler: None,
9641            handler_uses_eq: false,
9642            runtime_version: None,
9643            packages: None,
9644            parameter_style: None,
9645        }
9646    }
9647}
9648
9649/// DROP FUNCTION statement
9650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9651#[cfg_attr(feature = "bindings", derive(TS))]
9652pub struct DropFunction {
9653    pub name: TableRef,
9654    pub parameters: Option<Vec<DataType>>,
9655    pub if_exists: bool,
9656    pub cascade: bool,
9657}
9658
9659impl DropFunction {
9660    pub fn new(name: impl Into<String>) -> Self {
9661        Self {
9662            name: TableRef::new(name),
9663            parameters: None,
9664            if_exists: false,
9665            cascade: false,
9666        }
9667    }
9668}
9669
9670/// CREATE PROCEDURE statement
9671#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9672#[cfg_attr(feature = "bindings", derive(TS))]
9673pub struct CreateProcedure {
9674    pub name: TableRef,
9675    pub parameters: Vec<FunctionParameter>,
9676    pub body: Option<FunctionBody>,
9677    pub or_replace: bool,
9678    /// TSQL: CREATE OR ALTER
9679    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9680    pub or_alter: bool,
9681    pub if_not_exists: bool,
9682    pub language: Option<String>,
9683    pub security: Option<FunctionSecurity>,
9684    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
9685    #[serde(default)]
9686    pub return_type: Option<DataType>,
9687    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
9688    #[serde(default)]
9689    pub execute_as: Option<String>,
9690    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
9691    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9692    pub with_options: Vec<String>,
9693    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
9694    #[serde(default = "default_true", skip_serializing_if = "is_true")]
9695    pub has_parens: bool,
9696    /// Whether the short form PROC was used (instead of PROCEDURE)
9697    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9698    pub use_proc_keyword: bool,
9699}
9700
9701impl CreateProcedure {
9702    pub fn new(name: impl Into<String>) -> Self {
9703        Self {
9704            name: TableRef::new(name),
9705            parameters: Vec::new(),
9706            body: None,
9707            or_replace: false,
9708            or_alter: false,
9709            if_not_exists: false,
9710            language: None,
9711            security: None,
9712            return_type: None,
9713            execute_as: None,
9714            with_options: Vec::new(),
9715            has_parens: true,
9716            use_proc_keyword: false,
9717        }
9718    }
9719}
9720
9721/// DROP PROCEDURE statement
9722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9723#[cfg_attr(feature = "bindings", derive(TS))]
9724pub struct DropProcedure {
9725    pub name: TableRef,
9726    pub parameters: Option<Vec<DataType>>,
9727    pub if_exists: bool,
9728    pub cascade: bool,
9729}
9730
9731impl DropProcedure {
9732    pub fn new(name: impl Into<String>) -> Self {
9733        Self {
9734            name: TableRef::new(name),
9735            parameters: None,
9736            if_exists: false,
9737            cascade: false,
9738        }
9739    }
9740}
9741
9742/// Sequence property tag for ordering
9743#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9744#[cfg_attr(feature = "bindings", derive(TS))]
9745pub enum SeqPropKind {
9746    Start,
9747    Increment,
9748    Minvalue,
9749    Maxvalue,
9750    Cache,
9751    NoCache,
9752    Cycle,
9753    NoCycle,
9754    OwnedBy,
9755    Order,
9756    NoOrder,
9757    Comment,
9758    /// SHARING=<value> (Oracle)
9759    Sharing,
9760    /// KEEP (Oracle)
9761    Keep,
9762    /// NOKEEP (Oracle)
9763    NoKeep,
9764    /// SCALE [EXTEND|NOEXTEND] (Oracle)
9765    Scale,
9766    /// NOSCALE (Oracle)
9767    NoScale,
9768    /// SHARD [EXTEND|NOEXTEND] (Oracle)
9769    Shard,
9770    /// NOSHARD (Oracle)
9771    NoShard,
9772    /// SESSION (Oracle)
9773    Session,
9774    /// GLOBAL (Oracle)
9775    Global,
9776    /// NOCACHE (single word, Oracle)
9777    NoCacheWord,
9778    /// NOCYCLE (single word, Oracle)
9779    NoCycleWord,
9780    /// NOMINVALUE (single word, Oracle)
9781    NoMinvalueWord,
9782    /// NOMAXVALUE (single word, Oracle)
9783    NoMaxvalueWord,
9784}
9785
9786/// CREATE SYNONYM statement (TSQL)
9787#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9788#[cfg_attr(feature = "bindings", derive(TS))]
9789pub struct CreateSynonym {
9790    /// The synonym name (can be qualified: schema.synonym_name)
9791    pub name: TableRef,
9792    /// The target object the synonym refers to
9793    pub target: TableRef,
9794}
9795
9796/// CREATE SEQUENCE statement
9797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9798#[cfg_attr(feature = "bindings", derive(TS))]
9799pub struct CreateSequence {
9800    pub name: TableRef,
9801    pub if_not_exists: bool,
9802    pub temporary: bool,
9803    #[serde(default)]
9804    pub or_replace: bool,
9805    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
9806    #[serde(default, skip_serializing_if = "Option::is_none")]
9807    pub as_type: Option<DataType>,
9808    pub increment: Option<i64>,
9809    pub minvalue: Option<SequenceBound>,
9810    pub maxvalue: Option<SequenceBound>,
9811    pub start: Option<i64>,
9812    pub cache: Option<i64>,
9813    pub cycle: bool,
9814    pub owned_by: Option<TableRef>,
9815    /// Whether OWNED BY NONE was specified
9816    #[serde(default)]
9817    pub owned_by_none: bool,
9818    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
9819    #[serde(default)]
9820    pub order: Option<bool>,
9821    /// Snowflake: COMMENT = 'value'
9822    #[serde(default)]
9823    pub comment: Option<String>,
9824    /// SHARING=<value> (Oracle)
9825    #[serde(default, skip_serializing_if = "Option::is_none")]
9826    pub sharing: Option<String>,
9827    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
9828    #[serde(default, skip_serializing_if = "Option::is_none")]
9829    pub scale_modifier: Option<String>,
9830    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
9831    #[serde(default, skip_serializing_if = "Option::is_none")]
9832    pub shard_modifier: Option<String>,
9833    /// Tracks the order in which properties appeared in the source
9834    #[serde(default)]
9835    pub property_order: Vec<SeqPropKind>,
9836}
9837
9838/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
9839#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9840#[cfg_attr(feature = "bindings", derive(TS))]
9841pub enum SequenceBound {
9842    Value(i64),
9843    None,
9844}
9845
9846impl CreateSequence {
9847    pub fn new(name: impl Into<String>) -> Self {
9848        Self {
9849            name: TableRef::new(name),
9850            if_not_exists: false,
9851            temporary: false,
9852            or_replace: false,
9853            as_type: None,
9854            increment: None,
9855            minvalue: None,
9856            maxvalue: None,
9857            start: None,
9858            cache: None,
9859            cycle: false,
9860            owned_by: None,
9861            owned_by_none: false,
9862            order: None,
9863            comment: None,
9864            sharing: None,
9865            scale_modifier: None,
9866            shard_modifier: None,
9867            property_order: Vec::new(),
9868        }
9869    }
9870}
9871
9872/// DROP SEQUENCE statement
9873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9874#[cfg_attr(feature = "bindings", derive(TS))]
9875pub struct DropSequence {
9876    pub name: TableRef,
9877    pub if_exists: bool,
9878    pub cascade: bool,
9879}
9880
9881impl DropSequence {
9882    pub fn new(name: impl Into<String>) -> Self {
9883        Self {
9884            name: TableRef::new(name),
9885            if_exists: false,
9886            cascade: false,
9887        }
9888    }
9889}
9890
9891/// ALTER SEQUENCE statement
9892#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9893#[cfg_attr(feature = "bindings", derive(TS))]
9894pub struct AlterSequence {
9895    pub name: TableRef,
9896    pub if_exists: bool,
9897    pub increment: Option<i64>,
9898    pub minvalue: Option<SequenceBound>,
9899    pub maxvalue: Option<SequenceBound>,
9900    pub start: Option<i64>,
9901    pub restart: Option<Option<i64>>,
9902    pub cache: Option<i64>,
9903    pub cycle: Option<bool>,
9904    pub owned_by: Option<Option<TableRef>>,
9905}
9906
9907impl AlterSequence {
9908    pub fn new(name: impl Into<String>) -> Self {
9909        Self {
9910            name: TableRef::new(name),
9911            if_exists: false,
9912            increment: None,
9913            minvalue: None,
9914            maxvalue: None,
9915            start: None,
9916            restart: None,
9917            cache: None,
9918            cycle: None,
9919            owned_by: None,
9920        }
9921    }
9922}
9923
9924/// CREATE TRIGGER statement
9925#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9926#[cfg_attr(feature = "bindings", derive(TS))]
9927pub struct CreateTrigger {
9928    pub name: Identifier,
9929    pub table: TableRef,
9930    pub timing: TriggerTiming,
9931    pub events: Vec<TriggerEvent>,
9932    #[serde(default, skip_serializing_if = "Option::is_none")]
9933    pub for_each: Option<TriggerForEach>,
9934    pub when: Option<Expression>,
9935    /// Whether the WHEN clause was parenthesized in the original SQL
9936    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9937    pub when_paren: bool,
9938    pub body: TriggerBody,
9939    pub or_replace: bool,
9940    /// TSQL: CREATE OR ALTER
9941    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9942    pub or_alter: bool,
9943    pub constraint: bool,
9944    pub deferrable: Option<bool>,
9945    pub initially_deferred: Option<bool>,
9946    pub referencing: Option<TriggerReferencing>,
9947}
9948
9949/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
9950#[derive(
9951    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9952)]
9953#[cfg_attr(feature = "bindings", derive(TS))]
9954pub enum TriggerTiming {
9955    Before,
9956    After,
9957    InsteadOf,
9958}
9959
9960/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
9961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9962#[cfg_attr(feature = "bindings", derive(TS))]
9963pub enum TriggerEvent {
9964    Insert,
9965    Update(Option<Vec<Identifier>>),
9966    Delete,
9967    Truncate,
9968}
9969
9970/// Trigger FOR EACH clause
9971#[derive(
9972    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9973)]
9974#[cfg_attr(feature = "bindings", derive(TS))]
9975pub enum TriggerForEach {
9976    Row,
9977    Statement,
9978}
9979
9980/// Trigger body
9981#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9982#[cfg_attr(feature = "bindings", derive(TS))]
9983pub enum TriggerBody {
9984    /// EXECUTE FUNCTION/PROCEDURE name(args)
9985    Execute {
9986        function: TableRef,
9987        args: Vec<Expression>,
9988    },
9989    /// BEGIN ... END block
9990    Block(String),
9991}
9992
9993/// Trigger REFERENCING clause
9994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9995#[cfg_attr(feature = "bindings", derive(TS))]
9996pub struct TriggerReferencing {
9997    pub old_table: Option<Identifier>,
9998    pub new_table: Option<Identifier>,
9999    pub old_row: Option<Identifier>,
10000    pub new_row: Option<Identifier>,
10001}
10002
10003impl CreateTrigger {
10004    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
10005        Self {
10006            name: Identifier::new(name),
10007            table: TableRef::new(table),
10008            timing: TriggerTiming::Before,
10009            events: Vec::new(),
10010            for_each: Some(TriggerForEach::Row),
10011            when: None,
10012            when_paren: false,
10013            body: TriggerBody::Execute {
10014                function: TableRef::new(""),
10015                args: Vec::new(),
10016            },
10017            or_replace: false,
10018            or_alter: false,
10019            constraint: false,
10020            deferrable: None,
10021            initially_deferred: None,
10022            referencing: None,
10023        }
10024    }
10025}
10026
10027/// DROP TRIGGER statement
10028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10029#[cfg_attr(feature = "bindings", derive(TS))]
10030pub struct DropTrigger {
10031    pub name: Identifier,
10032    pub table: Option<TableRef>,
10033    pub if_exists: bool,
10034    pub cascade: bool,
10035}
10036
10037impl DropTrigger {
10038    pub fn new(name: impl Into<String>) -> Self {
10039        Self {
10040            name: Identifier::new(name),
10041            table: None,
10042            if_exists: false,
10043            cascade: false,
10044        }
10045    }
10046}
10047
10048/// CREATE TYPE statement
10049#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10050#[cfg_attr(feature = "bindings", derive(TS))]
10051pub struct CreateType {
10052    pub name: TableRef,
10053    pub definition: TypeDefinition,
10054    pub if_not_exists: bool,
10055}
10056
10057/// Type definition
10058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10059#[cfg_attr(feature = "bindings", derive(TS))]
10060pub enum TypeDefinition {
10061    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
10062    Enum(Vec<String>),
10063    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
10064    Composite(Vec<TypeAttribute>),
10065    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
10066    Range {
10067        subtype: DataType,
10068        subtype_diff: Option<String>,
10069        canonical: Option<String>,
10070    },
10071    /// Base type (for advanced usage)
10072    Base {
10073        input: String,
10074        output: String,
10075        internallength: Option<i32>,
10076    },
10077    /// Domain type
10078    Domain {
10079        base_type: DataType,
10080        default: Option<Expression>,
10081        constraints: Vec<DomainConstraint>,
10082    },
10083}
10084
10085/// Type attribute for composite types
10086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10087#[cfg_attr(feature = "bindings", derive(TS))]
10088pub struct TypeAttribute {
10089    pub name: Identifier,
10090    pub data_type: DataType,
10091    pub collate: Option<Identifier>,
10092}
10093
10094/// Domain constraint
10095#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10096#[cfg_attr(feature = "bindings", derive(TS))]
10097pub struct DomainConstraint {
10098    pub name: Option<Identifier>,
10099    pub check: Expression,
10100}
10101
10102impl CreateType {
10103    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
10104        Self {
10105            name: TableRef::new(name),
10106            definition: TypeDefinition::Enum(values),
10107            if_not_exists: false,
10108        }
10109    }
10110
10111    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
10112        Self {
10113            name: TableRef::new(name),
10114            definition: TypeDefinition::Composite(attributes),
10115            if_not_exists: false,
10116        }
10117    }
10118}
10119
10120/// DROP TYPE statement
10121#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10122#[cfg_attr(feature = "bindings", derive(TS))]
10123pub struct DropType {
10124    pub name: TableRef,
10125    pub if_exists: bool,
10126    pub cascade: bool,
10127}
10128
10129impl DropType {
10130    pub fn new(name: impl Into<String>) -> Self {
10131        Self {
10132            name: TableRef::new(name),
10133            if_exists: false,
10134            cascade: false,
10135        }
10136    }
10137}
10138
10139/// DESCRIBE statement - shows table structure or query plan
10140#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10141#[cfg_attr(feature = "bindings", derive(TS))]
10142pub struct Describe {
10143    /// The target to describe (table name or query)
10144    pub target: Expression,
10145    /// EXTENDED format
10146    pub extended: bool,
10147    /// FORMATTED format
10148    pub formatted: bool,
10149    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10150    #[serde(default)]
10151    pub kind: Option<String>,
10152    /// Properties like type=stage
10153    #[serde(default)]
10154    pub properties: Vec<(String, String)>,
10155    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10156    #[serde(default, skip_serializing_if = "Option::is_none")]
10157    pub style: Option<String>,
10158    /// Partition specification for DESCRIBE PARTITION
10159    #[serde(default)]
10160    pub partition: Option<Box<Expression>>,
10161    /// Leading comments before the statement
10162    #[serde(default)]
10163    pub leading_comments: Vec<String>,
10164    /// AS JSON suffix (Databricks)
10165    #[serde(default)]
10166    pub as_json: bool,
10167    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10168    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10169    pub params: Vec<String>,
10170}
10171
10172impl Describe {
10173    pub fn new(target: Expression) -> Self {
10174        Self {
10175            target,
10176            extended: false,
10177            formatted: false,
10178            kind: None,
10179            properties: Vec::new(),
10180            style: None,
10181            partition: None,
10182            leading_comments: Vec::new(),
10183            as_json: false,
10184            params: Vec::new(),
10185        }
10186    }
10187}
10188
10189/// SHOW statement - displays database objects
10190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10191#[cfg_attr(feature = "bindings", derive(TS))]
10192pub struct Show {
10193    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10194    pub this: String,
10195    /// Whether TERSE was specified
10196    #[serde(default)]
10197    pub terse: bool,
10198    /// Whether HISTORY was specified
10199    #[serde(default)]
10200    pub history: bool,
10201    /// LIKE pattern
10202    pub like: Option<Expression>,
10203    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10204    pub scope_kind: Option<String>,
10205    /// IN scope object
10206    pub scope: Option<Expression>,
10207    /// STARTS WITH pattern
10208    pub starts_with: Option<Expression>,
10209    /// LIMIT clause
10210    pub limit: Option<Box<Limit>>,
10211    /// FROM clause (for specific object)
10212    pub from: Option<Expression>,
10213    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10214    #[serde(default, skip_serializing_if = "Option::is_none")]
10215    pub where_clause: Option<Expression>,
10216    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10217    #[serde(default, skip_serializing_if = "Option::is_none")]
10218    pub for_target: Option<Expression>,
10219    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10220    #[serde(default, skip_serializing_if = "Option::is_none")]
10221    pub db: Option<Expression>,
10222    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10223    #[serde(default, skip_serializing_if = "Option::is_none")]
10224    pub target: Option<Expression>,
10225    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10226    #[serde(default, skip_serializing_if = "Option::is_none")]
10227    pub mutex: Option<bool>,
10228    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10229    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10230    pub privileges: Vec<String>,
10231}
10232
10233impl Show {
10234    pub fn new(this: impl Into<String>) -> Self {
10235        Self {
10236            this: this.into(),
10237            terse: false,
10238            history: false,
10239            like: None,
10240            scope_kind: None,
10241            scope: None,
10242            starts_with: None,
10243            limit: None,
10244            from: None,
10245            where_clause: None,
10246            for_target: None,
10247            db: None,
10248            target: None,
10249            mutex: None,
10250            privileges: Vec::new(),
10251        }
10252    }
10253}
10254
10255/// Represent an explicit parenthesized expression for grouping precedence.
10256///
10257/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10258/// correctly instead of being flattened to `a + b * c`.
10259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10260#[cfg_attr(feature = "bindings", derive(TS))]
10261pub struct Paren {
10262    /// The inner expression wrapped by parentheses.
10263    pub this: Expression,
10264    #[serde(default)]
10265    pub trailing_comments: Vec<String>,
10266}
10267
10268/// Expression annotated with trailing comments (for round-trip preservation)
10269#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10270#[cfg_attr(feature = "bindings", derive(TS))]
10271pub struct Annotated {
10272    pub this: Expression,
10273    pub trailing_comments: Vec<String>,
10274}
10275
10276// === BATCH GENERATED STRUCT DEFINITIONS ===
10277// Generated from Python sqlglot expressions.py
10278
10279/// Refresh
10280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10281#[cfg_attr(feature = "bindings", derive(TS))]
10282pub struct Refresh {
10283    pub this: Box<Expression>,
10284    pub kind: String,
10285}
10286
10287/// LockingStatement
10288#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10289#[cfg_attr(feature = "bindings", derive(TS))]
10290pub struct LockingStatement {
10291    pub this: Box<Expression>,
10292    pub expression: Box<Expression>,
10293}
10294
10295/// SequenceProperties
10296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10297#[cfg_attr(feature = "bindings", derive(TS))]
10298pub struct SequenceProperties {
10299    #[serde(default)]
10300    pub increment: Option<Box<Expression>>,
10301    #[serde(default)]
10302    pub minvalue: Option<Box<Expression>>,
10303    #[serde(default)]
10304    pub maxvalue: Option<Box<Expression>>,
10305    #[serde(default)]
10306    pub cache: Option<Box<Expression>>,
10307    #[serde(default)]
10308    pub start: Option<Box<Expression>>,
10309    #[serde(default)]
10310    pub owned: Option<Box<Expression>>,
10311    #[serde(default)]
10312    pub options: Vec<Expression>,
10313}
10314
10315/// TruncateTable
10316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10317#[cfg_attr(feature = "bindings", derive(TS))]
10318pub struct TruncateTable {
10319    #[serde(default)]
10320    pub expressions: Vec<Expression>,
10321    #[serde(default)]
10322    pub is_database: Option<Box<Expression>>,
10323    #[serde(default)]
10324    pub exists: bool,
10325    #[serde(default)]
10326    pub only: Option<Box<Expression>>,
10327    #[serde(default)]
10328    pub cluster: Option<Box<Expression>>,
10329    #[serde(default)]
10330    pub identity: Option<Box<Expression>>,
10331    #[serde(default)]
10332    pub option: Option<Box<Expression>>,
10333    #[serde(default)]
10334    pub partition: Option<Box<Expression>>,
10335}
10336
10337/// Clone
10338#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10339#[cfg_attr(feature = "bindings", derive(TS))]
10340pub struct Clone {
10341    pub this: Box<Expression>,
10342    #[serde(default)]
10343    pub shallow: Option<Box<Expression>>,
10344    #[serde(default)]
10345    pub copy: Option<Box<Expression>>,
10346}
10347
10348/// Attach
10349#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10350#[cfg_attr(feature = "bindings", derive(TS))]
10351pub struct Attach {
10352    pub this: Box<Expression>,
10353    #[serde(default)]
10354    pub exists: bool,
10355    #[serde(default)]
10356    pub expressions: Vec<Expression>,
10357}
10358
10359/// Detach
10360#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10361#[cfg_attr(feature = "bindings", derive(TS))]
10362pub struct Detach {
10363    pub this: Box<Expression>,
10364    #[serde(default)]
10365    pub exists: bool,
10366}
10367
10368/// Install
10369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10370#[cfg_attr(feature = "bindings", derive(TS))]
10371pub struct Install {
10372    pub this: Box<Expression>,
10373    #[serde(default)]
10374    pub from_: Option<Box<Expression>>,
10375    #[serde(default)]
10376    pub force: Option<Box<Expression>>,
10377}
10378
10379/// Summarize
10380#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10381#[cfg_attr(feature = "bindings", derive(TS))]
10382pub struct Summarize {
10383    pub this: Box<Expression>,
10384    #[serde(default)]
10385    pub table: Option<Box<Expression>>,
10386}
10387
10388/// Declare
10389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10390#[cfg_attr(feature = "bindings", derive(TS))]
10391pub struct Declare {
10392    #[serde(default)]
10393    pub expressions: Vec<Expression>,
10394    #[serde(default)]
10395    pub replace: bool,
10396}
10397
10398/// DeclareItem
10399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10400#[cfg_attr(feature = "bindings", derive(TS))]
10401pub struct DeclareItem {
10402    pub this: Box<Expression>,
10403    #[serde(default)]
10404    pub kind: Option<String>,
10405    #[serde(default)]
10406    pub default: Option<Box<Expression>>,
10407    #[serde(default)]
10408    pub has_as: bool,
10409    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10410    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10411    pub additional_names: Vec<Expression>,
10412}
10413
10414/// Set
10415#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10416#[cfg_attr(feature = "bindings", derive(TS))]
10417pub struct Set {
10418    #[serde(default)]
10419    pub expressions: Vec<Expression>,
10420    #[serde(default)]
10421    pub unset: Option<Box<Expression>>,
10422    #[serde(default)]
10423    pub tag: Option<Box<Expression>>,
10424}
10425
10426/// Heredoc
10427#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10428#[cfg_attr(feature = "bindings", derive(TS))]
10429pub struct Heredoc {
10430    pub this: Box<Expression>,
10431    #[serde(default)]
10432    pub tag: Option<Box<Expression>>,
10433}
10434
10435/// QueryBand
10436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10437#[cfg_attr(feature = "bindings", derive(TS))]
10438pub struct QueryBand {
10439    pub this: Box<Expression>,
10440    #[serde(default)]
10441    pub scope: Option<Box<Expression>>,
10442    #[serde(default)]
10443    pub update: Option<Box<Expression>>,
10444}
10445
10446/// UserDefinedFunction
10447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10448#[cfg_attr(feature = "bindings", derive(TS))]
10449pub struct UserDefinedFunction {
10450    pub this: Box<Expression>,
10451    #[serde(default)]
10452    pub expressions: Vec<Expression>,
10453    #[serde(default)]
10454    pub wrapped: Option<Box<Expression>>,
10455}
10456
10457/// RecursiveWithSearch
10458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10459#[cfg_attr(feature = "bindings", derive(TS))]
10460pub struct RecursiveWithSearch {
10461    pub kind: String,
10462    pub this: Box<Expression>,
10463    pub expression: Box<Expression>,
10464    #[serde(default)]
10465    pub using: Option<Box<Expression>>,
10466}
10467
10468/// ProjectionDef
10469#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10470#[cfg_attr(feature = "bindings", derive(TS))]
10471pub struct ProjectionDef {
10472    pub this: Box<Expression>,
10473    pub expression: Box<Expression>,
10474}
10475
10476/// TableAlias
10477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10478#[cfg_attr(feature = "bindings", derive(TS))]
10479pub struct TableAlias {
10480    #[serde(default)]
10481    pub this: Option<Box<Expression>>,
10482    #[serde(default)]
10483    pub columns: Vec<Expression>,
10484}
10485
10486/// ByteString
10487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10488#[cfg_attr(feature = "bindings", derive(TS))]
10489pub struct ByteString {
10490    pub this: Box<Expression>,
10491    #[serde(default)]
10492    pub is_bytes: Option<Box<Expression>>,
10493}
10494
10495/// HexStringExpr - Hex string expression (not literal)
10496/// BigQuery: converts to FROM_HEX(this)
10497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10498#[cfg_attr(feature = "bindings", derive(TS))]
10499pub struct HexStringExpr {
10500    pub this: Box<Expression>,
10501    #[serde(default)]
10502    pub is_integer: Option<bool>,
10503}
10504
10505/// UnicodeString
10506#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10507#[cfg_attr(feature = "bindings", derive(TS))]
10508pub struct UnicodeString {
10509    pub this: Box<Expression>,
10510    #[serde(default)]
10511    pub escape: Option<Box<Expression>>,
10512}
10513
10514/// AlterColumn
10515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10516#[cfg_attr(feature = "bindings", derive(TS))]
10517pub struct AlterColumn {
10518    pub this: Box<Expression>,
10519    #[serde(default)]
10520    pub dtype: Option<Box<Expression>>,
10521    #[serde(default)]
10522    pub collate: Option<Box<Expression>>,
10523    #[serde(default)]
10524    pub using: Option<Box<Expression>>,
10525    #[serde(default)]
10526    pub default: Option<Box<Expression>>,
10527    #[serde(default)]
10528    pub drop: Option<Box<Expression>>,
10529    #[serde(default)]
10530    pub comment: Option<Box<Expression>>,
10531    #[serde(default)]
10532    pub allow_null: Option<Box<Expression>>,
10533    #[serde(default)]
10534    pub visible: Option<Box<Expression>>,
10535    #[serde(default)]
10536    pub rename_to: Option<Box<Expression>>,
10537}
10538
10539/// AlterSortKey
10540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10541#[cfg_attr(feature = "bindings", derive(TS))]
10542pub struct AlterSortKey {
10543    #[serde(default)]
10544    pub this: Option<Box<Expression>>,
10545    #[serde(default)]
10546    pub expressions: Vec<Expression>,
10547    #[serde(default)]
10548    pub compound: Option<Box<Expression>>,
10549}
10550
10551/// AlterSet
10552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10553#[cfg_attr(feature = "bindings", derive(TS))]
10554pub struct AlterSet {
10555    #[serde(default)]
10556    pub expressions: Vec<Expression>,
10557    #[serde(default)]
10558    pub option: Option<Box<Expression>>,
10559    #[serde(default)]
10560    pub tablespace: Option<Box<Expression>>,
10561    #[serde(default)]
10562    pub access_method: Option<Box<Expression>>,
10563    #[serde(default)]
10564    pub file_format: Option<Box<Expression>>,
10565    #[serde(default)]
10566    pub copy_options: Option<Box<Expression>>,
10567    #[serde(default)]
10568    pub tag: Option<Box<Expression>>,
10569    #[serde(default)]
10570    pub location: Option<Box<Expression>>,
10571    #[serde(default)]
10572    pub serde: Option<Box<Expression>>,
10573}
10574
10575/// RenameColumn
10576#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10577#[cfg_attr(feature = "bindings", derive(TS))]
10578pub struct RenameColumn {
10579    pub this: Box<Expression>,
10580    #[serde(default)]
10581    pub to: Option<Box<Expression>>,
10582    #[serde(default)]
10583    pub exists: bool,
10584}
10585
10586/// Comprehension
10587#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10588#[cfg_attr(feature = "bindings", derive(TS))]
10589pub struct Comprehension {
10590    pub this: Box<Expression>,
10591    pub expression: Box<Expression>,
10592    #[serde(default)]
10593    pub position: Option<Box<Expression>>,
10594    #[serde(default)]
10595    pub iterator: Option<Box<Expression>>,
10596    #[serde(default)]
10597    pub condition: Option<Box<Expression>>,
10598}
10599
10600/// MergeTreeTTLAction
10601#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10602#[cfg_attr(feature = "bindings", derive(TS))]
10603pub struct MergeTreeTTLAction {
10604    pub this: Box<Expression>,
10605    #[serde(default)]
10606    pub delete: Option<Box<Expression>>,
10607    #[serde(default)]
10608    pub recompress: Option<Box<Expression>>,
10609    #[serde(default)]
10610    pub to_disk: Option<Box<Expression>>,
10611    #[serde(default)]
10612    pub to_volume: Option<Box<Expression>>,
10613}
10614
10615/// MergeTreeTTL
10616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10617#[cfg_attr(feature = "bindings", derive(TS))]
10618pub struct MergeTreeTTL {
10619    #[serde(default)]
10620    pub expressions: Vec<Expression>,
10621    #[serde(default)]
10622    pub where_: Option<Box<Expression>>,
10623    #[serde(default)]
10624    pub group: Option<Box<Expression>>,
10625    #[serde(default)]
10626    pub aggregates: Option<Box<Expression>>,
10627}
10628
10629/// IndexConstraintOption
10630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10631#[cfg_attr(feature = "bindings", derive(TS))]
10632pub struct IndexConstraintOption {
10633    #[serde(default)]
10634    pub key_block_size: Option<Box<Expression>>,
10635    #[serde(default)]
10636    pub using: Option<Box<Expression>>,
10637    #[serde(default)]
10638    pub parser: Option<Box<Expression>>,
10639    #[serde(default)]
10640    pub comment: Option<Box<Expression>>,
10641    #[serde(default)]
10642    pub visible: Option<Box<Expression>>,
10643    #[serde(default)]
10644    pub engine_attr: Option<Box<Expression>>,
10645    #[serde(default)]
10646    pub secondary_engine_attr: Option<Box<Expression>>,
10647}
10648
10649/// PeriodForSystemTimeConstraint
10650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10651#[cfg_attr(feature = "bindings", derive(TS))]
10652pub struct PeriodForSystemTimeConstraint {
10653    pub this: Box<Expression>,
10654    pub expression: Box<Expression>,
10655}
10656
10657/// CaseSpecificColumnConstraint
10658#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10659#[cfg_attr(feature = "bindings", derive(TS))]
10660pub struct CaseSpecificColumnConstraint {
10661    #[serde(default)]
10662    pub not_: Option<Box<Expression>>,
10663}
10664
10665/// CharacterSetColumnConstraint
10666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10667#[cfg_attr(feature = "bindings", derive(TS))]
10668pub struct CharacterSetColumnConstraint {
10669    pub this: Box<Expression>,
10670}
10671
10672/// CheckColumnConstraint
10673#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10674#[cfg_attr(feature = "bindings", derive(TS))]
10675pub struct CheckColumnConstraint {
10676    pub this: Box<Expression>,
10677    #[serde(default)]
10678    pub enforced: Option<Box<Expression>>,
10679}
10680
10681/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
10682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10683#[cfg_attr(feature = "bindings", derive(TS))]
10684pub struct AssumeColumnConstraint {
10685    pub this: Box<Expression>,
10686}
10687
10688/// CompressColumnConstraint
10689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10690#[cfg_attr(feature = "bindings", derive(TS))]
10691pub struct CompressColumnConstraint {
10692    #[serde(default)]
10693    pub this: Option<Box<Expression>>,
10694}
10695
10696/// DateFormatColumnConstraint
10697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10698#[cfg_attr(feature = "bindings", derive(TS))]
10699pub struct DateFormatColumnConstraint {
10700    pub this: Box<Expression>,
10701}
10702
10703/// EphemeralColumnConstraint
10704#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10705#[cfg_attr(feature = "bindings", derive(TS))]
10706pub struct EphemeralColumnConstraint {
10707    #[serde(default)]
10708    pub this: Option<Box<Expression>>,
10709}
10710
10711/// WithOperator
10712#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10713#[cfg_attr(feature = "bindings", derive(TS))]
10714pub struct WithOperator {
10715    pub this: Box<Expression>,
10716    pub op: String,
10717}
10718
10719/// GeneratedAsIdentityColumnConstraint
10720#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10721#[cfg_attr(feature = "bindings", derive(TS))]
10722pub struct GeneratedAsIdentityColumnConstraint {
10723    #[serde(default)]
10724    pub this: Option<Box<Expression>>,
10725    #[serde(default)]
10726    pub expression: Option<Box<Expression>>,
10727    #[serde(default)]
10728    pub on_null: Option<Box<Expression>>,
10729    #[serde(default)]
10730    pub start: Option<Box<Expression>>,
10731    #[serde(default)]
10732    pub increment: Option<Box<Expression>>,
10733    #[serde(default)]
10734    pub minvalue: Option<Box<Expression>>,
10735    #[serde(default)]
10736    pub maxvalue: Option<Box<Expression>>,
10737    #[serde(default)]
10738    pub cycle: Option<Box<Expression>>,
10739    #[serde(default)]
10740    pub order: Option<Box<Expression>>,
10741}
10742
10743/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
10744/// TSQL: outputs "IDENTITY"
10745#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10746#[cfg_attr(feature = "bindings", derive(TS))]
10747pub struct AutoIncrementColumnConstraint;
10748
10749/// CommentColumnConstraint - Column comment marker
10750#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10751#[cfg_attr(feature = "bindings", derive(TS))]
10752pub struct CommentColumnConstraint;
10753
10754/// GeneratedAsRowColumnConstraint
10755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10756#[cfg_attr(feature = "bindings", derive(TS))]
10757pub struct GeneratedAsRowColumnConstraint {
10758    #[serde(default)]
10759    pub start: Option<Box<Expression>>,
10760    #[serde(default)]
10761    pub hidden: Option<Box<Expression>>,
10762}
10763
10764/// IndexColumnConstraint
10765#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10766#[cfg_attr(feature = "bindings", derive(TS))]
10767pub struct IndexColumnConstraint {
10768    #[serde(default)]
10769    pub this: Option<Box<Expression>>,
10770    #[serde(default)]
10771    pub expressions: Vec<Expression>,
10772    #[serde(default)]
10773    pub kind: Option<String>,
10774    #[serde(default)]
10775    pub index_type: Option<Box<Expression>>,
10776    #[serde(default)]
10777    pub options: Vec<Expression>,
10778    #[serde(default)]
10779    pub expression: Option<Box<Expression>>,
10780    #[serde(default)]
10781    pub granularity: Option<Box<Expression>>,
10782}
10783
10784/// MaskingPolicyColumnConstraint
10785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10786#[cfg_attr(feature = "bindings", derive(TS))]
10787pub struct MaskingPolicyColumnConstraint {
10788    pub this: Box<Expression>,
10789    #[serde(default)]
10790    pub expressions: Vec<Expression>,
10791}
10792
10793/// NotNullColumnConstraint
10794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10795#[cfg_attr(feature = "bindings", derive(TS))]
10796pub struct NotNullColumnConstraint {
10797    #[serde(default)]
10798    pub allow_null: Option<Box<Expression>>,
10799}
10800
10801/// DefaultColumnConstraint - DEFAULT value for a column
10802#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10803#[cfg_attr(feature = "bindings", derive(TS))]
10804pub struct DefaultColumnConstraint {
10805    pub this: Box<Expression>,
10806    /// TSQL: DEFAULT value FOR column (table-level default constraint)
10807    #[serde(default, skip_serializing_if = "Option::is_none")]
10808    pub for_column: Option<Identifier>,
10809}
10810
10811/// PrimaryKeyColumnConstraint
10812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10813#[cfg_attr(feature = "bindings", derive(TS))]
10814pub struct PrimaryKeyColumnConstraint {
10815    #[serde(default)]
10816    pub desc: Option<Box<Expression>>,
10817    #[serde(default)]
10818    pub options: Vec<Expression>,
10819}
10820
10821/// UniqueColumnConstraint
10822#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10823#[cfg_attr(feature = "bindings", derive(TS))]
10824pub struct UniqueColumnConstraint {
10825    #[serde(default)]
10826    pub this: Option<Box<Expression>>,
10827    #[serde(default)]
10828    pub index_type: Option<Box<Expression>>,
10829    #[serde(default)]
10830    pub on_conflict: Option<Box<Expression>>,
10831    #[serde(default)]
10832    pub nulls: Option<Box<Expression>>,
10833    #[serde(default)]
10834    pub options: Vec<Expression>,
10835}
10836
10837/// WatermarkColumnConstraint
10838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10839#[cfg_attr(feature = "bindings", derive(TS))]
10840pub struct WatermarkColumnConstraint {
10841    pub this: Box<Expression>,
10842    pub expression: Box<Expression>,
10843}
10844
10845/// ComputedColumnConstraint
10846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10847#[cfg_attr(feature = "bindings", derive(TS))]
10848pub struct ComputedColumnConstraint {
10849    pub this: Box<Expression>,
10850    #[serde(default)]
10851    pub persisted: Option<Box<Expression>>,
10852    #[serde(default)]
10853    pub not_null: Option<Box<Expression>>,
10854    #[serde(default)]
10855    pub data_type: Option<Box<Expression>>,
10856}
10857
10858/// InOutColumnConstraint
10859#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10860#[cfg_attr(feature = "bindings", derive(TS))]
10861pub struct InOutColumnConstraint {
10862    #[serde(default)]
10863    pub input_: Option<Box<Expression>>,
10864    #[serde(default)]
10865    pub output: Option<Box<Expression>>,
10866}
10867
10868/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
10869#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10870#[cfg_attr(feature = "bindings", derive(TS))]
10871pub struct PathColumnConstraint {
10872    pub this: Box<Expression>,
10873}
10874
10875/// Constraint
10876#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10877#[cfg_attr(feature = "bindings", derive(TS))]
10878pub struct Constraint {
10879    pub this: Box<Expression>,
10880    #[serde(default)]
10881    pub expressions: Vec<Expression>,
10882}
10883
10884/// Export
10885#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10886#[cfg_attr(feature = "bindings", derive(TS))]
10887pub struct Export {
10888    pub this: Box<Expression>,
10889    #[serde(default)]
10890    pub connection: Option<Box<Expression>>,
10891    #[serde(default)]
10892    pub options: Vec<Expression>,
10893}
10894
10895/// Filter
10896#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10897#[cfg_attr(feature = "bindings", derive(TS))]
10898pub struct Filter {
10899    pub this: Box<Expression>,
10900    pub expression: Box<Expression>,
10901}
10902
10903/// Changes
10904#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10905#[cfg_attr(feature = "bindings", derive(TS))]
10906pub struct Changes {
10907    #[serde(default)]
10908    pub information: Option<Box<Expression>>,
10909    #[serde(default)]
10910    pub at_before: Option<Box<Expression>>,
10911    #[serde(default)]
10912    pub end: Option<Box<Expression>>,
10913}
10914
10915/// Directory
10916#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10917#[cfg_attr(feature = "bindings", derive(TS))]
10918pub struct Directory {
10919    pub this: Box<Expression>,
10920    #[serde(default)]
10921    pub local: Option<Box<Expression>>,
10922    #[serde(default)]
10923    pub row_format: Option<Box<Expression>>,
10924}
10925
10926/// ForeignKey
10927#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10928#[cfg_attr(feature = "bindings", derive(TS))]
10929pub struct ForeignKey {
10930    #[serde(default)]
10931    pub expressions: Vec<Expression>,
10932    #[serde(default)]
10933    pub reference: Option<Box<Expression>>,
10934    #[serde(default)]
10935    pub delete: Option<Box<Expression>>,
10936    #[serde(default)]
10937    pub update: Option<Box<Expression>>,
10938    #[serde(default)]
10939    pub options: Vec<Expression>,
10940}
10941
10942/// ColumnPrefix
10943#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10944#[cfg_attr(feature = "bindings", derive(TS))]
10945pub struct ColumnPrefix {
10946    pub this: Box<Expression>,
10947    pub expression: Box<Expression>,
10948}
10949
10950/// PrimaryKey
10951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10952#[cfg_attr(feature = "bindings", derive(TS))]
10953pub struct PrimaryKey {
10954    #[serde(default)]
10955    pub this: Option<Box<Expression>>,
10956    #[serde(default)]
10957    pub expressions: Vec<Expression>,
10958    #[serde(default)]
10959    pub options: Vec<Expression>,
10960    #[serde(default)]
10961    pub include: Option<Box<Expression>>,
10962}
10963
10964/// Into
10965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10966#[cfg_attr(feature = "bindings", derive(TS))]
10967pub struct IntoClause {
10968    #[serde(default)]
10969    pub this: Option<Box<Expression>>,
10970    #[serde(default)]
10971    pub temporary: bool,
10972    #[serde(default)]
10973    pub unlogged: Option<Box<Expression>>,
10974    #[serde(default)]
10975    pub bulk_collect: Option<Box<Expression>>,
10976    #[serde(default)]
10977    pub expressions: Vec<Expression>,
10978}
10979
10980/// JoinHint
10981#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10982#[cfg_attr(feature = "bindings", derive(TS))]
10983pub struct JoinHint {
10984    pub this: Box<Expression>,
10985    #[serde(default)]
10986    pub expressions: Vec<Expression>,
10987}
10988
10989/// Opclass
10990#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10991#[cfg_attr(feature = "bindings", derive(TS))]
10992pub struct Opclass {
10993    pub this: Box<Expression>,
10994    pub expression: Box<Expression>,
10995}
10996
10997/// Index
10998#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10999#[cfg_attr(feature = "bindings", derive(TS))]
11000pub struct Index {
11001    #[serde(default)]
11002    pub this: Option<Box<Expression>>,
11003    #[serde(default)]
11004    pub table: Option<Box<Expression>>,
11005    #[serde(default)]
11006    pub unique: bool,
11007    #[serde(default)]
11008    pub primary: Option<Box<Expression>>,
11009    #[serde(default)]
11010    pub amp: Option<Box<Expression>>,
11011    #[serde(default)]
11012    pub params: Vec<Expression>,
11013}
11014
11015/// IndexParameters
11016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11017#[cfg_attr(feature = "bindings", derive(TS))]
11018pub struct IndexParameters {
11019    #[serde(default)]
11020    pub using: Option<Box<Expression>>,
11021    #[serde(default)]
11022    pub include: Option<Box<Expression>>,
11023    #[serde(default)]
11024    pub columns: Vec<Expression>,
11025    #[serde(default)]
11026    pub with_storage: Option<Box<Expression>>,
11027    #[serde(default)]
11028    pub partition_by: Option<Box<Expression>>,
11029    #[serde(default)]
11030    pub tablespace: Option<Box<Expression>>,
11031    #[serde(default)]
11032    pub where_: Option<Box<Expression>>,
11033    #[serde(default)]
11034    pub on: Option<Box<Expression>>,
11035}
11036
11037/// ConditionalInsert
11038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11039#[cfg_attr(feature = "bindings", derive(TS))]
11040pub struct ConditionalInsert {
11041    pub this: Box<Expression>,
11042    #[serde(default)]
11043    pub expression: Option<Box<Expression>>,
11044    #[serde(default)]
11045    pub else_: Option<Box<Expression>>,
11046}
11047
11048/// MultitableInserts
11049#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11050#[cfg_attr(feature = "bindings", derive(TS))]
11051pub struct MultitableInserts {
11052    #[serde(default)]
11053    pub expressions: Vec<Expression>,
11054    pub kind: String,
11055    #[serde(default)]
11056    pub source: Option<Box<Expression>>,
11057    /// Leading comments before the statement
11058    #[serde(default)]
11059    pub leading_comments: Vec<String>,
11060    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
11061    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11062    pub overwrite: bool,
11063}
11064
11065/// OnConflict
11066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11067#[cfg_attr(feature = "bindings", derive(TS))]
11068pub struct OnConflict {
11069    #[serde(default)]
11070    pub duplicate: Option<Box<Expression>>,
11071    #[serde(default)]
11072    pub expressions: Vec<Expression>,
11073    #[serde(default)]
11074    pub action: Option<Box<Expression>>,
11075    #[serde(default)]
11076    pub conflict_keys: Option<Box<Expression>>,
11077    #[serde(default)]
11078    pub index_predicate: Option<Box<Expression>>,
11079    #[serde(default)]
11080    pub constraint: Option<Box<Expression>>,
11081    #[serde(default)]
11082    pub where_: Option<Box<Expression>>,
11083}
11084
11085/// OnCondition
11086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11087#[cfg_attr(feature = "bindings", derive(TS))]
11088pub struct OnCondition {
11089    #[serde(default)]
11090    pub error: Option<Box<Expression>>,
11091    #[serde(default)]
11092    pub empty: Option<Box<Expression>>,
11093    #[serde(default)]
11094    pub null: Option<Box<Expression>>,
11095}
11096
11097/// Returning
11098#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11099#[cfg_attr(feature = "bindings", derive(TS))]
11100pub struct Returning {
11101    #[serde(default)]
11102    pub expressions: Vec<Expression>,
11103    #[serde(default)]
11104    pub into: Option<Box<Expression>>,
11105}
11106
11107/// Introducer
11108#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11109#[cfg_attr(feature = "bindings", derive(TS))]
11110pub struct Introducer {
11111    pub this: Box<Expression>,
11112    pub expression: Box<Expression>,
11113}
11114
11115/// PartitionRange
11116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11117#[cfg_attr(feature = "bindings", derive(TS))]
11118pub struct PartitionRange {
11119    pub this: Box<Expression>,
11120    #[serde(default)]
11121    pub expression: Option<Box<Expression>>,
11122    #[serde(default)]
11123    pub expressions: Vec<Expression>,
11124}
11125
11126/// Group
11127#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11128#[cfg_attr(feature = "bindings", derive(TS))]
11129pub struct Group {
11130    #[serde(default)]
11131    pub expressions: Vec<Expression>,
11132    #[serde(default)]
11133    pub grouping_sets: Option<Box<Expression>>,
11134    #[serde(default)]
11135    pub cube: Option<Box<Expression>>,
11136    #[serde(default)]
11137    pub rollup: Option<Box<Expression>>,
11138    #[serde(default)]
11139    pub totals: Option<Box<Expression>>,
11140    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11141    #[serde(default)]
11142    pub all: Option<bool>,
11143}
11144
11145/// Cube
11146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11147#[cfg_attr(feature = "bindings", derive(TS))]
11148pub struct Cube {
11149    #[serde(default)]
11150    pub expressions: Vec<Expression>,
11151}
11152
11153/// Rollup
11154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11155#[cfg_attr(feature = "bindings", derive(TS))]
11156pub struct Rollup {
11157    #[serde(default)]
11158    pub expressions: Vec<Expression>,
11159}
11160
11161/// GroupingSets
11162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11163#[cfg_attr(feature = "bindings", derive(TS))]
11164pub struct GroupingSets {
11165    #[serde(default)]
11166    pub expressions: Vec<Expression>,
11167}
11168
11169/// LimitOptions
11170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11171#[cfg_attr(feature = "bindings", derive(TS))]
11172pub struct LimitOptions {
11173    #[serde(default)]
11174    pub percent: Option<Box<Expression>>,
11175    #[serde(default)]
11176    pub rows: Option<Box<Expression>>,
11177    #[serde(default)]
11178    pub with_ties: Option<Box<Expression>>,
11179}
11180
11181/// Lateral
11182#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11183#[cfg_attr(feature = "bindings", derive(TS))]
11184pub struct Lateral {
11185    pub this: Box<Expression>,
11186    #[serde(default)]
11187    pub view: Option<Box<Expression>>,
11188    #[serde(default)]
11189    pub outer: Option<Box<Expression>>,
11190    #[serde(default)]
11191    pub alias: Option<String>,
11192    /// Whether the alias was originally quoted (backtick/double-quote)
11193    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11194    pub alias_quoted: bool,
11195    #[serde(default)]
11196    pub cross_apply: Option<Box<Expression>>,
11197    #[serde(default)]
11198    pub ordinality: Option<Box<Expression>>,
11199    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11200    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11201    pub column_aliases: Vec<String>,
11202}
11203
11204/// TableFromRows
11205#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11206#[cfg_attr(feature = "bindings", derive(TS))]
11207pub struct TableFromRows {
11208    pub this: Box<Expression>,
11209    #[serde(default)]
11210    pub alias: Option<String>,
11211    #[serde(default)]
11212    pub joins: Vec<Expression>,
11213    #[serde(default)]
11214    pub pivots: Option<Box<Expression>>,
11215    #[serde(default)]
11216    pub sample: Option<Box<Expression>>,
11217}
11218
11219/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11220/// Used for set-returning functions with typed column definitions
11221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11222#[cfg_attr(feature = "bindings", derive(TS))]
11223pub struct RowsFrom {
11224    /// List of function expressions, each potentially with an alias and typed columns
11225    pub expressions: Vec<Expression>,
11226    /// WITH ORDINALITY modifier
11227    #[serde(default)]
11228    pub ordinality: bool,
11229    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11230    #[serde(default)]
11231    pub alias: Option<Box<Expression>>,
11232}
11233
11234/// WithFill
11235#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11236#[cfg_attr(feature = "bindings", derive(TS))]
11237pub struct WithFill {
11238    #[serde(default)]
11239    pub from_: Option<Box<Expression>>,
11240    #[serde(default)]
11241    pub to: Option<Box<Expression>>,
11242    #[serde(default)]
11243    pub step: Option<Box<Expression>>,
11244    #[serde(default)]
11245    pub staleness: Option<Box<Expression>>,
11246    #[serde(default)]
11247    pub interpolate: Option<Box<Expression>>,
11248}
11249
11250/// Property
11251#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11252#[cfg_attr(feature = "bindings", derive(TS))]
11253pub struct Property {
11254    pub this: Box<Expression>,
11255    #[serde(default)]
11256    pub value: Option<Box<Expression>>,
11257}
11258
11259/// GrantPrivilege
11260#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11261#[cfg_attr(feature = "bindings", derive(TS))]
11262pub struct GrantPrivilege {
11263    pub this: Box<Expression>,
11264    #[serde(default)]
11265    pub expressions: Vec<Expression>,
11266}
11267
11268/// AllowedValuesProperty
11269#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11270#[cfg_attr(feature = "bindings", derive(TS))]
11271pub struct AllowedValuesProperty {
11272    #[serde(default)]
11273    pub expressions: Vec<Expression>,
11274}
11275
11276/// AlgorithmProperty
11277#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11278#[cfg_attr(feature = "bindings", derive(TS))]
11279pub struct AlgorithmProperty {
11280    pub this: Box<Expression>,
11281}
11282
11283/// AutoIncrementProperty
11284#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11285#[cfg_attr(feature = "bindings", derive(TS))]
11286pub struct AutoIncrementProperty {
11287    pub this: Box<Expression>,
11288}
11289
11290/// AutoRefreshProperty
11291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11292#[cfg_attr(feature = "bindings", derive(TS))]
11293pub struct AutoRefreshProperty {
11294    pub this: Box<Expression>,
11295}
11296
11297/// BackupProperty
11298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11299#[cfg_attr(feature = "bindings", derive(TS))]
11300pub struct BackupProperty {
11301    pub this: Box<Expression>,
11302}
11303
11304/// BuildProperty
11305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11306#[cfg_attr(feature = "bindings", derive(TS))]
11307pub struct BuildProperty {
11308    pub this: Box<Expression>,
11309}
11310
11311/// BlockCompressionProperty
11312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11313#[cfg_attr(feature = "bindings", derive(TS))]
11314pub struct BlockCompressionProperty {
11315    #[serde(default)]
11316    pub autotemp: Option<Box<Expression>>,
11317    #[serde(default)]
11318    pub always: Option<Box<Expression>>,
11319    #[serde(default)]
11320    pub default: Option<Box<Expression>>,
11321    #[serde(default)]
11322    pub manual: Option<Box<Expression>>,
11323    #[serde(default)]
11324    pub never: Option<Box<Expression>>,
11325}
11326
11327/// CharacterSetProperty
11328#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11329#[cfg_attr(feature = "bindings", derive(TS))]
11330pub struct CharacterSetProperty {
11331    pub this: Box<Expression>,
11332    #[serde(default)]
11333    pub default: Option<Box<Expression>>,
11334}
11335
11336/// ChecksumProperty
11337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11338#[cfg_attr(feature = "bindings", derive(TS))]
11339pub struct ChecksumProperty {
11340    #[serde(default)]
11341    pub on: Option<Box<Expression>>,
11342    #[serde(default)]
11343    pub default: Option<Box<Expression>>,
11344}
11345
11346/// CollateProperty
11347#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11348#[cfg_attr(feature = "bindings", derive(TS))]
11349pub struct CollateProperty {
11350    pub this: Box<Expression>,
11351    #[serde(default)]
11352    pub default: Option<Box<Expression>>,
11353}
11354
11355/// DataBlocksizeProperty
11356#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11357#[cfg_attr(feature = "bindings", derive(TS))]
11358pub struct DataBlocksizeProperty {
11359    #[serde(default)]
11360    pub size: Option<i64>,
11361    #[serde(default)]
11362    pub units: Option<Box<Expression>>,
11363    #[serde(default)]
11364    pub minimum: Option<Box<Expression>>,
11365    #[serde(default)]
11366    pub maximum: Option<Box<Expression>>,
11367    #[serde(default)]
11368    pub default: Option<Box<Expression>>,
11369}
11370
11371/// DataDeletionProperty
11372#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11373#[cfg_attr(feature = "bindings", derive(TS))]
11374pub struct DataDeletionProperty {
11375    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11376    #[ast(skip)]
11377    pub on: Box<Expression>,
11378    #[serde(default)]
11379    pub filter_column: Option<Box<Expression>>,
11380    #[serde(default)]
11381    pub retention_period: Option<Box<Expression>>,
11382}
11383
11384/// DefinerProperty
11385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11386#[cfg_attr(feature = "bindings", derive(TS))]
11387pub struct DefinerProperty {
11388    pub this: Box<Expression>,
11389}
11390
11391/// DistKeyProperty
11392#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11393#[cfg_attr(feature = "bindings", derive(TS))]
11394pub struct DistKeyProperty {
11395    pub this: Box<Expression>,
11396}
11397
11398/// DistributedByProperty
11399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11400#[cfg_attr(feature = "bindings", derive(TS))]
11401pub struct DistributedByProperty {
11402    #[serde(default)]
11403    pub expressions: Vec<Expression>,
11404    pub kind: String,
11405    #[serde(default)]
11406    pub buckets: Option<Box<Expression>>,
11407    #[serde(default)]
11408    pub order: Option<Box<Expression>>,
11409}
11410
11411/// DistStyleProperty
11412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11413#[cfg_attr(feature = "bindings", derive(TS))]
11414pub struct DistStyleProperty {
11415    pub this: Box<Expression>,
11416}
11417
11418/// DuplicateKeyProperty
11419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11420#[cfg_attr(feature = "bindings", derive(TS))]
11421pub struct DuplicateKeyProperty {
11422    #[serde(default)]
11423    pub expressions: Vec<Expression>,
11424}
11425
11426/// EngineProperty
11427#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11428#[cfg_attr(feature = "bindings", derive(TS))]
11429pub struct EngineProperty {
11430    pub this: Box<Expression>,
11431}
11432
11433/// ToTableProperty
11434#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11435#[cfg_attr(feature = "bindings", derive(TS))]
11436pub struct ToTableProperty {
11437    pub this: Box<Expression>,
11438}
11439
11440/// ExecuteAsProperty
11441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11442#[cfg_attr(feature = "bindings", derive(TS))]
11443pub struct ExecuteAsProperty {
11444    pub this: Box<Expression>,
11445}
11446
11447/// ExternalProperty
11448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11449#[cfg_attr(feature = "bindings", derive(TS))]
11450pub struct ExternalProperty {
11451    #[serde(default)]
11452    pub this: Option<Box<Expression>>,
11453}
11454
11455/// FallbackProperty
11456#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11457#[cfg_attr(feature = "bindings", derive(TS))]
11458pub struct FallbackProperty {
11459    #[serde(default)]
11460    pub no: Option<Box<Expression>>,
11461    #[serde(default)]
11462    pub protection: Option<Box<Expression>>,
11463}
11464
11465/// FileFormatProperty
11466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11467#[cfg_attr(feature = "bindings", derive(TS))]
11468pub struct FileFormatProperty {
11469    #[serde(default)]
11470    pub this: Option<Box<Expression>>,
11471    #[serde(default)]
11472    pub expressions: Vec<Expression>,
11473    #[serde(default)]
11474    pub hive_format: Option<Box<Expression>>,
11475}
11476
11477/// CredentialsProperty
11478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11479#[cfg_attr(feature = "bindings", derive(TS))]
11480pub struct CredentialsProperty {
11481    #[serde(default)]
11482    pub expressions: Vec<Expression>,
11483}
11484
11485/// FreespaceProperty
11486#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11487#[cfg_attr(feature = "bindings", derive(TS))]
11488pub struct FreespaceProperty {
11489    pub this: Box<Expression>,
11490    #[serde(default)]
11491    pub percent: Option<Box<Expression>>,
11492}
11493
11494/// InheritsProperty
11495#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11496#[cfg_attr(feature = "bindings", derive(TS))]
11497pub struct InheritsProperty {
11498    #[serde(default)]
11499    pub expressions: Vec<Expression>,
11500}
11501
11502/// InputModelProperty
11503#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11504#[cfg_attr(feature = "bindings", derive(TS))]
11505pub struct InputModelProperty {
11506    pub this: Box<Expression>,
11507}
11508
11509/// OutputModelProperty
11510#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11511#[cfg_attr(feature = "bindings", derive(TS))]
11512pub struct OutputModelProperty {
11513    pub this: Box<Expression>,
11514}
11515
11516/// IsolatedLoadingProperty
11517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11518#[cfg_attr(feature = "bindings", derive(TS))]
11519pub struct IsolatedLoadingProperty {
11520    #[serde(default)]
11521    pub no: Option<Box<Expression>>,
11522    #[serde(default)]
11523    pub concurrent: Option<Box<Expression>>,
11524    #[serde(default)]
11525    pub target: Option<Box<Expression>>,
11526}
11527
11528/// JournalProperty
11529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11530#[cfg_attr(feature = "bindings", derive(TS))]
11531pub struct JournalProperty {
11532    #[serde(default)]
11533    pub no: Option<Box<Expression>>,
11534    #[serde(default)]
11535    pub dual: Option<Box<Expression>>,
11536    #[serde(default)]
11537    pub before: Option<Box<Expression>>,
11538    #[serde(default)]
11539    pub local: Option<Box<Expression>>,
11540    #[serde(default)]
11541    pub after: Option<Box<Expression>>,
11542}
11543
11544/// LanguageProperty
11545#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11546#[cfg_attr(feature = "bindings", derive(TS))]
11547pub struct LanguageProperty {
11548    pub this: Box<Expression>,
11549}
11550
11551/// EnviromentProperty
11552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11553#[cfg_attr(feature = "bindings", derive(TS))]
11554pub struct EnviromentProperty {
11555    #[serde(default)]
11556    pub expressions: Vec<Expression>,
11557}
11558
11559/// ClusteredByProperty
11560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11561#[cfg_attr(feature = "bindings", derive(TS))]
11562pub struct ClusteredByProperty {
11563    #[serde(default)]
11564    pub expressions: Vec<Expression>,
11565    #[serde(default)]
11566    pub sorted_by: Option<Box<Expression>>,
11567    #[serde(default)]
11568    pub buckets: Option<Box<Expression>>,
11569}
11570
11571/// DictProperty
11572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11573#[cfg_attr(feature = "bindings", derive(TS))]
11574pub struct DictProperty {
11575    pub this: Box<Expression>,
11576    pub kind: String,
11577    #[serde(default)]
11578    pub settings: Option<Box<Expression>>,
11579}
11580
11581/// DictRange
11582#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11583#[cfg_attr(feature = "bindings", derive(TS))]
11584pub struct DictRange {
11585    pub this: Box<Expression>,
11586    #[serde(default)]
11587    pub min: Option<Box<Expression>>,
11588    #[serde(default)]
11589    pub max: Option<Box<Expression>>,
11590}
11591
11592/// OnCluster
11593#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11594#[cfg_attr(feature = "bindings", derive(TS))]
11595pub struct OnCluster {
11596    pub this: Box<Expression>,
11597}
11598
11599/// LikeProperty
11600#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11601#[cfg_attr(feature = "bindings", derive(TS))]
11602pub struct LikeProperty {
11603    pub this: Box<Expression>,
11604    #[serde(default)]
11605    pub expressions: Vec<Expression>,
11606}
11607
11608/// LocationProperty
11609#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11610#[cfg_attr(feature = "bindings", derive(TS))]
11611pub struct LocationProperty {
11612    pub this: Box<Expression>,
11613}
11614
11615/// LockProperty
11616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11617#[cfg_attr(feature = "bindings", derive(TS))]
11618pub struct LockProperty {
11619    pub this: Box<Expression>,
11620}
11621
11622/// LockingProperty
11623#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11624#[cfg_attr(feature = "bindings", derive(TS))]
11625pub struct LockingProperty {
11626    #[serde(default)]
11627    pub this: Option<Box<Expression>>,
11628    pub kind: String,
11629    #[serde(default)]
11630    pub for_or_in: Option<Box<Expression>>,
11631    #[serde(default)]
11632    pub lock_type: Option<Box<Expression>>,
11633    #[serde(default)]
11634    pub override_: Option<Box<Expression>>,
11635}
11636
11637/// LogProperty
11638#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11639#[cfg_attr(feature = "bindings", derive(TS))]
11640pub struct LogProperty {
11641    #[serde(default)]
11642    pub no: Option<Box<Expression>>,
11643}
11644
11645/// MaterializedProperty
11646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11647#[cfg_attr(feature = "bindings", derive(TS))]
11648pub struct MaterializedProperty {
11649    #[serde(default)]
11650    pub this: Option<Box<Expression>>,
11651}
11652
11653/// MergeBlockRatioProperty
11654#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11655#[cfg_attr(feature = "bindings", derive(TS))]
11656pub struct MergeBlockRatioProperty {
11657    #[serde(default)]
11658    pub this: Option<Box<Expression>>,
11659    #[serde(default)]
11660    pub no: Option<Box<Expression>>,
11661    #[serde(default)]
11662    pub default: Option<Box<Expression>>,
11663    #[serde(default)]
11664    pub percent: Option<Box<Expression>>,
11665}
11666
11667/// OnProperty
11668#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11669#[cfg_attr(feature = "bindings", derive(TS))]
11670pub struct OnProperty {
11671    pub this: Box<Expression>,
11672}
11673
11674/// OnCommitProperty
11675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11676#[cfg_attr(feature = "bindings", derive(TS))]
11677pub struct OnCommitProperty {
11678    #[serde(default)]
11679    pub delete: Option<Box<Expression>>,
11680}
11681
11682/// PartitionedByProperty
11683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11684#[cfg_attr(feature = "bindings", derive(TS))]
11685pub struct PartitionedByProperty {
11686    pub this: Box<Expression>,
11687}
11688
11689/// BigQuery PARTITION BY property in CREATE TABLE statements.
11690#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11691#[cfg_attr(feature = "bindings", derive(TS))]
11692pub struct PartitionByProperty {
11693    #[serde(default)]
11694    pub expressions: Vec<Expression>,
11695}
11696
11697/// PartitionedByBucket
11698#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11699#[cfg_attr(feature = "bindings", derive(TS))]
11700pub struct PartitionedByBucket {
11701    pub this: Box<Expression>,
11702    pub expression: Box<Expression>,
11703}
11704
11705/// BigQuery CLUSTER BY property in CREATE TABLE statements.
11706#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11707#[cfg_attr(feature = "bindings", derive(TS))]
11708pub struct ClusterByColumnsProperty {
11709    #[serde(default)]
11710    pub columns: Vec<Identifier>,
11711}
11712
11713/// PartitionByTruncate
11714#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11715#[cfg_attr(feature = "bindings", derive(TS))]
11716pub struct PartitionByTruncate {
11717    pub this: Box<Expression>,
11718    pub expression: Box<Expression>,
11719}
11720
11721/// PartitionByRangeProperty
11722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11723#[cfg_attr(feature = "bindings", derive(TS))]
11724pub struct PartitionByRangeProperty {
11725    #[serde(default)]
11726    pub partition_expressions: Option<Box<Expression>>,
11727    #[serde(default)]
11728    pub create_expressions: Option<Box<Expression>>,
11729}
11730
11731/// PartitionByRangePropertyDynamic
11732#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11733#[cfg_attr(feature = "bindings", derive(TS))]
11734pub struct PartitionByRangePropertyDynamic {
11735    #[serde(default)]
11736    pub this: Option<Box<Expression>>,
11737    #[serde(default)]
11738    pub start: Option<Box<Expression>>,
11739    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
11740    #[serde(default)]
11741    pub use_start_end: bool,
11742    #[serde(default)]
11743    pub end: Option<Box<Expression>>,
11744    #[serde(default)]
11745    pub every: Option<Box<Expression>>,
11746}
11747
11748/// PartitionByListProperty
11749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11750#[cfg_attr(feature = "bindings", derive(TS))]
11751pub struct PartitionByListProperty {
11752    #[serde(default)]
11753    pub partition_expressions: Option<Box<Expression>>,
11754    #[serde(default)]
11755    pub create_expressions: Option<Box<Expression>>,
11756}
11757
11758/// PartitionList
11759#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11760#[cfg_attr(feature = "bindings", derive(TS))]
11761pub struct PartitionList {
11762    pub this: Box<Expression>,
11763    #[serde(default)]
11764    pub expressions: Vec<Expression>,
11765}
11766
11767/// Partition - represents PARTITION/SUBPARTITION clause
11768#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11769#[cfg_attr(feature = "bindings", derive(TS))]
11770pub struct Partition {
11771    pub expressions: Vec<Expression>,
11772    #[serde(default)]
11773    pub subpartition: bool,
11774}
11775
11776/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
11777/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
11778#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11779#[cfg_attr(feature = "bindings", derive(TS))]
11780pub struct RefreshTriggerProperty {
11781    /// Method: COMPLETE or AUTO
11782    pub method: String,
11783    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
11784    #[serde(default)]
11785    pub kind: Option<String>,
11786    /// For SCHEDULE: EVERY n (the number)
11787    #[serde(default)]
11788    pub every: Option<Box<Expression>>,
11789    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
11790    #[serde(default)]
11791    pub unit: Option<String>,
11792    /// For SCHEDULE: STARTS 'datetime'
11793    #[serde(default)]
11794    pub starts: Option<Box<Expression>>,
11795}
11796
11797/// UniqueKeyProperty
11798#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11799#[cfg_attr(feature = "bindings", derive(TS))]
11800pub struct UniqueKeyProperty {
11801    #[serde(default)]
11802    pub expressions: Vec<Expression>,
11803}
11804
11805/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
11806#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11807#[cfg_attr(feature = "bindings", derive(TS))]
11808pub struct RollupProperty {
11809    pub expressions: Vec<RollupIndex>,
11810}
11811
11812/// RollupIndex - A single rollup index: name(col1, col2)
11813#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11814#[cfg_attr(feature = "bindings", derive(TS))]
11815pub struct RollupIndex {
11816    pub name: Identifier,
11817    pub expressions: Vec<Identifier>,
11818}
11819
11820/// PartitionBoundSpec
11821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11822#[cfg_attr(feature = "bindings", derive(TS))]
11823pub struct PartitionBoundSpec {
11824    #[serde(default)]
11825    pub this: Option<Box<Expression>>,
11826    #[serde(default)]
11827    pub expression: Option<Box<Expression>>,
11828    #[serde(default)]
11829    pub from_expressions: Option<Box<Expression>>,
11830    #[serde(default)]
11831    pub to_expressions: Option<Box<Expression>>,
11832}
11833
11834/// PartitionedOfProperty
11835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11836#[cfg_attr(feature = "bindings", derive(TS))]
11837pub struct PartitionedOfProperty {
11838    pub this: Box<Expression>,
11839    pub expression: Box<Expression>,
11840}
11841
11842/// RemoteWithConnectionModelProperty
11843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11844#[cfg_attr(feature = "bindings", derive(TS))]
11845pub struct RemoteWithConnectionModelProperty {
11846    pub this: Box<Expression>,
11847}
11848
11849/// ReturnsProperty
11850#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11851#[cfg_attr(feature = "bindings", derive(TS))]
11852pub struct ReturnsProperty {
11853    #[serde(default)]
11854    pub this: Option<Box<Expression>>,
11855    #[serde(default)]
11856    pub is_table: Option<Box<Expression>>,
11857    #[serde(default)]
11858    pub table: Option<Box<Expression>>,
11859    #[serde(default)]
11860    pub null: Option<Box<Expression>>,
11861}
11862
11863/// RowFormatProperty
11864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11865#[cfg_attr(feature = "bindings", derive(TS))]
11866pub struct RowFormatProperty {
11867    pub this: Box<Expression>,
11868}
11869
11870/// RowFormatDelimitedProperty
11871#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11872#[cfg_attr(feature = "bindings", derive(TS))]
11873pub struct RowFormatDelimitedProperty {
11874    #[serde(default)]
11875    pub fields: Option<Box<Expression>>,
11876    #[serde(default)]
11877    pub escaped: Option<Box<Expression>>,
11878    #[serde(default)]
11879    pub collection_items: Option<Box<Expression>>,
11880    #[serde(default)]
11881    pub map_keys: Option<Box<Expression>>,
11882    #[serde(default)]
11883    pub lines: Option<Box<Expression>>,
11884    #[serde(default)]
11885    pub null: Option<Box<Expression>>,
11886    #[serde(default)]
11887    pub serde: Option<Box<Expression>>,
11888}
11889
11890/// RowFormatSerdeProperty
11891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11892#[cfg_attr(feature = "bindings", derive(TS))]
11893pub struct RowFormatSerdeProperty {
11894    pub this: Box<Expression>,
11895    #[serde(default)]
11896    pub serde_properties: Option<Box<Expression>>,
11897}
11898
11899/// QueryTransform
11900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11901#[cfg_attr(feature = "bindings", derive(TS))]
11902pub struct QueryTransform {
11903    #[serde(default)]
11904    pub expressions: Vec<Expression>,
11905    #[serde(default)]
11906    pub command_script: Option<Box<Expression>>,
11907    #[serde(default)]
11908    pub schema: Option<Box<Expression>>,
11909    #[serde(default)]
11910    pub row_format_before: Option<Box<Expression>>,
11911    #[serde(default)]
11912    pub record_writer: Option<Box<Expression>>,
11913    #[serde(default)]
11914    pub row_format_after: Option<Box<Expression>>,
11915    #[serde(default)]
11916    pub record_reader: Option<Box<Expression>>,
11917}
11918
11919/// SampleProperty
11920#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11921#[cfg_attr(feature = "bindings", derive(TS))]
11922pub struct SampleProperty {
11923    pub this: Box<Expression>,
11924}
11925
11926/// SecurityProperty
11927#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11928#[cfg_attr(feature = "bindings", derive(TS))]
11929pub struct SecurityProperty {
11930    pub this: Box<Expression>,
11931}
11932
11933/// SchemaCommentProperty
11934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11935#[cfg_attr(feature = "bindings", derive(TS))]
11936pub struct SchemaCommentProperty {
11937    pub this: Box<Expression>,
11938}
11939
11940/// SemanticView
11941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11942#[cfg_attr(feature = "bindings", derive(TS))]
11943pub struct SemanticView {
11944    pub this: Box<Expression>,
11945    #[serde(default)]
11946    pub metrics: Option<Box<Expression>>,
11947    #[serde(default)]
11948    pub dimensions: Option<Box<Expression>>,
11949    #[serde(default)]
11950    pub facts: Option<Box<Expression>>,
11951    #[serde(default)]
11952    pub where_: Option<Box<Expression>>,
11953}
11954
11955/// SerdeProperties
11956#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11957#[cfg_attr(feature = "bindings", derive(TS))]
11958pub struct SerdeProperties {
11959    #[serde(default)]
11960    pub expressions: Vec<Expression>,
11961    #[serde(default)]
11962    pub with_: Option<Box<Expression>>,
11963}
11964
11965/// SetProperty
11966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11967#[cfg_attr(feature = "bindings", derive(TS))]
11968pub struct SetProperty {
11969    #[serde(default)]
11970    pub multi: Option<Box<Expression>>,
11971}
11972
11973/// SharingProperty
11974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11975#[cfg_attr(feature = "bindings", derive(TS))]
11976pub struct SharingProperty {
11977    #[serde(default)]
11978    pub this: Option<Box<Expression>>,
11979}
11980
11981/// SetConfigProperty
11982#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11983#[cfg_attr(feature = "bindings", derive(TS))]
11984pub struct SetConfigProperty {
11985    pub this: Box<Expression>,
11986}
11987
11988/// SettingsProperty
11989#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11990#[cfg_attr(feature = "bindings", derive(TS))]
11991pub struct SettingsProperty {
11992    #[serde(default)]
11993    pub expressions: Vec<Expression>,
11994}
11995
11996/// SortKeyProperty
11997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11998#[cfg_attr(feature = "bindings", derive(TS))]
11999pub struct SortKeyProperty {
12000    pub this: Box<Expression>,
12001    #[serde(default)]
12002    pub compound: Option<Box<Expression>>,
12003}
12004
12005/// SqlReadWriteProperty
12006#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12007#[cfg_attr(feature = "bindings", derive(TS))]
12008pub struct SqlReadWriteProperty {
12009    pub this: Box<Expression>,
12010}
12011
12012/// SqlSecurityProperty
12013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12014#[cfg_attr(feature = "bindings", derive(TS))]
12015pub struct SqlSecurityProperty {
12016    pub this: Box<Expression>,
12017}
12018
12019/// StabilityProperty
12020#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12021#[cfg_attr(feature = "bindings", derive(TS))]
12022pub struct StabilityProperty {
12023    pub this: Box<Expression>,
12024}
12025
12026/// StorageHandlerProperty
12027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12028#[cfg_attr(feature = "bindings", derive(TS))]
12029pub struct StorageHandlerProperty {
12030    pub this: Box<Expression>,
12031}
12032
12033/// TemporaryProperty
12034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12035#[cfg_attr(feature = "bindings", derive(TS))]
12036pub struct TemporaryProperty {
12037    #[serde(default)]
12038    pub this: Option<Box<Expression>>,
12039}
12040
12041/// Tags
12042#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12043#[cfg_attr(feature = "bindings", derive(TS))]
12044pub struct Tags {
12045    #[serde(default)]
12046    pub expressions: Vec<Expression>,
12047}
12048
12049/// TransformModelProperty
12050#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12051#[cfg_attr(feature = "bindings", derive(TS))]
12052pub struct TransformModelProperty {
12053    #[serde(default)]
12054    pub expressions: Vec<Expression>,
12055}
12056
12057/// TransientProperty
12058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12059#[cfg_attr(feature = "bindings", derive(TS))]
12060pub struct TransientProperty {
12061    #[serde(default)]
12062    pub this: Option<Box<Expression>>,
12063}
12064
12065/// UsingTemplateProperty
12066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12067#[cfg_attr(feature = "bindings", derive(TS))]
12068pub struct UsingTemplateProperty {
12069    pub this: Box<Expression>,
12070}
12071
12072/// ViewAttributeProperty
12073#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12074#[cfg_attr(feature = "bindings", derive(TS))]
12075pub struct ViewAttributeProperty {
12076    pub this: Box<Expression>,
12077}
12078
12079/// VolatileProperty
12080#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12081#[cfg_attr(feature = "bindings", derive(TS))]
12082pub struct VolatileProperty {
12083    #[serde(default)]
12084    pub this: Option<Box<Expression>>,
12085}
12086
12087/// WithDataProperty
12088#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12089#[cfg_attr(feature = "bindings", derive(TS))]
12090pub struct WithDataProperty {
12091    #[serde(default)]
12092    pub no: Option<Box<Expression>>,
12093    #[serde(default)]
12094    pub statistics: Option<Box<Expression>>,
12095}
12096
12097/// WithJournalTableProperty
12098#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12099#[cfg_attr(feature = "bindings", derive(TS))]
12100pub struct WithJournalTableProperty {
12101    pub this: Box<Expression>,
12102}
12103
12104/// WithSchemaBindingProperty
12105#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12106#[cfg_attr(feature = "bindings", derive(TS))]
12107pub struct WithSchemaBindingProperty {
12108    pub this: Box<Expression>,
12109}
12110
12111/// WithSystemVersioningProperty
12112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12113#[cfg_attr(feature = "bindings", derive(TS))]
12114pub struct WithSystemVersioningProperty {
12115    #[serde(default)]
12116    pub on: Option<Box<Expression>>,
12117    #[serde(default)]
12118    pub this: Option<Box<Expression>>,
12119    #[serde(default)]
12120    pub data_consistency: Option<Box<Expression>>,
12121    #[serde(default)]
12122    pub retention_period: Option<Box<Expression>>,
12123    #[serde(default)]
12124    pub with_: Option<Box<Expression>>,
12125}
12126
12127/// WithProcedureOptions
12128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12129#[cfg_attr(feature = "bindings", derive(TS))]
12130pub struct WithProcedureOptions {
12131    #[serde(default)]
12132    pub expressions: Vec<Expression>,
12133}
12134
12135/// EncodeProperty
12136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12137#[cfg_attr(feature = "bindings", derive(TS))]
12138pub struct EncodeProperty {
12139    pub this: Box<Expression>,
12140    #[serde(default)]
12141    pub properties: Vec<Expression>,
12142    #[serde(default)]
12143    pub key: Option<Box<Expression>>,
12144}
12145
12146/// IncludeProperty
12147#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12148#[cfg_attr(feature = "bindings", derive(TS))]
12149pub struct IncludeProperty {
12150    pub this: Box<Expression>,
12151    #[serde(default)]
12152    pub alias: Option<String>,
12153    #[serde(default)]
12154    pub column_def: Option<Box<Expression>>,
12155}
12156
12157/// Properties
12158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12159#[cfg_attr(feature = "bindings", derive(TS))]
12160pub struct Properties {
12161    #[serde(default)]
12162    pub expressions: Vec<Expression>,
12163}
12164
12165/// Key/value pair in a BigQuery OPTIONS (...) clause.
12166#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12167#[cfg_attr(feature = "bindings", derive(TS))]
12168pub struct OptionEntry {
12169    pub key: Identifier,
12170    pub value: Expression,
12171}
12172
12173/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12174#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12175#[cfg_attr(feature = "bindings", derive(TS))]
12176pub struct OptionsProperty {
12177    #[serde(default)]
12178    pub entries: Vec<OptionEntry>,
12179}
12180
12181/// InputOutputFormat
12182#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12183#[cfg_attr(feature = "bindings", derive(TS))]
12184pub struct InputOutputFormat {
12185    #[serde(default)]
12186    pub input_format: Option<Box<Expression>>,
12187    #[serde(default)]
12188    pub output_format: Option<Box<Expression>>,
12189}
12190
12191/// Reference
12192#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12193#[cfg_attr(feature = "bindings", derive(TS))]
12194pub struct Reference {
12195    pub this: Box<Expression>,
12196    #[serde(default)]
12197    pub expressions: Vec<Expression>,
12198    #[serde(default)]
12199    pub options: Vec<Expression>,
12200}
12201
12202/// QueryOption
12203#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12204#[cfg_attr(feature = "bindings", derive(TS))]
12205pub struct QueryOption {
12206    pub this: Box<Expression>,
12207    #[serde(default)]
12208    pub expression: Option<Box<Expression>>,
12209}
12210
12211/// WithTableHint
12212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12213#[cfg_attr(feature = "bindings", derive(TS))]
12214pub struct WithTableHint {
12215    #[serde(default)]
12216    pub expressions: Vec<Expression>,
12217}
12218
12219/// IndexTableHint
12220#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12221#[cfg_attr(feature = "bindings", derive(TS))]
12222pub struct IndexTableHint {
12223    pub this: Box<Expression>,
12224    #[serde(default)]
12225    pub expressions: Vec<Expression>,
12226    #[serde(default)]
12227    pub target: Option<Box<Expression>>,
12228}
12229
12230/// Get
12231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12232#[cfg_attr(feature = "bindings", derive(TS))]
12233pub struct Get {
12234    pub this: Box<Expression>,
12235    #[serde(default)]
12236    pub target: Option<Box<Expression>>,
12237    #[serde(default)]
12238    pub properties: Vec<Expression>,
12239}
12240
12241/// SetOperation
12242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12243#[cfg_attr(feature = "bindings", derive(TS))]
12244pub struct SetOperation {
12245    #[serde(default)]
12246    pub with_: Option<Box<Expression>>,
12247    pub this: Box<Expression>,
12248    pub expression: Box<Expression>,
12249    #[serde(default)]
12250    pub distinct: bool,
12251    #[serde(default)]
12252    pub by_name: Option<Box<Expression>>,
12253    #[serde(default)]
12254    pub side: Option<Box<Expression>>,
12255    #[serde(default)]
12256    pub kind: Option<String>,
12257    #[serde(default)]
12258    pub on: Option<Box<Expression>>,
12259}
12260
12261/// Var - Simple variable reference (for SQL variables, keywords as values)
12262#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12263#[cfg_attr(feature = "bindings", derive(TS))]
12264pub struct Var {
12265    pub this: String,
12266}
12267
12268/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12269#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12270#[cfg_attr(feature = "bindings", derive(TS))]
12271pub struct Variadic {
12272    pub this: Box<Expression>,
12273}
12274
12275/// Version
12276#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12277#[cfg_attr(feature = "bindings", derive(TS))]
12278pub struct Version {
12279    pub this: Box<Expression>,
12280    pub kind: String,
12281    #[serde(default)]
12282    pub expression: Option<Box<Expression>>,
12283}
12284
12285/// Schema
12286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12287#[cfg_attr(feature = "bindings", derive(TS))]
12288pub struct Schema {
12289    #[serde(default)]
12290    pub this: Option<Box<Expression>>,
12291    #[serde(default)]
12292    pub expressions: Vec<Expression>,
12293}
12294
12295/// Lock
12296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12297#[cfg_attr(feature = "bindings", derive(TS))]
12298pub struct Lock {
12299    #[serde(default)]
12300    pub update: Option<Box<Expression>>,
12301    #[serde(default)]
12302    pub expressions: Vec<Expression>,
12303    #[serde(default)]
12304    pub wait: Option<Box<Expression>>,
12305    #[serde(default)]
12306    pub key: Option<Box<Expression>>,
12307}
12308
12309/// TableSample - wraps an expression with a TABLESAMPLE clause
12310/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12312#[cfg_attr(feature = "bindings", derive(TS))]
12313pub struct TableSample {
12314    /// The expression being sampled (subquery, function, etc.)
12315    #[serde(default, skip_serializing_if = "Option::is_none")]
12316    pub this: Option<Box<Expression>>,
12317    /// The sample specification
12318    #[serde(default, skip_serializing_if = "Option::is_none")]
12319    pub sample: Option<Box<Sample>>,
12320    #[serde(default)]
12321    pub expressions: Vec<Expression>,
12322    #[serde(default)]
12323    pub method: Option<String>,
12324    #[serde(default)]
12325    pub bucket_numerator: Option<Box<Expression>>,
12326    #[serde(default)]
12327    pub bucket_denominator: Option<Box<Expression>>,
12328    #[serde(default)]
12329    pub bucket_field: Option<Box<Expression>>,
12330    #[serde(default)]
12331    pub percent: Option<Box<Expression>>,
12332    #[serde(default)]
12333    pub rows: Option<Box<Expression>>,
12334    #[serde(default)]
12335    pub size: Option<i64>,
12336    #[serde(default)]
12337    pub seed: Option<Box<Expression>>,
12338}
12339
12340/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12341#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12342#[cfg_attr(feature = "bindings", derive(TS))]
12343pub struct Tag {
12344    #[serde(default)]
12345    pub this: Option<Box<Expression>>,
12346    #[serde(default)]
12347    pub prefix: Option<Box<Expression>>,
12348    #[serde(default)]
12349    pub postfix: Option<Box<Expression>>,
12350}
12351
12352/// UnpivotColumns
12353#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12354#[cfg_attr(feature = "bindings", derive(TS))]
12355pub struct UnpivotColumns {
12356    pub this: Box<Expression>,
12357    #[serde(default)]
12358    pub expressions: Vec<Expression>,
12359}
12360
12361/// SessionParameter
12362#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12363#[cfg_attr(feature = "bindings", derive(TS))]
12364pub struct SessionParameter {
12365    pub this: Box<Expression>,
12366    #[serde(default)]
12367    pub kind: Option<String>,
12368}
12369
12370/// PseudoType
12371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12372#[cfg_attr(feature = "bindings", derive(TS))]
12373pub struct PseudoType {
12374    pub this: Box<Expression>,
12375}
12376
12377/// ObjectIdentifier
12378#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12379#[cfg_attr(feature = "bindings", derive(TS))]
12380pub struct ObjectIdentifier {
12381    pub this: Box<Expression>,
12382}
12383
12384/// Transaction
12385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12386#[cfg_attr(feature = "bindings", derive(TS))]
12387pub struct Transaction {
12388    #[serde(default)]
12389    pub this: Option<Box<Expression>>,
12390    #[serde(default)]
12391    pub modes: Option<Box<Expression>>,
12392    #[serde(default)]
12393    pub mark: Option<Box<Expression>>,
12394}
12395
12396/// Commit
12397#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12398#[cfg_attr(feature = "bindings", derive(TS))]
12399pub struct Commit {
12400    #[serde(default)]
12401    pub chain: Option<Box<Expression>>,
12402    #[serde(default)]
12403    pub this: Option<Box<Expression>>,
12404    #[serde(default)]
12405    pub durability: Option<Box<Expression>>,
12406}
12407
12408/// Rollback
12409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12410#[cfg_attr(feature = "bindings", derive(TS))]
12411pub struct Rollback {
12412    #[serde(default)]
12413    pub savepoint: Option<Box<Expression>>,
12414    #[serde(default)]
12415    pub this: Option<Box<Expression>>,
12416}
12417
12418/// AlterSession
12419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12420#[cfg_attr(feature = "bindings", derive(TS))]
12421pub struct AlterSession {
12422    #[serde(default)]
12423    pub expressions: Vec<Expression>,
12424    #[serde(default)]
12425    pub unset: Option<Box<Expression>>,
12426}
12427
12428/// Analyze
12429#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12430#[cfg_attr(feature = "bindings", derive(TS))]
12431pub struct Analyze {
12432    #[serde(default)]
12433    pub kind: Option<String>,
12434    #[serde(default)]
12435    pub this: Option<Box<Expression>>,
12436    #[serde(default)]
12437    pub options: Vec<Expression>,
12438    #[serde(default)]
12439    pub mode: Option<Box<Expression>>,
12440    #[serde(default)]
12441    pub partition: Option<Box<Expression>>,
12442    #[serde(default)]
12443    pub expression: Option<Box<Expression>>,
12444    #[serde(default)]
12445    pub properties: Vec<Expression>,
12446    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12447    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12448    pub columns: Vec<String>,
12449}
12450
12451/// AnalyzeStatistics
12452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12453#[cfg_attr(feature = "bindings", derive(TS))]
12454pub struct AnalyzeStatistics {
12455    pub kind: String,
12456    #[serde(default)]
12457    pub option: Option<Box<Expression>>,
12458    #[serde(default)]
12459    pub this: Option<Box<Expression>>,
12460    #[serde(default)]
12461    pub expressions: Vec<Expression>,
12462}
12463
12464/// AnalyzeHistogram
12465#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12466#[cfg_attr(feature = "bindings", derive(TS))]
12467pub struct AnalyzeHistogram {
12468    pub this: Box<Expression>,
12469    #[serde(default)]
12470    pub expressions: Vec<Expression>,
12471    #[serde(default)]
12472    pub expression: Option<Box<Expression>>,
12473    #[serde(default)]
12474    pub update_options: Option<Box<Expression>>,
12475}
12476
12477/// AnalyzeSample
12478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12479#[cfg_attr(feature = "bindings", derive(TS))]
12480pub struct AnalyzeSample {
12481    pub kind: String,
12482    #[serde(default)]
12483    pub sample: Option<Box<Expression>>,
12484}
12485
12486/// AnalyzeListChainedRows
12487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12488#[cfg_attr(feature = "bindings", derive(TS))]
12489pub struct AnalyzeListChainedRows {
12490    #[serde(default)]
12491    pub expression: Option<Box<Expression>>,
12492}
12493
12494/// AnalyzeDelete
12495#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12496#[cfg_attr(feature = "bindings", derive(TS))]
12497pub struct AnalyzeDelete {
12498    #[serde(default)]
12499    pub kind: Option<String>,
12500}
12501
12502/// AnalyzeWith
12503#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12504#[cfg_attr(feature = "bindings", derive(TS))]
12505pub struct AnalyzeWith {
12506    #[serde(default)]
12507    pub expressions: Vec<Expression>,
12508}
12509
12510/// AnalyzeValidate
12511#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12512#[cfg_attr(feature = "bindings", derive(TS))]
12513pub struct AnalyzeValidate {
12514    pub kind: String,
12515    #[serde(default)]
12516    pub this: Option<Box<Expression>>,
12517    #[serde(default)]
12518    pub expression: Option<Box<Expression>>,
12519}
12520
12521/// AddPartition
12522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12523#[cfg_attr(feature = "bindings", derive(TS))]
12524pub struct AddPartition {
12525    pub this: Box<Expression>,
12526    #[serde(default)]
12527    pub exists: bool,
12528    #[serde(default)]
12529    pub location: Option<Box<Expression>>,
12530}
12531
12532/// AttachOption
12533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12534#[cfg_attr(feature = "bindings", derive(TS))]
12535pub struct AttachOption {
12536    pub this: Box<Expression>,
12537    #[serde(default)]
12538    pub expression: Option<Box<Expression>>,
12539}
12540
12541/// DropPartition
12542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12543#[cfg_attr(feature = "bindings", derive(TS))]
12544pub struct DropPartition {
12545    #[serde(default)]
12546    pub expressions: Vec<Expression>,
12547    #[serde(default)]
12548    pub exists: bool,
12549}
12550
12551/// ReplacePartition
12552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12553#[cfg_attr(feature = "bindings", derive(TS))]
12554pub struct ReplacePartition {
12555    pub expression: Box<Expression>,
12556    #[serde(default)]
12557    pub source: Option<Box<Expression>>,
12558}
12559
12560/// DPipe
12561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12562#[cfg_attr(feature = "bindings", derive(TS))]
12563pub struct DPipe {
12564    pub this: Box<Expression>,
12565    pub expression: Box<Expression>,
12566    #[serde(default)]
12567    pub safe: Option<Box<Expression>>,
12568}
12569
12570/// Operator
12571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12572#[cfg_attr(feature = "bindings", derive(TS))]
12573pub struct Operator {
12574    pub this: Box<Expression>,
12575    #[serde(default)]
12576    pub operator: Option<Box<Expression>>,
12577    pub expression: Box<Expression>,
12578    /// Comments between OPERATOR() and the RHS expression
12579    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12580    pub comments: Vec<String>,
12581}
12582
12583/// PivotAny
12584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12585#[cfg_attr(feature = "bindings", derive(TS))]
12586pub struct PivotAny {
12587    #[serde(default)]
12588    pub this: Option<Box<Expression>>,
12589}
12590
12591/// Aliases
12592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12593#[cfg_attr(feature = "bindings", derive(TS))]
12594pub struct Aliases {
12595    pub this: Box<Expression>,
12596    #[serde(default)]
12597    pub expressions: Vec<Expression>,
12598}
12599
12600/// AtIndex
12601#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12602#[cfg_attr(feature = "bindings", derive(TS))]
12603pub struct AtIndex {
12604    pub this: Box<Expression>,
12605    pub expression: Box<Expression>,
12606}
12607
12608/// FromTimeZone
12609#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12610#[cfg_attr(feature = "bindings", derive(TS))]
12611pub struct FromTimeZone {
12612    pub this: Box<Expression>,
12613    #[serde(default)]
12614    pub zone: Option<Box<Expression>>,
12615}
12616
12617/// Format override for a column in Teradata
12618#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12619#[cfg_attr(feature = "bindings", derive(TS))]
12620pub struct FormatPhrase {
12621    pub this: Box<Expression>,
12622    pub format: String,
12623}
12624
12625/// ForIn
12626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12627#[cfg_attr(feature = "bindings", derive(TS))]
12628pub struct ForIn {
12629    pub this: Box<Expression>,
12630    pub expression: Box<Expression>,
12631}
12632
12633/// Automatically converts unit arg into a var.
12634#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12635#[cfg_attr(feature = "bindings", derive(TS))]
12636pub struct TimeUnit {
12637    #[serde(default)]
12638    pub unit: Option<String>,
12639}
12640
12641/// IntervalOp
12642#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12643#[cfg_attr(feature = "bindings", derive(TS))]
12644pub struct IntervalOp {
12645    #[serde(default)]
12646    pub unit: Option<String>,
12647    pub expression: Box<Expression>,
12648}
12649
12650/// HavingMax
12651#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12652#[cfg_attr(feature = "bindings", derive(TS))]
12653pub struct HavingMax {
12654    pub this: Box<Expression>,
12655    pub expression: Box<Expression>,
12656    #[serde(default)]
12657    pub max: Option<Box<Expression>>,
12658}
12659
12660/// CosineDistance
12661#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12662#[cfg_attr(feature = "bindings", derive(TS))]
12663pub struct CosineDistance {
12664    pub this: Box<Expression>,
12665    pub expression: Box<Expression>,
12666}
12667
12668/// DotProduct
12669#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12670#[cfg_attr(feature = "bindings", derive(TS))]
12671pub struct DotProduct {
12672    pub this: Box<Expression>,
12673    pub expression: Box<Expression>,
12674}
12675
12676/// EuclideanDistance
12677#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12678#[cfg_attr(feature = "bindings", derive(TS))]
12679pub struct EuclideanDistance {
12680    pub this: Box<Expression>,
12681    pub expression: Box<Expression>,
12682}
12683
12684/// ManhattanDistance
12685#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12686#[cfg_attr(feature = "bindings", derive(TS))]
12687pub struct ManhattanDistance {
12688    pub this: Box<Expression>,
12689    pub expression: Box<Expression>,
12690}
12691
12692/// JarowinklerSimilarity
12693#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12694#[cfg_attr(feature = "bindings", derive(TS))]
12695pub struct JarowinklerSimilarity {
12696    pub this: Box<Expression>,
12697    pub expression: Box<Expression>,
12698}
12699
12700/// Booland
12701#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12702#[cfg_attr(feature = "bindings", derive(TS))]
12703pub struct Booland {
12704    pub this: Box<Expression>,
12705    pub expression: Box<Expression>,
12706}
12707
12708/// Boolor
12709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12710#[cfg_attr(feature = "bindings", derive(TS))]
12711pub struct Boolor {
12712    pub this: Box<Expression>,
12713    pub expression: Box<Expression>,
12714}
12715
12716/// ParameterizedAgg
12717#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12718#[cfg_attr(feature = "bindings", derive(TS))]
12719pub struct ParameterizedAgg {
12720    pub this: Box<Expression>,
12721    #[serde(default)]
12722    pub expressions: Vec<Expression>,
12723    #[serde(default)]
12724    pub params: Vec<Expression>,
12725}
12726
12727/// ArgMax
12728#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12729#[cfg_attr(feature = "bindings", derive(TS))]
12730pub struct ArgMax {
12731    pub this: Box<Expression>,
12732    pub expression: Box<Expression>,
12733    #[serde(default)]
12734    pub count: Option<Box<Expression>>,
12735}
12736
12737/// ArgMin
12738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12739#[cfg_attr(feature = "bindings", derive(TS))]
12740pub struct ArgMin {
12741    pub this: Box<Expression>,
12742    pub expression: Box<Expression>,
12743    #[serde(default)]
12744    pub count: Option<Box<Expression>>,
12745}
12746
12747/// ApproxTopK
12748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12749#[cfg_attr(feature = "bindings", derive(TS))]
12750pub struct ApproxTopK {
12751    pub this: Box<Expression>,
12752    #[serde(default)]
12753    pub expression: Option<Box<Expression>>,
12754    #[serde(default)]
12755    pub counters: Option<Box<Expression>>,
12756}
12757
12758/// ApproxTopKAccumulate
12759#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12760#[cfg_attr(feature = "bindings", derive(TS))]
12761pub struct ApproxTopKAccumulate {
12762    pub this: Box<Expression>,
12763    #[serde(default)]
12764    pub expression: Option<Box<Expression>>,
12765}
12766
12767/// ApproxTopKCombine
12768#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12769#[cfg_attr(feature = "bindings", derive(TS))]
12770pub struct ApproxTopKCombine {
12771    pub this: Box<Expression>,
12772    #[serde(default)]
12773    pub expression: Option<Box<Expression>>,
12774}
12775
12776/// ApproxTopKEstimate
12777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12778#[cfg_attr(feature = "bindings", derive(TS))]
12779pub struct ApproxTopKEstimate {
12780    pub this: Box<Expression>,
12781    #[serde(default)]
12782    pub expression: Option<Box<Expression>>,
12783}
12784
12785/// ApproxTopSum
12786#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12787#[cfg_attr(feature = "bindings", derive(TS))]
12788pub struct ApproxTopSum {
12789    pub this: Box<Expression>,
12790    pub expression: Box<Expression>,
12791    #[serde(default)]
12792    pub count: Option<Box<Expression>>,
12793}
12794
12795/// ApproxQuantiles
12796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12797#[cfg_attr(feature = "bindings", derive(TS))]
12798pub struct ApproxQuantiles {
12799    pub this: Box<Expression>,
12800    #[serde(default)]
12801    pub expression: Option<Box<Expression>>,
12802}
12803
12804/// Minhash
12805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12806#[cfg_attr(feature = "bindings", derive(TS))]
12807pub struct Minhash {
12808    pub this: Box<Expression>,
12809    #[serde(default)]
12810    pub expressions: Vec<Expression>,
12811}
12812
12813/// FarmFingerprint
12814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12815#[cfg_attr(feature = "bindings", derive(TS))]
12816pub struct FarmFingerprint {
12817    #[serde(default)]
12818    pub expressions: Vec<Expression>,
12819}
12820
12821/// Float64
12822#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12823#[cfg_attr(feature = "bindings", derive(TS))]
12824pub struct Float64 {
12825    pub this: Box<Expression>,
12826    #[serde(default)]
12827    pub expression: Option<Box<Expression>>,
12828}
12829
12830/// Transform
12831#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12832#[cfg_attr(feature = "bindings", derive(TS))]
12833pub struct Transform {
12834    pub this: Box<Expression>,
12835    pub expression: Box<Expression>,
12836}
12837
12838/// Translate
12839#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12840#[cfg_attr(feature = "bindings", derive(TS))]
12841pub struct Translate {
12842    pub this: Box<Expression>,
12843    #[serde(default)]
12844    pub from_: Option<Box<Expression>>,
12845    #[serde(default)]
12846    pub to: Option<Box<Expression>>,
12847}
12848
12849/// Grouping
12850#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12851#[cfg_attr(feature = "bindings", derive(TS))]
12852pub struct Grouping {
12853    #[serde(default)]
12854    pub expressions: Vec<Expression>,
12855}
12856
12857/// GroupingId
12858#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12859#[cfg_attr(feature = "bindings", derive(TS))]
12860pub struct GroupingId {
12861    #[serde(default)]
12862    pub expressions: Vec<Expression>,
12863}
12864
12865/// Anonymous
12866#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12867#[cfg_attr(feature = "bindings", derive(TS))]
12868pub struct Anonymous {
12869    pub this: Box<Expression>,
12870    #[serde(default)]
12871    pub expressions: Vec<Expression>,
12872}
12873
12874/// AnonymousAggFunc
12875#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12876#[cfg_attr(feature = "bindings", derive(TS))]
12877pub struct AnonymousAggFunc {
12878    pub this: Box<Expression>,
12879    #[serde(default)]
12880    pub expressions: Vec<Expression>,
12881}
12882
12883/// CombinedAggFunc
12884#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12885#[cfg_attr(feature = "bindings", derive(TS))]
12886pub struct CombinedAggFunc {
12887    pub this: Box<Expression>,
12888    #[serde(default)]
12889    pub expressions: Vec<Expression>,
12890}
12891
12892/// CombinedParameterizedAgg
12893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12894#[cfg_attr(feature = "bindings", derive(TS))]
12895pub struct CombinedParameterizedAgg {
12896    pub this: Box<Expression>,
12897    #[serde(default)]
12898    pub expressions: Vec<Expression>,
12899    #[serde(default)]
12900    pub params: Vec<Expression>,
12901}
12902
12903/// HashAgg
12904#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12905#[cfg_attr(feature = "bindings", derive(TS))]
12906pub struct HashAgg {
12907    pub this: Box<Expression>,
12908    #[serde(default)]
12909    pub expressions: Vec<Expression>,
12910}
12911
12912/// Hll
12913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12914#[cfg_attr(feature = "bindings", derive(TS))]
12915pub struct Hll {
12916    pub this: Box<Expression>,
12917    #[serde(default)]
12918    pub expressions: Vec<Expression>,
12919}
12920
12921/// Apply
12922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12923#[cfg_attr(feature = "bindings", derive(TS))]
12924pub struct Apply {
12925    pub this: Box<Expression>,
12926    pub expression: Box<Expression>,
12927}
12928
12929/// ToBoolean
12930#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12931#[cfg_attr(feature = "bindings", derive(TS))]
12932pub struct ToBoolean {
12933    pub this: Box<Expression>,
12934    #[serde(default)]
12935    pub safe: Option<Box<Expression>>,
12936}
12937
12938/// List
12939#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12940#[cfg_attr(feature = "bindings", derive(TS))]
12941pub struct List {
12942    #[serde(default)]
12943    pub expressions: Vec<Expression>,
12944}
12945
12946/// ToMap - Materialize-style map constructor
12947/// Can hold either:
12948/// - A SELECT subquery (MAP(SELECT 'a', 1))
12949/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
12950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12951#[cfg_attr(feature = "bindings", derive(TS))]
12952pub struct ToMap {
12953    /// Either a Select subquery or a Struct containing PropertyEQ entries
12954    pub this: Box<Expression>,
12955}
12956
12957/// Pad
12958#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12959#[cfg_attr(feature = "bindings", derive(TS))]
12960pub struct Pad {
12961    pub this: Box<Expression>,
12962    pub expression: Box<Expression>,
12963    #[serde(default)]
12964    pub fill_pattern: Option<Box<Expression>>,
12965    #[serde(default)]
12966    pub is_left: Option<Box<Expression>>,
12967}
12968
12969/// ToChar
12970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12971#[cfg_attr(feature = "bindings", derive(TS))]
12972pub struct ToChar {
12973    pub this: Box<Expression>,
12974    #[serde(default)]
12975    pub format: Option<String>,
12976    #[serde(default)]
12977    pub nlsparam: Option<Box<Expression>>,
12978    #[serde(default)]
12979    pub is_numeric: Option<Box<Expression>>,
12980}
12981
12982/// StringFunc - String type conversion function (BigQuery STRING)
12983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12984#[cfg_attr(feature = "bindings", derive(TS))]
12985pub struct StringFunc {
12986    pub this: Box<Expression>,
12987    #[serde(default)]
12988    pub zone: Option<Box<Expression>>,
12989}
12990
12991/// ToNumber
12992#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12993#[cfg_attr(feature = "bindings", derive(TS))]
12994pub struct ToNumber {
12995    pub this: Box<Expression>,
12996    #[serde(default)]
12997    pub format: Option<Box<Expression>>,
12998    #[serde(default)]
12999    pub nlsparam: Option<Box<Expression>>,
13000    #[serde(default)]
13001    pub precision: Option<Box<Expression>>,
13002    #[serde(default)]
13003    pub scale: Option<Box<Expression>>,
13004    #[serde(default)]
13005    pub safe: Option<Box<Expression>>,
13006    #[serde(default)]
13007    pub safe_name: Option<Box<Expression>>,
13008}
13009
13010/// ToDouble
13011#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13012#[cfg_attr(feature = "bindings", derive(TS))]
13013pub struct ToDouble {
13014    pub this: Box<Expression>,
13015    #[serde(default)]
13016    pub format: Option<String>,
13017    #[serde(default)]
13018    pub safe: Option<Box<Expression>>,
13019}
13020
13021/// ToDecfloat
13022#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13023#[cfg_attr(feature = "bindings", derive(TS))]
13024pub struct ToDecfloat {
13025    pub this: Box<Expression>,
13026    #[serde(default)]
13027    pub format: Option<String>,
13028}
13029
13030/// TryToDecfloat
13031#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13032#[cfg_attr(feature = "bindings", derive(TS))]
13033pub struct TryToDecfloat {
13034    pub this: Box<Expression>,
13035    #[serde(default)]
13036    pub format: Option<String>,
13037}
13038
13039/// ToFile
13040#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13041#[cfg_attr(feature = "bindings", derive(TS))]
13042pub struct ToFile {
13043    pub this: Box<Expression>,
13044    #[serde(default)]
13045    pub path: Option<Box<Expression>>,
13046    #[serde(default)]
13047    pub safe: Option<Box<Expression>>,
13048}
13049
13050/// Columns
13051#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13052#[cfg_attr(feature = "bindings", derive(TS))]
13053pub struct Columns {
13054    pub this: Box<Expression>,
13055    #[serde(default)]
13056    pub unpack: Option<Box<Expression>>,
13057}
13058
13059/// ConvertToCharset
13060#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13061#[cfg_attr(feature = "bindings", derive(TS))]
13062pub struct ConvertToCharset {
13063    pub this: Box<Expression>,
13064    #[serde(default)]
13065    pub dest: Option<Box<Expression>>,
13066    #[serde(default)]
13067    pub source: Option<Box<Expression>>,
13068}
13069
13070/// ConvertTimezone
13071#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13072#[cfg_attr(feature = "bindings", derive(TS))]
13073pub struct ConvertTimezone {
13074    #[serde(default)]
13075    pub source_tz: Option<Box<Expression>>,
13076    #[serde(default)]
13077    pub target_tz: Option<Box<Expression>>,
13078    #[serde(default)]
13079    pub timestamp: Option<Box<Expression>>,
13080    #[serde(default)]
13081    pub options: Vec<Expression>,
13082}
13083
13084/// GenerateSeries
13085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13086#[cfg_attr(feature = "bindings", derive(TS))]
13087pub struct GenerateSeries {
13088    #[serde(default)]
13089    pub start: Option<Box<Expression>>,
13090    #[serde(default)]
13091    pub end: Option<Box<Expression>>,
13092    #[serde(default)]
13093    pub step: Option<Box<Expression>>,
13094    #[serde(default)]
13095    pub is_end_exclusive: Option<Box<Expression>>,
13096}
13097
13098/// AIAgg
13099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13100#[cfg_attr(feature = "bindings", derive(TS))]
13101pub struct AIAgg {
13102    pub this: Box<Expression>,
13103    pub expression: Box<Expression>,
13104}
13105
13106/// AIClassify
13107#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13108#[cfg_attr(feature = "bindings", derive(TS))]
13109pub struct AIClassify {
13110    pub this: Box<Expression>,
13111    #[serde(default)]
13112    pub categories: Option<Box<Expression>>,
13113    #[serde(default)]
13114    pub config: Option<Box<Expression>>,
13115}
13116
13117/// ArrayAll
13118#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13119#[cfg_attr(feature = "bindings", derive(TS))]
13120pub struct ArrayAll {
13121    pub this: Box<Expression>,
13122    pub expression: Box<Expression>,
13123}
13124
13125/// ArrayAny
13126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13127#[cfg_attr(feature = "bindings", derive(TS))]
13128pub struct ArrayAny {
13129    pub this: Box<Expression>,
13130    pub expression: Box<Expression>,
13131}
13132
13133/// ArrayConstructCompact
13134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13135#[cfg_attr(feature = "bindings", derive(TS))]
13136pub struct ArrayConstructCompact {
13137    #[serde(default)]
13138    pub expressions: Vec<Expression>,
13139}
13140
13141/// StPoint
13142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13143#[cfg_attr(feature = "bindings", derive(TS))]
13144pub struct StPoint {
13145    pub this: Box<Expression>,
13146    pub expression: Box<Expression>,
13147    #[serde(default)]
13148    pub null: Option<Box<Expression>>,
13149}
13150
13151/// StDistance
13152#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13153#[cfg_attr(feature = "bindings", derive(TS))]
13154pub struct StDistance {
13155    pub this: Box<Expression>,
13156    pub expression: Box<Expression>,
13157    #[serde(default)]
13158    pub use_spheroid: Option<Box<Expression>>,
13159}
13160
13161/// StringToArray
13162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13163#[cfg_attr(feature = "bindings", derive(TS))]
13164pub struct StringToArray {
13165    pub this: Box<Expression>,
13166    #[serde(default)]
13167    pub expression: Option<Box<Expression>>,
13168    #[serde(default)]
13169    pub null: Option<Box<Expression>>,
13170}
13171
13172/// ArraySum
13173#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13174#[cfg_attr(feature = "bindings", derive(TS))]
13175pub struct ArraySum {
13176    pub this: Box<Expression>,
13177    #[serde(default)]
13178    pub expression: Option<Box<Expression>>,
13179}
13180
13181/// ObjectAgg
13182#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13183#[cfg_attr(feature = "bindings", derive(TS))]
13184pub struct ObjectAgg {
13185    pub this: Box<Expression>,
13186    pub expression: Box<Expression>,
13187}
13188
13189/// CastToStrType
13190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13191#[cfg_attr(feature = "bindings", derive(TS))]
13192pub struct CastToStrType {
13193    pub this: Box<Expression>,
13194    #[serde(default)]
13195    pub to: Option<Box<Expression>>,
13196}
13197
13198/// CheckJson
13199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13200#[cfg_attr(feature = "bindings", derive(TS))]
13201pub struct CheckJson {
13202    pub this: Box<Expression>,
13203}
13204
13205/// CheckXml
13206#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13207#[cfg_attr(feature = "bindings", derive(TS))]
13208pub struct CheckXml {
13209    pub this: Box<Expression>,
13210    #[serde(default)]
13211    pub disable_auto_convert: Option<Box<Expression>>,
13212}
13213
13214/// TranslateCharacters
13215#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13216#[cfg_attr(feature = "bindings", derive(TS))]
13217pub struct TranslateCharacters {
13218    pub this: Box<Expression>,
13219    pub expression: Box<Expression>,
13220    #[serde(default)]
13221    pub with_error: Option<Box<Expression>>,
13222}
13223
13224/// CurrentSchemas
13225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13226#[cfg_attr(feature = "bindings", derive(TS))]
13227pub struct CurrentSchemas {
13228    #[serde(default)]
13229    pub this: Option<Box<Expression>>,
13230}
13231
13232/// CurrentDatetime
13233#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13234#[cfg_attr(feature = "bindings", derive(TS))]
13235pub struct CurrentDatetime {
13236    #[serde(default)]
13237    pub this: Option<Box<Expression>>,
13238}
13239
13240/// Localtime
13241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13242#[cfg_attr(feature = "bindings", derive(TS))]
13243pub struct Localtime {
13244    #[serde(default)]
13245    pub this: Option<Box<Expression>>,
13246}
13247
13248/// Localtimestamp
13249#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13250#[cfg_attr(feature = "bindings", derive(TS))]
13251pub struct Localtimestamp {
13252    #[serde(default)]
13253    pub this: Option<Box<Expression>>,
13254}
13255
13256/// Systimestamp
13257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13258#[cfg_attr(feature = "bindings", derive(TS))]
13259pub struct Systimestamp {
13260    #[serde(default)]
13261    pub this: Option<Box<Expression>>,
13262}
13263
13264/// CurrentSchema
13265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13266#[cfg_attr(feature = "bindings", derive(TS))]
13267pub struct CurrentSchema {
13268    #[serde(default)]
13269    pub this: Option<Box<Expression>>,
13270}
13271
13272/// CurrentUser
13273#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13274#[cfg_attr(feature = "bindings", derive(TS))]
13275pub struct CurrentUser {
13276    #[serde(default)]
13277    pub this: Option<Box<Expression>>,
13278}
13279
13280/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13282#[cfg_attr(feature = "bindings", derive(TS))]
13283pub struct SessionUser;
13284
13285/// JSONPathRoot - Represents $ in JSON path expressions
13286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13287#[cfg_attr(feature = "bindings", derive(TS))]
13288pub struct JSONPathRoot;
13289
13290/// UtcTime
13291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13292#[cfg_attr(feature = "bindings", derive(TS))]
13293pub struct UtcTime {
13294    #[serde(default)]
13295    pub this: Option<Box<Expression>>,
13296}
13297
13298/// UtcTimestamp
13299#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13300#[cfg_attr(feature = "bindings", derive(TS))]
13301pub struct UtcTimestamp {
13302    #[serde(default)]
13303    pub this: Option<Box<Expression>>,
13304}
13305
13306/// TimestampFunc - TIMESTAMP constructor function
13307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13308#[cfg_attr(feature = "bindings", derive(TS))]
13309pub struct TimestampFunc {
13310    #[serde(default)]
13311    pub this: Option<Box<Expression>>,
13312    #[serde(default)]
13313    pub zone: Option<Box<Expression>>,
13314    #[serde(default)]
13315    pub with_tz: Option<bool>,
13316    #[serde(default)]
13317    pub safe: Option<bool>,
13318}
13319
13320/// DateBin
13321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13322#[cfg_attr(feature = "bindings", derive(TS))]
13323pub struct DateBin {
13324    pub this: Box<Expression>,
13325    pub expression: Box<Expression>,
13326    #[serde(default)]
13327    pub unit: Option<String>,
13328    #[serde(default)]
13329    pub zone: Option<Box<Expression>>,
13330    #[serde(default)]
13331    pub origin: Option<Box<Expression>>,
13332}
13333
13334/// Datetime
13335#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13336#[cfg_attr(feature = "bindings", derive(TS))]
13337pub struct Datetime {
13338    pub this: Box<Expression>,
13339    #[serde(default)]
13340    pub expression: Option<Box<Expression>>,
13341}
13342
13343/// DatetimeAdd
13344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13345#[cfg_attr(feature = "bindings", derive(TS))]
13346pub struct DatetimeAdd {
13347    pub this: Box<Expression>,
13348    pub expression: Box<Expression>,
13349    #[serde(default)]
13350    pub unit: Option<String>,
13351}
13352
13353/// DatetimeSub
13354#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13355#[cfg_attr(feature = "bindings", derive(TS))]
13356pub struct DatetimeSub {
13357    pub this: Box<Expression>,
13358    pub expression: Box<Expression>,
13359    #[serde(default)]
13360    pub unit: Option<String>,
13361}
13362
13363/// DatetimeDiff
13364#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13365#[cfg_attr(feature = "bindings", derive(TS))]
13366pub struct DatetimeDiff {
13367    pub this: Box<Expression>,
13368    pub expression: Box<Expression>,
13369    #[serde(default)]
13370    pub unit: Option<String>,
13371}
13372
13373/// DatetimeTrunc
13374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13375#[cfg_attr(feature = "bindings", derive(TS))]
13376pub struct DatetimeTrunc {
13377    pub this: Box<Expression>,
13378    pub unit: String,
13379    #[serde(default)]
13380    pub zone: Option<Box<Expression>>,
13381}
13382
13383/// Dayname
13384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13385#[cfg_attr(feature = "bindings", derive(TS))]
13386pub struct Dayname {
13387    pub this: Box<Expression>,
13388    #[serde(default)]
13389    pub abbreviated: Option<Box<Expression>>,
13390}
13391
13392/// MakeInterval
13393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13394#[cfg_attr(feature = "bindings", derive(TS))]
13395pub struct MakeInterval {
13396    #[serde(default)]
13397    pub year: Option<Box<Expression>>,
13398    #[serde(default)]
13399    pub month: Option<Box<Expression>>,
13400    #[serde(default)]
13401    pub week: Option<Box<Expression>>,
13402    #[serde(default)]
13403    pub day: Option<Box<Expression>>,
13404    #[serde(default)]
13405    pub hour: Option<Box<Expression>>,
13406    #[serde(default)]
13407    pub minute: Option<Box<Expression>>,
13408    #[serde(default)]
13409    pub second: Option<Box<Expression>>,
13410}
13411
13412/// PreviousDay
13413#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13414#[cfg_attr(feature = "bindings", derive(TS))]
13415pub struct PreviousDay {
13416    pub this: Box<Expression>,
13417    pub expression: Box<Expression>,
13418}
13419
13420/// Elt
13421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13422#[cfg_attr(feature = "bindings", derive(TS))]
13423pub struct Elt {
13424    pub this: Box<Expression>,
13425    #[serde(default)]
13426    pub expressions: Vec<Expression>,
13427}
13428
13429/// TimestampAdd
13430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13431#[cfg_attr(feature = "bindings", derive(TS))]
13432pub struct TimestampAdd {
13433    pub this: Box<Expression>,
13434    pub expression: Box<Expression>,
13435    #[serde(default)]
13436    pub unit: Option<String>,
13437}
13438
13439/// TimestampSub
13440#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13441#[cfg_attr(feature = "bindings", derive(TS))]
13442pub struct TimestampSub {
13443    pub this: Box<Expression>,
13444    pub expression: Box<Expression>,
13445    #[serde(default)]
13446    pub unit: Option<String>,
13447}
13448
13449/// TimestampDiff
13450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13451#[cfg_attr(feature = "bindings", derive(TS))]
13452pub struct TimestampDiff {
13453    pub this: Box<Expression>,
13454    pub expression: Box<Expression>,
13455    #[serde(default)]
13456    pub unit: Option<String>,
13457}
13458
13459/// TimeSlice
13460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13461#[cfg_attr(feature = "bindings", derive(TS))]
13462pub struct TimeSlice {
13463    pub this: Box<Expression>,
13464    pub expression: Box<Expression>,
13465    pub unit: String,
13466    #[serde(default)]
13467    pub kind: Option<String>,
13468}
13469
13470/// TimeAdd
13471#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13472#[cfg_attr(feature = "bindings", derive(TS))]
13473pub struct TimeAdd {
13474    pub this: Box<Expression>,
13475    pub expression: Box<Expression>,
13476    #[serde(default)]
13477    pub unit: Option<String>,
13478}
13479
13480/// TimeSub
13481#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13482#[cfg_attr(feature = "bindings", derive(TS))]
13483pub struct TimeSub {
13484    pub this: Box<Expression>,
13485    pub expression: Box<Expression>,
13486    #[serde(default)]
13487    pub unit: Option<String>,
13488}
13489
13490/// TimeDiff
13491#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13492#[cfg_attr(feature = "bindings", derive(TS))]
13493pub struct TimeDiff {
13494    pub this: Box<Expression>,
13495    pub expression: Box<Expression>,
13496    #[serde(default)]
13497    pub unit: Option<String>,
13498}
13499
13500/// TimeTrunc
13501#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13502#[cfg_attr(feature = "bindings", derive(TS))]
13503pub struct TimeTrunc {
13504    pub this: Box<Expression>,
13505    pub unit: String,
13506    #[serde(default)]
13507    pub zone: Option<Box<Expression>>,
13508}
13509
13510/// DateFromParts
13511#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13512#[cfg_attr(feature = "bindings", derive(TS))]
13513pub struct DateFromParts {
13514    #[serde(default)]
13515    pub year: Option<Box<Expression>>,
13516    #[serde(default)]
13517    pub month: Option<Box<Expression>>,
13518    #[serde(default)]
13519    pub day: Option<Box<Expression>>,
13520    #[serde(default)]
13521    pub allow_overflow: Option<Box<Expression>>,
13522}
13523
13524/// TimeFromParts
13525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13526#[cfg_attr(feature = "bindings", derive(TS))]
13527pub struct TimeFromParts {
13528    #[serde(default)]
13529    pub hour: Option<Box<Expression>>,
13530    #[serde(default)]
13531    pub min: Option<Box<Expression>>,
13532    #[serde(default)]
13533    pub sec: Option<Box<Expression>>,
13534    #[serde(default)]
13535    pub nano: Option<Box<Expression>>,
13536    #[serde(default)]
13537    pub fractions: Option<Box<Expression>>,
13538    #[serde(default)]
13539    pub precision: Option<i64>,
13540}
13541
13542/// DecodeCase
13543#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13544#[cfg_attr(feature = "bindings", derive(TS))]
13545pub struct DecodeCase {
13546    #[serde(default)]
13547    pub expressions: Vec<Expression>,
13548}
13549
13550/// Decrypt
13551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13552#[cfg_attr(feature = "bindings", derive(TS))]
13553pub struct Decrypt {
13554    pub this: Box<Expression>,
13555    #[serde(default)]
13556    pub passphrase: Option<Box<Expression>>,
13557    #[serde(default)]
13558    pub aad: Option<Box<Expression>>,
13559    #[serde(default)]
13560    pub encryption_method: Option<Box<Expression>>,
13561    #[serde(default)]
13562    pub safe: Option<Box<Expression>>,
13563}
13564
13565/// DecryptRaw
13566#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13567#[cfg_attr(feature = "bindings", derive(TS))]
13568pub struct DecryptRaw {
13569    pub this: Box<Expression>,
13570    #[serde(default)]
13571    pub key: Option<Box<Expression>>,
13572    #[serde(default)]
13573    pub iv: Option<Box<Expression>>,
13574    #[serde(default)]
13575    pub aad: Option<Box<Expression>>,
13576    #[serde(default)]
13577    pub encryption_method: Option<Box<Expression>>,
13578    #[serde(default)]
13579    pub aead: Option<Box<Expression>>,
13580    #[serde(default)]
13581    pub safe: Option<Box<Expression>>,
13582}
13583
13584/// Encode
13585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13586#[cfg_attr(feature = "bindings", derive(TS))]
13587pub struct Encode {
13588    pub this: Box<Expression>,
13589    #[serde(default)]
13590    pub charset: Option<Box<Expression>>,
13591}
13592
13593/// Encrypt
13594#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13595#[cfg_attr(feature = "bindings", derive(TS))]
13596pub struct Encrypt {
13597    pub this: Box<Expression>,
13598    #[serde(default)]
13599    pub passphrase: Option<Box<Expression>>,
13600    #[serde(default)]
13601    pub aad: Option<Box<Expression>>,
13602    #[serde(default)]
13603    pub encryption_method: Option<Box<Expression>>,
13604}
13605
13606/// EncryptRaw
13607#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13608#[cfg_attr(feature = "bindings", derive(TS))]
13609pub struct EncryptRaw {
13610    pub this: Box<Expression>,
13611    #[serde(default)]
13612    pub key: Option<Box<Expression>>,
13613    #[serde(default)]
13614    pub iv: Option<Box<Expression>>,
13615    #[serde(default)]
13616    pub aad: Option<Box<Expression>>,
13617    #[serde(default)]
13618    pub encryption_method: Option<Box<Expression>>,
13619}
13620
13621/// EqualNull
13622#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13623#[cfg_attr(feature = "bindings", derive(TS))]
13624pub struct EqualNull {
13625    pub this: Box<Expression>,
13626    pub expression: Box<Expression>,
13627}
13628
13629/// ToBinary
13630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13631#[cfg_attr(feature = "bindings", derive(TS))]
13632pub struct ToBinary {
13633    pub this: Box<Expression>,
13634    #[serde(default)]
13635    pub format: Option<String>,
13636    #[serde(default)]
13637    pub safe: Option<Box<Expression>>,
13638}
13639
13640/// Base64DecodeBinary
13641#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13642#[cfg_attr(feature = "bindings", derive(TS))]
13643pub struct Base64DecodeBinary {
13644    pub this: Box<Expression>,
13645    #[serde(default)]
13646    pub alphabet: Option<Box<Expression>>,
13647}
13648
13649/// Base64DecodeString
13650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13651#[cfg_attr(feature = "bindings", derive(TS))]
13652pub struct Base64DecodeString {
13653    pub this: Box<Expression>,
13654    #[serde(default)]
13655    pub alphabet: Option<Box<Expression>>,
13656}
13657
13658/// Base64Encode
13659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13660#[cfg_attr(feature = "bindings", derive(TS))]
13661pub struct Base64Encode {
13662    pub this: Box<Expression>,
13663    #[serde(default)]
13664    pub max_line_length: Option<Box<Expression>>,
13665    #[serde(default)]
13666    pub alphabet: Option<Box<Expression>>,
13667}
13668
13669/// TryBase64DecodeBinary
13670#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13671#[cfg_attr(feature = "bindings", derive(TS))]
13672pub struct TryBase64DecodeBinary {
13673    pub this: Box<Expression>,
13674    #[serde(default)]
13675    pub alphabet: Option<Box<Expression>>,
13676}
13677
13678/// TryBase64DecodeString
13679#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13680#[cfg_attr(feature = "bindings", derive(TS))]
13681pub struct TryBase64DecodeString {
13682    pub this: Box<Expression>,
13683    #[serde(default)]
13684    pub alphabet: Option<Box<Expression>>,
13685}
13686
13687/// GapFill
13688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13689#[cfg_attr(feature = "bindings", derive(TS))]
13690pub struct GapFill {
13691    pub this: Box<Expression>,
13692    #[serde(default)]
13693    pub ts_column: Option<Box<Expression>>,
13694    #[serde(default)]
13695    pub bucket_width: Option<Box<Expression>>,
13696    #[serde(default)]
13697    pub partitioning_columns: Option<Box<Expression>>,
13698    #[serde(default)]
13699    pub value_columns: Option<Box<Expression>>,
13700    #[serde(default)]
13701    pub origin: Option<Box<Expression>>,
13702    #[serde(default)]
13703    pub ignore_nulls: Option<Box<Expression>>,
13704}
13705
13706/// GenerateDateArray
13707#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13708#[cfg_attr(feature = "bindings", derive(TS))]
13709pub struct GenerateDateArray {
13710    #[serde(default)]
13711    pub start: Option<Box<Expression>>,
13712    #[serde(default)]
13713    pub end: Option<Box<Expression>>,
13714    #[serde(default)]
13715    pub step: Option<Box<Expression>>,
13716}
13717
13718/// GenerateTimestampArray
13719#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13720#[cfg_attr(feature = "bindings", derive(TS))]
13721pub struct GenerateTimestampArray {
13722    #[serde(default)]
13723    pub start: Option<Box<Expression>>,
13724    #[serde(default)]
13725    pub end: Option<Box<Expression>>,
13726    #[serde(default)]
13727    pub step: Option<Box<Expression>>,
13728}
13729
13730/// GetExtract
13731#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13732#[cfg_attr(feature = "bindings", derive(TS))]
13733pub struct GetExtract {
13734    pub this: Box<Expression>,
13735    pub expression: Box<Expression>,
13736}
13737
13738/// Getbit
13739#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13740#[cfg_attr(feature = "bindings", derive(TS))]
13741pub struct Getbit {
13742    pub this: Box<Expression>,
13743    pub expression: Box<Expression>,
13744    #[serde(default)]
13745    pub zero_is_msb: Option<Box<Expression>>,
13746}
13747
13748/// OverflowTruncateBehavior
13749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13750#[cfg_attr(feature = "bindings", derive(TS))]
13751pub struct OverflowTruncateBehavior {
13752    #[serde(default)]
13753    pub this: Option<Box<Expression>>,
13754    #[serde(default)]
13755    pub with_count: Option<Box<Expression>>,
13756}
13757
13758/// HexEncode
13759#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13760#[cfg_attr(feature = "bindings", derive(TS))]
13761pub struct HexEncode {
13762    pub this: Box<Expression>,
13763    #[serde(default)]
13764    pub case: Option<Box<Expression>>,
13765}
13766
13767/// Compress
13768#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13769#[cfg_attr(feature = "bindings", derive(TS))]
13770pub struct Compress {
13771    pub this: Box<Expression>,
13772    #[serde(default)]
13773    pub method: Option<String>,
13774}
13775
13776/// DecompressBinary
13777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13778#[cfg_attr(feature = "bindings", derive(TS))]
13779pub struct DecompressBinary {
13780    pub this: Box<Expression>,
13781    pub method: String,
13782}
13783
13784/// DecompressString
13785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13786#[cfg_attr(feature = "bindings", derive(TS))]
13787pub struct DecompressString {
13788    pub this: Box<Expression>,
13789    pub method: String,
13790}
13791
13792/// Xor
13793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13794#[cfg_attr(feature = "bindings", derive(TS))]
13795pub struct Xor {
13796    #[serde(default)]
13797    pub this: Option<Box<Expression>>,
13798    #[serde(default)]
13799    pub expression: Option<Box<Expression>>,
13800    #[serde(default)]
13801    pub expressions: Vec<Expression>,
13802}
13803
13804/// Nullif
13805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13806#[cfg_attr(feature = "bindings", derive(TS))]
13807pub struct Nullif {
13808    pub this: Box<Expression>,
13809    pub expression: Box<Expression>,
13810}
13811
13812/// JSON
13813#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13814#[cfg_attr(feature = "bindings", derive(TS))]
13815pub struct JSON {
13816    #[serde(default)]
13817    pub this: Option<Box<Expression>>,
13818    #[serde(default)]
13819    pub with_: Option<Box<Expression>>,
13820    #[serde(default)]
13821    pub unique: bool,
13822}
13823
13824/// JSONPath
13825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13826#[cfg_attr(feature = "bindings", derive(TS))]
13827pub struct JSONPath {
13828    #[serde(default)]
13829    pub expressions: Vec<Expression>,
13830    #[serde(default)]
13831    pub escape: Option<Box<Expression>>,
13832}
13833
13834/// JSONPathFilter
13835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13836#[cfg_attr(feature = "bindings", derive(TS))]
13837pub struct JSONPathFilter {
13838    pub this: Box<Expression>,
13839}
13840
13841/// JSONPathKey
13842#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13843#[cfg_attr(feature = "bindings", derive(TS))]
13844pub struct JSONPathKey {
13845    pub this: Box<Expression>,
13846}
13847
13848/// JSONPathRecursive
13849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13850#[cfg_attr(feature = "bindings", derive(TS))]
13851pub struct JSONPathRecursive {
13852    #[serde(default)]
13853    pub this: Option<Box<Expression>>,
13854}
13855
13856/// JSONPathScript
13857#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13858#[cfg_attr(feature = "bindings", derive(TS))]
13859pub struct JSONPathScript {
13860    pub this: Box<Expression>,
13861}
13862
13863/// JSONPathSlice
13864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13865#[cfg_attr(feature = "bindings", derive(TS))]
13866pub struct JSONPathSlice {
13867    #[serde(default)]
13868    pub start: Option<Box<Expression>>,
13869    #[serde(default)]
13870    pub end: Option<Box<Expression>>,
13871    #[serde(default)]
13872    pub step: Option<Box<Expression>>,
13873}
13874
13875/// JSONPathSelector
13876#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13877#[cfg_attr(feature = "bindings", derive(TS))]
13878pub struct JSONPathSelector {
13879    pub this: Box<Expression>,
13880}
13881
13882/// JSONPathSubscript
13883#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13884#[cfg_attr(feature = "bindings", derive(TS))]
13885pub struct JSONPathSubscript {
13886    pub this: Box<Expression>,
13887}
13888
13889/// JSONPathUnion
13890#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13891#[cfg_attr(feature = "bindings", derive(TS))]
13892pub struct JSONPathUnion {
13893    #[serde(default)]
13894    pub expressions: Vec<Expression>,
13895}
13896
13897/// Format
13898#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13899#[cfg_attr(feature = "bindings", derive(TS))]
13900pub struct Format {
13901    pub this: Box<Expression>,
13902    #[serde(default)]
13903    pub expressions: Vec<Expression>,
13904}
13905
13906/// JSONKeys
13907#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13908#[cfg_attr(feature = "bindings", derive(TS))]
13909pub struct JSONKeys {
13910    pub this: Box<Expression>,
13911    #[serde(default)]
13912    pub expression: Option<Box<Expression>>,
13913    #[serde(default)]
13914    pub expressions: Vec<Expression>,
13915}
13916
13917/// JSONKeyValue
13918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13919#[cfg_attr(feature = "bindings", derive(TS))]
13920pub struct JSONKeyValue {
13921    pub this: Box<Expression>,
13922    pub expression: Box<Expression>,
13923}
13924
13925/// JSONKeysAtDepth
13926#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13927#[cfg_attr(feature = "bindings", derive(TS))]
13928pub struct JSONKeysAtDepth {
13929    pub this: Box<Expression>,
13930    #[serde(default)]
13931    pub expression: Option<Box<Expression>>,
13932    #[serde(default)]
13933    pub mode: Option<Box<Expression>>,
13934}
13935
13936/// JSONObject
13937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13938#[cfg_attr(feature = "bindings", derive(TS))]
13939pub struct JSONObject {
13940    #[serde(default)]
13941    pub expressions: Vec<Expression>,
13942    #[serde(default)]
13943    pub null_handling: Option<Box<Expression>>,
13944    #[serde(default)]
13945    pub unique_keys: Option<Box<Expression>>,
13946    #[serde(default)]
13947    pub return_type: Option<Box<Expression>>,
13948    #[serde(default)]
13949    pub encoding: Option<Box<Expression>>,
13950}
13951
13952/// JSONObjectAgg
13953#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13954#[cfg_attr(feature = "bindings", derive(TS))]
13955pub struct JSONObjectAgg {
13956    #[serde(default)]
13957    pub expressions: Vec<Expression>,
13958    #[serde(default)]
13959    pub null_handling: Option<Box<Expression>>,
13960    #[serde(default)]
13961    pub unique_keys: Option<Box<Expression>>,
13962    #[serde(default)]
13963    pub return_type: Option<Box<Expression>>,
13964    #[serde(default)]
13965    pub encoding: Option<Box<Expression>>,
13966}
13967
13968/// JSONBObjectAgg
13969#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13970#[cfg_attr(feature = "bindings", derive(TS))]
13971pub struct JSONBObjectAgg {
13972    pub this: Box<Expression>,
13973    pub expression: Box<Expression>,
13974}
13975
13976/// JSONArray
13977#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13978#[cfg_attr(feature = "bindings", derive(TS))]
13979pub struct JSONArray {
13980    #[serde(default)]
13981    pub expressions: Vec<Expression>,
13982    #[serde(default)]
13983    pub null_handling: Option<Box<Expression>>,
13984    #[serde(default)]
13985    pub return_type: Option<Box<Expression>>,
13986    #[serde(default)]
13987    pub strict: Option<Box<Expression>>,
13988}
13989
13990/// JSONArrayAgg
13991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13992#[cfg_attr(feature = "bindings", derive(TS))]
13993pub struct JSONArrayAgg {
13994    pub this: Box<Expression>,
13995    #[serde(default)]
13996    pub order: Option<Box<Expression>>,
13997    #[serde(default)]
13998    pub null_handling: Option<Box<Expression>>,
13999    #[serde(default)]
14000    pub return_type: Option<Box<Expression>>,
14001    #[serde(default)]
14002    pub strict: Option<Box<Expression>>,
14003}
14004
14005/// JSONExists
14006#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14007#[cfg_attr(feature = "bindings", derive(TS))]
14008pub struct JSONExists {
14009    pub this: Box<Expression>,
14010    #[serde(default)]
14011    pub path: Option<Box<Expression>>,
14012    #[serde(default)]
14013    pub passing: Option<Box<Expression>>,
14014    #[serde(default)]
14015    pub on_condition: Option<Box<Expression>>,
14016    #[serde(default)]
14017    pub from_dcolonqmark: Option<Box<Expression>>,
14018}
14019
14020/// JSONColumnDef
14021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14022#[cfg_attr(feature = "bindings", derive(TS))]
14023pub struct JSONColumnDef {
14024    #[serde(default)]
14025    pub this: Option<Box<Expression>>,
14026    #[serde(default)]
14027    pub kind: Option<String>,
14028    #[serde(default)]
14029    pub format_json: bool,
14030    #[serde(default)]
14031    pub path: Option<Box<Expression>>,
14032    #[serde(default)]
14033    pub nested_schema: Option<Box<Expression>>,
14034    #[serde(default)]
14035    pub ordinality: Option<Box<Expression>>,
14036}
14037
14038/// JSONSchema
14039#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14040#[cfg_attr(feature = "bindings", derive(TS))]
14041pub struct JSONSchema {
14042    #[serde(default)]
14043    pub expressions: Vec<Expression>,
14044}
14045
14046/// JSONSet
14047#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14048#[cfg_attr(feature = "bindings", derive(TS))]
14049pub struct JSONSet {
14050    pub this: Box<Expression>,
14051    #[serde(default)]
14052    pub expressions: Vec<Expression>,
14053}
14054
14055/// JSONStripNulls
14056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14057#[cfg_attr(feature = "bindings", derive(TS))]
14058pub struct JSONStripNulls {
14059    pub this: Box<Expression>,
14060    #[serde(default)]
14061    pub expression: Option<Box<Expression>>,
14062    #[serde(default)]
14063    pub include_arrays: Option<Box<Expression>>,
14064    #[serde(default)]
14065    pub remove_empty: Option<Box<Expression>>,
14066}
14067
14068/// JSONValue
14069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14070#[cfg_attr(feature = "bindings", derive(TS))]
14071pub struct JSONValue {
14072    pub this: Box<Expression>,
14073    #[serde(default)]
14074    pub path: Option<Box<Expression>>,
14075    #[serde(default)]
14076    pub returning: Option<Box<Expression>>,
14077    #[serde(default)]
14078    pub on_condition: Option<Box<Expression>>,
14079}
14080
14081/// JSONValueArray
14082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14083#[cfg_attr(feature = "bindings", derive(TS))]
14084pub struct JSONValueArray {
14085    pub this: Box<Expression>,
14086    #[serde(default)]
14087    pub expression: Option<Box<Expression>>,
14088}
14089
14090/// JSONRemove
14091#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14092#[cfg_attr(feature = "bindings", derive(TS))]
14093pub struct JSONRemove {
14094    pub this: Box<Expression>,
14095    #[serde(default)]
14096    pub expressions: Vec<Expression>,
14097}
14098
14099/// JSONTable
14100#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14101#[cfg_attr(feature = "bindings", derive(TS))]
14102pub struct JSONTable {
14103    pub this: Box<Expression>,
14104    #[serde(default)]
14105    pub schema: Option<Box<Expression>>,
14106    #[serde(default)]
14107    pub path: Option<Box<Expression>>,
14108    #[serde(default)]
14109    pub error_handling: Option<Box<Expression>>,
14110    #[serde(default)]
14111    pub empty_handling: Option<Box<Expression>>,
14112}
14113
14114/// JSONType
14115#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14116#[cfg_attr(feature = "bindings", derive(TS))]
14117pub struct JSONType {
14118    pub this: Box<Expression>,
14119    #[serde(default)]
14120    pub expression: Option<Box<Expression>>,
14121}
14122
14123/// ObjectInsert
14124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14125#[cfg_attr(feature = "bindings", derive(TS))]
14126pub struct ObjectInsert {
14127    pub this: Box<Expression>,
14128    #[serde(default)]
14129    pub key: Option<Box<Expression>>,
14130    #[serde(default)]
14131    pub value: Option<Box<Expression>>,
14132    #[serde(default)]
14133    pub update_flag: Option<Box<Expression>>,
14134}
14135
14136/// OpenJSONColumnDef
14137#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14138#[cfg_attr(feature = "bindings", derive(TS))]
14139pub struct OpenJSONColumnDef {
14140    pub this: Box<Expression>,
14141    pub kind: String,
14142    #[serde(default)]
14143    pub path: Option<Box<Expression>>,
14144    #[serde(default)]
14145    pub as_json: Option<Box<Expression>>,
14146    /// The parsed data type for proper generation
14147    #[serde(default, skip_serializing_if = "Option::is_none")]
14148    pub data_type: Option<DataType>,
14149}
14150
14151/// OpenJSON
14152#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14153#[cfg_attr(feature = "bindings", derive(TS))]
14154pub struct OpenJSON {
14155    pub this: Box<Expression>,
14156    #[serde(default)]
14157    pub path: Option<Box<Expression>>,
14158    #[serde(default)]
14159    pub expressions: Vec<Expression>,
14160}
14161
14162/// JSONBExists
14163#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14164#[cfg_attr(feature = "bindings", derive(TS))]
14165pub struct JSONBExists {
14166    pub this: Box<Expression>,
14167    #[serde(default)]
14168    pub path: Option<Box<Expression>>,
14169}
14170
14171/// JSONCast
14172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14173#[cfg_attr(feature = "bindings", derive(TS))]
14174pub struct JSONCast {
14175    pub this: Box<Expression>,
14176    pub to: DataType,
14177}
14178
14179/// JSONExtract
14180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14181#[cfg_attr(feature = "bindings", derive(TS))]
14182pub struct JSONExtract {
14183    pub this: Box<Expression>,
14184    pub expression: Box<Expression>,
14185    #[serde(default)]
14186    pub only_json_types: Option<Box<Expression>>,
14187    #[serde(default)]
14188    pub expressions: Vec<Expression>,
14189    #[serde(default)]
14190    pub variant_extract: Option<Box<Expression>>,
14191    #[serde(default)]
14192    pub json_query: Option<Box<Expression>>,
14193    #[serde(default)]
14194    pub option: Option<Box<Expression>>,
14195    #[serde(default)]
14196    pub quote: Option<Box<Expression>>,
14197    #[serde(default)]
14198    pub on_condition: Option<Box<Expression>>,
14199    #[serde(default)]
14200    pub requires_json: Option<Box<Expression>>,
14201}
14202
14203/// JSONExtractQuote
14204#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14205#[cfg_attr(feature = "bindings", derive(TS))]
14206pub struct JSONExtractQuote {
14207    #[serde(default)]
14208    pub option: Option<Box<Expression>>,
14209    #[serde(default)]
14210    pub scalar: Option<Box<Expression>>,
14211}
14212
14213/// JSONExtractArray
14214#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14215#[cfg_attr(feature = "bindings", derive(TS))]
14216pub struct JSONExtractArray {
14217    pub this: Box<Expression>,
14218    #[serde(default)]
14219    pub expression: Option<Box<Expression>>,
14220}
14221
14222/// JSONExtractScalar
14223#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14224#[cfg_attr(feature = "bindings", derive(TS))]
14225pub struct JSONExtractScalar {
14226    pub this: Box<Expression>,
14227    pub expression: Box<Expression>,
14228    #[serde(default)]
14229    pub only_json_types: Option<Box<Expression>>,
14230    #[serde(default)]
14231    pub expressions: Vec<Expression>,
14232    #[serde(default)]
14233    pub json_type: Option<Box<Expression>>,
14234    #[serde(default)]
14235    pub scalar_only: Option<Box<Expression>>,
14236}
14237
14238/// JSONBExtractScalar
14239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14240#[cfg_attr(feature = "bindings", derive(TS))]
14241pub struct JSONBExtractScalar {
14242    pub this: Box<Expression>,
14243    pub expression: Box<Expression>,
14244    #[serde(default)]
14245    pub json_type: Option<Box<Expression>>,
14246}
14247
14248/// JSONFormat
14249#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14250#[cfg_attr(feature = "bindings", derive(TS))]
14251pub struct JSONFormat {
14252    #[serde(default)]
14253    pub this: Option<Box<Expression>>,
14254    #[serde(default)]
14255    pub options: Vec<Expression>,
14256    #[serde(default)]
14257    pub is_json: Option<Box<Expression>>,
14258    #[serde(default)]
14259    pub to_json: Option<Box<Expression>>,
14260}
14261
14262/// JSONArrayAppend
14263#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14264#[cfg_attr(feature = "bindings", derive(TS))]
14265pub struct JSONArrayAppend {
14266    pub this: Box<Expression>,
14267    #[serde(default)]
14268    pub expressions: Vec<Expression>,
14269}
14270
14271/// JSONArrayContains
14272#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14273#[cfg_attr(feature = "bindings", derive(TS))]
14274pub struct JSONArrayContains {
14275    pub this: Box<Expression>,
14276    pub expression: Box<Expression>,
14277    #[serde(default)]
14278    pub json_type: Option<Box<Expression>>,
14279}
14280
14281/// JSONArrayInsert
14282#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14283#[cfg_attr(feature = "bindings", derive(TS))]
14284pub struct JSONArrayInsert {
14285    pub this: Box<Expression>,
14286    #[serde(default)]
14287    pub expressions: Vec<Expression>,
14288}
14289
14290/// ParseJSON
14291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14292#[cfg_attr(feature = "bindings", derive(TS))]
14293pub struct ParseJSON {
14294    pub this: Box<Expression>,
14295    #[serde(default)]
14296    pub expression: Option<Box<Expression>>,
14297    #[serde(default)]
14298    pub safe: Option<Box<Expression>>,
14299}
14300
14301/// ParseUrl
14302#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14303#[cfg_attr(feature = "bindings", derive(TS))]
14304pub struct ParseUrl {
14305    pub this: Box<Expression>,
14306    #[serde(default)]
14307    pub part_to_extract: Option<Box<Expression>>,
14308    #[serde(default)]
14309    pub key: Option<Box<Expression>>,
14310    #[serde(default)]
14311    pub permissive: Option<Box<Expression>>,
14312}
14313
14314/// ParseIp
14315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14316#[cfg_attr(feature = "bindings", derive(TS))]
14317pub struct ParseIp {
14318    pub this: Box<Expression>,
14319    #[serde(default)]
14320    pub type_: Option<Box<Expression>>,
14321    #[serde(default)]
14322    pub permissive: Option<Box<Expression>>,
14323}
14324
14325/// ParseTime
14326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14327#[cfg_attr(feature = "bindings", derive(TS))]
14328pub struct ParseTime {
14329    pub this: Box<Expression>,
14330    pub format: String,
14331}
14332
14333/// ParseDatetime
14334#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14335#[cfg_attr(feature = "bindings", derive(TS))]
14336pub struct ParseDatetime {
14337    pub this: Box<Expression>,
14338    #[serde(default)]
14339    pub format: Option<String>,
14340    #[serde(default)]
14341    pub zone: Option<Box<Expression>>,
14342}
14343
14344/// Map
14345#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14346#[cfg_attr(feature = "bindings", derive(TS))]
14347pub struct Map {
14348    #[serde(default)]
14349    pub keys: Vec<Expression>,
14350    #[serde(default)]
14351    pub values: Vec<Expression>,
14352}
14353
14354/// MapCat
14355#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14356#[cfg_attr(feature = "bindings", derive(TS))]
14357pub struct MapCat {
14358    pub this: Box<Expression>,
14359    pub expression: Box<Expression>,
14360}
14361
14362/// MapDelete
14363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14364#[cfg_attr(feature = "bindings", derive(TS))]
14365pub struct MapDelete {
14366    pub this: Box<Expression>,
14367    #[serde(default)]
14368    pub expressions: Vec<Expression>,
14369}
14370
14371/// MapInsert
14372#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14373#[cfg_attr(feature = "bindings", derive(TS))]
14374pub struct MapInsert {
14375    pub this: Box<Expression>,
14376    #[serde(default)]
14377    pub key: Option<Box<Expression>>,
14378    #[serde(default)]
14379    pub value: Option<Box<Expression>>,
14380    #[serde(default)]
14381    pub update_flag: Option<Box<Expression>>,
14382}
14383
14384/// MapPick
14385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14386#[cfg_attr(feature = "bindings", derive(TS))]
14387pub struct MapPick {
14388    pub this: Box<Expression>,
14389    #[serde(default)]
14390    pub expressions: Vec<Expression>,
14391}
14392
14393/// ScopeResolution
14394#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14395#[cfg_attr(feature = "bindings", derive(TS))]
14396pub struct ScopeResolution {
14397    #[serde(default)]
14398    pub this: Option<Box<Expression>>,
14399    pub expression: Box<Expression>,
14400}
14401
14402/// Slice
14403#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14404#[cfg_attr(feature = "bindings", derive(TS))]
14405pub struct Slice {
14406    #[serde(default)]
14407    pub this: Option<Box<Expression>>,
14408    #[serde(default)]
14409    pub expression: Option<Box<Expression>>,
14410    #[serde(default)]
14411    pub step: Option<Box<Expression>>,
14412}
14413
14414/// VarMap
14415#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14416#[cfg_attr(feature = "bindings", derive(TS))]
14417pub struct VarMap {
14418    #[serde(default)]
14419    pub keys: Vec<Expression>,
14420    #[serde(default)]
14421    pub values: Vec<Expression>,
14422}
14423
14424/// MatchAgainst
14425#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14426#[cfg_attr(feature = "bindings", derive(TS))]
14427pub struct MatchAgainst {
14428    pub this: Box<Expression>,
14429    #[serde(default)]
14430    pub expressions: Vec<Expression>,
14431    #[serde(default)]
14432    pub modifier: Option<Box<Expression>>,
14433}
14434
14435/// MD5Digest
14436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14437#[cfg_attr(feature = "bindings", derive(TS))]
14438pub struct MD5Digest {
14439    pub this: Box<Expression>,
14440    #[serde(default)]
14441    pub expressions: Vec<Expression>,
14442}
14443
14444/// Monthname
14445#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14446#[cfg_attr(feature = "bindings", derive(TS))]
14447pub struct Monthname {
14448    pub this: Box<Expression>,
14449    #[serde(default)]
14450    pub abbreviated: Option<Box<Expression>>,
14451}
14452
14453/// Ntile
14454#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14455#[cfg_attr(feature = "bindings", derive(TS))]
14456pub struct Ntile {
14457    #[serde(default)]
14458    pub this: Option<Box<Expression>>,
14459}
14460
14461/// Normalize
14462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14463#[cfg_attr(feature = "bindings", derive(TS))]
14464pub struct Normalize {
14465    pub this: Box<Expression>,
14466    #[serde(default)]
14467    pub form: Option<Box<Expression>>,
14468    #[serde(default)]
14469    pub is_casefold: Option<Box<Expression>>,
14470}
14471
14472/// Normal
14473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14474#[cfg_attr(feature = "bindings", derive(TS))]
14475pub struct Normal {
14476    pub this: Box<Expression>,
14477    #[serde(default)]
14478    pub stddev: Option<Box<Expression>>,
14479    #[serde(default)]
14480    pub gen: Option<Box<Expression>>,
14481}
14482
14483/// Predict
14484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14485#[cfg_attr(feature = "bindings", derive(TS))]
14486pub struct Predict {
14487    pub this: Box<Expression>,
14488    pub expression: Box<Expression>,
14489    #[serde(default)]
14490    pub params_struct: Option<Box<Expression>>,
14491}
14492
14493/// MLTranslate
14494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14495#[cfg_attr(feature = "bindings", derive(TS))]
14496pub struct MLTranslate {
14497    pub this: Box<Expression>,
14498    pub expression: Box<Expression>,
14499    #[serde(default)]
14500    pub params_struct: Option<Box<Expression>>,
14501}
14502
14503/// FeaturesAtTime
14504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14505#[cfg_attr(feature = "bindings", derive(TS))]
14506pub struct FeaturesAtTime {
14507    pub this: Box<Expression>,
14508    #[serde(default)]
14509    pub time: Option<Box<Expression>>,
14510    #[serde(default)]
14511    pub num_rows: Option<Box<Expression>>,
14512    #[serde(default)]
14513    pub ignore_feature_nulls: Option<Box<Expression>>,
14514}
14515
14516/// GenerateEmbedding
14517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14518#[cfg_attr(feature = "bindings", derive(TS))]
14519pub struct GenerateEmbedding {
14520    pub this: Box<Expression>,
14521    pub expression: Box<Expression>,
14522    #[serde(default)]
14523    pub params_struct: Option<Box<Expression>>,
14524    #[serde(default)]
14525    pub is_text: Option<Box<Expression>>,
14526}
14527
14528/// MLForecast
14529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14530#[cfg_attr(feature = "bindings", derive(TS))]
14531pub struct MLForecast {
14532    pub this: Box<Expression>,
14533    #[serde(default)]
14534    pub expression: Option<Box<Expression>>,
14535    #[serde(default)]
14536    pub params_struct: Option<Box<Expression>>,
14537}
14538
14539/// ModelAttribute
14540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14541#[cfg_attr(feature = "bindings", derive(TS))]
14542pub struct ModelAttribute {
14543    pub this: Box<Expression>,
14544    pub expression: Box<Expression>,
14545}
14546
14547/// VectorSearch
14548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14549#[cfg_attr(feature = "bindings", derive(TS))]
14550pub struct VectorSearch {
14551    pub this: Box<Expression>,
14552    #[serde(default)]
14553    pub column_to_search: Option<Box<Expression>>,
14554    #[serde(default)]
14555    pub query_table: Option<Box<Expression>>,
14556    #[serde(default)]
14557    pub query_column_to_search: Option<Box<Expression>>,
14558    #[serde(default)]
14559    pub top_k: Option<Box<Expression>>,
14560    #[serde(default)]
14561    pub distance_type: Option<Box<Expression>>,
14562    #[serde(default)]
14563    pub options: Vec<Expression>,
14564}
14565
14566/// Quantile
14567#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14568#[cfg_attr(feature = "bindings", derive(TS))]
14569pub struct Quantile {
14570    pub this: Box<Expression>,
14571    #[serde(default)]
14572    pub quantile: Option<Box<Expression>>,
14573}
14574
14575/// ApproxQuantile
14576#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14577#[cfg_attr(feature = "bindings", derive(TS))]
14578pub struct ApproxQuantile {
14579    pub this: Box<Expression>,
14580    #[serde(default)]
14581    pub quantile: Option<Box<Expression>>,
14582    #[serde(default)]
14583    pub accuracy: Option<Box<Expression>>,
14584    #[serde(default)]
14585    pub weight: Option<Box<Expression>>,
14586    #[serde(default)]
14587    pub error_tolerance: Option<Box<Expression>>,
14588}
14589
14590/// ApproxPercentileEstimate
14591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14592#[cfg_attr(feature = "bindings", derive(TS))]
14593pub struct ApproxPercentileEstimate {
14594    pub this: Box<Expression>,
14595    #[serde(default)]
14596    pub percentile: Option<Box<Expression>>,
14597}
14598
14599/// Randn
14600#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14601#[cfg_attr(feature = "bindings", derive(TS))]
14602pub struct Randn {
14603    #[serde(default)]
14604    pub this: Option<Box<Expression>>,
14605}
14606
14607/// Randstr
14608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14609#[cfg_attr(feature = "bindings", derive(TS))]
14610pub struct Randstr {
14611    pub this: Box<Expression>,
14612    #[serde(default)]
14613    pub generator: Option<Box<Expression>>,
14614}
14615
14616/// RangeN
14617#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14618#[cfg_attr(feature = "bindings", derive(TS))]
14619pub struct RangeN {
14620    pub this: Box<Expression>,
14621    #[serde(default)]
14622    pub expressions: Vec<Expression>,
14623    #[serde(default)]
14624    pub each: Option<Box<Expression>>,
14625}
14626
14627/// RangeBucket
14628#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14629#[cfg_attr(feature = "bindings", derive(TS))]
14630pub struct RangeBucket {
14631    pub this: Box<Expression>,
14632    pub expression: Box<Expression>,
14633}
14634
14635/// ReadCSV
14636#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14637#[cfg_attr(feature = "bindings", derive(TS))]
14638pub struct ReadCSV {
14639    pub this: Box<Expression>,
14640    #[serde(default)]
14641    pub expressions: Vec<Expression>,
14642}
14643
14644/// ReadParquet
14645#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14646#[cfg_attr(feature = "bindings", derive(TS))]
14647pub struct ReadParquet {
14648    #[serde(default)]
14649    pub expressions: Vec<Expression>,
14650}
14651
14652/// Reduce
14653#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14654#[cfg_attr(feature = "bindings", derive(TS))]
14655pub struct Reduce {
14656    pub this: Box<Expression>,
14657    #[serde(default)]
14658    pub initial: Option<Box<Expression>>,
14659    #[serde(default)]
14660    pub merge: Option<Box<Expression>>,
14661    #[serde(default)]
14662    pub finish: Option<Box<Expression>>,
14663}
14664
14665/// RegexpExtractAll
14666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14667#[cfg_attr(feature = "bindings", derive(TS))]
14668pub struct RegexpExtractAll {
14669    pub this: Box<Expression>,
14670    pub expression: Box<Expression>,
14671    #[serde(default)]
14672    pub group: Option<Box<Expression>>,
14673    #[serde(default)]
14674    pub parameters: Option<Box<Expression>>,
14675    #[serde(default)]
14676    pub position: Option<Box<Expression>>,
14677    #[serde(default)]
14678    pub occurrence: Option<Box<Expression>>,
14679}
14680
14681/// RegexpILike
14682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14683#[cfg_attr(feature = "bindings", derive(TS))]
14684pub struct RegexpILike {
14685    pub this: Box<Expression>,
14686    pub expression: Box<Expression>,
14687    #[serde(default)]
14688    pub flag: Option<Box<Expression>>,
14689}
14690
14691/// RegexpFullMatch
14692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14693#[cfg_attr(feature = "bindings", derive(TS))]
14694pub struct RegexpFullMatch {
14695    pub this: Box<Expression>,
14696    pub expression: Box<Expression>,
14697    #[serde(default)]
14698    pub options: Vec<Expression>,
14699}
14700
14701/// RegexpInstr
14702#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14703#[cfg_attr(feature = "bindings", derive(TS))]
14704pub struct RegexpInstr {
14705    pub this: Box<Expression>,
14706    pub expression: Box<Expression>,
14707    #[serde(default)]
14708    pub position: Option<Box<Expression>>,
14709    #[serde(default)]
14710    pub occurrence: Option<Box<Expression>>,
14711    #[serde(default)]
14712    pub option: Option<Box<Expression>>,
14713    #[serde(default)]
14714    pub parameters: Option<Box<Expression>>,
14715    #[serde(default)]
14716    pub group: Option<Box<Expression>>,
14717}
14718
14719/// RegexpSplit
14720#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14721#[cfg_attr(feature = "bindings", derive(TS))]
14722pub struct RegexpSplit {
14723    pub this: Box<Expression>,
14724    pub expression: Box<Expression>,
14725    #[serde(default)]
14726    pub limit: Option<Box<Expression>>,
14727}
14728
14729/// RegexpCount
14730#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14731#[cfg_attr(feature = "bindings", derive(TS))]
14732pub struct RegexpCount {
14733    pub this: Box<Expression>,
14734    pub expression: Box<Expression>,
14735    #[serde(default)]
14736    pub position: Option<Box<Expression>>,
14737    #[serde(default)]
14738    pub parameters: Option<Box<Expression>>,
14739}
14740
14741/// RegrValx
14742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14743#[cfg_attr(feature = "bindings", derive(TS))]
14744pub struct RegrValx {
14745    pub this: Box<Expression>,
14746    pub expression: Box<Expression>,
14747}
14748
14749/// RegrValy
14750#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14751#[cfg_attr(feature = "bindings", derive(TS))]
14752pub struct RegrValy {
14753    pub this: Box<Expression>,
14754    pub expression: Box<Expression>,
14755}
14756
14757/// RegrAvgy
14758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14759#[cfg_attr(feature = "bindings", derive(TS))]
14760pub struct RegrAvgy {
14761    pub this: Box<Expression>,
14762    pub expression: Box<Expression>,
14763}
14764
14765/// RegrAvgx
14766#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14767#[cfg_attr(feature = "bindings", derive(TS))]
14768pub struct RegrAvgx {
14769    pub this: Box<Expression>,
14770    pub expression: Box<Expression>,
14771}
14772
14773/// RegrCount
14774#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14775#[cfg_attr(feature = "bindings", derive(TS))]
14776pub struct RegrCount {
14777    pub this: Box<Expression>,
14778    pub expression: Box<Expression>,
14779}
14780
14781/// RegrIntercept
14782#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14783#[cfg_attr(feature = "bindings", derive(TS))]
14784pub struct RegrIntercept {
14785    pub this: Box<Expression>,
14786    pub expression: Box<Expression>,
14787}
14788
14789/// RegrR2
14790#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14791#[cfg_attr(feature = "bindings", derive(TS))]
14792pub struct RegrR2 {
14793    pub this: Box<Expression>,
14794    pub expression: Box<Expression>,
14795}
14796
14797/// RegrSxx
14798#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14799#[cfg_attr(feature = "bindings", derive(TS))]
14800pub struct RegrSxx {
14801    pub this: Box<Expression>,
14802    pub expression: Box<Expression>,
14803}
14804
14805/// RegrSxy
14806#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14807#[cfg_attr(feature = "bindings", derive(TS))]
14808pub struct RegrSxy {
14809    pub this: Box<Expression>,
14810    pub expression: Box<Expression>,
14811}
14812
14813/// RegrSyy
14814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14815#[cfg_attr(feature = "bindings", derive(TS))]
14816pub struct RegrSyy {
14817    pub this: Box<Expression>,
14818    pub expression: Box<Expression>,
14819}
14820
14821/// RegrSlope
14822#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14823#[cfg_attr(feature = "bindings", derive(TS))]
14824pub struct RegrSlope {
14825    pub this: Box<Expression>,
14826    pub expression: Box<Expression>,
14827}
14828
14829/// SafeAdd
14830#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14831#[cfg_attr(feature = "bindings", derive(TS))]
14832pub struct SafeAdd {
14833    pub this: Box<Expression>,
14834    pub expression: Box<Expression>,
14835}
14836
14837/// SafeDivide
14838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14839#[cfg_attr(feature = "bindings", derive(TS))]
14840pub struct SafeDivide {
14841    pub this: Box<Expression>,
14842    pub expression: Box<Expression>,
14843}
14844
14845/// SafeMultiply
14846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14847#[cfg_attr(feature = "bindings", derive(TS))]
14848pub struct SafeMultiply {
14849    pub this: Box<Expression>,
14850    pub expression: Box<Expression>,
14851}
14852
14853/// SafeSubtract
14854#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14855#[cfg_attr(feature = "bindings", derive(TS))]
14856pub struct SafeSubtract {
14857    pub this: Box<Expression>,
14858    pub expression: Box<Expression>,
14859}
14860
14861/// SHA2
14862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14863#[cfg_attr(feature = "bindings", derive(TS))]
14864pub struct SHA2 {
14865    pub this: Box<Expression>,
14866    #[serde(default)]
14867    pub length: Option<i64>,
14868}
14869
14870/// SHA2Digest
14871#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14872#[cfg_attr(feature = "bindings", derive(TS))]
14873pub struct SHA2Digest {
14874    pub this: Box<Expression>,
14875    #[serde(default)]
14876    pub length: Option<i64>,
14877}
14878
14879/// SortArray
14880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14881#[cfg_attr(feature = "bindings", derive(TS))]
14882pub struct SortArray {
14883    pub this: Box<Expression>,
14884    #[serde(default)]
14885    pub asc: Option<Box<Expression>>,
14886    #[serde(default)]
14887    pub nulls_first: Option<Box<Expression>>,
14888}
14889
14890/// SplitPart
14891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14892#[cfg_attr(feature = "bindings", derive(TS))]
14893pub struct SplitPart {
14894    pub this: Box<Expression>,
14895    #[serde(default)]
14896    pub delimiter: Option<Box<Expression>>,
14897    #[serde(default)]
14898    pub part_index: Option<Box<Expression>>,
14899}
14900
14901/// SUBSTRING_INDEX(str, delim, count)
14902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14903#[cfg_attr(feature = "bindings", derive(TS))]
14904pub struct SubstringIndex {
14905    pub this: Box<Expression>,
14906    #[serde(default)]
14907    pub delimiter: Option<Box<Expression>>,
14908    #[serde(default)]
14909    pub count: Option<Box<Expression>>,
14910}
14911
14912/// StandardHash
14913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14914#[cfg_attr(feature = "bindings", derive(TS))]
14915pub struct StandardHash {
14916    pub this: Box<Expression>,
14917    #[serde(default)]
14918    pub expression: Option<Box<Expression>>,
14919}
14920
14921/// StrPosition
14922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14923#[cfg_attr(feature = "bindings", derive(TS))]
14924pub struct StrPosition {
14925    pub this: Box<Expression>,
14926    #[serde(default)]
14927    pub substr: Option<Box<Expression>>,
14928    #[serde(default)]
14929    pub position: Option<Box<Expression>>,
14930    #[serde(default)]
14931    pub occurrence: Option<Box<Expression>>,
14932}
14933
14934/// Search
14935#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14936#[cfg_attr(feature = "bindings", derive(TS))]
14937pub struct Search {
14938    pub this: Box<Expression>,
14939    pub expression: Box<Expression>,
14940    #[serde(default)]
14941    pub json_scope: Option<Box<Expression>>,
14942    #[serde(default)]
14943    pub analyzer: Option<Box<Expression>>,
14944    #[serde(default)]
14945    pub analyzer_options: Option<Box<Expression>>,
14946    #[serde(default)]
14947    pub search_mode: Option<Box<Expression>>,
14948}
14949
14950/// SearchIp
14951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14952#[cfg_attr(feature = "bindings", derive(TS))]
14953pub struct SearchIp {
14954    pub this: Box<Expression>,
14955    pub expression: Box<Expression>,
14956}
14957
14958/// StrToDate
14959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14960#[cfg_attr(feature = "bindings", derive(TS))]
14961pub struct StrToDate {
14962    pub this: Box<Expression>,
14963    #[serde(default)]
14964    pub format: Option<String>,
14965    #[serde(default)]
14966    pub safe: Option<Box<Expression>>,
14967}
14968
14969/// StrToTime
14970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14971#[cfg_attr(feature = "bindings", derive(TS))]
14972pub struct StrToTime {
14973    pub this: Box<Expression>,
14974    pub format: String,
14975    #[serde(default)]
14976    pub zone: Option<Box<Expression>>,
14977    #[serde(default)]
14978    pub safe: Option<Box<Expression>>,
14979    #[serde(default)]
14980    pub target_type: Option<Box<Expression>>,
14981}
14982
14983/// StrToUnix
14984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14985#[cfg_attr(feature = "bindings", derive(TS))]
14986pub struct StrToUnix {
14987    #[serde(default)]
14988    pub this: Option<Box<Expression>>,
14989    #[serde(default)]
14990    pub format: Option<String>,
14991}
14992
14993/// StrToMap
14994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14995#[cfg_attr(feature = "bindings", derive(TS))]
14996pub struct StrToMap {
14997    pub this: Box<Expression>,
14998    #[serde(default)]
14999    pub pair_delim: Option<Box<Expression>>,
15000    #[serde(default)]
15001    pub key_value_delim: Option<Box<Expression>>,
15002    #[serde(default)]
15003    pub duplicate_resolution_callback: Option<Box<Expression>>,
15004}
15005
15006/// NumberToStr
15007#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15008#[cfg_attr(feature = "bindings", derive(TS))]
15009pub struct NumberToStr {
15010    pub this: Box<Expression>,
15011    pub format: String,
15012    #[serde(default)]
15013    pub culture: Option<Box<Expression>>,
15014}
15015
15016/// FromBase
15017#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15018#[cfg_attr(feature = "bindings", derive(TS))]
15019pub struct FromBase {
15020    pub this: Box<Expression>,
15021    pub expression: Box<Expression>,
15022}
15023
15024/// Stuff
15025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15026#[cfg_attr(feature = "bindings", derive(TS))]
15027pub struct Stuff {
15028    pub this: Box<Expression>,
15029    #[serde(default)]
15030    pub start: Option<Box<Expression>>,
15031    #[serde(default)]
15032    pub length: Option<i64>,
15033    pub expression: Box<Expression>,
15034}
15035
15036/// TimeToStr
15037#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15038#[cfg_attr(feature = "bindings", derive(TS))]
15039pub struct TimeToStr {
15040    pub this: Box<Expression>,
15041    pub format: String,
15042    #[serde(default)]
15043    pub culture: Option<Box<Expression>>,
15044    #[serde(default)]
15045    pub zone: Option<Box<Expression>>,
15046}
15047
15048/// TimeStrToTime
15049#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15050#[cfg_attr(feature = "bindings", derive(TS))]
15051pub struct TimeStrToTime {
15052    pub this: Box<Expression>,
15053    #[serde(default)]
15054    pub zone: Option<Box<Expression>>,
15055}
15056
15057/// TsOrDsAdd
15058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15059#[cfg_attr(feature = "bindings", derive(TS))]
15060pub struct TsOrDsAdd {
15061    pub this: Box<Expression>,
15062    pub expression: Box<Expression>,
15063    #[serde(default)]
15064    pub unit: Option<String>,
15065    #[serde(default)]
15066    pub return_type: Option<Box<Expression>>,
15067}
15068
15069/// TsOrDsDiff
15070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15071#[cfg_attr(feature = "bindings", derive(TS))]
15072pub struct TsOrDsDiff {
15073    pub this: Box<Expression>,
15074    pub expression: Box<Expression>,
15075    #[serde(default)]
15076    pub unit: Option<String>,
15077}
15078
15079/// TsOrDsToDate
15080#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15081#[cfg_attr(feature = "bindings", derive(TS))]
15082pub struct TsOrDsToDate {
15083    pub this: Box<Expression>,
15084    #[serde(default)]
15085    pub format: Option<String>,
15086    #[serde(default)]
15087    pub safe: Option<Box<Expression>>,
15088}
15089
15090/// TsOrDsToTime
15091#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15092#[cfg_attr(feature = "bindings", derive(TS))]
15093pub struct TsOrDsToTime {
15094    pub this: Box<Expression>,
15095    #[serde(default)]
15096    pub format: Option<String>,
15097    #[serde(default)]
15098    pub safe: Option<Box<Expression>>,
15099}
15100
15101/// Unhex
15102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15103#[cfg_attr(feature = "bindings", derive(TS))]
15104pub struct Unhex {
15105    pub this: Box<Expression>,
15106    #[serde(default)]
15107    pub expression: Option<Box<Expression>>,
15108}
15109
15110/// Uniform
15111#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15112#[cfg_attr(feature = "bindings", derive(TS))]
15113pub struct Uniform {
15114    pub this: Box<Expression>,
15115    pub expression: Box<Expression>,
15116    #[serde(default)]
15117    pub gen: Option<Box<Expression>>,
15118    #[serde(default)]
15119    pub seed: Option<Box<Expression>>,
15120}
15121
15122/// UnixToStr
15123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15124#[cfg_attr(feature = "bindings", derive(TS))]
15125pub struct UnixToStr {
15126    pub this: Box<Expression>,
15127    #[serde(default)]
15128    pub format: Option<String>,
15129}
15130
15131/// UnixToTime
15132#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15133#[cfg_attr(feature = "bindings", derive(TS))]
15134pub struct UnixToTime {
15135    pub this: Box<Expression>,
15136    #[serde(default)]
15137    pub scale: Option<i64>,
15138    #[serde(default)]
15139    pub zone: Option<Box<Expression>>,
15140    #[serde(default)]
15141    pub hours: Option<Box<Expression>>,
15142    #[serde(default)]
15143    pub minutes: Option<Box<Expression>>,
15144    #[serde(default)]
15145    pub format: Option<String>,
15146    #[serde(default)]
15147    pub target_type: Option<Box<Expression>>,
15148}
15149
15150/// Uuid
15151#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15152#[cfg_attr(feature = "bindings", derive(TS))]
15153pub struct Uuid {
15154    #[serde(default)]
15155    pub this: Option<Box<Expression>>,
15156    #[serde(default)]
15157    pub name: Option<String>,
15158    #[serde(default)]
15159    pub is_string: Option<Box<Expression>>,
15160}
15161
15162/// TimestampFromParts
15163#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15164#[cfg_attr(feature = "bindings", derive(TS))]
15165pub struct TimestampFromParts {
15166    #[serde(default)]
15167    pub zone: Option<Box<Expression>>,
15168    #[serde(default)]
15169    pub milli: Option<Box<Expression>>,
15170    #[serde(default)]
15171    pub this: Option<Box<Expression>>,
15172    #[serde(default)]
15173    pub expression: Option<Box<Expression>>,
15174}
15175
15176/// TimestampTzFromParts
15177#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15178#[cfg_attr(feature = "bindings", derive(TS))]
15179pub struct TimestampTzFromParts {
15180    #[serde(default)]
15181    pub zone: Option<Box<Expression>>,
15182}
15183
15184/// Corr
15185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15186#[cfg_attr(feature = "bindings", derive(TS))]
15187pub struct Corr {
15188    pub this: Box<Expression>,
15189    pub expression: Box<Expression>,
15190    #[serde(default)]
15191    pub null_on_zero_variance: Option<Box<Expression>>,
15192}
15193
15194/// WidthBucket
15195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15196#[cfg_attr(feature = "bindings", derive(TS))]
15197pub struct WidthBucket {
15198    pub this: Box<Expression>,
15199    #[serde(default)]
15200    pub min_value: Option<Box<Expression>>,
15201    #[serde(default)]
15202    pub max_value: Option<Box<Expression>>,
15203    #[serde(default)]
15204    pub num_buckets: Option<Box<Expression>>,
15205    #[serde(default)]
15206    pub threshold: Option<Box<Expression>>,
15207}
15208
15209/// CovarSamp
15210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15211#[cfg_attr(feature = "bindings", derive(TS))]
15212pub struct CovarSamp {
15213    pub this: Box<Expression>,
15214    pub expression: Box<Expression>,
15215}
15216
15217/// CovarPop
15218#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15219#[cfg_attr(feature = "bindings", derive(TS))]
15220pub struct CovarPop {
15221    pub this: Box<Expression>,
15222    pub expression: Box<Expression>,
15223}
15224
15225/// Week
15226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15227#[cfg_attr(feature = "bindings", derive(TS))]
15228pub struct Week {
15229    pub this: Box<Expression>,
15230    #[serde(default)]
15231    pub mode: Option<Box<Expression>>,
15232}
15233
15234/// XMLElement
15235#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15236#[cfg_attr(feature = "bindings", derive(TS))]
15237pub struct XMLElement {
15238    pub this: Box<Expression>,
15239    #[serde(default)]
15240    pub expressions: Vec<Expression>,
15241    #[serde(default)]
15242    pub evalname: Option<Box<Expression>>,
15243}
15244
15245/// XMLGet
15246#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15247#[cfg_attr(feature = "bindings", derive(TS))]
15248pub struct XMLGet {
15249    pub this: Box<Expression>,
15250    pub expression: Box<Expression>,
15251    #[serde(default)]
15252    pub instance: Option<Box<Expression>>,
15253}
15254
15255/// XMLTable
15256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15257#[cfg_attr(feature = "bindings", derive(TS))]
15258pub struct XMLTable {
15259    pub this: Box<Expression>,
15260    #[serde(default)]
15261    pub namespaces: Option<Box<Expression>>,
15262    #[serde(default)]
15263    pub passing: Option<Box<Expression>>,
15264    #[serde(default)]
15265    pub columns: Vec<Expression>,
15266    #[serde(default)]
15267    pub by_ref: Option<Box<Expression>>,
15268}
15269
15270/// XMLKeyValueOption
15271#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15272#[cfg_attr(feature = "bindings", derive(TS))]
15273pub struct XMLKeyValueOption {
15274    pub this: Box<Expression>,
15275    #[serde(default)]
15276    pub expression: Option<Box<Expression>>,
15277}
15278
15279/// Zipf
15280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15281#[cfg_attr(feature = "bindings", derive(TS))]
15282pub struct Zipf {
15283    pub this: Box<Expression>,
15284    #[serde(default)]
15285    pub elementcount: Option<Box<Expression>>,
15286    #[serde(default)]
15287    pub gen: Option<Box<Expression>>,
15288}
15289
15290/// Merge
15291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15292#[cfg_attr(feature = "bindings", derive(TS))]
15293pub struct Merge {
15294    pub this: Box<Expression>,
15295    pub using: Box<Expression>,
15296    #[serde(default)]
15297    pub on: Option<Box<Expression>>,
15298    #[serde(default)]
15299    pub using_cond: Option<Box<Expression>>,
15300    #[serde(default)]
15301    pub whens: Option<Box<Expression>>,
15302    #[serde(default)]
15303    pub with_: Option<Box<Expression>>,
15304    #[serde(default)]
15305    pub returning: Option<Box<Expression>>,
15306}
15307
15308/// When
15309#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15310#[cfg_attr(feature = "bindings", derive(TS))]
15311pub struct When {
15312    #[serde(default)]
15313    pub matched: Option<Box<Expression>>,
15314    #[serde(default)]
15315    pub source: Option<Box<Expression>>,
15316    #[serde(default)]
15317    pub condition: Option<Box<Expression>>,
15318    pub then: Box<Expression>,
15319}
15320
15321/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15323#[cfg_attr(feature = "bindings", derive(TS))]
15324pub struct Whens {
15325    #[serde(default)]
15326    pub expressions: Vec<Expression>,
15327}
15328
15329/// NextValueFor
15330#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15331#[cfg_attr(feature = "bindings", derive(TS))]
15332pub struct NextValueFor {
15333    pub this: Box<Expression>,
15334    #[serde(default)]
15335    pub order: Option<Box<Expression>>,
15336}
15337
15338#[cfg(test)]
15339mod tests {
15340    use super::*;
15341
15342    #[test]
15343    #[cfg(feature = "bindings")]
15344    fn export_typescript_types() {
15345        // This test exports TypeScript types to the generated directory
15346        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
15347        Expression::export_all(&ts_rs::Config::default())
15348            .expect("Failed to export Expression types");
15349
15350        let mut variant_names = String::from(
15351            "// This file was generated from the Rust Expression enum. Do not edit it manually.\n\n",
15352        );
15353        variant_names.push_str("export const EXPRESSION_VARIANT_NAMES = [\n");
15354        for name in Expression::SERIALIZED_VARIANT_NAMES {
15355            use std::fmt::Write;
15356            writeln!(variant_names, "  {name:?},").expect("writing to a String cannot fail");
15357        }
15358        variant_names.push_str("] as const;\n");
15359
15360        let output_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
15361            .join("bindings/ExpressionVariantNames.ts");
15362        std::fs::write(output_path, variant_names)
15363            .expect("Failed to export serialized Expression variant names");
15364    }
15365
15366    #[test]
15367    fn test_simple_select_builder() {
15368        let select = Select::new()
15369            .column(Expression::star())
15370            .from(Expression::Table(Box::new(TableRef::new("users"))));
15371
15372        assert_eq!(select.expressions.len(), 1);
15373        assert!(select.from.is_some());
15374    }
15375
15376    #[test]
15377    fn test_expression_alias() {
15378        let expr = Expression::column("id").alias("user_id");
15379
15380        match expr {
15381            Expression::Alias(a) => {
15382                assert_eq!(a.alias.name, "user_id");
15383            }
15384            _ => panic!("Expected Alias"),
15385        }
15386    }
15387
15388    #[test]
15389    fn test_literal_creation() {
15390        let num = Expression::number(42);
15391        let str = Expression::string("hello");
15392
15393        match num {
15394            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
15395                let Literal::Number(n) = lit.as_ref() else {
15396                    unreachable!()
15397                };
15398                assert_eq!(n, "42")
15399            }
15400            _ => panic!("Expected Number"),
15401        }
15402
15403        match str {
15404            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
15405                let Literal::String(s) = lit.as_ref() else {
15406                    unreachable!()
15407                };
15408                assert_eq!(s, "hello")
15409            }
15410            _ => panic!("Expected String"),
15411        }
15412    }
15413
15414    #[test]
15415    fn test_expression_sql() {
15416        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
15417        assert_eq!(expr.sql(), "SELECT 1 + 2");
15418    }
15419
15420    #[test]
15421    fn test_expression_sql_for() {
15422        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
15423        let sql = expr.sql_for(crate::DialectType::Generic);
15424        // Generic mode normalizes IF() to CASE WHEN
15425        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
15426    }
15427}