Skip to main content

polyglot_sql/
expressions.rs

1//! SQL Expression AST (Abstract Syntax Tree).
2//!
3//! This module defines all the AST node types used to represent parsed SQL
4//! statements and expressions. The design follows Python sqlglot's expression
5//! hierarchy, ported to a Rust enum-based AST.
6//!
7//! # Architecture
8//!
9//! The central type is [`Expression`], a large tagged enum with one variant per
10//! SQL construct. Inner structs carry the fields for each variant. Most
11//! heap-allocated variants are wrapped in `Box` to keep the enum size small.
12//!
13//! # Variant Groups
14//!
15//! | Group | Examples | Purpose |
16//! |---|---|---|
17//! | **Queries** | `Select`, `Union`, `Intersect`, `Except`, `Subquery` | Top-level query structures |
18//! | **DML** | `Insert`, `Update`, `Delete`, `Merge`, `Copy` | Data manipulation |
19//! | **DDL** | `CreateTable`, `AlterTable`, `DropView`, `CreateIndex` | Schema definition |
20//! | **Clauses** | `From`, `Join`, `Where`, `GroupBy`, `OrderBy`, `With` | Query clauses |
21//! | **Operators** | `And`, `Or`, `Add`, `Eq`, `Like`, `Not` | Binary and unary operations |
22//! | **Functions** | `Function`, `AggregateFunction`, `WindowFunction`, `Count`, `Sum` | Scalar, aggregate, and window functions |
23//! | **Literals** | `Literal`, `Boolean`, `Null`, `Interval` | Constant values |
24//! | **Types** | `DataType`, `Cast`, `TryCast`, `SafeCast` | Data types and casts |
25//! | **Identifiers** | `Identifier`, `Column`, `Table`, `Star` | Name references |
26//!
27//! # SQL Generation
28//!
29//! Every `Expression` can be rendered back to SQL via [`Expression::sql()`]
30//! (generic dialect) or [`Expression::sql_for()`] (specific dialect). The
31//! actual generation logic lives in the `generator` module.
32
33use crate::tokens::Span;
34use serde::{Deserialize, Serialize};
35use std::fmt;
36#[cfg(feature = "bindings")]
37use ts_rs::TS;
38
39/// Helper function for serde default value
40fn default_true() -> bool {
41    true
42}
43
44fn is_true(v: &bool) -> bool {
45    *v
46}
47
48/// Represent any SQL expression or statement as a single, recursive AST node.
49///
50/// `Expression` is the root type of the polyglot AST. Every parsed SQL
51/// construct -- from a simple integer literal to a multi-CTE query with
52/// window functions -- is represented as a variant of this enum.
53///
54/// Variants are organized into logical groups (see the module-level docs).
55/// Most non-trivial variants box their payload so that `size_of::<Expression>()`
56/// stays small (currently two words: tag + pointer).
57///
58/// # Constructing Expressions
59///
60/// Use the convenience constructors on `impl Expression` for common cases:
61///
62/// ```rust,ignore
63/// use polyglot_sql::expressions::Expression;
64///
65/// let col  = Expression::column("id");
66/// let lit  = Expression::number(42);
67/// let star = Expression::star();
68/// ```
69///
70/// # Generating SQL
71///
72/// ```rust,ignore
73/// let expr = Expression::column("name");
74/// assert_eq!(expr.sql(), "name");
75/// ```
76#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
77#[cfg_attr(feature = "bindings", derive(TS))]
78#[serde(rename_all = "snake_case")]
79#[cfg_attr(feature = "bindings", ts(export))]
80pub enum Expression {
81    // Literals
82    Literal(Box<Literal>),
83    Boolean(BooleanLiteral),
84    Null(Null),
85
86    // Identifiers
87    Identifier(Identifier),
88    Column(Box<Column>),
89    Table(Box<TableRef>),
90    Star(Star),
91    /// Snowflake braced wildcard syntax: {*}, {tbl.*}, {* EXCLUDE (...)}, {* ILIKE '...'}
92    BracedWildcard(Box<Expression>),
93
94    // Queries
95    Select(Box<Select>),
96    Union(Box<Union>),
97    Intersect(Box<Intersect>),
98    Except(Box<Except>),
99    Subquery(Box<Subquery>),
100    PipeOperator(Box<PipeOperator>),
101    Pivot(Box<Pivot>),
102    PivotAlias(Box<PivotAlias>),
103    Unpivot(Box<Unpivot>),
104    Values(Box<Values>),
105    PreWhere(Box<PreWhere>),
106    Stream(Box<Stream>),
107    UsingData(Box<UsingData>),
108    XmlNamespace(Box<XmlNamespace>),
109
110    // DML
111    Insert(Box<Insert>),
112    Update(Box<Update>),
113    Delete(Box<Delete>),
114    Copy(Box<CopyStmt>),
115    Put(Box<PutStmt>),
116    StageReference(Box<StageReference>),
117    TryCatch(Box<TryCatch>),
118
119    // Expressions
120    Alias(Box<Alias>),
121    Cast(Box<Cast>),
122    Collation(Box<CollationExpr>),
123    Case(Box<Case>),
124
125    // Binary operations
126    And(Box<BinaryOp>),
127    Or(Box<BinaryOp>),
128    Add(Box<BinaryOp>),
129    Sub(Box<BinaryOp>),
130    Mul(Box<BinaryOp>),
131    Div(Box<BinaryOp>),
132    Mod(Box<BinaryOp>),
133    Eq(Box<BinaryOp>),
134    Neq(Box<BinaryOp>),
135    Lt(Box<BinaryOp>),
136    Lte(Box<BinaryOp>),
137    Gt(Box<BinaryOp>),
138    Gte(Box<BinaryOp>),
139    Like(Box<LikeOp>),
140    ILike(Box<LikeOp>),
141    /// SQLite MATCH operator (FTS)
142    Match(Box<BinaryOp>),
143    BitwiseAnd(Box<BinaryOp>),
144    BitwiseOr(Box<BinaryOp>),
145    BitwiseXor(Box<BinaryOp>),
146    Concat(Box<BinaryOp>),
147    Adjacent(Box<BinaryOp>),   // PostgreSQL range adjacency operator (-|-)
148    TsMatch(Box<BinaryOp>),    // PostgreSQL text search match operator (@@)
149    PropertyEQ(Box<BinaryOp>), // := assignment operator (MySQL @var := val, DuckDB named args)
150
151    // PostgreSQL array/JSONB operators
152    ArrayContainsAll(Box<BinaryOp>), // @> operator (array contains all)
153    ArrayContainedBy(Box<BinaryOp>), // <@ operator (array contained by)
154    ArrayOverlaps(Box<BinaryOp>),    // && operator (array overlaps)
155    JSONBContainsAllTopKeys(Box<BinaryOp>), // ?& operator (JSONB contains all keys)
156    JSONBContainsAnyTopKeys(Box<BinaryOp>), // ?| operator (JSONB contains any key)
157    JSONBDeleteAtPath(Box<BinaryOp>), // #- operator (JSONB delete at path)
158    ExtendsLeft(Box<BinaryOp>),      // &< operator (PostgreSQL range extends left)
159    ExtendsRight(Box<BinaryOp>),     // &> operator (PostgreSQL range extends right)
160
161    // Unary operations
162    Not(Box<UnaryOp>),
163    Neg(Box<UnaryOp>),
164    BitwiseNot(Box<UnaryOp>),
165
166    // Predicates
167    In(Box<In>),
168    Between(Box<Between>),
169    IsNull(Box<IsNull>),
170    IsTrue(Box<IsTrueFalse>),
171    IsFalse(Box<IsTrueFalse>),
172    IsJson(Box<IsJson>),
173    Is(Box<BinaryOp>), // General IS expression (e.g., a IS ?)
174    Exists(Box<Exists>),
175    /// MySQL MEMBER OF operator: expr MEMBER OF(json_array)
176    MemberOf(Box<BinaryOp>),
177
178    // Functions
179    Function(Box<Function>),
180    AggregateFunction(Box<AggregateFunction>),
181    WindowFunction(Box<WindowFunction>),
182
183    // Clauses
184    From(Box<From>),
185    Join(Box<Join>),
186    JoinedTable(Box<JoinedTable>),
187    Where(Box<Where>),
188    GroupBy(Box<GroupBy>),
189    Having(Box<Having>),
190    OrderBy(Box<OrderBy>),
191    Limit(Box<Limit>),
192    Offset(Box<Offset>),
193    Qualify(Box<Qualify>),
194    With(Box<With>),
195    Cte(Box<Cte>),
196    DistributeBy(Box<DistributeBy>),
197    ClusterBy(Box<ClusterBy>),
198    SortBy(Box<SortBy>),
199    LateralView(Box<LateralView>),
200    Hint(Box<Hint>),
201    Pseudocolumn(Pseudocolumn),
202
203    // Oracle hierarchical queries (CONNECT BY)
204    Connect(Box<Connect>),
205    Prior(Box<Prior>),
206    ConnectByRoot(Box<ConnectByRoot>),
207
208    // Pattern matching (MATCH_RECOGNIZE)
209    MatchRecognize(Box<MatchRecognize>),
210
211    // Order expressions
212    Ordered(Box<Ordered>),
213
214    // Window specifications
215    Window(Box<WindowSpec>),
216    Over(Box<Over>),
217    WithinGroup(Box<WithinGroup>),
218
219    // Data types
220    DataType(DataType),
221
222    // Arrays and structs
223    Array(Box<Array>),
224    Struct(Box<Struct>),
225    Tuple(Box<Tuple>),
226
227    // Interval
228    Interval(Box<Interval>),
229
230    // String functions
231    ConcatWs(Box<ConcatWs>),
232    Substring(Box<SubstringFunc>),
233    Upper(Box<UnaryFunc>),
234    Lower(Box<UnaryFunc>),
235    Length(Box<UnaryFunc>),
236    Trim(Box<TrimFunc>),
237    LTrim(Box<UnaryFunc>),
238    RTrim(Box<UnaryFunc>),
239    Replace(Box<ReplaceFunc>),
240    Reverse(Box<UnaryFunc>),
241    Left(Box<LeftRightFunc>),
242    Right(Box<LeftRightFunc>),
243    Repeat(Box<RepeatFunc>),
244    Lpad(Box<PadFunc>),
245    Rpad(Box<PadFunc>),
246    Split(Box<SplitFunc>),
247    RegexpLike(Box<RegexpFunc>),
248    RegexpReplace(Box<RegexpReplaceFunc>),
249    RegexpExtract(Box<RegexpExtractFunc>),
250    Overlay(Box<OverlayFunc>),
251
252    // Math functions
253    Abs(Box<UnaryFunc>),
254    Round(Box<RoundFunc>),
255    Floor(Box<FloorFunc>),
256    Ceil(Box<CeilFunc>),
257    Power(Box<BinaryFunc>),
258    Sqrt(Box<UnaryFunc>),
259    Cbrt(Box<UnaryFunc>),
260    Ln(Box<UnaryFunc>),
261    Log(Box<LogFunc>),
262    Exp(Box<UnaryFunc>),
263    Sign(Box<UnaryFunc>),
264    Greatest(Box<VarArgFunc>),
265    Least(Box<VarArgFunc>),
266
267    // Date/time functions
268    CurrentDate(CurrentDate),
269    CurrentTime(CurrentTime),
270    CurrentTimestamp(CurrentTimestamp),
271    CurrentTimestampLTZ(CurrentTimestampLTZ),
272    AtTimeZone(Box<AtTimeZone>),
273    DateAdd(Box<DateAddFunc>),
274    DateSub(Box<DateAddFunc>),
275    DateDiff(Box<DateDiffFunc>),
276    DateTrunc(Box<DateTruncFunc>),
277    Extract(Box<ExtractFunc>),
278    ToDate(Box<ToDateFunc>),
279    ToTimestamp(Box<ToTimestampFunc>),
280    Date(Box<UnaryFunc>),
281    Time(Box<UnaryFunc>),
282    DateFromUnixDate(Box<UnaryFunc>),
283    UnixDate(Box<UnaryFunc>),
284    UnixSeconds(Box<UnaryFunc>),
285    UnixMillis(Box<UnaryFunc>),
286    UnixMicros(Box<UnaryFunc>),
287    UnixToTimeStr(Box<BinaryFunc>),
288    TimeStrToDate(Box<UnaryFunc>),
289    DateToDi(Box<UnaryFunc>),
290    DiToDate(Box<UnaryFunc>),
291    TsOrDiToDi(Box<UnaryFunc>),
292    TsOrDsToDatetime(Box<UnaryFunc>),
293    TsOrDsToTimestamp(Box<UnaryFunc>),
294    YearOfWeek(Box<UnaryFunc>),
295    YearOfWeekIso(Box<UnaryFunc>),
296
297    // Control flow functions
298    Coalesce(Box<VarArgFunc>),
299    NullIf(Box<BinaryFunc>),
300    IfFunc(Box<IfFunc>),
301    IfNull(Box<BinaryFunc>),
302    Nvl(Box<BinaryFunc>),
303    Nvl2(Box<Nvl2Func>),
304
305    // Type conversion
306    TryCast(Box<Cast>),
307    SafeCast(Box<Cast>),
308
309    // Typed aggregate functions
310    Count(Box<CountFunc>),
311    Sum(Box<AggFunc>),
312    Avg(Box<AggFunc>),
313    Min(Box<AggFunc>),
314    Max(Box<AggFunc>),
315    GroupConcat(Box<GroupConcatFunc>),
316    StringAgg(Box<StringAggFunc>),
317    ListAgg(Box<ListAggFunc>),
318    ArrayAgg(Box<AggFunc>),
319    CountIf(Box<AggFunc>),
320    SumIf(Box<SumIfFunc>),
321    Stddev(Box<AggFunc>),
322    StddevPop(Box<AggFunc>),
323    StddevSamp(Box<AggFunc>),
324    Variance(Box<AggFunc>),
325    VarPop(Box<AggFunc>),
326    VarSamp(Box<AggFunc>),
327    Median(Box<AggFunc>),
328    Mode(Box<AggFunc>),
329    First(Box<AggFunc>),
330    Last(Box<AggFunc>),
331    AnyValue(Box<AggFunc>),
332    ApproxDistinct(Box<AggFunc>),
333    ApproxCountDistinct(Box<AggFunc>),
334    ApproxPercentile(Box<ApproxPercentileFunc>),
335    Percentile(Box<PercentileFunc>),
336    LogicalAnd(Box<AggFunc>),
337    LogicalOr(Box<AggFunc>),
338    Skewness(Box<AggFunc>),
339    BitwiseCount(Box<UnaryFunc>),
340    ArrayConcatAgg(Box<AggFunc>),
341    ArrayUniqueAgg(Box<AggFunc>),
342    BoolXorAgg(Box<AggFunc>),
343
344    // Typed window functions
345    RowNumber(RowNumber),
346    Rank(Rank),
347    DenseRank(DenseRank),
348    NTile(Box<NTileFunc>),
349    Lead(Box<LeadLagFunc>),
350    Lag(Box<LeadLagFunc>),
351    FirstValue(Box<ValueFunc>),
352    LastValue(Box<ValueFunc>),
353    NthValue(Box<NthValueFunc>),
354    PercentRank(PercentRank),
355    CumeDist(CumeDist),
356    PercentileCont(Box<PercentileFunc>),
357    PercentileDisc(Box<PercentileFunc>),
358
359    // Additional string functions
360    Contains(Box<BinaryFunc>),
361    StartsWith(Box<BinaryFunc>),
362    EndsWith(Box<BinaryFunc>),
363    Position(Box<PositionFunc>),
364    Initcap(Box<UnaryFunc>),
365    Ascii(Box<UnaryFunc>),
366    Chr(Box<UnaryFunc>),
367    /// MySQL CHAR function with multiple args and optional USING charset
368    CharFunc(Box<CharFunc>),
369    Soundex(Box<UnaryFunc>),
370    Levenshtein(Box<BinaryFunc>),
371    ByteLength(Box<UnaryFunc>),
372    Hex(Box<UnaryFunc>),
373    LowerHex(Box<UnaryFunc>),
374    Unicode(Box<UnaryFunc>),
375
376    // Additional math functions
377    ModFunc(Box<BinaryFunc>),
378    Random(Random),
379    Rand(Box<Rand>),
380    TruncFunc(Box<TruncateFunc>),
381    Pi(Pi),
382    Radians(Box<UnaryFunc>),
383    Degrees(Box<UnaryFunc>),
384    Sin(Box<UnaryFunc>),
385    Cos(Box<UnaryFunc>),
386    Tan(Box<UnaryFunc>),
387    Asin(Box<UnaryFunc>),
388    Acos(Box<UnaryFunc>),
389    Atan(Box<UnaryFunc>),
390    Atan2(Box<BinaryFunc>),
391    IsNan(Box<UnaryFunc>),
392    IsInf(Box<UnaryFunc>),
393    IntDiv(Box<BinaryFunc>),
394
395    // Control flow
396    Decode(Box<DecodeFunc>),
397
398    // Additional date/time functions
399    DateFormat(Box<DateFormatFunc>),
400    FormatDate(Box<DateFormatFunc>),
401    Year(Box<UnaryFunc>),
402    Month(Box<UnaryFunc>),
403    Day(Box<UnaryFunc>),
404    Hour(Box<UnaryFunc>),
405    Minute(Box<UnaryFunc>),
406    Second(Box<UnaryFunc>),
407    DayOfWeek(Box<UnaryFunc>),
408    DayOfWeekIso(Box<UnaryFunc>),
409    DayOfMonth(Box<UnaryFunc>),
410    DayOfYear(Box<UnaryFunc>),
411    WeekOfYear(Box<UnaryFunc>),
412    Quarter(Box<UnaryFunc>),
413    AddMonths(Box<BinaryFunc>),
414    MonthsBetween(Box<BinaryFunc>),
415    LastDay(Box<LastDayFunc>),
416    NextDay(Box<BinaryFunc>),
417    Epoch(Box<UnaryFunc>),
418    EpochMs(Box<UnaryFunc>),
419    FromUnixtime(Box<FromUnixtimeFunc>),
420    UnixTimestamp(Box<UnixTimestampFunc>),
421    MakeDate(Box<MakeDateFunc>),
422    MakeTimestamp(Box<MakeTimestampFunc>),
423    TimestampTrunc(Box<DateTruncFunc>),
424    TimeStrToUnix(Box<UnaryFunc>),
425
426    // Session/User functions
427    SessionUser(SessionUser),
428
429    // Hash/Crypto functions
430    SHA(Box<UnaryFunc>),
431    SHA1Digest(Box<UnaryFunc>),
432
433    // Time conversion functions
434    TimeToUnix(Box<UnaryFunc>),
435
436    // Array functions
437    ArrayFunc(Box<ArrayConstructor>),
438    ArrayLength(Box<UnaryFunc>),
439    ArraySize(Box<UnaryFunc>),
440    Cardinality(Box<UnaryFunc>),
441    ArrayContains(Box<BinaryFunc>),
442    ArrayPosition(Box<BinaryFunc>),
443    ArrayAppend(Box<BinaryFunc>),
444    ArrayPrepend(Box<BinaryFunc>),
445    ArrayConcat(Box<VarArgFunc>),
446    ArraySort(Box<ArraySortFunc>),
447    ArrayReverse(Box<UnaryFunc>),
448    ArrayDistinct(Box<UnaryFunc>),
449    ArrayJoin(Box<ArrayJoinFunc>),
450    ArrayToString(Box<ArrayJoinFunc>),
451    Unnest(Box<UnnestFunc>),
452    Explode(Box<UnaryFunc>),
453    ExplodeOuter(Box<UnaryFunc>),
454    ArrayFilter(Box<ArrayFilterFunc>),
455    ArrayTransform(Box<ArrayTransformFunc>),
456    ArrayFlatten(Box<UnaryFunc>),
457    ArrayCompact(Box<UnaryFunc>),
458    ArrayIntersect(Box<VarArgFunc>),
459    ArrayUnion(Box<BinaryFunc>),
460    ArrayExcept(Box<BinaryFunc>),
461    ArrayRemove(Box<BinaryFunc>),
462    ArrayZip(Box<VarArgFunc>),
463    Sequence(Box<SequenceFunc>),
464    Generate(Box<SequenceFunc>),
465    ExplodingGenerateSeries(Box<SequenceFunc>),
466    ToArray(Box<UnaryFunc>),
467    StarMap(Box<BinaryFunc>),
468
469    // Struct functions
470    StructFunc(Box<StructConstructor>),
471    StructExtract(Box<StructExtractFunc>),
472    NamedStruct(Box<NamedStructFunc>),
473
474    // Map functions
475    MapFunc(Box<MapConstructor>),
476    MapFromEntries(Box<UnaryFunc>),
477    MapFromArrays(Box<BinaryFunc>),
478    MapKeys(Box<UnaryFunc>),
479    MapValues(Box<UnaryFunc>),
480    MapContainsKey(Box<BinaryFunc>),
481    MapConcat(Box<VarArgFunc>),
482    ElementAt(Box<BinaryFunc>),
483    TransformKeys(Box<TransformFunc>),
484    TransformValues(Box<TransformFunc>),
485
486    // Exasol: function call with EMITS clause
487    FunctionEmits(Box<FunctionEmits>),
488
489    // JSON functions
490    JsonExtract(Box<JsonExtractFunc>),
491    JsonExtractScalar(Box<JsonExtractFunc>),
492    JsonExtractPath(Box<JsonPathFunc>),
493    JsonArray(Box<VarArgFunc>),
494    JsonObject(Box<JsonObjectFunc>),
495    JsonQuery(Box<JsonExtractFunc>),
496    JsonValue(Box<JsonExtractFunc>),
497    JsonArrayLength(Box<UnaryFunc>),
498    JsonKeys(Box<UnaryFunc>),
499    JsonType(Box<UnaryFunc>),
500    ParseJson(Box<UnaryFunc>),
501    ToJson(Box<UnaryFunc>),
502    JsonSet(Box<JsonModifyFunc>),
503    JsonInsert(Box<JsonModifyFunc>),
504    JsonRemove(Box<JsonPathFunc>),
505    JsonMergePatch(Box<BinaryFunc>),
506    JsonArrayAgg(Box<JsonArrayAggFunc>),
507    JsonObjectAgg(Box<JsonObjectAggFunc>),
508
509    // Type casting/conversion
510    Convert(Box<ConvertFunc>),
511    Typeof(Box<UnaryFunc>),
512
513    // Additional expressions
514    Lambda(Box<LambdaExpr>),
515    Parameter(Box<Parameter>),
516    Placeholder(Placeholder),
517    NamedArgument(Box<NamedArgument>),
518    /// TABLE ref or MODEL ref used as a function argument (BigQuery)
519    /// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
520    TableArgument(Box<TableArgument>),
521    SqlComment(Box<SqlComment>),
522
523    // Additional predicates
524    NullSafeEq(Box<BinaryOp>),
525    NullSafeNeq(Box<BinaryOp>),
526    Glob(Box<BinaryOp>),
527    SimilarTo(Box<SimilarToExpr>),
528    Any(Box<QuantifiedExpr>),
529    All(Box<QuantifiedExpr>),
530    Overlaps(Box<OverlapsExpr>),
531
532    // Bitwise operations
533    BitwiseLeftShift(Box<BinaryOp>),
534    BitwiseRightShift(Box<BinaryOp>),
535    BitwiseAndAgg(Box<AggFunc>),
536    BitwiseOrAgg(Box<AggFunc>),
537    BitwiseXorAgg(Box<AggFunc>),
538
539    // Array/struct/map access
540    Subscript(Box<Subscript>),
541    Dot(Box<DotAccess>),
542    MethodCall(Box<MethodCall>),
543    ArraySlice(Box<ArraySlice>),
544
545    // DDL statements
546    CreateTable(Box<CreateTable>),
547    DropTable(Box<DropTable>),
548    Undrop(Box<Undrop>),
549    AlterTable(Box<AlterTable>),
550    SplitTable(Box<SplitTable>),
551    FlashbackTable(Box<FlashbackTable>),
552    CreateIndex(Box<CreateIndex>),
553    DropIndex(Box<DropIndex>),
554    CreateView(Box<CreateView>),
555    DropView(Box<DropView>),
556    AlterView(Box<AlterView>),
557    AlterIndex(Box<AlterIndex>),
558    Truncate(Box<Truncate>),
559    Use(Box<Use>),
560    Cache(Box<Cache>),
561    Uncache(Box<Uncache>),
562    LoadData(Box<LoadData>),
563    Pragma(Box<Pragma>),
564    Grant(Box<Grant>),
565    Revoke(Box<Revoke>),
566    Comment(Box<Comment>),
567    SetStatement(Box<SetStatement>),
568    // Phase 4: Additional DDL statements
569    CreateSchema(Box<CreateSchema>),
570    DropSchema(Box<DropSchema>),
571    DropNamespace(Box<DropNamespace>),
572    CreateDatabase(Box<CreateDatabase>),
573    DropDatabase(Box<DropDatabase>),
574    CreateFunction(Box<CreateFunction>),
575    DropFunction(Box<DropFunction>),
576    CreateProcedure(Box<CreateProcedure>),
577    DropProcedure(Box<DropProcedure>),
578    CreateSequence(Box<CreateSequence>),
579    CreateSynonym(Box<CreateSynonym>),
580    DropSequence(Box<DropSequence>),
581    AlterSequence(Box<AlterSequence>),
582    CreateTrigger(Box<CreateTrigger>),
583    DropTrigger(Box<DropTrigger>),
584    CreateType(Box<CreateType>),
585    DropType(Box<DropType>),
586    Describe(Box<Describe>),
587    Show(Box<Show>),
588
589    // Transaction and other commands
590    Command(Box<Command>),
591    Kill(Box<Kill>),
592    /// PREPARE statement (PostgreSQL/generic prepared statement definition)
593    Prepare(Box<PrepareStatement>),
594    /// EXEC/EXECUTE statement (TSQL stored procedure call)
595    Execute(Box<ExecuteStatement>),
596
597    /// Snowflake CREATE TASK statement
598    CreateTask(Box<CreateTask>),
599
600    // Placeholder for unparsed/raw SQL
601    Raw(Raw),
602
603    // Paren for grouping
604    Paren(Box<Paren>),
605
606    // Expression with trailing comments (for round-trip preservation)
607    Annotated(Box<Annotated>),
608
609    // === BATCH GENERATED EXPRESSION TYPES ===
610    // Generated from Python sqlglot expressions.py
611    Refresh(Box<Refresh>),
612    LockingStatement(Box<LockingStatement>),
613    SequenceProperties(Box<SequenceProperties>),
614    TruncateTable(Box<TruncateTable>),
615    Clone(Box<Clone>),
616    Attach(Box<Attach>),
617    Detach(Box<Detach>),
618    Install(Box<Install>),
619    Summarize(Box<Summarize>),
620    Declare(Box<Declare>),
621    DeclareItem(Box<DeclareItem>),
622    Set(Box<Set>),
623    Heredoc(Box<Heredoc>),
624    SetItem(Box<SetItem>),
625    QueryBand(Box<QueryBand>),
626    UserDefinedFunction(Box<UserDefinedFunction>),
627    RecursiveWithSearch(Box<RecursiveWithSearch>),
628    ProjectionDef(Box<ProjectionDef>),
629    TableAlias(Box<TableAlias>),
630    ByteString(Box<ByteString>),
631    HexStringExpr(Box<HexStringExpr>),
632    UnicodeString(Box<UnicodeString>),
633    ColumnPosition(Box<ColumnPosition>),
634    ColumnDef(Box<ColumnDef>),
635    AlterColumn(Box<AlterColumn>),
636    AlterSortKey(Box<AlterSortKey>),
637    AlterSet(Box<AlterSet>),
638    RenameColumn(Box<RenameColumn>),
639    Comprehension(Box<Comprehension>),
640    MergeTreeTTLAction(Box<MergeTreeTTLAction>),
641    MergeTreeTTL(Box<MergeTreeTTL>),
642    IndexConstraintOption(Box<IndexConstraintOption>),
643    ColumnConstraint(Box<ColumnConstraint>),
644    PeriodForSystemTimeConstraint(Box<PeriodForSystemTimeConstraint>),
645    CaseSpecificColumnConstraint(Box<CaseSpecificColumnConstraint>),
646    CharacterSetColumnConstraint(Box<CharacterSetColumnConstraint>),
647    CheckColumnConstraint(Box<CheckColumnConstraint>),
648    AssumeColumnConstraint(Box<AssumeColumnConstraint>),
649    CompressColumnConstraint(Box<CompressColumnConstraint>),
650    DateFormatColumnConstraint(Box<DateFormatColumnConstraint>),
651    EphemeralColumnConstraint(Box<EphemeralColumnConstraint>),
652    WithOperator(Box<WithOperator>),
653    GeneratedAsIdentityColumnConstraint(Box<GeneratedAsIdentityColumnConstraint>),
654    AutoIncrementColumnConstraint(AutoIncrementColumnConstraint),
655    CommentColumnConstraint(CommentColumnConstraint),
656    GeneratedAsRowColumnConstraint(Box<GeneratedAsRowColumnConstraint>),
657    IndexColumnConstraint(Box<IndexColumnConstraint>),
658    MaskingPolicyColumnConstraint(Box<MaskingPolicyColumnConstraint>),
659    NotNullColumnConstraint(Box<NotNullColumnConstraint>),
660    PrimaryKeyColumnConstraint(Box<PrimaryKeyColumnConstraint>),
661    UniqueColumnConstraint(Box<UniqueColumnConstraint>),
662    WatermarkColumnConstraint(Box<WatermarkColumnConstraint>),
663    ComputedColumnConstraint(Box<ComputedColumnConstraint>),
664    InOutColumnConstraint(Box<InOutColumnConstraint>),
665    DefaultColumnConstraint(Box<DefaultColumnConstraint>),
666    PathColumnConstraint(Box<PathColumnConstraint>),
667    Constraint(Box<Constraint>),
668    Export(Box<Export>),
669    Filter(Box<Filter>),
670    Changes(Box<Changes>),
671    CopyParameter(Box<CopyParameter>),
672    Credentials(Box<Credentials>),
673    Directory(Box<Directory>),
674    ForeignKey(Box<ForeignKey>),
675    ColumnPrefix(Box<ColumnPrefix>),
676    PrimaryKey(Box<PrimaryKey>),
677    IntoClause(Box<IntoClause>),
678    JoinHint(Box<JoinHint>),
679    Opclass(Box<Opclass>),
680    Index(Box<Index>),
681    IndexParameters(Box<IndexParameters>),
682    ConditionalInsert(Box<ConditionalInsert>),
683    MultitableInserts(Box<MultitableInserts>),
684    OnConflict(Box<OnConflict>),
685    OnCondition(Box<OnCondition>),
686    Returning(Box<Returning>),
687    Introducer(Box<Introducer>),
688    PartitionRange(Box<PartitionRange>),
689    Fetch(Box<Fetch>),
690    Group(Box<Group>),
691    Cube(Box<Cube>),
692    Rollup(Box<Rollup>),
693    GroupingSets(Box<GroupingSets>),
694    LimitOptions(Box<LimitOptions>),
695    Lateral(Box<Lateral>),
696    TableFromRows(Box<TableFromRows>),
697    RowsFrom(Box<RowsFrom>),
698    MatchRecognizeMeasure(Box<MatchRecognizeMeasure>),
699    WithFill(Box<WithFill>),
700    Property(Box<Property>),
701    GrantPrivilege(Box<GrantPrivilege>),
702    GrantPrincipal(Box<GrantPrincipal>),
703    AllowedValuesProperty(Box<AllowedValuesProperty>),
704    AlgorithmProperty(Box<AlgorithmProperty>),
705    AutoIncrementProperty(Box<AutoIncrementProperty>),
706    AutoRefreshProperty(Box<AutoRefreshProperty>),
707    BackupProperty(Box<BackupProperty>),
708    BuildProperty(Box<BuildProperty>),
709    BlockCompressionProperty(Box<BlockCompressionProperty>),
710    CharacterSetProperty(Box<CharacterSetProperty>),
711    ChecksumProperty(Box<ChecksumProperty>),
712    CollateProperty(Box<CollateProperty>),
713    DataBlocksizeProperty(Box<DataBlocksizeProperty>),
714    DataDeletionProperty(Box<DataDeletionProperty>),
715    DefinerProperty(Box<DefinerProperty>),
716    DistKeyProperty(Box<DistKeyProperty>),
717    DistributedByProperty(Box<DistributedByProperty>),
718    DistStyleProperty(Box<DistStyleProperty>),
719    DuplicateKeyProperty(Box<DuplicateKeyProperty>),
720    EngineProperty(Box<EngineProperty>),
721    ToTableProperty(Box<ToTableProperty>),
722    ExecuteAsProperty(Box<ExecuteAsProperty>),
723    ExternalProperty(Box<ExternalProperty>),
724    FallbackProperty(Box<FallbackProperty>),
725    FileFormatProperty(Box<FileFormatProperty>),
726    CredentialsProperty(Box<CredentialsProperty>),
727    FreespaceProperty(Box<FreespaceProperty>),
728    InheritsProperty(Box<InheritsProperty>),
729    InputModelProperty(Box<InputModelProperty>),
730    OutputModelProperty(Box<OutputModelProperty>),
731    IsolatedLoadingProperty(Box<IsolatedLoadingProperty>),
732    JournalProperty(Box<JournalProperty>),
733    LanguageProperty(Box<LanguageProperty>),
734    EnviromentProperty(Box<EnviromentProperty>),
735    ClusteredByProperty(Box<ClusteredByProperty>),
736    DictProperty(Box<DictProperty>),
737    DictRange(Box<DictRange>),
738    OnCluster(Box<OnCluster>),
739    LikeProperty(Box<LikeProperty>),
740    LocationProperty(Box<LocationProperty>),
741    LockProperty(Box<LockProperty>),
742    LockingProperty(Box<LockingProperty>),
743    LogProperty(Box<LogProperty>),
744    MaterializedProperty(Box<MaterializedProperty>),
745    MergeBlockRatioProperty(Box<MergeBlockRatioProperty>),
746    OnProperty(Box<OnProperty>),
747    OnCommitProperty(Box<OnCommitProperty>),
748    PartitionedByProperty(Box<PartitionedByProperty>),
749    PartitionByProperty(Box<PartitionByProperty>),
750    PartitionedByBucket(Box<PartitionedByBucket>),
751    ClusterByColumnsProperty(Box<ClusterByColumnsProperty>),
752    PartitionByTruncate(Box<PartitionByTruncate>),
753    PartitionByRangeProperty(Box<PartitionByRangeProperty>),
754    PartitionByRangePropertyDynamic(Box<PartitionByRangePropertyDynamic>),
755    PartitionByListProperty(Box<PartitionByListProperty>),
756    PartitionList(Box<PartitionList>),
757    Partition(Box<Partition>),
758    RefreshTriggerProperty(Box<RefreshTriggerProperty>),
759    UniqueKeyProperty(Box<UniqueKeyProperty>),
760    RollupProperty(Box<RollupProperty>),
761    PartitionBoundSpec(Box<PartitionBoundSpec>),
762    PartitionedOfProperty(Box<PartitionedOfProperty>),
763    RemoteWithConnectionModelProperty(Box<RemoteWithConnectionModelProperty>),
764    ReturnsProperty(Box<ReturnsProperty>),
765    RowFormatProperty(Box<RowFormatProperty>),
766    RowFormatDelimitedProperty(Box<RowFormatDelimitedProperty>),
767    RowFormatSerdeProperty(Box<RowFormatSerdeProperty>),
768    QueryTransform(Box<QueryTransform>),
769    SampleProperty(Box<SampleProperty>),
770    SecurityProperty(Box<SecurityProperty>),
771    SchemaCommentProperty(Box<SchemaCommentProperty>),
772    SemanticView(Box<SemanticView>),
773    SerdeProperties(Box<SerdeProperties>),
774    SetProperty(Box<SetProperty>),
775    SharingProperty(Box<SharingProperty>),
776    SetConfigProperty(Box<SetConfigProperty>),
777    SettingsProperty(Box<SettingsProperty>),
778    SortKeyProperty(Box<SortKeyProperty>),
779    SqlReadWriteProperty(Box<SqlReadWriteProperty>),
780    SqlSecurityProperty(Box<SqlSecurityProperty>),
781    StabilityProperty(Box<StabilityProperty>),
782    StorageHandlerProperty(Box<StorageHandlerProperty>),
783    TemporaryProperty(Box<TemporaryProperty>),
784    Tags(Box<Tags>),
785    TransformModelProperty(Box<TransformModelProperty>),
786    TransientProperty(Box<TransientProperty>),
787    UsingTemplateProperty(Box<UsingTemplateProperty>),
788    ViewAttributeProperty(Box<ViewAttributeProperty>),
789    VolatileProperty(Box<VolatileProperty>),
790    WithDataProperty(Box<WithDataProperty>),
791    WithJournalTableProperty(Box<WithJournalTableProperty>),
792    WithSchemaBindingProperty(Box<WithSchemaBindingProperty>),
793    WithSystemVersioningProperty(Box<WithSystemVersioningProperty>),
794    WithProcedureOptions(Box<WithProcedureOptions>),
795    EncodeProperty(Box<EncodeProperty>),
796    IncludeProperty(Box<IncludeProperty>),
797    Properties(Box<Properties>),
798    OptionsProperty(Box<OptionsProperty>),
799    InputOutputFormat(Box<InputOutputFormat>),
800    Reference(Box<Reference>),
801    QueryOption(Box<QueryOption>),
802    WithTableHint(Box<WithTableHint>),
803    IndexTableHint(Box<IndexTableHint>),
804    HistoricalData(Box<HistoricalData>),
805    Get(Box<Get>),
806    SetOperation(Box<SetOperation>),
807    Var(Box<Var>),
808    Variadic(Box<Variadic>),
809    Version(Box<Version>),
810    Schema(Box<Schema>),
811    Lock(Box<Lock>),
812    TableSample(Box<TableSample>),
813    Tag(Box<Tag>),
814    UnpivotColumns(Box<UnpivotColumns>),
815    WindowSpec(Box<WindowSpec>),
816    SessionParameter(Box<SessionParameter>),
817    PseudoType(Box<PseudoType>),
818    ObjectIdentifier(Box<ObjectIdentifier>),
819    Transaction(Box<Transaction>),
820    Commit(Box<Commit>),
821    Rollback(Box<Rollback>),
822    AlterSession(Box<AlterSession>),
823    Analyze(Box<Analyze>),
824    AnalyzeStatistics(Box<AnalyzeStatistics>),
825    AnalyzeHistogram(Box<AnalyzeHistogram>),
826    AnalyzeSample(Box<AnalyzeSample>),
827    AnalyzeListChainedRows(Box<AnalyzeListChainedRows>),
828    AnalyzeDelete(Box<AnalyzeDelete>),
829    AnalyzeWith(Box<AnalyzeWith>),
830    AnalyzeValidate(Box<AnalyzeValidate>),
831    AddPartition(Box<AddPartition>),
832    AttachOption(Box<AttachOption>),
833    DropPartition(Box<DropPartition>),
834    ReplacePartition(Box<ReplacePartition>),
835    DPipe(Box<DPipe>),
836    Operator(Box<Operator>),
837    PivotAny(Box<PivotAny>),
838    Aliases(Box<Aliases>),
839    AtIndex(Box<AtIndex>),
840    FromTimeZone(Box<FromTimeZone>),
841    FormatPhrase(Box<FormatPhrase>),
842    ForIn(Box<ForIn>),
843    TimeUnit(Box<TimeUnit>),
844    IntervalOp(Box<IntervalOp>),
845    IntervalSpan(Box<IntervalSpan>),
846    HavingMax(Box<HavingMax>),
847    CosineDistance(Box<CosineDistance>),
848    DotProduct(Box<DotProduct>),
849    EuclideanDistance(Box<EuclideanDistance>),
850    ManhattanDistance(Box<ManhattanDistance>),
851    JarowinklerSimilarity(Box<JarowinklerSimilarity>),
852    Booland(Box<Booland>),
853    Boolor(Box<Boolor>),
854    ParameterizedAgg(Box<ParameterizedAgg>),
855    ArgMax(Box<ArgMax>),
856    ArgMin(Box<ArgMin>),
857    ApproxTopK(Box<ApproxTopK>),
858    ApproxTopKAccumulate(Box<ApproxTopKAccumulate>),
859    ApproxTopKCombine(Box<ApproxTopKCombine>),
860    ApproxTopKEstimate(Box<ApproxTopKEstimate>),
861    ApproxTopSum(Box<ApproxTopSum>),
862    ApproxQuantiles(Box<ApproxQuantiles>),
863    Minhash(Box<Minhash>),
864    FarmFingerprint(Box<FarmFingerprint>),
865    Float64(Box<Float64>),
866    Transform(Box<Transform>),
867    Translate(Box<Translate>),
868    Grouping(Box<Grouping>),
869    GroupingId(Box<GroupingId>),
870    Anonymous(Box<Anonymous>),
871    AnonymousAggFunc(Box<AnonymousAggFunc>),
872    CombinedAggFunc(Box<CombinedAggFunc>),
873    CombinedParameterizedAgg(Box<CombinedParameterizedAgg>),
874    HashAgg(Box<HashAgg>),
875    Hll(Box<Hll>),
876    Apply(Box<Apply>),
877    ToBoolean(Box<ToBoolean>),
878    List(Box<List>),
879    ToMap(Box<ToMap>),
880    Pad(Box<Pad>),
881    ToChar(Box<ToChar>),
882    ToNumber(Box<ToNumber>),
883    ToDouble(Box<ToDouble>),
884    Int64(Box<UnaryFunc>),
885    StringFunc(Box<StringFunc>),
886    ToDecfloat(Box<ToDecfloat>),
887    TryToDecfloat(Box<TryToDecfloat>),
888    ToFile(Box<ToFile>),
889    Columns(Box<Columns>),
890    ConvertToCharset(Box<ConvertToCharset>),
891    ConvertTimezone(Box<ConvertTimezone>),
892    GenerateSeries(Box<GenerateSeries>),
893    AIAgg(Box<AIAgg>),
894    AIClassify(Box<AIClassify>),
895    ArrayAll(Box<ArrayAll>),
896    ArrayAny(Box<ArrayAny>),
897    ArrayConstructCompact(Box<ArrayConstructCompact>),
898    StPoint(Box<StPoint>),
899    StDistance(Box<StDistance>),
900    StringToArray(Box<StringToArray>),
901    ArraySum(Box<ArraySum>),
902    ObjectAgg(Box<ObjectAgg>),
903    CastToStrType(Box<CastToStrType>),
904    CheckJson(Box<CheckJson>),
905    CheckXml(Box<CheckXml>),
906    TranslateCharacters(Box<TranslateCharacters>),
907    CurrentSchemas(Box<CurrentSchemas>),
908    CurrentDatetime(Box<CurrentDatetime>),
909    Localtime(Box<Localtime>),
910    Localtimestamp(Box<Localtimestamp>),
911    Systimestamp(Box<Systimestamp>),
912    CurrentSchema(Box<CurrentSchema>),
913    CurrentUser(Box<CurrentUser>),
914    UtcTime(Box<UtcTime>),
915    UtcTimestamp(Box<UtcTimestamp>),
916    Timestamp(Box<TimestampFunc>),
917    DateBin(Box<DateBin>),
918    Datetime(Box<Datetime>),
919    DatetimeAdd(Box<DatetimeAdd>),
920    DatetimeSub(Box<DatetimeSub>),
921    DatetimeDiff(Box<DatetimeDiff>),
922    DatetimeTrunc(Box<DatetimeTrunc>),
923    Dayname(Box<Dayname>),
924    MakeInterval(Box<MakeInterval>),
925    PreviousDay(Box<PreviousDay>),
926    Elt(Box<Elt>),
927    TimestampAdd(Box<TimestampAdd>),
928    TimestampSub(Box<TimestampSub>),
929    TimestampDiff(Box<TimestampDiff>),
930    TimeSlice(Box<TimeSlice>),
931    TimeAdd(Box<TimeAdd>),
932    TimeSub(Box<TimeSub>),
933    TimeDiff(Box<TimeDiff>),
934    TimeTrunc(Box<TimeTrunc>),
935    DateFromParts(Box<DateFromParts>),
936    TimeFromParts(Box<TimeFromParts>),
937    DecodeCase(Box<DecodeCase>),
938    Decrypt(Box<Decrypt>),
939    DecryptRaw(Box<DecryptRaw>),
940    Encode(Box<Encode>),
941    Encrypt(Box<Encrypt>),
942    EncryptRaw(Box<EncryptRaw>),
943    EqualNull(Box<EqualNull>),
944    ToBinary(Box<ToBinary>),
945    Base64DecodeBinary(Box<Base64DecodeBinary>),
946    Base64DecodeString(Box<Base64DecodeString>),
947    Base64Encode(Box<Base64Encode>),
948    TryBase64DecodeBinary(Box<TryBase64DecodeBinary>),
949    TryBase64DecodeString(Box<TryBase64DecodeString>),
950    GapFill(Box<GapFill>),
951    GenerateDateArray(Box<GenerateDateArray>),
952    GenerateTimestampArray(Box<GenerateTimestampArray>),
953    GetExtract(Box<GetExtract>),
954    Getbit(Box<Getbit>),
955    OverflowTruncateBehavior(Box<OverflowTruncateBehavior>),
956    HexEncode(Box<HexEncode>),
957    Compress(Box<Compress>),
958    DecompressBinary(Box<DecompressBinary>),
959    DecompressString(Box<DecompressString>),
960    Xor(Box<Xor>),
961    Nullif(Box<Nullif>),
962    JSON(Box<JSON>),
963    JSONPath(Box<JSONPath>),
964    JSONPathFilter(Box<JSONPathFilter>),
965    JSONPathKey(Box<JSONPathKey>),
966    JSONPathRecursive(Box<JSONPathRecursive>),
967    JSONPathScript(Box<JSONPathScript>),
968    JSONPathSlice(Box<JSONPathSlice>),
969    JSONPathSelector(Box<JSONPathSelector>),
970    JSONPathSubscript(Box<JSONPathSubscript>),
971    JSONPathUnion(Box<JSONPathUnion>),
972    Format(Box<Format>),
973    JSONKeys(Box<JSONKeys>),
974    JSONKeyValue(Box<JSONKeyValue>),
975    JSONKeysAtDepth(Box<JSONKeysAtDepth>),
976    JSONObject(Box<JSONObject>),
977    JSONObjectAgg(Box<JSONObjectAgg>),
978    JSONBObjectAgg(Box<JSONBObjectAgg>),
979    JSONArray(Box<JSONArray>),
980    JSONArrayAgg(Box<JSONArrayAgg>),
981    JSONExists(Box<JSONExists>),
982    JSONColumnDef(Box<JSONColumnDef>),
983    JSONSchema(Box<JSONSchema>),
984    JSONSet(Box<JSONSet>),
985    JSONStripNulls(Box<JSONStripNulls>),
986    JSONValue(Box<JSONValue>),
987    JSONValueArray(Box<JSONValueArray>),
988    JSONRemove(Box<JSONRemove>),
989    JSONTable(Box<JSONTable>),
990    JSONType(Box<JSONType>),
991    ObjectInsert(Box<ObjectInsert>),
992    OpenJSONColumnDef(Box<OpenJSONColumnDef>),
993    OpenJSON(Box<OpenJSON>),
994    JSONBExists(Box<JSONBExists>),
995    JSONBContains(Box<BinaryFunc>),
996    JSONBExtract(Box<BinaryFunc>),
997    JSONCast(Box<JSONCast>),
998    JSONExtract(Box<JSONExtract>),
999    JSONExtractQuote(Box<JSONExtractQuote>),
1000    JSONExtractArray(Box<JSONExtractArray>),
1001    JSONExtractScalar(Box<JSONExtractScalar>),
1002    JSONBExtractScalar(Box<JSONBExtractScalar>),
1003    JSONFormat(Box<JSONFormat>),
1004    JSONBool(Box<UnaryFunc>),
1005    JSONPathRoot(JSONPathRoot),
1006    JSONArrayAppend(Box<JSONArrayAppend>),
1007    JSONArrayContains(Box<JSONArrayContains>),
1008    JSONArrayInsert(Box<JSONArrayInsert>),
1009    ParseJSON(Box<ParseJSON>),
1010    ParseUrl(Box<ParseUrl>),
1011    ParseIp(Box<ParseIp>),
1012    ParseTime(Box<ParseTime>),
1013    ParseDatetime(Box<ParseDatetime>),
1014    Map(Box<Map>),
1015    MapCat(Box<MapCat>),
1016    MapDelete(Box<MapDelete>),
1017    MapInsert(Box<MapInsert>),
1018    MapPick(Box<MapPick>),
1019    ScopeResolution(Box<ScopeResolution>),
1020    Slice(Box<Slice>),
1021    VarMap(Box<VarMap>),
1022    MatchAgainst(Box<MatchAgainst>),
1023    MD5Digest(Box<MD5Digest>),
1024    MD5NumberLower64(Box<UnaryFunc>),
1025    MD5NumberUpper64(Box<UnaryFunc>),
1026    Monthname(Box<Monthname>),
1027    Ntile(Box<Ntile>),
1028    Normalize(Box<Normalize>),
1029    Normal(Box<Normal>),
1030    Predict(Box<Predict>),
1031    MLTranslate(Box<MLTranslate>),
1032    FeaturesAtTime(Box<FeaturesAtTime>),
1033    GenerateEmbedding(Box<GenerateEmbedding>),
1034    MLForecast(Box<MLForecast>),
1035    ModelAttribute(Box<ModelAttribute>),
1036    VectorSearch(Box<VectorSearch>),
1037    Quantile(Box<Quantile>),
1038    ApproxQuantile(Box<ApproxQuantile>),
1039    ApproxPercentileEstimate(Box<ApproxPercentileEstimate>),
1040    Randn(Box<Randn>),
1041    Randstr(Box<Randstr>),
1042    RangeN(Box<RangeN>),
1043    RangeBucket(Box<RangeBucket>),
1044    ReadCSV(Box<ReadCSV>),
1045    ReadParquet(Box<ReadParquet>),
1046    Reduce(Box<Reduce>),
1047    RegexpExtractAll(Box<RegexpExtractAll>),
1048    RegexpILike(Box<RegexpILike>),
1049    RegexpFullMatch(Box<RegexpFullMatch>),
1050    RegexpInstr(Box<RegexpInstr>),
1051    RegexpSplit(Box<RegexpSplit>),
1052    RegexpCount(Box<RegexpCount>),
1053    RegrValx(Box<RegrValx>),
1054    RegrValy(Box<RegrValy>),
1055    RegrAvgy(Box<RegrAvgy>),
1056    RegrAvgx(Box<RegrAvgx>),
1057    RegrCount(Box<RegrCount>),
1058    RegrIntercept(Box<RegrIntercept>),
1059    RegrR2(Box<RegrR2>),
1060    RegrSxx(Box<RegrSxx>),
1061    RegrSxy(Box<RegrSxy>),
1062    RegrSyy(Box<RegrSyy>),
1063    RegrSlope(Box<RegrSlope>),
1064    SafeAdd(Box<SafeAdd>),
1065    SafeDivide(Box<SafeDivide>),
1066    SafeMultiply(Box<SafeMultiply>),
1067    SafeSubtract(Box<SafeSubtract>),
1068    SHA2(Box<SHA2>),
1069    SHA2Digest(Box<SHA2Digest>),
1070    SortArray(Box<SortArray>),
1071    SplitPart(Box<SplitPart>),
1072    SubstringIndex(Box<SubstringIndex>),
1073    StandardHash(Box<StandardHash>),
1074    StrPosition(Box<StrPosition>),
1075    Search(Box<Search>),
1076    SearchIp(Box<SearchIp>),
1077    StrToDate(Box<StrToDate>),
1078    DateStrToDate(Box<UnaryFunc>),
1079    DateToDateStr(Box<UnaryFunc>),
1080    StrToTime(Box<StrToTime>),
1081    StrToUnix(Box<StrToUnix>),
1082    StrToMap(Box<StrToMap>),
1083    NumberToStr(Box<NumberToStr>),
1084    FromBase(Box<FromBase>),
1085    Stuff(Box<Stuff>),
1086    TimeToStr(Box<TimeToStr>),
1087    TimeStrToTime(Box<TimeStrToTime>),
1088    TsOrDsAdd(Box<TsOrDsAdd>),
1089    TsOrDsDiff(Box<TsOrDsDiff>),
1090    TsOrDsToDate(Box<TsOrDsToDate>),
1091    TsOrDsToTime(Box<TsOrDsToTime>),
1092    Unhex(Box<Unhex>),
1093    Uniform(Box<Uniform>),
1094    UnixToStr(Box<UnixToStr>),
1095    UnixToTime(Box<UnixToTime>),
1096    Uuid(Box<Uuid>),
1097    TimestampFromParts(Box<TimestampFromParts>),
1098    TimestampTzFromParts(Box<TimestampTzFromParts>),
1099    Corr(Box<Corr>),
1100    WidthBucket(Box<WidthBucket>),
1101    CovarSamp(Box<CovarSamp>),
1102    CovarPop(Box<CovarPop>),
1103    Week(Box<Week>),
1104    XMLElement(Box<XMLElement>),
1105    XMLGet(Box<XMLGet>),
1106    XMLTable(Box<XMLTable>),
1107    XMLKeyValueOption(Box<XMLKeyValueOption>),
1108    Zipf(Box<Zipf>),
1109    Merge(Box<Merge>),
1110    When(Box<When>),
1111    Whens(Box<Whens>),
1112    NextValueFor(Box<NextValueFor>),
1113    /// RETURN statement (DuckDB stored procedures)
1114    ReturnStmt(Box<Expression>),
1115}
1116
1117impl Expression {
1118    /// Create a `Column` variant, boxing the value automatically.
1119    #[inline]
1120    pub fn boxed_column(col: Column) -> Self {
1121        Expression::Column(Box::new(col))
1122    }
1123
1124    /// Create a `Table` variant, boxing the value automatically.
1125    #[inline]
1126    pub fn boxed_table(t: TableRef) -> Self {
1127        Expression::Table(Box::new(t))
1128    }
1129
1130    /// Returns `true` if this expression is a valid top-level SQL statement.
1131    ///
1132    /// Bare expressions like identifiers, literals, and function calls are not
1133    /// valid statements. This is used by `validate()` to reject inputs like
1134    /// `SELECT scooby dooby doo` which the parser splits into `SELECT scooby AS dooby`
1135    /// plus the bare identifier `doo`.
1136    pub fn is_statement(&self) -> bool {
1137        match self {
1138            // Queries
1139            Expression::Select(_)
1140            | Expression::Union(_)
1141            | Expression::Intersect(_)
1142            | Expression::Except(_)
1143            | Expression::Subquery(_)
1144            | Expression::Values(_)
1145            | Expression::PipeOperator(_)
1146
1147            // DML
1148            | Expression::Insert(_)
1149            | Expression::Update(_)
1150            | Expression::Delete(_)
1151            | Expression::Copy(_)
1152            | Expression::Put(_)
1153            | Expression::Merge(_)
1154            | Expression::TryCatch(_)
1155
1156            // DDL
1157            | Expression::CreateTable(_)
1158            | Expression::DropTable(_)
1159            | Expression::Undrop(_)
1160            | Expression::AlterTable(_)
1161            | Expression::SplitTable(_)
1162            | Expression::FlashbackTable(_)
1163            | Expression::CreateIndex(_)
1164            | Expression::DropIndex(_)
1165            | Expression::CreateView(_)
1166            | Expression::DropView(_)
1167            | Expression::AlterView(_)
1168            | Expression::AlterIndex(_)
1169            | Expression::Truncate(_)
1170            | Expression::TruncateTable(_)
1171            | Expression::CreateSchema(_)
1172            | Expression::DropSchema(_)
1173            | Expression::DropNamespace(_)
1174            | Expression::CreateDatabase(_)
1175            | Expression::DropDatabase(_)
1176            | Expression::CreateFunction(_)
1177            | Expression::DropFunction(_)
1178            | Expression::CreateProcedure(_)
1179            | Expression::DropProcedure(_)
1180            | Expression::CreateSequence(_)
1181            | Expression::CreateSynonym(_)
1182            | Expression::DropSequence(_)
1183            | Expression::AlterSequence(_)
1184            | Expression::CreateTrigger(_)
1185            | Expression::DropTrigger(_)
1186            | Expression::CreateType(_)
1187            | Expression::DropType(_)
1188            | Expression::Comment(_)
1189
1190            // Session/Transaction/Control
1191            | Expression::Use(_)
1192            | Expression::Set(_)
1193            | Expression::SetStatement(_)
1194            | Expression::Transaction(_)
1195            | Expression::Commit(_)
1196            | Expression::Rollback(_)
1197            | Expression::Grant(_)
1198            | Expression::Revoke(_)
1199            | Expression::Cache(_)
1200            | Expression::Uncache(_)
1201            | Expression::LoadData(_)
1202            | Expression::Pragma(_)
1203            | Expression::Describe(_)
1204            | Expression::Show(_)
1205            | Expression::Kill(_)
1206            | Expression::Prepare(_)
1207            | Expression::Execute(_)
1208            | Expression::Declare(_)
1209            | Expression::Refresh(_)
1210            | Expression::AlterSession(_)
1211            | Expression::LockingStatement(_)
1212
1213            // Analyze
1214            | Expression::Analyze(_)
1215            | Expression::AnalyzeStatistics(_)
1216            | Expression::AnalyzeHistogram(_)
1217            | Expression::AnalyzeSample(_)
1218            | Expression::AnalyzeListChainedRows(_)
1219            | Expression::AnalyzeDelete(_)
1220
1221            // Attach/Detach/Install/Summarize
1222            | Expression::Attach(_)
1223            | Expression::Detach(_)
1224            | Expression::Install(_)
1225            | Expression::Summarize(_)
1226
1227            // Pivot at statement level
1228            | Expression::Pivot(_)
1229            | Expression::Unpivot(_)
1230
1231            // Command (raw/unparsed statements)
1232            | Expression::Command(_)
1233            | Expression::Raw(_)
1234            | Expression::CreateTask(_)
1235
1236            // Return statement
1237            | Expression::ReturnStmt(_) => true,
1238
1239            // Annotated wraps another expression with comments — check inner
1240            Expression::Annotated(a) => a.this.is_statement(),
1241
1242            // Alias at top level can wrap a statement (e.g., parenthesized subquery with alias)
1243            Expression::Alias(a) => a.this.is_statement(),
1244
1245            // Everything else (identifiers, literals, operators, functions, etc.)
1246            _ => false,
1247        }
1248    }
1249
1250    /// Create a literal number expression from an integer.
1251    pub fn number(n: i64) -> Self {
1252        Expression::Literal(Box::new(Literal::Number(n.to_string())))
1253    }
1254
1255    /// Create a single-quoted literal string expression.
1256    pub fn string(s: impl Into<String>) -> Self {
1257        Expression::Literal(Box::new(Literal::String(s.into())))
1258    }
1259
1260    /// Create a literal number expression from a float.
1261    pub fn float(f: f64) -> Self {
1262        Expression::Literal(Box::new(Literal::Number(f.to_string())))
1263    }
1264
1265    /// Get the inferred type annotation, if present.
1266    ///
1267    /// For value-producing expressions with an `inferred_type` field, returns
1268    /// the stored type. For literals and boolean constants, computes the type
1269    /// on the fly from the variant. For DDL/clause expressions, returns `None`.
1270    pub fn inferred_type(&self) -> Option<&DataType> {
1271        match self {
1272            // Structs with inferred_type field
1273            Expression::And(op)
1274            | Expression::Or(op)
1275            | Expression::Add(op)
1276            | Expression::Sub(op)
1277            | Expression::Mul(op)
1278            | Expression::Div(op)
1279            | Expression::Mod(op)
1280            | Expression::Eq(op)
1281            | Expression::Neq(op)
1282            | Expression::Lt(op)
1283            | Expression::Lte(op)
1284            | Expression::Gt(op)
1285            | Expression::Gte(op)
1286            | Expression::Concat(op)
1287            | Expression::BitwiseAnd(op)
1288            | Expression::BitwiseOr(op)
1289            | Expression::BitwiseXor(op)
1290            | Expression::Adjacent(op)
1291            | Expression::TsMatch(op)
1292            | Expression::PropertyEQ(op)
1293            | Expression::ArrayContainsAll(op)
1294            | Expression::ArrayContainedBy(op)
1295            | Expression::ArrayOverlaps(op)
1296            | Expression::JSONBContainsAllTopKeys(op)
1297            | Expression::JSONBContainsAnyTopKeys(op)
1298            | Expression::JSONBDeleteAtPath(op)
1299            | Expression::ExtendsLeft(op)
1300            | Expression::ExtendsRight(op)
1301            | Expression::Is(op)
1302            | Expression::MemberOf(op)
1303            | Expression::Match(op)
1304            | Expression::NullSafeEq(op)
1305            | Expression::NullSafeNeq(op)
1306            | Expression::Glob(op)
1307            | Expression::BitwiseLeftShift(op)
1308            | Expression::BitwiseRightShift(op) => op.inferred_type.as_ref(),
1309
1310            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1311                op.inferred_type.as_ref()
1312            }
1313
1314            Expression::Like(op) | Expression::ILike(op) => op.inferred_type.as_ref(),
1315
1316            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1317                c.inferred_type.as_ref()
1318            }
1319
1320            Expression::Column(c) => c.inferred_type.as_ref(),
1321            Expression::Function(f) => f.inferred_type.as_ref(),
1322            Expression::AggregateFunction(f) => f.inferred_type.as_ref(),
1323            Expression::WindowFunction(f) => f.inferred_type.as_ref(),
1324            Expression::Case(c) => c.inferred_type.as_ref(),
1325            Expression::Subquery(s) => s.inferred_type.as_ref(),
1326            Expression::Alias(a) => a.inferred_type.as_ref(),
1327            Expression::Unnest(u) => u.inferred_type.as_ref(),
1328            Expression::IfFunc(f) => f.inferred_type.as_ref(),
1329            Expression::Nvl2(f) => f.inferred_type.as_ref(),
1330            Expression::Count(f) => f.inferred_type.as_ref(),
1331            Expression::GroupConcat(f) => f.inferred_type.as_ref(),
1332            Expression::StringAgg(f) => f.inferred_type.as_ref(),
1333            Expression::ListAgg(f) => f.inferred_type.as_ref(),
1334            Expression::SumIf(f) => f.inferred_type.as_ref(),
1335
1336            // UnaryFunc variants
1337            Expression::Upper(f)
1338            | Expression::Lower(f)
1339            | Expression::Length(f)
1340            | Expression::LTrim(f)
1341            | Expression::RTrim(f)
1342            | Expression::Reverse(f)
1343            | Expression::Abs(f)
1344            | Expression::Sqrt(f)
1345            | Expression::Cbrt(f)
1346            | Expression::Ln(f)
1347            | Expression::Exp(f)
1348            | Expression::Sign(f)
1349            | Expression::Date(f)
1350            | Expression::Time(f)
1351            | Expression::Initcap(f)
1352            | Expression::Ascii(f)
1353            | Expression::Chr(f)
1354            | Expression::Soundex(f)
1355            | Expression::ByteLength(f)
1356            | Expression::Hex(f)
1357            | Expression::LowerHex(f)
1358            | Expression::Unicode(f)
1359            | Expression::Typeof(f)
1360            | Expression::Explode(f)
1361            | Expression::ExplodeOuter(f)
1362            | Expression::MapFromEntries(f)
1363            | Expression::MapKeys(f)
1364            | Expression::MapValues(f)
1365            | Expression::ArrayLength(f)
1366            | Expression::ArraySize(f)
1367            | Expression::Cardinality(f)
1368            | Expression::ArrayReverse(f)
1369            | Expression::ArrayDistinct(f)
1370            | Expression::ArrayFlatten(f)
1371            | Expression::ArrayCompact(f)
1372            | Expression::ToArray(f)
1373            | Expression::JsonArrayLength(f)
1374            | Expression::JsonKeys(f)
1375            | Expression::JsonType(f)
1376            | Expression::ParseJson(f)
1377            | Expression::ToJson(f)
1378            | Expression::Radians(f)
1379            | Expression::Degrees(f)
1380            | Expression::Sin(f)
1381            | Expression::Cos(f)
1382            | Expression::Tan(f)
1383            | Expression::Asin(f)
1384            | Expression::Acos(f)
1385            | Expression::Atan(f)
1386            | Expression::IsNan(f)
1387            | Expression::IsInf(f)
1388            | Expression::Year(f)
1389            | Expression::Month(f)
1390            | Expression::Day(f)
1391            | Expression::Hour(f)
1392            | Expression::Minute(f)
1393            | Expression::Second(f)
1394            | Expression::DayOfWeek(f)
1395            | Expression::DayOfWeekIso(f)
1396            | Expression::DayOfMonth(f)
1397            | Expression::DayOfYear(f)
1398            | Expression::WeekOfYear(f)
1399            | Expression::Quarter(f)
1400            | Expression::Epoch(f)
1401            | Expression::EpochMs(f)
1402            | Expression::BitwiseCount(f)
1403            | Expression::DateFromUnixDate(f)
1404            | Expression::UnixDate(f)
1405            | Expression::UnixSeconds(f)
1406            | Expression::UnixMillis(f)
1407            | Expression::UnixMicros(f)
1408            | Expression::TimeStrToDate(f)
1409            | Expression::DateToDi(f)
1410            | Expression::DiToDate(f)
1411            | Expression::TsOrDiToDi(f)
1412            | Expression::TsOrDsToDatetime(f)
1413            | Expression::TsOrDsToTimestamp(f)
1414            | Expression::YearOfWeek(f)
1415            | Expression::YearOfWeekIso(f)
1416            | Expression::SHA(f)
1417            | Expression::SHA1Digest(f)
1418            | Expression::TimeToUnix(f)
1419            | Expression::TimeStrToUnix(f) => f.inferred_type.as_ref(),
1420
1421            // BinaryFunc variants
1422            Expression::Power(f)
1423            | Expression::NullIf(f)
1424            | Expression::IfNull(f)
1425            | Expression::Nvl(f)
1426            | Expression::Contains(f)
1427            | Expression::StartsWith(f)
1428            | Expression::EndsWith(f)
1429            | Expression::Levenshtein(f)
1430            | Expression::ModFunc(f)
1431            | Expression::IntDiv(f)
1432            | Expression::Atan2(f)
1433            | Expression::AddMonths(f)
1434            | Expression::MonthsBetween(f)
1435            | Expression::NextDay(f)
1436            | Expression::UnixToTimeStr(f)
1437            | Expression::ArrayContains(f)
1438            | Expression::ArrayPosition(f)
1439            | Expression::ArrayAppend(f)
1440            | Expression::ArrayPrepend(f)
1441            | Expression::ArrayUnion(f)
1442            | Expression::ArrayExcept(f)
1443            | Expression::ArrayRemove(f)
1444            | Expression::StarMap(f)
1445            | Expression::MapFromArrays(f)
1446            | Expression::MapContainsKey(f)
1447            | Expression::ElementAt(f)
1448            | Expression::JsonMergePatch(f) => f.inferred_type.as_ref(),
1449
1450            // VarArgFunc variants
1451            Expression::Coalesce(f)
1452            | Expression::Greatest(f)
1453            | Expression::Least(f)
1454            | Expression::ArrayConcat(f)
1455            | Expression::ArrayIntersect(f)
1456            | Expression::ArrayZip(f)
1457            | Expression::MapConcat(f)
1458            | Expression::JsonArray(f) => f.inferred_type.as_ref(),
1459
1460            // AggFunc variants
1461            Expression::Sum(f)
1462            | Expression::Avg(f)
1463            | Expression::Min(f)
1464            | Expression::Max(f)
1465            | Expression::ArrayAgg(f)
1466            | Expression::CountIf(f)
1467            | Expression::Stddev(f)
1468            | Expression::StddevPop(f)
1469            | Expression::StddevSamp(f)
1470            | Expression::Variance(f)
1471            | Expression::VarPop(f)
1472            | Expression::VarSamp(f)
1473            | Expression::Median(f)
1474            | Expression::Mode(f)
1475            | Expression::First(f)
1476            | Expression::Last(f)
1477            | Expression::AnyValue(f)
1478            | Expression::ApproxDistinct(f)
1479            | Expression::ApproxCountDistinct(f)
1480            | Expression::LogicalAnd(f)
1481            | Expression::LogicalOr(f)
1482            | Expression::Skewness(f)
1483            | Expression::ArrayConcatAgg(f)
1484            | Expression::ArrayUniqueAgg(f)
1485            | Expression::BoolXorAgg(f)
1486            | Expression::BitwiseAndAgg(f)
1487            | Expression::BitwiseOrAgg(f)
1488            | Expression::BitwiseXorAgg(f) => f.inferred_type.as_ref(),
1489
1490            // Everything else: no inferred_type field
1491            _ => None,
1492        }
1493    }
1494
1495    /// Set the inferred type annotation on this expression.
1496    ///
1497    /// Only has an effect on value-producing expressions with an `inferred_type`
1498    /// field. For other expression types, this is a no-op.
1499    pub fn set_inferred_type(&mut self, dt: DataType) {
1500        match self {
1501            Expression::And(op)
1502            | Expression::Or(op)
1503            | Expression::Add(op)
1504            | Expression::Sub(op)
1505            | Expression::Mul(op)
1506            | Expression::Div(op)
1507            | Expression::Mod(op)
1508            | Expression::Eq(op)
1509            | Expression::Neq(op)
1510            | Expression::Lt(op)
1511            | Expression::Lte(op)
1512            | Expression::Gt(op)
1513            | Expression::Gte(op)
1514            | Expression::Concat(op)
1515            | Expression::BitwiseAnd(op)
1516            | Expression::BitwiseOr(op)
1517            | Expression::BitwiseXor(op)
1518            | Expression::Adjacent(op)
1519            | Expression::TsMatch(op)
1520            | Expression::PropertyEQ(op)
1521            | Expression::ArrayContainsAll(op)
1522            | Expression::ArrayContainedBy(op)
1523            | Expression::ArrayOverlaps(op)
1524            | Expression::JSONBContainsAllTopKeys(op)
1525            | Expression::JSONBContainsAnyTopKeys(op)
1526            | Expression::JSONBDeleteAtPath(op)
1527            | Expression::ExtendsLeft(op)
1528            | Expression::ExtendsRight(op)
1529            | Expression::Is(op)
1530            | Expression::MemberOf(op)
1531            | Expression::Match(op)
1532            | Expression::NullSafeEq(op)
1533            | Expression::NullSafeNeq(op)
1534            | Expression::Glob(op)
1535            | Expression::BitwiseLeftShift(op)
1536            | Expression::BitwiseRightShift(op) => op.inferred_type = Some(dt),
1537
1538            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1539                op.inferred_type = Some(dt)
1540            }
1541
1542            Expression::Like(op) | Expression::ILike(op) => op.inferred_type = Some(dt),
1543
1544            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1545                c.inferred_type = Some(dt)
1546            }
1547
1548            Expression::Column(c) => c.inferred_type = Some(dt),
1549            Expression::Function(f) => f.inferred_type = Some(dt),
1550            Expression::AggregateFunction(f) => f.inferred_type = Some(dt),
1551            Expression::WindowFunction(f) => f.inferred_type = Some(dt),
1552            Expression::Case(c) => c.inferred_type = Some(dt),
1553            Expression::Subquery(s) => s.inferred_type = Some(dt),
1554            Expression::Alias(a) => a.inferred_type = Some(dt),
1555            Expression::Unnest(u) => u.inferred_type = Some(dt),
1556            Expression::IfFunc(f) => f.inferred_type = Some(dt),
1557            Expression::Nvl2(f) => f.inferred_type = Some(dt),
1558            Expression::Count(f) => f.inferred_type = Some(dt),
1559            Expression::GroupConcat(f) => f.inferred_type = Some(dt),
1560            Expression::StringAgg(f) => f.inferred_type = Some(dt),
1561            Expression::ListAgg(f) => f.inferred_type = Some(dt),
1562            Expression::SumIf(f) => f.inferred_type = Some(dt),
1563
1564            // UnaryFunc variants
1565            Expression::Upper(f)
1566            | Expression::Lower(f)
1567            | Expression::Length(f)
1568            | Expression::LTrim(f)
1569            | Expression::RTrim(f)
1570            | Expression::Reverse(f)
1571            | Expression::Abs(f)
1572            | Expression::Sqrt(f)
1573            | Expression::Cbrt(f)
1574            | Expression::Ln(f)
1575            | Expression::Exp(f)
1576            | Expression::Sign(f)
1577            | Expression::Date(f)
1578            | Expression::Time(f)
1579            | Expression::Initcap(f)
1580            | Expression::Ascii(f)
1581            | Expression::Chr(f)
1582            | Expression::Soundex(f)
1583            | Expression::ByteLength(f)
1584            | Expression::Hex(f)
1585            | Expression::LowerHex(f)
1586            | Expression::Unicode(f)
1587            | Expression::Typeof(f)
1588            | Expression::Explode(f)
1589            | Expression::ExplodeOuter(f)
1590            | Expression::MapFromEntries(f)
1591            | Expression::MapKeys(f)
1592            | Expression::MapValues(f)
1593            | Expression::ArrayLength(f)
1594            | Expression::ArraySize(f)
1595            | Expression::Cardinality(f)
1596            | Expression::ArrayReverse(f)
1597            | Expression::ArrayDistinct(f)
1598            | Expression::ArrayFlatten(f)
1599            | Expression::ArrayCompact(f)
1600            | Expression::ToArray(f)
1601            | Expression::JsonArrayLength(f)
1602            | Expression::JsonKeys(f)
1603            | Expression::JsonType(f)
1604            | Expression::ParseJson(f)
1605            | Expression::ToJson(f)
1606            | Expression::Radians(f)
1607            | Expression::Degrees(f)
1608            | Expression::Sin(f)
1609            | Expression::Cos(f)
1610            | Expression::Tan(f)
1611            | Expression::Asin(f)
1612            | Expression::Acos(f)
1613            | Expression::Atan(f)
1614            | Expression::IsNan(f)
1615            | Expression::IsInf(f)
1616            | Expression::Year(f)
1617            | Expression::Month(f)
1618            | Expression::Day(f)
1619            | Expression::Hour(f)
1620            | Expression::Minute(f)
1621            | Expression::Second(f)
1622            | Expression::DayOfWeek(f)
1623            | Expression::DayOfWeekIso(f)
1624            | Expression::DayOfMonth(f)
1625            | Expression::DayOfYear(f)
1626            | Expression::WeekOfYear(f)
1627            | Expression::Quarter(f)
1628            | Expression::Epoch(f)
1629            | Expression::EpochMs(f)
1630            | Expression::BitwiseCount(f)
1631            | Expression::DateFromUnixDate(f)
1632            | Expression::UnixDate(f)
1633            | Expression::UnixSeconds(f)
1634            | Expression::UnixMillis(f)
1635            | Expression::UnixMicros(f)
1636            | Expression::TimeStrToDate(f)
1637            | Expression::DateToDi(f)
1638            | Expression::DiToDate(f)
1639            | Expression::TsOrDiToDi(f)
1640            | Expression::TsOrDsToDatetime(f)
1641            | Expression::TsOrDsToTimestamp(f)
1642            | Expression::YearOfWeek(f)
1643            | Expression::YearOfWeekIso(f)
1644            | Expression::SHA(f)
1645            | Expression::SHA1Digest(f)
1646            | Expression::TimeToUnix(f)
1647            | Expression::TimeStrToUnix(f) => f.inferred_type = Some(dt),
1648
1649            // BinaryFunc variants
1650            Expression::Power(f)
1651            | Expression::NullIf(f)
1652            | Expression::IfNull(f)
1653            | Expression::Nvl(f)
1654            | Expression::Contains(f)
1655            | Expression::StartsWith(f)
1656            | Expression::EndsWith(f)
1657            | Expression::Levenshtein(f)
1658            | Expression::ModFunc(f)
1659            | Expression::IntDiv(f)
1660            | Expression::Atan2(f)
1661            | Expression::AddMonths(f)
1662            | Expression::MonthsBetween(f)
1663            | Expression::NextDay(f)
1664            | Expression::UnixToTimeStr(f)
1665            | Expression::ArrayContains(f)
1666            | Expression::ArrayPosition(f)
1667            | Expression::ArrayAppend(f)
1668            | Expression::ArrayPrepend(f)
1669            | Expression::ArrayUnion(f)
1670            | Expression::ArrayExcept(f)
1671            | Expression::ArrayRemove(f)
1672            | Expression::StarMap(f)
1673            | Expression::MapFromArrays(f)
1674            | Expression::MapContainsKey(f)
1675            | Expression::ElementAt(f)
1676            | Expression::JsonMergePatch(f) => f.inferred_type = Some(dt),
1677
1678            // VarArgFunc variants
1679            Expression::Coalesce(f)
1680            | Expression::Greatest(f)
1681            | Expression::Least(f)
1682            | Expression::ArrayConcat(f)
1683            | Expression::ArrayIntersect(f)
1684            | Expression::ArrayZip(f)
1685            | Expression::MapConcat(f)
1686            | Expression::JsonArray(f) => f.inferred_type = Some(dt),
1687
1688            // AggFunc variants
1689            Expression::Sum(f)
1690            | Expression::Avg(f)
1691            | Expression::Min(f)
1692            | Expression::Max(f)
1693            | Expression::ArrayAgg(f)
1694            | Expression::CountIf(f)
1695            | Expression::Stddev(f)
1696            | Expression::StddevPop(f)
1697            | Expression::StddevSamp(f)
1698            | Expression::Variance(f)
1699            | Expression::VarPop(f)
1700            | Expression::VarSamp(f)
1701            | Expression::Median(f)
1702            | Expression::Mode(f)
1703            | Expression::First(f)
1704            | Expression::Last(f)
1705            | Expression::AnyValue(f)
1706            | Expression::ApproxDistinct(f)
1707            | Expression::ApproxCountDistinct(f)
1708            | Expression::LogicalAnd(f)
1709            | Expression::LogicalOr(f)
1710            | Expression::Skewness(f)
1711            | Expression::ArrayConcatAgg(f)
1712            | Expression::ArrayUniqueAgg(f)
1713            | Expression::BoolXorAgg(f)
1714            | Expression::BitwiseAndAgg(f)
1715            | Expression::BitwiseOrAgg(f)
1716            | Expression::BitwiseXorAgg(f) => f.inferred_type = Some(dt),
1717
1718            // Expressions without inferred_type field - no-op
1719            _ => {}
1720        }
1721    }
1722
1723    /// Create an unqualified column reference (e.g. `name`).
1724    pub fn column(name: impl Into<String>) -> Self {
1725        Expression::Column(Box::new(Column {
1726            name: Identifier::new(name),
1727            table: None,
1728            join_mark: false,
1729            trailing_comments: Vec::new(),
1730            span: None,
1731            inferred_type: None,
1732        }))
1733    }
1734
1735    /// Create a qualified column reference (`table.column`).
1736    pub fn qualified_column(table: impl Into<String>, column: impl Into<String>) -> Self {
1737        Expression::Column(Box::new(Column {
1738            name: Identifier::new(column),
1739            table: Some(Identifier::new(table)),
1740            join_mark: false,
1741            trailing_comments: Vec::new(),
1742            span: None,
1743            inferred_type: None,
1744        }))
1745    }
1746
1747    /// Create a bare identifier expression (not a column reference).
1748    pub fn identifier(name: impl Into<String>) -> Self {
1749        Expression::Identifier(Identifier::new(name))
1750    }
1751
1752    /// Create a NULL expression
1753    pub fn null() -> Self {
1754        Expression::Null(Null)
1755    }
1756
1757    /// Create a TRUE expression
1758    pub fn true_() -> Self {
1759        Expression::Boolean(BooleanLiteral { value: true })
1760    }
1761
1762    /// Create a FALSE expression
1763    pub fn false_() -> Self {
1764        Expression::Boolean(BooleanLiteral { value: false })
1765    }
1766
1767    /// Create a wildcard star (`*`) expression with no EXCEPT/REPLACE/RENAME modifiers.
1768    pub fn star() -> Self {
1769        Expression::Star(Star {
1770            table: None,
1771            except: None,
1772            replace: None,
1773            rename: None,
1774            trailing_comments: Vec::new(),
1775            span: None,
1776        })
1777    }
1778
1779    /// Wrap this expression in an `AS` alias (e.g. `expr AS name`).
1780    pub fn alias(self, name: impl Into<String>) -> Self {
1781        Expression::Alias(Box::new(Alias::new(self, Identifier::new(name))))
1782    }
1783
1784    /// Check if this is a SELECT expression
1785    pub fn is_select(&self) -> bool {
1786        matches!(self, Expression::Select(_))
1787    }
1788
1789    /// Try to get as a Select
1790    pub fn as_select(&self) -> Option<&Select> {
1791        match self {
1792            Expression::Select(s) => Some(s),
1793            _ => None,
1794        }
1795    }
1796
1797    /// Try to get as a mutable Select
1798    pub fn as_select_mut(&mut self) -> Option<&mut Select> {
1799        match self {
1800            Expression::Select(s) => Some(s),
1801            _ => None,
1802        }
1803    }
1804
1805    /// Generate a SQL string for this expression using the generic (dialect-agnostic) generator.
1806    ///
1807    /// Returns an empty string if generation fails. For dialect-specific output,
1808    /// use [`sql_for()`](Self::sql_for) instead.
1809    #[cfg(feature = "generate")]
1810    pub fn sql(&self) -> String {
1811        crate::generator::Generator::sql(self).unwrap_or_default()
1812    }
1813
1814    /// Generate a SQL string for this expression targeting a specific dialect.
1815    ///
1816    /// Dialect-specific rules (identifier quoting, function names, type mappings,
1817    /// syntax variations) are applied automatically.  Returns an empty string if
1818    /// generation fails.
1819    #[cfg(feature = "generate")]
1820    pub fn sql_for(&self, dialect: crate::dialects::DialectType) -> String {
1821        crate::generate(self, dialect).unwrap_or_default()
1822    }
1823}
1824
1825// === Python API accessor methods ===
1826
1827impl Expression {
1828    /// Returns the serde-compatible snake_case variant name without serialization.
1829    /// This is much faster than serializing to JSON and extracting the key.
1830    pub fn variant_name(&self) -> &'static str {
1831        match self {
1832            Expression::Literal(_) => "literal",
1833            Expression::Boolean(_) => "boolean",
1834            Expression::Null(_) => "null",
1835            Expression::Identifier(_) => "identifier",
1836            Expression::Column(_) => "column",
1837            Expression::Table(_) => "table",
1838            Expression::Star(_) => "star",
1839            Expression::BracedWildcard(_) => "braced_wildcard",
1840            Expression::Select(_) => "select",
1841            Expression::Union(_) => "union",
1842            Expression::Intersect(_) => "intersect",
1843            Expression::Except(_) => "except",
1844            Expression::Subquery(_) => "subquery",
1845            Expression::PipeOperator(_) => "pipe_operator",
1846            Expression::Pivot(_) => "pivot",
1847            Expression::PivotAlias(_) => "pivot_alias",
1848            Expression::Unpivot(_) => "unpivot",
1849            Expression::Values(_) => "values",
1850            Expression::PreWhere(_) => "pre_where",
1851            Expression::Stream(_) => "stream",
1852            Expression::UsingData(_) => "using_data",
1853            Expression::XmlNamespace(_) => "xml_namespace",
1854            Expression::Insert(_) => "insert",
1855            Expression::Update(_) => "update",
1856            Expression::Delete(_) => "delete",
1857            Expression::Copy(_) => "copy",
1858            Expression::Put(_) => "put",
1859            Expression::StageReference(_) => "stage_reference",
1860            Expression::Alias(_) => "alias",
1861            Expression::Cast(_) => "cast",
1862            Expression::Collation(_) => "collation",
1863            Expression::Case(_) => "case",
1864            Expression::And(_) => "and",
1865            Expression::Or(_) => "or",
1866            Expression::Add(_) => "add",
1867            Expression::Sub(_) => "sub",
1868            Expression::Mul(_) => "mul",
1869            Expression::Div(_) => "div",
1870            Expression::Mod(_) => "mod",
1871            Expression::Eq(_) => "eq",
1872            Expression::Neq(_) => "neq",
1873            Expression::Lt(_) => "lt",
1874            Expression::Lte(_) => "lte",
1875            Expression::Gt(_) => "gt",
1876            Expression::Gte(_) => "gte",
1877            Expression::Like(_) => "like",
1878            Expression::ILike(_) => "i_like",
1879            Expression::Match(_) => "match",
1880            Expression::BitwiseAnd(_) => "bitwise_and",
1881            Expression::BitwiseOr(_) => "bitwise_or",
1882            Expression::BitwiseXor(_) => "bitwise_xor",
1883            Expression::Concat(_) => "concat",
1884            Expression::Adjacent(_) => "adjacent",
1885            Expression::TsMatch(_) => "ts_match",
1886            Expression::PropertyEQ(_) => "property_e_q",
1887            Expression::ArrayContainsAll(_) => "array_contains_all",
1888            Expression::ArrayContainedBy(_) => "array_contained_by",
1889            Expression::ArrayOverlaps(_) => "array_overlaps",
1890            Expression::JSONBContainsAllTopKeys(_) => "j_s_o_n_b_contains_all_top_keys",
1891            Expression::JSONBContainsAnyTopKeys(_) => "j_s_o_n_b_contains_any_top_keys",
1892            Expression::JSONBDeleteAtPath(_) => "j_s_o_n_b_delete_at_path",
1893            Expression::ExtendsLeft(_) => "extends_left",
1894            Expression::ExtendsRight(_) => "extends_right",
1895            Expression::Not(_) => "not",
1896            Expression::Neg(_) => "neg",
1897            Expression::BitwiseNot(_) => "bitwise_not",
1898            Expression::In(_) => "in",
1899            Expression::Between(_) => "between",
1900            Expression::IsNull(_) => "is_null",
1901            Expression::IsTrue(_) => "is_true",
1902            Expression::IsFalse(_) => "is_false",
1903            Expression::IsJson(_) => "is_json",
1904            Expression::Is(_) => "is",
1905            Expression::Exists(_) => "exists",
1906            Expression::MemberOf(_) => "member_of",
1907            Expression::Function(_) => "function",
1908            Expression::AggregateFunction(_) => "aggregate_function",
1909            Expression::WindowFunction(_) => "window_function",
1910            Expression::From(_) => "from",
1911            Expression::Join(_) => "join",
1912            Expression::JoinedTable(_) => "joined_table",
1913            Expression::Where(_) => "where",
1914            Expression::GroupBy(_) => "group_by",
1915            Expression::Having(_) => "having",
1916            Expression::OrderBy(_) => "order_by",
1917            Expression::Limit(_) => "limit",
1918            Expression::Offset(_) => "offset",
1919            Expression::Qualify(_) => "qualify",
1920            Expression::With(_) => "with",
1921            Expression::Cte(_) => "cte",
1922            Expression::DistributeBy(_) => "distribute_by",
1923            Expression::ClusterBy(_) => "cluster_by",
1924            Expression::SortBy(_) => "sort_by",
1925            Expression::LateralView(_) => "lateral_view",
1926            Expression::Hint(_) => "hint",
1927            Expression::Pseudocolumn(_) => "pseudocolumn",
1928            Expression::Connect(_) => "connect",
1929            Expression::Prior(_) => "prior",
1930            Expression::ConnectByRoot(_) => "connect_by_root",
1931            Expression::MatchRecognize(_) => "match_recognize",
1932            Expression::Ordered(_) => "ordered",
1933            Expression::Window(_) => "window",
1934            Expression::Over(_) => "over",
1935            Expression::WithinGroup(_) => "within_group",
1936            Expression::DataType(_) => "data_type",
1937            Expression::Array(_) => "array",
1938            Expression::Struct(_) => "struct",
1939            Expression::Tuple(_) => "tuple",
1940            Expression::Interval(_) => "interval",
1941            Expression::ConcatWs(_) => "concat_ws",
1942            Expression::Substring(_) => "substring",
1943            Expression::Upper(_) => "upper",
1944            Expression::Lower(_) => "lower",
1945            Expression::Length(_) => "length",
1946            Expression::Trim(_) => "trim",
1947            Expression::LTrim(_) => "l_trim",
1948            Expression::RTrim(_) => "r_trim",
1949            Expression::Replace(_) => "replace",
1950            Expression::Reverse(_) => "reverse",
1951            Expression::Left(_) => "left",
1952            Expression::Right(_) => "right",
1953            Expression::Repeat(_) => "repeat",
1954            Expression::Lpad(_) => "lpad",
1955            Expression::Rpad(_) => "rpad",
1956            Expression::Split(_) => "split",
1957            Expression::RegexpLike(_) => "regexp_like",
1958            Expression::RegexpReplace(_) => "regexp_replace",
1959            Expression::RegexpExtract(_) => "regexp_extract",
1960            Expression::Overlay(_) => "overlay",
1961            Expression::Abs(_) => "abs",
1962            Expression::Round(_) => "round",
1963            Expression::Floor(_) => "floor",
1964            Expression::Ceil(_) => "ceil",
1965            Expression::Power(_) => "power",
1966            Expression::Sqrt(_) => "sqrt",
1967            Expression::Cbrt(_) => "cbrt",
1968            Expression::Ln(_) => "ln",
1969            Expression::Log(_) => "log",
1970            Expression::Exp(_) => "exp",
1971            Expression::Sign(_) => "sign",
1972            Expression::Greatest(_) => "greatest",
1973            Expression::Least(_) => "least",
1974            Expression::CurrentDate(_) => "current_date",
1975            Expression::CurrentTime(_) => "current_time",
1976            Expression::CurrentTimestamp(_) => "current_timestamp",
1977            Expression::CurrentTimestampLTZ(_) => "current_timestamp_l_t_z",
1978            Expression::AtTimeZone(_) => "at_time_zone",
1979            Expression::DateAdd(_) => "date_add",
1980            Expression::DateSub(_) => "date_sub",
1981            Expression::DateDiff(_) => "date_diff",
1982            Expression::DateTrunc(_) => "date_trunc",
1983            Expression::Extract(_) => "extract",
1984            Expression::ToDate(_) => "to_date",
1985            Expression::ToTimestamp(_) => "to_timestamp",
1986            Expression::Date(_) => "date",
1987            Expression::Time(_) => "time",
1988            Expression::DateFromUnixDate(_) => "date_from_unix_date",
1989            Expression::UnixDate(_) => "unix_date",
1990            Expression::UnixSeconds(_) => "unix_seconds",
1991            Expression::UnixMillis(_) => "unix_millis",
1992            Expression::UnixMicros(_) => "unix_micros",
1993            Expression::UnixToTimeStr(_) => "unix_to_time_str",
1994            Expression::TimeStrToDate(_) => "time_str_to_date",
1995            Expression::DateToDi(_) => "date_to_di",
1996            Expression::DiToDate(_) => "di_to_date",
1997            Expression::TsOrDiToDi(_) => "ts_or_di_to_di",
1998            Expression::TsOrDsToDatetime(_) => "ts_or_ds_to_datetime",
1999            Expression::TsOrDsToTimestamp(_) => "ts_or_ds_to_timestamp",
2000            Expression::YearOfWeek(_) => "year_of_week",
2001            Expression::YearOfWeekIso(_) => "year_of_week_iso",
2002            Expression::Coalesce(_) => "coalesce",
2003            Expression::NullIf(_) => "null_if",
2004            Expression::IfFunc(_) => "if_func",
2005            Expression::IfNull(_) => "if_null",
2006            Expression::Nvl(_) => "nvl",
2007            Expression::Nvl2(_) => "nvl2",
2008            Expression::TryCast(_) => "try_cast",
2009            Expression::SafeCast(_) => "safe_cast",
2010            Expression::Count(_) => "count",
2011            Expression::Sum(_) => "sum",
2012            Expression::Avg(_) => "avg",
2013            Expression::Min(_) => "min",
2014            Expression::Max(_) => "max",
2015            Expression::GroupConcat(_) => "group_concat",
2016            Expression::StringAgg(_) => "string_agg",
2017            Expression::ListAgg(_) => "list_agg",
2018            Expression::ArrayAgg(_) => "array_agg",
2019            Expression::CountIf(_) => "count_if",
2020            Expression::SumIf(_) => "sum_if",
2021            Expression::Stddev(_) => "stddev",
2022            Expression::StddevPop(_) => "stddev_pop",
2023            Expression::StddevSamp(_) => "stddev_samp",
2024            Expression::Variance(_) => "variance",
2025            Expression::VarPop(_) => "var_pop",
2026            Expression::VarSamp(_) => "var_samp",
2027            Expression::Median(_) => "median",
2028            Expression::Mode(_) => "mode",
2029            Expression::First(_) => "first",
2030            Expression::Last(_) => "last",
2031            Expression::AnyValue(_) => "any_value",
2032            Expression::ApproxDistinct(_) => "approx_distinct",
2033            Expression::ApproxCountDistinct(_) => "approx_count_distinct",
2034            Expression::ApproxPercentile(_) => "approx_percentile",
2035            Expression::Percentile(_) => "percentile",
2036            Expression::LogicalAnd(_) => "logical_and",
2037            Expression::LogicalOr(_) => "logical_or",
2038            Expression::Skewness(_) => "skewness",
2039            Expression::BitwiseCount(_) => "bitwise_count",
2040            Expression::ArrayConcatAgg(_) => "array_concat_agg",
2041            Expression::ArrayUniqueAgg(_) => "array_unique_agg",
2042            Expression::BoolXorAgg(_) => "bool_xor_agg",
2043            Expression::RowNumber(_) => "row_number",
2044            Expression::Rank(_) => "rank",
2045            Expression::DenseRank(_) => "dense_rank",
2046            Expression::NTile(_) => "n_tile",
2047            Expression::Lead(_) => "lead",
2048            Expression::Lag(_) => "lag",
2049            Expression::FirstValue(_) => "first_value",
2050            Expression::LastValue(_) => "last_value",
2051            Expression::NthValue(_) => "nth_value",
2052            Expression::PercentRank(_) => "percent_rank",
2053            Expression::CumeDist(_) => "cume_dist",
2054            Expression::PercentileCont(_) => "percentile_cont",
2055            Expression::PercentileDisc(_) => "percentile_disc",
2056            Expression::Contains(_) => "contains",
2057            Expression::StartsWith(_) => "starts_with",
2058            Expression::EndsWith(_) => "ends_with",
2059            Expression::Position(_) => "position",
2060            Expression::Initcap(_) => "initcap",
2061            Expression::Ascii(_) => "ascii",
2062            Expression::Chr(_) => "chr",
2063            Expression::CharFunc(_) => "char_func",
2064            Expression::Soundex(_) => "soundex",
2065            Expression::Levenshtein(_) => "levenshtein",
2066            Expression::ByteLength(_) => "byte_length",
2067            Expression::Hex(_) => "hex",
2068            Expression::LowerHex(_) => "lower_hex",
2069            Expression::Unicode(_) => "unicode",
2070            Expression::ModFunc(_) => "mod_func",
2071            Expression::Random(_) => "random",
2072            Expression::Rand(_) => "rand",
2073            Expression::TruncFunc(_) => "trunc_func",
2074            Expression::Pi(_) => "pi",
2075            Expression::Radians(_) => "radians",
2076            Expression::Degrees(_) => "degrees",
2077            Expression::Sin(_) => "sin",
2078            Expression::Cos(_) => "cos",
2079            Expression::Tan(_) => "tan",
2080            Expression::Asin(_) => "asin",
2081            Expression::Acos(_) => "acos",
2082            Expression::Atan(_) => "atan",
2083            Expression::Atan2(_) => "atan2",
2084            Expression::IsNan(_) => "is_nan",
2085            Expression::IsInf(_) => "is_inf",
2086            Expression::IntDiv(_) => "int_div",
2087            Expression::Decode(_) => "decode",
2088            Expression::DateFormat(_) => "date_format",
2089            Expression::FormatDate(_) => "format_date",
2090            Expression::Year(_) => "year",
2091            Expression::Month(_) => "month",
2092            Expression::Day(_) => "day",
2093            Expression::Hour(_) => "hour",
2094            Expression::Minute(_) => "minute",
2095            Expression::Second(_) => "second",
2096            Expression::DayOfWeek(_) => "day_of_week",
2097            Expression::DayOfWeekIso(_) => "day_of_week_iso",
2098            Expression::DayOfMonth(_) => "day_of_month",
2099            Expression::DayOfYear(_) => "day_of_year",
2100            Expression::WeekOfYear(_) => "week_of_year",
2101            Expression::Quarter(_) => "quarter",
2102            Expression::AddMonths(_) => "add_months",
2103            Expression::MonthsBetween(_) => "months_between",
2104            Expression::LastDay(_) => "last_day",
2105            Expression::NextDay(_) => "next_day",
2106            Expression::Epoch(_) => "epoch",
2107            Expression::EpochMs(_) => "epoch_ms",
2108            Expression::FromUnixtime(_) => "from_unixtime",
2109            Expression::UnixTimestamp(_) => "unix_timestamp",
2110            Expression::MakeDate(_) => "make_date",
2111            Expression::MakeTimestamp(_) => "make_timestamp",
2112            Expression::TimestampTrunc(_) => "timestamp_trunc",
2113            Expression::TimeStrToUnix(_) => "time_str_to_unix",
2114            Expression::SessionUser(_) => "session_user",
2115            Expression::SHA(_) => "s_h_a",
2116            Expression::SHA1Digest(_) => "s_h_a1_digest",
2117            Expression::TimeToUnix(_) => "time_to_unix",
2118            Expression::ArrayFunc(_) => "array_func",
2119            Expression::ArrayLength(_) => "array_length",
2120            Expression::ArraySize(_) => "array_size",
2121            Expression::Cardinality(_) => "cardinality",
2122            Expression::ArrayContains(_) => "array_contains",
2123            Expression::ArrayPosition(_) => "array_position",
2124            Expression::ArrayAppend(_) => "array_append",
2125            Expression::ArrayPrepend(_) => "array_prepend",
2126            Expression::ArrayConcat(_) => "array_concat",
2127            Expression::ArraySort(_) => "array_sort",
2128            Expression::ArrayReverse(_) => "array_reverse",
2129            Expression::ArrayDistinct(_) => "array_distinct",
2130            Expression::ArrayJoin(_) => "array_join",
2131            Expression::ArrayToString(_) => "array_to_string",
2132            Expression::Unnest(_) => "unnest",
2133            Expression::Explode(_) => "explode",
2134            Expression::ExplodeOuter(_) => "explode_outer",
2135            Expression::ArrayFilter(_) => "array_filter",
2136            Expression::ArrayTransform(_) => "array_transform",
2137            Expression::ArrayFlatten(_) => "array_flatten",
2138            Expression::ArrayCompact(_) => "array_compact",
2139            Expression::ArrayIntersect(_) => "array_intersect",
2140            Expression::ArrayUnion(_) => "array_union",
2141            Expression::ArrayExcept(_) => "array_except",
2142            Expression::ArrayRemove(_) => "array_remove",
2143            Expression::ArrayZip(_) => "array_zip",
2144            Expression::Sequence(_) => "sequence",
2145            Expression::Generate(_) => "generate",
2146            Expression::ExplodingGenerateSeries(_) => "exploding_generate_series",
2147            Expression::ToArray(_) => "to_array",
2148            Expression::StarMap(_) => "star_map",
2149            Expression::StructFunc(_) => "struct_func",
2150            Expression::StructExtract(_) => "struct_extract",
2151            Expression::NamedStruct(_) => "named_struct",
2152            Expression::MapFunc(_) => "map_func",
2153            Expression::MapFromEntries(_) => "map_from_entries",
2154            Expression::MapFromArrays(_) => "map_from_arrays",
2155            Expression::MapKeys(_) => "map_keys",
2156            Expression::MapValues(_) => "map_values",
2157            Expression::MapContainsKey(_) => "map_contains_key",
2158            Expression::MapConcat(_) => "map_concat",
2159            Expression::ElementAt(_) => "element_at",
2160            Expression::TransformKeys(_) => "transform_keys",
2161            Expression::TransformValues(_) => "transform_values",
2162            Expression::FunctionEmits(_) => "function_emits",
2163            Expression::JsonExtract(_) => "json_extract",
2164            Expression::JsonExtractScalar(_) => "json_extract_scalar",
2165            Expression::JsonExtractPath(_) => "json_extract_path",
2166            Expression::JsonArray(_) => "json_array",
2167            Expression::JsonObject(_) => "json_object",
2168            Expression::JsonQuery(_) => "json_query",
2169            Expression::JsonValue(_) => "json_value",
2170            Expression::JsonArrayLength(_) => "json_array_length",
2171            Expression::JsonKeys(_) => "json_keys",
2172            Expression::JsonType(_) => "json_type",
2173            Expression::ParseJson(_) => "parse_json",
2174            Expression::ToJson(_) => "to_json",
2175            Expression::JsonSet(_) => "json_set",
2176            Expression::JsonInsert(_) => "json_insert",
2177            Expression::JsonRemove(_) => "json_remove",
2178            Expression::JsonMergePatch(_) => "json_merge_patch",
2179            Expression::JsonArrayAgg(_) => "json_array_agg",
2180            Expression::JsonObjectAgg(_) => "json_object_agg",
2181            Expression::Convert(_) => "convert",
2182            Expression::Typeof(_) => "typeof",
2183            Expression::Lambda(_) => "lambda",
2184            Expression::Parameter(_) => "parameter",
2185            Expression::Placeholder(_) => "placeholder",
2186            Expression::NamedArgument(_) => "named_argument",
2187            Expression::TableArgument(_) => "table_argument",
2188            Expression::SqlComment(_) => "sql_comment",
2189            Expression::NullSafeEq(_) => "null_safe_eq",
2190            Expression::NullSafeNeq(_) => "null_safe_neq",
2191            Expression::Glob(_) => "glob",
2192            Expression::SimilarTo(_) => "similar_to",
2193            Expression::Any(_) => "any",
2194            Expression::All(_) => "all",
2195            Expression::Overlaps(_) => "overlaps",
2196            Expression::BitwiseLeftShift(_) => "bitwise_left_shift",
2197            Expression::BitwiseRightShift(_) => "bitwise_right_shift",
2198            Expression::BitwiseAndAgg(_) => "bitwise_and_agg",
2199            Expression::BitwiseOrAgg(_) => "bitwise_or_agg",
2200            Expression::BitwiseXorAgg(_) => "bitwise_xor_agg",
2201            Expression::Subscript(_) => "subscript",
2202            Expression::Dot(_) => "dot",
2203            Expression::MethodCall(_) => "method_call",
2204            Expression::ArraySlice(_) => "array_slice",
2205            Expression::CreateTable(_) => "create_table",
2206            Expression::DropTable(_) => "drop_table",
2207            Expression::Undrop(_) => "undrop",
2208            Expression::AlterTable(_) => "alter_table",
2209            Expression::SplitTable(_) => "split_table",
2210            Expression::FlashbackTable(_) => "flashback_table",
2211            Expression::CreateIndex(_) => "create_index",
2212            Expression::DropIndex(_) => "drop_index",
2213            Expression::CreateView(_) => "create_view",
2214            Expression::DropView(_) => "drop_view",
2215            Expression::AlterView(_) => "alter_view",
2216            Expression::AlterIndex(_) => "alter_index",
2217            Expression::Truncate(_) => "truncate",
2218            Expression::Use(_) => "use",
2219            Expression::Cache(_) => "cache",
2220            Expression::Uncache(_) => "uncache",
2221            Expression::LoadData(_) => "load_data",
2222            Expression::Pragma(_) => "pragma",
2223            Expression::Grant(_) => "grant",
2224            Expression::Revoke(_) => "revoke",
2225            Expression::Comment(_) => "comment",
2226            Expression::SetStatement(_) => "set_statement",
2227            Expression::CreateSchema(_) => "create_schema",
2228            Expression::DropSchema(_) => "drop_schema",
2229            Expression::DropNamespace(_) => "drop_namespace",
2230            Expression::CreateDatabase(_) => "create_database",
2231            Expression::DropDatabase(_) => "drop_database",
2232            Expression::CreateFunction(_) => "create_function",
2233            Expression::DropFunction(_) => "drop_function",
2234            Expression::CreateProcedure(_) => "create_procedure",
2235            Expression::DropProcedure(_) => "drop_procedure",
2236            Expression::CreateSequence(_) => "create_sequence",
2237            Expression::CreateSynonym(_) => "create_synonym",
2238            Expression::DropSequence(_) => "drop_sequence",
2239            Expression::AlterSequence(_) => "alter_sequence",
2240            Expression::CreateTrigger(_) => "create_trigger",
2241            Expression::DropTrigger(_) => "drop_trigger",
2242            Expression::CreateType(_) => "create_type",
2243            Expression::DropType(_) => "drop_type",
2244            Expression::Describe(_) => "describe",
2245            Expression::Show(_) => "show",
2246            Expression::Command(_) => "command",
2247            Expression::TryCatch(_) => "try_catch",
2248            Expression::Kill(_) => "kill",
2249            Expression::Prepare(_) => "prepare",
2250            Expression::Execute(_) => "execute",
2251            Expression::Raw(_) => "raw",
2252            Expression::CreateTask(_) => "create_task",
2253            Expression::Paren(_) => "paren",
2254            Expression::Annotated(_) => "annotated",
2255            Expression::Refresh(_) => "refresh",
2256            Expression::LockingStatement(_) => "locking_statement",
2257            Expression::SequenceProperties(_) => "sequence_properties",
2258            Expression::TruncateTable(_) => "truncate_table",
2259            Expression::Clone(_) => "clone",
2260            Expression::Attach(_) => "attach",
2261            Expression::Detach(_) => "detach",
2262            Expression::Install(_) => "install",
2263            Expression::Summarize(_) => "summarize",
2264            Expression::Declare(_) => "declare",
2265            Expression::DeclareItem(_) => "declare_item",
2266            Expression::Set(_) => "set",
2267            Expression::Heredoc(_) => "heredoc",
2268            Expression::SetItem(_) => "set_item",
2269            Expression::QueryBand(_) => "query_band",
2270            Expression::UserDefinedFunction(_) => "user_defined_function",
2271            Expression::RecursiveWithSearch(_) => "recursive_with_search",
2272            Expression::ProjectionDef(_) => "projection_def",
2273            Expression::TableAlias(_) => "table_alias",
2274            Expression::ByteString(_) => "byte_string",
2275            Expression::HexStringExpr(_) => "hex_string_expr",
2276            Expression::UnicodeString(_) => "unicode_string",
2277            Expression::ColumnPosition(_) => "column_position",
2278            Expression::ColumnDef(_) => "column_def",
2279            Expression::AlterColumn(_) => "alter_column",
2280            Expression::AlterSortKey(_) => "alter_sort_key",
2281            Expression::AlterSet(_) => "alter_set",
2282            Expression::RenameColumn(_) => "rename_column",
2283            Expression::Comprehension(_) => "comprehension",
2284            Expression::MergeTreeTTLAction(_) => "merge_tree_t_t_l_action",
2285            Expression::MergeTreeTTL(_) => "merge_tree_t_t_l",
2286            Expression::IndexConstraintOption(_) => "index_constraint_option",
2287            Expression::ColumnConstraint(_) => "column_constraint",
2288            Expression::PeriodForSystemTimeConstraint(_) => "period_for_system_time_constraint",
2289            Expression::CaseSpecificColumnConstraint(_) => "case_specific_column_constraint",
2290            Expression::CharacterSetColumnConstraint(_) => "character_set_column_constraint",
2291            Expression::CheckColumnConstraint(_) => "check_column_constraint",
2292            Expression::AssumeColumnConstraint(_) => "assume_column_constraint",
2293            Expression::CompressColumnConstraint(_) => "compress_column_constraint",
2294            Expression::DateFormatColumnConstraint(_) => "date_format_column_constraint",
2295            Expression::EphemeralColumnConstraint(_) => "ephemeral_column_constraint",
2296            Expression::WithOperator(_) => "with_operator",
2297            Expression::GeneratedAsIdentityColumnConstraint(_) => {
2298                "generated_as_identity_column_constraint"
2299            }
2300            Expression::AutoIncrementColumnConstraint(_) => "auto_increment_column_constraint",
2301            Expression::CommentColumnConstraint(_) => "comment_column_constraint",
2302            Expression::GeneratedAsRowColumnConstraint(_) => "generated_as_row_column_constraint",
2303            Expression::IndexColumnConstraint(_) => "index_column_constraint",
2304            Expression::MaskingPolicyColumnConstraint(_) => "masking_policy_column_constraint",
2305            Expression::NotNullColumnConstraint(_) => "not_null_column_constraint",
2306            Expression::PrimaryKeyColumnConstraint(_) => "primary_key_column_constraint",
2307            Expression::UniqueColumnConstraint(_) => "unique_column_constraint",
2308            Expression::WatermarkColumnConstraint(_) => "watermark_column_constraint",
2309            Expression::ComputedColumnConstraint(_) => "computed_column_constraint",
2310            Expression::InOutColumnConstraint(_) => "in_out_column_constraint",
2311            Expression::DefaultColumnConstraint(_) => "default_column_constraint",
2312            Expression::PathColumnConstraint(_) => "path_column_constraint",
2313            Expression::Constraint(_) => "constraint",
2314            Expression::Export(_) => "export",
2315            Expression::Filter(_) => "filter",
2316            Expression::Changes(_) => "changes",
2317            Expression::CopyParameter(_) => "copy_parameter",
2318            Expression::Credentials(_) => "credentials",
2319            Expression::Directory(_) => "directory",
2320            Expression::ForeignKey(_) => "foreign_key",
2321            Expression::ColumnPrefix(_) => "column_prefix",
2322            Expression::PrimaryKey(_) => "primary_key",
2323            Expression::IntoClause(_) => "into_clause",
2324            Expression::JoinHint(_) => "join_hint",
2325            Expression::Opclass(_) => "opclass",
2326            Expression::Index(_) => "index",
2327            Expression::IndexParameters(_) => "index_parameters",
2328            Expression::ConditionalInsert(_) => "conditional_insert",
2329            Expression::MultitableInserts(_) => "multitable_inserts",
2330            Expression::OnConflict(_) => "on_conflict",
2331            Expression::OnCondition(_) => "on_condition",
2332            Expression::Returning(_) => "returning",
2333            Expression::Introducer(_) => "introducer",
2334            Expression::PartitionRange(_) => "partition_range",
2335            Expression::Fetch(_) => "fetch",
2336            Expression::Group(_) => "group",
2337            Expression::Cube(_) => "cube",
2338            Expression::Rollup(_) => "rollup",
2339            Expression::GroupingSets(_) => "grouping_sets",
2340            Expression::LimitOptions(_) => "limit_options",
2341            Expression::Lateral(_) => "lateral",
2342            Expression::TableFromRows(_) => "table_from_rows",
2343            Expression::RowsFrom(_) => "rows_from",
2344            Expression::MatchRecognizeMeasure(_) => "match_recognize_measure",
2345            Expression::WithFill(_) => "with_fill",
2346            Expression::Property(_) => "property",
2347            Expression::GrantPrivilege(_) => "grant_privilege",
2348            Expression::GrantPrincipal(_) => "grant_principal",
2349            Expression::AllowedValuesProperty(_) => "allowed_values_property",
2350            Expression::AlgorithmProperty(_) => "algorithm_property",
2351            Expression::AutoIncrementProperty(_) => "auto_increment_property",
2352            Expression::AutoRefreshProperty(_) => "auto_refresh_property",
2353            Expression::BackupProperty(_) => "backup_property",
2354            Expression::BuildProperty(_) => "build_property",
2355            Expression::BlockCompressionProperty(_) => "block_compression_property",
2356            Expression::CharacterSetProperty(_) => "character_set_property",
2357            Expression::ChecksumProperty(_) => "checksum_property",
2358            Expression::CollateProperty(_) => "collate_property",
2359            Expression::DataBlocksizeProperty(_) => "data_blocksize_property",
2360            Expression::DataDeletionProperty(_) => "data_deletion_property",
2361            Expression::DefinerProperty(_) => "definer_property",
2362            Expression::DistKeyProperty(_) => "dist_key_property",
2363            Expression::DistributedByProperty(_) => "distributed_by_property",
2364            Expression::DistStyleProperty(_) => "dist_style_property",
2365            Expression::DuplicateKeyProperty(_) => "duplicate_key_property",
2366            Expression::EngineProperty(_) => "engine_property",
2367            Expression::ToTableProperty(_) => "to_table_property",
2368            Expression::ExecuteAsProperty(_) => "execute_as_property",
2369            Expression::ExternalProperty(_) => "external_property",
2370            Expression::FallbackProperty(_) => "fallback_property",
2371            Expression::FileFormatProperty(_) => "file_format_property",
2372            Expression::CredentialsProperty(_) => "credentials_property",
2373            Expression::FreespaceProperty(_) => "freespace_property",
2374            Expression::InheritsProperty(_) => "inherits_property",
2375            Expression::InputModelProperty(_) => "input_model_property",
2376            Expression::OutputModelProperty(_) => "output_model_property",
2377            Expression::IsolatedLoadingProperty(_) => "isolated_loading_property",
2378            Expression::JournalProperty(_) => "journal_property",
2379            Expression::LanguageProperty(_) => "language_property",
2380            Expression::EnviromentProperty(_) => "enviroment_property",
2381            Expression::ClusteredByProperty(_) => "clustered_by_property",
2382            Expression::DictProperty(_) => "dict_property",
2383            Expression::DictRange(_) => "dict_range",
2384            Expression::OnCluster(_) => "on_cluster",
2385            Expression::LikeProperty(_) => "like_property",
2386            Expression::LocationProperty(_) => "location_property",
2387            Expression::LockProperty(_) => "lock_property",
2388            Expression::LockingProperty(_) => "locking_property",
2389            Expression::LogProperty(_) => "log_property",
2390            Expression::MaterializedProperty(_) => "materialized_property",
2391            Expression::MergeBlockRatioProperty(_) => "merge_block_ratio_property",
2392            Expression::OnProperty(_) => "on_property",
2393            Expression::OnCommitProperty(_) => "on_commit_property",
2394            Expression::PartitionedByProperty(_) => "partitioned_by_property",
2395            Expression::PartitionByProperty(_) => "partition_by_property",
2396            Expression::PartitionedByBucket(_) => "partitioned_by_bucket",
2397            Expression::ClusterByColumnsProperty(_) => "cluster_by_columns_property",
2398            Expression::PartitionByTruncate(_) => "partition_by_truncate",
2399            Expression::PartitionByRangeProperty(_) => "partition_by_range_property",
2400            Expression::PartitionByRangePropertyDynamic(_) => "partition_by_range_property_dynamic",
2401            Expression::PartitionByListProperty(_) => "partition_by_list_property",
2402            Expression::PartitionList(_) => "partition_list",
2403            Expression::Partition(_) => "partition",
2404            Expression::RefreshTriggerProperty(_) => "refresh_trigger_property",
2405            Expression::UniqueKeyProperty(_) => "unique_key_property",
2406            Expression::RollupProperty(_) => "rollup_property",
2407            Expression::PartitionBoundSpec(_) => "partition_bound_spec",
2408            Expression::PartitionedOfProperty(_) => "partitioned_of_property",
2409            Expression::RemoteWithConnectionModelProperty(_) => {
2410                "remote_with_connection_model_property"
2411            }
2412            Expression::ReturnsProperty(_) => "returns_property",
2413            Expression::RowFormatProperty(_) => "row_format_property",
2414            Expression::RowFormatDelimitedProperty(_) => "row_format_delimited_property",
2415            Expression::RowFormatSerdeProperty(_) => "row_format_serde_property",
2416            Expression::QueryTransform(_) => "query_transform",
2417            Expression::SampleProperty(_) => "sample_property",
2418            Expression::SecurityProperty(_) => "security_property",
2419            Expression::SchemaCommentProperty(_) => "schema_comment_property",
2420            Expression::SemanticView(_) => "semantic_view",
2421            Expression::SerdeProperties(_) => "serde_properties",
2422            Expression::SetProperty(_) => "set_property",
2423            Expression::SharingProperty(_) => "sharing_property",
2424            Expression::SetConfigProperty(_) => "set_config_property",
2425            Expression::SettingsProperty(_) => "settings_property",
2426            Expression::SortKeyProperty(_) => "sort_key_property",
2427            Expression::SqlReadWriteProperty(_) => "sql_read_write_property",
2428            Expression::SqlSecurityProperty(_) => "sql_security_property",
2429            Expression::StabilityProperty(_) => "stability_property",
2430            Expression::StorageHandlerProperty(_) => "storage_handler_property",
2431            Expression::TemporaryProperty(_) => "temporary_property",
2432            Expression::Tags(_) => "tags",
2433            Expression::TransformModelProperty(_) => "transform_model_property",
2434            Expression::TransientProperty(_) => "transient_property",
2435            Expression::UsingTemplateProperty(_) => "using_template_property",
2436            Expression::ViewAttributeProperty(_) => "view_attribute_property",
2437            Expression::VolatileProperty(_) => "volatile_property",
2438            Expression::WithDataProperty(_) => "with_data_property",
2439            Expression::WithJournalTableProperty(_) => "with_journal_table_property",
2440            Expression::WithSchemaBindingProperty(_) => "with_schema_binding_property",
2441            Expression::WithSystemVersioningProperty(_) => "with_system_versioning_property",
2442            Expression::WithProcedureOptions(_) => "with_procedure_options",
2443            Expression::EncodeProperty(_) => "encode_property",
2444            Expression::IncludeProperty(_) => "include_property",
2445            Expression::Properties(_) => "properties",
2446            Expression::OptionsProperty(_) => "options_property",
2447            Expression::InputOutputFormat(_) => "input_output_format",
2448            Expression::Reference(_) => "reference",
2449            Expression::QueryOption(_) => "query_option",
2450            Expression::WithTableHint(_) => "with_table_hint",
2451            Expression::IndexTableHint(_) => "index_table_hint",
2452            Expression::HistoricalData(_) => "historical_data",
2453            Expression::Get(_) => "get",
2454            Expression::SetOperation(_) => "set_operation",
2455            Expression::Var(_) => "var",
2456            Expression::Variadic(_) => "variadic",
2457            Expression::Version(_) => "version",
2458            Expression::Schema(_) => "schema",
2459            Expression::Lock(_) => "lock",
2460            Expression::TableSample(_) => "table_sample",
2461            Expression::Tag(_) => "tag",
2462            Expression::UnpivotColumns(_) => "unpivot_columns",
2463            Expression::WindowSpec(_) => "window_spec",
2464            Expression::SessionParameter(_) => "session_parameter",
2465            Expression::PseudoType(_) => "pseudo_type",
2466            Expression::ObjectIdentifier(_) => "object_identifier",
2467            Expression::Transaction(_) => "transaction",
2468            Expression::Commit(_) => "commit",
2469            Expression::Rollback(_) => "rollback",
2470            Expression::AlterSession(_) => "alter_session",
2471            Expression::Analyze(_) => "analyze",
2472            Expression::AnalyzeStatistics(_) => "analyze_statistics",
2473            Expression::AnalyzeHistogram(_) => "analyze_histogram",
2474            Expression::AnalyzeSample(_) => "analyze_sample",
2475            Expression::AnalyzeListChainedRows(_) => "analyze_list_chained_rows",
2476            Expression::AnalyzeDelete(_) => "analyze_delete",
2477            Expression::AnalyzeWith(_) => "analyze_with",
2478            Expression::AnalyzeValidate(_) => "analyze_validate",
2479            Expression::AddPartition(_) => "add_partition",
2480            Expression::AttachOption(_) => "attach_option",
2481            Expression::DropPartition(_) => "drop_partition",
2482            Expression::ReplacePartition(_) => "replace_partition",
2483            Expression::DPipe(_) => "d_pipe",
2484            Expression::Operator(_) => "operator",
2485            Expression::PivotAny(_) => "pivot_any",
2486            Expression::Aliases(_) => "aliases",
2487            Expression::AtIndex(_) => "at_index",
2488            Expression::FromTimeZone(_) => "from_time_zone",
2489            Expression::FormatPhrase(_) => "format_phrase",
2490            Expression::ForIn(_) => "for_in",
2491            Expression::TimeUnit(_) => "time_unit",
2492            Expression::IntervalOp(_) => "interval_op",
2493            Expression::IntervalSpan(_) => "interval_span",
2494            Expression::HavingMax(_) => "having_max",
2495            Expression::CosineDistance(_) => "cosine_distance",
2496            Expression::DotProduct(_) => "dot_product",
2497            Expression::EuclideanDistance(_) => "euclidean_distance",
2498            Expression::ManhattanDistance(_) => "manhattan_distance",
2499            Expression::JarowinklerSimilarity(_) => "jarowinkler_similarity",
2500            Expression::Booland(_) => "booland",
2501            Expression::Boolor(_) => "boolor",
2502            Expression::ParameterizedAgg(_) => "parameterized_agg",
2503            Expression::ArgMax(_) => "arg_max",
2504            Expression::ArgMin(_) => "arg_min",
2505            Expression::ApproxTopK(_) => "approx_top_k",
2506            Expression::ApproxTopKAccumulate(_) => "approx_top_k_accumulate",
2507            Expression::ApproxTopKCombine(_) => "approx_top_k_combine",
2508            Expression::ApproxTopKEstimate(_) => "approx_top_k_estimate",
2509            Expression::ApproxTopSum(_) => "approx_top_sum",
2510            Expression::ApproxQuantiles(_) => "approx_quantiles",
2511            Expression::Minhash(_) => "minhash",
2512            Expression::FarmFingerprint(_) => "farm_fingerprint",
2513            Expression::Float64(_) => "float64",
2514            Expression::Transform(_) => "transform",
2515            Expression::Translate(_) => "translate",
2516            Expression::Grouping(_) => "grouping",
2517            Expression::GroupingId(_) => "grouping_id",
2518            Expression::Anonymous(_) => "anonymous",
2519            Expression::AnonymousAggFunc(_) => "anonymous_agg_func",
2520            Expression::CombinedAggFunc(_) => "combined_agg_func",
2521            Expression::CombinedParameterizedAgg(_) => "combined_parameterized_agg",
2522            Expression::HashAgg(_) => "hash_agg",
2523            Expression::Hll(_) => "hll",
2524            Expression::Apply(_) => "apply",
2525            Expression::ToBoolean(_) => "to_boolean",
2526            Expression::List(_) => "list",
2527            Expression::ToMap(_) => "to_map",
2528            Expression::Pad(_) => "pad",
2529            Expression::ToChar(_) => "to_char",
2530            Expression::ToNumber(_) => "to_number",
2531            Expression::ToDouble(_) => "to_double",
2532            Expression::Int64(_) => "int64",
2533            Expression::StringFunc(_) => "string_func",
2534            Expression::ToDecfloat(_) => "to_decfloat",
2535            Expression::TryToDecfloat(_) => "try_to_decfloat",
2536            Expression::ToFile(_) => "to_file",
2537            Expression::Columns(_) => "columns",
2538            Expression::ConvertToCharset(_) => "convert_to_charset",
2539            Expression::ConvertTimezone(_) => "convert_timezone",
2540            Expression::GenerateSeries(_) => "generate_series",
2541            Expression::AIAgg(_) => "a_i_agg",
2542            Expression::AIClassify(_) => "a_i_classify",
2543            Expression::ArrayAll(_) => "array_all",
2544            Expression::ArrayAny(_) => "array_any",
2545            Expression::ArrayConstructCompact(_) => "array_construct_compact",
2546            Expression::StPoint(_) => "st_point",
2547            Expression::StDistance(_) => "st_distance",
2548            Expression::StringToArray(_) => "string_to_array",
2549            Expression::ArraySum(_) => "array_sum",
2550            Expression::ObjectAgg(_) => "object_agg",
2551            Expression::CastToStrType(_) => "cast_to_str_type",
2552            Expression::CheckJson(_) => "check_json",
2553            Expression::CheckXml(_) => "check_xml",
2554            Expression::TranslateCharacters(_) => "translate_characters",
2555            Expression::CurrentSchemas(_) => "current_schemas",
2556            Expression::CurrentDatetime(_) => "current_datetime",
2557            Expression::Localtime(_) => "localtime",
2558            Expression::Localtimestamp(_) => "localtimestamp",
2559            Expression::Systimestamp(_) => "systimestamp",
2560            Expression::CurrentSchema(_) => "current_schema",
2561            Expression::CurrentUser(_) => "current_user",
2562            Expression::UtcTime(_) => "utc_time",
2563            Expression::UtcTimestamp(_) => "utc_timestamp",
2564            Expression::Timestamp(_) => "timestamp",
2565            Expression::DateBin(_) => "date_bin",
2566            Expression::Datetime(_) => "datetime",
2567            Expression::DatetimeAdd(_) => "datetime_add",
2568            Expression::DatetimeSub(_) => "datetime_sub",
2569            Expression::DatetimeDiff(_) => "datetime_diff",
2570            Expression::DatetimeTrunc(_) => "datetime_trunc",
2571            Expression::Dayname(_) => "dayname",
2572            Expression::MakeInterval(_) => "make_interval",
2573            Expression::PreviousDay(_) => "previous_day",
2574            Expression::Elt(_) => "elt",
2575            Expression::TimestampAdd(_) => "timestamp_add",
2576            Expression::TimestampSub(_) => "timestamp_sub",
2577            Expression::TimestampDiff(_) => "timestamp_diff",
2578            Expression::TimeSlice(_) => "time_slice",
2579            Expression::TimeAdd(_) => "time_add",
2580            Expression::TimeSub(_) => "time_sub",
2581            Expression::TimeDiff(_) => "time_diff",
2582            Expression::TimeTrunc(_) => "time_trunc",
2583            Expression::DateFromParts(_) => "date_from_parts",
2584            Expression::TimeFromParts(_) => "time_from_parts",
2585            Expression::DecodeCase(_) => "decode_case",
2586            Expression::Decrypt(_) => "decrypt",
2587            Expression::DecryptRaw(_) => "decrypt_raw",
2588            Expression::Encode(_) => "encode",
2589            Expression::Encrypt(_) => "encrypt",
2590            Expression::EncryptRaw(_) => "encrypt_raw",
2591            Expression::EqualNull(_) => "equal_null",
2592            Expression::ToBinary(_) => "to_binary",
2593            Expression::Base64DecodeBinary(_) => "base64_decode_binary",
2594            Expression::Base64DecodeString(_) => "base64_decode_string",
2595            Expression::Base64Encode(_) => "base64_encode",
2596            Expression::TryBase64DecodeBinary(_) => "try_base64_decode_binary",
2597            Expression::TryBase64DecodeString(_) => "try_base64_decode_string",
2598            Expression::GapFill(_) => "gap_fill",
2599            Expression::GenerateDateArray(_) => "generate_date_array",
2600            Expression::GenerateTimestampArray(_) => "generate_timestamp_array",
2601            Expression::GetExtract(_) => "get_extract",
2602            Expression::Getbit(_) => "getbit",
2603            Expression::OverflowTruncateBehavior(_) => "overflow_truncate_behavior",
2604            Expression::HexEncode(_) => "hex_encode",
2605            Expression::Compress(_) => "compress",
2606            Expression::DecompressBinary(_) => "decompress_binary",
2607            Expression::DecompressString(_) => "decompress_string",
2608            Expression::Xor(_) => "xor",
2609            Expression::Nullif(_) => "nullif",
2610            Expression::JSON(_) => "j_s_o_n",
2611            Expression::JSONPath(_) => "j_s_o_n_path",
2612            Expression::JSONPathFilter(_) => "j_s_o_n_path_filter",
2613            Expression::JSONPathKey(_) => "j_s_o_n_path_key",
2614            Expression::JSONPathRecursive(_) => "j_s_o_n_path_recursive",
2615            Expression::JSONPathScript(_) => "j_s_o_n_path_script",
2616            Expression::JSONPathSlice(_) => "j_s_o_n_path_slice",
2617            Expression::JSONPathSelector(_) => "j_s_o_n_path_selector",
2618            Expression::JSONPathSubscript(_) => "j_s_o_n_path_subscript",
2619            Expression::JSONPathUnion(_) => "j_s_o_n_path_union",
2620            Expression::Format(_) => "format",
2621            Expression::JSONKeys(_) => "j_s_o_n_keys",
2622            Expression::JSONKeyValue(_) => "j_s_o_n_key_value",
2623            Expression::JSONKeysAtDepth(_) => "j_s_o_n_keys_at_depth",
2624            Expression::JSONObject(_) => "j_s_o_n_object",
2625            Expression::JSONObjectAgg(_) => "j_s_o_n_object_agg",
2626            Expression::JSONBObjectAgg(_) => "j_s_o_n_b_object_agg",
2627            Expression::JSONArray(_) => "j_s_o_n_array",
2628            Expression::JSONArrayAgg(_) => "j_s_o_n_array_agg",
2629            Expression::JSONExists(_) => "j_s_o_n_exists",
2630            Expression::JSONColumnDef(_) => "j_s_o_n_column_def",
2631            Expression::JSONSchema(_) => "j_s_o_n_schema",
2632            Expression::JSONSet(_) => "j_s_o_n_set",
2633            Expression::JSONStripNulls(_) => "j_s_o_n_strip_nulls",
2634            Expression::JSONValue(_) => "j_s_o_n_value",
2635            Expression::JSONValueArray(_) => "j_s_o_n_value_array",
2636            Expression::JSONRemove(_) => "j_s_o_n_remove",
2637            Expression::JSONTable(_) => "j_s_o_n_table",
2638            Expression::JSONType(_) => "j_s_o_n_type",
2639            Expression::ObjectInsert(_) => "object_insert",
2640            Expression::OpenJSONColumnDef(_) => "open_j_s_o_n_column_def",
2641            Expression::OpenJSON(_) => "open_j_s_o_n",
2642            Expression::JSONBExists(_) => "j_s_o_n_b_exists",
2643            Expression::JSONBContains(_) => "j_s_o_n_b_contains",
2644            Expression::JSONBExtract(_) => "j_s_o_n_b_extract",
2645            Expression::JSONCast(_) => "j_s_o_n_cast",
2646            Expression::JSONExtract(_) => "j_s_o_n_extract",
2647            Expression::JSONExtractQuote(_) => "j_s_o_n_extract_quote",
2648            Expression::JSONExtractArray(_) => "j_s_o_n_extract_array",
2649            Expression::JSONExtractScalar(_) => "j_s_o_n_extract_scalar",
2650            Expression::JSONBExtractScalar(_) => "j_s_o_n_b_extract_scalar",
2651            Expression::JSONFormat(_) => "j_s_o_n_format",
2652            Expression::JSONBool(_) => "j_s_o_n_bool",
2653            Expression::JSONPathRoot(_) => "j_s_o_n_path_root",
2654            Expression::JSONArrayAppend(_) => "j_s_o_n_array_append",
2655            Expression::JSONArrayContains(_) => "j_s_o_n_array_contains",
2656            Expression::JSONArrayInsert(_) => "j_s_o_n_array_insert",
2657            Expression::ParseJSON(_) => "parse_j_s_o_n",
2658            Expression::ParseUrl(_) => "parse_url",
2659            Expression::ParseIp(_) => "parse_ip",
2660            Expression::ParseTime(_) => "parse_time",
2661            Expression::ParseDatetime(_) => "parse_datetime",
2662            Expression::Map(_) => "map",
2663            Expression::MapCat(_) => "map_cat",
2664            Expression::MapDelete(_) => "map_delete",
2665            Expression::MapInsert(_) => "map_insert",
2666            Expression::MapPick(_) => "map_pick",
2667            Expression::ScopeResolution(_) => "scope_resolution",
2668            Expression::Slice(_) => "slice",
2669            Expression::VarMap(_) => "var_map",
2670            Expression::MatchAgainst(_) => "match_against",
2671            Expression::MD5Digest(_) => "m_d5_digest",
2672            Expression::MD5NumberLower64(_) => "m_d5_number_lower64",
2673            Expression::MD5NumberUpper64(_) => "m_d5_number_upper64",
2674            Expression::Monthname(_) => "monthname",
2675            Expression::Ntile(_) => "ntile",
2676            Expression::Normalize(_) => "normalize",
2677            Expression::Normal(_) => "normal",
2678            Expression::Predict(_) => "predict",
2679            Expression::MLTranslate(_) => "m_l_translate",
2680            Expression::FeaturesAtTime(_) => "features_at_time",
2681            Expression::GenerateEmbedding(_) => "generate_embedding",
2682            Expression::MLForecast(_) => "m_l_forecast",
2683            Expression::ModelAttribute(_) => "model_attribute",
2684            Expression::VectorSearch(_) => "vector_search",
2685            Expression::Quantile(_) => "quantile",
2686            Expression::ApproxQuantile(_) => "approx_quantile",
2687            Expression::ApproxPercentileEstimate(_) => "approx_percentile_estimate",
2688            Expression::Randn(_) => "randn",
2689            Expression::Randstr(_) => "randstr",
2690            Expression::RangeN(_) => "range_n",
2691            Expression::RangeBucket(_) => "range_bucket",
2692            Expression::ReadCSV(_) => "read_c_s_v",
2693            Expression::ReadParquet(_) => "read_parquet",
2694            Expression::Reduce(_) => "reduce",
2695            Expression::RegexpExtractAll(_) => "regexp_extract_all",
2696            Expression::RegexpILike(_) => "regexp_i_like",
2697            Expression::RegexpFullMatch(_) => "regexp_full_match",
2698            Expression::RegexpInstr(_) => "regexp_instr",
2699            Expression::RegexpSplit(_) => "regexp_split",
2700            Expression::RegexpCount(_) => "regexp_count",
2701            Expression::RegrValx(_) => "regr_valx",
2702            Expression::RegrValy(_) => "regr_valy",
2703            Expression::RegrAvgy(_) => "regr_avgy",
2704            Expression::RegrAvgx(_) => "regr_avgx",
2705            Expression::RegrCount(_) => "regr_count",
2706            Expression::RegrIntercept(_) => "regr_intercept",
2707            Expression::RegrR2(_) => "regr_r2",
2708            Expression::RegrSxx(_) => "regr_sxx",
2709            Expression::RegrSxy(_) => "regr_sxy",
2710            Expression::RegrSyy(_) => "regr_syy",
2711            Expression::RegrSlope(_) => "regr_slope",
2712            Expression::SafeAdd(_) => "safe_add",
2713            Expression::SafeDivide(_) => "safe_divide",
2714            Expression::SafeMultiply(_) => "safe_multiply",
2715            Expression::SafeSubtract(_) => "safe_subtract",
2716            Expression::SHA2(_) => "s_h_a2",
2717            Expression::SHA2Digest(_) => "s_h_a2_digest",
2718            Expression::SortArray(_) => "sort_array",
2719            Expression::SplitPart(_) => "split_part",
2720            Expression::SubstringIndex(_) => "substring_index",
2721            Expression::StandardHash(_) => "standard_hash",
2722            Expression::StrPosition(_) => "str_position",
2723            Expression::Search(_) => "search",
2724            Expression::SearchIp(_) => "search_ip",
2725            Expression::StrToDate(_) => "str_to_date",
2726            Expression::DateStrToDate(_) => "date_str_to_date",
2727            Expression::DateToDateStr(_) => "date_to_date_str",
2728            Expression::StrToTime(_) => "str_to_time",
2729            Expression::StrToUnix(_) => "str_to_unix",
2730            Expression::StrToMap(_) => "str_to_map",
2731            Expression::NumberToStr(_) => "number_to_str",
2732            Expression::FromBase(_) => "from_base",
2733            Expression::Stuff(_) => "stuff",
2734            Expression::TimeToStr(_) => "time_to_str",
2735            Expression::TimeStrToTime(_) => "time_str_to_time",
2736            Expression::TsOrDsAdd(_) => "ts_or_ds_add",
2737            Expression::TsOrDsDiff(_) => "ts_or_ds_diff",
2738            Expression::TsOrDsToDate(_) => "ts_or_ds_to_date",
2739            Expression::TsOrDsToTime(_) => "ts_or_ds_to_time",
2740            Expression::Unhex(_) => "unhex",
2741            Expression::Uniform(_) => "uniform",
2742            Expression::UnixToStr(_) => "unix_to_str",
2743            Expression::UnixToTime(_) => "unix_to_time",
2744            Expression::Uuid(_) => "uuid",
2745            Expression::TimestampFromParts(_) => "timestamp_from_parts",
2746            Expression::TimestampTzFromParts(_) => "timestamp_tz_from_parts",
2747            Expression::Corr(_) => "corr",
2748            Expression::WidthBucket(_) => "width_bucket",
2749            Expression::CovarSamp(_) => "covar_samp",
2750            Expression::CovarPop(_) => "covar_pop",
2751            Expression::Week(_) => "week",
2752            Expression::XMLElement(_) => "x_m_l_element",
2753            Expression::XMLGet(_) => "x_m_l_get",
2754            Expression::XMLTable(_) => "x_m_l_table",
2755            Expression::XMLKeyValueOption(_) => "x_m_l_key_value_option",
2756            Expression::Zipf(_) => "zipf",
2757            Expression::Merge(_) => "merge",
2758            Expression::When(_) => "when",
2759            Expression::Whens(_) => "whens",
2760            Expression::NextValueFor(_) => "next_value_for",
2761            Expression::ReturnStmt(_) => "return_stmt",
2762        }
2763    }
2764
2765    /// Returns the primary child expression (".this" in sqlglot).
2766    pub fn get_this(&self) -> Option<&Expression> {
2767        match self {
2768            // Unary ops
2769            Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this),
2770            // UnaryFunc variants
2771            Expression::Upper(f)
2772            | Expression::Lower(f)
2773            | Expression::Length(f)
2774            | Expression::LTrim(f)
2775            | Expression::RTrim(f)
2776            | Expression::Reverse(f)
2777            | Expression::Abs(f)
2778            | Expression::Sqrt(f)
2779            | Expression::Cbrt(f)
2780            | Expression::Ln(f)
2781            | Expression::Exp(f)
2782            | Expression::Sign(f)
2783            | Expression::Date(f)
2784            | Expression::Time(f)
2785            | Expression::Initcap(f)
2786            | Expression::Ascii(f)
2787            | Expression::Chr(f)
2788            | Expression::Soundex(f)
2789            | Expression::ByteLength(f)
2790            | Expression::Hex(f)
2791            | Expression::LowerHex(f)
2792            | Expression::Unicode(f)
2793            | Expression::Typeof(f)
2794            | Expression::Explode(f)
2795            | Expression::ExplodeOuter(f)
2796            | Expression::MapFromEntries(f)
2797            | Expression::MapKeys(f)
2798            | Expression::MapValues(f)
2799            | Expression::ArrayLength(f)
2800            | Expression::ArraySize(f)
2801            | Expression::Cardinality(f)
2802            | Expression::ArrayReverse(f)
2803            | Expression::ArrayDistinct(f)
2804            | Expression::ArrayFlatten(f)
2805            | Expression::ArrayCompact(f)
2806            | Expression::ToArray(f)
2807            | Expression::JsonArrayLength(f)
2808            | Expression::JsonKeys(f)
2809            | Expression::JsonType(f)
2810            | Expression::ParseJson(f)
2811            | Expression::ToJson(f)
2812            | Expression::Radians(f)
2813            | Expression::Degrees(f)
2814            | Expression::Sin(f)
2815            | Expression::Cos(f)
2816            | Expression::Tan(f)
2817            | Expression::Asin(f)
2818            | Expression::Acos(f)
2819            | Expression::Atan(f)
2820            | Expression::IsNan(f)
2821            | Expression::IsInf(f)
2822            | Expression::Year(f)
2823            | Expression::Month(f)
2824            | Expression::Day(f)
2825            | Expression::Hour(f)
2826            | Expression::Minute(f)
2827            | Expression::Second(f)
2828            | Expression::DayOfWeek(f)
2829            | Expression::DayOfWeekIso(f)
2830            | Expression::DayOfMonth(f)
2831            | Expression::DayOfYear(f)
2832            | Expression::WeekOfYear(f)
2833            | Expression::Quarter(f)
2834            | Expression::Epoch(f)
2835            | Expression::EpochMs(f)
2836            | Expression::BitwiseCount(f)
2837            | Expression::DateFromUnixDate(f)
2838            | Expression::UnixDate(f)
2839            | Expression::UnixSeconds(f)
2840            | Expression::UnixMillis(f)
2841            | Expression::UnixMicros(f)
2842            | Expression::TimeStrToDate(f)
2843            | Expression::DateToDi(f)
2844            | Expression::DiToDate(f)
2845            | Expression::TsOrDiToDi(f)
2846            | Expression::TsOrDsToDatetime(f)
2847            | Expression::TsOrDsToTimestamp(f)
2848            | Expression::YearOfWeek(f)
2849            | Expression::YearOfWeekIso(f)
2850            | Expression::SHA(f)
2851            | Expression::SHA1Digest(f)
2852            | Expression::TimeToUnix(f)
2853            | Expression::TimeStrToUnix(f)
2854            | Expression::Int64(f)
2855            | Expression::JSONBool(f)
2856            | Expression::MD5NumberLower64(f)
2857            | Expression::MD5NumberUpper64(f)
2858            | Expression::DateStrToDate(f)
2859            | Expression::DateToDateStr(f) => Some(&f.this),
2860            // BinaryFunc - this is the primary child
2861            Expression::Power(f)
2862            | Expression::NullIf(f)
2863            | Expression::IfNull(f)
2864            | Expression::Nvl(f)
2865            | Expression::Contains(f)
2866            | Expression::StartsWith(f)
2867            | Expression::EndsWith(f)
2868            | Expression::Levenshtein(f)
2869            | Expression::ModFunc(f)
2870            | Expression::IntDiv(f)
2871            | Expression::Atan2(f)
2872            | Expression::AddMonths(f)
2873            | Expression::MonthsBetween(f)
2874            | Expression::NextDay(f)
2875            | Expression::UnixToTimeStr(f)
2876            | Expression::ArrayContains(f)
2877            | Expression::ArrayPosition(f)
2878            | Expression::ArrayAppend(f)
2879            | Expression::ArrayPrepend(f)
2880            | Expression::ArrayUnion(f)
2881            | Expression::ArrayExcept(f)
2882            | Expression::ArrayRemove(f)
2883            | Expression::StarMap(f)
2884            | Expression::MapFromArrays(f)
2885            | Expression::MapContainsKey(f)
2886            | Expression::ElementAt(f)
2887            | Expression::JsonMergePatch(f)
2888            | Expression::JSONBContains(f)
2889            | Expression::JSONBExtract(f) => Some(&f.this),
2890            // AggFunc - this is the primary child
2891            Expression::Sum(af)
2892            | Expression::Avg(af)
2893            | Expression::Min(af)
2894            | Expression::Max(af)
2895            | Expression::ArrayAgg(af)
2896            | Expression::CountIf(af)
2897            | Expression::Stddev(af)
2898            | Expression::StddevPop(af)
2899            | Expression::StddevSamp(af)
2900            | Expression::Variance(af)
2901            | Expression::VarPop(af)
2902            | Expression::VarSamp(af)
2903            | Expression::Median(af)
2904            | Expression::Mode(af)
2905            | Expression::First(af)
2906            | Expression::Last(af)
2907            | Expression::AnyValue(af)
2908            | Expression::ApproxDistinct(af)
2909            | Expression::ApproxCountDistinct(af)
2910            | Expression::LogicalAnd(af)
2911            | Expression::LogicalOr(af)
2912            | Expression::Skewness(af)
2913            | Expression::ArrayConcatAgg(af)
2914            | Expression::ArrayUniqueAgg(af)
2915            | Expression::BoolXorAgg(af)
2916            | Expression::BitwiseAndAgg(af)
2917            | Expression::BitwiseOrAgg(af)
2918            | Expression::BitwiseXorAgg(af) => Some(&af.this),
2919            // Binary operations - left is "this" in sqlglot
2920            Expression::And(op)
2921            | Expression::Or(op)
2922            | Expression::Add(op)
2923            | Expression::Sub(op)
2924            | Expression::Mul(op)
2925            | Expression::Div(op)
2926            | Expression::Mod(op)
2927            | Expression::Eq(op)
2928            | Expression::Neq(op)
2929            | Expression::Lt(op)
2930            | Expression::Lte(op)
2931            | Expression::Gt(op)
2932            | Expression::Gte(op)
2933            | Expression::BitwiseAnd(op)
2934            | Expression::BitwiseOr(op)
2935            | Expression::BitwiseXor(op)
2936            | Expression::Concat(op)
2937            | Expression::Adjacent(op)
2938            | Expression::TsMatch(op)
2939            | Expression::PropertyEQ(op)
2940            | Expression::ArrayContainsAll(op)
2941            | Expression::ArrayContainedBy(op)
2942            | Expression::ArrayOverlaps(op)
2943            | Expression::JSONBContainsAllTopKeys(op)
2944            | Expression::JSONBContainsAnyTopKeys(op)
2945            | Expression::JSONBDeleteAtPath(op)
2946            | Expression::ExtendsLeft(op)
2947            | Expression::ExtendsRight(op)
2948            | Expression::Is(op)
2949            | Expression::MemberOf(op)
2950            | Expression::Match(op)
2951            | Expression::NullSafeEq(op)
2952            | Expression::NullSafeNeq(op)
2953            | Expression::Glob(op)
2954            | Expression::BitwiseLeftShift(op)
2955            | Expression::BitwiseRightShift(op) => Some(&op.left),
2956            // Like operations - left is "this"
2957            Expression::Like(op) | Expression::ILike(op) => Some(&op.left),
2958            // Structural types with .this
2959            Expression::Alias(a) => Some(&a.this),
2960            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => Some(&c.this),
2961            Expression::Paren(p) => Some(&p.this),
2962            Expression::Annotated(a) => Some(&a.this),
2963            Expression::Subquery(s) => Some(&s.this),
2964            Expression::Where(w) => Some(&w.this),
2965            Expression::Having(h) => Some(&h.this),
2966            Expression::Qualify(q) => Some(&q.this),
2967            Expression::IsNull(i) => Some(&i.this),
2968            Expression::Exists(e) => Some(&e.this),
2969            Expression::Ordered(o) => Some(&o.this),
2970            Expression::WindowFunction(wf) => Some(&wf.this),
2971            Expression::Cte(cte) => Some(&cte.this),
2972            Expression::Between(b) => Some(&b.this),
2973            Expression::In(i) => Some(&i.this),
2974            Expression::ReturnStmt(e) => Some(e),
2975            _ => None,
2976        }
2977    }
2978
2979    /// Returns the secondary child expression (".expression" in sqlglot).
2980    pub fn get_expression(&self) -> Option<&Expression> {
2981        match self {
2982            // Binary operations - right is "expression"
2983            Expression::And(op)
2984            | Expression::Or(op)
2985            | Expression::Add(op)
2986            | Expression::Sub(op)
2987            | Expression::Mul(op)
2988            | Expression::Div(op)
2989            | Expression::Mod(op)
2990            | Expression::Eq(op)
2991            | Expression::Neq(op)
2992            | Expression::Lt(op)
2993            | Expression::Lte(op)
2994            | Expression::Gt(op)
2995            | Expression::Gte(op)
2996            | Expression::BitwiseAnd(op)
2997            | Expression::BitwiseOr(op)
2998            | Expression::BitwiseXor(op)
2999            | Expression::Concat(op)
3000            | Expression::Adjacent(op)
3001            | Expression::TsMatch(op)
3002            | Expression::PropertyEQ(op)
3003            | Expression::ArrayContainsAll(op)
3004            | Expression::ArrayContainedBy(op)
3005            | Expression::ArrayOverlaps(op)
3006            | Expression::JSONBContainsAllTopKeys(op)
3007            | Expression::JSONBContainsAnyTopKeys(op)
3008            | Expression::JSONBDeleteAtPath(op)
3009            | Expression::ExtendsLeft(op)
3010            | Expression::ExtendsRight(op)
3011            | Expression::Is(op)
3012            | Expression::MemberOf(op)
3013            | Expression::Match(op)
3014            | Expression::NullSafeEq(op)
3015            | Expression::NullSafeNeq(op)
3016            | Expression::Glob(op)
3017            | Expression::BitwiseLeftShift(op)
3018            | Expression::BitwiseRightShift(op) => Some(&op.right),
3019            // Like operations - right is "expression"
3020            Expression::Like(op) | Expression::ILike(op) => Some(&op.right),
3021            // BinaryFunc - expression is the secondary
3022            Expression::Power(f)
3023            | Expression::NullIf(f)
3024            | Expression::IfNull(f)
3025            | Expression::Nvl(f)
3026            | Expression::Contains(f)
3027            | Expression::StartsWith(f)
3028            | Expression::EndsWith(f)
3029            | Expression::Levenshtein(f)
3030            | Expression::ModFunc(f)
3031            | Expression::IntDiv(f)
3032            | Expression::Atan2(f)
3033            | Expression::AddMonths(f)
3034            | Expression::MonthsBetween(f)
3035            | Expression::NextDay(f)
3036            | Expression::UnixToTimeStr(f)
3037            | Expression::ArrayContains(f)
3038            | Expression::ArrayPosition(f)
3039            | Expression::ArrayAppend(f)
3040            | Expression::ArrayPrepend(f)
3041            | Expression::ArrayUnion(f)
3042            | Expression::ArrayExcept(f)
3043            | Expression::ArrayRemove(f)
3044            | Expression::StarMap(f)
3045            | Expression::MapFromArrays(f)
3046            | Expression::MapContainsKey(f)
3047            | Expression::ElementAt(f)
3048            | Expression::JsonMergePatch(f)
3049            | Expression::JSONBContains(f)
3050            | Expression::JSONBExtract(f) => Some(&f.expression),
3051            _ => None,
3052        }
3053    }
3054
3055    /// Returns the list of child expressions (".expressions" in sqlglot).
3056    pub fn get_expressions(&self) -> &[Expression] {
3057        match self {
3058            Expression::Select(s) => &s.expressions,
3059            Expression::Function(f) => &f.args,
3060            Expression::AggregateFunction(f) => &f.args,
3061            Expression::From(f) => &f.expressions,
3062            Expression::GroupBy(g) => &g.expressions,
3063            Expression::In(i) => &i.expressions,
3064            Expression::Array(a) => &a.expressions,
3065            Expression::Tuple(t) => &t.expressions,
3066            Expression::Coalesce(f)
3067            | Expression::Greatest(f)
3068            | Expression::Least(f)
3069            | Expression::ArrayConcat(f)
3070            | Expression::ArrayIntersect(f)
3071            | Expression::ArrayZip(f)
3072            | Expression::MapConcat(f)
3073            | Expression::JsonArray(f) => &f.expressions,
3074            _ => &[],
3075        }
3076    }
3077
3078    /// Returns the name of this expression as a string slice.
3079    pub fn get_name(&self) -> &str {
3080        match self {
3081            Expression::Identifier(id) => &id.name,
3082            Expression::Column(col) => &col.name.name,
3083            Expression::Table(t) => &t.name.name,
3084            Expression::Literal(lit) => lit.value_str(),
3085            Expression::Star(_) => "*",
3086            Expression::Function(f) => &f.name,
3087            Expression::AggregateFunction(f) => &f.name,
3088            Expression::Alias(a) => a.this.get_name(),
3089            Expression::Boolean(b) => {
3090                if b.value {
3091                    "TRUE"
3092                } else {
3093                    "FALSE"
3094                }
3095            }
3096            Expression::Null(_) => "NULL",
3097            _ => "",
3098        }
3099    }
3100
3101    /// Returns the alias name if this expression has one.
3102    pub fn get_alias(&self) -> &str {
3103        match self {
3104            Expression::Alias(a) => &a.alias.name,
3105            Expression::Table(t) => t.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3106            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3107            _ => "",
3108        }
3109    }
3110
3111    /// Returns the output name of this expression (what it shows up as in a SELECT).
3112    pub fn get_output_name(&self) -> &str {
3113        match self {
3114            Expression::Alias(a) => &a.alias.name,
3115            Expression::Column(c) => &c.name.name,
3116            Expression::Identifier(id) => &id.name,
3117            Expression::Literal(lit) => lit.value_str(),
3118            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3119            Expression::Star(_) => "*",
3120            _ => "",
3121        }
3122    }
3123
3124    /// Returns comments attached to this expression.
3125    pub fn get_comments(&self) -> Vec<&str> {
3126        match self {
3127            Expression::Identifier(id) => id.trailing_comments.iter().map(|s| s.as_str()).collect(),
3128            Expression::Column(c) => c.trailing_comments.iter().map(|s| s.as_str()).collect(),
3129            Expression::Star(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3130            Expression::Paren(p) => p.trailing_comments.iter().map(|s| s.as_str()).collect(),
3131            Expression::Annotated(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3132            Expression::Alias(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3133            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
3134                c.trailing_comments.iter().map(|s| s.as_str()).collect()
3135            }
3136            Expression::And(op)
3137            | Expression::Or(op)
3138            | Expression::Add(op)
3139            | Expression::Sub(op)
3140            | Expression::Mul(op)
3141            | Expression::Div(op)
3142            | Expression::Mod(op)
3143            | Expression::Eq(op)
3144            | Expression::Neq(op)
3145            | Expression::Lt(op)
3146            | Expression::Lte(op)
3147            | Expression::Gt(op)
3148            | Expression::Gte(op)
3149            | Expression::Concat(op)
3150            | Expression::BitwiseAnd(op)
3151            | Expression::BitwiseOr(op)
3152            | Expression::BitwiseXor(op) => {
3153                op.trailing_comments.iter().map(|s| s.as_str()).collect()
3154            }
3155            Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(),
3156            Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3157            _ => Vec::new(),
3158        }
3159    }
3160}
3161
3162impl fmt::Display for Expression {
3163    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3164        // Basic display - full SQL generation is in generator module
3165        match self {
3166            Expression::Literal(lit) => write!(f, "{}", lit),
3167            Expression::Identifier(id) => write!(f, "{}", id),
3168            Expression::Column(col) => write!(f, "{}", col),
3169            Expression::Star(_) => write!(f, "*"),
3170            Expression::Null(_) => write!(f, "NULL"),
3171            Expression::Boolean(b) => write!(f, "{}", if b.value { "TRUE" } else { "FALSE" }),
3172            Expression::Select(_) => write!(f, "SELECT ..."),
3173            _ => write!(f, "{:?}", self),
3174        }
3175    }
3176}
3177
3178/// Represent a SQL literal value.
3179///
3180/// Numeric values are stored as their original text representation (not parsed
3181/// to `i64`/`f64`) so that precision, trailing zeros, and hex notation are
3182/// preserved across round-trips.
3183///
3184/// Dialect-specific literal forms (triple-quoted strings, dollar-quoted
3185/// strings, raw strings, etc.) each have a dedicated variant so that the
3186/// generator can emit them with the correct syntax.
3187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3188#[cfg_attr(feature = "bindings", derive(TS))]
3189#[serde(tag = "literal_type", content = "value", rename_all = "snake_case")]
3190pub enum Literal {
3191    /// Single-quoted string literal: `'hello'`
3192    String(String),
3193    /// Numeric literal, stored as the original text: `42`, `3.14`, `1e10`
3194    Number(String),
3195    /// Hex string literal: `X'FF'`
3196    HexString(String),
3197    /// Hex number: 0xA, 0xFF (BigQuery, SQLite style) - represents an integer in hex notation
3198    HexNumber(String),
3199    BitString(String),
3200    /// Byte string: b"..." (BigQuery style)
3201    ByteString(String),
3202    /// National string: N'abc'
3203    NationalString(String),
3204    /// DATE literal: DATE '2024-01-15'
3205    Date(String),
3206    /// TIME literal: TIME '10:30:00'
3207    Time(String),
3208    /// TIMESTAMP literal: TIMESTAMP '2024-01-15 10:30:00'
3209    Timestamp(String),
3210    /// DATETIME literal: DATETIME '2024-01-15 10:30:00' (BigQuery)
3211    Datetime(String),
3212    /// Triple-quoted string: """...""" or '''...'''
3213    /// Contains (content, quote_char) where quote_char is '"' or '\''
3214    TripleQuotedString(String, char),
3215    /// Escape string: E'...' (PostgreSQL)
3216    EscapeString(String),
3217    /// Dollar-quoted string: $$...$$  (PostgreSQL)
3218    DollarString(String),
3219    /// Raw string: r"..." or r'...' (BigQuery, Spark, Databricks)
3220    /// In raw strings, backslashes are literal and not escape characters.
3221    /// When converting to a regular string, backslashes must be doubled.
3222    RawString(String),
3223}
3224
3225impl Literal {
3226    /// Returns the inner value as a string slice, regardless of literal type.
3227    pub fn value_str(&self) -> &str {
3228        match self {
3229            Literal::String(s)
3230            | Literal::Number(s)
3231            | Literal::HexString(s)
3232            | Literal::HexNumber(s)
3233            | Literal::BitString(s)
3234            | Literal::ByteString(s)
3235            | Literal::NationalString(s)
3236            | Literal::Date(s)
3237            | Literal::Time(s)
3238            | Literal::Timestamp(s)
3239            | Literal::Datetime(s)
3240            | Literal::EscapeString(s)
3241            | Literal::DollarString(s)
3242            | Literal::RawString(s) => s.as_str(),
3243            Literal::TripleQuotedString(s, _) => s.as_str(),
3244        }
3245    }
3246
3247    /// Returns `true` if this is a string-type literal.
3248    pub fn is_string(&self) -> bool {
3249        matches!(
3250            self,
3251            Literal::String(_)
3252                | Literal::NationalString(_)
3253                | Literal::EscapeString(_)
3254                | Literal::DollarString(_)
3255                | Literal::RawString(_)
3256                | Literal::TripleQuotedString(_, _)
3257        )
3258    }
3259
3260    /// Returns `true` if this is a numeric literal.
3261    pub fn is_number(&self) -> bool {
3262        matches!(self, Literal::Number(_) | Literal::HexNumber(_))
3263    }
3264}
3265
3266impl fmt::Display for Literal {
3267    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3268        match self {
3269            Literal::String(s) => write!(f, "'{}'", s),
3270            Literal::Number(n) => write!(f, "{}", n),
3271            Literal::HexString(h) => write!(f, "X'{}'", h),
3272            Literal::HexNumber(h) => write!(f, "0x{}", h),
3273            Literal::BitString(b) => write!(f, "B'{}'", b),
3274            Literal::ByteString(b) => write!(f, "b'{}'", b),
3275            Literal::NationalString(s) => write!(f, "N'{}'", s),
3276            Literal::Date(d) => write!(f, "DATE '{}'", d),
3277            Literal::Time(t) => write!(f, "TIME '{}'", t),
3278            Literal::Timestamp(ts) => write!(f, "TIMESTAMP '{}'", ts),
3279            Literal::Datetime(dt) => write!(f, "DATETIME '{}'", dt),
3280            Literal::TripleQuotedString(s, q) => {
3281                write!(f, "{0}{0}{0}{1}{0}{0}{0}", q, s)
3282            }
3283            Literal::EscapeString(s) => write!(f, "E'{}'", s),
3284            Literal::DollarString(s) => write!(f, "$${}$$", s),
3285            Literal::RawString(s) => write!(f, "r'{}'", s),
3286        }
3287    }
3288}
3289
3290/// Boolean literal
3291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3292#[cfg_attr(feature = "bindings", derive(TS))]
3293pub struct BooleanLiteral {
3294    pub value: bool,
3295}
3296
3297/// NULL literal
3298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3299#[cfg_attr(feature = "bindings", derive(TS))]
3300pub struct Null;
3301
3302/// Represent a SQL identifier (table name, column name, alias, keyword-as-name, etc.).
3303///
3304/// The `quoted` flag indicates whether the identifier was originally delimited
3305/// (double-quoted, backtick-quoted, or bracket-quoted depending on the
3306/// dialect). The generator uses this flag to decide whether to emit quoting
3307/// characters.
3308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3309#[cfg_attr(feature = "bindings", derive(TS))]
3310pub struct Identifier {
3311    /// The raw text of the identifier, without any quoting characters.
3312    pub name: String,
3313    /// Whether the identifier was quoted in the source SQL.
3314    pub quoted: bool,
3315    #[serde(default)]
3316    pub trailing_comments: Vec<String>,
3317    /// Source position span (populated during parsing, None for programmatically constructed nodes)
3318    #[serde(default, skip_serializing_if = "Option::is_none")]
3319    pub span: Option<Span>,
3320}
3321
3322impl Identifier {
3323    pub fn new(name: impl Into<String>) -> Self {
3324        Self {
3325            name: name.into(),
3326            quoted: false,
3327            trailing_comments: Vec::new(),
3328            span: None,
3329        }
3330    }
3331
3332    pub fn quoted(name: impl Into<String>) -> Self {
3333        Self {
3334            name: name.into(),
3335            quoted: true,
3336            trailing_comments: Vec::new(),
3337            span: None,
3338        }
3339    }
3340
3341    pub fn empty() -> Self {
3342        Self {
3343            name: String::new(),
3344            quoted: false,
3345            trailing_comments: Vec::new(),
3346            span: None,
3347        }
3348    }
3349
3350    pub fn is_empty(&self) -> bool {
3351        self.name.is_empty()
3352    }
3353
3354    /// Set the source span on this identifier
3355    pub fn with_span(mut self, span: Span) -> Self {
3356        self.span = Some(span);
3357        self
3358    }
3359}
3360
3361impl fmt::Display for Identifier {
3362    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3363        if self.quoted {
3364            write!(f, "\"{}\"", self.name)
3365        } else {
3366            write!(f, "{}", self.name)
3367        }
3368    }
3369}
3370
3371/// Represent a column reference, optionally qualified by a table name.
3372///
3373/// Renders as `name` when unqualified, or `table.name` when qualified.
3374/// Use [`Expression::column()`] or [`Expression::qualified_column()`] for
3375/// convenient construction.
3376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3377#[cfg_attr(feature = "bindings", derive(TS))]
3378pub struct Column {
3379    /// The column name.
3380    pub name: Identifier,
3381    /// Optional table qualifier (e.g. `t` in `t.col`).
3382    pub table: Option<Identifier>,
3383    /// Oracle-style join marker (+) for outer joins
3384    #[serde(default)]
3385    pub join_mark: bool,
3386    /// Trailing comments that appeared after this column reference
3387    #[serde(default)]
3388    pub trailing_comments: Vec<String>,
3389    /// Source position span
3390    #[serde(default, skip_serializing_if = "Option::is_none")]
3391    pub span: Option<Span>,
3392    /// Inferred data type from type annotation
3393    #[serde(default, skip_serializing_if = "Option::is_none")]
3394    #[ast(skip)]
3395    pub inferred_type: Option<DataType>,
3396}
3397
3398impl fmt::Display for Column {
3399    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3400        if let Some(table) = &self.table {
3401            write!(f, "{}.{}", table, self.name)
3402        } else {
3403            write!(f, "{}", self.name)
3404        }
3405    }
3406}
3407
3408/// Represent a table reference with optional schema and catalog qualifiers.
3409///
3410/// Renders as `name`, `schema.name`, or `catalog.schema.name` depending on
3411/// which qualifiers are present. Supports aliases, column alias lists,
3412/// time-travel clauses (Snowflake, BigQuery), table hints (TSQL), and
3413/// several other dialect-specific extensions.
3414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3415#[cfg_attr(feature = "bindings", derive(TS))]
3416pub struct TableRef {
3417    /// The unqualified table name.
3418    pub name: Identifier,
3419    /// Optional schema qualifier (e.g. `public` in `public.users`).
3420    pub schema: Option<Identifier>,
3421    /// Optional catalog qualifier (e.g. `mydb` in `mydb.public.users`).
3422    pub catalog: Option<Identifier>,
3423    /// Optional table alias (e.g. `t` in `FROM users AS t`).
3424    pub alias: Option<Identifier>,
3425    /// Whether AS keyword was explicitly used for the alias
3426    #[serde(default)]
3427    pub alias_explicit_as: bool,
3428    /// Column aliases for table alias: AS t(c1, c2)
3429    #[serde(default)]
3430    pub column_aliases: Vec<Identifier>,
3431    /// Leading comments that appeared before this table reference in a FROM clause
3432    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3433    pub leading_comments: Vec<String>,
3434    /// Trailing comments that appeared after this table reference
3435    #[serde(default)]
3436    pub trailing_comments: Vec<String>,
3437    /// Snowflake time travel: BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
3438    #[serde(default)]
3439    pub when: Option<Box<HistoricalData>>,
3440    /// PostgreSQL ONLY modifier: prevents scanning child tables in inheritance hierarchy
3441    #[serde(default)]
3442    pub only: bool,
3443    /// ClickHouse FINAL modifier: forces final aggregation for MergeTree tables
3444    #[serde(default)]
3445    pub final_: bool,
3446    /// TABLESAMPLE clause attached to this table reference (DuckDB, BigQuery)
3447    #[serde(default, skip_serializing_if = "Option::is_none")]
3448    pub table_sample: Option<Box<Sample>>,
3449    /// TSQL table hints: WITH (TABLOCK, INDEX(myindex), ...)
3450    #[serde(default)]
3451    pub hints: Vec<Expression>,
3452    /// TSQL: FOR SYSTEM_TIME temporal clause
3453    /// Contains the full clause text, e.g., "FOR SYSTEM_TIME BETWEEN c AND d"
3454    #[serde(default, skip_serializing_if = "Option::is_none")]
3455    pub system_time: Option<String>,
3456    /// MySQL: PARTITION(p0, p1, ...) hint for reading from specific partitions
3457    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3458    pub partitions: Vec<Identifier>,
3459    /// Snowflake IDENTIFIER() function: dynamic table name from string/variable
3460    /// When set, this is used instead of the name field
3461    #[serde(default, skip_serializing_if = "Option::is_none")]
3462    pub identifier_func: Option<Box<Expression>>,
3463    /// Snowflake CHANGES clause: CHANGES (INFORMATION => ...) AT (...) END (...)
3464    #[serde(default, skip_serializing_if = "Option::is_none")]
3465    pub changes: Option<Box<Changes>>,
3466    /// Time travel version clause: FOR VERSION AS OF / FOR TIMESTAMP AS OF (Presto/Trino, BigQuery, Databricks)
3467    #[serde(default, skip_serializing_if = "Option::is_none")]
3468    pub version: Option<Box<Version>>,
3469    /// Source position span
3470    #[serde(default, skip_serializing_if = "Option::is_none")]
3471    pub span: Option<Span>,
3472}
3473
3474impl TableRef {
3475    pub fn new(name: impl Into<String>) -> Self {
3476        Self {
3477            name: Identifier::new(name),
3478            schema: None,
3479            catalog: None,
3480            alias: None,
3481            alias_explicit_as: false,
3482            column_aliases: Vec::new(),
3483            leading_comments: Vec::new(),
3484            trailing_comments: Vec::new(),
3485            when: None,
3486            only: false,
3487            final_: false,
3488            table_sample: None,
3489            hints: Vec::new(),
3490            system_time: None,
3491            partitions: Vec::new(),
3492            identifier_func: None,
3493            changes: None,
3494            version: None,
3495            span: None,
3496        }
3497    }
3498
3499    /// Create with a schema qualifier.
3500    pub fn new_with_schema(name: impl Into<String>, schema: impl Into<String>) -> Self {
3501        let mut t = Self::new(name);
3502        t.schema = Some(Identifier::new(schema));
3503        t
3504    }
3505
3506    /// Create with catalog and schema qualifiers.
3507    pub fn new_with_catalog(
3508        name: impl Into<String>,
3509        schema: impl Into<String>,
3510        catalog: impl Into<String>,
3511    ) -> Self {
3512        let mut t = Self::new(name);
3513        t.schema = Some(Identifier::new(schema));
3514        t.catalog = Some(Identifier::new(catalog));
3515        t
3516    }
3517
3518    /// Create from an Identifier, preserving the quoted flag
3519    pub fn from_identifier(name: Identifier) -> Self {
3520        Self {
3521            name,
3522            schema: None,
3523            catalog: None,
3524            alias: None,
3525            alias_explicit_as: false,
3526            column_aliases: Vec::new(),
3527            leading_comments: Vec::new(),
3528            trailing_comments: Vec::new(),
3529            when: None,
3530            only: false,
3531            final_: false,
3532            table_sample: None,
3533            hints: Vec::new(),
3534            system_time: None,
3535            partitions: Vec::new(),
3536            identifier_func: None,
3537            changes: None,
3538            version: None,
3539            span: None,
3540        }
3541    }
3542
3543    pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
3544        self.alias = Some(Identifier::new(alias));
3545        self
3546    }
3547
3548    pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
3549        self.schema = Some(Identifier::new(schema));
3550        self
3551    }
3552}
3553
3554/// Represent a wildcard star expression (`*`, `table.*`).
3555///
3556/// Supports the EXCEPT/EXCLUDE, REPLACE, and RENAME modifiers found in
3557/// DuckDB, BigQuery, and Snowflake (e.g. `SELECT * EXCEPT (id) FROM t`).
3558#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3559#[cfg_attr(feature = "bindings", derive(TS))]
3560pub struct Star {
3561    /// Optional table qualifier (e.g. `t` in `t.*`).
3562    pub table: Option<Identifier>,
3563    /// EXCLUDE / EXCEPT columns (DuckDB, BigQuery, Snowflake)
3564    pub except: Option<Vec<Identifier>>,
3565    /// REPLACE expressions (BigQuery, Snowflake)
3566    pub replace: Option<Vec<Alias>>,
3567    /// RENAME columns (Snowflake)
3568    pub rename: Option<Vec<(Identifier, Identifier)>>,
3569    /// Trailing comments that appeared after the star
3570    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3571    pub trailing_comments: Vec<String>,
3572    /// Source position span
3573    #[serde(default, skip_serializing_if = "Option::is_none")]
3574    pub span: Option<Span>,
3575}
3576
3577/// Represent a complete SELECT statement.
3578///
3579/// This is the most feature-rich AST node, covering the full surface area of
3580/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3581/// `Vec` are omitted from the generated SQL when absent.
3582///
3583/// # Key Fields
3584///
3585/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3586/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3587/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3588/// - `where_clause` -- the WHERE predicate.
3589/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3590/// - `having` -- HAVING predicate.
3591/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3592/// - `limit` / `offset` / `fetch` -- result set limiting.
3593/// - `with` -- Common Table Expressions (CTEs).
3594/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3595/// - `windows` -- named window definitions (WINDOW w AS ...).
3596///
3597/// Dialect-specific extensions are supported via fields like `prewhere`
3598/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3599/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3600#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3601#[cfg_attr(feature = "bindings", derive(TS))]
3602pub struct Select {
3603    /// The select-list: columns, expressions, aliases, and wildcards.
3604    pub expressions: Vec<Expression>,
3605    /// The FROM clause, containing one or more table sources.
3606    pub from: Option<From>,
3607    /// JOIN clauses applied after the FROM source.
3608    pub joins: Vec<Join>,
3609    pub lateral_views: Vec<LateralView>,
3610    /// ClickHouse PREWHERE clause
3611    #[serde(default, skip_serializing_if = "Option::is_none")]
3612    pub prewhere: Option<Expression>,
3613    pub where_clause: Option<Where>,
3614    pub group_by: Option<GroupBy>,
3615    pub having: Option<Having>,
3616    pub qualify: Option<Qualify>,
3617    pub order_by: Option<OrderBy>,
3618    pub distribute_by: Option<DistributeBy>,
3619    pub cluster_by: Option<ClusterBy>,
3620    pub sort_by: Option<SortBy>,
3621    pub limit: Option<Limit>,
3622    pub offset: Option<Offset>,
3623    /// ClickHouse LIMIT BY clause expressions
3624    #[serde(default, skip_serializing_if = "Option::is_none")]
3625    pub limit_by: Option<Vec<Expression>>,
3626    pub fetch: Option<Fetch>,
3627    pub distinct: bool,
3628    pub distinct_on: Option<Vec<Expression>>,
3629    pub top: Option<Top>,
3630    pub with: Option<With>,
3631    pub sample: Option<Sample>,
3632    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3633    #[serde(default, skip_serializing_if = "Option::is_none")]
3634    pub settings: Option<Vec<Expression>>,
3635    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3636    #[serde(default, skip_serializing_if = "Option::is_none")]
3637    pub format: Option<Expression>,
3638    pub windows: Option<Vec<NamedWindow>>,
3639    pub hint: Option<Hint>,
3640    /// Oracle CONNECT BY clause for hierarchical queries
3641    pub connect: Option<Connect>,
3642    /// SELECT ... INTO table_name for creating tables
3643    pub into: Option<SelectInto>,
3644    /// FOR UPDATE/SHARE locking clauses
3645    #[serde(default)]
3646    pub locks: Vec<Lock>,
3647    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3648    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3649    pub for_xml: Vec<Expression>,
3650    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3651    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3652    pub for_json: Vec<Expression>,
3653    /// Leading comments before the statement
3654    #[serde(default)]
3655    pub leading_comments: Vec<String>,
3656    /// Comments that appear after SELECT keyword (before expressions)
3657    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3658    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3659    pub post_select_comments: Vec<String>,
3660    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3661    #[serde(default, skip_serializing_if = "Option::is_none")]
3662    pub kind: Option<String>,
3663    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3664    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3665    pub operation_modifiers: Vec<String>,
3666    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3667    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3668    pub qualify_after_window: bool,
3669    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3670    #[serde(default, skip_serializing_if = "Option::is_none")]
3671    pub option: Option<String>,
3672    /// Redshift-style EXCLUDE clause at the end of the projection list
3673    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3674    #[serde(default, skip_serializing_if = "Option::is_none")]
3675    pub exclude: Option<Vec<Expression>>,
3676}
3677
3678impl Select {
3679    pub fn new() -> Self {
3680        Self {
3681            expressions: Vec::new(),
3682            from: None,
3683            joins: Vec::new(),
3684            lateral_views: Vec::new(),
3685            prewhere: None,
3686            where_clause: None,
3687            group_by: None,
3688            having: None,
3689            qualify: None,
3690            order_by: None,
3691            distribute_by: None,
3692            cluster_by: None,
3693            sort_by: None,
3694            limit: None,
3695            offset: None,
3696            limit_by: None,
3697            fetch: None,
3698            distinct: false,
3699            distinct_on: None,
3700            top: None,
3701            with: None,
3702            sample: None,
3703            settings: None,
3704            format: None,
3705            windows: None,
3706            hint: None,
3707            connect: None,
3708            into: None,
3709            locks: Vec::new(),
3710            for_xml: Vec::new(),
3711            for_json: Vec::new(),
3712            leading_comments: Vec::new(),
3713            post_select_comments: Vec::new(),
3714            kind: None,
3715            operation_modifiers: Vec::new(),
3716            qualify_after_window: false,
3717            option: None,
3718            exclude: None,
3719        }
3720    }
3721
3722    /// Add a column to select
3723    pub fn column(mut self, expr: Expression) -> Self {
3724        self.expressions.push(expr);
3725        self
3726    }
3727
3728    /// Set the FROM clause
3729    pub fn from(mut self, table: Expression) -> Self {
3730        self.from = Some(From {
3731            expressions: vec![table],
3732        });
3733        self
3734    }
3735
3736    /// Add a WHERE clause
3737    pub fn where_(mut self, condition: Expression) -> Self {
3738        self.where_clause = Some(Where { this: condition });
3739        self
3740    }
3741
3742    /// Set DISTINCT
3743    pub fn distinct(mut self) -> Self {
3744        self.distinct = true;
3745        self
3746    }
3747
3748    /// Add a JOIN
3749    pub fn join(mut self, join: Join) -> Self {
3750        self.joins.push(join);
3751        self
3752    }
3753
3754    /// Set ORDER BY
3755    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
3756        self.order_by = Some(OrderBy {
3757            expressions,
3758            siblings: false,
3759            comments: Vec::new(),
3760        });
3761        self
3762    }
3763
3764    /// Set LIMIT
3765    pub fn limit(mut self, n: Expression) -> Self {
3766        self.limit = Some(Limit {
3767            this: n,
3768            percent: false,
3769            comments: Vec::new(),
3770        });
3771        self
3772    }
3773
3774    /// Set OFFSET
3775    pub fn offset(mut self, n: Expression) -> Self {
3776        self.offset = Some(Offset {
3777            this: n,
3778            rows: None,
3779        });
3780        self
3781    }
3782}
3783
3784impl Default for Select {
3785    fn default() -> Self {
3786        Self::new()
3787    }
3788}
3789
3790/// Represent a UNION set operation between two query expressions.
3791///
3792/// When `all` is true, duplicate rows are preserved (UNION ALL).
3793/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
3794/// Supports DuckDB's BY NAME modifier and BigQuery's CORRESPONDING modifier.
3795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3796#[cfg_attr(feature = "bindings", derive(TS))]
3797pub struct Union {
3798    /// The left-hand query operand.
3799    pub left: Expression,
3800    /// The right-hand query operand.
3801    pub right: Expression,
3802    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
3803    pub all: bool,
3804    /// Whether DISTINCT was explicitly specified
3805    #[serde(default)]
3806    pub distinct: bool,
3807    /// Optional WITH clause
3808    pub with: Option<With>,
3809    /// ORDER BY applied to entire UNION result
3810    pub order_by: Option<OrderBy>,
3811    /// LIMIT applied to entire UNION result
3812    pub limit: Option<Box<Expression>>,
3813    /// OFFSET applied to entire UNION result
3814    pub offset: Option<Box<Expression>>,
3815    /// DISTRIBUTE BY clause (Hive/Spark)
3816    #[serde(default, skip_serializing_if = "Option::is_none")]
3817    pub distribute_by: Option<DistributeBy>,
3818    /// SORT BY clause (Hive/Spark)
3819    #[serde(default, skip_serializing_if = "Option::is_none")]
3820    pub sort_by: Option<SortBy>,
3821    /// CLUSTER BY clause (Hive/Spark)
3822    #[serde(default, skip_serializing_if = "Option::is_none")]
3823    pub cluster_by: Option<ClusterBy>,
3824    /// DuckDB BY NAME modifier
3825    #[serde(default)]
3826    pub by_name: bool,
3827    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3828    #[serde(default, skip_serializing_if = "Option::is_none")]
3829    pub side: Option<String>,
3830    /// BigQuery: Set operation kind (INNER)
3831    #[serde(default, skip_serializing_if = "Option::is_none")]
3832    pub kind: Option<String>,
3833    /// BigQuery: CORRESPONDING modifier
3834    #[serde(default)]
3835    pub corresponding: bool,
3836    /// BigQuery: STRICT modifier (before CORRESPONDING)
3837    #[serde(default)]
3838    pub strict: bool,
3839    /// BigQuery: BY (columns) after CORRESPONDING
3840    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3841    pub on_columns: Vec<Expression>,
3842}
3843
3844/// Iteratively flatten the left-recursive chain to prevent stack overflow
3845/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3846impl Drop for Union {
3847    fn drop(&mut self) {
3848        loop {
3849            if let Expression::Union(ref mut inner) = self.left {
3850                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3851                let old_left = std::mem::replace(&mut self.left, next_left);
3852                drop(old_left);
3853            } else {
3854                break;
3855            }
3856        }
3857    }
3858}
3859
3860/// Represent an INTERSECT set operation between two query expressions.
3861///
3862/// Returns only rows that appear in both operands. When `all` is true,
3863/// duplicates are preserved according to their multiplicity.
3864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3865#[cfg_attr(feature = "bindings", derive(TS))]
3866pub struct Intersect {
3867    /// The left-hand query operand.
3868    pub left: Expression,
3869    /// The right-hand query operand.
3870    pub right: Expression,
3871    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
3872    pub all: bool,
3873    /// Whether DISTINCT was explicitly specified
3874    #[serde(default)]
3875    pub distinct: bool,
3876    /// Optional WITH clause
3877    pub with: Option<With>,
3878    /// ORDER BY applied to entire INTERSECT result
3879    pub order_by: Option<OrderBy>,
3880    /// LIMIT applied to entire INTERSECT result
3881    pub limit: Option<Box<Expression>>,
3882    /// OFFSET applied to entire INTERSECT result
3883    pub offset: Option<Box<Expression>>,
3884    /// DISTRIBUTE BY clause (Hive/Spark)
3885    #[serde(default, skip_serializing_if = "Option::is_none")]
3886    pub distribute_by: Option<DistributeBy>,
3887    /// SORT BY clause (Hive/Spark)
3888    #[serde(default, skip_serializing_if = "Option::is_none")]
3889    pub sort_by: Option<SortBy>,
3890    /// CLUSTER BY clause (Hive/Spark)
3891    #[serde(default, skip_serializing_if = "Option::is_none")]
3892    pub cluster_by: Option<ClusterBy>,
3893    /// DuckDB BY NAME modifier
3894    #[serde(default)]
3895    pub by_name: bool,
3896    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3897    #[serde(default, skip_serializing_if = "Option::is_none")]
3898    pub side: Option<String>,
3899    /// BigQuery: Set operation kind (INNER)
3900    #[serde(default, skip_serializing_if = "Option::is_none")]
3901    pub kind: Option<String>,
3902    /// BigQuery: CORRESPONDING modifier
3903    #[serde(default)]
3904    pub corresponding: bool,
3905    /// BigQuery: STRICT modifier (before CORRESPONDING)
3906    #[serde(default)]
3907    pub strict: bool,
3908    /// BigQuery: BY (columns) after CORRESPONDING
3909    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3910    pub on_columns: Vec<Expression>,
3911}
3912
3913impl Drop for Intersect {
3914    fn drop(&mut self) {
3915        loop {
3916            if let Expression::Intersect(ref mut inner) = self.left {
3917                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3918                let old_left = std::mem::replace(&mut self.left, next_left);
3919                drop(old_left);
3920            } else {
3921                break;
3922            }
3923        }
3924    }
3925}
3926
3927/// Represent an EXCEPT (MINUS) set operation between two query expressions.
3928///
3929/// Returns rows from the left operand that do not appear in the right operand.
3930/// When `all` is true, duplicates are subtracted according to their multiplicity.
3931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3932#[cfg_attr(feature = "bindings", derive(TS))]
3933pub struct Except {
3934    /// The left-hand query operand.
3935    pub left: Expression,
3936    /// The right-hand query operand (rows to subtract).
3937    pub right: Expression,
3938    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
3939    pub all: bool,
3940    /// Whether DISTINCT was explicitly specified
3941    #[serde(default)]
3942    pub distinct: bool,
3943    /// Optional WITH clause
3944    pub with: Option<With>,
3945    /// ORDER BY applied to entire EXCEPT result
3946    pub order_by: Option<OrderBy>,
3947    /// LIMIT applied to entire EXCEPT result
3948    pub limit: Option<Box<Expression>>,
3949    /// OFFSET applied to entire EXCEPT result
3950    pub offset: Option<Box<Expression>>,
3951    /// DISTRIBUTE BY clause (Hive/Spark)
3952    #[serde(default, skip_serializing_if = "Option::is_none")]
3953    pub distribute_by: Option<DistributeBy>,
3954    /// SORT BY clause (Hive/Spark)
3955    #[serde(default, skip_serializing_if = "Option::is_none")]
3956    pub sort_by: Option<SortBy>,
3957    /// CLUSTER BY clause (Hive/Spark)
3958    #[serde(default, skip_serializing_if = "Option::is_none")]
3959    pub cluster_by: Option<ClusterBy>,
3960    /// DuckDB BY NAME modifier
3961    #[serde(default)]
3962    pub by_name: bool,
3963    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3964    #[serde(default, skip_serializing_if = "Option::is_none")]
3965    pub side: Option<String>,
3966    /// BigQuery: Set operation kind (INNER)
3967    #[serde(default, skip_serializing_if = "Option::is_none")]
3968    pub kind: Option<String>,
3969    /// BigQuery: CORRESPONDING modifier
3970    #[serde(default)]
3971    pub corresponding: bool,
3972    /// BigQuery: STRICT modifier (before CORRESPONDING)
3973    #[serde(default)]
3974    pub strict: bool,
3975    /// BigQuery: BY (columns) after CORRESPONDING
3976    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3977    pub on_columns: Vec<Expression>,
3978}
3979
3980impl Drop for Except {
3981    fn drop(&mut self) {
3982        loop {
3983            if let Expression::Except(ref mut inner) = self.left {
3984                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3985                let old_left = std::mem::replace(&mut self.left, next_left);
3986                drop(old_left);
3987            } else {
3988                break;
3989            }
3990        }
3991    }
3992}
3993
3994/// INTO clause for SELECT INTO statements
3995#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3996#[cfg_attr(feature = "bindings", derive(TS))]
3997pub struct SelectInto {
3998    /// Target table or variable (used when single target)
3999    pub this: Expression,
4000    /// Whether TEMPORARY keyword was used
4001    #[serde(default)]
4002    pub temporary: bool,
4003    /// Whether UNLOGGED keyword was used (PostgreSQL)
4004    #[serde(default)]
4005    pub unlogged: bool,
4006    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4007    #[serde(default)]
4008    pub bulk_collect: bool,
4009    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4010    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4011    pub expressions: Vec<Expression>,
4012}
4013
4014/// Represent a parenthesized subquery expression.
4015///
4016/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4017/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4018/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4019/// modifiers are rendered inside or outside the parentheses.
4020///
4021/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4022/// scalar subqueries in select-lists, and derived tables.
4023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4024#[cfg_attr(feature = "bindings", derive(TS))]
4025pub struct Subquery {
4026    /// The inner query expression.
4027    pub this: Expression,
4028    /// Optional alias for the derived table.
4029    pub alias: Option<Identifier>,
4030    /// Optional column aliases: AS t(c1, c2)
4031    pub column_aliases: Vec<Identifier>,
4032    /// Whether AS keyword was explicitly used for the alias.
4033    #[serde(default)]
4034    pub alias_explicit_as: bool,
4035    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4036    #[serde(skip_serializing_if = "Option::is_none", default)]
4037    pub alias_keyword: Option<String>,
4038    /// ORDER BY clause (for parenthesized queries)
4039    pub order_by: Option<OrderBy>,
4040    /// LIMIT clause
4041    pub limit: Option<Limit>,
4042    /// OFFSET clause
4043    pub offset: Option<Offset>,
4044    /// DISTRIBUTE BY clause (Hive/Spark)
4045    #[serde(default, skip_serializing_if = "Option::is_none")]
4046    pub distribute_by: Option<DistributeBy>,
4047    /// SORT BY clause (Hive/Spark)
4048    #[serde(default, skip_serializing_if = "Option::is_none")]
4049    pub sort_by: Option<SortBy>,
4050    /// CLUSTER BY clause (Hive/Spark)
4051    #[serde(default, skip_serializing_if = "Option::is_none")]
4052    pub cluster_by: Option<ClusterBy>,
4053    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4054    #[serde(default)]
4055    pub lateral: bool,
4056    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4057    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4058    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4059    #[serde(default)]
4060    pub modifiers_inside: bool,
4061    /// Trailing comments after the closing paren
4062    #[serde(default)]
4063    pub trailing_comments: Vec<String>,
4064    /// Inferred data type from type annotation
4065    #[serde(default, skip_serializing_if = "Option::is_none")]
4066    #[ast(skip)]
4067    pub inferred_type: Option<DataType>,
4068}
4069
4070/// Pipe operator expression: query |> transform
4071///
4072/// Used in DataFusion and BigQuery pipe syntax:
4073///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4074#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4075#[cfg_attr(feature = "bindings", derive(TS))]
4076pub struct PipeOperator {
4077    /// The input query/expression (left side of |>)
4078    pub this: Expression,
4079    /// The piped operation (right side of |>)
4080    pub expression: Expression,
4081}
4082
4083/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4085#[cfg_attr(feature = "bindings", derive(TS))]
4086pub struct Values {
4087    /// The rows of values
4088    pub expressions: Vec<Tuple>,
4089    /// Optional alias for the table
4090    pub alias: Option<Identifier>,
4091    /// Optional column aliases: AS t(c1, c2)
4092    pub column_aliases: Vec<Identifier>,
4093}
4094
4095/// PIVOT operation - supports both standard and DuckDB simplified syntax
4096///
4097/// Standard syntax (in FROM clause):
4098///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4099///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4100///
4101/// DuckDB simplified syntax (statement-level):
4102///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4103///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4104#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4105#[cfg_attr(feature = "bindings", derive(TS))]
4106pub struct Pivot {
4107    /// Source table/expression
4108    pub this: Expression,
4109    /// For standard PIVOT: the aggregation function(s) (first is primary)
4110    /// For DuckDB simplified: unused (use `using` instead)
4111    #[serde(default)]
4112    pub expressions: Vec<Expression>,
4113    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4114    #[serde(default)]
4115    pub fields: Vec<Expression>,
4116    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4117    #[serde(default)]
4118    pub using: Vec<Expression>,
4119    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4120    #[serde(default)]
4121    pub group: Option<Box<Expression>>,
4122    /// Whether this is an UNPIVOT (vs PIVOT)
4123    #[serde(default)]
4124    pub unpivot: bool,
4125    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4126    #[serde(default)]
4127    pub into: Option<Box<Expression>>,
4128    /// Optional alias
4129    #[serde(default)]
4130    pub alias: Option<Identifier>,
4131    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4132    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4133    pub alias_columns: Vec<Identifier>,
4134    /// Include/exclude nulls (for UNPIVOT)
4135    #[serde(default)]
4136    pub include_nulls: Option<bool>,
4137    /// Default on null value (Snowflake)
4138    #[serde(default)]
4139    pub default_on_null: Option<Box<Expression>>,
4140    /// WITH clause (CTEs)
4141    #[serde(default, skip_serializing_if = "Option::is_none")]
4142    pub with: Option<With>,
4143}
4144
4145/// UNPIVOT operation
4146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4147#[cfg_attr(feature = "bindings", derive(TS))]
4148pub struct Unpivot {
4149    pub this: Expression,
4150    pub value_column: Identifier,
4151    pub name_column: Identifier,
4152    pub columns: Vec<Expression>,
4153    pub alias: Option<Identifier>,
4154    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4155    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4156    pub alias_columns: Vec<Identifier>,
4157    /// Whether the value_column was parenthesized in the original SQL
4158    #[serde(default)]
4159    pub value_column_parenthesized: bool,
4160    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4161    #[serde(default)]
4162    pub include_nulls: Option<bool>,
4163    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4164    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4165    pub extra_value_columns: Vec<Identifier>,
4166}
4167
4168/// PIVOT alias for aliasing pivot expressions
4169/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4171#[cfg_attr(feature = "bindings", derive(TS))]
4172pub struct PivotAlias {
4173    pub this: Expression,
4174    pub alias: Expression,
4175}
4176
4177/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4179#[cfg_attr(feature = "bindings", derive(TS))]
4180pub struct PreWhere {
4181    pub this: Expression,
4182}
4183
4184/// STREAM definition (Snowflake) - for change data capture
4185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4186#[cfg_attr(feature = "bindings", derive(TS))]
4187pub struct Stream {
4188    pub this: Expression,
4189    #[serde(skip_serializing_if = "Option::is_none")]
4190    pub on: Option<Expression>,
4191    #[serde(skip_serializing_if = "Option::is_none")]
4192    pub show_initial_rows: Option<bool>,
4193}
4194
4195/// USING DATA clause for data import statements
4196#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4197#[cfg_attr(feature = "bindings", derive(TS))]
4198pub struct UsingData {
4199    pub this: Expression,
4200}
4201
4202/// XML Namespace declaration
4203#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4204#[cfg_attr(feature = "bindings", derive(TS))]
4205pub struct XmlNamespace {
4206    pub this: Expression,
4207    #[serde(skip_serializing_if = "Option::is_none")]
4208    pub alias: Option<Identifier>,
4209}
4210
4211/// ROW FORMAT clause for Hive/Spark
4212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4213#[cfg_attr(feature = "bindings", derive(TS))]
4214pub struct RowFormat {
4215    pub delimited: bool,
4216    pub fields_terminated_by: Option<String>,
4217    pub collection_items_terminated_by: Option<String>,
4218    pub map_keys_terminated_by: Option<String>,
4219    pub lines_terminated_by: Option<String>,
4220    pub null_defined_as: Option<String>,
4221}
4222
4223/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4225#[cfg_attr(feature = "bindings", derive(TS))]
4226pub struct DirectoryInsert {
4227    pub local: bool,
4228    pub path: String,
4229    pub row_format: Option<RowFormat>,
4230    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4231    #[serde(default)]
4232    pub stored_as: Option<String>,
4233}
4234
4235/// INSERT statement
4236#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4237#[cfg_attr(feature = "bindings", derive(TS))]
4238pub struct Insert {
4239    pub table: TableRef,
4240    pub columns: Vec<Identifier>,
4241    pub values: Vec<Vec<Expression>>,
4242    pub query: Option<Expression>,
4243    /// INSERT OVERWRITE for Hive/Spark
4244    pub overwrite: bool,
4245    /// PARTITION clause for Hive/Spark
4246    pub partition: Vec<(Identifier, Option<Expression>)>,
4247    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4248    #[serde(default)]
4249    pub directory: Option<DirectoryInsert>,
4250    /// RETURNING clause (PostgreSQL, SQLite)
4251    #[serde(default)]
4252    pub returning: Vec<Expression>,
4253    /// OUTPUT clause (TSQL)
4254    #[serde(default)]
4255    pub output: Option<OutputClause>,
4256    /// ON CONFLICT clause (PostgreSQL, SQLite)
4257    #[serde(default)]
4258    pub on_conflict: Option<Box<Expression>>,
4259    /// Leading comments before the statement
4260    #[serde(default)]
4261    pub leading_comments: Vec<String>,
4262    /// IF EXISTS clause (Hive)
4263    #[serde(default)]
4264    pub if_exists: bool,
4265    /// WITH clause (CTEs)
4266    #[serde(default)]
4267    pub with: Option<With>,
4268    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4269    #[serde(default)]
4270    pub ignore: bool,
4271    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4272    #[serde(default)]
4273    pub source_alias: Option<Identifier>,
4274    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4275    #[serde(default)]
4276    pub alias: Option<Identifier>,
4277    /// Whether the alias uses explicit AS keyword
4278    #[serde(default)]
4279    pub alias_explicit_as: bool,
4280    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4281    #[serde(default)]
4282    pub default_values: bool,
4283    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4284    #[serde(default)]
4285    pub by_name: bool,
4286    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4287    #[serde(default, skip_serializing_if = "Option::is_none")]
4288    pub conflict_action: Option<String>,
4289    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4290    #[serde(default)]
4291    pub is_replace: bool,
4292    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4293    #[serde(default, skip_serializing_if = "Option::is_none")]
4294    pub hint: Option<Hint>,
4295    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4296    #[serde(default)]
4297    pub replace_where: Option<Box<Expression>>,
4298    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4299    #[serde(default)]
4300    pub source: Option<Box<Expression>>,
4301    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4302    #[serde(default, skip_serializing_if = "Option::is_none")]
4303    pub function_target: Option<Box<Expression>>,
4304    /// ClickHouse: PARTITION BY expr
4305    #[serde(default, skip_serializing_if = "Option::is_none")]
4306    pub partition_by: Option<Box<Expression>>,
4307    /// ClickHouse: SETTINGS key = val, ...
4308    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4309    pub settings: Vec<Expression>,
4310}
4311
4312/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4313#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4314#[cfg_attr(feature = "bindings", derive(TS))]
4315pub struct OutputClause {
4316    /// Columns/expressions to output
4317    pub columns: Vec<Expression>,
4318    /// Optional INTO target table or table variable
4319    #[serde(default)]
4320    pub into_table: Option<Expression>,
4321}
4322
4323/// UPDATE statement
4324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4325#[cfg_attr(feature = "bindings", derive(TS))]
4326pub struct Update {
4327    pub table: TableRef,
4328    #[serde(default)]
4329    pub hint: Option<Hint>,
4330    /// Additional tables for multi-table UPDATE (MySQL syntax)
4331    #[serde(default)]
4332    pub extra_tables: Vec<TableRef>,
4333    /// JOINs attached to the table list (MySQL multi-table syntax)
4334    #[serde(default)]
4335    pub table_joins: Vec<Join>,
4336    pub set: Vec<(Identifier, Expression)>,
4337    pub from_clause: Option<From>,
4338    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4339    #[serde(default)]
4340    pub from_joins: Vec<Join>,
4341    pub where_clause: Option<Where>,
4342    /// RETURNING clause (PostgreSQL, SQLite)
4343    #[serde(default)]
4344    pub returning: Vec<Expression>,
4345    /// OUTPUT clause (TSQL)
4346    #[serde(default)]
4347    pub output: Option<OutputClause>,
4348    /// WITH clause (CTEs)
4349    #[serde(default)]
4350    pub with: Option<With>,
4351    /// Leading comments before the statement
4352    #[serde(default)]
4353    pub leading_comments: Vec<String>,
4354    /// LIMIT clause (MySQL)
4355    #[serde(default)]
4356    pub limit: Option<Expression>,
4357    /// ORDER BY clause (MySQL)
4358    #[serde(default)]
4359    pub order_by: Option<OrderBy>,
4360    /// Whether FROM clause appears before SET (Snowflake syntax)
4361    #[serde(default)]
4362    pub from_before_set: bool,
4363}
4364
4365/// DELETE statement
4366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4367#[cfg_attr(feature = "bindings", derive(TS))]
4368pub struct Delete {
4369    pub table: TableRef,
4370    #[serde(default)]
4371    pub hint: Option<Hint>,
4372    /// ClickHouse: ON CLUSTER clause for distributed DDL
4373    #[serde(default, skip_serializing_if = "Option::is_none")]
4374    pub on_cluster: Option<OnCluster>,
4375    /// Optional alias for the table
4376    pub alias: Option<Identifier>,
4377    /// Whether the alias was declared with explicit AS keyword
4378    #[serde(default)]
4379    pub alias_explicit_as: bool,
4380    /// PostgreSQL/DuckDB USING clause - additional tables to join
4381    pub using: Vec<TableRef>,
4382    pub where_clause: Option<Where>,
4383    /// OUTPUT clause (TSQL)
4384    #[serde(default)]
4385    pub output: Option<OutputClause>,
4386    /// Leading comments before the statement
4387    #[serde(default)]
4388    pub leading_comments: Vec<String>,
4389    /// WITH clause (CTEs)
4390    #[serde(default)]
4391    pub with: Option<With>,
4392    /// LIMIT clause (MySQL)
4393    #[serde(default)]
4394    pub limit: Option<Expression>,
4395    /// ORDER BY clause (MySQL)
4396    #[serde(default)]
4397    pub order_by: Option<OrderBy>,
4398    /// RETURNING clause (PostgreSQL)
4399    #[serde(default)]
4400    pub returning: Vec<Expression>,
4401    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4402    /// These are the target tables to delete from
4403    #[serde(default)]
4404    pub tables: Vec<TableRef>,
4405    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4406    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4407    #[serde(default)]
4408    pub tables_from_using: bool,
4409    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4410    #[serde(default)]
4411    pub joins: Vec<Join>,
4412    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4413    #[serde(default)]
4414    pub force_index: Option<String>,
4415    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4416    #[serde(default)]
4417    pub no_from: bool,
4418}
4419
4420/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4422#[cfg_attr(feature = "bindings", derive(TS))]
4423pub struct CopyStmt {
4424    /// Target table or query
4425    pub this: Expression,
4426    /// True for FROM (loading into table), false for TO (exporting)
4427    pub kind: bool,
4428    /// Source/destination file(s) or stage
4429    pub files: Vec<Expression>,
4430    /// Copy parameters
4431    #[serde(default)]
4432    pub params: Vec<CopyParameter>,
4433    /// Credentials for external access
4434    #[serde(default)]
4435    pub credentials: Option<Box<Credentials>>,
4436    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4437    #[serde(default)]
4438    pub is_into: bool,
4439    /// Whether parameters are wrapped in WITH (...) syntax
4440    #[serde(default)]
4441    pub with_wrapped: bool,
4442}
4443
4444/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4445#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4446#[cfg_attr(feature = "bindings", derive(TS))]
4447pub struct CopyParameter {
4448    pub name: String,
4449    pub value: Option<Expression>,
4450    pub values: Vec<Expression>,
4451    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4452    #[serde(default)]
4453    pub eq: bool,
4454}
4455
4456/// Credentials for external access (S3, Azure, etc.)
4457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4458#[cfg_attr(feature = "bindings", derive(TS))]
4459pub struct Credentials {
4460    pub credentials: Vec<(String, String)>,
4461    pub encryption: Option<String>,
4462    pub storage: Option<String>,
4463}
4464
4465/// PUT statement (Snowflake)
4466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4467#[cfg_attr(feature = "bindings", derive(TS))]
4468pub struct PutStmt {
4469    /// Source file path
4470    pub source: String,
4471    /// Whether source was quoted in the original SQL
4472    #[serde(default)]
4473    pub source_quoted: bool,
4474    /// Target stage
4475    pub target: Expression,
4476    /// PUT parameters
4477    #[serde(default)]
4478    pub params: Vec<CopyParameter>,
4479}
4480
4481/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4482#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4483#[cfg_attr(feature = "bindings", derive(TS))]
4484pub struct StageReference {
4485    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4486    pub name: String,
4487    /// Optional path within the stage (e.g., "/path/to/file.csv")
4488    #[serde(default)]
4489    pub path: Option<String>,
4490    /// Optional FILE_FORMAT parameter
4491    #[serde(default)]
4492    pub file_format: Option<Expression>,
4493    /// Optional PATTERN parameter
4494    #[serde(default)]
4495    pub pattern: Option<String>,
4496    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4497    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4498    pub quoted: bool,
4499}
4500
4501/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4503#[cfg_attr(feature = "bindings", derive(TS))]
4504pub struct HistoricalData {
4505    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4506    pub this: Box<Expression>,
4507    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4508    pub kind: String,
4509    /// The expression value (e.g., the statement ID or timestamp)
4510    pub expression: Box<Expression>,
4511}
4512
4513/// Represent an aliased expression (`expr AS name`).
4514///
4515/// Used for column aliases in select-lists, table aliases on subqueries,
4516/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4518#[cfg_attr(feature = "bindings", derive(TS))]
4519pub struct Alias {
4520    /// The expression being aliased.
4521    pub this: Expression,
4522    /// The alias name (required for simple aliases, optional when only column aliases provided)
4523    pub alias: Identifier,
4524    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4525    #[serde(default)]
4526    pub column_aliases: Vec<Identifier>,
4527    /// Whether AS keyword was explicitly used for the alias.
4528    #[serde(default)]
4529    pub alias_explicit_as: bool,
4530    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4531    #[serde(skip_serializing_if = "Option::is_none", default)]
4532    pub alias_keyword: Option<String>,
4533    /// Comments that appeared between the expression and AS keyword
4534    #[serde(default)]
4535    pub pre_alias_comments: Vec<String>,
4536    /// Trailing comments that appeared after the alias
4537    #[serde(default)]
4538    pub trailing_comments: Vec<String>,
4539    /// Inferred data type from type annotation
4540    #[serde(default, skip_serializing_if = "Option::is_none")]
4541    #[ast(skip)]
4542    pub inferred_type: Option<DataType>,
4543}
4544
4545impl Alias {
4546    /// Create a simple alias
4547    pub fn new(this: Expression, alias: Identifier) -> Self {
4548        Self {
4549            this,
4550            alias,
4551            column_aliases: Vec::new(),
4552            alias_explicit_as: false,
4553            alias_keyword: None,
4554            pre_alias_comments: Vec::new(),
4555            trailing_comments: Vec::new(),
4556            inferred_type: None,
4557        }
4558    }
4559
4560    /// Create an alias with column aliases only (no table alias name)
4561    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4562        Self {
4563            this,
4564            alias: Identifier::empty(),
4565            column_aliases,
4566            alias_explicit_as: false,
4567            alias_keyword: None,
4568            pre_alias_comments: Vec::new(),
4569            trailing_comments: Vec::new(),
4570            inferred_type: None,
4571        }
4572    }
4573}
4574
4575/// Represent a type cast expression.
4576///
4577/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4578/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4579/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4580/// CONVERSION ERROR (Oracle) clauses.
4581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4582#[cfg_attr(feature = "bindings", derive(TS))]
4583pub struct Cast {
4584    /// The expression being cast.
4585    pub this: Expression,
4586    /// The target data type.
4587    pub to: DataType,
4588    #[serde(default)]
4589    pub trailing_comments: Vec<String>,
4590    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4591    #[serde(default)]
4592    pub double_colon_syntax: bool,
4593    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4594    #[serde(skip_serializing_if = "Option::is_none", default)]
4595    pub format: Option<Box<Expression>>,
4596    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4597    #[serde(skip_serializing_if = "Option::is_none", default)]
4598    pub default: Option<Box<Expression>>,
4599    /// Inferred data type from type annotation
4600    #[serde(default, skip_serializing_if = "Option::is_none")]
4601    #[ast(skip)]
4602    pub inferred_type: Option<DataType>,
4603}
4604
4605///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4606#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4607#[cfg_attr(feature = "bindings", derive(TS))]
4608pub struct CollationExpr {
4609    pub this: Expression,
4610    pub collation: String,
4611    /// True if the collation was single-quoted in the original SQL (string literal)
4612    #[serde(default)]
4613    pub quoted: bool,
4614    /// True if the collation was double-quoted in the original SQL (identifier)
4615    #[serde(default)]
4616    pub double_quoted: bool,
4617}
4618
4619/// Represent a CASE expression (both simple and searched forms).
4620///
4621/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4622/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4623/// Each entry in `whens` is a `(condition, result)` pair.
4624#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4625#[cfg_attr(feature = "bindings", derive(TS))]
4626pub struct Case {
4627    /// The operand for simple CASE, or `None` for searched CASE.
4628    pub operand: Option<Expression>,
4629    /// Pairs of (WHEN condition, THEN result).
4630    pub whens: Vec<(Expression, Expression)>,
4631    /// Optional ELSE result.
4632    pub else_: Option<Expression>,
4633    /// Comments from the CASE keyword (emitted after END)
4634    #[serde(default)]
4635    #[serde(skip_serializing_if = "Vec::is_empty")]
4636    pub comments: Vec<String>,
4637    /// Inferred data type from type annotation
4638    #[serde(default, skip_serializing_if = "Option::is_none")]
4639    #[ast(skip)]
4640    pub inferred_type: Option<DataType>,
4641}
4642
4643/// Represent a binary operation (two operands separated by an operator).
4644///
4645/// This is the shared payload struct for all binary operator variants in the
4646/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4647/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4648/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4649/// preservation of inline comments around operators.
4650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4651#[cfg_attr(feature = "bindings", derive(TS))]
4652pub struct BinaryOp {
4653    pub left: Expression,
4654    pub right: Expression,
4655    /// Comments after the left operand (before the operator)
4656    #[serde(default)]
4657    pub left_comments: Vec<String>,
4658    /// Comments after the operator (before the right operand)
4659    #[serde(default)]
4660    pub operator_comments: Vec<String>,
4661    /// Comments after the right operand
4662    #[serde(default)]
4663    pub trailing_comments: Vec<String>,
4664    /// Inferred data type from type annotation
4665    #[serde(default, skip_serializing_if = "Option::is_none")]
4666    #[ast(skip)]
4667    pub inferred_type: Option<DataType>,
4668}
4669
4670impl BinaryOp {
4671    pub fn new(left: Expression, right: Expression) -> Self {
4672        Self {
4673            left,
4674            right,
4675            left_comments: Vec::new(),
4676            operator_comments: Vec::new(),
4677            trailing_comments: Vec::new(),
4678            inferred_type: None,
4679        }
4680    }
4681}
4682
4683/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4685#[cfg_attr(feature = "bindings", derive(TS))]
4686pub struct LikeOp {
4687    pub left: Expression,
4688    pub right: Expression,
4689    /// ESCAPE character/expression
4690    #[serde(default)]
4691    pub escape: Option<Expression>,
4692    /// Quantifier: ANY, ALL, or SOME
4693    #[serde(default)]
4694    pub quantifier: Option<String>,
4695    /// Inferred data type from type annotation
4696    #[serde(default, skip_serializing_if = "Option::is_none")]
4697    #[ast(skip)]
4698    pub inferred_type: Option<DataType>,
4699}
4700
4701impl LikeOp {
4702    pub fn new(left: Expression, right: Expression) -> Self {
4703        Self {
4704            left,
4705            right,
4706            escape: None,
4707            quantifier: None,
4708            inferred_type: None,
4709        }
4710    }
4711
4712    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4713        Self {
4714            left,
4715            right,
4716            escape: Some(escape),
4717            quantifier: None,
4718            inferred_type: None,
4719        }
4720    }
4721}
4722
4723/// Represent a unary operation (single operand with a prefix operator).
4724///
4725/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4727#[cfg_attr(feature = "bindings", derive(TS))]
4728pub struct UnaryOp {
4729    /// The operand expression.
4730    pub this: Expression,
4731    /// Inferred data type from type annotation
4732    #[serde(default, skip_serializing_if = "Option::is_none")]
4733    #[ast(skip)]
4734    pub inferred_type: Option<DataType>,
4735}
4736
4737impl UnaryOp {
4738    pub fn new(this: Expression) -> Self {
4739        Self {
4740            this,
4741            inferred_type: None,
4742        }
4743    }
4744}
4745
4746/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4747///
4748/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4749/// but not both. When `not` is true, the predicate is `NOT IN`.
4750#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4751#[cfg_attr(feature = "bindings", derive(TS))]
4752pub struct In {
4753    /// The expression being tested.
4754    pub this: Expression,
4755    /// The value list (mutually exclusive with `query`).
4756    pub expressions: Vec<Expression>,
4757    /// A subquery (mutually exclusive with `expressions`).
4758    pub query: Option<Expression>,
4759    /// Whether this is NOT IN.
4760    pub not: bool,
4761    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4762    pub global: bool,
4763    /// BigQuery: IN UNNEST(expr)
4764    #[serde(default, skip_serializing_if = "Option::is_none")]
4765    pub unnest: Option<Box<Expression>>,
4766    /// Whether the right side is a bare field reference (no parentheses).
4767    /// Matches Python sqlglot's `field` attribute on `In` expression.
4768    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4769    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4770    pub is_field: bool,
4771}
4772
4773/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4774#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4775#[cfg_attr(feature = "bindings", derive(TS))]
4776pub struct Between {
4777    /// The expression being tested.
4778    pub this: Expression,
4779    /// The lower bound.
4780    pub low: Expression,
4781    /// The upper bound.
4782    pub high: Expression,
4783    /// Whether this is NOT BETWEEN.
4784    pub not: bool,
4785    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4786    #[serde(default)]
4787    pub symmetric: Option<bool>,
4788}
4789
4790/// IS NULL predicate
4791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4792#[cfg_attr(feature = "bindings", derive(TS))]
4793pub struct IsNull {
4794    pub this: Expression,
4795    pub not: bool,
4796    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4797    #[serde(default)]
4798    pub postfix_form: bool,
4799}
4800
4801/// IS TRUE / IS FALSE predicate
4802#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4803#[cfg_attr(feature = "bindings", derive(TS))]
4804pub struct IsTrueFalse {
4805    pub this: Expression,
4806    pub not: bool,
4807}
4808
4809/// IS JSON predicate (SQL standard)
4810/// Checks if a value is valid JSON
4811#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4812#[cfg_attr(feature = "bindings", derive(TS))]
4813pub struct IsJson {
4814    pub this: Expression,
4815    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4816    pub json_type: Option<String>,
4817    /// Key uniqueness constraint
4818    pub unique_keys: Option<JsonUniqueKeys>,
4819    /// Whether IS NOT JSON
4820    pub negated: bool,
4821}
4822
4823/// JSON unique keys constraint variants
4824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4825#[cfg_attr(feature = "bindings", derive(TS))]
4826pub enum JsonUniqueKeys {
4827    /// WITH UNIQUE KEYS
4828    With,
4829    /// WITHOUT UNIQUE KEYS
4830    Without,
4831    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4832    Shorthand,
4833}
4834
4835/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4837#[cfg_attr(feature = "bindings", derive(TS))]
4838pub struct Exists {
4839    /// The subquery expression.
4840    pub this: Expression,
4841    /// Whether this is NOT EXISTS.
4842    pub not: bool,
4843}
4844
4845/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
4846///
4847/// This is the generic function node. Well-known aggregates, window functions,
4848/// and built-in functions each have their own dedicated `Expression` variants
4849/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
4850/// not recognize as built-ins are represented with this struct.
4851#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4852#[cfg_attr(feature = "bindings", derive(TS))]
4853pub struct Function {
4854    /// The function name, as originally written (may be schema-qualified).
4855    pub name: String,
4856    /// Positional arguments to the function.
4857    pub args: Vec<Expression>,
4858    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
4859    pub distinct: bool,
4860    #[serde(default)]
4861    pub trailing_comments: Vec<String>,
4862    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
4863    #[serde(default)]
4864    pub use_bracket_syntax: bool,
4865    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
4866    #[serde(default)]
4867    pub no_parens: bool,
4868    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
4869    #[serde(default)]
4870    pub quoted: bool,
4871    /// Source position span
4872    #[serde(default, skip_serializing_if = "Option::is_none")]
4873    pub span: Option<Span>,
4874    /// Inferred data type from type annotation
4875    #[serde(default, skip_serializing_if = "Option::is_none")]
4876    #[ast(skip)]
4877    pub inferred_type: Option<DataType>,
4878}
4879
4880impl Default for Function {
4881    fn default() -> Self {
4882        Self {
4883            name: String::new(),
4884            args: Vec::new(),
4885            distinct: false,
4886            trailing_comments: Vec::new(),
4887            use_bracket_syntax: false,
4888            no_parens: false,
4889            quoted: false,
4890            span: None,
4891            inferred_type: None,
4892        }
4893    }
4894}
4895
4896impl Function {
4897    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
4898        Self {
4899            name: name.into(),
4900            args,
4901            distinct: false,
4902            trailing_comments: Vec::new(),
4903            use_bracket_syntax: false,
4904            no_parens: false,
4905            quoted: false,
4906            span: None,
4907            inferred_type: None,
4908        }
4909    }
4910}
4911
4912/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
4913///
4914/// This struct is used for aggregate function calls that are not covered by
4915/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
4916/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
4917/// IGNORE NULLS / RESPECT NULLS modifiers.
4918#[derive(
4919    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
4920)]
4921#[cfg_attr(feature = "bindings", derive(TS))]
4922pub struct AggregateFunction {
4923    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
4924    pub name: String,
4925    /// Positional arguments.
4926    pub args: Vec<Expression>,
4927    /// Whether DISTINCT was specified.
4928    pub distinct: bool,
4929    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
4930    pub filter: Option<Expression>,
4931    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
4932    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4933    pub order_by: Vec<Ordered>,
4934    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
4935    #[serde(default, skip_serializing_if = "Option::is_none")]
4936    pub limit: Option<Box<Expression>>,
4937    /// IGNORE NULLS / RESPECT NULLS
4938    #[serde(default, skip_serializing_if = "Option::is_none")]
4939    pub ignore_nulls: Option<bool>,
4940    /// Inferred data type from type annotation
4941    #[serde(default, skip_serializing_if = "Option::is_none")]
4942    #[ast(skip)]
4943    pub inferred_type: Option<DataType>,
4944}
4945
4946/// Represent a window function call with its OVER clause.
4947///
4948/// The inner `this` expression is typically a window-specific expression
4949/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
4950/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
4951/// frame specification.
4952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4953#[cfg_attr(feature = "bindings", derive(TS))]
4954pub struct WindowFunction {
4955    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
4956    pub this: Expression,
4957    /// The OVER clause defining the window partitioning, ordering, and frame.
4958    pub over: Over,
4959    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
4960    #[serde(default, skip_serializing_if = "Option::is_none")]
4961    pub keep: Option<Keep>,
4962    /// Inferred data type from type annotation
4963    #[serde(default, skip_serializing_if = "Option::is_none")]
4964    #[ast(skip)]
4965    pub inferred_type: Option<DataType>,
4966}
4967
4968/// Oracle KEEP clause for aggregate functions
4969/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
4970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4971#[cfg_attr(feature = "bindings", derive(TS))]
4972pub struct Keep {
4973    /// true = FIRST, false = LAST
4974    pub first: bool,
4975    /// ORDER BY clause inside KEEP
4976    pub order_by: Vec<Ordered>,
4977}
4978
4979/// WITHIN GROUP clause (for ordered-set aggregate functions)
4980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4981#[cfg_attr(feature = "bindings", derive(TS))]
4982pub struct WithinGroup {
4983    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
4984    pub this: Expression,
4985    /// The ORDER BY clause within the group
4986    pub order_by: Vec<Ordered>,
4987}
4988
4989/// Represent the FROM clause of a SELECT statement.
4990///
4991/// Contains one or more table sources (tables, subqueries, table-valued
4992/// functions, etc.). Multiple entries represent comma-separated implicit joins.
4993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4994#[cfg_attr(feature = "bindings", derive(TS))]
4995pub struct From {
4996    /// The table source expressions.
4997    pub expressions: Vec<Expression>,
4998}
4999
5000/// Represent a JOIN clause between two table sources.
5001///
5002/// The join condition can be specified via `on` (ON predicate) or `using`
5003/// (USING column list), but not both. The `kind` field determines the join
5004/// type (INNER, LEFT, CROSS, etc.).
5005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5006#[cfg_attr(feature = "bindings", derive(TS))]
5007pub struct Join {
5008    /// The right-hand table expression being joined.
5009    pub this: Expression,
5010    /// The ON condition (mutually exclusive with `using`).
5011    pub on: Option<Expression>,
5012    /// The USING column list (mutually exclusive with `on`).
5013    pub using: Vec<Identifier>,
5014    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5015    pub kind: JoinKind,
5016    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5017    pub use_inner_keyword: bool,
5018    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5019    pub use_outer_keyword: bool,
5020    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5021    pub deferred_condition: bool,
5022    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5023    #[serde(default, skip_serializing_if = "Option::is_none")]
5024    pub join_hint: Option<String>,
5025    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5026    #[serde(default, skip_serializing_if = "Option::is_none")]
5027    pub match_condition: Option<Expression>,
5028    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5029    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5030    pub pivots: Vec<Expression>,
5031    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5032    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5033    pub comments: Vec<String>,
5034    /// Nesting group identifier for nested join pretty-printing.
5035    /// Joins in the same group were parsed together; group boundaries come from
5036    /// deferred condition resolution phases.
5037    #[serde(default)]
5038    pub nesting_group: usize,
5039    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5040    #[serde(default)]
5041    pub directed: bool,
5042}
5043
5044/// Enumerate all supported SQL join types.
5045///
5046/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5047/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5048/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5049/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5050#[derive(
5051    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5052)]
5053#[cfg_attr(feature = "bindings", derive(TS))]
5054pub enum JoinKind {
5055    Inner,
5056    Left,
5057    Right,
5058    Full,
5059    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5060    Cross,
5061    Natural,
5062    NaturalLeft,
5063    NaturalRight,
5064    NaturalFull,
5065    Semi,
5066    Anti,
5067    // Directional SEMI/ANTI joins
5068    LeftSemi,
5069    LeftAnti,
5070    RightSemi,
5071    RightAnti,
5072    // SQL Server specific
5073    CrossApply,
5074    OuterApply,
5075    // Time-series specific
5076    AsOf,
5077    AsOfLeft,
5078    AsOfRight,
5079    // Lateral join
5080    Lateral,
5081    LeftLateral,
5082    // MySQL specific
5083    Straight,
5084    // Implicit join (comma-separated tables: FROM a, b)
5085    Implicit,
5086    // ClickHouse ARRAY JOIN
5087    Array,
5088    LeftArray,
5089    // ClickHouse PASTE JOIN (positional join)
5090    Paste,
5091    // DuckDB POSITIONAL JOIN
5092    Positional,
5093}
5094
5095impl Default for JoinKind {
5096    fn default() -> Self {
5097        JoinKind::Inner
5098    }
5099}
5100
5101/// Parenthesized table expression with joins
5102/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5103#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5104#[cfg_attr(feature = "bindings", derive(TS))]
5105pub struct JoinedTable {
5106    /// The left-hand side table expression
5107    pub left: Expression,
5108    /// The joins applied to the left table
5109    pub joins: Vec<Join>,
5110    /// LATERAL VIEW clauses (Hive/Spark)
5111    pub lateral_views: Vec<LateralView>,
5112    /// Optional alias for the joined table expression
5113    pub alias: Option<Identifier>,
5114}
5115
5116/// Represent a WHERE clause containing a boolean filter predicate.
5117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5118#[cfg_attr(feature = "bindings", derive(TS))]
5119pub struct Where {
5120    /// The filter predicate expression.
5121    pub this: Expression,
5122}
5123
5124/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5125///
5126/// The `expressions` list may contain plain columns, ordinal positions,
5127/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5129#[cfg_attr(feature = "bindings", derive(TS))]
5130pub struct GroupBy {
5131    /// The grouping expressions.
5132    pub expressions: Vec<Expression>,
5133    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5134    #[serde(default)]
5135    pub all: Option<bool>,
5136    /// ClickHouse: WITH TOTALS modifier
5137    #[serde(default)]
5138    pub totals: bool,
5139    /// Leading comments that appeared before the GROUP BY keyword
5140    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5141    pub comments: Vec<String>,
5142}
5143
5144/// Represent a HAVING clause containing a predicate over aggregate results.
5145#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5146#[cfg_attr(feature = "bindings", derive(TS))]
5147pub struct Having {
5148    /// The filter predicate, typically involving aggregate functions.
5149    pub this: Expression,
5150    /// Leading comments that appeared before the HAVING keyword
5151    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5152    pub comments: Vec<String>,
5153}
5154
5155/// Represent an ORDER BY clause containing one or more sort specifications.
5156#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5157#[cfg_attr(feature = "bindings", derive(TS))]
5158pub struct OrderBy {
5159    /// The sort specifications, each with direction and null ordering.
5160    pub expressions: Vec<Ordered>,
5161    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5162    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5163    pub siblings: bool,
5164    /// Leading comments that appeared before the ORDER BY keyword
5165    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5166    pub comments: Vec<String>,
5167}
5168
5169/// Represent an expression with sort direction and null ordering.
5170///
5171/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5172/// When `desc` is false the sort is ascending. The `nulls_first` field
5173/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5174/// (database default).
5175#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5176#[cfg_attr(feature = "bindings", derive(TS))]
5177pub struct Ordered {
5178    /// The expression to sort by.
5179    pub this: Expression,
5180    /// Whether the sort direction is descending (true) or ascending (false).
5181    pub desc: bool,
5182    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5183    pub nulls_first: Option<bool>,
5184    /// Whether ASC was explicitly written (not just implied)
5185    #[serde(default)]
5186    pub explicit_asc: bool,
5187    /// ClickHouse WITH FILL clause
5188    #[serde(default, skip_serializing_if = "Option::is_none")]
5189    pub with_fill: Option<Box<WithFill>>,
5190}
5191
5192impl Ordered {
5193    pub fn asc(expr: Expression) -> Self {
5194        Self {
5195            this: expr,
5196            desc: false,
5197            nulls_first: None,
5198            explicit_asc: false,
5199            with_fill: None,
5200        }
5201    }
5202
5203    pub fn desc(expr: Expression) -> Self {
5204        Self {
5205            this: expr,
5206            desc: true,
5207            nulls_first: None,
5208            explicit_asc: false,
5209            with_fill: None,
5210        }
5211    }
5212}
5213
5214/// DISTRIBUTE BY clause (Hive/Spark)
5215/// Controls how rows are distributed across reducers
5216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5217#[cfg_attr(feature = "bindings", derive(TS))]
5218#[cfg_attr(feature = "bindings", ts(export))]
5219pub struct DistributeBy {
5220    pub expressions: Vec<Expression>,
5221}
5222
5223/// CLUSTER BY clause (Hive/Spark)
5224/// Combines DISTRIBUTE BY and SORT BY on the same columns
5225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5226#[cfg_attr(feature = "bindings", derive(TS))]
5227#[cfg_attr(feature = "bindings", ts(export))]
5228pub struct ClusterBy {
5229    pub expressions: Vec<Ordered>,
5230}
5231
5232/// SORT BY clause (Hive/Spark)
5233/// Sorts data within each reducer (local sort, not global)
5234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5235#[cfg_attr(feature = "bindings", derive(TS))]
5236#[cfg_attr(feature = "bindings", ts(export))]
5237pub struct SortBy {
5238    pub expressions: Vec<Ordered>,
5239}
5240
5241/// LATERAL VIEW clause (Hive/Spark)
5242/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5243#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5244#[cfg_attr(feature = "bindings", derive(TS))]
5245#[cfg_attr(feature = "bindings", ts(export))]
5246pub struct LateralView {
5247    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5248    pub this: Expression,
5249    /// Table alias for the generated table
5250    pub table_alias: Option<Identifier>,
5251    /// Column aliases for the generated columns
5252    pub column_aliases: Vec<Identifier>,
5253    /// OUTER keyword - preserve nulls when input is empty/null
5254    pub outer: bool,
5255}
5256
5257/// Query hint
5258#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5259#[cfg_attr(feature = "bindings", derive(TS))]
5260#[cfg_attr(feature = "bindings", ts(export))]
5261pub struct Hint {
5262    pub expressions: Vec<HintExpression>,
5263}
5264
5265/// Individual hint expression
5266#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5267#[cfg_attr(feature = "bindings", derive(TS))]
5268#[cfg_attr(feature = "bindings", ts(export))]
5269pub enum HintExpression {
5270    /// Function-style hint: USE_HASH(table)
5271    Function { name: String, args: Vec<Expression> },
5272    /// Simple identifier hint: PARALLEL
5273    Identifier(String),
5274    /// Raw hint text (unparsed)
5275    Raw(String),
5276}
5277
5278/// Pseudocolumn type
5279#[derive(
5280    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5281)]
5282#[cfg_attr(feature = "bindings", derive(TS))]
5283#[cfg_attr(feature = "bindings", ts(export))]
5284pub enum PseudocolumnType {
5285    Rownum,      // Oracle ROWNUM
5286    Rowid,       // Oracle ROWID
5287    Level,       // Oracle LEVEL (for CONNECT BY)
5288    Sysdate,     // Oracle SYSDATE
5289    ObjectId,    // Oracle OBJECT_ID
5290    ObjectValue, // Oracle OBJECT_VALUE
5291}
5292
5293impl PseudocolumnType {
5294    pub fn as_str(&self) -> &'static str {
5295        match self {
5296            PseudocolumnType::Rownum => "ROWNUM",
5297            PseudocolumnType::Rowid => "ROWID",
5298            PseudocolumnType::Level => "LEVEL",
5299            PseudocolumnType::Sysdate => "SYSDATE",
5300            PseudocolumnType::ObjectId => "OBJECT_ID",
5301            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5302        }
5303    }
5304
5305    pub fn from_str(s: &str) -> Option<Self> {
5306        match s.to_uppercase().as_str() {
5307            "ROWNUM" => Some(PseudocolumnType::Rownum),
5308            "ROWID" => Some(PseudocolumnType::Rowid),
5309            "LEVEL" => Some(PseudocolumnType::Level),
5310            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5311            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5312            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5313            _ => None,
5314        }
5315    }
5316}
5317
5318/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5319/// These are special identifiers that should not be quoted
5320#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5321#[cfg_attr(feature = "bindings", derive(TS))]
5322#[cfg_attr(feature = "bindings", ts(export))]
5323pub struct Pseudocolumn {
5324    pub kind: PseudocolumnType,
5325}
5326
5327impl Pseudocolumn {
5328    pub fn rownum() -> Self {
5329        Self {
5330            kind: PseudocolumnType::Rownum,
5331        }
5332    }
5333
5334    pub fn rowid() -> Self {
5335        Self {
5336            kind: PseudocolumnType::Rowid,
5337        }
5338    }
5339
5340    pub fn level() -> Self {
5341        Self {
5342            kind: PseudocolumnType::Level,
5343        }
5344    }
5345}
5346
5347/// Oracle CONNECT BY clause for hierarchical queries
5348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5349#[cfg_attr(feature = "bindings", derive(TS))]
5350#[cfg_attr(feature = "bindings", ts(export))]
5351pub struct Connect {
5352    /// START WITH condition (optional, can come before or after CONNECT BY)
5353    pub start: Option<Expression>,
5354    /// CONNECT BY condition (required, contains PRIOR references)
5355    pub connect: Expression,
5356    /// NOCYCLE keyword to prevent infinite loops
5357    pub nocycle: bool,
5358}
5359
5360/// Oracle PRIOR expression - references parent row's value in CONNECT BY
5361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5362#[cfg_attr(feature = "bindings", derive(TS))]
5363#[cfg_attr(feature = "bindings", ts(export))]
5364pub struct Prior {
5365    pub this: Expression,
5366}
5367
5368/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5370#[cfg_attr(feature = "bindings", derive(TS))]
5371#[cfg_attr(feature = "bindings", ts(export))]
5372pub struct ConnectByRoot {
5373    pub this: Expression,
5374}
5375
5376/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5377#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5378#[cfg_attr(feature = "bindings", derive(TS))]
5379#[cfg_attr(feature = "bindings", ts(export))]
5380pub struct MatchRecognize {
5381    /// Source table/expression
5382    pub this: Option<Box<Expression>>,
5383    /// PARTITION BY expressions
5384    pub partition_by: Option<Vec<Expression>>,
5385    /// ORDER BY expressions
5386    pub order_by: Option<Vec<Ordered>>,
5387    /// MEASURES definitions
5388    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5389    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5390    pub rows: Option<MatchRecognizeRows>,
5391    /// AFTER MATCH SKIP behavior
5392    pub after: Option<MatchRecognizeAfter>,
5393    /// PATTERN definition (stored as raw string for complex regex patterns)
5394    pub pattern: Option<String>,
5395    /// DEFINE clauses (pattern variable definitions)
5396    pub define: Option<Vec<(Identifier, Expression)>>,
5397    /// Optional alias for the result
5398    pub alias: Option<Identifier>,
5399    /// Whether AS keyword was explicitly present before alias
5400    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5401    pub alias_explicit_as: bool,
5402}
5403
5404/// MEASURES expression with optional RUNNING/FINAL semantics
5405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5406#[cfg_attr(feature = "bindings", derive(TS))]
5407#[cfg_attr(feature = "bindings", ts(export))]
5408pub struct MatchRecognizeMeasure {
5409    /// The measure expression
5410    pub this: Expression,
5411    /// RUNNING or FINAL semantics (Snowflake-specific)
5412    pub window_frame: Option<MatchRecognizeSemantics>,
5413}
5414
5415/// Semantics for MEASURES in MATCH_RECOGNIZE
5416#[derive(
5417    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5418)]
5419#[cfg_attr(feature = "bindings", derive(TS))]
5420#[cfg_attr(feature = "bindings", ts(export))]
5421pub enum MatchRecognizeSemantics {
5422    Running,
5423    Final,
5424}
5425
5426/// Row output semantics for MATCH_RECOGNIZE
5427#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5428#[cfg_attr(feature = "bindings", derive(TS))]
5429#[cfg_attr(feature = "bindings", ts(export))]
5430pub enum MatchRecognizeRows {
5431    OneRowPerMatch,
5432    AllRowsPerMatch,
5433    AllRowsPerMatchShowEmptyMatches,
5434    AllRowsPerMatchOmitEmptyMatches,
5435    AllRowsPerMatchWithUnmatchedRows,
5436}
5437
5438/// AFTER MATCH SKIP behavior
5439#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5440#[cfg_attr(feature = "bindings", derive(TS))]
5441#[cfg_attr(feature = "bindings", ts(export))]
5442pub enum MatchRecognizeAfter {
5443    PastLastRow,
5444    ToNextRow,
5445    ToFirst(Identifier),
5446    ToLast(Identifier),
5447}
5448
5449/// Represent a LIMIT clause that restricts the number of returned rows.
5450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5451#[cfg_attr(feature = "bindings", derive(TS))]
5452pub struct Limit {
5453    /// The limit count expression.
5454    pub this: Expression,
5455    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5456    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5457    pub percent: bool,
5458    /// Comments from before the LIMIT keyword (emitted after the limit value)
5459    #[serde(default)]
5460    #[serde(skip_serializing_if = "Vec::is_empty")]
5461    pub comments: Vec<String>,
5462}
5463
5464/// OFFSET clause
5465#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5466#[cfg_attr(feature = "bindings", derive(TS))]
5467pub struct Offset {
5468    pub this: Expression,
5469    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5470    #[serde(skip_serializing_if = "Option::is_none", default)]
5471    pub rows: Option<bool>,
5472}
5473
5474/// TOP clause (SQL Server)
5475#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5476#[cfg_attr(feature = "bindings", derive(TS))]
5477pub struct Top {
5478    pub this: Expression,
5479    pub percent: bool,
5480    pub with_ties: bool,
5481    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5482    #[serde(default)]
5483    pub parenthesized: bool,
5484}
5485
5486/// FETCH FIRST/NEXT clause (SQL standard)
5487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5488#[cfg_attr(feature = "bindings", derive(TS))]
5489pub struct Fetch {
5490    /// FIRST or NEXT
5491    pub direction: String,
5492    /// Count expression (optional)
5493    pub count: Option<Expression>,
5494    /// PERCENT modifier
5495    pub percent: bool,
5496    /// ROWS or ROW keyword present
5497    pub rows: bool,
5498    /// WITH TIES modifier
5499    pub with_ties: bool,
5500}
5501
5502/// Represent a QUALIFY clause for filtering on window function results.
5503///
5504/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5505/// typically references a window function (e.g.
5506/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5508#[cfg_attr(feature = "bindings", derive(TS))]
5509pub struct Qualify {
5510    /// The filter predicate over window function results.
5511    pub this: Expression,
5512}
5513
5514/// SAMPLE / TABLESAMPLE clause
5515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5516#[cfg_attr(feature = "bindings", derive(TS))]
5517pub struct Sample {
5518    pub method: SampleMethod,
5519    pub size: Expression,
5520    pub seed: Option<Expression>,
5521    /// ClickHouse OFFSET expression after SAMPLE size
5522    #[serde(default)]
5523    pub offset: Option<Expression>,
5524    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5525    pub unit_after_size: bool,
5526    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5527    #[serde(default)]
5528    pub use_sample_keyword: bool,
5529    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5530    #[serde(default)]
5531    pub explicit_method: bool,
5532    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5533    #[serde(default)]
5534    pub method_before_size: bool,
5535    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5536    #[serde(default)]
5537    pub use_seed_keyword: bool,
5538    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5539    pub bucket_numerator: Option<Box<Expression>>,
5540    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5541    pub bucket_denominator: Option<Box<Expression>>,
5542    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5543    pub bucket_field: Option<Box<Expression>>,
5544    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5545    #[serde(default)]
5546    pub is_using_sample: bool,
5547    /// Whether the unit was explicitly PERCENT (vs ROWS)
5548    #[serde(default)]
5549    pub is_percent: bool,
5550    /// Whether to suppress method output (for cross-dialect transpilation)
5551    #[serde(default)]
5552    pub suppress_method_output: bool,
5553}
5554
5555/// Sample method
5556#[derive(
5557    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5558)]
5559#[cfg_attr(feature = "bindings", derive(TS))]
5560pub enum SampleMethod {
5561    Bernoulli,
5562    System,
5563    Block,
5564    Row,
5565    Percent,
5566    /// Hive bucket sampling
5567    Bucket,
5568    /// DuckDB reservoir sampling
5569    Reservoir,
5570}
5571
5572/// Named window definition (WINDOW w AS (...))
5573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5574#[cfg_attr(feature = "bindings", derive(TS))]
5575pub struct NamedWindow {
5576    pub name: Identifier,
5577    pub spec: Over,
5578}
5579
5580/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5581///
5582/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5583/// that reference themselves. Each CTE is defined in the `ctes` vector and
5584/// can be referenced by name in subsequent CTEs and in the main query body.
5585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5586#[cfg_attr(feature = "bindings", derive(TS))]
5587pub struct With {
5588    /// The list of CTE definitions, in order.
5589    pub ctes: Vec<Cte>,
5590    /// Whether the WITH RECURSIVE keyword was used.
5591    pub recursive: bool,
5592    /// Leading comments before the statement
5593    #[serde(default)]
5594    pub leading_comments: Vec<String>,
5595    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5596    #[serde(default, skip_serializing_if = "Option::is_none")]
5597    pub search: Option<Box<Expression>>,
5598}
5599
5600/// Represent a single Common Table Expression definition.
5601///
5602/// A CTE has a name (`alias`), an optional column list, and a body query.
5603/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5604/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5605/// the expression comes before the alias (`alias_first`).
5606#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5607#[cfg_attr(feature = "bindings", derive(TS))]
5608pub struct Cte {
5609    /// The CTE name.
5610    pub alias: Identifier,
5611    /// The CTE body (typically a SELECT, UNION, etc.).
5612    pub this: Expression,
5613    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5614    pub columns: Vec<Identifier>,
5615    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5616    pub materialized: Option<bool>,
5617    /// USING KEY (columns) for DuckDB recursive CTEs
5618    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5619    pub key_expressions: Vec<Identifier>,
5620    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5621    #[serde(default)]
5622    pub alias_first: bool,
5623    /// Comments associated with this CTE (placed after alias name, before AS)
5624    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5625    pub comments: Vec<String>,
5626}
5627
5628/// Window specification
5629#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5630#[cfg_attr(feature = "bindings", derive(TS))]
5631pub struct WindowSpec {
5632    pub partition_by: Vec<Expression>,
5633    pub order_by: Vec<Ordered>,
5634    pub frame: Option<WindowFrame>,
5635}
5636
5637/// OVER clause
5638#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5639#[cfg_attr(feature = "bindings", derive(TS))]
5640pub struct Over {
5641    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
5642    pub window_name: Option<Identifier>,
5643    pub partition_by: Vec<Expression>,
5644    pub order_by: Vec<Ordered>,
5645    pub frame: Option<WindowFrame>,
5646    pub alias: Option<Identifier>,
5647}
5648
5649/// Window frame
5650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5651#[cfg_attr(feature = "bindings", derive(TS))]
5652pub struct WindowFrame {
5653    pub kind: WindowFrameKind,
5654    pub start: WindowFrameBound,
5655    pub end: Option<WindowFrameBound>,
5656    pub exclude: Option<WindowFrameExclude>,
5657    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
5658    #[serde(default, skip_serializing_if = "Option::is_none")]
5659    pub kind_text: Option<String>,
5660    /// Original text of the start bound side keyword (e.g. "preceding")
5661    #[serde(default, skip_serializing_if = "Option::is_none")]
5662    pub start_side_text: Option<String>,
5663    /// Original text of the end bound side keyword
5664    #[serde(default, skip_serializing_if = "Option::is_none")]
5665    pub end_side_text: Option<String>,
5666}
5667
5668#[derive(
5669    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5670)]
5671#[cfg_attr(feature = "bindings", derive(TS))]
5672pub enum WindowFrameKind {
5673    Rows,
5674    Range,
5675    Groups,
5676}
5677
5678/// EXCLUDE clause for window frames
5679#[derive(
5680    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5681)]
5682#[cfg_attr(feature = "bindings", derive(TS))]
5683pub enum WindowFrameExclude {
5684    CurrentRow,
5685    Group,
5686    Ties,
5687    NoOthers,
5688}
5689
5690#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5691#[cfg_attr(feature = "bindings", derive(TS))]
5692pub enum WindowFrameBound {
5693    CurrentRow,
5694    UnboundedPreceding,
5695    UnboundedFollowing,
5696    Preceding(Box<Expression>),
5697    Following(Box<Expression>),
5698    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
5699    BarePreceding,
5700    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
5701    BareFollowing,
5702    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
5703    Value(Box<Expression>),
5704}
5705
5706/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
5707#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5708#[cfg_attr(feature = "bindings", derive(TS))]
5709pub struct StructField {
5710    pub name: String,
5711    pub data_type: DataType,
5712    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5713    pub options: Vec<Expression>,
5714    #[serde(default, skip_serializing_if = "Option::is_none")]
5715    pub comment: Option<String>,
5716}
5717
5718impl StructField {
5719    /// Create a new struct field without options
5720    pub fn new(name: String, data_type: DataType) -> Self {
5721        Self {
5722            name,
5723            data_type,
5724            options: Vec::new(),
5725            comment: None,
5726        }
5727    }
5728
5729    /// Create a new struct field with options
5730    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
5731        Self {
5732            name,
5733            data_type,
5734            options,
5735            comment: None,
5736        }
5737    }
5738
5739    /// Create a new struct field with options and comment
5740    pub fn with_options_and_comment(
5741        name: String,
5742        data_type: DataType,
5743        options: Vec<Expression>,
5744        comment: Option<String>,
5745    ) -> Self {
5746        Self {
5747            name,
5748            data_type,
5749            options,
5750            comment,
5751        }
5752    }
5753}
5754
5755/// Oracle-specific data types whose semantics cannot be represented losslessly by the
5756/// generic [`DataType`] variants.
5757///
5758/// Keeping these types structured allows the Oracle parser to retain details such as a
5759/// negative `NUMBER` scale, `BYTE`/`CHAR` length semantics, interval precisions, and
5760/// `TIMESTAMP WITH LOCAL TIME ZONE` until the target dialect is known.
5761#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5762#[cfg_attr(feature = "bindings", derive(TS))]
5763#[serde(tag = "oracle_data_type", rename_all = "snake_case")]
5764pub enum OracleDataType {
5765    Number {
5766        precision: Option<u32>,
5767        scale: Option<i32>,
5768    },
5769    BinaryFloat,
5770    BinaryDouble,
5771    Float {
5772        precision: Option<u32>,
5773    },
5774    Character {
5775        kind: OracleCharacterKind,
5776        length: Option<u32>,
5777        semantics: Option<OracleCharacterLengthSemantics>,
5778    },
5779    Date,
5780    Timestamp {
5781        precision: Option<u32>,
5782        timezone: OracleTimestampTimeZone,
5783    },
5784    IntervalYearToMonth {
5785        year_precision: Option<u32>,
5786    },
5787    IntervalDayToSecond {
5788        day_precision: Option<u32>,
5789        fractional_seconds_precision: Option<u32>,
5790    },
5791    Clob {
5792        national: bool,
5793    },
5794    Blob,
5795    Raw {
5796        length: Option<u32>,
5797    },
5798    Long {
5799        raw: bool,
5800    },
5801    RowId,
5802}
5803
5804#[derive(
5805    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5806)]
5807#[cfg_attr(feature = "bindings", derive(TS))]
5808#[serde(rename_all = "snake_case")]
5809pub enum OracleCharacterKind {
5810    Char,
5811    VarChar,
5812    NChar,
5813    NVarChar,
5814}
5815
5816#[derive(
5817    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5818)]
5819#[cfg_attr(feature = "bindings", derive(TS))]
5820#[serde(rename_all = "snake_case")]
5821pub enum OracleCharacterLengthSemantics {
5822    Byte,
5823    Char,
5824}
5825
5826#[derive(
5827    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5828)]
5829#[cfg_attr(feature = "bindings", derive(TS))]
5830#[serde(rename_all = "snake_case")]
5831pub enum OracleTimestampTimeZone {
5832    None,
5833    WithTimeZone,
5834    WithLocalTimeZone,
5835}
5836
5837/// Enumerate all SQL data types recognized by the parser.
5838///
5839/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
5840/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
5841/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
5842///
5843/// This enum is used in CAST expressions, column definitions, function return
5844/// types, and anywhere a data type specification appears in SQL.
5845///
5846/// Types that do not match any known variant fall through to `Custom { name }`,
5847/// preserving the original type name for round-trip fidelity.
5848#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5849#[cfg_attr(feature = "bindings", derive(TS))]
5850#[serde(tag = "data_type", rename_all = "snake_case")]
5851pub enum DataType {
5852    // Numeric
5853    Boolean,
5854    TinyInt {
5855        length: Option<u32>,
5856    },
5857    SmallInt {
5858        length: Option<u32>,
5859    },
5860    /// Int type with optional length. `integer_spelling` indicates whether the original
5861    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
5862    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
5863    Int {
5864        length: Option<u32>,
5865        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5866        integer_spelling: bool,
5867    },
5868    BigInt {
5869        length: Option<u32>,
5870    },
5871    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
5872    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
5873    /// preserve the original spelling.
5874    Float {
5875        precision: Option<u32>,
5876        scale: Option<u32>,
5877        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5878        real_spelling: bool,
5879    },
5880    Double {
5881        precision: Option<u32>,
5882        scale: Option<u32>,
5883    },
5884    Decimal {
5885        precision: Option<u32>,
5886        scale: Option<u32>,
5887    },
5888    /// Structured Oracle data type retained until the target dialect is known.
5889    Oracle {
5890        oracle_type: OracleDataType,
5891    },
5892
5893    // String
5894    Char {
5895        length: Option<u32>,
5896    },
5897    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
5898    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
5899    VarChar {
5900        length: Option<u32>,
5901        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5902        parenthesized_length: bool,
5903    },
5904    /// String type with optional max length (BigQuery STRING(n))
5905    String {
5906        length: Option<u32>,
5907    },
5908    Text,
5909    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
5910    TextWithLength {
5911        length: u32,
5912    },
5913
5914    // Binary
5915    Binary {
5916        length: Option<u32>,
5917    },
5918    VarBinary {
5919        length: Option<u32>,
5920    },
5921    Blob,
5922
5923    // Bit
5924    Bit {
5925        length: Option<u32>,
5926    },
5927    VarBit {
5928        length: Option<u32>,
5929    },
5930
5931    // Date/Time
5932    Date,
5933    Time {
5934        precision: Option<u32>,
5935        #[serde(default)]
5936        timezone: bool,
5937    },
5938    Timestamp {
5939        precision: Option<u32>,
5940        timezone: bool,
5941    },
5942    Interval {
5943        unit: Option<String>,
5944        /// For range intervals like INTERVAL DAY TO HOUR
5945        #[serde(default, skip_serializing_if = "Option::is_none")]
5946        to: Option<String>,
5947    },
5948
5949    // JSON
5950    Json,
5951    JsonB,
5952
5953    // UUID
5954    Uuid,
5955
5956    // Array
5957    Array {
5958        element_type: Box<DataType>,
5959        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
5960        #[serde(default, skip_serializing_if = "Option::is_none")]
5961        dimension: Option<u32>,
5962    },
5963
5964    /// List type (Materialize): INT LIST, TEXT LIST LIST
5965    /// Uses postfix LIST syntax instead of ARRAY<T>
5966    List {
5967        element_type: Box<DataType>,
5968    },
5969
5970    // Struct/Map
5971    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
5972    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
5973    Struct {
5974        fields: Vec<StructField>,
5975        nested: bool,
5976    },
5977    Map {
5978        key_type: Box<DataType>,
5979        value_type: Box<DataType>,
5980    },
5981
5982    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
5983    Enum {
5984        values: Vec<String>,
5985        #[serde(default, skip_serializing_if = "Vec::is_empty")]
5986        assignments: Vec<Option<String>>,
5987    },
5988
5989    // Set type (MySQL): SET('a', 'b', 'c')
5990    Set {
5991        values: Vec<String>,
5992    },
5993
5994    // Union type (DuckDB): UNION(num INT, str TEXT)
5995    Union {
5996        fields: Vec<(String, DataType)>,
5997    },
5998
5999    // Vector (Snowflake / SingleStore)
6000    Vector {
6001        #[serde(default)]
6002        element_type: Option<Box<DataType>>,
6003        dimension: Option<u32>,
6004    },
6005
6006    // Object (Snowflake structured type)
6007    // fields: Vec of (field_name, field_type, not_null)
6008    Object {
6009        fields: Vec<(String, DataType, bool)>,
6010        modifier: Option<String>,
6011    },
6012
6013    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
6014    Nullable {
6015        inner: Box<DataType>,
6016    },
6017
6018    // Custom/User-defined
6019    Custom {
6020        name: String,
6021    },
6022
6023    // Spatial types
6024    Geometry {
6025        subtype: Option<String>,
6026        srid: Option<u32>,
6027    },
6028    Geography {
6029        subtype: Option<String>,
6030        srid: Option<u32>,
6031    },
6032
6033    // Character Set (for CONVERT USING in MySQL)
6034    // Renders as CHAR CHARACTER SET {name} in cast target
6035    CharacterSet {
6036        name: String,
6037    },
6038
6039    // Unknown
6040    Unknown,
6041}
6042
6043/// Array expression
6044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6045#[cfg_attr(feature = "bindings", derive(TS))]
6046#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
6047pub struct Array {
6048    pub expressions: Vec<Expression>,
6049}
6050
6051/// Struct expression
6052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6053#[cfg_attr(feature = "bindings", derive(TS))]
6054pub struct Struct {
6055    pub fields: Vec<(Option<String>, Expression)>,
6056}
6057
6058/// Tuple expression
6059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6060#[cfg_attr(feature = "bindings", derive(TS))]
6061pub struct Tuple {
6062    pub expressions: Vec<Expression>,
6063}
6064
6065/// Interval expression
6066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6067#[cfg_attr(feature = "bindings", derive(TS))]
6068pub struct Interval {
6069    /// The value expression (e.g., '1', 5, column_ref)
6070    pub this: Option<Expression>,
6071    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
6072    pub unit: Option<IntervalUnitSpec>,
6073}
6074
6075/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
6076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6077#[cfg_attr(feature = "bindings", derive(TS))]
6078#[serde(tag = "type", rename_all = "snake_case")]
6079pub enum IntervalUnitSpec {
6080    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
6081    Simple {
6082        unit: IntervalUnit,
6083        /// Whether to use plural form (e.g., DAYS vs DAY)
6084        use_plural: bool,
6085    },
6086    /// Interval span (e.g., HOUR TO SECOND)
6087    Span(IntervalSpan),
6088    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6089    /// The start and end can be expressions like function calls with precision
6090    ExprSpan(IntervalSpanExpr),
6091    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6092    Expr(Box<Expression>),
6093}
6094
6095/// Interval span for ranges like HOUR TO SECOND
6096#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6097#[cfg_attr(feature = "bindings", derive(TS))]
6098pub struct IntervalSpan {
6099    /// Start unit (e.g., HOUR)
6100    pub this: IntervalUnit,
6101    /// End unit (e.g., SECOND)
6102    pub expression: IntervalUnit,
6103}
6104
6105/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6106/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6107#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6108#[cfg_attr(feature = "bindings", derive(TS))]
6109pub struct IntervalSpanExpr {
6110    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6111    pub this: Box<Expression>,
6112    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6113    pub expression: Box<Expression>,
6114}
6115
6116#[derive(
6117    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6118)]
6119#[cfg_attr(feature = "bindings", derive(TS))]
6120pub enum IntervalUnit {
6121    Year,
6122    Quarter,
6123    Month,
6124    Week,
6125    Day,
6126    Hour,
6127    Minute,
6128    Second,
6129    Millisecond,
6130    Microsecond,
6131    Nanosecond,
6132}
6133
6134/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6136#[cfg_attr(feature = "bindings", derive(TS))]
6137pub struct Command {
6138    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6139    pub this: String,
6140}
6141
6142/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6143/// Syntax: PREPARE name [(type, ...)] AS statement
6144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6145#[cfg_attr(feature = "bindings", derive(TS))]
6146pub struct PrepareStatement {
6147    /// The prepared statement name.
6148    pub name: Identifier,
6149    /// Optional PostgreSQL parameter type list.
6150    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6151    pub parameter_types: Vec<DataType>,
6152    /// The statement to execute when the prepared statement is invoked.
6153    pub statement: Expression,
6154}
6155
6156/// T-SQL TRY/CATCH block.
6157#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6158#[cfg_attr(feature = "bindings", derive(TS))]
6159pub struct TryCatch {
6160    /// Statements inside BEGIN TRY ... END TRY.
6161    #[serde(default)]
6162    pub try_body: Vec<Expression>,
6163    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6164    #[serde(default, skip_serializing_if = "Option::is_none")]
6165    pub catch_body: Option<Vec<Expression>>,
6166}
6167
6168/// EXEC/EXECUTE statement (TSQL stored procedure call)
6169/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6171#[cfg_attr(feature = "bindings", derive(TS))]
6172pub struct ExecuteStatement {
6173    /// The procedure name (can be qualified: schema.proc_name)
6174    pub this: Expression,
6175    /// Optional T-SQL return-status variable (`EXECUTE @status = procedure`).
6176    #[serde(default, skip_serializing_if = "Option::is_none")]
6177    pub return_status: Option<String>,
6178    /// Named parameters: @param=value pairs
6179    #[serde(default)]
6180    pub parameters: Vec<ExecuteParameter>,
6181    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6182    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6183    pub arguments: Vec<Expression>,
6184    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6185    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6186    pub prepared: bool,
6187    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6188    #[serde(default, skip_serializing_if = "Option::is_none")]
6189    pub suffix: Option<String>,
6190}
6191
6192/// Named parameter in EXEC statement: @name=value
6193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6194#[cfg_attr(feature = "bindings", derive(TS))]
6195pub struct ExecuteParameter {
6196    /// Parameter name (including @)
6197    pub name: String,
6198    /// Parameter value
6199    pub value: Expression,
6200    /// Whether this is a positional parameter (no = sign)
6201    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6202    pub positional: bool,
6203    /// TSQL OUTPUT modifier on parameter
6204    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6205    pub output: bool,
6206}
6207
6208/// KILL statement (MySQL/MariaDB)
6209/// KILL [CONNECTION | QUERY] <id>
6210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6211#[cfg_attr(feature = "bindings", derive(TS))]
6212pub struct Kill {
6213    /// The target (process ID or connection ID)
6214    pub this: Expression,
6215    /// Optional kind: "CONNECTION" or "QUERY"
6216    pub kind: Option<String>,
6217}
6218
6219/// Snowflake CREATE TASK statement
6220#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6221#[cfg_attr(feature = "bindings", derive(TS))]
6222pub struct CreateTask {
6223    pub or_replace: bool,
6224    pub if_not_exists: bool,
6225    /// Task name (possibly qualified: db.schema.task)
6226    pub name: String,
6227    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6228    pub properties: String,
6229    /// The SQL statement body after AS
6230    pub body: Expression,
6231}
6232
6233/// Raw/unparsed SQL
6234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6235#[cfg_attr(feature = "bindings", derive(TS))]
6236pub struct Raw {
6237    pub sql: String,
6238}
6239
6240// ============================================================================
6241// Function expression types
6242// ============================================================================
6243
6244/// Generic unary function (takes a single argument)
6245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6246#[cfg_attr(feature = "bindings", derive(TS))]
6247pub struct UnaryFunc {
6248    pub this: Expression,
6249    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6250    #[serde(skip_serializing_if = "Option::is_none", default)]
6251    pub original_name: Option<String>,
6252    /// Inferred data type from type annotation
6253    #[serde(default, skip_serializing_if = "Option::is_none")]
6254    #[ast(skip)]
6255    pub inferred_type: Option<DataType>,
6256}
6257
6258impl UnaryFunc {
6259    /// Create a new UnaryFunc with no original_name
6260    pub fn new(this: Expression) -> Self {
6261        Self {
6262            this,
6263            original_name: None,
6264            inferred_type: None,
6265        }
6266    }
6267
6268    /// Create a new UnaryFunc with an original name for round-trip preservation
6269    pub fn with_name(this: Expression, name: String) -> Self {
6270        Self {
6271            this,
6272            original_name: Some(name),
6273            inferred_type: None,
6274        }
6275    }
6276}
6277
6278/// CHAR/CHR function with multiple args and optional USING charset
6279/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6280/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6282#[cfg_attr(feature = "bindings", derive(TS))]
6283pub struct CharFunc {
6284    pub args: Vec<Expression>,
6285    #[serde(skip_serializing_if = "Option::is_none", default)]
6286    pub charset: Option<String>,
6287    /// Original function name (CHAR or CHR), defaults to CHAR
6288    #[serde(skip_serializing_if = "Option::is_none", default)]
6289    pub name: Option<String>,
6290}
6291
6292/// Generic binary function (takes two arguments)
6293#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6294#[cfg_attr(feature = "bindings", derive(TS))]
6295pub struct BinaryFunc {
6296    pub this: Expression,
6297    pub expression: Expression,
6298    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6299    #[serde(skip_serializing_if = "Option::is_none", default)]
6300    pub original_name: Option<String>,
6301    /// Inferred data type from type annotation
6302    #[serde(default, skip_serializing_if = "Option::is_none")]
6303    #[ast(skip)]
6304    pub inferred_type: Option<DataType>,
6305}
6306
6307/// Variable argument function
6308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6309#[cfg_attr(feature = "bindings", derive(TS))]
6310pub struct VarArgFunc {
6311    pub expressions: Vec<Expression>,
6312    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6313    #[serde(skip_serializing_if = "Option::is_none", default)]
6314    pub original_name: Option<String>,
6315    /// Inferred data type from type annotation
6316    #[serde(default, skip_serializing_if = "Option::is_none")]
6317    #[ast(skip)]
6318    pub inferred_type: Option<DataType>,
6319}
6320
6321/// CONCAT_WS function
6322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6323#[cfg_attr(feature = "bindings", derive(TS))]
6324pub struct ConcatWs {
6325    pub separator: Expression,
6326    pub expressions: Vec<Expression>,
6327}
6328
6329/// SUBSTRING function
6330#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6331#[cfg_attr(feature = "bindings", derive(TS))]
6332pub struct SubstringFunc {
6333    pub this: Expression,
6334    pub start: Expression,
6335    pub length: Option<Expression>,
6336    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6337    #[serde(default)]
6338    pub from_for_syntax: bool,
6339}
6340
6341/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6342#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6343#[cfg_attr(feature = "bindings", derive(TS))]
6344pub struct OverlayFunc {
6345    pub this: Expression,
6346    pub replacement: Expression,
6347    pub from: Expression,
6348    pub length: Option<Expression>,
6349}
6350
6351/// TRIM function
6352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6353#[cfg_attr(feature = "bindings", derive(TS))]
6354pub struct TrimFunc {
6355    pub this: Expression,
6356    pub characters: Option<Expression>,
6357    pub position: TrimPosition,
6358    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6359    #[serde(default)]
6360    pub sql_standard_syntax: bool,
6361    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6362    #[serde(default)]
6363    pub position_explicit: bool,
6364}
6365
6366#[derive(
6367    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6368)]
6369#[cfg_attr(feature = "bindings", derive(TS))]
6370pub enum TrimPosition {
6371    Both,
6372    Leading,
6373    Trailing,
6374}
6375
6376/// REPLACE function
6377#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6378#[cfg_attr(feature = "bindings", derive(TS))]
6379pub struct ReplaceFunc {
6380    pub this: Expression,
6381    pub old: Expression,
6382    pub new: Expression,
6383}
6384
6385/// LEFT/RIGHT function
6386#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6387#[cfg_attr(feature = "bindings", derive(TS))]
6388pub struct LeftRightFunc {
6389    pub this: Expression,
6390    pub length: Expression,
6391}
6392
6393/// REPEAT function
6394#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6395#[cfg_attr(feature = "bindings", derive(TS))]
6396pub struct RepeatFunc {
6397    pub this: Expression,
6398    pub times: Expression,
6399}
6400
6401/// LPAD/RPAD function
6402#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6403#[cfg_attr(feature = "bindings", derive(TS))]
6404pub struct PadFunc {
6405    pub this: Expression,
6406    pub length: Expression,
6407    pub fill: Option<Expression>,
6408}
6409
6410/// SPLIT function
6411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6412#[cfg_attr(feature = "bindings", derive(TS))]
6413pub struct SplitFunc {
6414    pub this: Expression,
6415    pub delimiter: Expression,
6416}
6417
6418/// REGEXP_LIKE function
6419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6420#[cfg_attr(feature = "bindings", derive(TS))]
6421pub struct RegexpFunc {
6422    pub this: Expression,
6423    pub pattern: Expression,
6424    pub flags: Option<Expression>,
6425}
6426
6427/// REGEXP_REPLACE function
6428#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6429#[cfg_attr(feature = "bindings", derive(TS))]
6430pub struct RegexpReplaceFunc {
6431    pub this: Expression,
6432    pub pattern: Expression,
6433    pub replacement: Expression,
6434    pub flags: Option<Expression>,
6435}
6436
6437/// REGEXP_EXTRACT function
6438#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6439#[cfg_attr(feature = "bindings", derive(TS))]
6440pub struct RegexpExtractFunc {
6441    pub this: Expression,
6442    pub pattern: Expression,
6443    pub group: Option<Expression>,
6444}
6445
6446/// ROUND function
6447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6448#[cfg_attr(feature = "bindings", derive(TS))]
6449pub struct RoundFunc {
6450    pub this: Expression,
6451    pub decimals: Option<Expression>,
6452}
6453
6454/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6455#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6456#[cfg_attr(feature = "bindings", derive(TS))]
6457pub struct FloorFunc {
6458    pub this: Expression,
6459    pub scale: Option<Expression>,
6460    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6461    #[serde(skip_serializing_if = "Option::is_none", default)]
6462    pub to: Option<Expression>,
6463}
6464
6465/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6467#[cfg_attr(feature = "bindings", derive(TS))]
6468pub struct CeilFunc {
6469    pub this: Expression,
6470    #[serde(skip_serializing_if = "Option::is_none", default)]
6471    pub decimals: Option<Expression>,
6472    /// Time unit for Druid-style CEIL(time TO unit) syntax
6473    #[serde(skip_serializing_if = "Option::is_none", default)]
6474    pub to: Option<Expression>,
6475}
6476
6477/// LOG function
6478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6479#[cfg_attr(feature = "bindings", derive(TS))]
6480pub struct LogFunc {
6481    pub this: Expression,
6482    pub base: Option<Expression>,
6483}
6484
6485/// CURRENT_DATE (no arguments)
6486#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6487#[cfg_attr(feature = "bindings", derive(TS))]
6488pub struct CurrentDate;
6489
6490/// CURRENT_TIME
6491#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6492#[cfg_attr(feature = "bindings", derive(TS))]
6493pub struct CurrentTime {
6494    pub precision: Option<u32>,
6495}
6496
6497/// CURRENT_TIMESTAMP
6498#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6499#[cfg_attr(feature = "bindings", derive(TS))]
6500pub struct CurrentTimestamp {
6501    pub precision: Option<u32>,
6502    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6503    #[serde(default)]
6504    pub sysdate: bool,
6505}
6506
6507/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6508#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6509#[cfg_attr(feature = "bindings", derive(TS))]
6510pub struct CurrentTimestampLTZ {
6511    pub precision: Option<u32>,
6512}
6513
6514/// AT TIME ZONE expression for timezone conversion
6515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6516#[cfg_attr(feature = "bindings", derive(TS))]
6517pub struct AtTimeZone {
6518    /// The expression to convert
6519    pub this: Expression,
6520    /// The target timezone
6521    pub zone: Expression,
6522}
6523
6524/// DATE_ADD / DATE_SUB function
6525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6526#[cfg_attr(feature = "bindings", derive(TS))]
6527pub struct DateAddFunc {
6528    pub this: Expression,
6529    pub interval: Expression,
6530    pub unit: IntervalUnit,
6531}
6532
6533/// DATEDIFF function
6534#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6535#[cfg_attr(feature = "bindings", derive(TS))]
6536pub struct DateDiffFunc {
6537    pub this: Expression,
6538    pub expression: Expression,
6539    pub unit: Option<IntervalUnit>,
6540}
6541
6542/// DATE_TRUNC function
6543#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6544#[cfg_attr(feature = "bindings", derive(TS))]
6545pub struct DateTruncFunc {
6546    pub this: Expression,
6547    pub unit: DateTimeField,
6548}
6549
6550/// EXTRACT function
6551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6552#[cfg_attr(feature = "bindings", derive(TS))]
6553pub struct ExtractFunc {
6554    pub this: Expression,
6555    pub field: DateTimeField,
6556}
6557
6558#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6559#[cfg_attr(feature = "bindings", derive(TS))]
6560pub enum DateTimeField {
6561    Year,
6562    Month,
6563    Day,
6564    Hour,
6565    Minute,
6566    Second,
6567    Millisecond,
6568    Microsecond,
6569    DayOfWeek,
6570    DayOfYear,
6571    Week,
6572    /// Week with a modifier like WEEK(monday), WEEK(sunday)
6573    WeekWithModifier(String),
6574    Quarter,
6575    Epoch,
6576    Timezone,
6577    TimezoneHour,
6578    TimezoneMinute,
6579    Date,
6580    Time,
6581    /// Custom datetime field for dialect-specific or arbitrary fields
6582    Custom(String),
6583}
6584
6585/// TO_DATE function
6586#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6587#[cfg_attr(feature = "bindings", derive(TS))]
6588pub struct ToDateFunc {
6589    pub this: Expression,
6590    pub format: Option<Expression>,
6591}
6592
6593/// TO_TIMESTAMP function
6594#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6595#[cfg_attr(feature = "bindings", derive(TS))]
6596pub struct ToTimestampFunc {
6597    pub this: Expression,
6598    pub format: Option<Expression>,
6599}
6600
6601/// IF function
6602#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6603#[cfg_attr(feature = "bindings", derive(TS))]
6604pub struct IfFunc {
6605    pub condition: Expression,
6606    pub true_value: Expression,
6607    pub false_value: Option<Expression>,
6608    /// Original function name (IF, IFF, IIF) for round-trip preservation
6609    #[serde(skip_serializing_if = "Option::is_none", default)]
6610    pub original_name: Option<String>,
6611    /// Inferred data type from type annotation
6612    #[serde(default, skip_serializing_if = "Option::is_none")]
6613    #[ast(skip)]
6614    pub inferred_type: Option<DataType>,
6615}
6616
6617/// NVL2 function
6618#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6619#[cfg_attr(feature = "bindings", derive(TS))]
6620pub struct Nvl2Func {
6621    pub this: Expression,
6622    pub true_value: Expression,
6623    pub false_value: Expression,
6624    /// Inferred data type from type annotation
6625    #[serde(default, skip_serializing_if = "Option::is_none")]
6626    #[ast(skip)]
6627    pub inferred_type: Option<DataType>,
6628}
6629
6630// ============================================================================
6631// Typed Aggregate Function types
6632// ============================================================================
6633
6634/// Generic aggregate function base type
6635#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6636#[cfg_attr(feature = "bindings", derive(TS))]
6637pub struct AggFunc {
6638    pub this: Expression,
6639    pub distinct: bool,
6640    pub filter: Option<Expression>,
6641    pub order_by: Vec<Ordered>,
6642    /// Original function name (case-preserving) when parsed from SQL
6643    #[serde(skip_serializing_if = "Option::is_none", default)]
6644    pub name: Option<String>,
6645    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
6646    #[serde(skip_serializing_if = "Option::is_none", default)]
6647    pub ignore_nulls: Option<bool>,
6648    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
6649    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
6650    #[serde(skip_serializing_if = "Option::is_none", default)]
6651    pub having_max: Option<(Box<Expression>, bool)>,
6652    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
6653    #[serde(skip_serializing_if = "Option::is_none", default)]
6654    pub limit: Option<Box<Expression>>,
6655    /// Inferred data type from type annotation
6656    #[serde(default, skip_serializing_if = "Option::is_none")]
6657    #[ast(skip)]
6658    pub inferred_type: Option<DataType>,
6659}
6660
6661/// COUNT function with optional star
6662#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6663#[cfg_attr(feature = "bindings", derive(TS))]
6664pub struct CountFunc {
6665    pub this: Option<Expression>,
6666    pub star: bool,
6667    pub distinct: bool,
6668    pub filter: Option<Expression>,
6669    /// IGNORE NULLS (true) or RESPECT NULLS (false)
6670    #[serde(default, skip_serializing_if = "Option::is_none")]
6671    pub ignore_nulls: Option<bool>,
6672    /// Original function name for case preservation (e.g., "count" or "COUNT")
6673    #[serde(default, skip_serializing_if = "Option::is_none")]
6674    pub original_name: Option<String>,
6675    /// Inferred data type from type annotation
6676    #[serde(default, skip_serializing_if = "Option::is_none")]
6677    #[ast(skip)]
6678    pub inferred_type: Option<DataType>,
6679}
6680
6681/// GROUP_CONCAT function (MySQL style)
6682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6683#[cfg_attr(feature = "bindings", derive(TS))]
6684pub struct GroupConcatFunc {
6685    pub this: Expression,
6686    pub separator: Option<Expression>,
6687    pub order_by: Option<Vec<Ordered>>,
6688    pub distinct: bool,
6689    pub filter: Option<Expression>,
6690    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
6691    #[serde(default, skip_serializing_if = "Option::is_none")]
6692    pub limit: Option<Box<Expression>>,
6693    /// Inferred data type from type annotation
6694    #[serde(default, skip_serializing_if = "Option::is_none")]
6695    #[ast(skip)]
6696    pub inferred_type: Option<DataType>,
6697}
6698
6699/// STRING_AGG function (PostgreSQL/Standard SQL)
6700#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6701#[cfg_attr(feature = "bindings", derive(TS))]
6702pub struct StringAggFunc {
6703    pub this: Expression,
6704    #[serde(default)]
6705    pub separator: Option<Expression>,
6706    #[serde(default)]
6707    pub order_by: Option<Vec<Ordered>>,
6708    #[serde(default)]
6709    pub distinct: bool,
6710    #[serde(default)]
6711    pub filter: Option<Expression>,
6712    /// BigQuery LIMIT inside STRING_AGG
6713    #[serde(default, skip_serializing_if = "Option::is_none")]
6714    pub limit: Option<Box<Expression>>,
6715    /// Inferred data type from type annotation
6716    #[serde(default, skip_serializing_if = "Option::is_none")]
6717    #[ast(skip)]
6718    pub inferred_type: Option<DataType>,
6719}
6720
6721/// LISTAGG function (Oracle style)
6722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6723#[cfg_attr(feature = "bindings", derive(TS))]
6724pub struct ListAggFunc {
6725    pub this: Expression,
6726    pub separator: Option<Expression>,
6727    pub on_overflow: Option<ListAggOverflow>,
6728    pub order_by: Option<Vec<Ordered>>,
6729    pub distinct: bool,
6730    pub filter: Option<Expression>,
6731    /// Inferred data type from type annotation
6732    #[serde(default, skip_serializing_if = "Option::is_none")]
6733    #[ast(skip)]
6734    pub inferred_type: Option<DataType>,
6735}
6736
6737/// LISTAGG ON OVERFLOW behavior
6738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6739#[cfg_attr(feature = "bindings", derive(TS))]
6740pub enum ListAggOverflow {
6741    Error,
6742    Truncate {
6743        filler: Option<Expression>,
6744        with_count: bool,
6745    },
6746}
6747
6748/// SUM_IF / COUNT_IF function
6749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6750#[cfg_attr(feature = "bindings", derive(TS))]
6751pub struct SumIfFunc {
6752    pub this: Expression,
6753    pub condition: Expression,
6754    pub filter: Option<Expression>,
6755    /// Inferred data type from type annotation
6756    #[serde(default, skip_serializing_if = "Option::is_none")]
6757    #[ast(skip)]
6758    pub inferred_type: Option<DataType>,
6759}
6760
6761/// APPROX_PERCENTILE function
6762#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6763#[cfg_attr(feature = "bindings", derive(TS))]
6764pub struct ApproxPercentileFunc {
6765    pub this: Expression,
6766    pub percentile: Expression,
6767    pub accuracy: Option<Expression>,
6768    pub filter: Option<Expression>,
6769}
6770
6771/// PERCENTILE_CONT / PERCENTILE_DISC function
6772#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6773#[cfg_attr(feature = "bindings", derive(TS))]
6774pub struct PercentileFunc {
6775    pub this: Expression,
6776    pub percentile: Expression,
6777    pub order_by: Option<Vec<Ordered>>,
6778    pub filter: Option<Expression>,
6779}
6780
6781// ============================================================================
6782// Typed Window Function types
6783// ============================================================================
6784
6785/// ROW_NUMBER function (no arguments)
6786#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6787#[cfg_attr(feature = "bindings", derive(TS))]
6788pub struct RowNumber;
6789
6790/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6792#[cfg_attr(feature = "bindings", derive(TS))]
6793pub struct Rank {
6794    /// DuckDB: RANK(ORDER BY col) - order by inside function
6795    #[serde(default, skip_serializing_if = "Option::is_none")]
6796    pub order_by: Option<Vec<Ordered>>,
6797    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6798    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6799    pub args: Vec<Expression>,
6800}
6801
6802/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
6803#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6804#[cfg_attr(feature = "bindings", derive(TS))]
6805pub struct DenseRank {
6806    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6807    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6808    pub args: Vec<Expression>,
6809}
6810
6811/// NTILE function (DuckDB allows ORDER BY inside)
6812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6813#[cfg_attr(feature = "bindings", derive(TS))]
6814pub struct NTileFunc {
6815    /// num_buckets is optional to support Databricks NTILE() without arguments
6816    #[serde(default, skip_serializing_if = "Option::is_none")]
6817    pub num_buckets: Option<Expression>,
6818    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
6819    #[serde(default, skip_serializing_if = "Option::is_none")]
6820    pub order_by: Option<Vec<Ordered>>,
6821}
6822
6823/// LEAD / LAG function
6824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6825#[cfg_attr(feature = "bindings", derive(TS))]
6826pub struct LeadLagFunc {
6827    pub this: Expression,
6828    pub offset: Option<Expression>,
6829    pub default: Option<Expression>,
6830    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6831    #[serde(default, skip_serializing_if = "Option::is_none")]
6832    pub ignore_nulls: Option<bool>,
6833}
6834
6835/// FIRST_VALUE / LAST_VALUE function
6836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6837#[cfg_attr(feature = "bindings", derive(TS))]
6838pub struct ValueFunc {
6839    pub this: Expression,
6840    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6841    #[serde(default, skip_serializing_if = "Option::is_none")]
6842    pub ignore_nulls: Option<bool>,
6843    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
6844    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6845    pub order_by: Vec<Ordered>,
6846}
6847
6848/// NTH_VALUE function
6849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6850#[cfg_attr(feature = "bindings", derive(TS))]
6851pub struct NthValueFunc {
6852    pub this: Expression,
6853    pub offset: Expression,
6854    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6855    #[serde(default, skip_serializing_if = "Option::is_none")]
6856    pub ignore_nulls: Option<bool>,
6857    /// Snowflake FROM FIRST / FROM LAST clause
6858    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
6859    #[serde(default, skip_serializing_if = "Option::is_none")]
6860    pub from_first: Option<bool>,
6861}
6862
6863/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6865#[cfg_attr(feature = "bindings", derive(TS))]
6866pub struct PercentRank {
6867    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
6868    #[serde(default, skip_serializing_if = "Option::is_none")]
6869    pub order_by: Option<Vec<Ordered>>,
6870    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6871    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6872    pub args: Vec<Expression>,
6873}
6874
6875/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6876#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6877#[cfg_attr(feature = "bindings", derive(TS))]
6878pub struct CumeDist {
6879    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
6880    #[serde(default, skip_serializing_if = "Option::is_none")]
6881    pub order_by: Option<Vec<Ordered>>,
6882    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6883    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6884    pub args: Vec<Expression>,
6885}
6886
6887// ============================================================================
6888// Additional String Function types
6889// ============================================================================
6890
6891/// POSITION/INSTR function
6892#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6893#[cfg_attr(feature = "bindings", derive(TS))]
6894pub struct PositionFunc {
6895    pub substring: Expression,
6896    pub string: Expression,
6897    pub start: Option<Expression>,
6898}
6899
6900// ============================================================================
6901// Additional Math Function types
6902// ============================================================================
6903
6904/// RANDOM function (no arguments)
6905#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6906#[cfg_attr(feature = "bindings", derive(TS))]
6907pub struct Random;
6908
6909/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
6910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6911#[cfg_attr(feature = "bindings", derive(TS))]
6912pub struct Rand {
6913    pub seed: Option<Box<Expression>>,
6914    /// Teradata RANDOM lower bound
6915    #[serde(default)]
6916    pub lower: Option<Box<Expression>>,
6917    /// Teradata RANDOM upper bound
6918    #[serde(default)]
6919    pub upper: Option<Box<Expression>>,
6920}
6921
6922/// TRUNCATE / TRUNC function
6923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6924#[cfg_attr(feature = "bindings", derive(TS))]
6925pub struct TruncateFunc {
6926    pub this: Expression,
6927    pub decimals: Option<Expression>,
6928}
6929
6930/// PI function (no arguments)
6931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6932#[cfg_attr(feature = "bindings", derive(TS))]
6933pub struct Pi;
6934
6935// ============================================================================
6936// Control Flow Function types
6937// ============================================================================
6938
6939/// DECODE function (Oracle style)
6940#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6941#[cfg_attr(feature = "bindings", derive(TS))]
6942pub struct DecodeFunc {
6943    pub this: Expression,
6944    pub search_results: Vec<(Expression, Expression)>,
6945    pub default: Option<Expression>,
6946}
6947
6948// ============================================================================
6949// Additional Date/Time Function types
6950// ============================================================================
6951
6952/// DATE_FORMAT / FORMAT_DATE function
6953#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6954#[cfg_attr(feature = "bindings", derive(TS))]
6955pub struct DateFormatFunc {
6956    pub this: Expression,
6957    pub format: Expression,
6958}
6959
6960/// FROM_UNIXTIME function
6961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6962#[cfg_attr(feature = "bindings", derive(TS))]
6963pub struct FromUnixtimeFunc {
6964    pub this: Expression,
6965    pub format: Option<Expression>,
6966}
6967
6968/// UNIX_TIMESTAMP function
6969#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6970#[cfg_attr(feature = "bindings", derive(TS))]
6971pub struct UnixTimestampFunc {
6972    pub this: Option<Expression>,
6973    pub format: Option<Expression>,
6974}
6975
6976/// MAKE_DATE function
6977#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6978#[cfg_attr(feature = "bindings", derive(TS))]
6979pub struct MakeDateFunc {
6980    pub year: Expression,
6981    pub month: Expression,
6982    pub day: Expression,
6983}
6984
6985/// MAKE_TIMESTAMP function
6986#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6987#[cfg_attr(feature = "bindings", derive(TS))]
6988pub struct MakeTimestampFunc {
6989    pub year: Expression,
6990    pub month: Expression,
6991    pub day: Expression,
6992    pub hour: Expression,
6993    pub minute: Expression,
6994    pub second: Expression,
6995    pub timezone: Option<Expression>,
6996}
6997
6998/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
6999#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7000#[cfg_attr(feature = "bindings", derive(TS))]
7001pub struct LastDayFunc {
7002    pub this: Expression,
7003    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
7004    #[serde(skip_serializing_if = "Option::is_none", default)]
7005    pub unit: Option<DateTimeField>,
7006}
7007
7008// ============================================================================
7009// Array Function types
7010// ============================================================================
7011
7012/// ARRAY constructor
7013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7014#[cfg_attr(feature = "bindings", derive(TS))]
7015pub struct ArrayConstructor {
7016    pub expressions: Vec<Expression>,
7017    pub bracket_notation: bool,
7018    /// True if LIST keyword was used instead of ARRAY (DuckDB)
7019    pub use_list_keyword: bool,
7020}
7021
7022/// ARRAY_SORT function
7023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7024#[cfg_attr(feature = "bindings", derive(TS))]
7025pub struct ArraySortFunc {
7026    pub this: Expression,
7027    pub comparator: Option<Expression>,
7028    pub desc: bool,
7029    pub nulls_first: Option<bool>,
7030}
7031
7032/// ARRAY_JOIN / ARRAY_TO_STRING function
7033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7034#[cfg_attr(feature = "bindings", derive(TS))]
7035pub struct ArrayJoinFunc {
7036    pub this: Expression,
7037    pub separator: Expression,
7038    pub null_replacement: Option<Expression>,
7039}
7040
7041/// UNNEST function
7042#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7043#[cfg_attr(feature = "bindings", derive(TS))]
7044pub struct UnnestFunc {
7045    pub this: Expression,
7046    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
7047    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7048    pub expressions: Vec<Expression>,
7049    pub with_ordinality: bool,
7050    pub alias: Option<Identifier>,
7051    /// BigQuery: offset alias for WITH OFFSET AS <name>
7052    #[serde(default, skip_serializing_if = "Option::is_none")]
7053    pub offset_alias: Option<Identifier>,
7054    /// Inferred type of the first UNNEST output column.
7055    #[serde(default, skip_serializing_if = "Option::is_none")]
7056    #[ast(skip)]
7057    pub inferred_type: Option<DataType>,
7058}
7059
7060/// ARRAY_FILTER function (with lambda)
7061#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7062#[cfg_attr(feature = "bindings", derive(TS))]
7063pub struct ArrayFilterFunc {
7064    pub this: Expression,
7065    pub filter: Expression,
7066}
7067
7068/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
7069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7070#[cfg_attr(feature = "bindings", derive(TS))]
7071pub struct ArrayTransformFunc {
7072    pub this: Expression,
7073    pub transform: Expression,
7074}
7075
7076/// SEQUENCE / GENERATE_SERIES function
7077#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7078#[cfg_attr(feature = "bindings", derive(TS))]
7079pub struct SequenceFunc {
7080    pub start: Expression,
7081    pub stop: Expression,
7082    pub step: Option<Expression>,
7083}
7084
7085// ============================================================================
7086// Struct Function types
7087// ============================================================================
7088
7089/// STRUCT constructor
7090#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7091#[cfg_attr(feature = "bindings", derive(TS))]
7092pub struct StructConstructor {
7093    pub fields: Vec<(Option<Identifier>, Expression)>,
7094}
7095
7096/// STRUCT_EXTRACT function
7097#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7098#[cfg_attr(feature = "bindings", derive(TS))]
7099pub struct StructExtractFunc {
7100    pub this: Expression,
7101    pub field: Identifier,
7102}
7103
7104/// NAMED_STRUCT function
7105#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7106#[cfg_attr(feature = "bindings", derive(TS))]
7107pub struct NamedStructFunc {
7108    pub pairs: Vec<(Expression, Expression)>,
7109}
7110
7111// ============================================================================
7112// Map Function types
7113// ============================================================================
7114
7115/// MAP constructor
7116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7117#[cfg_attr(feature = "bindings", derive(TS))]
7118pub struct MapConstructor {
7119    pub keys: Vec<Expression>,
7120    pub values: Vec<Expression>,
7121    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7122    #[serde(default)]
7123    pub curly_brace_syntax: bool,
7124    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7125    #[serde(default)]
7126    pub with_map_keyword: bool,
7127}
7128
7129/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7130#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7131#[cfg_attr(feature = "bindings", derive(TS))]
7132pub struct TransformFunc {
7133    pub this: Expression,
7134    pub transform: Expression,
7135}
7136
7137/// Function call with EMITS clause (Exasol)
7138/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7139#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7140#[cfg_attr(feature = "bindings", derive(TS))]
7141pub struct FunctionEmits {
7142    /// The function call expression
7143    pub this: Expression,
7144    /// The EMITS schema definition
7145    pub emits: Expression,
7146}
7147
7148// ============================================================================
7149// JSON Function types
7150// ============================================================================
7151
7152/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7153#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7154#[cfg_attr(feature = "bindings", derive(TS))]
7155pub struct JsonExtractFunc {
7156    pub this: Expression,
7157    pub path: Expression,
7158    pub returning: Option<DataType>,
7159    /// True if parsed from -> or ->> operator syntax
7160    #[serde(default)]
7161    pub arrow_syntax: bool,
7162    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7163    #[serde(default)]
7164    pub hash_arrow_syntax: bool,
7165    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7166    #[serde(default)]
7167    pub wrapper_option: Option<String>,
7168    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7169    #[serde(default)]
7170    pub quotes_option: Option<String>,
7171    /// ON SCALAR STRING flag
7172    #[serde(default)]
7173    pub on_scalar_string: bool,
7174    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7175    #[serde(default)]
7176    pub on_error: Option<String>,
7177}
7178
7179/// JSON path extraction
7180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7181#[cfg_attr(feature = "bindings", derive(TS))]
7182pub struct JsonPathFunc {
7183    pub this: Expression,
7184    pub paths: Vec<Expression>,
7185}
7186
7187/// JSON_OBJECT function
7188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7189#[cfg_attr(feature = "bindings", derive(TS))]
7190pub struct JsonObjectFunc {
7191    pub pairs: Vec<(Expression, Expression)>,
7192    pub null_handling: Option<JsonNullHandling>,
7193    #[serde(default)]
7194    pub with_unique_keys: bool,
7195    #[serde(default)]
7196    pub returning_type: Option<DataType>,
7197    #[serde(default)]
7198    pub format_json: bool,
7199    #[serde(default)]
7200    pub encoding: Option<String>,
7201    /// For JSON_OBJECT(*) syntax
7202    #[serde(default)]
7203    pub star: bool,
7204}
7205
7206/// JSON null handling options
7207#[derive(
7208    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7209)]
7210#[cfg_attr(feature = "bindings", derive(TS))]
7211pub enum JsonNullHandling {
7212    NullOnNull,
7213    AbsentOnNull,
7214}
7215
7216/// JSON_SET / JSON_INSERT function
7217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7218#[cfg_attr(feature = "bindings", derive(TS))]
7219pub struct JsonModifyFunc {
7220    pub this: Expression,
7221    pub path_values: Vec<(Expression, Expression)>,
7222}
7223
7224/// JSON_ARRAYAGG function
7225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7226#[cfg_attr(feature = "bindings", derive(TS))]
7227pub struct JsonArrayAggFunc {
7228    pub this: Expression,
7229    pub order_by: Option<Vec<Ordered>>,
7230    pub null_handling: Option<JsonNullHandling>,
7231    pub filter: Option<Expression>,
7232}
7233
7234/// JSON_OBJECTAGG function
7235#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7236#[cfg_attr(feature = "bindings", derive(TS))]
7237pub struct JsonObjectAggFunc {
7238    pub key: Expression,
7239    pub value: Expression,
7240    pub null_handling: Option<JsonNullHandling>,
7241    pub filter: Option<Expression>,
7242}
7243
7244// ============================================================================
7245// Type Casting Function types
7246// ============================================================================
7247
7248/// CONVERT function (SQL Server style)
7249#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7250#[cfg_attr(feature = "bindings", derive(TS))]
7251pub struct ConvertFunc {
7252    pub this: Expression,
7253    pub to: DataType,
7254    pub style: Option<Expression>,
7255}
7256
7257// ============================================================================
7258// Additional Expression types
7259// ============================================================================
7260
7261/// Lambda expression
7262#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7263#[cfg_attr(feature = "bindings", derive(TS))]
7264pub struct LambdaExpr {
7265    pub parameters: Vec<Identifier>,
7266    pub body: Expression,
7267    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7268    #[serde(default)]
7269    pub colon: bool,
7270    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7271    /// Maps parameter index to data type
7272    #[serde(default)]
7273    pub parameter_types: Vec<Option<DataType>>,
7274}
7275
7276/// Parameter (parameterized queries)
7277#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7278#[cfg_attr(feature = "bindings", derive(TS))]
7279pub struct Parameter {
7280    pub name: Option<String>,
7281    pub index: Option<u32>,
7282    pub style: ParameterStyle,
7283    /// Whether the name was quoted (e.g., @"x" vs @x)
7284    #[serde(default)]
7285    pub quoted: bool,
7286    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7287    #[serde(default)]
7288    pub string_quoted: bool,
7289    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7290    #[serde(default)]
7291    pub expression: Option<String>,
7292}
7293
7294/// Parameter placeholder styles
7295#[derive(
7296    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7297)]
7298#[cfg_attr(feature = "bindings", derive(TS))]
7299pub enum ParameterStyle {
7300    Question,     // ?
7301    Dollar,       // $1, $2
7302    DollarBrace,  // ${name} (Databricks, Hive template variables)
7303    Brace,        // {name} (Spark/Databricks widget/template variables)
7304    Colon,        // :name
7305    At,           // @name
7306    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7307    DoubleDollar, // $$name
7308    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7309}
7310
7311/// Placeholder expression
7312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7313#[cfg_attr(feature = "bindings", derive(TS))]
7314pub struct Placeholder {
7315    pub index: Option<u32>,
7316}
7317
7318/// Named argument in function call: name => value or name := value
7319#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7320#[cfg_attr(feature = "bindings", derive(TS))]
7321pub struct NamedArgument {
7322    pub name: Identifier,
7323    pub value: Expression,
7324    /// The separator used: `=>`, `:=`, or `=`
7325    pub separator: NamedArgSeparator,
7326}
7327
7328/// Separator style for named arguments
7329#[derive(
7330    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7331)]
7332#[cfg_attr(feature = "bindings", derive(TS))]
7333pub enum NamedArgSeparator {
7334    /// `=>` (standard SQL, Snowflake, BigQuery)
7335    DArrow,
7336    /// `:=` (Oracle, MySQL)
7337    ColonEq,
7338    /// `=` (simple equals, some dialects)
7339    Eq,
7340}
7341
7342/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7343/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7345#[cfg_attr(feature = "bindings", derive(TS))]
7346pub struct TableArgument {
7347    /// The keyword prefix: "TABLE" or "MODEL"
7348    pub prefix: String,
7349    /// The table/model reference expression
7350    pub this: Expression,
7351}
7352
7353/// SQL Comment preservation
7354#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7355#[cfg_attr(feature = "bindings", derive(TS))]
7356pub struct SqlComment {
7357    pub text: String,
7358    pub is_block: bool,
7359}
7360
7361// ============================================================================
7362// Additional Predicate types
7363// ============================================================================
7364
7365/// SIMILAR TO expression
7366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7367#[cfg_attr(feature = "bindings", derive(TS))]
7368pub struct SimilarToExpr {
7369    pub this: Expression,
7370    pub pattern: Expression,
7371    pub escape: Option<Expression>,
7372    pub not: bool,
7373}
7374
7375/// ANY / ALL quantified expression
7376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7377#[cfg_attr(feature = "bindings", derive(TS))]
7378pub struct QuantifiedExpr {
7379    pub this: Expression,
7380    pub subquery: Expression,
7381    pub op: Option<QuantifiedOp>,
7382}
7383
7384/// Comparison operator for quantified expressions
7385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7386#[cfg_attr(feature = "bindings", derive(TS))]
7387pub enum QuantifiedOp {
7388    Eq,
7389    Neq,
7390    Lt,
7391    Lte,
7392    Gt,
7393    Gte,
7394}
7395
7396/// OVERLAPS expression
7397/// Supports two forms:
7398/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7399/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7401#[cfg_attr(feature = "bindings", derive(TS))]
7402pub struct OverlapsExpr {
7403    /// Left operand for simple binary form
7404    #[serde(skip_serializing_if = "Option::is_none")]
7405    pub this: Option<Expression>,
7406    /// Right operand for simple binary form
7407    #[serde(skip_serializing_if = "Option::is_none")]
7408    pub expression: Option<Expression>,
7409    /// Left range start for full ANSI form
7410    #[serde(skip_serializing_if = "Option::is_none")]
7411    pub left_start: Option<Expression>,
7412    /// Left range end for full ANSI form
7413    #[serde(skip_serializing_if = "Option::is_none")]
7414    pub left_end: Option<Expression>,
7415    /// Right range start for full ANSI form
7416    #[serde(skip_serializing_if = "Option::is_none")]
7417    pub right_start: Option<Expression>,
7418    /// Right range end for full ANSI form
7419    #[serde(skip_serializing_if = "Option::is_none")]
7420    pub right_end: Option<Expression>,
7421}
7422
7423// ============================================================================
7424// Array/Struct/Map access
7425// ============================================================================
7426
7427/// Subscript access (array[index] or map[key])
7428#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7429#[cfg_attr(feature = "bindings", derive(TS))]
7430pub struct Subscript {
7431    pub this: Expression,
7432    pub index: Expression,
7433}
7434
7435/// Dot access (struct.field)
7436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7437#[cfg_attr(feature = "bindings", derive(TS))]
7438pub struct DotAccess {
7439    pub this: Expression,
7440    pub field: Identifier,
7441}
7442
7443/// Method call (expr.method(args))
7444#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7445#[cfg_attr(feature = "bindings", derive(TS))]
7446pub struct MethodCall {
7447    pub this: Expression,
7448    pub method: Identifier,
7449    pub args: Vec<Expression>,
7450}
7451
7452/// Array slice (array[start:end])
7453#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7454#[cfg_attr(feature = "bindings", derive(TS))]
7455pub struct ArraySlice {
7456    pub this: Expression,
7457    pub start: Option<Expression>,
7458    pub end: Option<Expression>,
7459}
7460
7461// ============================================================================
7462// DDL (Data Definition Language) Statements
7463// ============================================================================
7464
7465/// ON COMMIT behavior for temporary tables
7466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7467#[cfg_attr(feature = "bindings", derive(TS))]
7468pub enum OnCommit {
7469    /// ON COMMIT PRESERVE ROWS
7470    PreserveRows,
7471    /// ON COMMIT DELETE ROWS
7472    DeleteRows,
7473}
7474
7475/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
7476#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7477#[cfg_attr(feature = "bindings", derive(TS))]
7478pub struct TiDBAutoRandom {
7479    #[serde(default, skip_serializing_if = "Option::is_none")]
7480    pub shard_bits: Option<u64>,
7481    #[serde(default, skip_serializing_if = "Option::is_none")]
7482    pub range_bits: Option<u64>,
7483    /// Whether the attribute was wrapped in a TiDB executable comment.
7484    #[serde(default)]
7485    pub executable_comment: bool,
7486}
7487
7488/// A TiDB-specific table option and its source syntax.
7489#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7490#[cfg_attr(feature = "bindings", derive(TS))]
7491pub struct TiDBTableOption {
7492    pub kind: TiDBTableOptionKind,
7493    /// Whether the option was wrapped in a TiDB executable comment.
7494    #[serde(default)]
7495    pub executable_comment: bool,
7496}
7497
7498/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
7499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7500#[cfg_attr(feature = "bindings", derive(TS))]
7501#[serde(tag = "type", rename_all = "snake_case")]
7502pub enum TiDBTableOptionKind {
7503    ShardRowIdBits {
7504        bits: u64,
7505    },
7506    PreSplitRegions {
7507        regions: u64,
7508    },
7509    AutoRandomBase {
7510        value: u64,
7511    },
7512    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
7513    PlacementPolicy {
7514        policy: Option<Identifier>,
7515    },
7516    Ttl {
7517        column: Identifier,
7518        interval: Interval,
7519        #[serde(default, skip_serializing_if = "Option::is_none")]
7520        enabled: Option<bool>,
7521    },
7522    TtlEnable {
7523        enabled: bool,
7524    },
7525    TtlJobInterval {
7526        interval: String,
7527    },
7528}
7529
7530/// CREATE TABLE statement
7531#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7532#[cfg_attr(feature = "bindings", derive(TS))]
7533pub struct CreateTable {
7534    pub name: TableRef,
7535    /// ClickHouse: ON CLUSTER clause for distributed DDL
7536    #[serde(default, skip_serializing_if = "Option::is_none")]
7537    pub on_cluster: Option<OnCluster>,
7538    pub columns: Vec<ColumnDef>,
7539    pub constraints: Vec<TableConstraint>,
7540    pub if_not_exists: bool,
7541    pub temporary: bool,
7542    pub or_replace: bool,
7543    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
7544    #[serde(default, skip_serializing_if = "Option::is_none")]
7545    pub table_modifier: Option<String>,
7546    pub as_select: Option<Expression>,
7547    /// Whether the AS SELECT was wrapped in parentheses
7548    #[serde(default)]
7549    pub as_select_parenthesized: bool,
7550    /// ON COMMIT behavior for temporary tables
7551    #[serde(default)]
7552    pub on_commit: Option<OnCommit>,
7553    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
7554    #[serde(default)]
7555    pub clone_source: Option<TableRef>,
7556    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
7557    #[serde(default, skip_serializing_if = "Option::is_none")]
7558    pub clone_at_clause: Option<Expression>,
7559    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
7560    #[serde(default)]
7561    pub is_copy: bool,
7562    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
7563    #[serde(default)]
7564    pub shallow_clone: bool,
7565    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
7566    #[serde(default)]
7567    pub deep_clone: bool,
7568    /// Leading comments before the statement
7569    #[serde(default)]
7570    pub leading_comments: Vec<String>,
7571    /// WITH properties (e.g., WITH (FORMAT='parquet'))
7572    #[serde(default)]
7573    pub with_properties: Vec<(String, String)>,
7574    /// Teradata: table options after name before columns (comma-separated)
7575    #[serde(default)]
7576    pub teradata_post_name_options: Vec<String>,
7577    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
7578    #[serde(default)]
7579    pub with_data: Option<bool>,
7580    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
7581    #[serde(default)]
7582    pub with_statistics: Option<bool>,
7583    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
7584    #[serde(default)]
7585    pub teradata_indexes: Vec<TeradataIndex>,
7586    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
7587    #[serde(default)]
7588    pub with_cte: Option<With>,
7589    /// Table properties like DEFAULT COLLATE (BigQuery)
7590    #[serde(default)]
7591    pub properties: Vec<Expression>,
7592    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
7593    #[serde(default, skip_serializing_if = "Option::is_none")]
7594    pub partition_of: Option<Expression>,
7595    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
7596    #[serde(default)]
7597    pub post_table_properties: Vec<Expression>,
7598    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
7599    #[serde(default)]
7600    pub mysql_table_options: Vec<(String, String)>,
7601    /// TiDB-specific table options after column definitions.
7602    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7603    pub tidb_table_options: Vec<TiDBTableOption>,
7604    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
7605    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7606    pub inherits: Vec<TableRef>,
7607    /// TSQL ON filegroup or ON filegroup (partition_column) clause
7608    #[serde(default, skip_serializing_if = "Option::is_none")]
7609    pub on_property: Option<OnProperty>,
7610    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
7611    #[serde(default)]
7612    pub copy_grants: bool,
7613    /// Snowflake: USING TEMPLATE expression for schema inference
7614    #[serde(default, skip_serializing_if = "Option::is_none")]
7615    pub using_template: Option<Box<Expression>>,
7616    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
7617    #[serde(default, skip_serializing_if = "Option::is_none")]
7618    pub rollup: Option<RollupProperty>,
7619    /// ClickHouse: UUID 'xxx' clause after table name
7620    #[serde(default, skip_serializing_if = "Option::is_none")]
7621    pub uuid: Option<String>,
7622    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
7623    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
7624    /// could appear in other engines.
7625    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7626    pub with_partition_columns: Vec<ColumnDef>,
7627    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
7628    /// for external tables that reference a Cloud Resource connection.
7629    #[serde(default, skip_serializing_if = "Option::is_none")]
7630    pub with_connection: Option<TableRef>,
7631}
7632
7633/// Teradata index specification for CREATE TABLE
7634#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7635#[cfg_attr(feature = "bindings", derive(TS))]
7636pub struct TeradataIndex {
7637    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
7638    pub kind: TeradataIndexKind,
7639    /// Optional index name
7640    pub name: Option<String>,
7641    /// Optional column list
7642    pub columns: Vec<String>,
7643}
7644
7645/// Kind of Teradata index
7646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7647#[cfg_attr(feature = "bindings", derive(TS))]
7648pub enum TeradataIndexKind {
7649    /// NO PRIMARY INDEX
7650    NoPrimary,
7651    /// PRIMARY INDEX
7652    Primary,
7653    /// PRIMARY AMP INDEX
7654    PrimaryAmp,
7655    /// UNIQUE INDEX
7656    Unique,
7657    /// UNIQUE PRIMARY INDEX
7658    UniquePrimary,
7659    /// INDEX (secondary, non-primary)
7660    Secondary,
7661}
7662
7663impl CreateTable {
7664    pub fn new(name: impl Into<String>) -> Self {
7665        Self {
7666            name: TableRef::new(name),
7667            on_cluster: None,
7668            columns: Vec::new(),
7669            constraints: Vec::new(),
7670            if_not_exists: false,
7671            temporary: false,
7672            or_replace: false,
7673            table_modifier: None,
7674            as_select: None,
7675            as_select_parenthesized: false,
7676            on_commit: None,
7677            clone_source: None,
7678            clone_at_clause: None,
7679            shallow_clone: false,
7680            deep_clone: false,
7681            is_copy: false,
7682            leading_comments: Vec::new(),
7683            with_properties: Vec::new(),
7684            teradata_post_name_options: Vec::new(),
7685            with_data: None,
7686            with_statistics: None,
7687            teradata_indexes: Vec::new(),
7688            with_cte: None,
7689            properties: Vec::new(),
7690            partition_of: None,
7691            post_table_properties: Vec::new(),
7692            mysql_table_options: Vec::new(),
7693            tidb_table_options: Vec::new(),
7694            inherits: Vec::new(),
7695            on_property: None,
7696            copy_grants: false,
7697            using_template: None,
7698            rollup: None,
7699            uuid: None,
7700            with_partition_columns: Vec::new(),
7701            with_connection: None,
7702        }
7703    }
7704}
7705
7706/// Sort order for PRIMARY KEY ASC/DESC
7707#[derive(
7708    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
7709)]
7710#[cfg_attr(feature = "bindings", derive(TS))]
7711pub enum SortOrder {
7712    Asc,
7713    Desc,
7714}
7715
7716/// Type of column constraint for tracking order
7717#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7718#[cfg_attr(feature = "bindings", derive(TS))]
7719pub enum ConstraintType {
7720    NotNull,
7721    Null,
7722    PrimaryKey,
7723    Unique,
7724    Default,
7725    AutoIncrement,
7726    AutoRandom,
7727    Collate,
7728    Comment,
7729    References,
7730    Check,
7731    GeneratedAsIdentity,
7732    /// Snowflake: TAG (key='value', ...)
7733    Tags,
7734    /// Computed/generated column
7735    ComputedColumn,
7736    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
7737    GeneratedAsRow,
7738    /// MySQL: ON UPDATE expression
7739    OnUpdate,
7740    /// PATH constraint for XMLTABLE/JSON_TABLE columns
7741    Path,
7742    /// Redshift: ENCODE encoding_type
7743    Encode,
7744}
7745
7746/// Column definition in CREATE TABLE
7747#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7748#[cfg_attr(feature = "bindings", derive(TS))]
7749pub struct ColumnDef {
7750    pub name: Identifier,
7751    pub data_type: DataType,
7752    pub nullable: Option<bool>,
7753    pub default: Option<Expression>,
7754    pub primary_key: bool,
7755    /// Sort order for PRIMARY KEY (ASC/DESC)
7756    #[serde(default)]
7757    pub primary_key_order: Option<SortOrder>,
7758    pub unique: bool,
7759    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
7760    #[serde(default)]
7761    pub unique_nulls_not_distinct: bool,
7762    pub auto_increment: bool,
7763    /// TiDB distributed primary-key allocation attribute.
7764    #[serde(default, skip_serializing_if = "Option::is_none")]
7765    pub auto_random: Option<TiDBAutoRandom>,
7766    pub comment: Option<String>,
7767    pub constraints: Vec<ColumnConstraint>,
7768    /// Track original order of constraints for accurate regeneration
7769    #[serde(default)]
7770    pub constraint_order: Vec<ConstraintType>,
7771    /// Teradata: FORMAT 'pattern'
7772    #[serde(default)]
7773    pub format: Option<String>,
7774    /// Teradata: TITLE 'title'
7775    #[serde(default)]
7776    pub title: Option<String>,
7777    /// Teradata: INLINE LENGTH n
7778    #[serde(default)]
7779    pub inline_length: Option<u64>,
7780    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
7781    #[serde(default)]
7782    pub compress: Option<Vec<Expression>>,
7783    /// Teradata: CHARACTER SET name
7784    #[serde(default)]
7785    pub character_set: Option<String>,
7786    /// Teradata: UPPERCASE
7787    #[serde(default)]
7788    pub uppercase: bool,
7789    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
7790    #[serde(default)]
7791    pub casespecific: Option<bool>,
7792    /// Snowflake: AUTOINCREMENT START value
7793    #[serde(default)]
7794    pub auto_increment_start: Option<Box<Expression>>,
7795    /// Snowflake: AUTOINCREMENT INCREMENT value
7796    #[serde(default)]
7797    pub auto_increment_increment: Option<Box<Expression>>,
7798    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
7799    #[serde(default)]
7800    pub auto_increment_order: Option<bool>,
7801    /// MySQL: UNSIGNED modifier
7802    #[serde(default)]
7803    pub unsigned: bool,
7804    /// MySQL: ZEROFILL modifier
7805    #[serde(default)]
7806    pub zerofill: bool,
7807    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
7808    #[serde(default, skip_serializing_if = "Option::is_none")]
7809    pub on_update: Option<Expression>,
7810    /// MySQL: column VISIBLE/INVISIBLE modifier.
7811    #[serde(default, skip_serializing_if = "Option::is_none")]
7812    pub visible: Option<bool>,
7813    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
7814    #[serde(default, skip_serializing_if = "Option::is_none")]
7815    pub unique_constraint_name: Option<String>,
7816    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
7817    #[serde(default, skip_serializing_if = "Option::is_none")]
7818    pub not_null_constraint_name: Option<String>,
7819    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
7820    #[serde(default, skip_serializing_if = "Option::is_none")]
7821    pub primary_key_constraint_name: Option<String>,
7822    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
7823    #[serde(default, skip_serializing_if = "Option::is_none")]
7824    pub check_constraint_name: Option<String>,
7825    /// BigQuery: OPTIONS (key=value, ...) on column
7826    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7827    pub options: Vec<Expression>,
7828    /// SQLite: Column definition without explicit type
7829    #[serde(default)]
7830    pub no_type: bool,
7831    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
7832    #[serde(default, skip_serializing_if = "Option::is_none")]
7833    pub encoding: Option<String>,
7834    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
7835    #[serde(default, skip_serializing_if = "Option::is_none")]
7836    pub codec: Option<String>,
7837    /// ClickHouse: EPHEMERAL [expr] modifier
7838    #[serde(default, skip_serializing_if = "Option::is_none")]
7839    pub ephemeral: Option<Option<Box<Expression>>>,
7840    /// ClickHouse: MATERIALIZED expr modifier
7841    #[serde(default, skip_serializing_if = "Option::is_none")]
7842    pub materialized_expr: Option<Box<Expression>>,
7843    /// ClickHouse: ALIAS expr modifier
7844    #[serde(default, skip_serializing_if = "Option::is_none")]
7845    pub alias_expr: Option<Box<Expression>>,
7846    /// ClickHouse: TTL expr modifier on columns
7847    #[serde(default, skip_serializing_if = "Option::is_none")]
7848    pub ttl_expr: Option<Box<Expression>>,
7849    /// TSQL: NOT FOR REPLICATION
7850    #[serde(default)]
7851    pub not_for_replication: bool,
7852}
7853
7854impl ColumnDef {
7855    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
7856        Self {
7857            name: Identifier::new(name),
7858            data_type,
7859            nullable: None,
7860            default: None,
7861            primary_key: false,
7862            primary_key_order: None,
7863            unique: false,
7864            unique_nulls_not_distinct: false,
7865            auto_increment: false,
7866            auto_random: None,
7867            comment: None,
7868            constraints: Vec::new(),
7869            constraint_order: Vec::new(),
7870            format: None,
7871            title: None,
7872            inline_length: None,
7873            compress: None,
7874            character_set: None,
7875            uppercase: false,
7876            casespecific: None,
7877            auto_increment_start: None,
7878            auto_increment_increment: None,
7879            auto_increment_order: None,
7880            unsigned: false,
7881            zerofill: false,
7882            on_update: None,
7883            visible: None,
7884            unique_constraint_name: None,
7885            not_null_constraint_name: None,
7886            primary_key_constraint_name: None,
7887            check_constraint_name: None,
7888            options: Vec::new(),
7889            no_type: false,
7890            encoding: None,
7891            codec: None,
7892            ephemeral: None,
7893            materialized_expr: None,
7894            alias_expr: None,
7895            ttl_expr: None,
7896            not_for_replication: false,
7897        }
7898    }
7899}
7900
7901/// Column-level constraint
7902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7903#[cfg_attr(feature = "bindings", derive(TS))]
7904pub enum ColumnConstraint {
7905    NotNull,
7906    Null,
7907    Unique,
7908    PrimaryKey,
7909    Default(Expression),
7910    Check(Expression),
7911    References(ForeignKeyRef),
7912    GeneratedAsIdentity(GeneratedAsIdentity),
7913    Collate(Identifier),
7914    Comment(String),
7915    /// Snowflake: TAG (key='value', ...)
7916    Tags(Tags),
7917    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
7918    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
7919    ComputedColumn(ComputedColumn),
7920    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7921    GeneratedAsRow(GeneratedAsRow),
7922    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
7923    Path(Expression),
7924}
7925
7926/// Computed/generated column constraint
7927#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7928#[cfg_attr(feature = "bindings", derive(TS))]
7929pub struct ComputedColumn {
7930    /// The expression that computes the column value
7931    pub expression: Box<Expression>,
7932    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
7933    #[serde(default)]
7934    pub persisted: bool,
7935    /// NOT NULL (TSQL computed columns)
7936    #[serde(default)]
7937    pub not_null: bool,
7938    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
7939    /// When None, defaults to dialect-appropriate output
7940    #[serde(default)]
7941    pub persistence_kind: Option<String>,
7942    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
7943    #[serde(default, skip_serializing_if = "Option::is_none")]
7944    pub data_type: Option<DataType>,
7945}
7946
7947/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7948#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7949#[cfg_attr(feature = "bindings", derive(TS))]
7950pub struct GeneratedAsRow {
7951    /// true = ROW START, false = ROW END
7952    pub start: bool,
7953    /// HIDDEN modifier
7954    #[serde(default)]
7955    pub hidden: bool,
7956}
7957
7958/// Generated identity column constraint
7959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7960#[cfg_attr(feature = "bindings", derive(TS))]
7961pub struct GeneratedAsIdentity {
7962    /// True for ALWAYS, False for BY DEFAULT
7963    pub always: bool,
7964    /// ON NULL (only valid with BY DEFAULT)
7965    pub on_null: bool,
7966    /// START WITH value
7967    pub start: Option<Box<Expression>>,
7968    /// INCREMENT BY value
7969    pub increment: Option<Box<Expression>>,
7970    /// MINVALUE
7971    pub minvalue: Option<Box<Expression>>,
7972    /// MAXVALUE
7973    pub maxvalue: Option<Box<Expression>>,
7974    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
7975    pub cycle: Option<bool>,
7976}
7977
7978/// Constraint modifiers (shared between table-level constraints)
7979#[derive(
7980    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
7981)]
7982#[cfg_attr(feature = "bindings", derive(TS))]
7983pub struct ConstraintModifiers {
7984    /// ENFORCED / NOT ENFORCED
7985    pub enforced: Option<bool>,
7986    /// DEFERRABLE / NOT DEFERRABLE
7987    pub deferrable: Option<bool>,
7988    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
7989    pub initially_deferred: Option<bool>,
7990    /// NORELY (Oracle)
7991    pub norely: bool,
7992    /// RELY (Oracle)
7993    pub rely: bool,
7994    /// USING index type (MySQL): BTREE or HASH
7995    #[serde(default)]
7996    pub using: Option<String>,
7997    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
7998    #[serde(default)]
7999    pub using_before_columns: bool,
8000    /// MySQL index COMMENT 'text'
8001    #[serde(default, skip_serializing_if = "Option::is_none")]
8002    pub comment: Option<String>,
8003    /// MySQL index VISIBLE/INVISIBLE
8004    #[serde(default, skip_serializing_if = "Option::is_none")]
8005    pub visible: Option<bool>,
8006    /// MySQL ENGINE_ATTRIBUTE = 'value'
8007    #[serde(default, skip_serializing_if = "Option::is_none")]
8008    pub engine_attribute: Option<String>,
8009    /// MySQL WITH PARSER name
8010    #[serde(default, skip_serializing_if = "Option::is_none")]
8011    pub with_parser: Option<String>,
8012    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
8013    #[serde(default)]
8014    pub not_valid: bool,
8015    /// TSQL CLUSTERED/NONCLUSTERED modifier
8016    #[serde(default, skip_serializing_if = "Option::is_none")]
8017    pub clustered: Option<String>,
8018    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
8019    #[serde(default, skip_serializing_if = "Option::is_none")]
8020    pub on_conflict: Option<String>,
8021    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
8022    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8023    pub with_options: Vec<(String, String)>,
8024    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
8025    #[serde(default, skip_serializing_if = "Option::is_none")]
8026    pub on_filegroup: Option<Identifier>,
8027}
8028
8029/// Table-level constraint
8030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8031#[cfg_attr(feature = "bindings", derive(TS))]
8032pub enum TableConstraint {
8033    PrimaryKey {
8034        name: Option<Identifier>,
8035        columns: Vec<Identifier>,
8036        /// Databricks primary-key columns marked with the TIMESERIES attribute.
8037        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8038        timeseries_columns: Vec<Identifier>,
8039        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
8040        #[serde(default)]
8041        include_columns: Vec<Identifier>,
8042        #[serde(default)]
8043        modifiers: ConstraintModifiers,
8044        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
8045        #[serde(default)]
8046        has_constraint_keyword: bool,
8047    },
8048    Unique {
8049        name: Option<Identifier>,
8050        columns: Vec<Identifier>,
8051        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
8052        #[serde(default)]
8053        columns_parenthesized: bool,
8054        #[serde(default)]
8055        modifiers: ConstraintModifiers,
8056        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
8057        #[serde(default)]
8058        has_constraint_keyword: bool,
8059        /// PostgreSQL 15+: NULLS NOT DISTINCT
8060        #[serde(default)]
8061        nulls_not_distinct: bool,
8062    },
8063    ForeignKey {
8064        name: Option<Identifier>,
8065        columns: Vec<Identifier>,
8066        #[serde(default)]
8067        references: Option<ForeignKeyRef>,
8068        /// ON DELETE action when REFERENCES is absent
8069        #[serde(default)]
8070        on_delete: Option<ReferentialAction>,
8071        /// ON UPDATE action when REFERENCES is absent
8072        #[serde(default)]
8073        on_update: Option<ReferentialAction>,
8074        #[serde(default)]
8075        modifiers: ConstraintModifiers,
8076    },
8077    Check {
8078        name: Option<Identifier>,
8079        expression: Expression,
8080        #[serde(default)]
8081        modifiers: ConstraintModifiers,
8082    },
8083    /// ClickHouse ASSUME constraint (query optimization assumption)
8084    Assume {
8085        name: Option<Identifier>,
8086        expression: Expression,
8087    },
8088    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
8089    Default {
8090        name: Option<Identifier>,
8091        expression: Expression,
8092        column: Identifier,
8093    },
8094    /// INDEX / KEY constraint (MySQL)
8095    Index {
8096        name: Option<Identifier>,
8097        columns: Vec<Identifier>,
8098        /// Expression-capable index key parts. This is used when an index contains
8099        /// functional key parts that cannot be represented by `columns`.
8100        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8101        key_parts: Vec<IndexKeyPart>,
8102        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8103        #[serde(default)]
8104        kind: Option<String>,
8105        #[serde(default)]
8106        modifiers: ConstraintModifiers,
8107        /// True if KEY keyword was used instead of INDEX
8108        #[serde(default)]
8109        use_key_keyword: bool,
8110        /// ClickHouse: indexed expression (instead of columns)
8111        #[serde(default, skip_serializing_if = "Option::is_none")]
8112        expression: Option<Box<Expression>>,
8113        /// ClickHouse: TYPE type_func(args)
8114        #[serde(default, skip_serializing_if = "Option::is_none")]
8115        index_type: Option<Box<Expression>>,
8116        /// ClickHouse: GRANULARITY n
8117        #[serde(default, skip_serializing_if = "Option::is_none")]
8118        granularity: Option<Box<Expression>>,
8119    },
8120    /// ClickHouse PROJECTION definition
8121    Projection {
8122        name: Identifier,
8123        expression: Expression,
8124    },
8125    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8126    Like {
8127        source: TableRef,
8128        /// Options as (INCLUDING|EXCLUDING, property) pairs
8129        options: Vec<(LikeOptionAction, String)>,
8130    },
8131    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8132    PeriodForSystemTime {
8133        start_col: Identifier,
8134        end_col: Identifier,
8135    },
8136    /// PostgreSQL EXCLUDE constraint
8137    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8138    Exclude {
8139        name: Option<Identifier>,
8140        /// Index access method (gist, btree, etc.)
8141        #[serde(default)]
8142        using: Option<String>,
8143        /// Elements: (expression, operator) pairs
8144        elements: Vec<ExcludeElement>,
8145        /// INCLUDE columns
8146        #[serde(default)]
8147        include_columns: Vec<Identifier>,
8148        /// WHERE predicate
8149        #[serde(default)]
8150        where_clause: Option<Box<Expression>>,
8151        /// WITH (storage_parameters)
8152        #[serde(default)]
8153        with_params: Vec<(String, String)>,
8154        /// USING INDEX TABLESPACE tablespace_name
8155        #[serde(default)]
8156        using_index_tablespace: Option<String>,
8157        #[serde(default)]
8158        modifiers: ConstraintModifiers,
8159    },
8160    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8161    Tags(Tags),
8162    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8163    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8164    /// for all deferrable constraints in the table
8165    InitiallyDeferred {
8166        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8167        deferred: bool,
8168    },
8169}
8170
8171/// Element in an EXCLUDE constraint: expression WITH operator
8172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8173#[cfg_attr(feature = "bindings", derive(TS))]
8174pub struct ExcludeElement {
8175    /// The column expression (may include operator class, ordering, nulls)
8176    pub expression: String,
8177    /// The operator (e.g., &&, =)
8178    pub operator: String,
8179}
8180
8181/// Action for LIKE clause options
8182#[derive(
8183    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8184)]
8185#[cfg_attr(feature = "bindings", derive(TS))]
8186pub enum LikeOptionAction {
8187    Including,
8188    Excluding,
8189}
8190
8191/// MATCH type for foreign keys
8192#[derive(
8193    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8194)]
8195#[cfg_attr(feature = "bindings", derive(TS))]
8196pub enum MatchType {
8197    Full,
8198    Partial,
8199    Simple,
8200}
8201
8202/// Foreign key reference
8203#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8204#[cfg_attr(feature = "bindings", derive(TS))]
8205pub struct ForeignKeyRef {
8206    pub table: TableRef,
8207    pub columns: Vec<Identifier>,
8208    pub on_delete: Option<ReferentialAction>,
8209    pub on_update: Option<ReferentialAction>,
8210    /// True if ON UPDATE appears before ON DELETE in the original SQL
8211    #[serde(default)]
8212    pub on_update_first: bool,
8213    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8214    #[serde(default)]
8215    pub match_type: Option<MatchType>,
8216    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8217    #[serde(default)]
8218    pub match_after_actions: bool,
8219    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8220    #[serde(default)]
8221    pub constraint_name: Option<String>,
8222    /// DEFERRABLE / NOT DEFERRABLE
8223    #[serde(default)]
8224    pub deferrable: Option<bool>,
8225    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8226    #[serde(default)]
8227    pub has_foreign_key_keywords: bool,
8228}
8229
8230/// Referential action for foreign keys
8231#[derive(
8232    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8233)]
8234#[cfg_attr(feature = "bindings", derive(TS))]
8235pub enum ReferentialAction {
8236    Cascade,
8237    SetNull,
8238    SetDefault,
8239    Restrict,
8240    NoAction,
8241}
8242
8243/// DROP TABLE statement
8244#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8245#[cfg_attr(feature = "bindings", derive(TS))]
8246pub struct DropTable {
8247    pub names: Vec<TableRef>,
8248    pub if_exists: bool,
8249    pub cascade: bool,
8250    /// Oracle: CASCADE CONSTRAINTS
8251    #[serde(default)]
8252    pub cascade_constraints: bool,
8253    /// Oracle: PURGE
8254    #[serde(default)]
8255    pub purge: bool,
8256    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8257    #[serde(default)]
8258    pub leading_comments: Vec<String>,
8259    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8260    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8261    #[serde(default, skip_serializing_if = "Option::is_none")]
8262    pub object_id_args: Option<String>,
8263    /// ClickHouse: SYNC modifier
8264    #[serde(default)]
8265    pub sync: bool,
8266    /// Snowflake: DROP ICEBERG TABLE
8267    #[serde(default)]
8268    pub iceberg: bool,
8269    /// RESTRICT modifier (opposite of CASCADE)
8270    #[serde(default)]
8271    pub restrict: bool,
8272}
8273
8274impl DropTable {
8275    pub fn new(name: impl Into<String>) -> Self {
8276        Self {
8277            names: vec![TableRef::new(name)],
8278            if_exists: false,
8279            cascade: false,
8280            cascade_constraints: false,
8281            purge: false,
8282            leading_comments: Vec::new(),
8283            object_id_args: None,
8284            sync: false,
8285            iceberg: false,
8286            restrict: false,
8287        }
8288    }
8289}
8290
8291/// UNDROP object statement (Snowflake, ClickHouse)
8292#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8293#[cfg_attr(feature = "bindings", derive(TS))]
8294pub struct Undrop {
8295    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8296    pub kind: String,
8297    /// The object name
8298    pub name: TableRef,
8299    /// IF EXISTS clause
8300    #[serde(default)]
8301    pub if_exists: bool,
8302    /// Snowflake: optional RENAME TO target
8303    #[serde(default, skip_serializing_if = "Option::is_none")]
8304    pub rename_to: Option<TableRef>,
8305}
8306
8307/// Partition scope for a TiDB `SPLIT TABLE` statement.
8308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8309#[cfg_attr(feature = "bindings", derive(TS))]
8310#[serde(tag = "type", rename_all = "snake_case")]
8311pub enum SplitTablePartitionScope {
8312    Table,
8313    AllPartitions,
8314    Partitions { names: Vec<Identifier> },
8315}
8316
8317/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8318#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8319#[cfg_attr(feature = "bindings", derive(TS))]
8320#[serde(tag = "type", rename_all = "snake_case")]
8321pub enum SplitTableMode {
8322    Between {
8323        lower: Vec<Expression>,
8324        upper: Vec<Expression>,
8325        regions: u64,
8326    },
8327    By {
8328        points: Vec<Vec<Expression>>,
8329    },
8330}
8331
8332/// TiDB `SPLIT [PARTITION] TABLE` statement.
8333#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8334#[cfg_attr(feature = "bindings", derive(TS))]
8335pub struct SplitTable {
8336    pub table: TableRef,
8337    pub partition_scope: SplitTablePartitionScope,
8338    #[serde(default, skip_serializing_if = "Option::is_none")]
8339    pub index: Option<Identifier>,
8340    pub mode: SplitTableMode,
8341}
8342
8343/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
8344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8345#[cfg_attr(feature = "bindings", derive(TS))]
8346pub struct FlashbackTable {
8347    pub table: TableRef,
8348    #[serde(default, skip_serializing_if = "Option::is_none")]
8349    pub rename_to: Option<Identifier>,
8350}
8351
8352/// ALTER TABLE statement
8353#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8354#[cfg_attr(feature = "bindings", derive(TS))]
8355pub struct AlterTable {
8356    pub name: TableRef,
8357    pub actions: Vec<AlterTableAction>,
8358    /// IF EXISTS clause
8359    #[serde(default)]
8360    pub if_exists: bool,
8361    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8362    #[serde(default, skip_serializing_if = "Option::is_none")]
8363    pub algorithm: Option<String>,
8364    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8365    #[serde(default, skip_serializing_if = "Option::is_none")]
8366    pub lock: Option<String>,
8367    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8368    #[serde(default, skip_serializing_if = "Option::is_none")]
8369    pub with_check: Option<String>,
8370    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8371    #[serde(default, skip_serializing_if = "Option::is_none")]
8372    pub partition: Option<Vec<(Identifier, Expression)>>,
8373    /// ClickHouse: ON CLUSTER clause for distributed DDL
8374    #[serde(default, skip_serializing_if = "Option::is_none")]
8375    pub on_cluster: Option<OnCluster>,
8376    /// Snowflake: ALTER ICEBERG TABLE
8377    #[serde(default, skip_serializing_if = "Option::is_none")]
8378    pub table_modifier: Option<String>,
8379}
8380
8381impl AlterTable {
8382    pub fn new(name: impl Into<String>) -> Self {
8383        Self {
8384            name: TableRef::new(name),
8385            actions: Vec::new(),
8386            if_exists: false,
8387            algorithm: None,
8388            lock: None,
8389            with_check: None,
8390            partition: None,
8391            on_cluster: None,
8392            table_modifier: None,
8393        }
8394    }
8395}
8396
8397/// Column position for ADD COLUMN (MySQL/MariaDB)
8398#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8399#[cfg_attr(feature = "bindings", derive(TS))]
8400pub enum ColumnPosition {
8401    First,
8402    After(Identifier),
8403}
8404
8405/// Actions for ALTER TABLE
8406#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8407#[cfg_attr(feature = "bindings", derive(TS))]
8408pub enum AlterTableAction {
8409    AddColumn {
8410        column: ColumnDef,
8411        if_not_exists: bool,
8412        position: Option<ColumnPosition>,
8413    },
8414    DropColumn {
8415        name: Identifier,
8416        if_exists: bool,
8417        cascade: bool,
8418    },
8419    RenameColumn {
8420        old_name: Identifier,
8421        new_name: Identifier,
8422        if_exists: bool,
8423    },
8424    AlterColumn {
8425        name: Identifier,
8426        action: AlterColumnAction,
8427        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8428        #[serde(default)]
8429        use_modify_keyword: bool,
8430    },
8431    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
8432    ModifyColumn {
8433        column: ColumnDef,
8434        if_exists: bool,
8435        position: Option<ColumnPosition>,
8436    },
8437    RenameTable(TableRef),
8438    AddConstraint(TableConstraint),
8439    DropConstraint {
8440        name: Identifier,
8441        if_exists: bool,
8442    },
8443    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8444    DropForeignKey {
8445        name: Identifier,
8446    },
8447    /// DROP PARTITION action (Hive/BigQuery)
8448    DropPartition {
8449        /// List of partitions to drop (each partition is a list of key=value pairs)
8450        partitions: Vec<Vec<(Identifier, Expression)>>,
8451        if_exists: bool,
8452    },
8453    /// ADD PARTITION action (Hive/Spark)
8454    AddPartition {
8455        /// The partition expression
8456        partition: Expression,
8457        if_not_exists: bool,
8458        location: Option<Expression>,
8459    },
8460    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8461    Delete {
8462        where_clause: Expression,
8463    },
8464    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8465    SwapWith(TableRef),
8466    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8467    SetProperty {
8468        properties: Vec<(String, Expression)>,
8469    },
8470    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8471    UnsetProperty {
8472        properties: Vec<String>,
8473    },
8474    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8475    ClusterBy {
8476        expressions: Vec<Expression>,
8477    },
8478    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8479    SetTag {
8480        expressions: Vec<(String, Expression)>,
8481    },
8482    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8483    UnsetTag {
8484        names: Vec<String>,
8485    },
8486    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8487    SetOptions {
8488        expressions: Vec<Expression>,
8489    },
8490    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8491    AlterIndex {
8492        name: Identifier,
8493        visible: bool,
8494    },
8495    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8496    SetAttribute {
8497        attribute: String,
8498    },
8499    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8500    SetStageFileFormat {
8501        options: Option<Expression>,
8502    },
8503    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8504    SetStageCopyOptions {
8505        options: Option<Expression>,
8506    },
8507    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8508    AddColumns {
8509        columns: Vec<ColumnDef>,
8510        cascade: bool,
8511    },
8512    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8513    DropColumns {
8514        names: Vec<Identifier>,
8515    },
8516    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8517    /// In SingleStore, data_type can be omitted for simple column renames
8518    ChangeColumn {
8519        old_name: Identifier,
8520        new_name: Identifier,
8521        #[serde(default, skip_serializing_if = "Option::is_none")]
8522        data_type: Option<DataType>,
8523        comment: Option<String>,
8524        #[serde(default)]
8525        cascade: bool,
8526    },
8527    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
8528    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
8529    AlterSortKey {
8530        /// AUTO or NONE keyword
8531        this: Option<String>,
8532        /// Column list for (col1, col2) syntax
8533        expressions: Vec<Expression>,
8534        /// Whether COMPOUND keyword was present
8535        compound: bool,
8536    },
8537    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
8538    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
8539    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
8540    AlterDistStyle {
8541        /// Distribution style: ALL, EVEN, AUTO, or KEY
8542        style: String,
8543        /// DISTKEY column (only when style is KEY)
8544        distkey: Option<Identifier>,
8545    },
8546    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
8547    SetTableProperties {
8548        properties: Vec<(Expression, Expression)>,
8549    },
8550    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
8551    SetLocation {
8552        location: String,
8553    },
8554    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
8555    SetFileFormat {
8556        format: String,
8557    },
8558    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
8559    ReplacePartition {
8560        partition: Expression,
8561        source: Option<Box<Expression>>,
8562    },
8563    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
8564    SetTiDBTableOption {
8565        option: TiDBTableOption,
8566        #[serde(default)]
8567        force: bool,
8568    },
8569    /// TiDB `REMOVE TTL`.
8570    RemoveTiDBTtl {
8571        #[serde(default)]
8572        executable_comment: bool,
8573    },
8574    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
8575    Raw {
8576        sql: String,
8577    },
8578}
8579
8580/// Actions for ALTER COLUMN
8581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8582#[cfg_attr(feature = "bindings", derive(TS))]
8583pub enum AlterColumnAction {
8584    SetDataType {
8585        data_type: DataType,
8586        /// USING expression for type conversion (PostgreSQL)
8587        using: Option<Expression>,
8588        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
8589        #[serde(default, skip_serializing_if = "Option::is_none")]
8590        collate: Option<String>,
8591    },
8592    SetDefault(Expression),
8593    DropDefault,
8594    SetNotNull,
8595    DropNotNull,
8596    /// Set column comment
8597    Comment(String),
8598    /// MySQL: SET VISIBLE
8599    SetVisible,
8600    /// MySQL: SET INVISIBLE
8601    SetInvisible,
8602}
8603
8604/// CREATE INDEX statement
8605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8606#[cfg_attr(feature = "bindings", derive(TS))]
8607pub struct CreateIndex {
8608    pub name: Identifier,
8609    pub table: TableRef,
8610    pub columns: Vec<IndexColumn>,
8611    /// Expression-capable index key parts. This is used when an index contains
8612    /// functional key parts that cannot be represented by `columns`.
8613    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8614    pub key_parts: Vec<IndexKeyPart>,
8615    pub unique: bool,
8616    pub if_not_exists: bool,
8617    pub using: Option<String>,
8618    /// TSQL CLUSTERED/NONCLUSTERED modifier
8619    #[serde(default)]
8620    pub clustered: Option<String>,
8621    /// PostgreSQL CONCURRENTLY modifier
8622    #[serde(default)]
8623    pub concurrently: bool,
8624    /// PostgreSQL WHERE clause for partial indexes
8625    #[serde(default)]
8626    pub where_clause: Option<Box<Expression>>,
8627    /// PostgreSQL INCLUDE columns
8628    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8629    pub include_columns: Vec<Identifier>,
8630    /// TSQL WITH options (e.g., allow_page_locks=on)
8631    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8632    pub with_options: Vec<(String, String)>,
8633    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
8634    #[serde(default)]
8635    pub on_filegroup: Option<String>,
8636}
8637
8638impl CreateIndex {
8639    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
8640        Self {
8641            name: Identifier::new(name),
8642            table: TableRef::new(table),
8643            columns: Vec::new(),
8644            key_parts: Vec::new(),
8645            unique: false,
8646            if_not_exists: false,
8647            using: None,
8648            clustered: None,
8649            concurrently: false,
8650            where_clause: None,
8651            include_columns: Vec::new(),
8652            with_options: Vec::new(),
8653            on_filegroup: None,
8654        }
8655    }
8656}
8657
8658/// Index column specification
8659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8660#[cfg_attr(feature = "bindings", derive(TS))]
8661pub struct IndexColumn {
8662    pub column: Identifier,
8663    pub desc: bool,
8664    /// Explicit ASC keyword was present
8665    #[serde(default)]
8666    pub asc: bool,
8667    pub nulls_first: Option<bool>,
8668    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
8669    #[serde(default, skip_serializing_if = "Option::is_none")]
8670    pub opclass: Option<String>,
8671}
8672
8673/// An expression-capable index key part.
8674#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8675#[cfg_attr(feature = "bindings", derive(TS))]
8676pub struct IndexKeyPart {
8677    pub expression: Box<Expression>,
8678    /// MySQL column prefix length, for example the `16` in `name(16)`.
8679    #[serde(default, skip_serializing_if = "Option::is_none")]
8680    pub prefix_length: Option<String>,
8681    pub desc: bool,
8682    /// Explicit ASC keyword was present.
8683    #[serde(default)]
8684    pub asc: bool,
8685    pub nulls_first: Option<bool>,
8686    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops).
8687    #[serde(default, skip_serializing_if = "Option::is_none")]
8688    pub opclass: Option<String>,
8689}
8690
8691/// DROP INDEX statement
8692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8693#[cfg_attr(feature = "bindings", derive(TS))]
8694pub struct DropIndex {
8695    pub name: TableRef,
8696    pub table: Option<TableRef>,
8697    pub if_exists: bool,
8698    /// PostgreSQL CONCURRENTLY modifier
8699    #[serde(default)]
8700    pub concurrently: bool,
8701}
8702
8703impl DropIndex {
8704    pub fn new(name: impl Into<String>) -> Self {
8705        Self {
8706            name: TableRef::new(name),
8707            table: None,
8708            if_exists: false,
8709            concurrently: false,
8710        }
8711    }
8712}
8713
8714/// View column definition with optional COMMENT and OPTIONS (BigQuery)
8715#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8716#[cfg_attr(feature = "bindings", derive(TS))]
8717pub struct ViewColumn {
8718    pub name: Identifier,
8719    pub comment: Option<String>,
8720    /// BigQuery: OPTIONS (key=value, ...) on column
8721    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8722    pub options: Vec<Expression>,
8723}
8724
8725impl ViewColumn {
8726    pub fn new(name: impl Into<String>) -> Self {
8727        Self {
8728            name: Identifier::new(name),
8729            comment: None,
8730            options: Vec::new(),
8731        }
8732    }
8733
8734    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
8735        Self {
8736            name: Identifier::new(name),
8737            comment: Some(comment.into()),
8738            options: Vec::new(),
8739        }
8740    }
8741}
8742
8743/// CREATE VIEW statement
8744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8745#[cfg_attr(feature = "bindings", derive(TS))]
8746pub struct CreateView {
8747    pub name: TableRef,
8748    pub columns: Vec<ViewColumn>,
8749    pub query: Expression,
8750    pub or_replace: bool,
8751    /// TSQL: CREATE OR ALTER
8752    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
8753    pub or_alter: bool,
8754    pub if_not_exists: bool,
8755    pub materialized: bool,
8756    pub temporary: bool,
8757    /// Snowflake: SECURE VIEW
8758    #[serde(default)]
8759    pub secure: bool,
8760    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
8761    #[serde(skip_serializing_if = "Option::is_none")]
8762    pub algorithm: Option<String>,
8763    /// MySQL: DEFINER=user@host
8764    #[serde(skip_serializing_if = "Option::is_none")]
8765    pub definer: Option<String>,
8766    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
8767    #[serde(skip_serializing_if = "Option::is_none")]
8768    pub security: Option<FunctionSecurity>,
8769    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
8770    #[serde(default = "default_true")]
8771    pub security_sql_style: bool,
8772    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
8773    #[serde(default)]
8774    pub security_after_name: bool,
8775    /// Whether the query was parenthesized: AS (SELECT ...)
8776    #[serde(default)]
8777    pub query_parenthesized: bool,
8778    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
8779    #[serde(skip_serializing_if = "Option::is_none")]
8780    pub locking_mode: Option<String>,
8781    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
8782    #[serde(skip_serializing_if = "Option::is_none")]
8783    pub locking_access: Option<String>,
8784    /// Snowflake: COPY GRANTS
8785    #[serde(default)]
8786    pub copy_grants: bool,
8787    /// Snowflake: COMMENT = 'text'
8788    #[serde(skip_serializing_if = "Option::is_none", default)]
8789    pub comment: Option<String>,
8790    /// Snowflake: WITH ROW ACCESS POLICY ... clause
8791    #[serde(skip_serializing_if = "Option::is_none", default)]
8792    pub row_access_policy: Option<String>,
8793    /// Snowflake: TAG (name='value', ...)
8794    #[serde(default)]
8795    pub tags: Vec<(String, String)>,
8796    /// BigQuery: OPTIONS (key=value, ...)
8797    #[serde(default)]
8798    pub options: Vec<Expression>,
8799    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
8800    #[serde(skip_serializing_if = "Option::is_none", default)]
8801    pub build: Option<String>,
8802    /// Doris: REFRESH property for materialized views
8803    #[serde(skip_serializing_if = "Option::is_none", default)]
8804    pub refresh: Option<Box<RefreshTriggerProperty>>,
8805    /// Doris: Schema with typed column definitions for materialized views
8806    /// This is used instead of `columns` when the view has typed column definitions
8807    #[serde(skip_serializing_if = "Option::is_none", default)]
8808    pub schema: Option<Box<Schema>>,
8809    /// Doris: KEY (columns) for materialized views
8810    #[serde(skip_serializing_if = "Option::is_none", default)]
8811    pub unique_key: Option<Box<UniqueKeyProperty>>,
8812    /// Redshift: WITH NO SCHEMA BINDING
8813    #[serde(default)]
8814    pub no_schema_binding: bool,
8815    /// Redshift: AUTO REFRESH YES|NO for materialized views
8816    #[serde(skip_serializing_if = "Option::is_none", default)]
8817    pub auto_refresh: Option<bool>,
8818    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
8819    #[serde(skip_serializing_if = "Option::is_none", default)]
8820    pub clickhouse_population: Option<String>,
8821    /// ClickHouse: ON CLUSTER clause
8822    #[serde(default, skip_serializing_if = "Option::is_none")]
8823    pub on_cluster: Option<OnCluster>,
8824    /// ClickHouse: TO destination_table
8825    #[serde(default, skip_serializing_if = "Option::is_none")]
8826    pub to_table: Option<TableRef>,
8827    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
8828    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8829    pub table_properties: Vec<Expression>,
8830}
8831
8832impl CreateView {
8833    pub fn new(name: impl Into<String>, query: Expression) -> Self {
8834        Self {
8835            name: TableRef::new(name),
8836            columns: Vec::new(),
8837            query,
8838            or_replace: false,
8839            or_alter: false,
8840            if_not_exists: false,
8841            materialized: false,
8842            temporary: false,
8843            secure: false,
8844            algorithm: None,
8845            definer: None,
8846            security: None,
8847            security_sql_style: true,
8848            security_after_name: false,
8849            query_parenthesized: false,
8850            locking_mode: None,
8851            locking_access: None,
8852            copy_grants: false,
8853            comment: None,
8854            row_access_policy: None,
8855            tags: Vec::new(),
8856            options: Vec::new(),
8857            build: None,
8858            refresh: None,
8859            schema: None,
8860            unique_key: None,
8861            no_schema_binding: false,
8862            auto_refresh: None,
8863            clickhouse_population: None,
8864            on_cluster: None,
8865            to_table: None,
8866            table_properties: Vec::new(),
8867        }
8868    }
8869}
8870
8871/// DROP VIEW statement
8872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8873#[cfg_attr(feature = "bindings", derive(TS))]
8874pub struct DropView {
8875    pub name: TableRef,
8876    pub if_exists: bool,
8877    pub materialized: bool,
8878}
8879
8880impl DropView {
8881    pub fn new(name: impl Into<String>) -> Self {
8882        Self {
8883            name: TableRef::new(name),
8884            if_exists: false,
8885            materialized: false,
8886        }
8887    }
8888}
8889
8890/// TRUNCATE TABLE statement
8891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8892#[cfg_attr(feature = "bindings", derive(TS))]
8893pub struct Truncate {
8894    /// Target of TRUNCATE (TABLE vs DATABASE)
8895    #[serde(default)]
8896    pub target: TruncateTarget,
8897    /// IF EXISTS clause
8898    #[serde(default)]
8899    pub if_exists: bool,
8900    pub table: TableRef,
8901    /// ClickHouse: ON CLUSTER clause for distributed DDL
8902    #[serde(default, skip_serializing_if = "Option::is_none")]
8903    pub on_cluster: Option<OnCluster>,
8904    pub cascade: bool,
8905    /// Additional tables for multi-table TRUNCATE
8906    #[serde(default)]
8907    pub extra_tables: Vec<TruncateTableEntry>,
8908    /// RESTART IDENTITY or CONTINUE IDENTITY
8909    #[serde(default)]
8910    pub identity: Option<TruncateIdentity>,
8911    /// RESTRICT option (alternative to CASCADE)
8912    #[serde(default)]
8913    pub restrict: bool,
8914    /// Hive PARTITION clause: PARTITION(key=value, ...)
8915    #[serde(default, skip_serializing_if = "Option::is_none")]
8916    pub partition: Option<Box<Expression>>,
8917}
8918
8919/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
8920#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8921#[cfg_attr(feature = "bindings", derive(TS))]
8922pub struct TruncateTableEntry {
8923    pub table: TableRef,
8924    /// Whether the table has a * suffix (inherit children)
8925    #[serde(default)]
8926    pub star: bool,
8927}
8928
8929/// TRUNCATE target type
8930#[derive(
8931    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8932)]
8933#[cfg_attr(feature = "bindings", derive(TS))]
8934pub enum TruncateTarget {
8935    Table,
8936    Database,
8937}
8938
8939impl Default for TruncateTarget {
8940    fn default() -> Self {
8941        TruncateTarget::Table
8942    }
8943}
8944
8945/// TRUNCATE identity option
8946#[derive(
8947    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8948)]
8949#[cfg_attr(feature = "bindings", derive(TS))]
8950pub enum TruncateIdentity {
8951    Restart,
8952    Continue,
8953}
8954
8955impl Truncate {
8956    pub fn new(table: impl Into<String>) -> Self {
8957        Self {
8958            target: TruncateTarget::Table,
8959            if_exists: false,
8960            table: TableRef::new(table),
8961            on_cluster: None,
8962            cascade: false,
8963            extra_tables: Vec::new(),
8964            identity: None,
8965            restrict: false,
8966            partition: None,
8967        }
8968    }
8969}
8970
8971/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
8972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8973#[cfg_attr(feature = "bindings", derive(TS))]
8974pub struct Use {
8975    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
8976    pub kind: Option<UseKind>,
8977    /// The name of the object
8978    pub this: Identifier,
8979}
8980
8981/// Kind of USE statement
8982#[derive(
8983    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8984)]
8985#[cfg_attr(feature = "bindings", derive(TS))]
8986pub enum UseKind {
8987    Database,
8988    Schema,
8989    Role,
8990    Warehouse,
8991    Catalog,
8992    /// Snowflake: USE SECONDARY ROLES ALL|NONE
8993    SecondaryRoles,
8994}
8995
8996/// SET variable statement
8997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8998#[cfg_attr(feature = "bindings", derive(TS))]
8999pub struct SetStatement {
9000    /// The items being set
9001    pub items: Vec<SetItem>,
9002}
9003
9004/// A single SET item (variable assignment)
9005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9006#[cfg_attr(feature = "bindings", derive(TS))]
9007pub struct SetItem {
9008    /// The variable name
9009    pub name: Expression,
9010    /// The value to set
9011    pub value: Expression,
9012    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
9013    pub kind: Option<String>,
9014    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
9015    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9016    pub no_equals: bool,
9017}
9018
9019/// CACHE TABLE statement (Spark)
9020#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9021#[cfg_attr(feature = "bindings", derive(TS))]
9022pub struct Cache {
9023    /// The table to cache
9024    pub table: Identifier,
9025    /// LAZY keyword - defer caching until first use
9026    pub lazy: bool,
9027    /// Optional OPTIONS clause (key-value pairs)
9028    pub options: Vec<(Expression, Expression)>,
9029    /// Optional AS clause with query
9030    pub query: Option<Expression>,
9031}
9032
9033/// UNCACHE TABLE statement (Spark)
9034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9035#[cfg_attr(feature = "bindings", derive(TS))]
9036pub struct Uncache {
9037    /// The table to uncache
9038    pub table: Identifier,
9039    /// IF EXISTS clause
9040    pub if_exists: bool,
9041}
9042
9043/// LOAD DATA statement (Hive)
9044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9045#[cfg_attr(feature = "bindings", derive(TS))]
9046pub struct LoadData {
9047    /// LOCAL keyword - load from local filesystem
9048    pub local: bool,
9049    /// The path to load data from (INPATH value)
9050    pub inpath: String,
9051    /// Whether to overwrite existing data
9052    pub overwrite: bool,
9053    /// The target table
9054    pub table: Expression,
9055    /// Optional PARTITION clause with key-value pairs
9056    pub partition: Vec<(Identifier, Expression)>,
9057    /// Optional INPUTFORMAT clause
9058    pub input_format: Option<String>,
9059    /// Optional SERDE clause
9060    pub serde: Option<String>,
9061}
9062
9063/// PRAGMA statement (SQLite)
9064#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9065#[cfg_attr(feature = "bindings", derive(TS))]
9066pub struct Pragma {
9067    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
9068    pub schema: Option<Identifier>,
9069    /// The pragma name
9070    pub name: Identifier,
9071    /// Optional value for assignment (PRAGMA name = value)
9072    pub value: Option<Expression>,
9073    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
9074    pub args: Vec<Expression>,
9075    /// Whether this pragma should be generated using assignment syntax.
9076    #[serde(default)]
9077    pub use_assignment_syntax: bool,
9078}
9079
9080/// A privilege with optional column list for GRANT/REVOKE
9081/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
9082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9083#[cfg_attr(feature = "bindings", derive(TS))]
9084pub struct Privilege {
9085    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
9086    pub name: String,
9087    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
9088    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9089    pub columns: Vec<String>,
9090}
9091
9092/// Principal in GRANT/REVOKE (user, role, etc.)
9093#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9094#[cfg_attr(feature = "bindings", derive(TS))]
9095pub struct GrantPrincipal {
9096    /// The name of the principal
9097    pub name: Identifier,
9098    /// Whether prefixed with ROLE keyword
9099    pub is_role: bool,
9100    /// Whether prefixed with GROUP keyword (Redshift)
9101    #[serde(default)]
9102    pub is_group: bool,
9103    /// Whether prefixed with SHARE keyword (Snowflake)
9104    #[serde(default)]
9105    pub is_share: bool,
9106}
9107
9108/// GRANT statement
9109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9110#[cfg_attr(feature = "bindings", derive(TS))]
9111pub struct Grant {
9112    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
9113    pub privileges: Vec<Privilege>,
9114    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9115    pub kind: Option<String>,
9116    /// The object to grant on
9117    pub securable: Identifier,
9118    /// Function parameter types (for FUNCTION kind)
9119    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9120    pub function_params: Vec<String>,
9121    /// The grantees
9122    pub principals: Vec<GrantPrincipal>,
9123    /// WITH GRANT OPTION
9124    pub grant_option: bool,
9125    /// TSQL: AS principal (the grantor role)
9126    #[serde(default, skip_serializing_if = "Option::is_none")]
9127    pub as_principal: Option<Identifier>,
9128}
9129
9130/// REVOKE statement
9131#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9132#[cfg_attr(feature = "bindings", derive(TS))]
9133pub struct Revoke {
9134    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9135    pub privileges: Vec<Privilege>,
9136    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9137    pub kind: Option<String>,
9138    /// The object to revoke from
9139    pub securable: Identifier,
9140    /// Function parameter types (for FUNCTION kind)
9141    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9142    pub function_params: Vec<String>,
9143    /// The grantees
9144    pub principals: Vec<GrantPrincipal>,
9145    /// GRANT OPTION FOR
9146    pub grant_option: bool,
9147    /// CASCADE
9148    pub cascade: bool,
9149    /// RESTRICT
9150    #[serde(default)]
9151    pub restrict: bool,
9152}
9153
9154/// COMMENT ON statement
9155#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9156#[cfg_attr(feature = "bindings", derive(TS))]
9157pub struct Comment {
9158    /// The object being commented on
9159    pub this: Expression,
9160    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9161    pub kind: String,
9162    /// The comment text expression
9163    pub expression: Expression,
9164    /// IF EXISTS clause
9165    pub exists: bool,
9166    /// MATERIALIZED keyword
9167    pub materialized: bool,
9168}
9169
9170// ============================================================================
9171// Phase 4: Additional DDL Statements
9172// ============================================================================
9173
9174/// ALTER VIEW statement
9175#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9176#[cfg_attr(feature = "bindings", derive(TS))]
9177pub struct AlterView {
9178    pub name: TableRef,
9179    pub actions: Vec<AlterViewAction>,
9180    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9181    #[serde(default, skip_serializing_if = "Option::is_none")]
9182    pub algorithm: Option<String>,
9183    /// MySQL: DEFINER = 'user'@'host'
9184    #[serde(default, skip_serializing_if = "Option::is_none")]
9185    pub definer: Option<String>,
9186    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9187    #[serde(default, skip_serializing_if = "Option::is_none")]
9188    pub sql_security: Option<String>,
9189    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9190    #[serde(default, skip_serializing_if = "Option::is_none")]
9191    pub with_option: Option<String>,
9192    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9193    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9194    pub columns: Vec<ViewColumn>,
9195}
9196
9197/// Actions for ALTER VIEW
9198#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9199#[cfg_attr(feature = "bindings", derive(TS))]
9200pub enum AlterViewAction {
9201    /// Rename the view
9202    Rename(TableRef),
9203    /// Change owner
9204    OwnerTo(Identifier),
9205    /// Set schema
9206    SetSchema(Identifier),
9207    /// Set authorization (Trino/Presto)
9208    SetAuthorization(String),
9209    /// Alter column
9210    AlterColumn {
9211        name: Identifier,
9212        action: AlterColumnAction,
9213    },
9214    /// Redefine view as query (SELECT, UNION, etc.)
9215    AsSelect(Box<Expression>),
9216    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9217    SetTblproperties(Vec<(String, String)>),
9218    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9219    UnsetTblproperties(Vec<String>),
9220}
9221
9222impl AlterView {
9223    pub fn new(name: impl Into<String>) -> Self {
9224        Self {
9225            name: TableRef::new(name),
9226            actions: Vec::new(),
9227            algorithm: None,
9228            definer: None,
9229            sql_security: None,
9230            with_option: None,
9231            columns: Vec::new(),
9232        }
9233    }
9234}
9235
9236/// ALTER INDEX statement
9237#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9238#[cfg_attr(feature = "bindings", derive(TS))]
9239pub struct AlterIndex {
9240    pub name: Identifier,
9241    pub table: Option<TableRef>,
9242    pub actions: Vec<AlterIndexAction>,
9243}
9244
9245/// Actions for ALTER INDEX
9246#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9247#[cfg_attr(feature = "bindings", derive(TS))]
9248pub enum AlterIndexAction {
9249    /// Rename the index
9250    Rename(Identifier),
9251    /// Set tablespace
9252    SetTablespace(Identifier),
9253    /// Set visibility (MySQL)
9254    Visible(bool),
9255}
9256
9257impl AlterIndex {
9258    pub fn new(name: impl Into<String>) -> Self {
9259        Self {
9260            name: Identifier::new(name),
9261            table: None,
9262            actions: Vec::new(),
9263        }
9264    }
9265}
9266
9267/// CREATE SCHEMA statement
9268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9269#[cfg_attr(feature = "bindings", derive(TS))]
9270pub struct CreateSchema {
9271    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9272    pub name: Vec<Identifier>,
9273    pub if_not_exists: bool,
9274    pub authorization: Option<Identifier>,
9275    /// CLONE source parts, possibly dot-qualified
9276    #[serde(default)]
9277    pub clone_from: Option<Vec<Identifier>>,
9278    /// AT/BEFORE clause for time travel (Snowflake)
9279    #[serde(default)]
9280    pub at_clause: Option<Expression>,
9281    /// Schema properties like DEFAULT COLLATE
9282    #[serde(default)]
9283    pub properties: Vec<Expression>,
9284    /// Leading comments before the statement
9285    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9286    pub leading_comments: Vec<String>,
9287}
9288
9289impl CreateSchema {
9290    pub fn new(name: impl Into<String>) -> Self {
9291        Self {
9292            name: vec![Identifier::new(name)],
9293            if_not_exists: false,
9294            authorization: None,
9295            clone_from: None,
9296            at_clause: None,
9297            properties: Vec::new(),
9298            leading_comments: Vec::new(),
9299        }
9300    }
9301}
9302
9303/// DROP SCHEMA statement
9304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9305#[cfg_attr(feature = "bindings", derive(TS))]
9306pub struct DropSchema {
9307    pub name: Identifier,
9308    pub if_exists: bool,
9309    pub cascade: bool,
9310}
9311
9312impl DropSchema {
9313    pub fn new(name: impl Into<String>) -> Self {
9314        Self {
9315            name: Identifier::new(name),
9316            if_exists: false,
9317            cascade: false,
9318        }
9319    }
9320}
9321
9322/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9324#[cfg_attr(feature = "bindings", derive(TS))]
9325pub struct DropNamespace {
9326    pub name: Identifier,
9327    pub if_exists: bool,
9328    pub cascade: bool,
9329}
9330
9331impl DropNamespace {
9332    pub fn new(name: impl Into<String>) -> Self {
9333        Self {
9334            name: Identifier::new(name),
9335            if_exists: false,
9336            cascade: false,
9337        }
9338    }
9339}
9340
9341/// CREATE DATABASE statement
9342#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9343#[cfg_attr(feature = "bindings", derive(TS))]
9344pub struct CreateDatabase {
9345    pub name: Identifier,
9346    pub if_not_exists: bool,
9347    pub options: Vec<DatabaseOption>,
9348    /// Snowflake CLONE source
9349    #[serde(default)]
9350    pub clone_from: Option<Identifier>,
9351    /// AT/BEFORE clause for time travel (Snowflake)
9352    #[serde(default)]
9353    pub at_clause: Option<Expression>,
9354}
9355
9356/// Database option
9357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9358#[cfg_attr(feature = "bindings", derive(TS))]
9359pub enum DatabaseOption {
9360    CharacterSet(String),
9361    Collate(String),
9362    Owner(Identifier),
9363    Template(Identifier),
9364    Encoding(String),
9365    Location(String),
9366}
9367
9368impl CreateDatabase {
9369    pub fn new(name: impl Into<String>) -> Self {
9370        Self {
9371            name: Identifier::new(name),
9372            if_not_exists: false,
9373            options: Vec::new(),
9374            clone_from: None,
9375            at_clause: None,
9376        }
9377    }
9378}
9379
9380/// DROP DATABASE statement
9381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9382#[cfg_attr(feature = "bindings", derive(TS))]
9383pub struct DropDatabase {
9384    pub name: Identifier,
9385    pub if_exists: bool,
9386    /// ClickHouse: SYNC modifier
9387    #[serde(default)]
9388    pub sync: bool,
9389}
9390
9391impl DropDatabase {
9392    pub fn new(name: impl Into<String>) -> Self {
9393        Self {
9394            name: Identifier::new(name),
9395            if_exists: false,
9396            sync: false,
9397        }
9398    }
9399}
9400
9401/// CREATE FUNCTION statement
9402#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9403#[cfg_attr(feature = "bindings", derive(TS))]
9404pub struct CreateFunction {
9405    pub name: TableRef,
9406    pub parameters: Vec<FunctionParameter>,
9407    pub return_type: Option<DataType>,
9408    pub body: Option<FunctionBody>,
9409    pub or_replace: bool,
9410    /// TSQL: CREATE OR ALTER
9411    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9412    pub or_alter: bool,
9413    pub if_not_exists: bool,
9414    pub temporary: bool,
9415    pub language: Option<String>,
9416    pub deterministic: Option<bool>,
9417    pub returns_null_on_null_input: Option<bool>,
9418    pub security: Option<FunctionSecurity>,
9419    /// Whether parentheses were present in the original syntax
9420    #[serde(default = "default_true")]
9421    pub has_parens: bool,
9422    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9423    #[serde(default)]
9424    pub sql_data_access: Option<SqlDataAccess>,
9425    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9426    #[serde(default, skip_serializing_if = "Option::is_none")]
9427    pub returns_table_body: Option<String>,
9428    /// True if LANGUAGE clause appears before RETURNS clause
9429    #[serde(default)]
9430    pub language_first: bool,
9431    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9432    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9433    pub set_options: Vec<FunctionSetOption>,
9434    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9435    #[serde(default)]
9436    pub strict: bool,
9437    /// BigQuery: OPTIONS (key=value, ...)
9438    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9439    pub options: Vec<Expression>,
9440    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9441    #[serde(default)]
9442    pub is_table_function: bool,
9443    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9444    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9445    pub property_order: Vec<FunctionPropertyKind>,
9446    /// Hive: USING JAR|FILE|ARCHIVE '...'
9447    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9448    pub using_resources: Vec<FunctionUsingResource>,
9449    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9450    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9451    pub environment: Vec<Expression>,
9452    /// HANDLER 'handler_function' clause (Databricks)
9453    #[serde(default, skip_serializing_if = "Option::is_none")]
9454    pub handler: Option<String>,
9455    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9456    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9457    pub handler_uses_eq: bool,
9458    /// Snowflake: RUNTIME_VERSION='3.11'
9459    #[serde(default, skip_serializing_if = "Option::is_none")]
9460    pub runtime_version: Option<String>,
9461    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9462    #[serde(default, skip_serializing_if = "Option::is_none")]
9463    pub packages: Option<Vec<String>>,
9464    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9465    #[serde(default, skip_serializing_if = "Option::is_none")]
9466    pub parameter_style: Option<String>,
9467}
9468
9469/// A SET option in CREATE FUNCTION (PostgreSQL)
9470#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9471#[cfg_attr(feature = "bindings", derive(TS))]
9472pub struct FunctionSetOption {
9473    pub name: String,
9474    pub value: FunctionSetValue,
9475}
9476
9477/// The value of a SET option
9478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9479#[cfg_attr(feature = "bindings", derive(TS))]
9480pub enum FunctionSetValue {
9481    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9482    Value { value: String, use_to: bool },
9483    /// SET key FROM CURRENT
9484    FromCurrent,
9485}
9486
9487/// SQL data access characteristics for functions
9488#[derive(
9489    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9490)]
9491#[cfg_attr(feature = "bindings", derive(TS))]
9492pub enum SqlDataAccess {
9493    /// NO SQL
9494    NoSql,
9495    /// CONTAINS SQL
9496    ContainsSql,
9497    /// READS SQL DATA
9498    ReadsSqlData,
9499    /// MODIFIES SQL DATA
9500    ModifiesSqlData,
9501}
9502
9503/// Types of properties in CREATE FUNCTION for tracking their original order
9504#[derive(
9505    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9506)]
9507#[cfg_attr(feature = "bindings", derive(TS))]
9508pub enum FunctionPropertyKind {
9509    /// SET option
9510    Set,
9511    /// AS body
9512    As,
9513    /// Hive: USING JAR|FILE|ARCHIVE ...
9514    Using,
9515    /// LANGUAGE clause
9516    Language,
9517    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9518    Determinism,
9519    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
9520    NullInput,
9521    /// SECURITY DEFINER/INVOKER
9522    Security,
9523    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
9524    SqlDataAccess,
9525    /// OPTIONS clause (BigQuery)
9526    Options,
9527    /// ENVIRONMENT clause (Databricks)
9528    Environment,
9529    /// HANDLER clause (Databricks)
9530    Handler,
9531    /// Snowflake: RUNTIME_VERSION='...'
9532    RuntimeVersion,
9533    /// Snowflake: PACKAGES=(...)
9534    Packages,
9535    /// PARAMETER STYLE clause (Databricks)
9536    ParameterStyle,
9537}
9538
9539/// Hive CREATE FUNCTION resource in a USING clause
9540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9541#[cfg_attr(feature = "bindings", derive(TS))]
9542pub struct FunctionUsingResource {
9543    pub kind: String,
9544    pub uri: String,
9545}
9546
9547/// Function parameter
9548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9549#[cfg_attr(feature = "bindings", derive(TS))]
9550pub struct FunctionParameter {
9551    pub name: Option<Identifier>,
9552    pub data_type: DataType,
9553    pub mode: Option<ParameterMode>,
9554    pub default: Option<Expression>,
9555    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
9556    #[serde(default, skip_serializing_if = "Option::is_none")]
9557    pub mode_text: Option<String>,
9558}
9559
9560/// Parameter mode (IN, OUT, INOUT, VARIADIC)
9561#[derive(
9562    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9563)]
9564#[cfg_attr(feature = "bindings", derive(TS))]
9565pub enum ParameterMode {
9566    In,
9567    Out,
9568    InOut,
9569    Variadic,
9570}
9571
9572/// Function body
9573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9574#[cfg_attr(feature = "bindings", derive(TS))]
9575pub enum FunctionBody {
9576    /// AS $$ ... $$ (dollar-quoted)
9577    Block(String),
9578    /// AS 'string' (single-quoted string literal body)
9579    StringLiteral(String),
9580    /// AS 'expression'
9581    Expression(Expression),
9582    /// EXTERNAL NAME 'library'
9583    External(String),
9584    /// RETURN expression
9585    Return(Expression),
9586    /// BEGIN ... END block with parsed statements
9587    Statements(Vec<Expression>),
9588    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
9589    /// Stores (content, optional_tag)
9590    DollarQuoted {
9591        content: String,
9592        tag: Option<String>,
9593    },
9594    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
9595    RawBlock(String),
9596}
9597
9598/// Function security (DEFINER, INVOKER, or NONE)
9599#[derive(
9600    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9601)]
9602#[cfg_attr(feature = "bindings", derive(TS))]
9603pub enum FunctionSecurity {
9604    Definer,
9605    Invoker,
9606    /// StarRocks/MySQL: SECURITY NONE
9607    None,
9608}
9609
9610impl CreateFunction {
9611    pub fn new(name: impl Into<String>) -> Self {
9612        Self {
9613            name: TableRef::new(name),
9614            parameters: Vec::new(),
9615            return_type: None,
9616            body: None,
9617            or_replace: false,
9618            or_alter: false,
9619            if_not_exists: false,
9620            temporary: false,
9621            language: None,
9622            deterministic: None,
9623            returns_null_on_null_input: None,
9624            security: None,
9625            has_parens: true,
9626            sql_data_access: None,
9627            returns_table_body: None,
9628            language_first: false,
9629            set_options: Vec::new(),
9630            strict: false,
9631            options: Vec::new(),
9632            is_table_function: false,
9633            property_order: Vec::new(),
9634            using_resources: Vec::new(),
9635            environment: Vec::new(),
9636            handler: None,
9637            handler_uses_eq: false,
9638            runtime_version: None,
9639            packages: None,
9640            parameter_style: None,
9641        }
9642    }
9643}
9644
9645/// DROP FUNCTION statement
9646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9647#[cfg_attr(feature = "bindings", derive(TS))]
9648pub struct DropFunction {
9649    pub name: TableRef,
9650    pub parameters: Option<Vec<DataType>>,
9651    pub if_exists: bool,
9652    pub cascade: bool,
9653}
9654
9655impl DropFunction {
9656    pub fn new(name: impl Into<String>) -> Self {
9657        Self {
9658            name: TableRef::new(name),
9659            parameters: None,
9660            if_exists: false,
9661            cascade: false,
9662        }
9663    }
9664}
9665
9666/// CREATE PROCEDURE statement
9667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9668#[cfg_attr(feature = "bindings", derive(TS))]
9669pub struct CreateProcedure {
9670    pub name: TableRef,
9671    pub parameters: Vec<FunctionParameter>,
9672    pub body: Option<FunctionBody>,
9673    pub or_replace: bool,
9674    /// TSQL: CREATE OR ALTER
9675    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9676    pub or_alter: bool,
9677    pub if_not_exists: bool,
9678    pub language: Option<String>,
9679    pub security: Option<FunctionSecurity>,
9680    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
9681    #[serde(default)]
9682    pub return_type: Option<DataType>,
9683    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
9684    #[serde(default)]
9685    pub execute_as: Option<String>,
9686    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
9687    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9688    pub with_options: Vec<String>,
9689    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
9690    #[serde(default = "default_true", skip_serializing_if = "is_true")]
9691    pub has_parens: bool,
9692    /// Whether the short form PROC was used (instead of PROCEDURE)
9693    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9694    pub use_proc_keyword: bool,
9695}
9696
9697impl CreateProcedure {
9698    pub fn new(name: impl Into<String>) -> Self {
9699        Self {
9700            name: TableRef::new(name),
9701            parameters: Vec::new(),
9702            body: None,
9703            or_replace: false,
9704            or_alter: false,
9705            if_not_exists: false,
9706            language: None,
9707            security: None,
9708            return_type: None,
9709            execute_as: None,
9710            with_options: Vec::new(),
9711            has_parens: true,
9712            use_proc_keyword: false,
9713        }
9714    }
9715}
9716
9717/// DROP PROCEDURE statement
9718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9719#[cfg_attr(feature = "bindings", derive(TS))]
9720pub struct DropProcedure {
9721    pub name: TableRef,
9722    pub parameters: Option<Vec<DataType>>,
9723    pub if_exists: bool,
9724    pub cascade: bool,
9725}
9726
9727impl DropProcedure {
9728    pub fn new(name: impl Into<String>) -> Self {
9729        Self {
9730            name: TableRef::new(name),
9731            parameters: None,
9732            if_exists: false,
9733            cascade: false,
9734        }
9735    }
9736}
9737
9738/// Sequence property tag for ordering
9739#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9740#[cfg_attr(feature = "bindings", derive(TS))]
9741pub enum SeqPropKind {
9742    Start,
9743    Increment,
9744    Minvalue,
9745    Maxvalue,
9746    Cache,
9747    NoCache,
9748    Cycle,
9749    NoCycle,
9750    OwnedBy,
9751    Order,
9752    NoOrder,
9753    Comment,
9754    /// SHARING=<value> (Oracle)
9755    Sharing,
9756    /// KEEP (Oracle)
9757    Keep,
9758    /// NOKEEP (Oracle)
9759    NoKeep,
9760    /// SCALE [EXTEND|NOEXTEND] (Oracle)
9761    Scale,
9762    /// NOSCALE (Oracle)
9763    NoScale,
9764    /// SHARD [EXTEND|NOEXTEND] (Oracle)
9765    Shard,
9766    /// NOSHARD (Oracle)
9767    NoShard,
9768    /// SESSION (Oracle)
9769    Session,
9770    /// GLOBAL (Oracle)
9771    Global,
9772    /// NOCACHE (single word, Oracle)
9773    NoCacheWord,
9774    /// NOCYCLE (single word, Oracle)
9775    NoCycleWord,
9776    /// NOMINVALUE (single word, Oracle)
9777    NoMinvalueWord,
9778    /// NOMAXVALUE (single word, Oracle)
9779    NoMaxvalueWord,
9780}
9781
9782/// CREATE SYNONYM statement (TSQL)
9783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9784#[cfg_attr(feature = "bindings", derive(TS))]
9785pub struct CreateSynonym {
9786    /// The synonym name (can be qualified: schema.synonym_name)
9787    pub name: TableRef,
9788    /// The target object the synonym refers to
9789    pub target: TableRef,
9790}
9791
9792/// CREATE SEQUENCE statement
9793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9794#[cfg_attr(feature = "bindings", derive(TS))]
9795pub struct CreateSequence {
9796    pub name: TableRef,
9797    pub if_not_exists: bool,
9798    pub temporary: bool,
9799    #[serde(default)]
9800    pub or_replace: bool,
9801    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
9802    #[serde(default, skip_serializing_if = "Option::is_none")]
9803    pub as_type: Option<DataType>,
9804    pub increment: Option<i64>,
9805    pub minvalue: Option<SequenceBound>,
9806    pub maxvalue: Option<SequenceBound>,
9807    pub start: Option<i64>,
9808    pub cache: Option<i64>,
9809    pub cycle: bool,
9810    pub owned_by: Option<TableRef>,
9811    /// Whether OWNED BY NONE was specified
9812    #[serde(default)]
9813    pub owned_by_none: bool,
9814    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
9815    #[serde(default)]
9816    pub order: Option<bool>,
9817    /// Snowflake: COMMENT = 'value'
9818    #[serde(default)]
9819    pub comment: Option<String>,
9820    /// SHARING=<value> (Oracle)
9821    #[serde(default, skip_serializing_if = "Option::is_none")]
9822    pub sharing: Option<String>,
9823    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
9824    #[serde(default, skip_serializing_if = "Option::is_none")]
9825    pub scale_modifier: Option<String>,
9826    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
9827    #[serde(default, skip_serializing_if = "Option::is_none")]
9828    pub shard_modifier: Option<String>,
9829    /// Tracks the order in which properties appeared in the source
9830    #[serde(default)]
9831    pub property_order: Vec<SeqPropKind>,
9832}
9833
9834/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
9835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9836#[cfg_attr(feature = "bindings", derive(TS))]
9837pub enum SequenceBound {
9838    Value(i64),
9839    None,
9840}
9841
9842impl CreateSequence {
9843    pub fn new(name: impl Into<String>) -> Self {
9844        Self {
9845            name: TableRef::new(name),
9846            if_not_exists: false,
9847            temporary: false,
9848            or_replace: false,
9849            as_type: None,
9850            increment: None,
9851            minvalue: None,
9852            maxvalue: None,
9853            start: None,
9854            cache: None,
9855            cycle: false,
9856            owned_by: None,
9857            owned_by_none: false,
9858            order: None,
9859            comment: None,
9860            sharing: None,
9861            scale_modifier: None,
9862            shard_modifier: None,
9863            property_order: Vec::new(),
9864        }
9865    }
9866}
9867
9868/// DROP SEQUENCE statement
9869#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9870#[cfg_attr(feature = "bindings", derive(TS))]
9871pub struct DropSequence {
9872    pub name: TableRef,
9873    pub if_exists: bool,
9874    pub cascade: bool,
9875}
9876
9877impl DropSequence {
9878    pub fn new(name: impl Into<String>) -> Self {
9879        Self {
9880            name: TableRef::new(name),
9881            if_exists: false,
9882            cascade: false,
9883        }
9884    }
9885}
9886
9887/// ALTER SEQUENCE statement
9888#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9889#[cfg_attr(feature = "bindings", derive(TS))]
9890pub struct AlterSequence {
9891    pub name: TableRef,
9892    pub if_exists: bool,
9893    pub increment: Option<i64>,
9894    pub minvalue: Option<SequenceBound>,
9895    pub maxvalue: Option<SequenceBound>,
9896    pub start: Option<i64>,
9897    pub restart: Option<Option<i64>>,
9898    pub cache: Option<i64>,
9899    pub cycle: Option<bool>,
9900    pub owned_by: Option<Option<TableRef>>,
9901}
9902
9903impl AlterSequence {
9904    pub fn new(name: impl Into<String>) -> Self {
9905        Self {
9906            name: TableRef::new(name),
9907            if_exists: false,
9908            increment: None,
9909            minvalue: None,
9910            maxvalue: None,
9911            start: None,
9912            restart: None,
9913            cache: None,
9914            cycle: None,
9915            owned_by: None,
9916        }
9917    }
9918}
9919
9920/// CREATE TRIGGER statement
9921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9922#[cfg_attr(feature = "bindings", derive(TS))]
9923pub struct CreateTrigger {
9924    pub name: Identifier,
9925    pub table: TableRef,
9926    pub timing: TriggerTiming,
9927    pub events: Vec<TriggerEvent>,
9928    #[serde(default, skip_serializing_if = "Option::is_none")]
9929    pub for_each: Option<TriggerForEach>,
9930    pub when: Option<Expression>,
9931    /// Whether the WHEN clause was parenthesized in the original SQL
9932    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9933    pub when_paren: bool,
9934    pub body: TriggerBody,
9935    pub or_replace: bool,
9936    /// TSQL: CREATE OR ALTER
9937    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9938    pub or_alter: bool,
9939    pub constraint: bool,
9940    pub deferrable: Option<bool>,
9941    pub initially_deferred: Option<bool>,
9942    pub referencing: Option<TriggerReferencing>,
9943}
9944
9945/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
9946#[derive(
9947    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9948)]
9949#[cfg_attr(feature = "bindings", derive(TS))]
9950pub enum TriggerTiming {
9951    Before,
9952    After,
9953    InsteadOf,
9954}
9955
9956/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
9957#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9958#[cfg_attr(feature = "bindings", derive(TS))]
9959pub enum TriggerEvent {
9960    Insert,
9961    Update(Option<Vec<Identifier>>),
9962    Delete,
9963    Truncate,
9964}
9965
9966/// Trigger FOR EACH clause
9967#[derive(
9968    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9969)]
9970#[cfg_attr(feature = "bindings", derive(TS))]
9971pub enum TriggerForEach {
9972    Row,
9973    Statement,
9974}
9975
9976/// Trigger body
9977#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9978#[cfg_attr(feature = "bindings", derive(TS))]
9979pub enum TriggerBody {
9980    /// EXECUTE FUNCTION/PROCEDURE name(args)
9981    Execute {
9982        function: TableRef,
9983        args: Vec<Expression>,
9984    },
9985    /// BEGIN ... END block
9986    Block(String),
9987}
9988
9989/// Trigger REFERENCING clause
9990#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9991#[cfg_attr(feature = "bindings", derive(TS))]
9992pub struct TriggerReferencing {
9993    pub old_table: Option<Identifier>,
9994    pub new_table: Option<Identifier>,
9995    pub old_row: Option<Identifier>,
9996    pub new_row: Option<Identifier>,
9997}
9998
9999impl CreateTrigger {
10000    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
10001        Self {
10002            name: Identifier::new(name),
10003            table: TableRef::new(table),
10004            timing: TriggerTiming::Before,
10005            events: Vec::new(),
10006            for_each: Some(TriggerForEach::Row),
10007            when: None,
10008            when_paren: false,
10009            body: TriggerBody::Execute {
10010                function: TableRef::new(""),
10011                args: Vec::new(),
10012            },
10013            or_replace: false,
10014            or_alter: false,
10015            constraint: false,
10016            deferrable: None,
10017            initially_deferred: None,
10018            referencing: None,
10019        }
10020    }
10021}
10022
10023/// DROP TRIGGER statement
10024#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10025#[cfg_attr(feature = "bindings", derive(TS))]
10026pub struct DropTrigger {
10027    pub name: Identifier,
10028    pub table: Option<TableRef>,
10029    pub if_exists: bool,
10030    pub cascade: bool,
10031}
10032
10033impl DropTrigger {
10034    pub fn new(name: impl Into<String>) -> Self {
10035        Self {
10036            name: Identifier::new(name),
10037            table: None,
10038            if_exists: false,
10039            cascade: false,
10040        }
10041    }
10042}
10043
10044/// CREATE TYPE statement
10045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10046#[cfg_attr(feature = "bindings", derive(TS))]
10047pub struct CreateType {
10048    pub name: TableRef,
10049    pub definition: TypeDefinition,
10050    pub if_not_exists: bool,
10051}
10052
10053/// Type definition
10054#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10055#[cfg_attr(feature = "bindings", derive(TS))]
10056pub enum TypeDefinition {
10057    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
10058    Enum(Vec<String>),
10059    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
10060    Composite(Vec<TypeAttribute>),
10061    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
10062    Range {
10063        subtype: DataType,
10064        subtype_diff: Option<String>,
10065        canonical: Option<String>,
10066    },
10067    /// Base type (for advanced usage)
10068    Base {
10069        input: String,
10070        output: String,
10071        internallength: Option<i32>,
10072    },
10073    /// Domain type
10074    Domain {
10075        base_type: DataType,
10076        default: Option<Expression>,
10077        constraints: Vec<DomainConstraint>,
10078    },
10079}
10080
10081/// Type attribute for composite types
10082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10083#[cfg_attr(feature = "bindings", derive(TS))]
10084pub struct TypeAttribute {
10085    pub name: Identifier,
10086    pub data_type: DataType,
10087    pub collate: Option<Identifier>,
10088}
10089
10090/// Domain constraint
10091#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10092#[cfg_attr(feature = "bindings", derive(TS))]
10093pub struct DomainConstraint {
10094    pub name: Option<Identifier>,
10095    pub check: Expression,
10096}
10097
10098impl CreateType {
10099    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
10100        Self {
10101            name: TableRef::new(name),
10102            definition: TypeDefinition::Enum(values),
10103            if_not_exists: false,
10104        }
10105    }
10106
10107    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
10108        Self {
10109            name: TableRef::new(name),
10110            definition: TypeDefinition::Composite(attributes),
10111            if_not_exists: false,
10112        }
10113    }
10114}
10115
10116/// DROP TYPE statement
10117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10118#[cfg_attr(feature = "bindings", derive(TS))]
10119pub struct DropType {
10120    pub name: TableRef,
10121    pub if_exists: bool,
10122    pub cascade: bool,
10123}
10124
10125impl DropType {
10126    pub fn new(name: impl Into<String>) -> Self {
10127        Self {
10128            name: TableRef::new(name),
10129            if_exists: false,
10130            cascade: false,
10131        }
10132    }
10133}
10134
10135/// DESCRIBE statement - shows table structure or query plan
10136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10137#[cfg_attr(feature = "bindings", derive(TS))]
10138pub struct Describe {
10139    /// The target to describe (table name or query)
10140    pub target: Expression,
10141    /// EXTENDED format
10142    pub extended: bool,
10143    /// FORMATTED format
10144    pub formatted: bool,
10145    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10146    #[serde(default)]
10147    pub kind: Option<String>,
10148    /// Properties like type=stage
10149    #[serde(default)]
10150    pub properties: Vec<(String, String)>,
10151    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10152    #[serde(default, skip_serializing_if = "Option::is_none")]
10153    pub style: Option<String>,
10154    /// Partition specification for DESCRIBE PARTITION
10155    #[serde(default)]
10156    pub partition: Option<Box<Expression>>,
10157    /// Leading comments before the statement
10158    #[serde(default)]
10159    pub leading_comments: Vec<String>,
10160    /// AS JSON suffix (Databricks)
10161    #[serde(default)]
10162    pub as_json: bool,
10163    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10164    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10165    pub params: Vec<String>,
10166}
10167
10168impl Describe {
10169    pub fn new(target: Expression) -> Self {
10170        Self {
10171            target,
10172            extended: false,
10173            formatted: false,
10174            kind: None,
10175            properties: Vec::new(),
10176            style: None,
10177            partition: None,
10178            leading_comments: Vec::new(),
10179            as_json: false,
10180            params: Vec::new(),
10181        }
10182    }
10183}
10184
10185/// SHOW statement - displays database objects
10186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10187#[cfg_attr(feature = "bindings", derive(TS))]
10188pub struct Show {
10189    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10190    pub this: String,
10191    /// Whether TERSE was specified
10192    #[serde(default)]
10193    pub terse: bool,
10194    /// Whether HISTORY was specified
10195    #[serde(default)]
10196    pub history: bool,
10197    /// LIKE pattern
10198    pub like: Option<Expression>,
10199    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10200    pub scope_kind: Option<String>,
10201    /// IN scope object
10202    pub scope: Option<Expression>,
10203    /// STARTS WITH pattern
10204    pub starts_with: Option<Expression>,
10205    /// LIMIT clause
10206    pub limit: Option<Box<Limit>>,
10207    /// FROM clause (for specific object)
10208    pub from: Option<Expression>,
10209    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10210    #[serde(default, skip_serializing_if = "Option::is_none")]
10211    pub where_clause: Option<Expression>,
10212    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10213    #[serde(default, skip_serializing_if = "Option::is_none")]
10214    pub for_target: Option<Expression>,
10215    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10216    #[serde(default, skip_serializing_if = "Option::is_none")]
10217    pub db: Option<Expression>,
10218    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10219    #[serde(default, skip_serializing_if = "Option::is_none")]
10220    pub target: Option<Expression>,
10221    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10222    #[serde(default, skip_serializing_if = "Option::is_none")]
10223    pub mutex: Option<bool>,
10224    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10225    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10226    pub privileges: Vec<String>,
10227}
10228
10229impl Show {
10230    pub fn new(this: impl Into<String>) -> Self {
10231        Self {
10232            this: this.into(),
10233            terse: false,
10234            history: false,
10235            like: None,
10236            scope_kind: None,
10237            scope: None,
10238            starts_with: None,
10239            limit: None,
10240            from: None,
10241            where_clause: None,
10242            for_target: None,
10243            db: None,
10244            target: None,
10245            mutex: None,
10246            privileges: Vec::new(),
10247        }
10248    }
10249}
10250
10251/// Represent an explicit parenthesized expression for grouping precedence.
10252///
10253/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10254/// correctly instead of being flattened to `a + b * c`.
10255#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10256#[cfg_attr(feature = "bindings", derive(TS))]
10257pub struct Paren {
10258    /// The inner expression wrapped by parentheses.
10259    pub this: Expression,
10260    #[serde(default)]
10261    pub trailing_comments: Vec<String>,
10262}
10263
10264/// Expression annotated with trailing comments (for round-trip preservation)
10265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10266#[cfg_attr(feature = "bindings", derive(TS))]
10267pub struct Annotated {
10268    pub this: Expression,
10269    pub trailing_comments: Vec<String>,
10270}
10271
10272// === BATCH GENERATED STRUCT DEFINITIONS ===
10273// Generated from Python sqlglot expressions.py
10274
10275/// Refresh
10276#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10277#[cfg_attr(feature = "bindings", derive(TS))]
10278pub struct Refresh {
10279    pub this: Box<Expression>,
10280    pub kind: String,
10281}
10282
10283/// LockingStatement
10284#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10285#[cfg_attr(feature = "bindings", derive(TS))]
10286pub struct LockingStatement {
10287    pub this: Box<Expression>,
10288    pub expression: Box<Expression>,
10289}
10290
10291/// SequenceProperties
10292#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10293#[cfg_attr(feature = "bindings", derive(TS))]
10294pub struct SequenceProperties {
10295    #[serde(default)]
10296    pub increment: Option<Box<Expression>>,
10297    #[serde(default)]
10298    pub minvalue: Option<Box<Expression>>,
10299    #[serde(default)]
10300    pub maxvalue: Option<Box<Expression>>,
10301    #[serde(default)]
10302    pub cache: Option<Box<Expression>>,
10303    #[serde(default)]
10304    pub start: Option<Box<Expression>>,
10305    #[serde(default)]
10306    pub owned: Option<Box<Expression>>,
10307    #[serde(default)]
10308    pub options: Vec<Expression>,
10309}
10310
10311/// TruncateTable
10312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10313#[cfg_attr(feature = "bindings", derive(TS))]
10314pub struct TruncateTable {
10315    #[serde(default)]
10316    pub expressions: Vec<Expression>,
10317    #[serde(default)]
10318    pub is_database: Option<Box<Expression>>,
10319    #[serde(default)]
10320    pub exists: bool,
10321    #[serde(default)]
10322    pub only: Option<Box<Expression>>,
10323    #[serde(default)]
10324    pub cluster: Option<Box<Expression>>,
10325    #[serde(default)]
10326    pub identity: Option<Box<Expression>>,
10327    #[serde(default)]
10328    pub option: Option<Box<Expression>>,
10329    #[serde(default)]
10330    pub partition: Option<Box<Expression>>,
10331}
10332
10333/// Clone
10334#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10335#[cfg_attr(feature = "bindings", derive(TS))]
10336pub struct Clone {
10337    pub this: Box<Expression>,
10338    #[serde(default)]
10339    pub shallow: Option<Box<Expression>>,
10340    #[serde(default)]
10341    pub copy: Option<Box<Expression>>,
10342}
10343
10344/// Attach
10345#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10346#[cfg_attr(feature = "bindings", derive(TS))]
10347pub struct Attach {
10348    pub this: Box<Expression>,
10349    #[serde(default)]
10350    pub exists: bool,
10351    #[serde(default)]
10352    pub expressions: Vec<Expression>,
10353}
10354
10355/// Detach
10356#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10357#[cfg_attr(feature = "bindings", derive(TS))]
10358pub struct Detach {
10359    pub this: Box<Expression>,
10360    #[serde(default)]
10361    pub exists: bool,
10362}
10363
10364/// Install
10365#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10366#[cfg_attr(feature = "bindings", derive(TS))]
10367pub struct Install {
10368    pub this: Box<Expression>,
10369    #[serde(default)]
10370    pub from_: Option<Box<Expression>>,
10371    #[serde(default)]
10372    pub force: Option<Box<Expression>>,
10373}
10374
10375/// Summarize
10376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10377#[cfg_attr(feature = "bindings", derive(TS))]
10378pub struct Summarize {
10379    pub this: Box<Expression>,
10380    #[serde(default)]
10381    pub table: Option<Box<Expression>>,
10382}
10383
10384/// Declare
10385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10386#[cfg_attr(feature = "bindings", derive(TS))]
10387pub struct Declare {
10388    #[serde(default)]
10389    pub expressions: Vec<Expression>,
10390    #[serde(default)]
10391    pub replace: bool,
10392}
10393
10394/// DeclareItem
10395#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10396#[cfg_attr(feature = "bindings", derive(TS))]
10397pub struct DeclareItem {
10398    pub this: Box<Expression>,
10399    #[serde(default)]
10400    pub kind: Option<String>,
10401    #[serde(default)]
10402    pub default: Option<Box<Expression>>,
10403    #[serde(default)]
10404    pub has_as: bool,
10405    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10406    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10407    pub additional_names: Vec<Expression>,
10408}
10409
10410/// Set
10411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10412#[cfg_attr(feature = "bindings", derive(TS))]
10413pub struct Set {
10414    #[serde(default)]
10415    pub expressions: Vec<Expression>,
10416    #[serde(default)]
10417    pub unset: Option<Box<Expression>>,
10418    #[serde(default)]
10419    pub tag: Option<Box<Expression>>,
10420}
10421
10422/// Heredoc
10423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10424#[cfg_attr(feature = "bindings", derive(TS))]
10425pub struct Heredoc {
10426    pub this: Box<Expression>,
10427    #[serde(default)]
10428    pub tag: Option<Box<Expression>>,
10429}
10430
10431/// QueryBand
10432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10433#[cfg_attr(feature = "bindings", derive(TS))]
10434pub struct QueryBand {
10435    pub this: Box<Expression>,
10436    #[serde(default)]
10437    pub scope: Option<Box<Expression>>,
10438    #[serde(default)]
10439    pub update: Option<Box<Expression>>,
10440}
10441
10442/// UserDefinedFunction
10443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10444#[cfg_attr(feature = "bindings", derive(TS))]
10445pub struct UserDefinedFunction {
10446    pub this: Box<Expression>,
10447    #[serde(default)]
10448    pub expressions: Vec<Expression>,
10449    #[serde(default)]
10450    pub wrapped: Option<Box<Expression>>,
10451}
10452
10453/// RecursiveWithSearch
10454#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10455#[cfg_attr(feature = "bindings", derive(TS))]
10456pub struct RecursiveWithSearch {
10457    pub kind: String,
10458    pub this: Box<Expression>,
10459    pub expression: Box<Expression>,
10460    #[serde(default)]
10461    pub using: Option<Box<Expression>>,
10462}
10463
10464/// ProjectionDef
10465#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10466#[cfg_attr(feature = "bindings", derive(TS))]
10467pub struct ProjectionDef {
10468    pub this: Box<Expression>,
10469    pub expression: Box<Expression>,
10470}
10471
10472/// TableAlias
10473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10474#[cfg_attr(feature = "bindings", derive(TS))]
10475pub struct TableAlias {
10476    #[serde(default)]
10477    pub this: Option<Box<Expression>>,
10478    #[serde(default)]
10479    pub columns: Vec<Expression>,
10480}
10481
10482/// ByteString
10483#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10484#[cfg_attr(feature = "bindings", derive(TS))]
10485pub struct ByteString {
10486    pub this: Box<Expression>,
10487    #[serde(default)]
10488    pub is_bytes: Option<Box<Expression>>,
10489}
10490
10491/// HexStringExpr - Hex string expression (not literal)
10492/// BigQuery: converts to FROM_HEX(this)
10493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10494#[cfg_attr(feature = "bindings", derive(TS))]
10495pub struct HexStringExpr {
10496    pub this: Box<Expression>,
10497    #[serde(default)]
10498    pub is_integer: Option<bool>,
10499}
10500
10501/// UnicodeString
10502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10503#[cfg_attr(feature = "bindings", derive(TS))]
10504pub struct UnicodeString {
10505    pub this: Box<Expression>,
10506    #[serde(default)]
10507    pub escape: Option<Box<Expression>>,
10508}
10509
10510/// AlterColumn
10511#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10512#[cfg_attr(feature = "bindings", derive(TS))]
10513pub struct AlterColumn {
10514    pub this: Box<Expression>,
10515    #[serde(default)]
10516    pub dtype: Option<Box<Expression>>,
10517    #[serde(default)]
10518    pub collate: Option<Box<Expression>>,
10519    #[serde(default)]
10520    pub using: Option<Box<Expression>>,
10521    #[serde(default)]
10522    pub default: Option<Box<Expression>>,
10523    #[serde(default)]
10524    pub drop: Option<Box<Expression>>,
10525    #[serde(default)]
10526    pub comment: Option<Box<Expression>>,
10527    #[serde(default)]
10528    pub allow_null: Option<Box<Expression>>,
10529    #[serde(default)]
10530    pub visible: Option<Box<Expression>>,
10531    #[serde(default)]
10532    pub rename_to: Option<Box<Expression>>,
10533}
10534
10535/// AlterSortKey
10536#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10537#[cfg_attr(feature = "bindings", derive(TS))]
10538pub struct AlterSortKey {
10539    #[serde(default)]
10540    pub this: Option<Box<Expression>>,
10541    #[serde(default)]
10542    pub expressions: Vec<Expression>,
10543    #[serde(default)]
10544    pub compound: Option<Box<Expression>>,
10545}
10546
10547/// AlterSet
10548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10549#[cfg_attr(feature = "bindings", derive(TS))]
10550pub struct AlterSet {
10551    #[serde(default)]
10552    pub expressions: Vec<Expression>,
10553    #[serde(default)]
10554    pub option: Option<Box<Expression>>,
10555    #[serde(default)]
10556    pub tablespace: Option<Box<Expression>>,
10557    #[serde(default)]
10558    pub access_method: Option<Box<Expression>>,
10559    #[serde(default)]
10560    pub file_format: Option<Box<Expression>>,
10561    #[serde(default)]
10562    pub copy_options: Option<Box<Expression>>,
10563    #[serde(default)]
10564    pub tag: Option<Box<Expression>>,
10565    #[serde(default)]
10566    pub location: Option<Box<Expression>>,
10567    #[serde(default)]
10568    pub serde: Option<Box<Expression>>,
10569}
10570
10571/// RenameColumn
10572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10573#[cfg_attr(feature = "bindings", derive(TS))]
10574pub struct RenameColumn {
10575    pub this: Box<Expression>,
10576    #[serde(default)]
10577    pub to: Option<Box<Expression>>,
10578    #[serde(default)]
10579    pub exists: bool,
10580}
10581
10582/// Comprehension
10583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10584#[cfg_attr(feature = "bindings", derive(TS))]
10585pub struct Comprehension {
10586    pub this: Box<Expression>,
10587    pub expression: Box<Expression>,
10588    #[serde(default)]
10589    pub position: Option<Box<Expression>>,
10590    #[serde(default)]
10591    pub iterator: Option<Box<Expression>>,
10592    #[serde(default)]
10593    pub condition: Option<Box<Expression>>,
10594}
10595
10596/// MergeTreeTTLAction
10597#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10598#[cfg_attr(feature = "bindings", derive(TS))]
10599pub struct MergeTreeTTLAction {
10600    pub this: Box<Expression>,
10601    #[serde(default)]
10602    pub delete: Option<Box<Expression>>,
10603    #[serde(default)]
10604    pub recompress: Option<Box<Expression>>,
10605    #[serde(default)]
10606    pub to_disk: Option<Box<Expression>>,
10607    #[serde(default)]
10608    pub to_volume: Option<Box<Expression>>,
10609}
10610
10611/// MergeTreeTTL
10612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10613#[cfg_attr(feature = "bindings", derive(TS))]
10614pub struct MergeTreeTTL {
10615    #[serde(default)]
10616    pub expressions: Vec<Expression>,
10617    #[serde(default)]
10618    pub where_: Option<Box<Expression>>,
10619    #[serde(default)]
10620    pub group: Option<Box<Expression>>,
10621    #[serde(default)]
10622    pub aggregates: Option<Box<Expression>>,
10623}
10624
10625/// IndexConstraintOption
10626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10627#[cfg_attr(feature = "bindings", derive(TS))]
10628pub struct IndexConstraintOption {
10629    #[serde(default)]
10630    pub key_block_size: Option<Box<Expression>>,
10631    #[serde(default)]
10632    pub using: Option<Box<Expression>>,
10633    #[serde(default)]
10634    pub parser: Option<Box<Expression>>,
10635    #[serde(default)]
10636    pub comment: Option<Box<Expression>>,
10637    #[serde(default)]
10638    pub visible: Option<Box<Expression>>,
10639    #[serde(default)]
10640    pub engine_attr: Option<Box<Expression>>,
10641    #[serde(default)]
10642    pub secondary_engine_attr: Option<Box<Expression>>,
10643}
10644
10645/// PeriodForSystemTimeConstraint
10646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10647#[cfg_attr(feature = "bindings", derive(TS))]
10648pub struct PeriodForSystemTimeConstraint {
10649    pub this: Box<Expression>,
10650    pub expression: Box<Expression>,
10651}
10652
10653/// CaseSpecificColumnConstraint
10654#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10655#[cfg_attr(feature = "bindings", derive(TS))]
10656pub struct CaseSpecificColumnConstraint {
10657    #[serde(default)]
10658    pub not_: Option<Box<Expression>>,
10659}
10660
10661/// CharacterSetColumnConstraint
10662#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10663#[cfg_attr(feature = "bindings", derive(TS))]
10664pub struct CharacterSetColumnConstraint {
10665    pub this: Box<Expression>,
10666}
10667
10668/// CheckColumnConstraint
10669#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10670#[cfg_attr(feature = "bindings", derive(TS))]
10671pub struct CheckColumnConstraint {
10672    pub this: Box<Expression>,
10673    #[serde(default)]
10674    pub enforced: Option<Box<Expression>>,
10675}
10676
10677/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
10678#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10679#[cfg_attr(feature = "bindings", derive(TS))]
10680pub struct AssumeColumnConstraint {
10681    pub this: Box<Expression>,
10682}
10683
10684/// CompressColumnConstraint
10685#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10686#[cfg_attr(feature = "bindings", derive(TS))]
10687pub struct CompressColumnConstraint {
10688    #[serde(default)]
10689    pub this: Option<Box<Expression>>,
10690}
10691
10692/// DateFormatColumnConstraint
10693#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10694#[cfg_attr(feature = "bindings", derive(TS))]
10695pub struct DateFormatColumnConstraint {
10696    pub this: Box<Expression>,
10697}
10698
10699/// EphemeralColumnConstraint
10700#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10701#[cfg_attr(feature = "bindings", derive(TS))]
10702pub struct EphemeralColumnConstraint {
10703    #[serde(default)]
10704    pub this: Option<Box<Expression>>,
10705}
10706
10707/// WithOperator
10708#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10709#[cfg_attr(feature = "bindings", derive(TS))]
10710pub struct WithOperator {
10711    pub this: Box<Expression>,
10712    pub op: String,
10713}
10714
10715/// GeneratedAsIdentityColumnConstraint
10716#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10717#[cfg_attr(feature = "bindings", derive(TS))]
10718pub struct GeneratedAsIdentityColumnConstraint {
10719    #[serde(default)]
10720    pub this: Option<Box<Expression>>,
10721    #[serde(default)]
10722    pub expression: Option<Box<Expression>>,
10723    #[serde(default)]
10724    pub on_null: Option<Box<Expression>>,
10725    #[serde(default)]
10726    pub start: Option<Box<Expression>>,
10727    #[serde(default)]
10728    pub increment: Option<Box<Expression>>,
10729    #[serde(default)]
10730    pub minvalue: Option<Box<Expression>>,
10731    #[serde(default)]
10732    pub maxvalue: Option<Box<Expression>>,
10733    #[serde(default)]
10734    pub cycle: Option<Box<Expression>>,
10735    #[serde(default)]
10736    pub order: Option<Box<Expression>>,
10737}
10738
10739/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
10740/// TSQL: outputs "IDENTITY"
10741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10742#[cfg_attr(feature = "bindings", derive(TS))]
10743pub struct AutoIncrementColumnConstraint;
10744
10745/// CommentColumnConstraint - Column comment marker
10746#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10747#[cfg_attr(feature = "bindings", derive(TS))]
10748pub struct CommentColumnConstraint;
10749
10750/// GeneratedAsRowColumnConstraint
10751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10752#[cfg_attr(feature = "bindings", derive(TS))]
10753pub struct GeneratedAsRowColumnConstraint {
10754    #[serde(default)]
10755    pub start: Option<Box<Expression>>,
10756    #[serde(default)]
10757    pub hidden: Option<Box<Expression>>,
10758}
10759
10760/// IndexColumnConstraint
10761#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10762#[cfg_attr(feature = "bindings", derive(TS))]
10763pub struct IndexColumnConstraint {
10764    #[serde(default)]
10765    pub this: Option<Box<Expression>>,
10766    #[serde(default)]
10767    pub expressions: Vec<Expression>,
10768    #[serde(default)]
10769    pub kind: Option<String>,
10770    #[serde(default)]
10771    pub index_type: Option<Box<Expression>>,
10772    #[serde(default)]
10773    pub options: Vec<Expression>,
10774    #[serde(default)]
10775    pub expression: Option<Box<Expression>>,
10776    #[serde(default)]
10777    pub granularity: Option<Box<Expression>>,
10778}
10779
10780/// MaskingPolicyColumnConstraint
10781#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10782#[cfg_attr(feature = "bindings", derive(TS))]
10783pub struct MaskingPolicyColumnConstraint {
10784    pub this: Box<Expression>,
10785    #[serde(default)]
10786    pub expressions: Vec<Expression>,
10787}
10788
10789/// NotNullColumnConstraint
10790#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10791#[cfg_attr(feature = "bindings", derive(TS))]
10792pub struct NotNullColumnConstraint {
10793    #[serde(default)]
10794    pub allow_null: Option<Box<Expression>>,
10795}
10796
10797/// DefaultColumnConstraint - DEFAULT value for a column
10798#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10799#[cfg_attr(feature = "bindings", derive(TS))]
10800pub struct DefaultColumnConstraint {
10801    pub this: Box<Expression>,
10802    /// TSQL: DEFAULT value FOR column (table-level default constraint)
10803    #[serde(default, skip_serializing_if = "Option::is_none")]
10804    pub for_column: Option<Identifier>,
10805}
10806
10807/// PrimaryKeyColumnConstraint
10808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10809#[cfg_attr(feature = "bindings", derive(TS))]
10810pub struct PrimaryKeyColumnConstraint {
10811    #[serde(default)]
10812    pub desc: Option<Box<Expression>>,
10813    #[serde(default)]
10814    pub options: Vec<Expression>,
10815}
10816
10817/// UniqueColumnConstraint
10818#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10819#[cfg_attr(feature = "bindings", derive(TS))]
10820pub struct UniqueColumnConstraint {
10821    #[serde(default)]
10822    pub this: Option<Box<Expression>>,
10823    #[serde(default)]
10824    pub index_type: Option<Box<Expression>>,
10825    #[serde(default)]
10826    pub on_conflict: Option<Box<Expression>>,
10827    #[serde(default)]
10828    pub nulls: Option<Box<Expression>>,
10829    #[serde(default)]
10830    pub options: Vec<Expression>,
10831}
10832
10833/// WatermarkColumnConstraint
10834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10835#[cfg_attr(feature = "bindings", derive(TS))]
10836pub struct WatermarkColumnConstraint {
10837    pub this: Box<Expression>,
10838    pub expression: Box<Expression>,
10839}
10840
10841/// ComputedColumnConstraint
10842#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10843#[cfg_attr(feature = "bindings", derive(TS))]
10844pub struct ComputedColumnConstraint {
10845    pub this: Box<Expression>,
10846    #[serde(default)]
10847    pub persisted: Option<Box<Expression>>,
10848    #[serde(default)]
10849    pub not_null: Option<Box<Expression>>,
10850    #[serde(default)]
10851    pub data_type: Option<Box<Expression>>,
10852}
10853
10854/// InOutColumnConstraint
10855#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10856#[cfg_attr(feature = "bindings", derive(TS))]
10857pub struct InOutColumnConstraint {
10858    #[serde(default)]
10859    pub input_: Option<Box<Expression>>,
10860    #[serde(default)]
10861    pub output: Option<Box<Expression>>,
10862}
10863
10864/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
10865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10866#[cfg_attr(feature = "bindings", derive(TS))]
10867pub struct PathColumnConstraint {
10868    pub this: Box<Expression>,
10869}
10870
10871/// Constraint
10872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10873#[cfg_attr(feature = "bindings", derive(TS))]
10874pub struct Constraint {
10875    pub this: Box<Expression>,
10876    #[serde(default)]
10877    pub expressions: Vec<Expression>,
10878}
10879
10880/// Export
10881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10882#[cfg_attr(feature = "bindings", derive(TS))]
10883pub struct Export {
10884    pub this: Box<Expression>,
10885    #[serde(default)]
10886    pub connection: Option<Box<Expression>>,
10887    #[serde(default)]
10888    pub options: Vec<Expression>,
10889}
10890
10891/// Filter
10892#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10893#[cfg_attr(feature = "bindings", derive(TS))]
10894pub struct Filter {
10895    pub this: Box<Expression>,
10896    pub expression: Box<Expression>,
10897}
10898
10899/// Changes
10900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10901#[cfg_attr(feature = "bindings", derive(TS))]
10902pub struct Changes {
10903    #[serde(default)]
10904    pub information: Option<Box<Expression>>,
10905    #[serde(default)]
10906    pub at_before: Option<Box<Expression>>,
10907    #[serde(default)]
10908    pub end: Option<Box<Expression>>,
10909}
10910
10911/// Directory
10912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10913#[cfg_attr(feature = "bindings", derive(TS))]
10914pub struct Directory {
10915    pub this: Box<Expression>,
10916    #[serde(default)]
10917    pub local: Option<Box<Expression>>,
10918    #[serde(default)]
10919    pub row_format: Option<Box<Expression>>,
10920}
10921
10922/// ForeignKey
10923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10924#[cfg_attr(feature = "bindings", derive(TS))]
10925pub struct ForeignKey {
10926    #[serde(default)]
10927    pub expressions: Vec<Expression>,
10928    #[serde(default)]
10929    pub reference: Option<Box<Expression>>,
10930    #[serde(default)]
10931    pub delete: Option<Box<Expression>>,
10932    #[serde(default)]
10933    pub update: Option<Box<Expression>>,
10934    #[serde(default)]
10935    pub options: Vec<Expression>,
10936}
10937
10938/// ColumnPrefix
10939#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10940#[cfg_attr(feature = "bindings", derive(TS))]
10941pub struct ColumnPrefix {
10942    pub this: Box<Expression>,
10943    pub expression: Box<Expression>,
10944}
10945
10946/// PrimaryKey
10947#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10948#[cfg_attr(feature = "bindings", derive(TS))]
10949pub struct PrimaryKey {
10950    #[serde(default)]
10951    pub this: Option<Box<Expression>>,
10952    #[serde(default)]
10953    pub expressions: Vec<Expression>,
10954    #[serde(default)]
10955    pub options: Vec<Expression>,
10956    #[serde(default)]
10957    pub include: Option<Box<Expression>>,
10958}
10959
10960/// Into
10961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10962#[cfg_attr(feature = "bindings", derive(TS))]
10963pub struct IntoClause {
10964    #[serde(default)]
10965    pub this: Option<Box<Expression>>,
10966    #[serde(default)]
10967    pub temporary: bool,
10968    #[serde(default)]
10969    pub unlogged: Option<Box<Expression>>,
10970    #[serde(default)]
10971    pub bulk_collect: Option<Box<Expression>>,
10972    #[serde(default)]
10973    pub expressions: Vec<Expression>,
10974}
10975
10976/// JoinHint
10977#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10978#[cfg_attr(feature = "bindings", derive(TS))]
10979pub struct JoinHint {
10980    pub this: Box<Expression>,
10981    #[serde(default)]
10982    pub expressions: Vec<Expression>,
10983}
10984
10985/// Opclass
10986#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10987#[cfg_attr(feature = "bindings", derive(TS))]
10988pub struct Opclass {
10989    pub this: Box<Expression>,
10990    pub expression: Box<Expression>,
10991}
10992
10993/// Index
10994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10995#[cfg_attr(feature = "bindings", derive(TS))]
10996pub struct Index {
10997    #[serde(default)]
10998    pub this: Option<Box<Expression>>,
10999    #[serde(default)]
11000    pub table: Option<Box<Expression>>,
11001    #[serde(default)]
11002    pub unique: bool,
11003    #[serde(default)]
11004    pub primary: Option<Box<Expression>>,
11005    #[serde(default)]
11006    pub amp: Option<Box<Expression>>,
11007    #[serde(default)]
11008    pub params: Vec<Expression>,
11009}
11010
11011/// IndexParameters
11012#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11013#[cfg_attr(feature = "bindings", derive(TS))]
11014pub struct IndexParameters {
11015    #[serde(default)]
11016    pub using: Option<Box<Expression>>,
11017    #[serde(default)]
11018    pub include: Option<Box<Expression>>,
11019    #[serde(default)]
11020    pub columns: Vec<Expression>,
11021    #[serde(default)]
11022    pub with_storage: Option<Box<Expression>>,
11023    #[serde(default)]
11024    pub partition_by: Option<Box<Expression>>,
11025    #[serde(default)]
11026    pub tablespace: Option<Box<Expression>>,
11027    #[serde(default)]
11028    pub where_: Option<Box<Expression>>,
11029    #[serde(default)]
11030    pub on: Option<Box<Expression>>,
11031}
11032
11033/// ConditionalInsert
11034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11035#[cfg_attr(feature = "bindings", derive(TS))]
11036pub struct ConditionalInsert {
11037    pub this: Box<Expression>,
11038    #[serde(default)]
11039    pub expression: Option<Box<Expression>>,
11040    #[serde(default)]
11041    pub else_: Option<Box<Expression>>,
11042}
11043
11044/// MultitableInserts
11045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11046#[cfg_attr(feature = "bindings", derive(TS))]
11047pub struct MultitableInserts {
11048    #[serde(default)]
11049    pub expressions: Vec<Expression>,
11050    pub kind: String,
11051    #[serde(default)]
11052    pub source: Option<Box<Expression>>,
11053    /// Leading comments before the statement
11054    #[serde(default)]
11055    pub leading_comments: Vec<String>,
11056    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
11057    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11058    pub overwrite: bool,
11059}
11060
11061/// OnConflict
11062#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11063#[cfg_attr(feature = "bindings", derive(TS))]
11064pub struct OnConflict {
11065    #[serde(default)]
11066    pub duplicate: Option<Box<Expression>>,
11067    #[serde(default)]
11068    pub expressions: Vec<Expression>,
11069    #[serde(default)]
11070    pub action: Option<Box<Expression>>,
11071    #[serde(default)]
11072    pub conflict_keys: Option<Box<Expression>>,
11073    #[serde(default)]
11074    pub index_predicate: Option<Box<Expression>>,
11075    #[serde(default)]
11076    pub constraint: Option<Box<Expression>>,
11077    #[serde(default)]
11078    pub where_: Option<Box<Expression>>,
11079}
11080
11081/// OnCondition
11082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11083#[cfg_attr(feature = "bindings", derive(TS))]
11084pub struct OnCondition {
11085    #[serde(default)]
11086    pub error: Option<Box<Expression>>,
11087    #[serde(default)]
11088    pub empty: Option<Box<Expression>>,
11089    #[serde(default)]
11090    pub null: Option<Box<Expression>>,
11091}
11092
11093/// Returning
11094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11095#[cfg_attr(feature = "bindings", derive(TS))]
11096pub struct Returning {
11097    #[serde(default)]
11098    pub expressions: Vec<Expression>,
11099    #[serde(default)]
11100    pub into: Option<Box<Expression>>,
11101}
11102
11103/// Introducer
11104#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11105#[cfg_attr(feature = "bindings", derive(TS))]
11106pub struct Introducer {
11107    pub this: Box<Expression>,
11108    pub expression: Box<Expression>,
11109}
11110
11111/// PartitionRange
11112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11113#[cfg_attr(feature = "bindings", derive(TS))]
11114pub struct PartitionRange {
11115    pub this: Box<Expression>,
11116    #[serde(default)]
11117    pub expression: Option<Box<Expression>>,
11118    #[serde(default)]
11119    pub expressions: Vec<Expression>,
11120}
11121
11122/// Group
11123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11124#[cfg_attr(feature = "bindings", derive(TS))]
11125pub struct Group {
11126    #[serde(default)]
11127    pub expressions: Vec<Expression>,
11128    #[serde(default)]
11129    pub grouping_sets: Option<Box<Expression>>,
11130    #[serde(default)]
11131    pub cube: Option<Box<Expression>>,
11132    #[serde(default)]
11133    pub rollup: Option<Box<Expression>>,
11134    #[serde(default)]
11135    pub totals: Option<Box<Expression>>,
11136    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11137    #[serde(default)]
11138    pub all: Option<bool>,
11139}
11140
11141/// Cube
11142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11143#[cfg_attr(feature = "bindings", derive(TS))]
11144pub struct Cube {
11145    #[serde(default)]
11146    pub expressions: Vec<Expression>,
11147}
11148
11149/// Rollup
11150#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11151#[cfg_attr(feature = "bindings", derive(TS))]
11152pub struct Rollup {
11153    #[serde(default)]
11154    pub expressions: Vec<Expression>,
11155}
11156
11157/// GroupingSets
11158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11159#[cfg_attr(feature = "bindings", derive(TS))]
11160pub struct GroupingSets {
11161    #[serde(default)]
11162    pub expressions: Vec<Expression>,
11163}
11164
11165/// LimitOptions
11166#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11167#[cfg_attr(feature = "bindings", derive(TS))]
11168pub struct LimitOptions {
11169    #[serde(default)]
11170    pub percent: Option<Box<Expression>>,
11171    #[serde(default)]
11172    pub rows: Option<Box<Expression>>,
11173    #[serde(default)]
11174    pub with_ties: Option<Box<Expression>>,
11175}
11176
11177/// Lateral
11178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11179#[cfg_attr(feature = "bindings", derive(TS))]
11180pub struct Lateral {
11181    pub this: Box<Expression>,
11182    #[serde(default)]
11183    pub view: Option<Box<Expression>>,
11184    #[serde(default)]
11185    pub outer: Option<Box<Expression>>,
11186    #[serde(default)]
11187    pub alias: Option<String>,
11188    /// Whether the alias was originally quoted (backtick/double-quote)
11189    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11190    pub alias_quoted: bool,
11191    #[serde(default)]
11192    pub cross_apply: Option<Box<Expression>>,
11193    #[serde(default)]
11194    pub ordinality: Option<Box<Expression>>,
11195    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11196    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11197    pub column_aliases: Vec<String>,
11198}
11199
11200/// TableFromRows
11201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11202#[cfg_attr(feature = "bindings", derive(TS))]
11203pub struct TableFromRows {
11204    pub this: Box<Expression>,
11205    #[serde(default)]
11206    pub alias: Option<String>,
11207    #[serde(default)]
11208    pub joins: Vec<Expression>,
11209    #[serde(default)]
11210    pub pivots: Option<Box<Expression>>,
11211    #[serde(default)]
11212    pub sample: Option<Box<Expression>>,
11213}
11214
11215/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11216/// Used for set-returning functions with typed column definitions
11217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11218#[cfg_attr(feature = "bindings", derive(TS))]
11219pub struct RowsFrom {
11220    /// List of function expressions, each potentially with an alias and typed columns
11221    pub expressions: Vec<Expression>,
11222    /// WITH ORDINALITY modifier
11223    #[serde(default)]
11224    pub ordinality: bool,
11225    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11226    #[serde(default)]
11227    pub alias: Option<Box<Expression>>,
11228}
11229
11230/// WithFill
11231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11232#[cfg_attr(feature = "bindings", derive(TS))]
11233pub struct WithFill {
11234    #[serde(default)]
11235    pub from_: Option<Box<Expression>>,
11236    #[serde(default)]
11237    pub to: Option<Box<Expression>>,
11238    #[serde(default)]
11239    pub step: Option<Box<Expression>>,
11240    #[serde(default)]
11241    pub staleness: Option<Box<Expression>>,
11242    #[serde(default)]
11243    pub interpolate: Option<Box<Expression>>,
11244}
11245
11246/// Property
11247#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11248#[cfg_attr(feature = "bindings", derive(TS))]
11249pub struct Property {
11250    pub this: Box<Expression>,
11251    #[serde(default)]
11252    pub value: Option<Box<Expression>>,
11253}
11254
11255/// GrantPrivilege
11256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11257#[cfg_attr(feature = "bindings", derive(TS))]
11258pub struct GrantPrivilege {
11259    pub this: Box<Expression>,
11260    #[serde(default)]
11261    pub expressions: Vec<Expression>,
11262}
11263
11264/// AllowedValuesProperty
11265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11266#[cfg_attr(feature = "bindings", derive(TS))]
11267pub struct AllowedValuesProperty {
11268    #[serde(default)]
11269    pub expressions: Vec<Expression>,
11270}
11271
11272/// AlgorithmProperty
11273#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11274#[cfg_attr(feature = "bindings", derive(TS))]
11275pub struct AlgorithmProperty {
11276    pub this: Box<Expression>,
11277}
11278
11279/// AutoIncrementProperty
11280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11281#[cfg_attr(feature = "bindings", derive(TS))]
11282pub struct AutoIncrementProperty {
11283    pub this: Box<Expression>,
11284}
11285
11286/// AutoRefreshProperty
11287#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11288#[cfg_attr(feature = "bindings", derive(TS))]
11289pub struct AutoRefreshProperty {
11290    pub this: Box<Expression>,
11291}
11292
11293/// BackupProperty
11294#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11295#[cfg_attr(feature = "bindings", derive(TS))]
11296pub struct BackupProperty {
11297    pub this: Box<Expression>,
11298}
11299
11300/// BuildProperty
11301#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11302#[cfg_attr(feature = "bindings", derive(TS))]
11303pub struct BuildProperty {
11304    pub this: Box<Expression>,
11305}
11306
11307/// BlockCompressionProperty
11308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11309#[cfg_attr(feature = "bindings", derive(TS))]
11310pub struct BlockCompressionProperty {
11311    #[serde(default)]
11312    pub autotemp: Option<Box<Expression>>,
11313    #[serde(default)]
11314    pub always: Option<Box<Expression>>,
11315    #[serde(default)]
11316    pub default: Option<Box<Expression>>,
11317    #[serde(default)]
11318    pub manual: Option<Box<Expression>>,
11319    #[serde(default)]
11320    pub never: Option<Box<Expression>>,
11321}
11322
11323/// CharacterSetProperty
11324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11325#[cfg_attr(feature = "bindings", derive(TS))]
11326pub struct CharacterSetProperty {
11327    pub this: Box<Expression>,
11328    #[serde(default)]
11329    pub default: Option<Box<Expression>>,
11330}
11331
11332/// ChecksumProperty
11333#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11334#[cfg_attr(feature = "bindings", derive(TS))]
11335pub struct ChecksumProperty {
11336    #[serde(default)]
11337    pub on: Option<Box<Expression>>,
11338    #[serde(default)]
11339    pub default: Option<Box<Expression>>,
11340}
11341
11342/// CollateProperty
11343#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11344#[cfg_attr(feature = "bindings", derive(TS))]
11345pub struct CollateProperty {
11346    pub this: Box<Expression>,
11347    #[serde(default)]
11348    pub default: Option<Box<Expression>>,
11349}
11350
11351/// DataBlocksizeProperty
11352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11353#[cfg_attr(feature = "bindings", derive(TS))]
11354pub struct DataBlocksizeProperty {
11355    #[serde(default)]
11356    pub size: Option<i64>,
11357    #[serde(default)]
11358    pub units: Option<Box<Expression>>,
11359    #[serde(default)]
11360    pub minimum: Option<Box<Expression>>,
11361    #[serde(default)]
11362    pub maximum: Option<Box<Expression>>,
11363    #[serde(default)]
11364    pub default: Option<Box<Expression>>,
11365}
11366
11367/// DataDeletionProperty
11368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11369#[cfg_attr(feature = "bindings", derive(TS))]
11370pub struct DataDeletionProperty {
11371    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11372    #[ast(skip)]
11373    pub on: Box<Expression>,
11374    #[serde(default)]
11375    pub filter_column: Option<Box<Expression>>,
11376    #[serde(default)]
11377    pub retention_period: Option<Box<Expression>>,
11378}
11379
11380/// DefinerProperty
11381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11382#[cfg_attr(feature = "bindings", derive(TS))]
11383pub struct DefinerProperty {
11384    pub this: Box<Expression>,
11385}
11386
11387/// DistKeyProperty
11388#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11389#[cfg_attr(feature = "bindings", derive(TS))]
11390pub struct DistKeyProperty {
11391    pub this: Box<Expression>,
11392}
11393
11394/// DistributedByProperty
11395#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11396#[cfg_attr(feature = "bindings", derive(TS))]
11397pub struct DistributedByProperty {
11398    #[serde(default)]
11399    pub expressions: Vec<Expression>,
11400    pub kind: String,
11401    #[serde(default)]
11402    pub buckets: Option<Box<Expression>>,
11403    #[serde(default)]
11404    pub order: Option<Box<Expression>>,
11405}
11406
11407/// DistStyleProperty
11408#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11409#[cfg_attr(feature = "bindings", derive(TS))]
11410pub struct DistStyleProperty {
11411    pub this: Box<Expression>,
11412}
11413
11414/// DuplicateKeyProperty
11415#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11416#[cfg_attr(feature = "bindings", derive(TS))]
11417pub struct DuplicateKeyProperty {
11418    #[serde(default)]
11419    pub expressions: Vec<Expression>,
11420}
11421
11422/// EngineProperty
11423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11424#[cfg_attr(feature = "bindings", derive(TS))]
11425pub struct EngineProperty {
11426    pub this: Box<Expression>,
11427}
11428
11429/// ToTableProperty
11430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11431#[cfg_attr(feature = "bindings", derive(TS))]
11432pub struct ToTableProperty {
11433    pub this: Box<Expression>,
11434}
11435
11436/// ExecuteAsProperty
11437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11438#[cfg_attr(feature = "bindings", derive(TS))]
11439pub struct ExecuteAsProperty {
11440    pub this: Box<Expression>,
11441}
11442
11443/// ExternalProperty
11444#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11445#[cfg_attr(feature = "bindings", derive(TS))]
11446pub struct ExternalProperty {
11447    #[serde(default)]
11448    pub this: Option<Box<Expression>>,
11449}
11450
11451/// FallbackProperty
11452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11453#[cfg_attr(feature = "bindings", derive(TS))]
11454pub struct FallbackProperty {
11455    #[serde(default)]
11456    pub no: Option<Box<Expression>>,
11457    #[serde(default)]
11458    pub protection: Option<Box<Expression>>,
11459}
11460
11461/// FileFormatProperty
11462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11463#[cfg_attr(feature = "bindings", derive(TS))]
11464pub struct FileFormatProperty {
11465    #[serde(default)]
11466    pub this: Option<Box<Expression>>,
11467    #[serde(default)]
11468    pub expressions: Vec<Expression>,
11469    #[serde(default)]
11470    pub hive_format: Option<Box<Expression>>,
11471}
11472
11473/// CredentialsProperty
11474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11475#[cfg_attr(feature = "bindings", derive(TS))]
11476pub struct CredentialsProperty {
11477    #[serde(default)]
11478    pub expressions: Vec<Expression>,
11479}
11480
11481/// FreespaceProperty
11482#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11483#[cfg_attr(feature = "bindings", derive(TS))]
11484pub struct FreespaceProperty {
11485    pub this: Box<Expression>,
11486    #[serde(default)]
11487    pub percent: Option<Box<Expression>>,
11488}
11489
11490/// InheritsProperty
11491#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11492#[cfg_attr(feature = "bindings", derive(TS))]
11493pub struct InheritsProperty {
11494    #[serde(default)]
11495    pub expressions: Vec<Expression>,
11496}
11497
11498/// InputModelProperty
11499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11500#[cfg_attr(feature = "bindings", derive(TS))]
11501pub struct InputModelProperty {
11502    pub this: Box<Expression>,
11503}
11504
11505/// OutputModelProperty
11506#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11507#[cfg_attr(feature = "bindings", derive(TS))]
11508pub struct OutputModelProperty {
11509    pub this: Box<Expression>,
11510}
11511
11512/// IsolatedLoadingProperty
11513#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11514#[cfg_attr(feature = "bindings", derive(TS))]
11515pub struct IsolatedLoadingProperty {
11516    #[serde(default)]
11517    pub no: Option<Box<Expression>>,
11518    #[serde(default)]
11519    pub concurrent: Option<Box<Expression>>,
11520    #[serde(default)]
11521    pub target: Option<Box<Expression>>,
11522}
11523
11524/// JournalProperty
11525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11526#[cfg_attr(feature = "bindings", derive(TS))]
11527pub struct JournalProperty {
11528    #[serde(default)]
11529    pub no: Option<Box<Expression>>,
11530    #[serde(default)]
11531    pub dual: Option<Box<Expression>>,
11532    #[serde(default)]
11533    pub before: Option<Box<Expression>>,
11534    #[serde(default)]
11535    pub local: Option<Box<Expression>>,
11536    #[serde(default)]
11537    pub after: Option<Box<Expression>>,
11538}
11539
11540/// LanguageProperty
11541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11542#[cfg_attr(feature = "bindings", derive(TS))]
11543pub struct LanguageProperty {
11544    pub this: Box<Expression>,
11545}
11546
11547/// EnviromentProperty
11548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11549#[cfg_attr(feature = "bindings", derive(TS))]
11550pub struct EnviromentProperty {
11551    #[serde(default)]
11552    pub expressions: Vec<Expression>,
11553}
11554
11555/// ClusteredByProperty
11556#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11557#[cfg_attr(feature = "bindings", derive(TS))]
11558pub struct ClusteredByProperty {
11559    #[serde(default)]
11560    pub expressions: Vec<Expression>,
11561    #[serde(default)]
11562    pub sorted_by: Option<Box<Expression>>,
11563    #[serde(default)]
11564    pub buckets: Option<Box<Expression>>,
11565}
11566
11567/// DictProperty
11568#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11569#[cfg_attr(feature = "bindings", derive(TS))]
11570pub struct DictProperty {
11571    pub this: Box<Expression>,
11572    pub kind: String,
11573    #[serde(default)]
11574    pub settings: Option<Box<Expression>>,
11575}
11576
11577/// DictRange
11578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11579#[cfg_attr(feature = "bindings", derive(TS))]
11580pub struct DictRange {
11581    pub this: Box<Expression>,
11582    #[serde(default)]
11583    pub min: Option<Box<Expression>>,
11584    #[serde(default)]
11585    pub max: Option<Box<Expression>>,
11586}
11587
11588/// OnCluster
11589#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11590#[cfg_attr(feature = "bindings", derive(TS))]
11591pub struct OnCluster {
11592    pub this: Box<Expression>,
11593}
11594
11595/// LikeProperty
11596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11597#[cfg_attr(feature = "bindings", derive(TS))]
11598pub struct LikeProperty {
11599    pub this: Box<Expression>,
11600    #[serde(default)]
11601    pub expressions: Vec<Expression>,
11602}
11603
11604/// LocationProperty
11605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11606#[cfg_attr(feature = "bindings", derive(TS))]
11607pub struct LocationProperty {
11608    pub this: Box<Expression>,
11609}
11610
11611/// LockProperty
11612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11613#[cfg_attr(feature = "bindings", derive(TS))]
11614pub struct LockProperty {
11615    pub this: Box<Expression>,
11616}
11617
11618/// LockingProperty
11619#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11620#[cfg_attr(feature = "bindings", derive(TS))]
11621pub struct LockingProperty {
11622    #[serde(default)]
11623    pub this: Option<Box<Expression>>,
11624    pub kind: String,
11625    #[serde(default)]
11626    pub for_or_in: Option<Box<Expression>>,
11627    #[serde(default)]
11628    pub lock_type: Option<Box<Expression>>,
11629    #[serde(default)]
11630    pub override_: Option<Box<Expression>>,
11631}
11632
11633/// LogProperty
11634#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11635#[cfg_attr(feature = "bindings", derive(TS))]
11636pub struct LogProperty {
11637    #[serde(default)]
11638    pub no: Option<Box<Expression>>,
11639}
11640
11641/// MaterializedProperty
11642#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11643#[cfg_attr(feature = "bindings", derive(TS))]
11644pub struct MaterializedProperty {
11645    #[serde(default)]
11646    pub this: Option<Box<Expression>>,
11647}
11648
11649/// MergeBlockRatioProperty
11650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11651#[cfg_attr(feature = "bindings", derive(TS))]
11652pub struct MergeBlockRatioProperty {
11653    #[serde(default)]
11654    pub this: Option<Box<Expression>>,
11655    #[serde(default)]
11656    pub no: Option<Box<Expression>>,
11657    #[serde(default)]
11658    pub default: Option<Box<Expression>>,
11659    #[serde(default)]
11660    pub percent: Option<Box<Expression>>,
11661}
11662
11663/// OnProperty
11664#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11665#[cfg_attr(feature = "bindings", derive(TS))]
11666pub struct OnProperty {
11667    pub this: Box<Expression>,
11668}
11669
11670/// OnCommitProperty
11671#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11672#[cfg_attr(feature = "bindings", derive(TS))]
11673pub struct OnCommitProperty {
11674    #[serde(default)]
11675    pub delete: Option<Box<Expression>>,
11676}
11677
11678/// PartitionedByProperty
11679#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11680#[cfg_attr(feature = "bindings", derive(TS))]
11681pub struct PartitionedByProperty {
11682    pub this: Box<Expression>,
11683}
11684
11685/// BigQuery PARTITION BY property in CREATE TABLE statements.
11686#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11687#[cfg_attr(feature = "bindings", derive(TS))]
11688pub struct PartitionByProperty {
11689    #[serde(default)]
11690    pub expressions: Vec<Expression>,
11691}
11692
11693/// PartitionedByBucket
11694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11695#[cfg_attr(feature = "bindings", derive(TS))]
11696pub struct PartitionedByBucket {
11697    pub this: Box<Expression>,
11698    pub expression: Box<Expression>,
11699}
11700
11701/// BigQuery CLUSTER BY property in CREATE TABLE statements.
11702#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11703#[cfg_attr(feature = "bindings", derive(TS))]
11704pub struct ClusterByColumnsProperty {
11705    #[serde(default)]
11706    pub columns: Vec<Identifier>,
11707}
11708
11709/// PartitionByTruncate
11710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11711#[cfg_attr(feature = "bindings", derive(TS))]
11712pub struct PartitionByTruncate {
11713    pub this: Box<Expression>,
11714    pub expression: Box<Expression>,
11715}
11716
11717/// PartitionByRangeProperty
11718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11719#[cfg_attr(feature = "bindings", derive(TS))]
11720pub struct PartitionByRangeProperty {
11721    #[serde(default)]
11722    pub partition_expressions: Option<Box<Expression>>,
11723    #[serde(default)]
11724    pub create_expressions: Option<Box<Expression>>,
11725}
11726
11727/// PartitionByRangePropertyDynamic
11728#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11729#[cfg_attr(feature = "bindings", derive(TS))]
11730pub struct PartitionByRangePropertyDynamic {
11731    #[serde(default)]
11732    pub this: Option<Box<Expression>>,
11733    #[serde(default)]
11734    pub start: Option<Box<Expression>>,
11735    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
11736    #[serde(default)]
11737    pub use_start_end: bool,
11738    #[serde(default)]
11739    pub end: Option<Box<Expression>>,
11740    #[serde(default)]
11741    pub every: Option<Box<Expression>>,
11742}
11743
11744/// PartitionByListProperty
11745#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11746#[cfg_attr(feature = "bindings", derive(TS))]
11747pub struct PartitionByListProperty {
11748    #[serde(default)]
11749    pub partition_expressions: Option<Box<Expression>>,
11750    #[serde(default)]
11751    pub create_expressions: Option<Box<Expression>>,
11752}
11753
11754/// PartitionList
11755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11756#[cfg_attr(feature = "bindings", derive(TS))]
11757pub struct PartitionList {
11758    pub this: Box<Expression>,
11759    #[serde(default)]
11760    pub expressions: Vec<Expression>,
11761}
11762
11763/// Partition - represents PARTITION/SUBPARTITION clause
11764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11765#[cfg_attr(feature = "bindings", derive(TS))]
11766pub struct Partition {
11767    pub expressions: Vec<Expression>,
11768    #[serde(default)]
11769    pub subpartition: bool,
11770}
11771
11772/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
11773/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
11774#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11775#[cfg_attr(feature = "bindings", derive(TS))]
11776pub struct RefreshTriggerProperty {
11777    /// Method: COMPLETE or AUTO
11778    pub method: String,
11779    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
11780    #[serde(default)]
11781    pub kind: Option<String>,
11782    /// For SCHEDULE: EVERY n (the number)
11783    #[serde(default)]
11784    pub every: Option<Box<Expression>>,
11785    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
11786    #[serde(default)]
11787    pub unit: Option<String>,
11788    /// For SCHEDULE: STARTS 'datetime'
11789    #[serde(default)]
11790    pub starts: Option<Box<Expression>>,
11791}
11792
11793/// UniqueKeyProperty
11794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11795#[cfg_attr(feature = "bindings", derive(TS))]
11796pub struct UniqueKeyProperty {
11797    #[serde(default)]
11798    pub expressions: Vec<Expression>,
11799}
11800
11801/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
11802#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11803#[cfg_attr(feature = "bindings", derive(TS))]
11804pub struct RollupProperty {
11805    pub expressions: Vec<RollupIndex>,
11806}
11807
11808/// RollupIndex - A single rollup index: name(col1, col2)
11809#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11810#[cfg_attr(feature = "bindings", derive(TS))]
11811pub struct RollupIndex {
11812    pub name: Identifier,
11813    pub expressions: Vec<Identifier>,
11814}
11815
11816/// PartitionBoundSpec
11817#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11818#[cfg_attr(feature = "bindings", derive(TS))]
11819pub struct PartitionBoundSpec {
11820    #[serde(default)]
11821    pub this: Option<Box<Expression>>,
11822    #[serde(default)]
11823    pub expression: Option<Box<Expression>>,
11824    #[serde(default)]
11825    pub from_expressions: Option<Box<Expression>>,
11826    #[serde(default)]
11827    pub to_expressions: Option<Box<Expression>>,
11828}
11829
11830/// PartitionedOfProperty
11831#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11832#[cfg_attr(feature = "bindings", derive(TS))]
11833pub struct PartitionedOfProperty {
11834    pub this: Box<Expression>,
11835    pub expression: Box<Expression>,
11836}
11837
11838/// RemoteWithConnectionModelProperty
11839#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11840#[cfg_attr(feature = "bindings", derive(TS))]
11841pub struct RemoteWithConnectionModelProperty {
11842    pub this: Box<Expression>,
11843}
11844
11845/// ReturnsProperty
11846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11847#[cfg_attr(feature = "bindings", derive(TS))]
11848pub struct ReturnsProperty {
11849    #[serde(default)]
11850    pub this: Option<Box<Expression>>,
11851    #[serde(default)]
11852    pub is_table: Option<Box<Expression>>,
11853    #[serde(default)]
11854    pub table: Option<Box<Expression>>,
11855    #[serde(default)]
11856    pub null: Option<Box<Expression>>,
11857}
11858
11859/// RowFormatProperty
11860#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11861#[cfg_attr(feature = "bindings", derive(TS))]
11862pub struct RowFormatProperty {
11863    pub this: Box<Expression>,
11864}
11865
11866/// RowFormatDelimitedProperty
11867#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11868#[cfg_attr(feature = "bindings", derive(TS))]
11869pub struct RowFormatDelimitedProperty {
11870    #[serde(default)]
11871    pub fields: Option<Box<Expression>>,
11872    #[serde(default)]
11873    pub escaped: Option<Box<Expression>>,
11874    #[serde(default)]
11875    pub collection_items: Option<Box<Expression>>,
11876    #[serde(default)]
11877    pub map_keys: Option<Box<Expression>>,
11878    #[serde(default)]
11879    pub lines: Option<Box<Expression>>,
11880    #[serde(default)]
11881    pub null: Option<Box<Expression>>,
11882    #[serde(default)]
11883    pub serde: Option<Box<Expression>>,
11884}
11885
11886/// RowFormatSerdeProperty
11887#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11888#[cfg_attr(feature = "bindings", derive(TS))]
11889pub struct RowFormatSerdeProperty {
11890    pub this: Box<Expression>,
11891    #[serde(default)]
11892    pub serde_properties: Option<Box<Expression>>,
11893}
11894
11895/// QueryTransform
11896#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11897#[cfg_attr(feature = "bindings", derive(TS))]
11898pub struct QueryTransform {
11899    #[serde(default)]
11900    pub expressions: Vec<Expression>,
11901    #[serde(default)]
11902    pub command_script: Option<Box<Expression>>,
11903    #[serde(default)]
11904    pub schema: Option<Box<Expression>>,
11905    #[serde(default)]
11906    pub row_format_before: Option<Box<Expression>>,
11907    #[serde(default)]
11908    pub record_writer: Option<Box<Expression>>,
11909    #[serde(default)]
11910    pub row_format_after: Option<Box<Expression>>,
11911    #[serde(default)]
11912    pub record_reader: Option<Box<Expression>>,
11913}
11914
11915/// SampleProperty
11916#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11917#[cfg_attr(feature = "bindings", derive(TS))]
11918pub struct SampleProperty {
11919    pub this: Box<Expression>,
11920}
11921
11922/// SecurityProperty
11923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11924#[cfg_attr(feature = "bindings", derive(TS))]
11925pub struct SecurityProperty {
11926    pub this: Box<Expression>,
11927}
11928
11929/// SchemaCommentProperty
11930#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11931#[cfg_attr(feature = "bindings", derive(TS))]
11932pub struct SchemaCommentProperty {
11933    pub this: Box<Expression>,
11934}
11935
11936/// SemanticView
11937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11938#[cfg_attr(feature = "bindings", derive(TS))]
11939pub struct SemanticView {
11940    pub this: Box<Expression>,
11941    #[serde(default)]
11942    pub metrics: Option<Box<Expression>>,
11943    #[serde(default)]
11944    pub dimensions: Option<Box<Expression>>,
11945    #[serde(default)]
11946    pub facts: Option<Box<Expression>>,
11947    #[serde(default)]
11948    pub where_: Option<Box<Expression>>,
11949}
11950
11951/// SerdeProperties
11952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11953#[cfg_attr(feature = "bindings", derive(TS))]
11954pub struct SerdeProperties {
11955    #[serde(default)]
11956    pub expressions: Vec<Expression>,
11957    #[serde(default)]
11958    pub with_: Option<Box<Expression>>,
11959}
11960
11961/// SetProperty
11962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11963#[cfg_attr(feature = "bindings", derive(TS))]
11964pub struct SetProperty {
11965    #[serde(default)]
11966    pub multi: Option<Box<Expression>>,
11967}
11968
11969/// SharingProperty
11970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11971#[cfg_attr(feature = "bindings", derive(TS))]
11972pub struct SharingProperty {
11973    #[serde(default)]
11974    pub this: Option<Box<Expression>>,
11975}
11976
11977/// SetConfigProperty
11978#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11979#[cfg_attr(feature = "bindings", derive(TS))]
11980pub struct SetConfigProperty {
11981    pub this: Box<Expression>,
11982}
11983
11984/// SettingsProperty
11985#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11986#[cfg_attr(feature = "bindings", derive(TS))]
11987pub struct SettingsProperty {
11988    #[serde(default)]
11989    pub expressions: Vec<Expression>,
11990}
11991
11992/// SortKeyProperty
11993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11994#[cfg_attr(feature = "bindings", derive(TS))]
11995pub struct SortKeyProperty {
11996    pub this: Box<Expression>,
11997    #[serde(default)]
11998    pub compound: Option<Box<Expression>>,
11999}
12000
12001/// SqlReadWriteProperty
12002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12003#[cfg_attr(feature = "bindings", derive(TS))]
12004pub struct SqlReadWriteProperty {
12005    pub this: Box<Expression>,
12006}
12007
12008/// SqlSecurityProperty
12009#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12010#[cfg_attr(feature = "bindings", derive(TS))]
12011pub struct SqlSecurityProperty {
12012    pub this: Box<Expression>,
12013}
12014
12015/// StabilityProperty
12016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12017#[cfg_attr(feature = "bindings", derive(TS))]
12018pub struct StabilityProperty {
12019    pub this: Box<Expression>,
12020}
12021
12022/// StorageHandlerProperty
12023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12024#[cfg_attr(feature = "bindings", derive(TS))]
12025pub struct StorageHandlerProperty {
12026    pub this: Box<Expression>,
12027}
12028
12029/// TemporaryProperty
12030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12031#[cfg_attr(feature = "bindings", derive(TS))]
12032pub struct TemporaryProperty {
12033    #[serde(default)]
12034    pub this: Option<Box<Expression>>,
12035}
12036
12037/// Tags
12038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12039#[cfg_attr(feature = "bindings", derive(TS))]
12040pub struct Tags {
12041    #[serde(default)]
12042    pub expressions: Vec<Expression>,
12043}
12044
12045/// TransformModelProperty
12046#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12047#[cfg_attr(feature = "bindings", derive(TS))]
12048pub struct TransformModelProperty {
12049    #[serde(default)]
12050    pub expressions: Vec<Expression>,
12051}
12052
12053/// TransientProperty
12054#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12055#[cfg_attr(feature = "bindings", derive(TS))]
12056pub struct TransientProperty {
12057    #[serde(default)]
12058    pub this: Option<Box<Expression>>,
12059}
12060
12061/// UsingTemplateProperty
12062#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12063#[cfg_attr(feature = "bindings", derive(TS))]
12064pub struct UsingTemplateProperty {
12065    pub this: Box<Expression>,
12066}
12067
12068/// ViewAttributeProperty
12069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12070#[cfg_attr(feature = "bindings", derive(TS))]
12071pub struct ViewAttributeProperty {
12072    pub this: Box<Expression>,
12073}
12074
12075/// VolatileProperty
12076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12077#[cfg_attr(feature = "bindings", derive(TS))]
12078pub struct VolatileProperty {
12079    #[serde(default)]
12080    pub this: Option<Box<Expression>>,
12081}
12082
12083/// WithDataProperty
12084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12085#[cfg_attr(feature = "bindings", derive(TS))]
12086pub struct WithDataProperty {
12087    #[serde(default)]
12088    pub no: Option<Box<Expression>>,
12089    #[serde(default)]
12090    pub statistics: Option<Box<Expression>>,
12091}
12092
12093/// WithJournalTableProperty
12094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12095#[cfg_attr(feature = "bindings", derive(TS))]
12096pub struct WithJournalTableProperty {
12097    pub this: Box<Expression>,
12098}
12099
12100/// WithSchemaBindingProperty
12101#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12102#[cfg_attr(feature = "bindings", derive(TS))]
12103pub struct WithSchemaBindingProperty {
12104    pub this: Box<Expression>,
12105}
12106
12107/// WithSystemVersioningProperty
12108#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12109#[cfg_attr(feature = "bindings", derive(TS))]
12110pub struct WithSystemVersioningProperty {
12111    #[serde(default)]
12112    pub on: Option<Box<Expression>>,
12113    #[serde(default)]
12114    pub this: Option<Box<Expression>>,
12115    #[serde(default)]
12116    pub data_consistency: Option<Box<Expression>>,
12117    #[serde(default)]
12118    pub retention_period: Option<Box<Expression>>,
12119    #[serde(default)]
12120    pub with_: Option<Box<Expression>>,
12121}
12122
12123/// WithProcedureOptions
12124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12125#[cfg_attr(feature = "bindings", derive(TS))]
12126pub struct WithProcedureOptions {
12127    #[serde(default)]
12128    pub expressions: Vec<Expression>,
12129}
12130
12131/// EncodeProperty
12132#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12133#[cfg_attr(feature = "bindings", derive(TS))]
12134pub struct EncodeProperty {
12135    pub this: Box<Expression>,
12136    #[serde(default)]
12137    pub properties: Vec<Expression>,
12138    #[serde(default)]
12139    pub key: Option<Box<Expression>>,
12140}
12141
12142/// IncludeProperty
12143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12144#[cfg_attr(feature = "bindings", derive(TS))]
12145pub struct IncludeProperty {
12146    pub this: Box<Expression>,
12147    #[serde(default)]
12148    pub alias: Option<String>,
12149    #[serde(default)]
12150    pub column_def: Option<Box<Expression>>,
12151}
12152
12153/// Properties
12154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12155#[cfg_attr(feature = "bindings", derive(TS))]
12156pub struct Properties {
12157    #[serde(default)]
12158    pub expressions: Vec<Expression>,
12159}
12160
12161/// Key/value pair in a BigQuery OPTIONS (...) clause.
12162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12163#[cfg_attr(feature = "bindings", derive(TS))]
12164pub struct OptionEntry {
12165    pub key: Identifier,
12166    pub value: Expression,
12167}
12168
12169/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12171#[cfg_attr(feature = "bindings", derive(TS))]
12172pub struct OptionsProperty {
12173    #[serde(default)]
12174    pub entries: Vec<OptionEntry>,
12175}
12176
12177/// InputOutputFormat
12178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12179#[cfg_attr(feature = "bindings", derive(TS))]
12180pub struct InputOutputFormat {
12181    #[serde(default)]
12182    pub input_format: Option<Box<Expression>>,
12183    #[serde(default)]
12184    pub output_format: Option<Box<Expression>>,
12185}
12186
12187/// Reference
12188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12189#[cfg_attr(feature = "bindings", derive(TS))]
12190pub struct Reference {
12191    pub this: Box<Expression>,
12192    #[serde(default)]
12193    pub expressions: Vec<Expression>,
12194    #[serde(default)]
12195    pub options: Vec<Expression>,
12196}
12197
12198/// QueryOption
12199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12200#[cfg_attr(feature = "bindings", derive(TS))]
12201pub struct QueryOption {
12202    pub this: Box<Expression>,
12203    #[serde(default)]
12204    pub expression: Option<Box<Expression>>,
12205}
12206
12207/// WithTableHint
12208#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12209#[cfg_attr(feature = "bindings", derive(TS))]
12210pub struct WithTableHint {
12211    #[serde(default)]
12212    pub expressions: Vec<Expression>,
12213}
12214
12215/// IndexTableHint
12216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12217#[cfg_attr(feature = "bindings", derive(TS))]
12218pub struct IndexTableHint {
12219    pub this: Box<Expression>,
12220    #[serde(default)]
12221    pub expressions: Vec<Expression>,
12222    #[serde(default)]
12223    pub target: Option<Box<Expression>>,
12224}
12225
12226/// Get
12227#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12228#[cfg_attr(feature = "bindings", derive(TS))]
12229pub struct Get {
12230    pub this: Box<Expression>,
12231    #[serde(default)]
12232    pub target: Option<Box<Expression>>,
12233    #[serde(default)]
12234    pub properties: Vec<Expression>,
12235}
12236
12237/// SetOperation
12238#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12239#[cfg_attr(feature = "bindings", derive(TS))]
12240pub struct SetOperation {
12241    #[serde(default)]
12242    pub with_: Option<Box<Expression>>,
12243    pub this: Box<Expression>,
12244    pub expression: Box<Expression>,
12245    #[serde(default)]
12246    pub distinct: bool,
12247    #[serde(default)]
12248    pub by_name: Option<Box<Expression>>,
12249    #[serde(default)]
12250    pub side: Option<Box<Expression>>,
12251    #[serde(default)]
12252    pub kind: Option<String>,
12253    #[serde(default)]
12254    pub on: Option<Box<Expression>>,
12255}
12256
12257/// Var - Simple variable reference (for SQL variables, keywords as values)
12258#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12259#[cfg_attr(feature = "bindings", derive(TS))]
12260pub struct Var {
12261    pub this: String,
12262}
12263
12264/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12266#[cfg_attr(feature = "bindings", derive(TS))]
12267pub struct Variadic {
12268    pub this: Box<Expression>,
12269}
12270
12271/// Version
12272#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12273#[cfg_attr(feature = "bindings", derive(TS))]
12274pub struct Version {
12275    pub this: Box<Expression>,
12276    pub kind: String,
12277    #[serde(default)]
12278    pub expression: Option<Box<Expression>>,
12279}
12280
12281/// Schema
12282#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12283#[cfg_attr(feature = "bindings", derive(TS))]
12284pub struct Schema {
12285    #[serde(default)]
12286    pub this: Option<Box<Expression>>,
12287    #[serde(default)]
12288    pub expressions: Vec<Expression>,
12289}
12290
12291/// Lock
12292#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12293#[cfg_attr(feature = "bindings", derive(TS))]
12294pub struct Lock {
12295    #[serde(default)]
12296    pub update: Option<Box<Expression>>,
12297    #[serde(default)]
12298    pub expressions: Vec<Expression>,
12299    #[serde(default)]
12300    pub wait: Option<Box<Expression>>,
12301    #[serde(default)]
12302    pub key: Option<Box<Expression>>,
12303}
12304
12305/// TableSample - wraps an expression with a TABLESAMPLE clause
12306/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12308#[cfg_attr(feature = "bindings", derive(TS))]
12309pub struct TableSample {
12310    /// The expression being sampled (subquery, function, etc.)
12311    #[serde(default, skip_serializing_if = "Option::is_none")]
12312    pub this: Option<Box<Expression>>,
12313    /// The sample specification
12314    #[serde(default, skip_serializing_if = "Option::is_none")]
12315    pub sample: Option<Box<Sample>>,
12316    #[serde(default)]
12317    pub expressions: Vec<Expression>,
12318    #[serde(default)]
12319    pub method: Option<String>,
12320    #[serde(default)]
12321    pub bucket_numerator: Option<Box<Expression>>,
12322    #[serde(default)]
12323    pub bucket_denominator: Option<Box<Expression>>,
12324    #[serde(default)]
12325    pub bucket_field: Option<Box<Expression>>,
12326    #[serde(default)]
12327    pub percent: Option<Box<Expression>>,
12328    #[serde(default)]
12329    pub rows: Option<Box<Expression>>,
12330    #[serde(default)]
12331    pub size: Option<i64>,
12332    #[serde(default)]
12333    pub seed: Option<Box<Expression>>,
12334}
12335
12336/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12338#[cfg_attr(feature = "bindings", derive(TS))]
12339pub struct Tag {
12340    #[serde(default)]
12341    pub this: Option<Box<Expression>>,
12342    #[serde(default)]
12343    pub prefix: Option<Box<Expression>>,
12344    #[serde(default)]
12345    pub postfix: Option<Box<Expression>>,
12346}
12347
12348/// UnpivotColumns
12349#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12350#[cfg_attr(feature = "bindings", derive(TS))]
12351pub struct UnpivotColumns {
12352    pub this: Box<Expression>,
12353    #[serde(default)]
12354    pub expressions: Vec<Expression>,
12355}
12356
12357/// SessionParameter
12358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12359#[cfg_attr(feature = "bindings", derive(TS))]
12360pub struct SessionParameter {
12361    pub this: Box<Expression>,
12362    #[serde(default)]
12363    pub kind: Option<String>,
12364}
12365
12366/// PseudoType
12367#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12368#[cfg_attr(feature = "bindings", derive(TS))]
12369pub struct PseudoType {
12370    pub this: Box<Expression>,
12371}
12372
12373/// ObjectIdentifier
12374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12375#[cfg_attr(feature = "bindings", derive(TS))]
12376pub struct ObjectIdentifier {
12377    pub this: Box<Expression>,
12378}
12379
12380/// Transaction
12381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12382#[cfg_attr(feature = "bindings", derive(TS))]
12383pub struct Transaction {
12384    #[serde(default)]
12385    pub this: Option<Box<Expression>>,
12386    #[serde(default)]
12387    pub modes: Option<Box<Expression>>,
12388    #[serde(default)]
12389    pub mark: Option<Box<Expression>>,
12390}
12391
12392/// Commit
12393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12394#[cfg_attr(feature = "bindings", derive(TS))]
12395pub struct Commit {
12396    #[serde(default)]
12397    pub chain: Option<Box<Expression>>,
12398    #[serde(default)]
12399    pub this: Option<Box<Expression>>,
12400    #[serde(default)]
12401    pub durability: Option<Box<Expression>>,
12402}
12403
12404/// Rollback
12405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12406#[cfg_attr(feature = "bindings", derive(TS))]
12407pub struct Rollback {
12408    #[serde(default)]
12409    pub savepoint: Option<Box<Expression>>,
12410    #[serde(default)]
12411    pub this: Option<Box<Expression>>,
12412}
12413
12414/// AlterSession
12415#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12416#[cfg_attr(feature = "bindings", derive(TS))]
12417pub struct AlterSession {
12418    #[serde(default)]
12419    pub expressions: Vec<Expression>,
12420    #[serde(default)]
12421    pub unset: Option<Box<Expression>>,
12422}
12423
12424/// Analyze
12425#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12426#[cfg_attr(feature = "bindings", derive(TS))]
12427pub struct Analyze {
12428    #[serde(default)]
12429    pub kind: Option<String>,
12430    #[serde(default)]
12431    pub this: Option<Box<Expression>>,
12432    #[serde(default)]
12433    pub options: Vec<Expression>,
12434    #[serde(default)]
12435    pub mode: Option<Box<Expression>>,
12436    #[serde(default)]
12437    pub partition: Option<Box<Expression>>,
12438    #[serde(default)]
12439    pub expression: Option<Box<Expression>>,
12440    #[serde(default)]
12441    pub properties: Vec<Expression>,
12442    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12443    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12444    pub columns: Vec<String>,
12445}
12446
12447/// AnalyzeStatistics
12448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12449#[cfg_attr(feature = "bindings", derive(TS))]
12450pub struct AnalyzeStatistics {
12451    pub kind: String,
12452    #[serde(default)]
12453    pub option: Option<Box<Expression>>,
12454    #[serde(default)]
12455    pub this: Option<Box<Expression>>,
12456    #[serde(default)]
12457    pub expressions: Vec<Expression>,
12458}
12459
12460/// AnalyzeHistogram
12461#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12462#[cfg_attr(feature = "bindings", derive(TS))]
12463pub struct AnalyzeHistogram {
12464    pub this: Box<Expression>,
12465    #[serde(default)]
12466    pub expressions: Vec<Expression>,
12467    #[serde(default)]
12468    pub expression: Option<Box<Expression>>,
12469    #[serde(default)]
12470    pub update_options: Option<Box<Expression>>,
12471}
12472
12473/// AnalyzeSample
12474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12475#[cfg_attr(feature = "bindings", derive(TS))]
12476pub struct AnalyzeSample {
12477    pub kind: String,
12478    #[serde(default)]
12479    pub sample: Option<Box<Expression>>,
12480}
12481
12482/// AnalyzeListChainedRows
12483#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12484#[cfg_attr(feature = "bindings", derive(TS))]
12485pub struct AnalyzeListChainedRows {
12486    #[serde(default)]
12487    pub expression: Option<Box<Expression>>,
12488}
12489
12490/// AnalyzeDelete
12491#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12492#[cfg_attr(feature = "bindings", derive(TS))]
12493pub struct AnalyzeDelete {
12494    #[serde(default)]
12495    pub kind: Option<String>,
12496}
12497
12498/// AnalyzeWith
12499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12500#[cfg_attr(feature = "bindings", derive(TS))]
12501pub struct AnalyzeWith {
12502    #[serde(default)]
12503    pub expressions: Vec<Expression>,
12504}
12505
12506/// AnalyzeValidate
12507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12508#[cfg_attr(feature = "bindings", derive(TS))]
12509pub struct AnalyzeValidate {
12510    pub kind: String,
12511    #[serde(default)]
12512    pub this: Option<Box<Expression>>,
12513    #[serde(default)]
12514    pub expression: Option<Box<Expression>>,
12515}
12516
12517/// AddPartition
12518#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12519#[cfg_attr(feature = "bindings", derive(TS))]
12520pub struct AddPartition {
12521    pub this: Box<Expression>,
12522    #[serde(default)]
12523    pub exists: bool,
12524    #[serde(default)]
12525    pub location: Option<Box<Expression>>,
12526}
12527
12528/// AttachOption
12529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12530#[cfg_attr(feature = "bindings", derive(TS))]
12531pub struct AttachOption {
12532    pub this: Box<Expression>,
12533    #[serde(default)]
12534    pub expression: Option<Box<Expression>>,
12535}
12536
12537/// DropPartition
12538#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12539#[cfg_attr(feature = "bindings", derive(TS))]
12540pub struct DropPartition {
12541    #[serde(default)]
12542    pub expressions: Vec<Expression>,
12543    #[serde(default)]
12544    pub exists: bool,
12545}
12546
12547/// ReplacePartition
12548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12549#[cfg_attr(feature = "bindings", derive(TS))]
12550pub struct ReplacePartition {
12551    pub expression: Box<Expression>,
12552    #[serde(default)]
12553    pub source: Option<Box<Expression>>,
12554}
12555
12556/// DPipe
12557#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12558#[cfg_attr(feature = "bindings", derive(TS))]
12559pub struct DPipe {
12560    pub this: Box<Expression>,
12561    pub expression: Box<Expression>,
12562    #[serde(default)]
12563    pub safe: Option<Box<Expression>>,
12564}
12565
12566/// Operator
12567#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12568#[cfg_attr(feature = "bindings", derive(TS))]
12569pub struct Operator {
12570    pub this: Box<Expression>,
12571    #[serde(default)]
12572    pub operator: Option<Box<Expression>>,
12573    pub expression: Box<Expression>,
12574    /// Comments between OPERATOR() and the RHS expression
12575    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12576    pub comments: Vec<String>,
12577}
12578
12579/// PivotAny
12580#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12581#[cfg_attr(feature = "bindings", derive(TS))]
12582pub struct PivotAny {
12583    #[serde(default)]
12584    pub this: Option<Box<Expression>>,
12585}
12586
12587/// Aliases
12588#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12589#[cfg_attr(feature = "bindings", derive(TS))]
12590pub struct Aliases {
12591    pub this: Box<Expression>,
12592    #[serde(default)]
12593    pub expressions: Vec<Expression>,
12594}
12595
12596/// AtIndex
12597#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12598#[cfg_attr(feature = "bindings", derive(TS))]
12599pub struct AtIndex {
12600    pub this: Box<Expression>,
12601    pub expression: Box<Expression>,
12602}
12603
12604/// FromTimeZone
12605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12606#[cfg_attr(feature = "bindings", derive(TS))]
12607pub struct FromTimeZone {
12608    pub this: Box<Expression>,
12609    #[serde(default)]
12610    pub zone: Option<Box<Expression>>,
12611}
12612
12613/// Format override for a column in Teradata
12614#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12615#[cfg_attr(feature = "bindings", derive(TS))]
12616pub struct FormatPhrase {
12617    pub this: Box<Expression>,
12618    pub format: String,
12619}
12620
12621/// ForIn
12622#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12623#[cfg_attr(feature = "bindings", derive(TS))]
12624pub struct ForIn {
12625    pub this: Box<Expression>,
12626    pub expression: Box<Expression>,
12627}
12628
12629/// Automatically converts unit arg into a var.
12630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12631#[cfg_attr(feature = "bindings", derive(TS))]
12632pub struct TimeUnit {
12633    #[serde(default)]
12634    pub unit: Option<String>,
12635}
12636
12637/// IntervalOp
12638#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12639#[cfg_attr(feature = "bindings", derive(TS))]
12640pub struct IntervalOp {
12641    #[serde(default)]
12642    pub unit: Option<String>,
12643    pub expression: Box<Expression>,
12644}
12645
12646/// HavingMax
12647#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12648#[cfg_attr(feature = "bindings", derive(TS))]
12649pub struct HavingMax {
12650    pub this: Box<Expression>,
12651    pub expression: Box<Expression>,
12652    #[serde(default)]
12653    pub max: Option<Box<Expression>>,
12654}
12655
12656/// CosineDistance
12657#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12658#[cfg_attr(feature = "bindings", derive(TS))]
12659pub struct CosineDistance {
12660    pub this: Box<Expression>,
12661    pub expression: Box<Expression>,
12662}
12663
12664/// DotProduct
12665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12666#[cfg_attr(feature = "bindings", derive(TS))]
12667pub struct DotProduct {
12668    pub this: Box<Expression>,
12669    pub expression: Box<Expression>,
12670}
12671
12672/// EuclideanDistance
12673#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12674#[cfg_attr(feature = "bindings", derive(TS))]
12675pub struct EuclideanDistance {
12676    pub this: Box<Expression>,
12677    pub expression: Box<Expression>,
12678}
12679
12680/// ManhattanDistance
12681#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12682#[cfg_attr(feature = "bindings", derive(TS))]
12683pub struct ManhattanDistance {
12684    pub this: Box<Expression>,
12685    pub expression: Box<Expression>,
12686}
12687
12688/// JarowinklerSimilarity
12689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12690#[cfg_attr(feature = "bindings", derive(TS))]
12691pub struct JarowinklerSimilarity {
12692    pub this: Box<Expression>,
12693    pub expression: Box<Expression>,
12694}
12695
12696/// Booland
12697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12698#[cfg_attr(feature = "bindings", derive(TS))]
12699pub struct Booland {
12700    pub this: Box<Expression>,
12701    pub expression: Box<Expression>,
12702}
12703
12704/// Boolor
12705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12706#[cfg_attr(feature = "bindings", derive(TS))]
12707pub struct Boolor {
12708    pub this: Box<Expression>,
12709    pub expression: Box<Expression>,
12710}
12711
12712/// ParameterizedAgg
12713#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12714#[cfg_attr(feature = "bindings", derive(TS))]
12715pub struct ParameterizedAgg {
12716    pub this: Box<Expression>,
12717    #[serde(default)]
12718    pub expressions: Vec<Expression>,
12719    #[serde(default)]
12720    pub params: Vec<Expression>,
12721}
12722
12723/// ArgMax
12724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12725#[cfg_attr(feature = "bindings", derive(TS))]
12726pub struct ArgMax {
12727    pub this: Box<Expression>,
12728    pub expression: Box<Expression>,
12729    #[serde(default)]
12730    pub count: Option<Box<Expression>>,
12731}
12732
12733/// ArgMin
12734#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12735#[cfg_attr(feature = "bindings", derive(TS))]
12736pub struct ArgMin {
12737    pub this: Box<Expression>,
12738    pub expression: Box<Expression>,
12739    #[serde(default)]
12740    pub count: Option<Box<Expression>>,
12741}
12742
12743/// ApproxTopK
12744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12745#[cfg_attr(feature = "bindings", derive(TS))]
12746pub struct ApproxTopK {
12747    pub this: Box<Expression>,
12748    #[serde(default)]
12749    pub expression: Option<Box<Expression>>,
12750    #[serde(default)]
12751    pub counters: Option<Box<Expression>>,
12752}
12753
12754/// ApproxTopKAccumulate
12755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12756#[cfg_attr(feature = "bindings", derive(TS))]
12757pub struct ApproxTopKAccumulate {
12758    pub this: Box<Expression>,
12759    #[serde(default)]
12760    pub expression: Option<Box<Expression>>,
12761}
12762
12763/// ApproxTopKCombine
12764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12765#[cfg_attr(feature = "bindings", derive(TS))]
12766pub struct ApproxTopKCombine {
12767    pub this: Box<Expression>,
12768    #[serde(default)]
12769    pub expression: Option<Box<Expression>>,
12770}
12771
12772/// ApproxTopKEstimate
12773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12774#[cfg_attr(feature = "bindings", derive(TS))]
12775pub struct ApproxTopKEstimate {
12776    pub this: Box<Expression>,
12777    #[serde(default)]
12778    pub expression: Option<Box<Expression>>,
12779}
12780
12781/// ApproxTopSum
12782#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12783#[cfg_attr(feature = "bindings", derive(TS))]
12784pub struct ApproxTopSum {
12785    pub this: Box<Expression>,
12786    pub expression: Box<Expression>,
12787    #[serde(default)]
12788    pub count: Option<Box<Expression>>,
12789}
12790
12791/// ApproxQuantiles
12792#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12793#[cfg_attr(feature = "bindings", derive(TS))]
12794pub struct ApproxQuantiles {
12795    pub this: Box<Expression>,
12796    #[serde(default)]
12797    pub expression: Option<Box<Expression>>,
12798}
12799
12800/// Minhash
12801#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12802#[cfg_attr(feature = "bindings", derive(TS))]
12803pub struct Minhash {
12804    pub this: Box<Expression>,
12805    #[serde(default)]
12806    pub expressions: Vec<Expression>,
12807}
12808
12809/// FarmFingerprint
12810#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12811#[cfg_attr(feature = "bindings", derive(TS))]
12812pub struct FarmFingerprint {
12813    #[serde(default)]
12814    pub expressions: Vec<Expression>,
12815}
12816
12817/// Float64
12818#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12819#[cfg_attr(feature = "bindings", derive(TS))]
12820pub struct Float64 {
12821    pub this: Box<Expression>,
12822    #[serde(default)]
12823    pub expression: Option<Box<Expression>>,
12824}
12825
12826/// Transform
12827#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12828#[cfg_attr(feature = "bindings", derive(TS))]
12829pub struct Transform {
12830    pub this: Box<Expression>,
12831    pub expression: Box<Expression>,
12832}
12833
12834/// Translate
12835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12836#[cfg_attr(feature = "bindings", derive(TS))]
12837pub struct Translate {
12838    pub this: Box<Expression>,
12839    #[serde(default)]
12840    pub from_: Option<Box<Expression>>,
12841    #[serde(default)]
12842    pub to: Option<Box<Expression>>,
12843}
12844
12845/// Grouping
12846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12847#[cfg_attr(feature = "bindings", derive(TS))]
12848pub struct Grouping {
12849    #[serde(default)]
12850    pub expressions: Vec<Expression>,
12851}
12852
12853/// GroupingId
12854#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12855#[cfg_attr(feature = "bindings", derive(TS))]
12856pub struct GroupingId {
12857    #[serde(default)]
12858    pub expressions: Vec<Expression>,
12859}
12860
12861/// Anonymous
12862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12863#[cfg_attr(feature = "bindings", derive(TS))]
12864pub struct Anonymous {
12865    pub this: Box<Expression>,
12866    #[serde(default)]
12867    pub expressions: Vec<Expression>,
12868}
12869
12870/// AnonymousAggFunc
12871#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12872#[cfg_attr(feature = "bindings", derive(TS))]
12873pub struct AnonymousAggFunc {
12874    pub this: Box<Expression>,
12875    #[serde(default)]
12876    pub expressions: Vec<Expression>,
12877}
12878
12879/// CombinedAggFunc
12880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12881#[cfg_attr(feature = "bindings", derive(TS))]
12882pub struct CombinedAggFunc {
12883    pub this: Box<Expression>,
12884    #[serde(default)]
12885    pub expressions: Vec<Expression>,
12886}
12887
12888/// CombinedParameterizedAgg
12889#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12890#[cfg_attr(feature = "bindings", derive(TS))]
12891pub struct CombinedParameterizedAgg {
12892    pub this: Box<Expression>,
12893    #[serde(default)]
12894    pub expressions: Vec<Expression>,
12895    #[serde(default)]
12896    pub params: Vec<Expression>,
12897}
12898
12899/// HashAgg
12900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12901#[cfg_attr(feature = "bindings", derive(TS))]
12902pub struct HashAgg {
12903    pub this: Box<Expression>,
12904    #[serde(default)]
12905    pub expressions: Vec<Expression>,
12906}
12907
12908/// Hll
12909#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12910#[cfg_attr(feature = "bindings", derive(TS))]
12911pub struct Hll {
12912    pub this: Box<Expression>,
12913    #[serde(default)]
12914    pub expressions: Vec<Expression>,
12915}
12916
12917/// Apply
12918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12919#[cfg_attr(feature = "bindings", derive(TS))]
12920pub struct Apply {
12921    pub this: Box<Expression>,
12922    pub expression: Box<Expression>,
12923}
12924
12925/// ToBoolean
12926#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12927#[cfg_attr(feature = "bindings", derive(TS))]
12928pub struct ToBoolean {
12929    pub this: Box<Expression>,
12930    #[serde(default)]
12931    pub safe: Option<Box<Expression>>,
12932}
12933
12934/// List
12935#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12936#[cfg_attr(feature = "bindings", derive(TS))]
12937pub struct List {
12938    #[serde(default)]
12939    pub expressions: Vec<Expression>,
12940}
12941
12942/// ToMap - Materialize-style map constructor
12943/// Can hold either:
12944/// - A SELECT subquery (MAP(SELECT 'a', 1))
12945/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
12946#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12947#[cfg_attr(feature = "bindings", derive(TS))]
12948pub struct ToMap {
12949    /// Either a Select subquery or a Struct containing PropertyEQ entries
12950    pub this: Box<Expression>,
12951}
12952
12953/// Pad
12954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12955#[cfg_attr(feature = "bindings", derive(TS))]
12956pub struct Pad {
12957    pub this: Box<Expression>,
12958    pub expression: Box<Expression>,
12959    #[serde(default)]
12960    pub fill_pattern: Option<Box<Expression>>,
12961    #[serde(default)]
12962    pub is_left: Option<Box<Expression>>,
12963}
12964
12965/// ToChar
12966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12967#[cfg_attr(feature = "bindings", derive(TS))]
12968pub struct ToChar {
12969    pub this: Box<Expression>,
12970    #[serde(default)]
12971    pub format: Option<String>,
12972    #[serde(default)]
12973    pub nlsparam: Option<Box<Expression>>,
12974    #[serde(default)]
12975    pub is_numeric: Option<Box<Expression>>,
12976}
12977
12978/// StringFunc - String type conversion function (BigQuery STRING)
12979#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12980#[cfg_attr(feature = "bindings", derive(TS))]
12981pub struct StringFunc {
12982    pub this: Box<Expression>,
12983    #[serde(default)]
12984    pub zone: Option<Box<Expression>>,
12985}
12986
12987/// ToNumber
12988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12989#[cfg_attr(feature = "bindings", derive(TS))]
12990pub struct ToNumber {
12991    pub this: Box<Expression>,
12992    #[serde(default)]
12993    pub format: Option<Box<Expression>>,
12994    #[serde(default)]
12995    pub nlsparam: Option<Box<Expression>>,
12996    #[serde(default)]
12997    pub precision: Option<Box<Expression>>,
12998    #[serde(default)]
12999    pub scale: Option<Box<Expression>>,
13000    #[serde(default)]
13001    pub safe: Option<Box<Expression>>,
13002    #[serde(default)]
13003    pub safe_name: Option<Box<Expression>>,
13004}
13005
13006/// ToDouble
13007#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13008#[cfg_attr(feature = "bindings", derive(TS))]
13009pub struct ToDouble {
13010    pub this: Box<Expression>,
13011    #[serde(default)]
13012    pub format: Option<String>,
13013    #[serde(default)]
13014    pub safe: Option<Box<Expression>>,
13015}
13016
13017/// ToDecfloat
13018#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13019#[cfg_attr(feature = "bindings", derive(TS))]
13020pub struct ToDecfloat {
13021    pub this: Box<Expression>,
13022    #[serde(default)]
13023    pub format: Option<String>,
13024}
13025
13026/// TryToDecfloat
13027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13028#[cfg_attr(feature = "bindings", derive(TS))]
13029pub struct TryToDecfloat {
13030    pub this: Box<Expression>,
13031    #[serde(default)]
13032    pub format: Option<String>,
13033}
13034
13035/// ToFile
13036#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13037#[cfg_attr(feature = "bindings", derive(TS))]
13038pub struct ToFile {
13039    pub this: Box<Expression>,
13040    #[serde(default)]
13041    pub path: Option<Box<Expression>>,
13042    #[serde(default)]
13043    pub safe: Option<Box<Expression>>,
13044}
13045
13046/// Columns
13047#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13048#[cfg_attr(feature = "bindings", derive(TS))]
13049pub struct Columns {
13050    pub this: Box<Expression>,
13051    #[serde(default)]
13052    pub unpack: Option<Box<Expression>>,
13053}
13054
13055/// ConvertToCharset
13056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13057#[cfg_attr(feature = "bindings", derive(TS))]
13058pub struct ConvertToCharset {
13059    pub this: Box<Expression>,
13060    #[serde(default)]
13061    pub dest: Option<Box<Expression>>,
13062    #[serde(default)]
13063    pub source: Option<Box<Expression>>,
13064}
13065
13066/// ConvertTimezone
13067#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13068#[cfg_attr(feature = "bindings", derive(TS))]
13069pub struct ConvertTimezone {
13070    #[serde(default)]
13071    pub source_tz: Option<Box<Expression>>,
13072    #[serde(default)]
13073    pub target_tz: Option<Box<Expression>>,
13074    #[serde(default)]
13075    pub timestamp: Option<Box<Expression>>,
13076    #[serde(default)]
13077    pub options: Vec<Expression>,
13078}
13079
13080/// GenerateSeries
13081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13082#[cfg_attr(feature = "bindings", derive(TS))]
13083pub struct GenerateSeries {
13084    #[serde(default)]
13085    pub start: Option<Box<Expression>>,
13086    #[serde(default)]
13087    pub end: Option<Box<Expression>>,
13088    #[serde(default)]
13089    pub step: Option<Box<Expression>>,
13090    #[serde(default)]
13091    pub is_end_exclusive: Option<Box<Expression>>,
13092}
13093
13094/// AIAgg
13095#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13096#[cfg_attr(feature = "bindings", derive(TS))]
13097pub struct AIAgg {
13098    pub this: Box<Expression>,
13099    pub expression: Box<Expression>,
13100}
13101
13102/// AIClassify
13103#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13104#[cfg_attr(feature = "bindings", derive(TS))]
13105pub struct AIClassify {
13106    pub this: Box<Expression>,
13107    #[serde(default)]
13108    pub categories: Option<Box<Expression>>,
13109    #[serde(default)]
13110    pub config: Option<Box<Expression>>,
13111}
13112
13113/// ArrayAll
13114#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13115#[cfg_attr(feature = "bindings", derive(TS))]
13116pub struct ArrayAll {
13117    pub this: Box<Expression>,
13118    pub expression: Box<Expression>,
13119}
13120
13121/// ArrayAny
13122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13123#[cfg_attr(feature = "bindings", derive(TS))]
13124pub struct ArrayAny {
13125    pub this: Box<Expression>,
13126    pub expression: Box<Expression>,
13127}
13128
13129/// ArrayConstructCompact
13130#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13131#[cfg_attr(feature = "bindings", derive(TS))]
13132pub struct ArrayConstructCompact {
13133    #[serde(default)]
13134    pub expressions: Vec<Expression>,
13135}
13136
13137/// StPoint
13138#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13139#[cfg_attr(feature = "bindings", derive(TS))]
13140pub struct StPoint {
13141    pub this: Box<Expression>,
13142    pub expression: Box<Expression>,
13143    #[serde(default)]
13144    pub null: Option<Box<Expression>>,
13145}
13146
13147/// StDistance
13148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13149#[cfg_attr(feature = "bindings", derive(TS))]
13150pub struct StDistance {
13151    pub this: Box<Expression>,
13152    pub expression: Box<Expression>,
13153    #[serde(default)]
13154    pub use_spheroid: Option<Box<Expression>>,
13155}
13156
13157/// StringToArray
13158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13159#[cfg_attr(feature = "bindings", derive(TS))]
13160pub struct StringToArray {
13161    pub this: Box<Expression>,
13162    #[serde(default)]
13163    pub expression: Option<Box<Expression>>,
13164    #[serde(default)]
13165    pub null: Option<Box<Expression>>,
13166}
13167
13168/// ArraySum
13169#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13170#[cfg_attr(feature = "bindings", derive(TS))]
13171pub struct ArraySum {
13172    pub this: Box<Expression>,
13173    #[serde(default)]
13174    pub expression: Option<Box<Expression>>,
13175}
13176
13177/// ObjectAgg
13178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13179#[cfg_attr(feature = "bindings", derive(TS))]
13180pub struct ObjectAgg {
13181    pub this: Box<Expression>,
13182    pub expression: Box<Expression>,
13183}
13184
13185/// CastToStrType
13186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13187#[cfg_attr(feature = "bindings", derive(TS))]
13188pub struct CastToStrType {
13189    pub this: Box<Expression>,
13190    #[serde(default)]
13191    pub to: Option<Box<Expression>>,
13192}
13193
13194/// CheckJson
13195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13196#[cfg_attr(feature = "bindings", derive(TS))]
13197pub struct CheckJson {
13198    pub this: Box<Expression>,
13199}
13200
13201/// CheckXml
13202#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13203#[cfg_attr(feature = "bindings", derive(TS))]
13204pub struct CheckXml {
13205    pub this: Box<Expression>,
13206    #[serde(default)]
13207    pub disable_auto_convert: Option<Box<Expression>>,
13208}
13209
13210/// TranslateCharacters
13211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13212#[cfg_attr(feature = "bindings", derive(TS))]
13213pub struct TranslateCharacters {
13214    pub this: Box<Expression>,
13215    pub expression: Box<Expression>,
13216    #[serde(default)]
13217    pub with_error: Option<Box<Expression>>,
13218}
13219
13220/// CurrentSchemas
13221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13222#[cfg_attr(feature = "bindings", derive(TS))]
13223pub struct CurrentSchemas {
13224    #[serde(default)]
13225    pub this: Option<Box<Expression>>,
13226}
13227
13228/// CurrentDatetime
13229#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13230#[cfg_attr(feature = "bindings", derive(TS))]
13231pub struct CurrentDatetime {
13232    #[serde(default)]
13233    pub this: Option<Box<Expression>>,
13234}
13235
13236/// Localtime
13237#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13238#[cfg_attr(feature = "bindings", derive(TS))]
13239pub struct Localtime {
13240    #[serde(default)]
13241    pub this: Option<Box<Expression>>,
13242}
13243
13244/// Localtimestamp
13245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13246#[cfg_attr(feature = "bindings", derive(TS))]
13247pub struct Localtimestamp {
13248    #[serde(default)]
13249    pub this: Option<Box<Expression>>,
13250}
13251
13252/// Systimestamp
13253#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13254#[cfg_attr(feature = "bindings", derive(TS))]
13255pub struct Systimestamp {
13256    #[serde(default)]
13257    pub this: Option<Box<Expression>>,
13258}
13259
13260/// CurrentSchema
13261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13262#[cfg_attr(feature = "bindings", derive(TS))]
13263pub struct CurrentSchema {
13264    #[serde(default)]
13265    pub this: Option<Box<Expression>>,
13266}
13267
13268/// CurrentUser
13269#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13270#[cfg_attr(feature = "bindings", derive(TS))]
13271pub struct CurrentUser {
13272    #[serde(default)]
13273    pub this: Option<Box<Expression>>,
13274}
13275
13276/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13277#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13278#[cfg_attr(feature = "bindings", derive(TS))]
13279pub struct SessionUser;
13280
13281/// JSONPathRoot - Represents $ in JSON path expressions
13282#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13283#[cfg_attr(feature = "bindings", derive(TS))]
13284pub struct JSONPathRoot;
13285
13286/// UtcTime
13287#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13288#[cfg_attr(feature = "bindings", derive(TS))]
13289pub struct UtcTime {
13290    #[serde(default)]
13291    pub this: Option<Box<Expression>>,
13292}
13293
13294/// UtcTimestamp
13295#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13296#[cfg_attr(feature = "bindings", derive(TS))]
13297pub struct UtcTimestamp {
13298    #[serde(default)]
13299    pub this: Option<Box<Expression>>,
13300}
13301
13302/// TimestampFunc - TIMESTAMP constructor function
13303#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13304#[cfg_attr(feature = "bindings", derive(TS))]
13305pub struct TimestampFunc {
13306    #[serde(default)]
13307    pub this: Option<Box<Expression>>,
13308    #[serde(default)]
13309    pub zone: Option<Box<Expression>>,
13310    #[serde(default)]
13311    pub with_tz: Option<bool>,
13312    #[serde(default)]
13313    pub safe: Option<bool>,
13314}
13315
13316/// DateBin
13317#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13318#[cfg_attr(feature = "bindings", derive(TS))]
13319pub struct DateBin {
13320    pub this: Box<Expression>,
13321    pub expression: Box<Expression>,
13322    #[serde(default)]
13323    pub unit: Option<String>,
13324    #[serde(default)]
13325    pub zone: Option<Box<Expression>>,
13326    #[serde(default)]
13327    pub origin: Option<Box<Expression>>,
13328}
13329
13330/// Datetime
13331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13332#[cfg_attr(feature = "bindings", derive(TS))]
13333pub struct Datetime {
13334    pub this: Box<Expression>,
13335    #[serde(default)]
13336    pub expression: Option<Box<Expression>>,
13337}
13338
13339/// DatetimeAdd
13340#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13341#[cfg_attr(feature = "bindings", derive(TS))]
13342pub struct DatetimeAdd {
13343    pub this: Box<Expression>,
13344    pub expression: Box<Expression>,
13345    #[serde(default)]
13346    pub unit: Option<String>,
13347}
13348
13349/// DatetimeSub
13350#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13351#[cfg_attr(feature = "bindings", derive(TS))]
13352pub struct DatetimeSub {
13353    pub this: Box<Expression>,
13354    pub expression: Box<Expression>,
13355    #[serde(default)]
13356    pub unit: Option<String>,
13357}
13358
13359/// DatetimeDiff
13360#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13361#[cfg_attr(feature = "bindings", derive(TS))]
13362pub struct DatetimeDiff {
13363    pub this: Box<Expression>,
13364    pub expression: Box<Expression>,
13365    #[serde(default)]
13366    pub unit: Option<String>,
13367}
13368
13369/// DatetimeTrunc
13370#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13371#[cfg_attr(feature = "bindings", derive(TS))]
13372pub struct DatetimeTrunc {
13373    pub this: Box<Expression>,
13374    pub unit: String,
13375    #[serde(default)]
13376    pub zone: Option<Box<Expression>>,
13377}
13378
13379/// Dayname
13380#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13381#[cfg_attr(feature = "bindings", derive(TS))]
13382pub struct Dayname {
13383    pub this: Box<Expression>,
13384    #[serde(default)]
13385    pub abbreviated: Option<Box<Expression>>,
13386}
13387
13388/// MakeInterval
13389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13390#[cfg_attr(feature = "bindings", derive(TS))]
13391pub struct MakeInterval {
13392    #[serde(default)]
13393    pub year: Option<Box<Expression>>,
13394    #[serde(default)]
13395    pub month: Option<Box<Expression>>,
13396    #[serde(default)]
13397    pub week: Option<Box<Expression>>,
13398    #[serde(default)]
13399    pub day: Option<Box<Expression>>,
13400    #[serde(default)]
13401    pub hour: Option<Box<Expression>>,
13402    #[serde(default)]
13403    pub minute: Option<Box<Expression>>,
13404    #[serde(default)]
13405    pub second: Option<Box<Expression>>,
13406}
13407
13408/// PreviousDay
13409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13410#[cfg_attr(feature = "bindings", derive(TS))]
13411pub struct PreviousDay {
13412    pub this: Box<Expression>,
13413    pub expression: Box<Expression>,
13414}
13415
13416/// Elt
13417#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13418#[cfg_attr(feature = "bindings", derive(TS))]
13419pub struct Elt {
13420    pub this: Box<Expression>,
13421    #[serde(default)]
13422    pub expressions: Vec<Expression>,
13423}
13424
13425/// TimestampAdd
13426#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13427#[cfg_attr(feature = "bindings", derive(TS))]
13428pub struct TimestampAdd {
13429    pub this: Box<Expression>,
13430    pub expression: Box<Expression>,
13431    #[serde(default)]
13432    pub unit: Option<String>,
13433}
13434
13435/// TimestampSub
13436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13437#[cfg_attr(feature = "bindings", derive(TS))]
13438pub struct TimestampSub {
13439    pub this: Box<Expression>,
13440    pub expression: Box<Expression>,
13441    #[serde(default)]
13442    pub unit: Option<String>,
13443}
13444
13445/// TimestampDiff
13446#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13447#[cfg_attr(feature = "bindings", derive(TS))]
13448pub struct TimestampDiff {
13449    pub this: Box<Expression>,
13450    pub expression: Box<Expression>,
13451    #[serde(default)]
13452    pub unit: Option<String>,
13453}
13454
13455/// TimeSlice
13456#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13457#[cfg_attr(feature = "bindings", derive(TS))]
13458pub struct TimeSlice {
13459    pub this: Box<Expression>,
13460    pub expression: Box<Expression>,
13461    pub unit: String,
13462    #[serde(default)]
13463    pub kind: Option<String>,
13464}
13465
13466/// TimeAdd
13467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13468#[cfg_attr(feature = "bindings", derive(TS))]
13469pub struct TimeAdd {
13470    pub this: Box<Expression>,
13471    pub expression: Box<Expression>,
13472    #[serde(default)]
13473    pub unit: Option<String>,
13474}
13475
13476/// TimeSub
13477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13478#[cfg_attr(feature = "bindings", derive(TS))]
13479pub struct TimeSub {
13480    pub this: Box<Expression>,
13481    pub expression: Box<Expression>,
13482    #[serde(default)]
13483    pub unit: Option<String>,
13484}
13485
13486/// TimeDiff
13487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13488#[cfg_attr(feature = "bindings", derive(TS))]
13489pub struct TimeDiff {
13490    pub this: Box<Expression>,
13491    pub expression: Box<Expression>,
13492    #[serde(default)]
13493    pub unit: Option<String>,
13494}
13495
13496/// TimeTrunc
13497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13498#[cfg_attr(feature = "bindings", derive(TS))]
13499pub struct TimeTrunc {
13500    pub this: Box<Expression>,
13501    pub unit: String,
13502    #[serde(default)]
13503    pub zone: Option<Box<Expression>>,
13504}
13505
13506/// DateFromParts
13507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13508#[cfg_attr(feature = "bindings", derive(TS))]
13509pub struct DateFromParts {
13510    #[serde(default)]
13511    pub year: Option<Box<Expression>>,
13512    #[serde(default)]
13513    pub month: Option<Box<Expression>>,
13514    #[serde(default)]
13515    pub day: Option<Box<Expression>>,
13516    #[serde(default)]
13517    pub allow_overflow: Option<Box<Expression>>,
13518}
13519
13520/// TimeFromParts
13521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13522#[cfg_attr(feature = "bindings", derive(TS))]
13523pub struct TimeFromParts {
13524    #[serde(default)]
13525    pub hour: Option<Box<Expression>>,
13526    #[serde(default)]
13527    pub min: Option<Box<Expression>>,
13528    #[serde(default)]
13529    pub sec: Option<Box<Expression>>,
13530    #[serde(default)]
13531    pub nano: Option<Box<Expression>>,
13532    #[serde(default)]
13533    pub fractions: Option<Box<Expression>>,
13534    #[serde(default)]
13535    pub precision: Option<i64>,
13536}
13537
13538/// DecodeCase
13539#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13540#[cfg_attr(feature = "bindings", derive(TS))]
13541pub struct DecodeCase {
13542    #[serde(default)]
13543    pub expressions: Vec<Expression>,
13544}
13545
13546/// Decrypt
13547#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13548#[cfg_attr(feature = "bindings", derive(TS))]
13549pub struct Decrypt {
13550    pub this: Box<Expression>,
13551    #[serde(default)]
13552    pub passphrase: Option<Box<Expression>>,
13553    #[serde(default)]
13554    pub aad: Option<Box<Expression>>,
13555    #[serde(default)]
13556    pub encryption_method: Option<Box<Expression>>,
13557    #[serde(default)]
13558    pub safe: Option<Box<Expression>>,
13559}
13560
13561/// DecryptRaw
13562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13563#[cfg_attr(feature = "bindings", derive(TS))]
13564pub struct DecryptRaw {
13565    pub this: Box<Expression>,
13566    #[serde(default)]
13567    pub key: Option<Box<Expression>>,
13568    #[serde(default)]
13569    pub iv: Option<Box<Expression>>,
13570    #[serde(default)]
13571    pub aad: Option<Box<Expression>>,
13572    #[serde(default)]
13573    pub encryption_method: Option<Box<Expression>>,
13574    #[serde(default)]
13575    pub aead: Option<Box<Expression>>,
13576    #[serde(default)]
13577    pub safe: Option<Box<Expression>>,
13578}
13579
13580/// Encode
13581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13582#[cfg_attr(feature = "bindings", derive(TS))]
13583pub struct Encode {
13584    pub this: Box<Expression>,
13585    #[serde(default)]
13586    pub charset: Option<Box<Expression>>,
13587}
13588
13589/// Encrypt
13590#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13591#[cfg_attr(feature = "bindings", derive(TS))]
13592pub struct Encrypt {
13593    pub this: Box<Expression>,
13594    #[serde(default)]
13595    pub passphrase: Option<Box<Expression>>,
13596    #[serde(default)]
13597    pub aad: Option<Box<Expression>>,
13598    #[serde(default)]
13599    pub encryption_method: Option<Box<Expression>>,
13600}
13601
13602/// EncryptRaw
13603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13604#[cfg_attr(feature = "bindings", derive(TS))]
13605pub struct EncryptRaw {
13606    pub this: Box<Expression>,
13607    #[serde(default)]
13608    pub key: Option<Box<Expression>>,
13609    #[serde(default)]
13610    pub iv: Option<Box<Expression>>,
13611    #[serde(default)]
13612    pub aad: Option<Box<Expression>>,
13613    #[serde(default)]
13614    pub encryption_method: Option<Box<Expression>>,
13615}
13616
13617/// EqualNull
13618#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13619#[cfg_attr(feature = "bindings", derive(TS))]
13620pub struct EqualNull {
13621    pub this: Box<Expression>,
13622    pub expression: Box<Expression>,
13623}
13624
13625/// ToBinary
13626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13627#[cfg_attr(feature = "bindings", derive(TS))]
13628pub struct ToBinary {
13629    pub this: Box<Expression>,
13630    #[serde(default)]
13631    pub format: Option<String>,
13632    #[serde(default)]
13633    pub safe: Option<Box<Expression>>,
13634}
13635
13636/// Base64DecodeBinary
13637#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13638#[cfg_attr(feature = "bindings", derive(TS))]
13639pub struct Base64DecodeBinary {
13640    pub this: Box<Expression>,
13641    #[serde(default)]
13642    pub alphabet: Option<Box<Expression>>,
13643}
13644
13645/// Base64DecodeString
13646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13647#[cfg_attr(feature = "bindings", derive(TS))]
13648pub struct Base64DecodeString {
13649    pub this: Box<Expression>,
13650    #[serde(default)]
13651    pub alphabet: Option<Box<Expression>>,
13652}
13653
13654/// Base64Encode
13655#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13656#[cfg_attr(feature = "bindings", derive(TS))]
13657pub struct Base64Encode {
13658    pub this: Box<Expression>,
13659    #[serde(default)]
13660    pub max_line_length: Option<Box<Expression>>,
13661    #[serde(default)]
13662    pub alphabet: Option<Box<Expression>>,
13663}
13664
13665/// TryBase64DecodeBinary
13666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13667#[cfg_attr(feature = "bindings", derive(TS))]
13668pub struct TryBase64DecodeBinary {
13669    pub this: Box<Expression>,
13670    #[serde(default)]
13671    pub alphabet: Option<Box<Expression>>,
13672}
13673
13674/// TryBase64DecodeString
13675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13676#[cfg_attr(feature = "bindings", derive(TS))]
13677pub struct TryBase64DecodeString {
13678    pub this: Box<Expression>,
13679    #[serde(default)]
13680    pub alphabet: Option<Box<Expression>>,
13681}
13682
13683/// GapFill
13684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13685#[cfg_attr(feature = "bindings", derive(TS))]
13686pub struct GapFill {
13687    pub this: Box<Expression>,
13688    #[serde(default)]
13689    pub ts_column: Option<Box<Expression>>,
13690    #[serde(default)]
13691    pub bucket_width: Option<Box<Expression>>,
13692    #[serde(default)]
13693    pub partitioning_columns: Option<Box<Expression>>,
13694    #[serde(default)]
13695    pub value_columns: Option<Box<Expression>>,
13696    #[serde(default)]
13697    pub origin: Option<Box<Expression>>,
13698    #[serde(default)]
13699    pub ignore_nulls: Option<Box<Expression>>,
13700}
13701
13702/// GenerateDateArray
13703#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13704#[cfg_attr(feature = "bindings", derive(TS))]
13705pub struct GenerateDateArray {
13706    #[serde(default)]
13707    pub start: Option<Box<Expression>>,
13708    #[serde(default)]
13709    pub end: Option<Box<Expression>>,
13710    #[serde(default)]
13711    pub step: Option<Box<Expression>>,
13712}
13713
13714/// GenerateTimestampArray
13715#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13716#[cfg_attr(feature = "bindings", derive(TS))]
13717pub struct GenerateTimestampArray {
13718    #[serde(default)]
13719    pub start: Option<Box<Expression>>,
13720    #[serde(default)]
13721    pub end: Option<Box<Expression>>,
13722    #[serde(default)]
13723    pub step: Option<Box<Expression>>,
13724}
13725
13726/// GetExtract
13727#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13728#[cfg_attr(feature = "bindings", derive(TS))]
13729pub struct GetExtract {
13730    pub this: Box<Expression>,
13731    pub expression: Box<Expression>,
13732}
13733
13734/// Getbit
13735#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13736#[cfg_attr(feature = "bindings", derive(TS))]
13737pub struct Getbit {
13738    pub this: Box<Expression>,
13739    pub expression: Box<Expression>,
13740    #[serde(default)]
13741    pub zero_is_msb: Option<Box<Expression>>,
13742}
13743
13744/// OverflowTruncateBehavior
13745#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13746#[cfg_attr(feature = "bindings", derive(TS))]
13747pub struct OverflowTruncateBehavior {
13748    #[serde(default)]
13749    pub this: Option<Box<Expression>>,
13750    #[serde(default)]
13751    pub with_count: Option<Box<Expression>>,
13752}
13753
13754/// HexEncode
13755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13756#[cfg_attr(feature = "bindings", derive(TS))]
13757pub struct HexEncode {
13758    pub this: Box<Expression>,
13759    #[serde(default)]
13760    pub case: Option<Box<Expression>>,
13761}
13762
13763/// Compress
13764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13765#[cfg_attr(feature = "bindings", derive(TS))]
13766pub struct Compress {
13767    pub this: Box<Expression>,
13768    #[serde(default)]
13769    pub method: Option<String>,
13770}
13771
13772/// DecompressBinary
13773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13774#[cfg_attr(feature = "bindings", derive(TS))]
13775pub struct DecompressBinary {
13776    pub this: Box<Expression>,
13777    pub method: String,
13778}
13779
13780/// DecompressString
13781#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13782#[cfg_attr(feature = "bindings", derive(TS))]
13783pub struct DecompressString {
13784    pub this: Box<Expression>,
13785    pub method: String,
13786}
13787
13788/// Xor
13789#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13790#[cfg_attr(feature = "bindings", derive(TS))]
13791pub struct Xor {
13792    #[serde(default)]
13793    pub this: Option<Box<Expression>>,
13794    #[serde(default)]
13795    pub expression: Option<Box<Expression>>,
13796    #[serde(default)]
13797    pub expressions: Vec<Expression>,
13798}
13799
13800/// Nullif
13801#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13802#[cfg_attr(feature = "bindings", derive(TS))]
13803pub struct Nullif {
13804    pub this: Box<Expression>,
13805    pub expression: Box<Expression>,
13806}
13807
13808/// JSON
13809#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13810#[cfg_attr(feature = "bindings", derive(TS))]
13811pub struct JSON {
13812    #[serde(default)]
13813    pub this: Option<Box<Expression>>,
13814    #[serde(default)]
13815    pub with_: Option<Box<Expression>>,
13816    #[serde(default)]
13817    pub unique: bool,
13818}
13819
13820/// JSONPath
13821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13822#[cfg_attr(feature = "bindings", derive(TS))]
13823pub struct JSONPath {
13824    #[serde(default)]
13825    pub expressions: Vec<Expression>,
13826    #[serde(default)]
13827    pub escape: Option<Box<Expression>>,
13828}
13829
13830/// JSONPathFilter
13831#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13832#[cfg_attr(feature = "bindings", derive(TS))]
13833pub struct JSONPathFilter {
13834    pub this: Box<Expression>,
13835}
13836
13837/// JSONPathKey
13838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13839#[cfg_attr(feature = "bindings", derive(TS))]
13840pub struct JSONPathKey {
13841    pub this: Box<Expression>,
13842}
13843
13844/// JSONPathRecursive
13845#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13846#[cfg_attr(feature = "bindings", derive(TS))]
13847pub struct JSONPathRecursive {
13848    #[serde(default)]
13849    pub this: Option<Box<Expression>>,
13850}
13851
13852/// JSONPathScript
13853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13854#[cfg_attr(feature = "bindings", derive(TS))]
13855pub struct JSONPathScript {
13856    pub this: Box<Expression>,
13857}
13858
13859/// JSONPathSlice
13860#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13861#[cfg_attr(feature = "bindings", derive(TS))]
13862pub struct JSONPathSlice {
13863    #[serde(default)]
13864    pub start: Option<Box<Expression>>,
13865    #[serde(default)]
13866    pub end: Option<Box<Expression>>,
13867    #[serde(default)]
13868    pub step: Option<Box<Expression>>,
13869}
13870
13871/// JSONPathSelector
13872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13873#[cfg_attr(feature = "bindings", derive(TS))]
13874pub struct JSONPathSelector {
13875    pub this: Box<Expression>,
13876}
13877
13878/// JSONPathSubscript
13879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13880#[cfg_attr(feature = "bindings", derive(TS))]
13881pub struct JSONPathSubscript {
13882    pub this: Box<Expression>,
13883}
13884
13885/// JSONPathUnion
13886#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13887#[cfg_attr(feature = "bindings", derive(TS))]
13888pub struct JSONPathUnion {
13889    #[serde(default)]
13890    pub expressions: Vec<Expression>,
13891}
13892
13893/// Format
13894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13895#[cfg_attr(feature = "bindings", derive(TS))]
13896pub struct Format {
13897    pub this: Box<Expression>,
13898    #[serde(default)]
13899    pub expressions: Vec<Expression>,
13900}
13901
13902/// JSONKeys
13903#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13904#[cfg_attr(feature = "bindings", derive(TS))]
13905pub struct JSONKeys {
13906    pub this: Box<Expression>,
13907    #[serde(default)]
13908    pub expression: Option<Box<Expression>>,
13909    #[serde(default)]
13910    pub expressions: Vec<Expression>,
13911}
13912
13913/// JSONKeyValue
13914#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13915#[cfg_attr(feature = "bindings", derive(TS))]
13916pub struct JSONKeyValue {
13917    pub this: Box<Expression>,
13918    pub expression: Box<Expression>,
13919}
13920
13921/// JSONKeysAtDepth
13922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13923#[cfg_attr(feature = "bindings", derive(TS))]
13924pub struct JSONKeysAtDepth {
13925    pub this: Box<Expression>,
13926    #[serde(default)]
13927    pub expression: Option<Box<Expression>>,
13928    #[serde(default)]
13929    pub mode: Option<Box<Expression>>,
13930}
13931
13932/// JSONObject
13933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13934#[cfg_attr(feature = "bindings", derive(TS))]
13935pub struct JSONObject {
13936    #[serde(default)]
13937    pub expressions: Vec<Expression>,
13938    #[serde(default)]
13939    pub null_handling: Option<Box<Expression>>,
13940    #[serde(default)]
13941    pub unique_keys: Option<Box<Expression>>,
13942    #[serde(default)]
13943    pub return_type: Option<Box<Expression>>,
13944    #[serde(default)]
13945    pub encoding: Option<Box<Expression>>,
13946}
13947
13948/// JSONObjectAgg
13949#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13950#[cfg_attr(feature = "bindings", derive(TS))]
13951pub struct JSONObjectAgg {
13952    #[serde(default)]
13953    pub expressions: Vec<Expression>,
13954    #[serde(default)]
13955    pub null_handling: Option<Box<Expression>>,
13956    #[serde(default)]
13957    pub unique_keys: Option<Box<Expression>>,
13958    #[serde(default)]
13959    pub return_type: Option<Box<Expression>>,
13960    #[serde(default)]
13961    pub encoding: Option<Box<Expression>>,
13962}
13963
13964/// JSONBObjectAgg
13965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13966#[cfg_attr(feature = "bindings", derive(TS))]
13967pub struct JSONBObjectAgg {
13968    pub this: Box<Expression>,
13969    pub expression: Box<Expression>,
13970}
13971
13972/// JSONArray
13973#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13974#[cfg_attr(feature = "bindings", derive(TS))]
13975pub struct JSONArray {
13976    #[serde(default)]
13977    pub expressions: Vec<Expression>,
13978    #[serde(default)]
13979    pub null_handling: Option<Box<Expression>>,
13980    #[serde(default)]
13981    pub return_type: Option<Box<Expression>>,
13982    #[serde(default)]
13983    pub strict: Option<Box<Expression>>,
13984}
13985
13986/// JSONArrayAgg
13987#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13988#[cfg_attr(feature = "bindings", derive(TS))]
13989pub struct JSONArrayAgg {
13990    pub this: Box<Expression>,
13991    #[serde(default)]
13992    pub order: Option<Box<Expression>>,
13993    #[serde(default)]
13994    pub null_handling: Option<Box<Expression>>,
13995    #[serde(default)]
13996    pub return_type: Option<Box<Expression>>,
13997    #[serde(default)]
13998    pub strict: Option<Box<Expression>>,
13999}
14000
14001/// JSONExists
14002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14003#[cfg_attr(feature = "bindings", derive(TS))]
14004pub struct JSONExists {
14005    pub this: Box<Expression>,
14006    #[serde(default)]
14007    pub path: Option<Box<Expression>>,
14008    #[serde(default)]
14009    pub passing: Option<Box<Expression>>,
14010    #[serde(default)]
14011    pub on_condition: Option<Box<Expression>>,
14012    #[serde(default)]
14013    pub from_dcolonqmark: Option<Box<Expression>>,
14014}
14015
14016/// JSONColumnDef
14017#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14018#[cfg_attr(feature = "bindings", derive(TS))]
14019pub struct JSONColumnDef {
14020    #[serde(default)]
14021    pub this: Option<Box<Expression>>,
14022    #[serde(default)]
14023    pub kind: Option<String>,
14024    #[serde(default)]
14025    pub format_json: bool,
14026    #[serde(default)]
14027    pub path: Option<Box<Expression>>,
14028    #[serde(default)]
14029    pub nested_schema: Option<Box<Expression>>,
14030    #[serde(default)]
14031    pub ordinality: Option<Box<Expression>>,
14032}
14033
14034/// JSONSchema
14035#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14036#[cfg_attr(feature = "bindings", derive(TS))]
14037pub struct JSONSchema {
14038    #[serde(default)]
14039    pub expressions: Vec<Expression>,
14040}
14041
14042/// JSONSet
14043#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14044#[cfg_attr(feature = "bindings", derive(TS))]
14045pub struct JSONSet {
14046    pub this: Box<Expression>,
14047    #[serde(default)]
14048    pub expressions: Vec<Expression>,
14049}
14050
14051/// JSONStripNulls
14052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14053#[cfg_attr(feature = "bindings", derive(TS))]
14054pub struct JSONStripNulls {
14055    pub this: Box<Expression>,
14056    #[serde(default)]
14057    pub expression: Option<Box<Expression>>,
14058    #[serde(default)]
14059    pub include_arrays: Option<Box<Expression>>,
14060    #[serde(default)]
14061    pub remove_empty: Option<Box<Expression>>,
14062}
14063
14064/// JSONValue
14065#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14066#[cfg_attr(feature = "bindings", derive(TS))]
14067pub struct JSONValue {
14068    pub this: Box<Expression>,
14069    #[serde(default)]
14070    pub path: Option<Box<Expression>>,
14071    #[serde(default)]
14072    pub returning: Option<Box<Expression>>,
14073    #[serde(default)]
14074    pub on_condition: Option<Box<Expression>>,
14075}
14076
14077/// JSONValueArray
14078#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14079#[cfg_attr(feature = "bindings", derive(TS))]
14080pub struct JSONValueArray {
14081    pub this: Box<Expression>,
14082    #[serde(default)]
14083    pub expression: Option<Box<Expression>>,
14084}
14085
14086/// JSONRemove
14087#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14088#[cfg_attr(feature = "bindings", derive(TS))]
14089pub struct JSONRemove {
14090    pub this: Box<Expression>,
14091    #[serde(default)]
14092    pub expressions: Vec<Expression>,
14093}
14094
14095/// JSONTable
14096#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14097#[cfg_attr(feature = "bindings", derive(TS))]
14098pub struct JSONTable {
14099    pub this: Box<Expression>,
14100    #[serde(default)]
14101    pub schema: Option<Box<Expression>>,
14102    #[serde(default)]
14103    pub path: Option<Box<Expression>>,
14104    #[serde(default)]
14105    pub error_handling: Option<Box<Expression>>,
14106    #[serde(default)]
14107    pub empty_handling: Option<Box<Expression>>,
14108}
14109
14110/// JSONType
14111#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14112#[cfg_attr(feature = "bindings", derive(TS))]
14113pub struct JSONType {
14114    pub this: Box<Expression>,
14115    #[serde(default)]
14116    pub expression: Option<Box<Expression>>,
14117}
14118
14119/// ObjectInsert
14120#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14121#[cfg_attr(feature = "bindings", derive(TS))]
14122pub struct ObjectInsert {
14123    pub this: Box<Expression>,
14124    #[serde(default)]
14125    pub key: Option<Box<Expression>>,
14126    #[serde(default)]
14127    pub value: Option<Box<Expression>>,
14128    #[serde(default)]
14129    pub update_flag: Option<Box<Expression>>,
14130}
14131
14132/// OpenJSONColumnDef
14133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14134#[cfg_attr(feature = "bindings", derive(TS))]
14135pub struct OpenJSONColumnDef {
14136    pub this: Box<Expression>,
14137    pub kind: String,
14138    #[serde(default)]
14139    pub path: Option<Box<Expression>>,
14140    #[serde(default)]
14141    pub as_json: Option<Box<Expression>>,
14142    /// The parsed data type for proper generation
14143    #[serde(default, skip_serializing_if = "Option::is_none")]
14144    pub data_type: Option<DataType>,
14145}
14146
14147/// OpenJSON
14148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14149#[cfg_attr(feature = "bindings", derive(TS))]
14150pub struct OpenJSON {
14151    pub this: Box<Expression>,
14152    #[serde(default)]
14153    pub path: Option<Box<Expression>>,
14154    #[serde(default)]
14155    pub expressions: Vec<Expression>,
14156}
14157
14158/// JSONBExists
14159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14160#[cfg_attr(feature = "bindings", derive(TS))]
14161pub struct JSONBExists {
14162    pub this: Box<Expression>,
14163    #[serde(default)]
14164    pub path: Option<Box<Expression>>,
14165}
14166
14167/// JSONCast
14168#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14169#[cfg_attr(feature = "bindings", derive(TS))]
14170pub struct JSONCast {
14171    pub this: Box<Expression>,
14172    pub to: DataType,
14173}
14174
14175/// JSONExtract
14176#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14177#[cfg_attr(feature = "bindings", derive(TS))]
14178pub struct JSONExtract {
14179    pub this: Box<Expression>,
14180    pub expression: Box<Expression>,
14181    #[serde(default)]
14182    pub only_json_types: Option<Box<Expression>>,
14183    #[serde(default)]
14184    pub expressions: Vec<Expression>,
14185    #[serde(default)]
14186    pub variant_extract: Option<Box<Expression>>,
14187    #[serde(default)]
14188    pub json_query: Option<Box<Expression>>,
14189    #[serde(default)]
14190    pub option: Option<Box<Expression>>,
14191    #[serde(default)]
14192    pub quote: Option<Box<Expression>>,
14193    #[serde(default)]
14194    pub on_condition: Option<Box<Expression>>,
14195    #[serde(default)]
14196    pub requires_json: Option<Box<Expression>>,
14197}
14198
14199/// JSONExtractQuote
14200#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14201#[cfg_attr(feature = "bindings", derive(TS))]
14202pub struct JSONExtractQuote {
14203    #[serde(default)]
14204    pub option: Option<Box<Expression>>,
14205    #[serde(default)]
14206    pub scalar: Option<Box<Expression>>,
14207}
14208
14209/// JSONExtractArray
14210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14211#[cfg_attr(feature = "bindings", derive(TS))]
14212pub struct JSONExtractArray {
14213    pub this: Box<Expression>,
14214    #[serde(default)]
14215    pub expression: Option<Box<Expression>>,
14216}
14217
14218/// JSONExtractScalar
14219#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14220#[cfg_attr(feature = "bindings", derive(TS))]
14221pub struct JSONExtractScalar {
14222    pub this: Box<Expression>,
14223    pub expression: Box<Expression>,
14224    #[serde(default)]
14225    pub only_json_types: Option<Box<Expression>>,
14226    #[serde(default)]
14227    pub expressions: Vec<Expression>,
14228    #[serde(default)]
14229    pub json_type: Option<Box<Expression>>,
14230    #[serde(default)]
14231    pub scalar_only: Option<Box<Expression>>,
14232}
14233
14234/// JSONBExtractScalar
14235#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14236#[cfg_attr(feature = "bindings", derive(TS))]
14237pub struct JSONBExtractScalar {
14238    pub this: Box<Expression>,
14239    pub expression: Box<Expression>,
14240    #[serde(default)]
14241    pub json_type: Option<Box<Expression>>,
14242}
14243
14244/// JSONFormat
14245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14246#[cfg_attr(feature = "bindings", derive(TS))]
14247pub struct JSONFormat {
14248    #[serde(default)]
14249    pub this: Option<Box<Expression>>,
14250    #[serde(default)]
14251    pub options: Vec<Expression>,
14252    #[serde(default)]
14253    pub is_json: Option<Box<Expression>>,
14254    #[serde(default)]
14255    pub to_json: Option<Box<Expression>>,
14256}
14257
14258/// JSONArrayAppend
14259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14260#[cfg_attr(feature = "bindings", derive(TS))]
14261pub struct JSONArrayAppend {
14262    pub this: Box<Expression>,
14263    #[serde(default)]
14264    pub expressions: Vec<Expression>,
14265}
14266
14267/// JSONArrayContains
14268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14269#[cfg_attr(feature = "bindings", derive(TS))]
14270pub struct JSONArrayContains {
14271    pub this: Box<Expression>,
14272    pub expression: Box<Expression>,
14273    #[serde(default)]
14274    pub json_type: Option<Box<Expression>>,
14275}
14276
14277/// JSONArrayInsert
14278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14279#[cfg_attr(feature = "bindings", derive(TS))]
14280pub struct JSONArrayInsert {
14281    pub this: Box<Expression>,
14282    #[serde(default)]
14283    pub expressions: Vec<Expression>,
14284}
14285
14286/// ParseJSON
14287#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14288#[cfg_attr(feature = "bindings", derive(TS))]
14289pub struct ParseJSON {
14290    pub this: Box<Expression>,
14291    #[serde(default)]
14292    pub expression: Option<Box<Expression>>,
14293    #[serde(default)]
14294    pub safe: Option<Box<Expression>>,
14295}
14296
14297/// ParseUrl
14298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14299#[cfg_attr(feature = "bindings", derive(TS))]
14300pub struct ParseUrl {
14301    pub this: Box<Expression>,
14302    #[serde(default)]
14303    pub part_to_extract: Option<Box<Expression>>,
14304    #[serde(default)]
14305    pub key: Option<Box<Expression>>,
14306    #[serde(default)]
14307    pub permissive: Option<Box<Expression>>,
14308}
14309
14310/// ParseIp
14311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14312#[cfg_attr(feature = "bindings", derive(TS))]
14313pub struct ParseIp {
14314    pub this: Box<Expression>,
14315    #[serde(default)]
14316    pub type_: Option<Box<Expression>>,
14317    #[serde(default)]
14318    pub permissive: Option<Box<Expression>>,
14319}
14320
14321/// ParseTime
14322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14323#[cfg_attr(feature = "bindings", derive(TS))]
14324pub struct ParseTime {
14325    pub this: Box<Expression>,
14326    pub format: String,
14327}
14328
14329/// ParseDatetime
14330#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14331#[cfg_attr(feature = "bindings", derive(TS))]
14332pub struct ParseDatetime {
14333    pub this: Box<Expression>,
14334    #[serde(default)]
14335    pub format: Option<String>,
14336    #[serde(default)]
14337    pub zone: Option<Box<Expression>>,
14338}
14339
14340/// Map
14341#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14342#[cfg_attr(feature = "bindings", derive(TS))]
14343pub struct Map {
14344    #[serde(default)]
14345    pub keys: Vec<Expression>,
14346    #[serde(default)]
14347    pub values: Vec<Expression>,
14348}
14349
14350/// MapCat
14351#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14352#[cfg_attr(feature = "bindings", derive(TS))]
14353pub struct MapCat {
14354    pub this: Box<Expression>,
14355    pub expression: Box<Expression>,
14356}
14357
14358/// MapDelete
14359#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14360#[cfg_attr(feature = "bindings", derive(TS))]
14361pub struct MapDelete {
14362    pub this: Box<Expression>,
14363    #[serde(default)]
14364    pub expressions: Vec<Expression>,
14365}
14366
14367/// MapInsert
14368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14369#[cfg_attr(feature = "bindings", derive(TS))]
14370pub struct MapInsert {
14371    pub this: Box<Expression>,
14372    #[serde(default)]
14373    pub key: Option<Box<Expression>>,
14374    #[serde(default)]
14375    pub value: Option<Box<Expression>>,
14376    #[serde(default)]
14377    pub update_flag: Option<Box<Expression>>,
14378}
14379
14380/// MapPick
14381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14382#[cfg_attr(feature = "bindings", derive(TS))]
14383pub struct MapPick {
14384    pub this: Box<Expression>,
14385    #[serde(default)]
14386    pub expressions: Vec<Expression>,
14387}
14388
14389/// ScopeResolution
14390#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14391#[cfg_attr(feature = "bindings", derive(TS))]
14392pub struct ScopeResolution {
14393    #[serde(default)]
14394    pub this: Option<Box<Expression>>,
14395    pub expression: Box<Expression>,
14396}
14397
14398/// Slice
14399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14400#[cfg_attr(feature = "bindings", derive(TS))]
14401pub struct Slice {
14402    #[serde(default)]
14403    pub this: Option<Box<Expression>>,
14404    #[serde(default)]
14405    pub expression: Option<Box<Expression>>,
14406    #[serde(default)]
14407    pub step: Option<Box<Expression>>,
14408}
14409
14410/// VarMap
14411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14412#[cfg_attr(feature = "bindings", derive(TS))]
14413pub struct VarMap {
14414    #[serde(default)]
14415    pub keys: Vec<Expression>,
14416    #[serde(default)]
14417    pub values: Vec<Expression>,
14418}
14419
14420/// MatchAgainst
14421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14422#[cfg_attr(feature = "bindings", derive(TS))]
14423pub struct MatchAgainst {
14424    pub this: Box<Expression>,
14425    #[serde(default)]
14426    pub expressions: Vec<Expression>,
14427    #[serde(default)]
14428    pub modifier: Option<Box<Expression>>,
14429}
14430
14431/// MD5Digest
14432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14433#[cfg_attr(feature = "bindings", derive(TS))]
14434pub struct MD5Digest {
14435    pub this: Box<Expression>,
14436    #[serde(default)]
14437    pub expressions: Vec<Expression>,
14438}
14439
14440/// Monthname
14441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14442#[cfg_attr(feature = "bindings", derive(TS))]
14443pub struct Monthname {
14444    pub this: Box<Expression>,
14445    #[serde(default)]
14446    pub abbreviated: Option<Box<Expression>>,
14447}
14448
14449/// Ntile
14450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14451#[cfg_attr(feature = "bindings", derive(TS))]
14452pub struct Ntile {
14453    #[serde(default)]
14454    pub this: Option<Box<Expression>>,
14455}
14456
14457/// Normalize
14458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14459#[cfg_attr(feature = "bindings", derive(TS))]
14460pub struct Normalize {
14461    pub this: Box<Expression>,
14462    #[serde(default)]
14463    pub form: Option<Box<Expression>>,
14464    #[serde(default)]
14465    pub is_casefold: Option<Box<Expression>>,
14466}
14467
14468/// Normal
14469#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14470#[cfg_attr(feature = "bindings", derive(TS))]
14471pub struct Normal {
14472    pub this: Box<Expression>,
14473    #[serde(default)]
14474    pub stddev: Option<Box<Expression>>,
14475    #[serde(default)]
14476    pub gen: Option<Box<Expression>>,
14477}
14478
14479/// Predict
14480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14481#[cfg_attr(feature = "bindings", derive(TS))]
14482pub struct Predict {
14483    pub this: Box<Expression>,
14484    pub expression: Box<Expression>,
14485    #[serde(default)]
14486    pub params_struct: Option<Box<Expression>>,
14487}
14488
14489/// MLTranslate
14490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14491#[cfg_attr(feature = "bindings", derive(TS))]
14492pub struct MLTranslate {
14493    pub this: Box<Expression>,
14494    pub expression: Box<Expression>,
14495    #[serde(default)]
14496    pub params_struct: Option<Box<Expression>>,
14497}
14498
14499/// FeaturesAtTime
14500#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14501#[cfg_attr(feature = "bindings", derive(TS))]
14502pub struct FeaturesAtTime {
14503    pub this: Box<Expression>,
14504    #[serde(default)]
14505    pub time: Option<Box<Expression>>,
14506    #[serde(default)]
14507    pub num_rows: Option<Box<Expression>>,
14508    #[serde(default)]
14509    pub ignore_feature_nulls: Option<Box<Expression>>,
14510}
14511
14512/// GenerateEmbedding
14513#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14514#[cfg_attr(feature = "bindings", derive(TS))]
14515pub struct GenerateEmbedding {
14516    pub this: Box<Expression>,
14517    pub expression: Box<Expression>,
14518    #[serde(default)]
14519    pub params_struct: Option<Box<Expression>>,
14520    #[serde(default)]
14521    pub is_text: Option<Box<Expression>>,
14522}
14523
14524/// MLForecast
14525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14526#[cfg_attr(feature = "bindings", derive(TS))]
14527pub struct MLForecast {
14528    pub this: Box<Expression>,
14529    #[serde(default)]
14530    pub expression: Option<Box<Expression>>,
14531    #[serde(default)]
14532    pub params_struct: Option<Box<Expression>>,
14533}
14534
14535/// ModelAttribute
14536#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14537#[cfg_attr(feature = "bindings", derive(TS))]
14538pub struct ModelAttribute {
14539    pub this: Box<Expression>,
14540    pub expression: Box<Expression>,
14541}
14542
14543/// VectorSearch
14544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14545#[cfg_attr(feature = "bindings", derive(TS))]
14546pub struct VectorSearch {
14547    pub this: Box<Expression>,
14548    #[serde(default)]
14549    pub column_to_search: Option<Box<Expression>>,
14550    #[serde(default)]
14551    pub query_table: Option<Box<Expression>>,
14552    #[serde(default)]
14553    pub query_column_to_search: Option<Box<Expression>>,
14554    #[serde(default)]
14555    pub top_k: Option<Box<Expression>>,
14556    #[serde(default)]
14557    pub distance_type: Option<Box<Expression>>,
14558    #[serde(default)]
14559    pub options: Vec<Expression>,
14560}
14561
14562/// Quantile
14563#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14564#[cfg_attr(feature = "bindings", derive(TS))]
14565pub struct Quantile {
14566    pub this: Box<Expression>,
14567    #[serde(default)]
14568    pub quantile: Option<Box<Expression>>,
14569}
14570
14571/// ApproxQuantile
14572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14573#[cfg_attr(feature = "bindings", derive(TS))]
14574pub struct ApproxQuantile {
14575    pub this: Box<Expression>,
14576    #[serde(default)]
14577    pub quantile: Option<Box<Expression>>,
14578    #[serde(default)]
14579    pub accuracy: Option<Box<Expression>>,
14580    #[serde(default)]
14581    pub weight: Option<Box<Expression>>,
14582    #[serde(default)]
14583    pub error_tolerance: Option<Box<Expression>>,
14584}
14585
14586/// ApproxPercentileEstimate
14587#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14588#[cfg_attr(feature = "bindings", derive(TS))]
14589pub struct ApproxPercentileEstimate {
14590    pub this: Box<Expression>,
14591    #[serde(default)]
14592    pub percentile: Option<Box<Expression>>,
14593}
14594
14595/// Randn
14596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14597#[cfg_attr(feature = "bindings", derive(TS))]
14598pub struct Randn {
14599    #[serde(default)]
14600    pub this: Option<Box<Expression>>,
14601}
14602
14603/// Randstr
14604#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14605#[cfg_attr(feature = "bindings", derive(TS))]
14606pub struct Randstr {
14607    pub this: Box<Expression>,
14608    #[serde(default)]
14609    pub generator: Option<Box<Expression>>,
14610}
14611
14612/// RangeN
14613#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14614#[cfg_attr(feature = "bindings", derive(TS))]
14615pub struct RangeN {
14616    pub this: Box<Expression>,
14617    #[serde(default)]
14618    pub expressions: Vec<Expression>,
14619    #[serde(default)]
14620    pub each: Option<Box<Expression>>,
14621}
14622
14623/// RangeBucket
14624#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14625#[cfg_attr(feature = "bindings", derive(TS))]
14626pub struct RangeBucket {
14627    pub this: Box<Expression>,
14628    pub expression: Box<Expression>,
14629}
14630
14631/// ReadCSV
14632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14633#[cfg_attr(feature = "bindings", derive(TS))]
14634pub struct ReadCSV {
14635    pub this: Box<Expression>,
14636    #[serde(default)]
14637    pub expressions: Vec<Expression>,
14638}
14639
14640/// ReadParquet
14641#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14642#[cfg_attr(feature = "bindings", derive(TS))]
14643pub struct ReadParquet {
14644    #[serde(default)]
14645    pub expressions: Vec<Expression>,
14646}
14647
14648/// Reduce
14649#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14650#[cfg_attr(feature = "bindings", derive(TS))]
14651pub struct Reduce {
14652    pub this: Box<Expression>,
14653    #[serde(default)]
14654    pub initial: Option<Box<Expression>>,
14655    #[serde(default)]
14656    pub merge: Option<Box<Expression>>,
14657    #[serde(default)]
14658    pub finish: Option<Box<Expression>>,
14659}
14660
14661/// RegexpExtractAll
14662#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14663#[cfg_attr(feature = "bindings", derive(TS))]
14664pub struct RegexpExtractAll {
14665    pub this: Box<Expression>,
14666    pub expression: Box<Expression>,
14667    #[serde(default)]
14668    pub group: Option<Box<Expression>>,
14669    #[serde(default)]
14670    pub parameters: Option<Box<Expression>>,
14671    #[serde(default)]
14672    pub position: Option<Box<Expression>>,
14673    #[serde(default)]
14674    pub occurrence: Option<Box<Expression>>,
14675}
14676
14677/// RegexpILike
14678#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14679#[cfg_attr(feature = "bindings", derive(TS))]
14680pub struct RegexpILike {
14681    pub this: Box<Expression>,
14682    pub expression: Box<Expression>,
14683    #[serde(default)]
14684    pub flag: Option<Box<Expression>>,
14685}
14686
14687/// RegexpFullMatch
14688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14689#[cfg_attr(feature = "bindings", derive(TS))]
14690pub struct RegexpFullMatch {
14691    pub this: Box<Expression>,
14692    pub expression: Box<Expression>,
14693    #[serde(default)]
14694    pub options: Vec<Expression>,
14695}
14696
14697/// RegexpInstr
14698#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14699#[cfg_attr(feature = "bindings", derive(TS))]
14700pub struct RegexpInstr {
14701    pub this: Box<Expression>,
14702    pub expression: Box<Expression>,
14703    #[serde(default)]
14704    pub position: Option<Box<Expression>>,
14705    #[serde(default)]
14706    pub occurrence: Option<Box<Expression>>,
14707    #[serde(default)]
14708    pub option: Option<Box<Expression>>,
14709    #[serde(default)]
14710    pub parameters: Option<Box<Expression>>,
14711    #[serde(default)]
14712    pub group: Option<Box<Expression>>,
14713}
14714
14715/// RegexpSplit
14716#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14717#[cfg_attr(feature = "bindings", derive(TS))]
14718pub struct RegexpSplit {
14719    pub this: Box<Expression>,
14720    pub expression: Box<Expression>,
14721    #[serde(default)]
14722    pub limit: Option<Box<Expression>>,
14723}
14724
14725/// RegexpCount
14726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14727#[cfg_attr(feature = "bindings", derive(TS))]
14728pub struct RegexpCount {
14729    pub this: Box<Expression>,
14730    pub expression: Box<Expression>,
14731    #[serde(default)]
14732    pub position: Option<Box<Expression>>,
14733    #[serde(default)]
14734    pub parameters: Option<Box<Expression>>,
14735}
14736
14737/// RegrValx
14738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14739#[cfg_attr(feature = "bindings", derive(TS))]
14740pub struct RegrValx {
14741    pub this: Box<Expression>,
14742    pub expression: Box<Expression>,
14743}
14744
14745/// RegrValy
14746#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14747#[cfg_attr(feature = "bindings", derive(TS))]
14748pub struct RegrValy {
14749    pub this: Box<Expression>,
14750    pub expression: Box<Expression>,
14751}
14752
14753/// RegrAvgy
14754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14755#[cfg_attr(feature = "bindings", derive(TS))]
14756pub struct RegrAvgy {
14757    pub this: Box<Expression>,
14758    pub expression: Box<Expression>,
14759}
14760
14761/// RegrAvgx
14762#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14763#[cfg_attr(feature = "bindings", derive(TS))]
14764pub struct RegrAvgx {
14765    pub this: Box<Expression>,
14766    pub expression: Box<Expression>,
14767}
14768
14769/// RegrCount
14770#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14771#[cfg_attr(feature = "bindings", derive(TS))]
14772pub struct RegrCount {
14773    pub this: Box<Expression>,
14774    pub expression: Box<Expression>,
14775}
14776
14777/// RegrIntercept
14778#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14779#[cfg_attr(feature = "bindings", derive(TS))]
14780pub struct RegrIntercept {
14781    pub this: Box<Expression>,
14782    pub expression: Box<Expression>,
14783}
14784
14785/// RegrR2
14786#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14787#[cfg_attr(feature = "bindings", derive(TS))]
14788pub struct RegrR2 {
14789    pub this: Box<Expression>,
14790    pub expression: Box<Expression>,
14791}
14792
14793/// RegrSxx
14794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14795#[cfg_attr(feature = "bindings", derive(TS))]
14796pub struct RegrSxx {
14797    pub this: Box<Expression>,
14798    pub expression: Box<Expression>,
14799}
14800
14801/// RegrSxy
14802#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14803#[cfg_attr(feature = "bindings", derive(TS))]
14804pub struct RegrSxy {
14805    pub this: Box<Expression>,
14806    pub expression: Box<Expression>,
14807}
14808
14809/// RegrSyy
14810#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14811#[cfg_attr(feature = "bindings", derive(TS))]
14812pub struct RegrSyy {
14813    pub this: Box<Expression>,
14814    pub expression: Box<Expression>,
14815}
14816
14817/// RegrSlope
14818#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14819#[cfg_attr(feature = "bindings", derive(TS))]
14820pub struct RegrSlope {
14821    pub this: Box<Expression>,
14822    pub expression: Box<Expression>,
14823}
14824
14825/// SafeAdd
14826#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14827#[cfg_attr(feature = "bindings", derive(TS))]
14828pub struct SafeAdd {
14829    pub this: Box<Expression>,
14830    pub expression: Box<Expression>,
14831}
14832
14833/// SafeDivide
14834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14835#[cfg_attr(feature = "bindings", derive(TS))]
14836pub struct SafeDivide {
14837    pub this: Box<Expression>,
14838    pub expression: Box<Expression>,
14839}
14840
14841/// SafeMultiply
14842#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14843#[cfg_attr(feature = "bindings", derive(TS))]
14844pub struct SafeMultiply {
14845    pub this: Box<Expression>,
14846    pub expression: Box<Expression>,
14847}
14848
14849/// SafeSubtract
14850#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14851#[cfg_attr(feature = "bindings", derive(TS))]
14852pub struct SafeSubtract {
14853    pub this: Box<Expression>,
14854    pub expression: Box<Expression>,
14855}
14856
14857/// SHA2
14858#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14859#[cfg_attr(feature = "bindings", derive(TS))]
14860pub struct SHA2 {
14861    pub this: Box<Expression>,
14862    #[serde(default)]
14863    pub length: Option<i64>,
14864}
14865
14866/// SHA2Digest
14867#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14868#[cfg_attr(feature = "bindings", derive(TS))]
14869pub struct SHA2Digest {
14870    pub this: Box<Expression>,
14871    #[serde(default)]
14872    pub length: Option<i64>,
14873}
14874
14875/// SortArray
14876#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14877#[cfg_attr(feature = "bindings", derive(TS))]
14878pub struct SortArray {
14879    pub this: Box<Expression>,
14880    #[serde(default)]
14881    pub asc: Option<Box<Expression>>,
14882    #[serde(default)]
14883    pub nulls_first: Option<Box<Expression>>,
14884}
14885
14886/// SplitPart
14887#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14888#[cfg_attr(feature = "bindings", derive(TS))]
14889pub struct SplitPart {
14890    pub this: Box<Expression>,
14891    #[serde(default)]
14892    pub delimiter: Option<Box<Expression>>,
14893    #[serde(default)]
14894    pub part_index: Option<Box<Expression>>,
14895}
14896
14897/// SUBSTRING_INDEX(str, delim, count)
14898#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14899#[cfg_attr(feature = "bindings", derive(TS))]
14900pub struct SubstringIndex {
14901    pub this: Box<Expression>,
14902    #[serde(default)]
14903    pub delimiter: Option<Box<Expression>>,
14904    #[serde(default)]
14905    pub count: Option<Box<Expression>>,
14906}
14907
14908/// StandardHash
14909#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14910#[cfg_attr(feature = "bindings", derive(TS))]
14911pub struct StandardHash {
14912    pub this: Box<Expression>,
14913    #[serde(default)]
14914    pub expression: Option<Box<Expression>>,
14915}
14916
14917/// StrPosition
14918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14919#[cfg_attr(feature = "bindings", derive(TS))]
14920pub struct StrPosition {
14921    pub this: Box<Expression>,
14922    #[serde(default)]
14923    pub substr: Option<Box<Expression>>,
14924    #[serde(default)]
14925    pub position: Option<Box<Expression>>,
14926    #[serde(default)]
14927    pub occurrence: Option<Box<Expression>>,
14928}
14929
14930/// Search
14931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14932#[cfg_attr(feature = "bindings", derive(TS))]
14933pub struct Search {
14934    pub this: Box<Expression>,
14935    pub expression: Box<Expression>,
14936    #[serde(default)]
14937    pub json_scope: Option<Box<Expression>>,
14938    #[serde(default)]
14939    pub analyzer: Option<Box<Expression>>,
14940    #[serde(default)]
14941    pub analyzer_options: Option<Box<Expression>>,
14942    #[serde(default)]
14943    pub search_mode: Option<Box<Expression>>,
14944}
14945
14946/// SearchIp
14947#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14948#[cfg_attr(feature = "bindings", derive(TS))]
14949pub struct SearchIp {
14950    pub this: Box<Expression>,
14951    pub expression: Box<Expression>,
14952}
14953
14954/// StrToDate
14955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14956#[cfg_attr(feature = "bindings", derive(TS))]
14957pub struct StrToDate {
14958    pub this: Box<Expression>,
14959    #[serde(default)]
14960    pub format: Option<String>,
14961    #[serde(default)]
14962    pub safe: Option<Box<Expression>>,
14963}
14964
14965/// StrToTime
14966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14967#[cfg_attr(feature = "bindings", derive(TS))]
14968pub struct StrToTime {
14969    pub this: Box<Expression>,
14970    pub format: String,
14971    #[serde(default)]
14972    pub zone: Option<Box<Expression>>,
14973    #[serde(default)]
14974    pub safe: Option<Box<Expression>>,
14975    #[serde(default)]
14976    pub target_type: Option<Box<Expression>>,
14977}
14978
14979/// StrToUnix
14980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14981#[cfg_attr(feature = "bindings", derive(TS))]
14982pub struct StrToUnix {
14983    #[serde(default)]
14984    pub this: Option<Box<Expression>>,
14985    #[serde(default)]
14986    pub format: Option<String>,
14987}
14988
14989/// StrToMap
14990#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14991#[cfg_attr(feature = "bindings", derive(TS))]
14992pub struct StrToMap {
14993    pub this: Box<Expression>,
14994    #[serde(default)]
14995    pub pair_delim: Option<Box<Expression>>,
14996    #[serde(default)]
14997    pub key_value_delim: Option<Box<Expression>>,
14998    #[serde(default)]
14999    pub duplicate_resolution_callback: Option<Box<Expression>>,
15000}
15001
15002/// NumberToStr
15003#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15004#[cfg_attr(feature = "bindings", derive(TS))]
15005pub struct NumberToStr {
15006    pub this: Box<Expression>,
15007    pub format: String,
15008    #[serde(default)]
15009    pub culture: Option<Box<Expression>>,
15010}
15011
15012/// FromBase
15013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15014#[cfg_attr(feature = "bindings", derive(TS))]
15015pub struct FromBase {
15016    pub this: Box<Expression>,
15017    pub expression: Box<Expression>,
15018}
15019
15020/// Stuff
15021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15022#[cfg_attr(feature = "bindings", derive(TS))]
15023pub struct Stuff {
15024    pub this: Box<Expression>,
15025    #[serde(default)]
15026    pub start: Option<Box<Expression>>,
15027    #[serde(default)]
15028    pub length: Option<i64>,
15029    pub expression: Box<Expression>,
15030}
15031
15032/// TimeToStr
15033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15034#[cfg_attr(feature = "bindings", derive(TS))]
15035pub struct TimeToStr {
15036    pub this: Box<Expression>,
15037    pub format: String,
15038    #[serde(default)]
15039    pub culture: Option<Box<Expression>>,
15040    #[serde(default)]
15041    pub zone: Option<Box<Expression>>,
15042}
15043
15044/// TimeStrToTime
15045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15046#[cfg_attr(feature = "bindings", derive(TS))]
15047pub struct TimeStrToTime {
15048    pub this: Box<Expression>,
15049    #[serde(default)]
15050    pub zone: Option<Box<Expression>>,
15051}
15052
15053/// TsOrDsAdd
15054#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15055#[cfg_attr(feature = "bindings", derive(TS))]
15056pub struct TsOrDsAdd {
15057    pub this: Box<Expression>,
15058    pub expression: Box<Expression>,
15059    #[serde(default)]
15060    pub unit: Option<String>,
15061    #[serde(default)]
15062    pub return_type: Option<Box<Expression>>,
15063}
15064
15065/// TsOrDsDiff
15066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15067#[cfg_attr(feature = "bindings", derive(TS))]
15068pub struct TsOrDsDiff {
15069    pub this: Box<Expression>,
15070    pub expression: Box<Expression>,
15071    #[serde(default)]
15072    pub unit: Option<String>,
15073}
15074
15075/// TsOrDsToDate
15076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15077#[cfg_attr(feature = "bindings", derive(TS))]
15078pub struct TsOrDsToDate {
15079    pub this: Box<Expression>,
15080    #[serde(default)]
15081    pub format: Option<String>,
15082    #[serde(default)]
15083    pub safe: Option<Box<Expression>>,
15084}
15085
15086/// TsOrDsToTime
15087#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15088#[cfg_attr(feature = "bindings", derive(TS))]
15089pub struct TsOrDsToTime {
15090    pub this: Box<Expression>,
15091    #[serde(default)]
15092    pub format: Option<String>,
15093    #[serde(default)]
15094    pub safe: Option<Box<Expression>>,
15095}
15096
15097/// Unhex
15098#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15099#[cfg_attr(feature = "bindings", derive(TS))]
15100pub struct Unhex {
15101    pub this: Box<Expression>,
15102    #[serde(default)]
15103    pub expression: Option<Box<Expression>>,
15104}
15105
15106/// Uniform
15107#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15108#[cfg_attr(feature = "bindings", derive(TS))]
15109pub struct Uniform {
15110    pub this: Box<Expression>,
15111    pub expression: Box<Expression>,
15112    #[serde(default)]
15113    pub gen: Option<Box<Expression>>,
15114    #[serde(default)]
15115    pub seed: Option<Box<Expression>>,
15116}
15117
15118/// UnixToStr
15119#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15120#[cfg_attr(feature = "bindings", derive(TS))]
15121pub struct UnixToStr {
15122    pub this: Box<Expression>,
15123    #[serde(default)]
15124    pub format: Option<String>,
15125}
15126
15127/// UnixToTime
15128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15129#[cfg_attr(feature = "bindings", derive(TS))]
15130pub struct UnixToTime {
15131    pub this: Box<Expression>,
15132    #[serde(default)]
15133    pub scale: Option<i64>,
15134    #[serde(default)]
15135    pub zone: Option<Box<Expression>>,
15136    #[serde(default)]
15137    pub hours: Option<Box<Expression>>,
15138    #[serde(default)]
15139    pub minutes: Option<Box<Expression>>,
15140    #[serde(default)]
15141    pub format: Option<String>,
15142    #[serde(default)]
15143    pub target_type: Option<Box<Expression>>,
15144}
15145
15146/// Uuid
15147#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15148#[cfg_attr(feature = "bindings", derive(TS))]
15149pub struct Uuid {
15150    #[serde(default)]
15151    pub this: Option<Box<Expression>>,
15152    #[serde(default)]
15153    pub name: Option<String>,
15154    #[serde(default)]
15155    pub is_string: Option<Box<Expression>>,
15156}
15157
15158/// TimestampFromParts
15159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15160#[cfg_attr(feature = "bindings", derive(TS))]
15161pub struct TimestampFromParts {
15162    #[serde(default)]
15163    pub zone: Option<Box<Expression>>,
15164    #[serde(default)]
15165    pub milli: Option<Box<Expression>>,
15166    #[serde(default)]
15167    pub this: Option<Box<Expression>>,
15168    #[serde(default)]
15169    pub expression: Option<Box<Expression>>,
15170}
15171
15172/// TimestampTzFromParts
15173#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15174#[cfg_attr(feature = "bindings", derive(TS))]
15175pub struct TimestampTzFromParts {
15176    #[serde(default)]
15177    pub zone: Option<Box<Expression>>,
15178}
15179
15180/// Corr
15181#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15182#[cfg_attr(feature = "bindings", derive(TS))]
15183pub struct Corr {
15184    pub this: Box<Expression>,
15185    pub expression: Box<Expression>,
15186    #[serde(default)]
15187    pub null_on_zero_variance: Option<Box<Expression>>,
15188}
15189
15190/// WidthBucket
15191#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15192#[cfg_attr(feature = "bindings", derive(TS))]
15193pub struct WidthBucket {
15194    pub this: Box<Expression>,
15195    #[serde(default)]
15196    pub min_value: Option<Box<Expression>>,
15197    #[serde(default)]
15198    pub max_value: Option<Box<Expression>>,
15199    #[serde(default)]
15200    pub num_buckets: Option<Box<Expression>>,
15201    #[serde(default)]
15202    pub threshold: Option<Box<Expression>>,
15203}
15204
15205/// CovarSamp
15206#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15207#[cfg_attr(feature = "bindings", derive(TS))]
15208pub struct CovarSamp {
15209    pub this: Box<Expression>,
15210    pub expression: Box<Expression>,
15211}
15212
15213/// CovarPop
15214#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15215#[cfg_attr(feature = "bindings", derive(TS))]
15216pub struct CovarPop {
15217    pub this: Box<Expression>,
15218    pub expression: Box<Expression>,
15219}
15220
15221/// Week
15222#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15223#[cfg_attr(feature = "bindings", derive(TS))]
15224pub struct Week {
15225    pub this: Box<Expression>,
15226    #[serde(default)]
15227    pub mode: Option<Box<Expression>>,
15228}
15229
15230/// XMLElement
15231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15232#[cfg_attr(feature = "bindings", derive(TS))]
15233pub struct XMLElement {
15234    pub this: Box<Expression>,
15235    #[serde(default)]
15236    pub expressions: Vec<Expression>,
15237    #[serde(default)]
15238    pub evalname: Option<Box<Expression>>,
15239}
15240
15241/// XMLGet
15242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15243#[cfg_attr(feature = "bindings", derive(TS))]
15244pub struct XMLGet {
15245    pub this: Box<Expression>,
15246    pub expression: Box<Expression>,
15247    #[serde(default)]
15248    pub instance: Option<Box<Expression>>,
15249}
15250
15251/// XMLTable
15252#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15253#[cfg_attr(feature = "bindings", derive(TS))]
15254pub struct XMLTable {
15255    pub this: Box<Expression>,
15256    #[serde(default)]
15257    pub namespaces: Option<Box<Expression>>,
15258    #[serde(default)]
15259    pub passing: Option<Box<Expression>>,
15260    #[serde(default)]
15261    pub columns: Vec<Expression>,
15262    #[serde(default)]
15263    pub by_ref: Option<Box<Expression>>,
15264}
15265
15266/// XMLKeyValueOption
15267#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15268#[cfg_attr(feature = "bindings", derive(TS))]
15269pub struct XMLKeyValueOption {
15270    pub this: Box<Expression>,
15271    #[serde(default)]
15272    pub expression: Option<Box<Expression>>,
15273}
15274
15275/// Zipf
15276#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15277#[cfg_attr(feature = "bindings", derive(TS))]
15278pub struct Zipf {
15279    pub this: Box<Expression>,
15280    #[serde(default)]
15281    pub elementcount: Option<Box<Expression>>,
15282    #[serde(default)]
15283    pub gen: Option<Box<Expression>>,
15284}
15285
15286/// Merge
15287#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15288#[cfg_attr(feature = "bindings", derive(TS))]
15289pub struct Merge {
15290    pub this: Box<Expression>,
15291    pub using: Box<Expression>,
15292    #[serde(default)]
15293    pub on: Option<Box<Expression>>,
15294    #[serde(default)]
15295    pub using_cond: Option<Box<Expression>>,
15296    #[serde(default)]
15297    pub whens: Option<Box<Expression>>,
15298    #[serde(default)]
15299    pub with_: Option<Box<Expression>>,
15300    #[serde(default)]
15301    pub returning: Option<Box<Expression>>,
15302}
15303
15304/// When
15305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15306#[cfg_attr(feature = "bindings", derive(TS))]
15307pub struct When {
15308    #[serde(default)]
15309    pub matched: Option<Box<Expression>>,
15310    #[serde(default)]
15311    pub source: Option<Box<Expression>>,
15312    #[serde(default)]
15313    pub condition: Option<Box<Expression>>,
15314    pub then: Box<Expression>,
15315}
15316
15317/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15318#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15319#[cfg_attr(feature = "bindings", derive(TS))]
15320pub struct Whens {
15321    #[serde(default)]
15322    pub expressions: Vec<Expression>,
15323}
15324
15325/// NextValueFor
15326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15327#[cfg_attr(feature = "bindings", derive(TS))]
15328pub struct NextValueFor {
15329    pub this: Box<Expression>,
15330    #[serde(default)]
15331    pub order: Option<Box<Expression>>,
15332}
15333
15334#[cfg(test)]
15335mod tests {
15336    use super::*;
15337
15338    #[test]
15339    #[cfg(feature = "bindings")]
15340    fn export_typescript_types() {
15341        // This test exports TypeScript types to the generated directory
15342        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
15343        Expression::export_all(&ts_rs::Config::default())
15344            .expect("Failed to export Expression types");
15345    }
15346
15347    #[test]
15348    fn test_simple_select_builder() {
15349        let select = Select::new()
15350            .column(Expression::star())
15351            .from(Expression::Table(Box::new(TableRef::new("users"))));
15352
15353        assert_eq!(select.expressions.len(), 1);
15354        assert!(select.from.is_some());
15355    }
15356
15357    #[test]
15358    fn test_expression_alias() {
15359        let expr = Expression::column("id").alias("user_id");
15360
15361        match expr {
15362            Expression::Alias(a) => {
15363                assert_eq!(a.alias.name, "user_id");
15364            }
15365            _ => panic!("Expected Alias"),
15366        }
15367    }
15368
15369    #[test]
15370    fn test_literal_creation() {
15371        let num = Expression::number(42);
15372        let str = Expression::string("hello");
15373
15374        match num {
15375            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
15376                let Literal::Number(n) = lit.as_ref() else {
15377                    unreachable!()
15378                };
15379                assert_eq!(n, "42")
15380            }
15381            _ => panic!("Expected Number"),
15382        }
15383
15384        match str {
15385            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
15386                let Literal::String(s) = lit.as_ref() else {
15387                    unreachable!()
15388                };
15389                assert_eq!(s, "hello")
15390            }
15391            _ => panic!("Expected String"),
15392        }
15393    }
15394
15395    #[test]
15396    fn test_expression_sql() {
15397        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
15398        assert_eq!(expr.sql(), "SELECT 1 + 2");
15399    }
15400
15401    #[test]
15402    fn test_expression_sql_for() {
15403        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
15404        let sql = expr.sql_for(crate::DialectType::Generic);
15405        // Generic mode normalizes IF() to CASE WHEN
15406        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
15407    }
15408}