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::IfFunc(f) => f.inferred_type.as_ref(),
1328            Expression::Nvl2(f) => f.inferred_type.as_ref(),
1329            Expression::Count(f) => f.inferred_type.as_ref(),
1330            Expression::GroupConcat(f) => f.inferred_type.as_ref(),
1331            Expression::StringAgg(f) => f.inferred_type.as_ref(),
1332            Expression::ListAgg(f) => f.inferred_type.as_ref(),
1333            Expression::SumIf(f) => f.inferred_type.as_ref(),
1334
1335            // UnaryFunc variants
1336            Expression::Upper(f)
1337            | Expression::Lower(f)
1338            | Expression::Length(f)
1339            | Expression::LTrim(f)
1340            | Expression::RTrim(f)
1341            | Expression::Reverse(f)
1342            | Expression::Abs(f)
1343            | Expression::Sqrt(f)
1344            | Expression::Cbrt(f)
1345            | Expression::Ln(f)
1346            | Expression::Exp(f)
1347            | Expression::Sign(f)
1348            | Expression::Date(f)
1349            | Expression::Time(f)
1350            | Expression::Initcap(f)
1351            | Expression::Ascii(f)
1352            | Expression::Chr(f)
1353            | Expression::Soundex(f)
1354            | Expression::ByteLength(f)
1355            | Expression::Hex(f)
1356            | Expression::LowerHex(f)
1357            | Expression::Unicode(f)
1358            | Expression::Typeof(f)
1359            | Expression::Explode(f)
1360            | Expression::ExplodeOuter(f)
1361            | Expression::MapFromEntries(f)
1362            | Expression::MapKeys(f)
1363            | Expression::MapValues(f)
1364            | Expression::ArrayLength(f)
1365            | Expression::ArraySize(f)
1366            | Expression::Cardinality(f)
1367            | Expression::ArrayReverse(f)
1368            | Expression::ArrayDistinct(f)
1369            | Expression::ArrayFlatten(f)
1370            | Expression::ArrayCompact(f)
1371            | Expression::ToArray(f)
1372            | Expression::JsonArrayLength(f)
1373            | Expression::JsonKeys(f)
1374            | Expression::JsonType(f)
1375            | Expression::ParseJson(f)
1376            | Expression::ToJson(f)
1377            | Expression::Radians(f)
1378            | Expression::Degrees(f)
1379            | Expression::Sin(f)
1380            | Expression::Cos(f)
1381            | Expression::Tan(f)
1382            | Expression::Asin(f)
1383            | Expression::Acos(f)
1384            | Expression::Atan(f)
1385            | Expression::IsNan(f)
1386            | Expression::IsInf(f)
1387            | Expression::Year(f)
1388            | Expression::Month(f)
1389            | Expression::Day(f)
1390            | Expression::Hour(f)
1391            | Expression::Minute(f)
1392            | Expression::Second(f)
1393            | Expression::DayOfWeek(f)
1394            | Expression::DayOfWeekIso(f)
1395            | Expression::DayOfMonth(f)
1396            | Expression::DayOfYear(f)
1397            | Expression::WeekOfYear(f)
1398            | Expression::Quarter(f)
1399            | Expression::Epoch(f)
1400            | Expression::EpochMs(f)
1401            | Expression::BitwiseCount(f)
1402            | Expression::DateFromUnixDate(f)
1403            | Expression::UnixDate(f)
1404            | Expression::UnixSeconds(f)
1405            | Expression::UnixMillis(f)
1406            | Expression::UnixMicros(f)
1407            | Expression::TimeStrToDate(f)
1408            | Expression::DateToDi(f)
1409            | Expression::DiToDate(f)
1410            | Expression::TsOrDiToDi(f)
1411            | Expression::TsOrDsToDatetime(f)
1412            | Expression::TsOrDsToTimestamp(f)
1413            | Expression::YearOfWeek(f)
1414            | Expression::YearOfWeekIso(f)
1415            | Expression::SHA(f)
1416            | Expression::SHA1Digest(f)
1417            | Expression::TimeToUnix(f)
1418            | Expression::TimeStrToUnix(f) => f.inferred_type.as_ref(),
1419
1420            // BinaryFunc variants
1421            Expression::Power(f)
1422            | Expression::NullIf(f)
1423            | Expression::IfNull(f)
1424            | Expression::Nvl(f)
1425            | Expression::Contains(f)
1426            | Expression::StartsWith(f)
1427            | Expression::EndsWith(f)
1428            | Expression::Levenshtein(f)
1429            | Expression::ModFunc(f)
1430            | Expression::IntDiv(f)
1431            | Expression::Atan2(f)
1432            | Expression::AddMonths(f)
1433            | Expression::MonthsBetween(f)
1434            | Expression::NextDay(f)
1435            | Expression::UnixToTimeStr(f)
1436            | Expression::ArrayContains(f)
1437            | Expression::ArrayPosition(f)
1438            | Expression::ArrayAppend(f)
1439            | Expression::ArrayPrepend(f)
1440            | Expression::ArrayUnion(f)
1441            | Expression::ArrayExcept(f)
1442            | Expression::ArrayRemove(f)
1443            | Expression::StarMap(f)
1444            | Expression::MapFromArrays(f)
1445            | Expression::MapContainsKey(f)
1446            | Expression::ElementAt(f)
1447            | Expression::JsonMergePatch(f) => f.inferred_type.as_ref(),
1448
1449            // VarArgFunc variants
1450            Expression::Coalesce(f)
1451            | Expression::Greatest(f)
1452            | Expression::Least(f)
1453            | Expression::ArrayConcat(f)
1454            | Expression::ArrayIntersect(f)
1455            | Expression::ArrayZip(f)
1456            | Expression::MapConcat(f)
1457            | Expression::JsonArray(f) => f.inferred_type.as_ref(),
1458
1459            // AggFunc variants
1460            Expression::Sum(f)
1461            | Expression::Avg(f)
1462            | Expression::Min(f)
1463            | Expression::Max(f)
1464            | Expression::ArrayAgg(f)
1465            | Expression::CountIf(f)
1466            | Expression::Stddev(f)
1467            | Expression::StddevPop(f)
1468            | Expression::StddevSamp(f)
1469            | Expression::Variance(f)
1470            | Expression::VarPop(f)
1471            | Expression::VarSamp(f)
1472            | Expression::Median(f)
1473            | Expression::Mode(f)
1474            | Expression::First(f)
1475            | Expression::Last(f)
1476            | Expression::AnyValue(f)
1477            | Expression::ApproxDistinct(f)
1478            | Expression::ApproxCountDistinct(f)
1479            | Expression::LogicalAnd(f)
1480            | Expression::LogicalOr(f)
1481            | Expression::Skewness(f)
1482            | Expression::ArrayConcatAgg(f)
1483            | Expression::ArrayUniqueAgg(f)
1484            | Expression::BoolXorAgg(f)
1485            | Expression::BitwiseAndAgg(f)
1486            | Expression::BitwiseOrAgg(f)
1487            | Expression::BitwiseXorAgg(f) => f.inferred_type.as_ref(),
1488
1489            // Everything else: no inferred_type field
1490            _ => None,
1491        }
1492    }
1493
1494    /// Set the inferred type annotation on this expression.
1495    ///
1496    /// Only has an effect on value-producing expressions with an `inferred_type`
1497    /// field. For other expression types, this is a no-op.
1498    pub fn set_inferred_type(&mut self, dt: DataType) {
1499        match self {
1500            Expression::And(op)
1501            | Expression::Or(op)
1502            | Expression::Add(op)
1503            | Expression::Sub(op)
1504            | Expression::Mul(op)
1505            | Expression::Div(op)
1506            | Expression::Mod(op)
1507            | Expression::Eq(op)
1508            | Expression::Neq(op)
1509            | Expression::Lt(op)
1510            | Expression::Lte(op)
1511            | Expression::Gt(op)
1512            | Expression::Gte(op)
1513            | Expression::Concat(op)
1514            | Expression::BitwiseAnd(op)
1515            | Expression::BitwiseOr(op)
1516            | Expression::BitwiseXor(op)
1517            | Expression::Adjacent(op)
1518            | Expression::TsMatch(op)
1519            | Expression::PropertyEQ(op)
1520            | Expression::ArrayContainsAll(op)
1521            | Expression::ArrayContainedBy(op)
1522            | Expression::ArrayOverlaps(op)
1523            | Expression::JSONBContainsAllTopKeys(op)
1524            | Expression::JSONBContainsAnyTopKeys(op)
1525            | Expression::JSONBDeleteAtPath(op)
1526            | Expression::ExtendsLeft(op)
1527            | Expression::ExtendsRight(op)
1528            | Expression::Is(op)
1529            | Expression::MemberOf(op)
1530            | Expression::Match(op)
1531            | Expression::NullSafeEq(op)
1532            | Expression::NullSafeNeq(op)
1533            | Expression::Glob(op)
1534            | Expression::BitwiseLeftShift(op)
1535            | Expression::BitwiseRightShift(op) => op.inferred_type = Some(dt),
1536
1537            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1538                op.inferred_type = Some(dt)
1539            }
1540
1541            Expression::Like(op) | Expression::ILike(op) => op.inferred_type = Some(dt),
1542
1543            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1544                c.inferred_type = Some(dt)
1545            }
1546
1547            Expression::Column(c) => c.inferred_type = Some(dt),
1548            Expression::Function(f) => f.inferred_type = Some(dt),
1549            Expression::AggregateFunction(f) => f.inferred_type = Some(dt),
1550            Expression::WindowFunction(f) => f.inferred_type = Some(dt),
1551            Expression::Case(c) => c.inferred_type = Some(dt),
1552            Expression::Subquery(s) => s.inferred_type = Some(dt),
1553            Expression::Alias(a) => a.inferred_type = Some(dt),
1554            Expression::IfFunc(f) => f.inferred_type = Some(dt),
1555            Expression::Nvl2(f) => f.inferred_type = Some(dt),
1556            Expression::Count(f) => f.inferred_type = Some(dt),
1557            Expression::GroupConcat(f) => f.inferred_type = Some(dt),
1558            Expression::StringAgg(f) => f.inferred_type = Some(dt),
1559            Expression::ListAgg(f) => f.inferred_type = Some(dt),
1560            Expression::SumIf(f) => f.inferred_type = Some(dt),
1561
1562            // UnaryFunc variants
1563            Expression::Upper(f)
1564            | Expression::Lower(f)
1565            | Expression::Length(f)
1566            | Expression::LTrim(f)
1567            | Expression::RTrim(f)
1568            | Expression::Reverse(f)
1569            | Expression::Abs(f)
1570            | Expression::Sqrt(f)
1571            | Expression::Cbrt(f)
1572            | Expression::Ln(f)
1573            | Expression::Exp(f)
1574            | Expression::Sign(f)
1575            | Expression::Date(f)
1576            | Expression::Time(f)
1577            | Expression::Initcap(f)
1578            | Expression::Ascii(f)
1579            | Expression::Chr(f)
1580            | Expression::Soundex(f)
1581            | Expression::ByteLength(f)
1582            | Expression::Hex(f)
1583            | Expression::LowerHex(f)
1584            | Expression::Unicode(f)
1585            | Expression::Typeof(f)
1586            | Expression::Explode(f)
1587            | Expression::ExplodeOuter(f)
1588            | Expression::MapFromEntries(f)
1589            | Expression::MapKeys(f)
1590            | Expression::MapValues(f)
1591            | Expression::ArrayLength(f)
1592            | Expression::ArraySize(f)
1593            | Expression::Cardinality(f)
1594            | Expression::ArrayReverse(f)
1595            | Expression::ArrayDistinct(f)
1596            | Expression::ArrayFlatten(f)
1597            | Expression::ArrayCompact(f)
1598            | Expression::ToArray(f)
1599            | Expression::JsonArrayLength(f)
1600            | Expression::JsonKeys(f)
1601            | Expression::JsonType(f)
1602            | Expression::ParseJson(f)
1603            | Expression::ToJson(f)
1604            | Expression::Radians(f)
1605            | Expression::Degrees(f)
1606            | Expression::Sin(f)
1607            | Expression::Cos(f)
1608            | Expression::Tan(f)
1609            | Expression::Asin(f)
1610            | Expression::Acos(f)
1611            | Expression::Atan(f)
1612            | Expression::IsNan(f)
1613            | Expression::IsInf(f)
1614            | Expression::Year(f)
1615            | Expression::Month(f)
1616            | Expression::Day(f)
1617            | Expression::Hour(f)
1618            | Expression::Minute(f)
1619            | Expression::Second(f)
1620            | Expression::DayOfWeek(f)
1621            | Expression::DayOfWeekIso(f)
1622            | Expression::DayOfMonth(f)
1623            | Expression::DayOfYear(f)
1624            | Expression::WeekOfYear(f)
1625            | Expression::Quarter(f)
1626            | Expression::Epoch(f)
1627            | Expression::EpochMs(f)
1628            | Expression::BitwiseCount(f)
1629            | Expression::DateFromUnixDate(f)
1630            | Expression::UnixDate(f)
1631            | Expression::UnixSeconds(f)
1632            | Expression::UnixMillis(f)
1633            | Expression::UnixMicros(f)
1634            | Expression::TimeStrToDate(f)
1635            | Expression::DateToDi(f)
1636            | Expression::DiToDate(f)
1637            | Expression::TsOrDiToDi(f)
1638            | Expression::TsOrDsToDatetime(f)
1639            | Expression::TsOrDsToTimestamp(f)
1640            | Expression::YearOfWeek(f)
1641            | Expression::YearOfWeekIso(f)
1642            | Expression::SHA(f)
1643            | Expression::SHA1Digest(f)
1644            | Expression::TimeToUnix(f)
1645            | Expression::TimeStrToUnix(f) => f.inferred_type = Some(dt),
1646
1647            // BinaryFunc variants
1648            Expression::Power(f)
1649            | Expression::NullIf(f)
1650            | Expression::IfNull(f)
1651            | Expression::Nvl(f)
1652            | Expression::Contains(f)
1653            | Expression::StartsWith(f)
1654            | Expression::EndsWith(f)
1655            | Expression::Levenshtein(f)
1656            | Expression::ModFunc(f)
1657            | Expression::IntDiv(f)
1658            | Expression::Atan2(f)
1659            | Expression::AddMonths(f)
1660            | Expression::MonthsBetween(f)
1661            | Expression::NextDay(f)
1662            | Expression::UnixToTimeStr(f)
1663            | Expression::ArrayContains(f)
1664            | Expression::ArrayPosition(f)
1665            | Expression::ArrayAppend(f)
1666            | Expression::ArrayPrepend(f)
1667            | Expression::ArrayUnion(f)
1668            | Expression::ArrayExcept(f)
1669            | Expression::ArrayRemove(f)
1670            | Expression::StarMap(f)
1671            | Expression::MapFromArrays(f)
1672            | Expression::MapContainsKey(f)
1673            | Expression::ElementAt(f)
1674            | Expression::JsonMergePatch(f) => f.inferred_type = Some(dt),
1675
1676            // VarArgFunc variants
1677            Expression::Coalesce(f)
1678            | Expression::Greatest(f)
1679            | Expression::Least(f)
1680            | Expression::ArrayConcat(f)
1681            | Expression::ArrayIntersect(f)
1682            | Expression::ArrayZip(f)
1683            | Expression::MapConcat(f)
1684            | Expression::JsonArray(f) => f.inferred_type = Some(dt),
1685
1686            // AggFunc variants
1687            Expression::Sum(f)
1688            | Expression::Avg(f)
1689            | Expression::Min(f)
1690            | Expression::Max(f)
1691            | Expression::ArrayAgg(f)
1692            | Expression::CountIf(f)
1693            | Expression::Stddev(f)
1694            | Expression::StddevPop(f)
1695            | Expression::StddevSamp(f)
1696            | Expression::Variance(f)
1697            | Expression::VarPop(f)
1698            | Expression::VarSamp(f)
1699            | Expression::Median(f)
1700            | Expression::Mode(f)
1701            | Expression::First(f)
1702            | Expression::Last(f)
1703            | Expression::AnyValue(f)
1704            | Expression::ApproxDistinct(f)
1705            | Expression::ApproxCountDistinct(f)
1706            | Expression::LogicalAnd(f)
1707            | Expression::LogicalOr(f)
1708            | Expression::Skewness(f)
1709            | Expression::ArrayConcatAgg(f)
1710            | Expression::ArrayUniqueAgg(f)
1711            | Expression::BoolXorAgg(f)
1712            | Expression::BitwiseAndAgg(f)
1713            | Expression::BitwiseOrAgg(f)
1714            | Expression::BitwiseXorAgg(f) => f.inferred_type = Some(dt),
1715
1716            // Expressions without inferred_type field - no-op
1717            _ => {}
1718        }
1719    }
1720
1721    /// Create an unqualified column reference (e.g. `name`).
1722    pub fn column(name: impl Into<String>) -> Self {
1723        Expression::Column(Box::new(Column {
1724            name: Identifier::new(name),
1725            table: None,
1726            join_mark: false,
1727            trailing_comments: Vec::new(),
1728            span: None,
1729            inferred_type: None,
1730        }))
1731    }
1732
1733    /// Create a qualified column reference (`table.column`).
1734    pub fn qualified_column(table: impl Into<String>, column: impl Into<String>) -> Self {
1735        Expression::Column(Box::new(Column {
1736            name: Identifier::new(column),
1737            table: Some(Identifier::new(table)),
1738            join_mark: false,
1739            trailing_comments: Vec::new(),
1740            span: None,
1741            inferred_type: None,
1742        }))
1743    }
1744
1745    /// Create a bare identifier expression (not a column reference).
1746    pub fn identifier(name: impl Into<String>) -> Self {
1747        Expression::Identifier(Identifier::new(name))
1748    }
1749
1750    /// Create a NULL expression
1751    pub fn null() -> Self {
1752        Expression::Null(Null)
1753    }
1754
1755    /// Create a TRUE expression
1756    pub fn true_() -> Self {
1757        Expression::Boolean(BooleanLiteral { value: true })
1758    }
1759
1760    /// Create a FALSE expression
1761    pub fn false_() -> Self {
1762        Expression::Boolean(BooleanLiteral { value: false })
1763    }
1764
1765    /// Create a wildcard star (`*`) expression with no EXCEPT/REPLACE/RENAME modifiers.
1766    pub fn star() -> Self {
1767        Expression::Star(Star {
1768            table: None,
1769            except: None,
1770            replace: None,
1771            rename: None,
1772            trailing_comments: Vec::new(),
1773            span: None,
1774        })
1775    }
1776
1777    /// Wrap this expression in an `AS` alias (e.g. `expr AS name`).
1778    pub fn alias(self, name: impl Into<String>) -> Self {
1779        Expression::Alias(Box::new(Alias::new(self, Identifier::new(name))))
1780    }
1781
1782    /// Check if this is a SELECT expression
1783    pub fn is_select(&self) -> bool {
1784        matches!(self, Expression::Select(_))
1785    }
1786
1787    /// Try to get as a Select
1788    pub fn as_select(&self) -> Option<&Select> {
1789        match self {
1790            Expression::Select(s) => Some(s),
1791            _ => None,
1792        }
1793    }
1794
1795    /// Try to get as a mutable Select
1796    pub fn as_select_mut(&mut self) -> Option<&mut Select> {
1797        match self {
1798            Expression::Select(s) => Some(s),
1799            _ => None,
1800        }
1801    }
1802
1803    /// Generate a SQL string for this expression using the generic (dialect-agnostic) generator.
1804    ///
1805    /// Returns an empty string if generation fails. For dialect-specific output,
1806    /// use [`sql_for()`](Self::sql_for) instead.
1807    #[cfg(feature = "generate")]
1808    pub fn sql(&self) -> String {
1809        crate::generator::Generator::sql(self).unwrap_or_default()
1810    }
1811
1812    /// Generate a SQL string for this expression targeting a specific dialect.
1813    ///
1814    /// Dialect-specific rules (identifier quoting, function names, type mappings,
1815    /// syntax variations) are applied automatically.  Returns an empty string if
1816    /// generation fails.
1817    #[cfg(feature = "generate")]
1818    pub fn sql_for(&self, dialect: crate::dialects::DialectType) -> String {
1819        crate::generate(self, dialect).unwrap_or_default()
1820    }
1821}
1822
1823// === Python API accessor methods ===
1824
1825impl Expression {
1826    /// Returns the serde-compatible snake_case variant name without serialization.
1827    /// This is much faster than serializing to JSON and extracting the key.
1828    pub fn variant_name(&self) -> &'static str {
1829        match self {
1830            Expression::Literal(_) => "literal",
1831            Expression::Boolean(_) => "boolean",
1832            Expression::Null(_) => "null",
1833            Expression::Identifier(_) => "identifier",
1834            Expression::Column(_) => "column",
1835            Expression::Table(_) => "table",
1836            Expression::Star(_) => "star",
1837            Expression::BracedWildcard(_) => "braced_wildcard",
1838            Expression::Select(_) => "select",
1839            Expression::Union(_) => "union",
1840            Expression::Intersect(_) => "intersect",
1841            Expression::Except(_) => "except",
1842            Expression::Subquery(_) => "subquery",
1843            Expression::PipeOperator(_) => "pipe_operator",
1844            Expression::Pivot(_) => "pivot",
1845            Expression::PivotAlias(_) => "pivot_alias",
1846            Expression::Unpivot(_) => "unpivot",
1847            Expression::Values(_) => "values",
1848            Expression::PreWhere(_) => "pre_where",
1849            Expression::Stream(_) => "stream",
1850            Expression::UsingData(_) => "using_data",
1851            Expression::XmlNamespace(_) => "xml_namespace",
1852            Expression::Insert(_) => "insert",
1853            Expression::Update(_) => "update",
1854            Expression::Delete(_) => "delete",
1855            Expression::Copy(_) => "copy",
1856            Expression::Put(_) => "put",
1857            Expression::StageReference(_) => "stage_reference",
1858            Expression::Alias(_) => "alias",
1859            Expression::Cast(_) => "cast",
1860            Expression::Collation(_) => "collation",
1861            Expression::Case(_) => "case",
1862            Expression::And(_) => "and",
1863            Expression::Or(_) => "or",
1864            Expression::Add(_) => "add",
1865            Expression::Sub(_) => "sub",
1866            Expression::Mul(_) => "mul",
1867            Expression::Div(_) => "div",
1868            Expression::Mod(_) => "mod",
1869            Expression::Eq(_) => "eq",
1870            Expression::Neq(_) => "neq",
1871            Expression::Lt(_) => "lt",
1872            Expression::Lte(_) => "lte",
1873            Expression::Gt(_) => "gt",
1874            Expression::Gte(_) => "gte",
1875            Expression::Like(_) => "like",
1876            Expression::ILike(_) => "i_like",
1877            Expression::Match(_) => "match",
1878            Expression::BitwiseAnd(_) => "bitwise_and",
1879            Expression::BitwiseOr(_) => "bitwise_or",
1880            Expression::BitwiseXor(_) => "bitwise_xor",
1881            Expression::Concat(_) => "concat",
1882            Expression::Adjacent(_) => "adjacent",
1883            Expression::TsMatch(_) => "ts_match",
1884            Expression::PropertyEQ(_) => "property_e_q",
1885            Expression::ArrayContainsAll(_) => "array_contains_all",
1886            Expression::ArrayContainedBy(_) => "array_contained_by",
1887            Expression::ArrayOverlaps(_) => "array_overlaps",
1888            Expression::JSONBContainsAllTopKeys(_) => "j_s_o_n_b_contains_all_top_keys",
1889            Expression::JSONBContainsAnyTopKeys(_) => "j_s_o_n_b_contains_any_top_keys",
1890            Expression::JSONBDeleteAtPath(_) => "j_s_o_n_b_delete_at_path",
1891            Expression::ExtendsLeft(_) => "extends_left",
1892            Expression::ExtendsRight(_) => "extends_right",
1893            Expression::Not(_) => "not",
1894            Expression::Neg(_) => "neg",
1895            Expression::BitwiseNot(_) => "bitwise_not",
1896            Expression::In(_) => "in",
1897            Expression::Between(_) => "between",
1898            Expression::IsNull(_) => "is_null",
1899            Expression::IsTrue(_) => "is_true",
1900            Expression::IsFalse(_) => "is_false",
1901            Expression::IsJson(_) => "is_json",
1902            Expression::Is(_) => "is",
1903            Expression::Exists(_) => "exists",
1904            Expression::MemberOf(_) => "member_of",
1905            Expression::Function(_) => "function",
1906            Expression::AggregateFunction(_) => "aggregate_function",
1907            Expression::WindowFunction(_) => "window_function",
1908            Expression::From(_) => "from",
1909            Expression::Join(_) => "join",
1910            Expression::JoinedTable(_) => "joined_table",
1911            Expression::Where(_) => "where",
1912            Expression::GroupBy(_) => "group_by",
1913            Expression::Having(_) => "having",
1914            Expression::OrderBy(_) => "order_by",
1915            Expression::Limit(_) => "limit",
1916            Expression::Offset(_) => "offset",
1917            Expression::Qualify(_) => "qualify",
1918            Expression::With(_) => "with",
1919            Expression::Cte(_) => "cte",
1920            Expression::DistributeBy(_) => "distribute_by",
1921            Expression::ClusterBy(_) => "cluster_by",
1922            Expression::SortBy(_) => "sort_by",
1923            Expression::LateralView(_) => "lateral_view",
1924            Expression::Hint(_) => "hint",
1925            Expression::Pseudocolumn(_) => "pseudocolumn",
1926            Expression::Connect(_) => "connect",
1927            Expression::Prior(_) => "prior",
1928            Expression::ConnectByRoot(_) => "connect_by_root",
1929            Expression::MatchRecognize(_) => "match_recognize",
1930            Expression::Ordered(_) => "ordered",
1931            Expression::Window(_) => "window",
1932            Expression::Over(_) => "over",
1933            Expression::WithinGroup(_) => "within_group",
1934            Expression::DataType(_) => "data_type",
1935            Expression::Array(_) => "array",
1936            Expression::Struct(_) => "struct",
1937            Expression::Tuple(_) => "tuple",
1938            Expression::Interval(_) => "interval",
1939            Expression::ConcatWs(_) => "concat_ws",
1940            Expression::Substring(_) => "substring",
1941            Expression::Upper(_) => "upper",
1942            Expression::Lower(_) => "lower",
1943            Expression::Length(_) => "length",
1944            Expression::Trim(_) => "trim",
1945            Expression::LTrim(_) => "l_trim",
1946            Expression::RTrim(_) => "r_trim",
1947            Expression::Replace(_) => "replace",
1948            Expression::Reverse(_) => "reverse",
1949            Expression::Left(_) => "left",
1950            Expression::Right(_) => "right",
1951            Expression::Repeat(_) => "repeat",
1952            Expression::Lpad(_) => "lpad",
1953            Expression::Rpad(_) => "rpad",
1954            Expression::Split(_) => "split",
1955            Expression::RegexpLike(_) => "regexp_like",
1956            Expression::RegexpReplace(_) => "regexp_replace",
1957            Expression::RegexpExtract(_) => "regexp_extract",
1958            Expression::Overlay(_) => "overlay",
1959            Expression::Abs(_) => "abs",
1960            Expression::Round(_) => "round",
1961            Expression::Floor(_) => "floor",
1962            Expression::Ceil(_) => "ceil",
1963            Expression::Power(_) => "power",
1964            Expression::Sqrt(_) => "sqrt",
1965            Expression::Cbrt(_) => "cbrt",
1966            Expression::Ln(_) => "ln",
1967            Expression::Log(_) => "log",
1968            Expression::Exp(_) => "exp",
1969            Expression::Sign(_) => "sign",
1970            Expression::Greatest(_) => "greatest",
1971            Expression::Least(_) => "least",
1972            Expression::CurrentDate(_) => "current_date",
1973            Expression::CurrentTime(_) => "current_time",
1974            Expression::CurrentTimestamp(_) => "current_timestamp",
1975            Expression::CurrentTimestampLTZ(_) => "current_timestamp_l_t_z",
1976            Expression::AtTimeZone(_) => "at_time_zone",
1977            Expression::DateAdd(_) => "date_add",
1978            Expression::DateSub(_) => "date_sub",
1979            Expression::DateDiff(_) => "date_diff",
1980            Expression::DateTrunc(_) => "date_trunc",
1981            Expression::Extract(_) => "extract",
1982            Expression::ToDate(_) => "to_date",
1983            Expression::ToTimestamp(_) => "to_timestamp",
1984            Expression::Date(_) => "date",
1985            Expression::Time(_) => "time",
1986            Expression::DateFromUnixDate(_) => "date_from_unix_date",
1987            Expression::UnixDate(_) => "unix_date",
1988            Expression::UnixSeconds(_) => "unix_seconds",
1989            Expression::UnixMillis(_) => "unix_millis",
1990            Expression::UnixMicros(_) => "unix_micros",
1991            Expression::UnixToTimeStr(_) => "unix_to_time_str",
1992            Expression::TimeStrToDate(_) => "time_str_to_date",
1993            Expression::DateToDi(_) => "date_to_di",
1994            Expression::DiToDate(_) => "di_to_date",
1995            Expression::TsOrDiToDi(_) => "ts_or_di_to_di",
1996            Expression::TsOrDsToDatetime(_) => "ts_or_ds_to_datetime",
1997            Expression::TsOrDsToTimestamp(_) => "ts_or_ds_to_timestamp",
1998            Expression::YearOfWeek(_) => "year_of_week",
1999            Expression::YearOfWeekIso(_) => "year_of_week_iso",
2000            Expression::Coalesce(_) => "coalesce",
2001            Expression::NullIf(_) => "null_if",
2002            Expression::IfFunc(_) => "if_func",
2003            Expression::IfNull(_) => "if_null",
2004            Expression::Nvl(_) => "nvl",
2005            Expression::Nvl2(_) => "nvl2",
2006            Expression::TryCast(_) => "try_cast",
2007            Expression::SafeCast(_) => "safe_cast",
2008            Expression::Count(_) => "count",
2009            Expression::Sum(_) => "sum",
2010            Expression::Avg(_) => "avg",
2011            Expression::Min(_) => "min",
2012            Expression::Max(_) => "max",
2013            Expression::GroupConcat(_) => "group_concat",
2014            Expression::StringAgg(_) => "string_agg",
2015            Expression::ListAgg(_) => "list_agg",
2016            Expression::ArrayAgg(_) => "array_agg",
2017            Expression::CountIf(_) => "count_if",
2018            Expression::SumIf(_) => "sum_if",
2019            Expression::Stddev(_) => "stddev",
2020            Expression::StddevPop(_) => "stddev_pop",
2021            Expression::StddevSamp(_) => "stddev_samp",
2022            Expression::Variance(_) => "variance",
2023            Expression::VarPop(_) => "var_pop",
2024            Expression::VarSamp(_) => "var_samp",
2025            Expression::Median(_) => "median",
2026            Expression::Mode(_) => "mode",
2027            Expression::First(_) => "first",
2028            Expression::Last(_) => "last",
2029            Expression::AnyValue(_) => "any_value",
2030            Expression::ApproxDistinct(_) => "approx_distinct",
2031            Expression::ApproxCountDistinct(_) => "approx_count_distinct",
2032            Expression::ApproxPercentile(_) => "approx_percentile",
2033            Expression::Percentile(_) => "percentile",
2034            Expression::LogicalAnd(_) => "logical_and",
2035            Expression::LogicalOr(_) => "logical_or",
2036            Expression::Skewness(_) => "skewness",
2037            Expression::BitwiseCount(_) => "bitwise_count",
2038            Expression::ArrayConcatAgg(_) => "array_concat_agg",
2039            Expression::ArrayUniqueAgg(_) => "array_unique_agg",
2040            Expression::BoolXorAgg(_) => "bool_xor_agg",
2041            Expression::RowNumber(_) => "row_number",
2042            Expression::Rank(_) => "rank",
2043            Expression::DenseRank(_) => "dense_rank",
2044            Expression::NTile(_) => "n_tile",
2045            Expression::Lead(_) => "lead",
2046            Expression::Lag(_) => "lag",
2047            Expression::FirstValue(_) => "first_value",
2048            Expression::LastValue(_) => "last_value",
2049            Expression::NthValue(_) => "nth_value",
2050            Expression::PercentRank(_) => "percent_rank",
2051            Expression::CumeDist(_) => "cume_dist",
2052            Expression::PercentileCont(_) => "percentile_cont",
2053            Expression::PercentileDisc(_) => "percentile_disc",
2054            Expression::Contains(_) => "contains",
2055            Expression::StartsWith(_) => "starts_with",
2056            Expression::EndsWith(_) => "ends_with",
2057            Expression::Position(_) => "position",
2058            Expression::Initcap(_) => "initcap",
2059            Expression::Ascii(_) => "ascii",
2060            Expression::Chr(_) => "chr",
2061            Expression::CharFunc(_) => "char_func",
2062            Expression::Soundex(_) => "soundex",
2063            Expression::Levenshtein(_) => "levenshtein",
2064            Expression::ByteLength(_) => "byte_length",
2065            Expression::Hex(_) => "hex",
2066            Expression::LowerHex(_) => "lower_hex",
2067            Expression::Unicode(_) => "unicode",
2068            Expression::ModFunc(_) => "mod_func",
2069            Expression::Random(_) => "random",
2070            Expression::Rand(_) => "rand",
2071            Expression::TruncFunc(_) => "trunc_func",
2072            Expression::Pi(_) => "pi",
2073            Expression::Radians(_) => "radians",
2074            Expression::Degrees(_) => "degrees",
2075            Expression::Sin(_) => "sin",
2076            Expression::Cos(_) => "cos",
2077            Expression::Tan(_) => "tan",
2078            Expression::Asin(_) => "asin",
2079            Expression::Acos(_) => "acos",
2080            Expression::Atan(_) => "atan",
2081            Expression::Atan2(_) => "atan2",
2082            Expression::IsNan(_) => "is_nan",
2083            Expression::IsInf(_) => "is_inf",
2084            Expression::IntDiv(_) => "int_div",
2085            Expression::Decode(_) => "decode",
2086            Expression::DateFormat(_) => "date_format",
2087            Expression::FormatDate(_) => "format_date",
2088            Expression::Year(_) => "year",
2089            Expression::Month(_) => "month",
2090            Expression::Day(_) => "day",
2091            Expression::Hour(_) => "hour",
2092            Expression::Minute(_) => "minute",
2093            Expression::Second(_) => "second",
2094            Expression::DayOfWeek(_) => "day_of_week",
2095            Expression::DayOfWeekIso(_) => "day_of_week_iso",
2096            Expression::DayOfMonth(_) => "day_of_month",
2097            Expression::DayOfYear(_) => "day_of_year",
2098            Expression::WeekOfYear(_) => "week_of_year",
2099            Expression::Quarter(_) => "quarter",
2100            Expression::AddMonths(_) => "add_months",
2101            Expression::MonthsBetween(_) => "months_between",
2102            Expression::LastDay(_) => "last_day",
2103            Expression::NextDay(_) => "next_day",
2104            Expression::Epoch(_) => "epoch",
2105            Expression::EpochMs(_) => "epoch_ms",
2106            Expression::FromUnixtime(_) => "from_unixtime",
2107            Expression::UnixTimestamp(_) => "unix_timestamp",
2108            Expression::MakeDate(_) => "make_date",
2109            Expression::MakeTimestamp(_) => "make_timestamp",
2110            Expression::TimestampTrunc(_) => "timestamp_trunc",
2111            Expression::TimeStrToUnix(_) => "time_str_to_unix",
2112            Expression::SessionUser(_) => "session_user",
2113            Expression::SHA(_) => "s_h_a",
2114            Expression::SHA1Digest(_) => "s_h_a1_digest",
2115            Expression::TimeToUnix(_) => "time_to_unix",
2116            Expression::ArrayFunc(_) => "array_func",
2117            Expression::ArrayLength(_) => "array_length",
2118            Expression::ArraySize(_) => "array_size",
2119            Expression::Cardinality(_) => "cardinality",
2120            Expression::ArrayContains(_) => "array_contains",
2121            Expression::ArrayPosition(_) => "array_position",
2122            Expression::ArrayAppend(_) => "array_append",
2123            Expression::ArrayPrepend(_) => "array_prepend",
2124            Expression::ArrayConcat(_) => "array_concat",
2125            Expression::ArraySort(_) => "array_sort",
2126            Expression::ArrayReverse(_) => "array_reverse",
2127            Expression::ArrayDistinct(_) => "array_distinct",
2128            Expression::ArrayJoin(_) => "array_join",
2129            Expression::ArrayToString(_) => "array_to_string",
2130            Expression::Unnest(_) => "unnest",
2131            Expression::Explode(_) => "explode",
2132            Expression::ExplodeOuter(_) => "explode_outer",
2133            Expression::ArrayFilter(_) => "array_filter",
2134            Expression::ArrayTransform(_) => "array_transform",
2135            Expression::ArrayFlatten(_) => "array_flatten",
2136            Expression::ArrayCompact(_) => "array_compact",
2137            Expression::ArrayIntersect(_) => "array_intersect",
2138            Expression::ArrayUnion(_) => "array_union",
2139            Expression::ArrayExcept(_) => "array_except",
2140            Expression::ArrayRemove(_) => "array_remove",
2141            Expression::ArrayZip(_) => "array_zip",
2142            Expression::Sequence(_) => "sequence",
2143            Expression::Generate(_) => "generate",
2144            Expression::ExplodingGenerateSeries(_) => "exploding_generate_series",
2145            Expression::ToArray(_) => "to_array",
2146            Expression::StarMap(_) => "star_map",
2147            Expression::StructFunc(_) => "struct_func",
2148            Expression::StructExtract(_) => "struct_extract",
2149            Expression::NamedStruct(_) => "named_struct",
2150            Expression::MapFunc(_) => "map_func",
2151            Expression::MapFromEntries(_) => "map_from_entries",
2152            Expression::MapFromArrays(_) => "map_from_arrays",
2153            Expression::MapKeys(_) => "map_keys",
2154            Expression::MapValues(_) => "map_values",
2155            Expression::MapContainsKey(_) => "map_contains_key",
2156            Expression::MapConcat(_) => "map_concat",
2157            Expression::ElementAt(_) => "element_at",
2158            Expression::TransformKeys(_) => "transform_keys",
2159            Expression::TransformValues(_) => "transform_values",
2160            Expression::FunctionEmits(_) => "function_emits",
2161            Expression::JsonExtract(_) => "json_extract",
2162            Expression::JsonExtractScalar(_) => "json_extract_scalar",
2163            Expression::JsonExtractPath(_) => "json_extract_path",
2164            Expression::JsonArray(_) => "json_array",
2165            Expression::JsonObject(_) => "json_object",
2166            Expression::JsonQuery(_) => "json_query",
2167            Expression::JsonValue(_) => "json_value",
2168            Expression::JsonArrayLength(_) => "json_array_length",
2169            Expression::JsonKeys(_) => "json_keys",
2170            Expression::JsonType(_) => "json_type",
2171            Expression::ParseJson(_) => "parse_json",
2172            Expression::ToJson(_) => "to_json",
2173            Expression::JsonSet(_) => "json_set",
2174            Expression::JsonInsert(_) => "json_insert",
2175            Expression::JsonRemove(_) => "json_remove",
2176            Expression::JsonMergePatch(_) => "json_merge_patch",
2177            Expression::JsonArrayAgg(_) => "json_array_agg",
2178            Expression::JsonObjectAgg(_) => "json_object_agg",
2179            Expression::Convert(_) => "convert",
2180            Expression::Typeof(_) => "typeof",
2181            Expression::Lambda(_) => "lambda",
2182            Expression::Parameter(_) => "parameter",
2183            Expression::Placeholder(_) => "placeholder",
2184            Expression::NamedArgument(_) => "named_argument",
2185            Expression::TableArgument(_) => "table_argument",
2186            Expression::SqlComment(_) => "sql_comment",
2187            Expression::NullSafeEq(_) => "null_safe_eq",
2188            Expression::NullSafeNeq(_) => "null_safe_neq",
2189            Expression::Glob(_) => "glob",
2190            Expression::SimilarTo(_) => "similar_to",
2191            Expression::Any(_) => "any",
2192            Expression::All(_) => "all",
2193            Expression::Overlaps(_) => "overlaps",
2194            Expression::BitwiseLeftShift(_) => "bitwise_left_shift",
2195            Expression::BitwiseRightShift(_) => "bitwise_right_shift",
2196            Expression::BitwiseAndAgg(_) => "bitwise_and_agg",
2197            Expression::BitwiseOrAgg(_) => "bitwise_or_agg",
2198            Expression::BitwiseXorAgg(_) => "bitwise_xor_agg",
2199            Expression::Subscript(_) => "subscript",
2200            Expression::Dot(_) => "dot",
2201            Expression::MethodCall(_) => "method_call",
2202            Expression::ArraySlice(_) => "array_slice",
2203            Expression::CreateTable(_) => "create_table",
2204            Expression::DropTable(_) => "drop_table",
2205            Expression::Undrop(_) => "undrop",
2206            Expression::AlterTable(_) => "alter_table",
2207            Expression::SplitTable(_) => "split_table",
2208            Expression::FlashbackTable(_) => "flashback_table",
2209            Expression::CreateIndex(_) => "create_index",
2210            Expression::DropIndex(_) => "drop_index",
2211            Expression::CreateView(_) => "create_view",
2212            Expression::DropView(_) => "drop_view",
2213            Expression::AlterView(_) => "alter_view",
2214            Expression::AlterIndex(_) => "alter_index",
2215            Expression::Truncate(_) => "truncate",
2216            Expression::Use(_) => "use",
2217            Expression::Cache(_) => "cache",
2218            Expression::Uncache(_) => "uncache",
2219            Expression::LoadData(_) => "load_data",
2220            Expression::Pragma(_) => "pragma",
2221            Expression::Grant(_) => "grant",
2222            Expression::Revoke(_) => "revoke",
2223            Expression::Comment(_) => "comment",
2224            Expression::SetStatement(_) => "set_statement",
2225            Expression::CreateSchema(_) => "create_schema",
2226            Expression::DropSchema(_) => "drop_schema",
2227            Expression::DropNamespace(_) => "drop_namespace",
2228            Expression::CreateDatabase(_) => "create_database",
2229            Expression::DropDatabase(_) => "drop_database",
2230            Expression::CreateFunction(_) => "create_function",
2231            Expression::DropFunction(_) => "drop_function",
2232            Expression::CreateProcedure(_) => "create_procedure",
2233            Expression::DropProcedure(_) => "drop_procedure",
2234            Expression::CreateSequence(_) => "create_sequence",
2235            Expression::CreateSynonym(_) => "create_synonym",
2236            Expression::DropSequence(_) => "drop_sequence",
2237            Expression::AlterSequence(_) => "alter_sequence",
2238            Expression::CreateTrigger(_) => "create_trigger",
2239            Expression::DropTrigger(_) => "drop_trigger",
2240            Expression::CreateType(_) => "create_type",
2241            Expression::DropType(_) => "drop_type",
2242            Expression::Describe(_) => "describe",
2243            Expression::Show(_) => "show",
2244            Expression::Command(_) => "command",
2245            Expression::TryCatch(_) => "try_catch",
2246            Expression::Kill(_) => "kill",
2247            Expression::Prepare(_) => "prepare",
2248            Expression::Execute(_) => "execute",
2249            Expression::Raw(_) => "raw",
2250            Expression::CreateTask(_) => "create_task",
2251            Expression::Paren(_) => "paren",
2252            Expression::Annotated(_) => "annotated",
2253            Expression::Refresh(_) => "refresh",
2254            Expression::LockingStatement(_) => "locking_statement",
2255            Expression::SequenceProperties(_) => "sequence_properties",
2256            Expression::TruncateTable(_) => "truncate_table",
2257            Expression::Clone(_) => "clone",
2258            Expression::Attach(_) => "attach",
2259            Expression::Detach(_) => "detach",
2260            Expression::Install(_) => "install",
2261            Expression::Summarize(_) => "summarize",
2262            Expression::Declare(_) => "declare",
2263            Expression::DeclareItem(_) => "declare_item",
2264            Expression::Set(_) => "set",
2265            Expression::Heredoc(_) => "heredoc",
2266            Expression::SetItem(_) => "set_item",
2267            Expression::QueryBand(_) => "query_band",
2268            Expression::UserDefinedFunction(_) => "user_defined_function",
2269            Expression::RecursiveWithSearch(_) => "recursive_with_search",
2270            Expression::ProjectionDef(_) => "projection_def",
2271            Expression::TableAlias(_) => "table_alias",
2272            Expression::ByteString(_) => "byte_string",
2273            Expression::HexStringExpr(_) => "hex_string_expr",
2274            Expression::UnicodeString(_) => "unicode_string",
2275            Expression::ColumnPosition(_) => "column_position",
2276            Expression::ColumnDef(_) => "column_def",
2277            Expression::AlterColumn(_) => "alter_column",
2278            Expression::AlterSortKey(_) => "alter_sort_key",
2279            Expression::AlterSet(_) => "alter_set",
2280            Expression::RenameColumn(_) => "rename_column",
2281            Expression::Comprehension(_) => "comprehension",
2282            Expression::MergeTreeTTLAction(_) => "merge_tree_t_t_l_action",
2283            Expression::MergeTreeTTL(_) => "merge_tree_t_t_l",
2284            Expression::IndexConstraintOption(_) => "index_constraint_option",
2285            Expression::ColumnConstraint(_) => "column_constraint",
2286            Expression::PeriodForSystemTimeConstraint(_) => "period_for_system_time_constraint",
2287            Expression::CaseSpecificColumnConstraint(_) => "case_specific_column_constraint",
2288            Expression::CharacterSetColumnConstraint(_) => "character_set_column_constraint",
2289            Expression::CheckColumnConstraint(_) => "check_column_constraint",
2290            Expression::AssumeColumnConstraint(_) => "assume_column_constraint",
2291            Expression::CompressColumnConstraint(_) => "compress_column_constraint",
2292            Expression::DateFormatColumnConstraint(_) => "date_format_column_constraint",
2293            Expression::EphemeralColumnConstraint(_) => "ephemeral_column_constraint",
2294            Expression::WithOperator(_) => "with_operator",
2295            Expression::GeneratedAsIdentityColumnConstraint(_) => {
2296                "generated_as_identity_column_constraint"
2297            }
2298            Expression::AutoIncrementColumnConstraint(_) => "auto_increment_column_constraint",
2299            Expression::CommentColumnConstraint(_) => "comment_column_constraint",
2300            Expression::GeneratedAsRowColumnConstraint(_) => "generated_as_row_column_constraint",
2301            Expression::IndexColumnConstraint(_) => "index_column_constraint",
2302            Expression::MaskingPolicyColumnConstraint(_) => "masking_policy_column_constraint",
2303            Expression::NotNullColumnConstraint(_) => "not_null_column_constraint",
2304            Expression::PrimaryKeyColumnConstraint(_) => "primary_key_column_constraint",
2305            Expression::UniqueColumnConstraint(_) => "unique_column_constraint",
2306            Expression::WatermarkColumnConstraint(_) => "watermark_column_constraint",
2307            Expression::ComputedColumnConstraint(_) => "computed_column_constraint",
2308            Expression::InOutColumnConstraint(_) => "in_out_column_constraint",
2309            Expression::DefaultColumnConstraint(_) => "default_column_constraint",
2310            Expression::PathColumnConstraint(_) => "path_column_constraint",
2311            Expression::Constraint(_) => "constraint",
2312            Expression::Export(_) => "export",
2313            Expression::Filter(_) => "filter",
2314            Expression::Changes(_) => "changes",
2315            Expression::CopyParameter(_) => "copy_parameter",
2316            Expression::Credentials(_) => "credentials",
2317            Expression::Directory(_) => "directory",
2318            Expression::ForeignKey(_) => "foreign_key",
2319            Expression::ColumnPrefix(_) => "column_prefix",
2320            Expression::PrimaryKey(_) => "primary_key",
2321            Expression::IntoClause(_) => "into_clause",
2322            Expression::JoinHint(_) => "join_hint",
2323            Expression::Opclass(_) => "opclass",
2324            Expression::Index(_) => "index",
2325            Expression::IndexParameters(_) => "index_parameters",
2326            Expression::ConditionalInsert(_) => "conditional_insert",
2327            Expression::MultitableInserts(_) => "multitable_inserts",
2328            Expression::OnConflict(_) => "on_conflict",
2329            Expression::OnCondition(_) => "on_condition",
2330            Expression::Returning(_) => "returning",
2331            Expression::Introducer(_) => "introducer",
2332            Expression::PartitionRange(_) => "partition_range",
2333            Expression::Fetch(_) => "fetch",
2334            Expression::Group(_) => "group",
2335            Expression::Cube(_) => "cube",
2336            Expression::Rollup(_) => "rollup",
2337            Expression::GroupingSets(_) => "grouping_sets",
2338            Expression::LimitOptions(_) => "limit_options",
2339            Expression::Lateral(_) => "lateral",
2340            Expression::TableFromRows(_) => "table_from_rows",
2341            Expression::RowsFrom(_) => "rows_from",
2342            Expression::MatchRecognizeMeasure(_) => "match_recognize_measure",
2343            Expression::WithFill(_) => "with_fill",
2344            Expression::Property(_) => "property",
2345            Expression::GrantPrivilege(_) => "grant_privilege",
2346            Expression::GrantPrincipal(_) => "grant_principal",
2347            Expression::AllowedValuesProperty(_) => "allowed_values_property",
2348            Expression::AlgorithmProperty(_) => "algorithm_property",
2349            Expression::AutoIncrementProperty(_) => "auto_increment_property",
2350            Expression::AutoRefreshProperty(_) => "auto_refresh_property",
2351            Expression::BackupProperty(_) => "backup_property",
2352            Expression::BuildProperty(_) => "build_property",
2353            Expression::BlockCompressionProperty(_) => "block_compression_property",
2354            Expression::CharacterSetProperty(_) => "character_set_property",
2355            Expression::ChecksumProperty(_) => "checksum_property",
2356            Expression::CollateProperty(_) => "collate_property",
2357            Expression::DataBlocksizeProperty(_) => "data_blocksize_property",
2358            Expression::DataDeletionProperty(_) => "data_deletion_property",
2359            Expression::DefinerProperty(_) => "definer_property",
2360            Expression::DistKeyProperty(_) => "dist_key_property",
2361            Expression::DistributedByProperty(_) => "distributed_by_property",
2362            Expression::DistStyleProperty(_) => "dist_style_property",
2363            Expression::DuplicateKeyProperty(_) => "duplicate_key_property",
2364            Expression::EngineProperty(_) => "engine_property",
2365            Expression::ToTableProperty(_) => "to_table_property",
2366            Expression::ExecuteAsProperty(_) => "execute_as_property",
2367            Expression::ExternalProperty(_) => "external_property",
2368            Expression::FallbackProperty(_) => "fallback_property",
2369            Expression::FileFormatProperty(_) => "file_format_property",
2370            Expression::CredentialsProperty(_) => "credentials_property",
2371            Expression::FreespaceProperty(_) => "freespace_property",
2372            Expression::InheritsProperty(_) => "inherits_property",
2373            Expression::InputModelProperty(_) => "input_model_property",
2374            Expression::OutputModelProperty(_) => "output_model_property",
2375            Expression::IsolatedLoadingProperty(_) => "isolated_loading_property",
2376            Expression::JournalProperty(_) => "journal_property",
2377            Expression::LanguageProperty(_) => "language_property",
2378            Expression::EnviromentProperty(_) => "enviroment_property",
2379            Expression::ClusteredByProperty(_) => "clustered_by_property",
2380            Expression::DictProperty(_) => "dict_property",
2381            Expression::DictRange(_) => "dict_range",
2382            Expression::OnCluster(_) => "on_cluster",
2383            Expression::LikeProperty(_) => "like_property",
2384            Expression::LocationProperty(_) => "location_property",
2385            Expression::LockProperty(_) => "lock_property",
2386            Expression::LockingProperty(_) => "locking_property",
2387            Expression::LogProperty(_) => "log_property",
2388            Expression::MaterializedProperty(_) => "materialized_property",
2389            Expression::MergeBlockRatioProperty(_) => "merge_block_ratio_property",
2390            Expression::OnProperty(_) => "on_property",
2391            Expression::OnCommitProperty(_) => "on_commit_property",
2392            Expression::PartitionedByProperty(_) => "partitioned_by_property",
2393            Expression::PartitionByProperty(_) => "partition_by_property",
2394            Expression::PartitionedByBucket(_) => "partitioned_by_bucket",
2395            Expression::ClusterByColumnsProperty(_) => "cluster_by_columns_property",
2396            Expression::PartitionByTruncate(_) => "partition_by_truncate",
2397            Expression::PartitionByRangeProperty(_) => "partition_by_range_property",
2398            Expression::PartitionByRangePropertyDynamic(_) => "partition_by_range_property_dynamic",
2399            Expression::PartitionByListProperty(_) => "partition_by_list_property",
2400            Expression::PartitionList(_) => "partition_list",
2401            Expression::Partition(_) => "partition",
2402            Expression::RefreshTriggerProperty(_) => "refresh_trigger_property",
2403            Expression::UniqueKeyProperty(_) => "unique_key_property",
2404            Expression::RollupProperty(_) => "rollup_property",
2405            Expression::PartitionBoundSpec(_) => "partition_bound_spec",
2406            Expression::PartitionedOfProperty(_) => "partitioned_of_property",
2407            Expression::RemoteWithConnectionModelProperty(_) => {
2408                "remote_with_connection_model_property"
2409            }
2410            Expression::ReturnsProperty(_) => "returns_property",
2411            Expression::RowFormatProperty(_) => "row_format_property",
2412            Expression::RowFormatDelimitedProperty(_) => "row_format_delimited_property",
2413            Expression::RowFormatSerdeProperty(_) => "row_format_serde_property",
2414            Expression::QueryTransform(_) => "query_transform",
2415            Expression::SampleProperty(_) => "sample_property",
2416            Expression::SecurityProperty(_) => "security_property",
2417            Expression::SchemaCommentProperty(_) => "schema_comment_property",
2418            Expression::SemanticView(_) => "semantic_view",
2419            Expression::SerdeProperties(_) => "serde_properties",
2420            Expression::SetProperty(_) => "set_property",
2421            Expression::SharingProperty(_) => "sharing_property",
2422            Expression::SetConfigProperty(_) => "set_config_property",
2423            Expression::SettingsProperty(_) => "settings_property",
2424            Expression::SortKeyProperty(_) => "sort_key_property",
2425            Expression::SqlReadWriteProperty(_) => "sql_read_write_property",
2426            Expression::SqlSecurityProperty(_) => "sql_security_property",
2427            Expression::StabilityProperty(_) => "stability_property",
2428            Expression::StorageHandlerProperty(_) => "storage_handler_property",
2429            Expression::TemporaryProperty(_) => "temporary_property",
2430            Expression::Tags(_) => "tags",
2431            Expression::TransformModelProperty(_) => "transform_model_property",
2432            Expression::TransientProperty(_) => "transient_property",
2433            Expression::UsingTemplateProperty(_) => "using_template_property",
2434            Expression::ViewAttributeProperty(_) => "view_attribute_property",
2435            Expression::VolatileProperty(_) => "volatile_property",
2436            Expression::WithDataProperty(_) => "with_data_property",
2437            Expression::WithJournalTableProperty(_) => "with_journal_table_property",
2438            Expression::WithSchemaBindingProperty(_) => "with_schema_binding_property",
2439            Expression::WithSystemVersioningProperty(_) => "with_system_versioning_property",
2440            Expression::WithProcedureOptions(_) => "with_procedure_options",
2441            Expression::EncodeProperty(_) => "encode_property",
2442            Expression::IncludeProperty(_) => "include_property",
2443            Expression::Properties(_) => "properties",
2444            Expression::OptionsProperty(_) => "options_property",
2445            Expression::InputOutputFormat(_) => "input_output_format",
2446            Expression::Reference(_) => "reference",
2447            Expression::QueryOption(_) => "query_option",
2448            Expression::WithTableHint(_) => "with_table_hint",
2449            Expression::IndexTableHint(_) => "index_table_hint",
2450            Expression::HistoricalData(_) => "historical_data",
2451            Expression::Get(_) => "get",
2452            Expression::SetOperation(_) => "set_operation",
2453            Expression::Var(_) => "var",
2454            Expression::Variadic(_) => "variadic",
2455            Expression::Version(_) => "version",
2456            Expression::Schema(_) => "schema",
2457            Expression::Lock(_) => "lock",
2458            Expression::TableSample(_) => "table_sample",
2459            Expression::Tag(_) => "tag",
2460            Expression::UnpivotColumns(_) => "unpivot_columns",
2461            Expression::WindowSpec(_) => "window_spec",
2462            Expression::SessionParameter(_) => "session_parameter",
2463            Expression::PseudoType(_) => "pseudo_type",
2464            Expression::ObjectIdentifier(_) => "object_identifier",
2465            Expression::Transaction(_) => "transaction",
2466            Expression::Commit(_) => "commit",
2467            Expression::Rollback(_) => "rollback",
2468            Expression::AlterSession(_) => "alter_session",
2469            Expression::Analyze(_) => "analyze",
2470            Expression::AnalyzeStatistics(_) => "analyze_statistics",
2471            Expression::AnalyzeHistogram(_) => "analyze_histogram",
2472            Expression::AnalyzeSample(_) => "analyze_sample",
2473            Expression::AnalyzeListChainedRows(_) => "analyze_list_chained_rows",
2474            Expression::AnalyzeDelete(_) => "analyze_delete",
2475            Expression::AnalyzeWith(_) => "analyze_with",
2476            Expression::AnalyzeValidate(_) => "analyze_validate",
2477            Expression::AddPartition(_) => "add_partition",
2478            Expression::AttachOption(_) => "attach_option",
2479            Expression::DropPartition(_) => "drop_partition",
2480            Expression::ReplacePartition(_) => "replace_partition",
2481            Expression::DPipe(_) => "d_pipe",
2482            Expression::Operator(_) => "operator",
2483            Expression::PivotAny(_) => "pivot_any",
2484            Expression::Aliases(_) => "aliases",
2485            Expression::AtIndex(_) => "at_index",
2486            Expression::FromTimeZone(_) => "from_time_zone",
2487            Expression::FormatPhrase(_) => "format_phrase",
2488            Expression::ForIn(_) => "for_in",
2489            Expression::TimeUnit(_) => "time_unit",
2490            Expression::IntervalOp(_) => "interval_op",
2491            Expression::IntervalSpan(_) => "interval_span",
2492            Expression::HavingMax(_) => "having_max",
2493            Expression::CosineDistance(_) => "cosine_distance",
2494            Expression::DotProduct(_) => "dot_product",
2495            Expression::EuclideanDistance(_) => "euclidean_distance",
2496            Expression::ManhattanDistance(_) => "manhattan_distance",
2497            Expression::JarowinklerSimilarity(_) => "jarowinkler_similarity",
2498            Expression::Booland(_) => "booland",
2499            Expression::Boolor(_) => "boolor",
2500            Expression::ParameterizedAgg(_) => "parameterized_agg",
2501            Expression::ArgMax(_) => "arg_max",
2502            Expression::ArgMin(_) => "arg_min",
2503            Expression::ApproxTopK(_) => "approx_top_k",
2504            Expression::ApproxTopKAccumulate(_) => "approx_top_k_accumulate",
2505            Expression::ApproxTopKCombine(_) => "approx_top_k_combine",
2506            Expression::ApproxTopKEstimate(_) => "approx_top_k_estimate",
2507            Expression::ApproxTopSum(_) => "approx_top_sum",
2508            Expression::ApproxQuantiles(_) => "approx_quantiles",
2509            Expression::Minhash(_) => "minhash",
2510            Expression::FarmFingerprint(_) => "farm_fingerprint",
2511            Expression::Float64(_) => "float64",
2512            Expression::Transform(_) => "transform",
2513            Expression::Translate(_) => "translate",
2514            Expression::Grouping(_) => "grouping",
2515            Expression::GroupingId(_) => "grouping_id",
2516            Expression::Anonymous(_) => "anonymous",
2517            Expression::AnonymousAggFunc(_) => "anonymous_agg_func",
2518            Expression::CombinedAggFunc(_) => "combined_agg_func",
2519            Expression::CombinedParameterizedAgg(_) => "combined_parameterized_agg",
2520            Expression::HashAgg(_) => "hash_agg",
2521            Expression::Hll(_) => "hll",
2522            Expression::Apply(_) => "apply",
2523            Expression::ToBoolean(_) => "to_boolean",
2524            Expression::List(_) => "list",
2525            Expression::ToMap(_) => "to_map",
2526            Expression::Pad(_) => "pad",
2527            Expression::ToChar(_) => "to_char",
2528            Expression::ToNumber(_) => "to_number",
2529            Expression::ToDouble(_) => "to_double",
2530            Expression::Int64(_) => "int64",
2531            Expression::StringFunc(_) => "string_func",
2532            Expression::ToDecfloat(_) => "to_decfloat",
2533            Expression::TryToDecfloat(_) => "try_to_decfloat",
2534            Expression::ToFile(_) => "to_file",
2535            Expression::Columns(_) => "columns",
2536            Expression::ConvertToCharset(_) => "convert_to_charset",
2537            Expression::ConvertTimezone(_) => "convert_timezone",
2538            Expression::GenerateSeries(_) => "generate_series",
2539            Expression::AIAgg(_) => "a_i_agg",
2540            Expression::AIClassify(_) => "a_i_classify",
2541            Expression::ArrayAll(_) => "array_all",
2542            Expression::ArrayAny(_) => "array_any",
2543            Expression::ArrayConstructCompact(_) => "array_construct_compact",
2544            Expression::StPoint(_) => "st_point",
2545            Expression::StDistance(_) => "st_distance",
2546            Expression::StringToArray(_) => "string_to_array",
2547            Expression::ArraySum(_) => "array_sum",
2548            Expression::ObjectAgg(_) => "object_agg",
2549            Expression::CastToStrType(_) => "cast_to_str_type",
2550            Expression::CheckJson(_) => "check_json",
2551            Expression::CheckXml(_) => "check_xml",
2552            Expression::TranslateCharacters(_) => "translate_characters",
2553            Expression::CurrentSchemas(_) => "current_schemas",
2554            Expression::CurrentDatetime(_) => "current_datetime",
2555            Expression::Localtime(_) => "localtime",
2556            Expression::Localtimestamp(_) => "localtimestamp",
2557            Expression::Systimestamp(_) => "systimestamp",
2558            Expression::CurrentSchema(_) => "current_schema",
2559            Expression::CurrentUser(_) => "current_user",
2560            Expression::UtcTime(_) => "utc_time",
2561            Expression::UtcTimestamp(_) => "utc_timestamp",
2562            Expression::Timestamp(_) => "timestamp",
2563            Expression::DateBin(_) => "date_bin",
2564            Expression::Datetime(_) => "datetime",
2565            Expression::DatetimeAdd(_) => "datetime_add",
2566            Expression::DatetimeSub(_) => "datetime_sub",
2567            Expression::DatetimeDiff(_) => "datetime_diff",
2568            Expression::DatetimeTrunc(_) => "datetime_trunc",
2569            Expression::Dayname(_) => "dayname",
2570            Expression::MakeInterval(_) => "make_interval",
2571            Expression::PreviousDay(_) => "previous_day",
2572            Expression::Elt(_) => "elt",
2573            Expression::TimestampAdd(_) => "timestamp_add",
2574            Expression::TimestampSub(_) => "timestamp_sub",
2575            Expression::TimestampDiff(_) => "timestamp_diff",
2576            Expression::TimeSlice(_) => "time_slice",
2577            Expression::TimeAdd(_) => "time_add",
2578            Expression::TimeSub(_) => "time_sub",
2579            Expression::TimeDiff(_) => "time_diff",
2580            Expression::TimeTrunc(_) => "time_trunc",
2581            Expression::DateFromParts(_) => "date_from_parts",
2582            Expression::TimeFromParts(_) => "time_from_parts",
2583            Expression::DecodeCase(_) => "decode_case",
2584            Expression::Decrypt(_) => "decrypt",
2585            Expression::DecryptRaw(_) => "decrypt_raw",
2586            Expression::Encode(_) => "encode",
2587            Expression::Encrypt(_) => "encrypt",
2588            Expression::EncryptRaw(_) => "encrypt_raw",
2589            Expression::EqualNull(_) => "equal_null",
2590            Expression::ToBinary(_) => "to_binary",
2591            Expression::Base64DecodeBinary(_) => "base64_decode_binary",
2592            Expression::Base64DecodeString(_) => "base64_decode_string",
2593            Expression::Base64Encode(_) => "base64_encode",
2594            Expression::TryBase64DecodeBinary(_) => "try_base64_decode_binary",
2595            Expression::TryBase64DecodeString(_) => "try_base64_decode_string",
2596            Expression::GapFill(_) => "gap_fill",
2597            Expression::GenerateDateArray(_) => "generate_date_array",
2598            Expression::GenerateTimestampArray(_) => "generate_timestamp_array",
2599            Expression::GetExtract(_) => "get_extract",
2600            Expression::Getbit(_) => "getbit",
2601            Expression::OverflowTruncateBehavior(_) => "overflow_truncate_behavior",
2602            Expression::HexEncode(_) => "hex_encode",
2603            Expression::Compress(_) => "compress",
2604            Expression::DecompressBinary(_) => "decompress_binary",
2605            Expression::DecompressString(_) => "decompress_string",
2606            Expression::Xor(_) => "xor",
2607            Expression::Nullif(_) => "nullif",
2608            Expression::JSON(_) => "j_s_o_n",
2609            Expression::JSONPath(_) => "j_s_o_n_path",
2610            Expression::JSONPathFilter(_) => "j_s_o_n_path_filter",
2611            Expression::JSONPathKey(_) => "j_s_o_n_path_key",
2612            Expression::JSONPathRecursive(_) => "j_s_o_n_path_recursive",
2613            Expression::JSONPathScript(_) => "j_s_o_n_path_script",
2614            Expression::JSONPathSlice(_) => "j_s_o_n_path_slice",
2615            Expression::JSONPathSelector(_) => "j_s_o_n_path_selector",
2616            Expression::JSONPathSubscript(_) => "j_s_o_n_path_subscript",
2617            Expression::JSONPathUnion(_) => "j_s_o_n_path_union",
2618            Expression::Format(_) => "format",
2619            Expression::JSONKeys(_) => "j_s_o_n_keys",
2620            Expression::JSONKeyValue(_) => "j_s_o_n_key_value",
2621            Expression::JSONKeysAtDepth(_) => "j_s_o_n_keys_at_depth",
2622            Expression::JSONObject(_) => "j_s_o_n_object",
2623            Expression::JSONObjectAgg(_) => "j_s_o_n_object_agg",
2624            Expression::JSONBObjectAgg(_) => "j_s_o_n_b_object_agg",
2625            Expression::JSONArray(_) => "j_s_o_n_array",
2626            Expression::JSONArrayAgg(_) => "j_s_o_n_array_agg",
2627            Expression::JSONExists(_) => "j_s_o_n_exists",
2628            Expression::JSONColumnDef(_) => "j_s_o_n_column_def",
2629            Expression::JSONSchema(_) => "j_s_o_n_schema",
2630            Expression::JSONSet(_) => "j_s_o_n_set",
2631            Expression::JSONStripNulls(_) => "j_s_o_n_strip_nulls",
2632            Expression::JSONValue(_) => "j_s_o_n_value",
2633            Expression::JSONValueArray(_) => "j_s_o_n_value_array",
2634            Expression::JSONRemove(_) => "j_s_o_n_remove",
2635            Expression::JSONTable(_) => "j_s_o_n_table",
2636            Expression::JSONType(_) => "j_s_o_n_type",
2637            Expression::ObjectInsert(_) => "object_insert",
2638            Expression::OpenJSONColumnDef(_) => "open_j_s_o_n_column_def",
2639            Expression::OpenJSON(_) => "open_j_s_o_n",
2640            Expression::JSONBExists(_) => "j_s_o_n_b_exists",
2641            Expression::JSONBContains(_) => "j_s_o_n_b_contains",
2642            Expression::JSONBExtract(_) => "j_s_o_n_b_extract",
2643            Expression::JSONCast(_) => "j_s_o_n_cast",
2644            Expression::JSONExtract(_) => "j_s_o_n_extract",
2645            Expression::JSONExtractQuote(_) => "j_s_o_n_extract_quote",
2646            Expression::JSONExtractArray(_) => "j_s_o_n_extract_array",
2647            Expression::JSONExtractScalar(_) => "j_s_o_n_extract_scalar",
2648            Expression::JSONBExtractScalar(_) => "j_s_o_n_b_extract_scalar",
2649            Expression::JSONFormat(_) => "j_s_o_n_format",
2650            Expression::JSONBool(_) => "j_s_o_n_bool",
2651            Expression::JSONPathRoot(_) => "j_s_o_n_path_root",
2652            Expression::JSONArrayAppend(_) => "j_s_o_n_array_append",
2653            Expression::JSONArrayContains(_) => "j_s_o_n_array_contains",
2654            Expression::JSONArrayInsert(_) => "j_s_o_n_array_insert",
2655            Expression::ParseJSON(_) => "parse_j_s_o_n",
2656            Expression::ParseUrl(_) => "parse_url",
2657            Expression::ParseIp(_) => "parse_ip",
2658            Expression::ParseTime(_) => "parse_time",
2659            Expression::ParseDatetime(_) => "parse_datetime",
2660            Expression::Map(_) => "map",
2661            Expression::MapCat(_) => "map_cat",
2662            Expression::MapDelete(_) => "map_delete",
2663            Expression::MapInsert(_) => "map_insert",
2664            Expression::MapPick(_) => "map_pick",
2665            Expression::ScopeResolution(_) => "scope_resolution",
2666            Expression::Slice(_) => "slice",
2667            Expression::VarMap(_) => "var_map",
2668            Expression::MatchAgainst(_) => "match_against",
2669            Expression::MD5Digest(_) => "m_d5_digest",
2670            Expression::MD5NumberLower64(_) => "m_d5_number_lower64",
2671            Expression::MD5NumberUpper64(_) => "m_d5_number_upper64",
2672            Expression::Monthname(_) => "monthname",
2673            Expression::Ntile(_) => "ntile",
2674            Expression::Normalize(_) => "normalize",
2675            Expression::Normal(_) => "normal",
2676            Expression::Predict(_) => "predict",
2677            Expression::MLTranslate(_) => "m_l_translate",
2678            Expression::FeaturesAtTime(_) => "features_at_time",
2679            Expression::GenerateEmbedding(_) => "generate_embedding",
2680            Expression::MLForecast(_) => "m_l_forecast",
2681            Expression::ModelAttribute(_) => "model_attribute",
2682            Expression::VectorSearch(_) => "vector_search",
2683            Expression::Quantile(_) => "quantile",
2684            Expression::ApproxQuantile(_) => "approx_quantile",
2685            Expression::ApproxPercentileEstimate(_) => "approx_percentile_estimate",
2686            Expression::Randn(_) => "randn",
2687            Expression::Randstr(_) => "randstr",
2688            Expression::RangeN(_) => "range_n",
2689            Expression::RangeBucket(_) => "range_bucket",
2690            Expression::ReadCSV(_) => "read_c_s_v",
2691            Expression::ReadParquet(_) => "read_parquet",
2692            Expression::Reduce(_) => "reduce",
2693            Expression::RegexpExtractAll(_) => "regexp_extract_all",
2694            Expression::RegexpILike(_) => "regexp_i_like",
2695            Expression::RegexpFullMatch(_) => "regexp_full_match",
2696            Expression::RegexpInstr(_) => "regexp_instr",
2697            Expression::RegexpSplit(_) => "regexp_split",
2698            Expression::RegexpCount(_) => "regexp_count",
2699            Expression::RegrValx(_) => "regr_valx",
2700            Expression::RegrValy(_) => "regr_valy",
2701            Expression::RegrAvgy(_) => "regr_avgy",
2702            Expression::RegrAvgx(_) => "regr_avgx",
2703            Expression::RegrCount(_) => "regr_count",
2704            Expression::RegrIntercept(_) => "regr_intercept",
2705            Expression::RegrR2(_) => "regr_r2",
2706            Expression::RegrSxx(_) => "regr_sxx",
2707            Expression::RegrSxy(_) => "regr_sxy",
2708            Expression::RegrSyy(_) => "regr_syy",
2709            Expression::RegrSlope(_) => "regr_slope",
2710            Expression::SafeAdd(_) => "safe_add",
2711            Expression::SafeDivide(_) => "safe_divide",
2712            Expression::SafeMultiply(_) => "safe_multiply",
2713            Expression::SafeSubtract(_) => "safe_subtract",
2714            Expression::SHA2(_) => "s_h_a2",
2715            Expression::SHA2Digest(_) => "s_h_a2_digest",
2716            Expression::SortArray(_) => "sort_array",
2717            Expression::SplitPart(_) => "split_part",
2718            Expression::SubstringIndex(_) => "substring_index",
2719            Expression::StandardHash(_) => "standard_hash",
2720            Expression::StrPosition(_) => "str_position",
2721            Expression::Search(_) => "search",
2722            Expression::SearchIp(_) => "search_ip",
2723            Expression::StrToDate(_) => "str_to_date",
2724            Expression::DateStrToDate(_) => "date_str_to_date",
2725            Expression::DateToDateStr(_) => "date_to_date_str",
2726            Expression::StrToTime(_) => "str_to_time",
2727            Expression::StrToUnix(_) => "str_to_unix",
2728            Expression::StrToMap(_) => "str_to_map",
2729            Expression::NumberToStr(_) => "number_to_str",
2730            Expression::FromBase(_) => "from_base",
2731            Expression::Stuff(_) => "stuff",
2732            Expression::TimeToStr(_) => "time_to_str",
2733            Expression::TimeStrToTime(_) => "time_str_to_time",
2734            Expression::TsOrDsAdd(_) => "ts_or_ds_add",
2735            Expression::TsOrDsDiff(_) => "ts_or_ds_diff",
2736            Expression::TsOrDsToDate(_) => "ts_or_ds_to_date",
2737            Expression::TsOrDsToTime(_) => "ts_or_ds_to_time",
2738            Expression::Unhex(_) => "unhex",
2739            Expression::Uniform(_) => "uniform",
2740            Expression::UnixToStr(_) => "unix_to_str",
2741            Expression::UnixToTime(_) => "unix_to_time",
2742            Expression::Uuid(_) => "uuid",
2743            Expression::TimestampFromParts(_) => "timestamp_from_parts",
2744            Expression::TimestampTzFromParts(_) => "timestamp_tz_from_parts",
2745            Expression::Corr(_) => "corr",
2746            Expression::WidthBucket(_) => "width_bucket",
2747            Expression::CovarSamp(_) => "covar_samp",
2748            Expression::CovarPop(_) => "covar_pop",
2749            Expression::Week(_) => "week",
2750            Expression::XMLElement(_) => "x_m_l_element",
2751            Expression::XMLGet(_) => "x_m_l_get",
2752            Expression::XMLTable(_) => "x_m_l_table",
2753            Expression::XMLKeyValueOption(_) => "x_m_l_key_value_option",
2754            Expression::Zipf(_) => "zipf",
2755            Expression::Merge(_) => "merge",
2756            Expression::When(_) => "when",
2757            Expression::Whens(_) => "whens",
2758            Expression::NextValueFor(_) => "next_value_for",
2759            Expression::ReturnStmt(_) => "return_stmt",
2760        }
2761    }
2762
2763    /// Returns the primary child expression (".this" in sqlglot).
2764    pub fn get_this(&self) -> Option<&Expression> {
2765        match self {
2766            // Unary ops
2767            Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this),
2768            // UnaryFunc variants
2769            Expression::Upper(f)
2770            | Expression::Lower(f)
2771            | Expression::Length(f)
2772            | Expression::LTrim(f)
2773            | Expression::RTrim(f)
2774            | Expression::Reverse(f)
2775            | Expression::Abs(f)
2776            | Expression::Sqrt(f)
2777            | Expression::Cbrt(f)
2778            | Expression::Ln(f)
2779            | Expression::Exp(f)
2780            | Expression::Sign(f)
2781            | Expression::Date(f)
2782            | Expression::Time(f)
2783            | Expression::Initcap(f)
2784            | Expression::Ascii(f)
2785            | Expression::Chr(f)
2786            | Expression::Soundex(f)
2787            | Expression::ByteLength(f)
2788            | Expression::Hex(f)
2789            | Expression::LowerHex(f)
2790            | Expression::Unicode(f)
2791            | Expression::Typeof(f)
2792            | Expression::Explode(f)
2793            | Expression::ExplodeOuter(f)
2794            | Expression::MapFromEntries(f)
2795            | Expression::MapKeys(f)
2796            | Expression::MapValues(f)
2797            | Expression::ArrayLength(f)
2798            | Expression::ArraySize(f)
2799            | Expression::Cardinality(f)
2800            | Expression::ArrayReverse(f)
2801            | Expression::ArrayDistinct(f)
2802            | Expression::ArrayFlatten(f)
2803            | Expression::ArrayCompact(f)
2804            | Expression::ToArray(f)
2805            | Expression::JsonArrayLength(f)
2806            | Expression::JsonKeys(f)
2807            | Expression::JsonType(f)
2808            | Expression::ParseJson(f)
2809            | Expression::ToJson(f)
2810            | Expression::Radians(f)
2811            | Expression::Degrees(f)
2812            | Expression::Sin(f)
2813            | Expression::Cos(f)
2814            | Expression::Tan(f)
2815            | Expression::Asin(f)
2816            | Expression::Acos(f)
2817            | Expression::Atan(f)
2818            | Expression::IsNan(f)
2819            | Expression::IsInf(f)
2820            | Expression::Year(f)
2821            | Expression::Month(f)
2822            | Expression::Day(f)
2823            | Expression::Hour(f)
2824            | Expression::Minute(f)
2825            | Expression::Second(f)
2826            | Expression::DayOfWeek(f)
2827            | Expression::DayOfWeekIso(f)
2828            | Expression::DayOfMonth(f)
2829            | Expression::DayOfYear(f)
2830            | Expression::WeekOfYear(f)
2831            | Expression::Quarter(f)
2832            | Expression::Epoch(f)
2833            | Expression::EpochMs(f)
2834            | Expression::BitwiseCount(f)
2835            | Expression::DateFromUnixDate(f)
2836            | Expression::UnixDate(f)
2837            | Expression::UnixSeconds(f)
2838            | Expression::UnixMillis(f)
2839            | Expression::UnixMicros(f)
2840            | Expression::TimeStrToDate(f)
2841            | Expression::DateToDi(f)
2842            | Expression::DiToDate(f)
2843            | Expression::TsOrDiToDi(f)
2844            | Expression::TsOrDsToDatetime(f)
2845            | Expression::TsOrDsToTimestamp(f)
2846            | Expression::YearOfWeek(f)
2847            | Expression::YearOfWeekIso(f)
2848            | Expression::SHA(f)
2849            | Expression::SHA1Digest(f)
2850            | Expression::TimeToUnix(f)
2851            | Expression::TimeStrToUnix(f)
2852            | Expression::Int64(f)
2853            | Expression::JSONBool(f)
2854            | Expression::MD5NumberLower64(f)
2855            | Expression::MD5NumberUpper64(f)
2856            | Expression::DateStrToDate(f)
2857            | Expression::DateToDateStr(f) => Some(&f.this),
2858            // BinaryFunc - this is the primary child
2859            Expression::Power(f)
2860            | Expression::NullIf(f)
2861            | Expression::IfNull(f)
2862            | Expression::Nvl(f)
2863            | Expression::Contains(f)
2864            | Expression::StartsWith(f)
2865            | Expression::EndsWith(f)
2866            | Expression::Levenshtein(f)
2867            | Expression::ModFunc(f)
2868            | Expression::IntDiv(f)
2869            | Expression::Atan2(f)
2870            | Expression::AddMonths(f)
2871            | Expression::MonthsBetween(f)
2872            | Expression::NextDay(f)
2873            | Expression::UnixToTimeStr(f)
2874            | Expression::ArrayContains(f)
2875            | Expression::ArrayPosition(f)
2876            | Expression::ArrayAppend(f)
2877            | Expression::ArrayPrepend(f)
2878            | Expression::ArrayUnion(f)
2879            | Expression::ArrayExcept(f)
2880            | Expression::ArrayRemove(f)
2881            | Expression::StarMap(f)
2882            | Expression::MapFromArrays(f)
2883            | Expression::MapContainsKey(f)
2884            | Expression::ElementAt(f)
2885            | Expression::JsonMergePatch(f)
2886            | Expression::JSONBContains(f)
2887            | Expression::JSONBExtract(f) => Some(&f.this),
2888            // AggFunc - this is the primary child
2889            Expression::Sum(af)
2890            | Expression::Avg(af)
2891            | Expression::Min(af)
2892            | Expression::Max(af)
2893            | Expression::ArrayAgg(af)
2894            | Expression::CountIf(af)
2895            | Expression::Stddev(af)
2896            | Expression::StddevPop(af)
2897            | Expression::StddevSamp(af)
2898            | Expression::Variance(af)
2899            | Expression::VarPop(af)
2900            | Expression::VarSamp(af)
2901            | Expression::Median(af)
2902            | Expression::Mode(af)
2903            | Expression::First(af)
2904            | Expression::Last(af)
2905            | Expression::AnyValue(af)
2906            | Expression::ApproxDistinct(af)
2907            | Expression::ApproxCountDistinct(af)
2908            | Expression::LogicalAnd(af)
2909            | Expression::LogicalOr(af)
2910            | Expression::Skewness(af)
2911            | Expression::ArrayConcatAgg(af)
2912            | Expression::ArrayUniqueAgg(af)
2913            | Expression::BoolXorAgg(af)
2914            | Expression::BitwiseAndAgg(af)
2915            | Expression::BitwiseOrAgg(af)
2916            | Expression::BitwiseXorAgg(af) => Some(&af.this),
2917            // Binary operations - left is "this" in sqlglot
2918            Expression::And(op)
2919            | Expression::Or(op)
2920            | Expression::Add(op)
2921            | Expression::Sub(op)
2922            | Expression::Mul(op)
2923            | Expression::Div(op)
2924            | Expression::Mod(op)
2925            | Expression::Eq(op)
2926            | Expression::Neq(op)
2927            | Expression::Lt(op)
2928            | Expression::Lte(op)
2929            | Expression::Gt(op)
2930            | Expression::Gte(op)
2931            | Expression::BitwiseAnd(op)
2932            | Expression::BitwiseOr(op)
2933            | Expression::BitwiseXor(op)
2934            | Expression::Concat(op)
2935            | Expression::Adjacent(op)
2936            | Expression::TsMatch(op)
2937            | Expression::PropertyEQ(op)
2938            | Expression::ArrayContainsAll(op)
2939            | Expression::ArrayContainedBy(op)
2940            | Expression::ArrayOverlaps(op)
2941            | Expression::JSONBContainsAllTopKeys(op)
2942            | Expression::JSONBContainsAnyTopKeys(op)
2943            | Expression::JSONBDeleteAtPath(op)
2944            | Expression::ExtendsLeft(op)
2945            | Expression::ExtendsRight(op)
2946            | Expression::Is(op)
2947            | Expression::MemberOf(op)
2948            | Expression::Match(op)
2949            | Expression::NullSafeEq(op)
2950            | Expression::NullSafeNeq(op)
2951            | Expression::Glob(op)
2952            | Expression::BitwiseLeftShift(op)
2953            | Expression::BitwiseRightShift(op) => Some(&op.left),
2954            // Like operations - left is "this"
2955            Expression::Like(op) | Expression::ILike(op) => Some(&op.left),
2956            // Structural types with .this
2957            Expression::Alias(a) => Some(&a.this),
2958            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => Some(&c.this),
2959            Expression::Paren(p) => Some(&p.this),
2960            Expression::Annotated(a) => Some(&a.this),
2961            Expression::Subquery(s) => Some(&s.this),
2962            Expression::Where(w) => Some(&w.this),
2963            Expression::Having(h) => Some(&h.this),
2964            Expression::Qualify(q) => Some(&q.this),
2965            Expression::IsNull(i) => Some(&i.this),
2966            Expression::Exists(e) => Some(&e.this),
2967            Expression::Ordered(o) => Some(&o.this),
2968            Expression::WindowFunction(wf) => Some(&wf.this),
2969            Expression::Cte(cte) => Some(&cte.this),
2970            Expression::Between(b) => Some(&b.this),
2971            Expression::In(i) => Some(&i.this),
2972            Expression::ReturnStmt(e) => Some(e),
2973            _ => None,
2974        }
2975    }
2976
2977    /// Returns the secondary child expression (".expression" in sqlglot).
2978    pub fn get_expression(&self) -> Option<&Expression> {
2979        match self {
2980            // Binary operations - right is "expression"
2981            Expression::And(op)
2982            | Expression::Or(op)
2983            | Expression::Add(op)
2984            | Expression::Sub(op)
2985            | Expression::Mul(op)
2986            | Expression::Div(op)
2987            | Expression::Mod(op)
2988            | Expression::Eq(op)
2989            | Expression::Neq(op)
2990            | Expression::Lt(op)
2991            | Expression::Lte(op)
2992            | Expression::Gt(op)
2993            | Expression::Gte(op)
2994            | Expression::BitwiseAnd(op)
2995            | Expression::BitwiseOr(op)
2996            | Expression::BitwiseXor(op)
2997            | Expression::Concat(op)
2998            | Expression::Adjacent(op)
2999            | Expression::TsMatch(op)
3000            | Expression::PropertyEQ(op)
3001            | Expression::ArrayContainsAll(op)
3002            | Expression::ArrayContainedBy(op)
3003            | Expression::ArrayOverlaps(op)
3004            | Expression::JSONBContainsAllTopKeys(op)
3005            | Expression::JSONBContainsAnyTopKeys(op)
3006            | Expression::JSONBDeleteAtPath(op)
3007            | Expression::ExtendsLeft(op)
3008            | Expression::ExtendsRight(op)
3009            | Expression::Is(op)
3010            | Expression::MemberOf(op)
3011            | Expression::Match(op)
3012            | Expression::NullSafeEq(op)
3013            | Expression::NullSafeNeq(op)
3014            | Expression::Glob(op)
3015            | Expression::BitwiseLeftShift(op)
3016            | Expression::BitwiseRightShift(op) => Some(&op.right),
3017            // Like operations - right is "expression"
3018            Expression::Like(op) | Expression::ILike(op) => Some(&op.right),
3019            // BinaryFunc - expression is the secondary
3020            Expression::Power(f)
3021            | Expression::NullIf(f)
3022            | Expression::IfNull(f)
3023            | Expression::Nvl(f)
3024            | Expression::Contains(f)
3025            | Expression::StartsWith(f)
3026            | Expression::EndsWith(f)
3027            | Expression::Levenshtein(f)
3028            | Expression::ModFunc(f)
3029            | Expression::IntDiv(f)
3030            | Expression::Atan2(f)
3031            | Expression::AddMonths(f)
3032            | Expression::MonthsBetween(f)
3033            | Expression::NextDay(f)
3034            | Expression::UnixToTimeStr(f)
3035            | Expression::ArrayContains(f)
3036            | Expression::ArrayPosition(f)
3037            | Expression::ArrayAppend(f)
3038            | Expression::ArrayPrepend(f)
3039            | Expression::ArrayUnion(f)
3040            | Expression::ArrayExcept(f)
3041            | Expression::ArrayRemove(f)
3042            | Expression::StarMap(f)
3043            | Expression::MapFromArrays(f)
3044            | Expression::MapContainsKey(f)
3045            | Expression::ElementAt(f)
3046            | Expression::JsonMergePatch(f)
3047            | Expression::JSONBContains(f)
3048            | Expression::JSONBExtract(f) => Some(&f.expression),
3049            _ => None,
3050        }
3051    }
3052
3053    /// Returns the list of child expressions (".expressions" in sqlglot).
3054    pub fn get_expressions(&self) -> &[Expression] {
3055        match self {
3056            Expression::Select(s) => &s.expressions,
3057            Expression::Function(f) => &f.args,
3058            Expression::AggregateFunction(f) => &f.args,
3059            Expression::From(f) => &f.expressions,
3060            Expression::GroupBy(g) => &g.expressions,
3061            Expression::In(i) => &i.expressions,
3062            Expression::Array(a) => &a.expressions,
3063            Expression::Tuple(t) => &t.expressions,
3064            Expression::Coalesce(f)
3065            | Expression::Greatest(f)
3066            | Expression::Least(f)
3067            | Expression::ArrayConcat(f)
3068            | Expression::ArrayIntersect(f)
3069            | Expression::ArrayZip(f)
3070            | Expression::MapConcat(f)
3071            | Expression::JsonArray(f) => &f.expressions,
3072            _ => &[],
3073        }
3074    }
3075
3076    /// Returns the name of this expression as a string slice.
3077    pub fn get_name(&self) -> &str {
3078        match self {
3079            Expression::Identifier(id) => &id.name,
3080            Expression::Column(col) => &col.name.name,
3081            Expression::Table(t) => &t.name.name,
3082            Expression::Literal(lit) => lit.value_str(),
3083            Expression::Star(_) => "*",
3084            Expression::Function(f) => &f.name,
3085            Expression::AggregateFunction(f) => &f.name,
3086            Expression::Alias(a) => a.this.get_name(),
3087            Expression::Boolean(b) => {
3088                if b.value {
3089                    "TRUE"
3090                } else {
3091                    "FALSE"
3092                }
3093            }
3094            Expression::Null(_) => "NULL",
3095            _ => "",
3096        }
3097    }
3098
3099    /// Returns the alias name if this expression has one.
3100    pub fn get_alias(&self) -> &str {
3101        match self {
3102            Expression::Alias(a) => &a.alias.name,
3103            Expression::Table(t) => t.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3104            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3105            _ => "",
3106        }
3107    }
3108
3109    /// Returns the output name of this expression (what it shows up as in a SELECT).
3110    pub fn get_output_name(&self) -> &str {
3111        match self {
3112            Expression::Alias(a) => &a.alias.name,
3113            Expression::Column(c) => &c.name.name,
3114            Expression::Identifier(id) => &id.name,
3115            Expression::Literal(lit) => lit.value_str(),
3116            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3117            Expression::Star(_) => "*",
3118            _ => "",
3119        }
3120    }
3121
3122    /// Returns comments attached to this expression.
3123    pub fn get_comments(&self) -> Vec<&str> {
3124        match self {
3125            Expression::Identifier(id) => id.trailing_comments.iter().map(|s| s.as_str()).collect(),
3126            Expression::Column(c) => c.trailing_comments.iter().map(|s| s.as_str()).collect(),
3127            Expression::Star(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3128            Expression::Paren(p) => p.trailing_comments.iter().map(|s| s.as_str()).collect(),
3129            Expression::Annotated(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3130            Expression::Alias(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3131            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
3132                c.trailing_comments.iter().map(|s| s.as_str()).collect()
3133            }
3134            Expression::And(op)
3135            | Expression::Or(op)
3136            | Expression::Add(op)
3137            | Expression::Sub(op)
3138            | Expression::Mul(op)
3139            | Expression::Div(op)
3140            | Expression::Mod(op)
3141            | Expression::Eq(op)
3142            | Expression::Neq(op)
3143            | Expression::Lt(op)
3144            | Expression::Lte(op)
3145            | Expression::Gt(op)
3146            | Expression::Gte(op)
3147            | Expression::Concat(op)
3148            | Expression::BitwiseAnd(op)
3149            | Expression::BitwiseOr(op)
3150            | Expression::BitwiseXor(op) => {
3151                op.trailing_comments.iter().map(|s| s.as_str()).collect()
3152            }
3153            Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(),
3154            Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3155            _ => Vec::new(),
3156        }
3157    }
3158}
3159
3160impl fmt::Display for Expression {
3161    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3162        // Basic display - full SQL generation is in generator module
3163        match self {
3164            Expression::Literal(lit) => write!(f, "{}", lit),
3165            Expression::Identifier(id) => write!(f, "{}", id),
3166            Expression::Column(col) => write!(f, "{}", col),
3167            Expression::Star(_) => write!(f, "*"),
3168            Expression::Null(_) => write!(f, "NULL"),
3169            Expression::Boolean(b) => write!(f, "{}", if b.value { "TRUE" } else { "FALSE" }),
3170            Expression::Select(_) => write!(f, "SELECT ..."),
3171            _ => write!(f, "{:?}", self),
3172        }
3173    }
3174}
3175
3176/// Represent a SQL literal value.
3177///
3178/// Numeric values are stored as their original text representation (not parsed
3179/// to `i64`/`f64`) so that precision, trailing zeros, and hex notation are
3180/// preserved across round-trips.
3181///
3182/// Dialect-specific literal forms (triple-quoted strings, dollar-quoted
3183/// strings, raw strings, etc.) each have a dedicated variant so that the
3184/// generator can emit them with the correct syntax.
3185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3186#[cfg_attr(feature = "bindings", derive(TS))]
3187#[serde(tag = "literal_type", content = "value", rename_all = "snake_case")]
3188pub enum Literal {
3189    /// Single-quoted string literal: `'hello'`
3190    String(String),
3191    /// Numeric literal, stored as the original text: `42`, `3.14`, `1e10`
3192    Number(String),
3193    /// Hex string literal: `X'FF'`
3194    HexString(String),
3195    /// Hex number: 0xA, 0xFF (BigQuery, SQLite style) - represents an integer in hex notation
3196    HexNumber(String),
3197    BitString(String),
3198    /// Byte string: b"..." (BigQuery style)
3199    ByteString(String),
3200    /// National string: N'abc'
3201    NationalString(String),
3202    /// DATE literal: DATE '2024-01-15'
3203    Date(String),
3204    /// TIME literal: TIME '10:30:00'
3205    Time(String),
3206    /// TIMESTAMP literal: TIMESTAMP '2024-01-15 10:30:00'
3207    Timestamp(String),
3208    /// DATETIME literal: DATETIME '2024-01-15 10:30:00' (BigQuery)
3209    Datetime(String),
3210    /// Triple-quoted string: """...""" or '''...'''
3211    /// Contains (content, quote_char) where quote_char is '"' or '\''
3212    TripleQuotedString(String, char),
3213    /// Escape string: E'...' (PostgreSQL)
3214    EscapeString(String),
3215    /// Dollar-quoted string: $$...$$  (PostgreSQL)
3216    DollarString(String),
3217    /// Raw string: r"..." or r'...' (BigQuery, Spark, Databricks)
3218    /// In raw strings, backslashes are literal and not escape characters.
3219    /// When converting to a regular string, backslashes must be doubled.
3220    RawString(String),
3221}
3222
3223impl Literal {
3224    /// Returns the inner value as a string slice, regardless of literal type.
3225    pub fn value_str(&self) -> &str {
3226        match self {
3227            Literal::String(s)
3228            | Literal::Number(s)
3229            | Literal::HexString(s)
3230            | Literal::HexNumber(s)
3231            | Literal::BitString(s)
3232            | Literal::ByteString(s)
3233            | Literal::NationalString(s)
3234            | Literal::Date(s)
3235            | Literal::Time(s)
3236            | Literal::Timestamp(s)
3237            | Literal::Datetime(s)
3238            | Literal::EscapeString(s)
3239            | Literal::DollarString(s)
3240            | Literal::RawString(s) => s.as_str(),
3241            Literal::TripleQuotedString(s, _) => s.as_str(),
3242        }
3243    }
3244
3245    /// Returns `true` if this is a string-type literal.
3246    pub fn is_string(&self) -> bool {
3247        matches!(
3248            self,
3249            Literal::String(_)
3250                | Literal::NationalString(_)
3251                | Literal::EscapeString(_)
3252                | Literal::DollarString(_)
3253                | Literal::RawString(_)
3254                | Literal::TripleQuotedString(_, _)
3255        )
3256    }
3257
3258    /// Returns `true` if this is a numeric literal.
3259    pub fn is_number(&self) -> bool {
3260        matches!(self, Literal::Number(_) | Literal::HexNumber(_))
3261    }
3262}
3263
3264impl fmt::Display for Literal {
3265    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3266        match self {
3267            Literal::String(s) => write!(f, "'{}'", s),
3268            Literal::Number(n) => write!(f, "{}", n),
3269            Literal::HexString(h) => write!(f, "X'{}'", h),
3270            Literal::HexNumber(h) => write!(f, "0x{}", h),
3271            Literal::BitString(b) => write!(f, "B'{}'", b),
3272            Literal::ByteString(b) => write!(f, "b'{}'", b),
3273            Literal::NationalString(s) => write!(f, "N'{}'", s),
3274            Literal::Date(d) => write!(f, "DATE '{}'", d),
3275            Literal::Time(t) => write!(f, "TIME '{}'", t),
3276            Literal::Timestamp(ts) => write!(f, "TIMESTAMP '{}'", ts),
3277            Literal::Datetime(dt) => write!(f, "DATETIME '{}'", dt),
3278            Literal::TripleQuotedString(s, q) => {
3279                write!(f, "{0}{0}{0}{1}{0}{0}{0}", q, s)
3280            }
3281            Literal::EscapeString(s) => write!(f, "E'{}'", s),
3282            Literal::DollarString(s) => write!(f, "$${}$$", s),
3283            Literal::RawString(s) => write!(f, "r'{}'", s),
3284        }
3285    }
3286}
3287
3288/// Boolean literal
3289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3290#[cfg_attr(feature = "bindings", derive(TS))]
3291pub struct BooleanLiteral {
3292    pub value: bool,
3293}
3294
3295/// NULL literal
3296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3297#[cfg_attr(feature = "bindings", derive(TS))]
3298pub struct Null;
3299
3300/// Represent a SQL identifier (table name, column name, alias, keyword-as-name, etc.).
3301///
3302/// The `quoted` flag indicates whether the identifier was originally delimited
3303/// (double-quoted, backtick-quoted, or bracket-quoted depending on the
3304/// dialect). The generator uses this flag to decide whether to emit quoting
3305/// characters.
3306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3307#[cfg_attr(feature = "bindings", derive(TS))]
3308pub struct Identifier {
3309    /// The raw text of the identifier, without any quoting characters.
3310    pub name: String,
3311    /// Whether the identifier was quoted in the source SQL.
3312    pub quoted: bool,
3313    #[serde(default)]
3314    pub trailing_comments: Vec<String>,
3315    /// Source position span (populated during parsing, None for programmatically constructed nodes)
3316    #[serde(default, skip_serializing_if = "Option::is_none")]
3317    pub span: Option<Span>,
3318}
3319
3320impl Identifier {
3321    pub fn new(name: impl Into<String>) -> Self {
3322        Self {
3323            name: name.into(),
3324            quoted: false,
3325            trailing_comments: Vec::new(),
3326            span: None,
3327        }
3328    }
3329
3330    pub fn quoted(name: impl Into<String>) -> Self {
3331        Self {
3332            name: name.into(),
3333            quoted: true,
3334            trailing_comments: Vec::new(),
3335            span: None,
3336        }
3337    }
3338
3339    pub fn empty() -> Self {
3340        Self {
3341            name: String::new(),
3342            quoted: false,
3343            trailing_comments: Vec::new(),
3344            span: None,
3345        }
3346    }
3347
3348    pub fn is_empty(&self) -> bool {
3349        self.name.is_empty()
3350    }
3351
3352    /// Set the source span on this identifier
3353    pub fn with_span(mut self, span: Span) -> Self {
3354        self.span = Some(span);
3355        self
3356    }
3357}
3358
3359impl fmt::Display for Identifier {
3360    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3361        if self.quoted {
3362            write!(f, "\"{}\"", self.name)
3363        } else {
3364            write!(f, "{}", self.name)
3365        }
3366    }
3367}
3368
3369/// Represent a column reference, optionally qualified by a table name.
3370///
3371/// Renders as `name` when unqualified, or `table.name` when qualified.
3372/// Use [`Expression::column()`] or [`Expression::qualified_column()`] for
3373/// convenient construction.
3374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3375#[cfg_attr(feature = "bindings", derive(TS))]
3376pub struct Column {
3377    /// The column name.
3378    pub name: Identifier,
3379    /// Optional table qualifier (e.g. `t` in `t.col`).
3380    pub table: Option<Identifier>,
3381    /// Oracle-style join marker (+) for outer joins
3382    #[serde(default)]
3383    pub join_mark: bool,
3384    /// Trailing comments that appeared after this column reference
3385    #[serde(default)]
3386    pub trailing_comments: Vec<String>,
3387    /// Source position span
3388    #[serde(default, skip_serializing_if = "Option::is_none")]
3389    pub span: Option<Span>,
3390    /// Inferred data type from type annotation
3391    #[serde(default, skip_serializing_if = "Option::is_none")]
3392    #[ast(skip)]
3393    pub inferred_type: Option<DataType>,
3394}
3395
3396impl fmt::Display for Column {
3397    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3398        if let Some(table) = &self.table {
3399            write!(f, "{}.{}", table, self.name)
3400        } else {
3401            write!(f, "{}", self.name)
3402        }
3403    }
3404}
3405
3406/// Represent a table reference with optional schema and catalog qualifiers.
3407///
3408/// Renders as `name`, `schema.name`, or `catalog.schema.name` depending on
3409/// which qualifiers are present. Supports aliases, column alias lists,
3410/// time-travel clauses (Snowflake, BigQuery), table hints (TSQL), and
3411/// several other dialect-specific extensions.
3412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3413#[cfg_attr(feature = "bindings", derive(TS))]
3414pub struct TableRef {
3415    /// The unqualified table name.
3416    pub name: Identifier,
3417    /// Optional schema qualifier (e.g. `public` in `public.users`).
3418    pub schema: Option<Identifier>,
3419    /// Optional catalog qualifier (e.g. `mydb` in `mydb.public.users`).
3420    pub catalog: Option<Identifier>,
3421    /// Optional table alias (e.g. `t` in `FROM users AS t`).
3422    pub alias: Option<Identifier>,
3423    /// Whether AS keyword was explicitly used for the alias
3424    #[serde(default)]
3425    pub alias_explicit_as: bool,
3426    /// Column aliases for table alias: AS t(c1, c2)
3427    #[serde(default)]
3428    pub column_aliases: Vec<Identifier>,
3429    /// Leading comments that appeared before this table reference in a FROM clause
3430    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3431    pub leading_comments: Vec<String>,
3432    /// Trailing comments that appeared after this table reference
3433    #[serde(default)]
3434    pub trailing_comments: Vec<String>,
3435    /// Snowflake time travel: BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
3436    #[serde(default)]
3437    pub when: Option<Box<HistoricalData>>,
3438    /// PostgreSQL ONLY modifier: prevents scanning child tables in inheritance hierarchy
3439    #[serde(default)]
3440    pub only: bool,
3441    /// ClickHouse FINAL modifier: forces final aggregation for MergeTree tables
3442    #[serde(default)]
3443    pub final_: bool,
3444    /// TABLESAMPLE clause attached to this table reference (DuckDB, BigQuery)
3445    #[serde(default, skip_serializing_if = "Option::is_none")]
3446    pub table_sample: Option<Box<Sample>>,
3447    /// TSQL table hints: WITH (TABLOCK, INDEX(myindex), ...)
3448    #[serde(default)]
3449    pub hints: Vec<Expression>,
3450    /// TSQL: FOR SYSTEM_TIME temporal clause
3451    /// Contains the full clause text, e.g., "FOR SYSTEM_TIME BETWEEN c AND d"
3452    #[serde(default, skip_serializing_if = "Option::is_none")]
3453    pub system_time: Option<String>,
3454    /// MySQL: PARTITION(p0, p1, ...) hint for reading from specific partitions
3455    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3456    pub partitions: Vec<Identifier>,
3457    /// Snowflake IDENTIFIER() function: dynamic table name from string/variable
3458    /// When set, this is used instead of the name field
3459    #[serde(default, skip_serializing_if = "Option::is_none")]
3460    pub identifier_func: Option<Box<Expression>>,
3461    /// Snowflake CHANGES clause: CHANGES (INFORMATION => ...) AT (...) END (...)
3462    #[serde(default, skip_serializing_if = "Option::is_none")]
3463    pub changes: Option<Box<Changes>>,
3464    /// Time travel version clause: FOR VERSION AS OF / FOR TIMESTAMP AS OF (Presto/Trino, BigQuery, Databricks)
3465    #[serde(default, skip_serializing_if = "Option::is_none")]
3466    pub version: Option<Box<Version>>,
3467    /// Source position span
3468    #[serde(default, skip_serializing_if = "Option::is_none")]
3469    pub span: Option<Span>,
3470}
3471
3472impl TableRef {
3473    pub fn new(name: impl Into<String>) -> Self {
3474        Self {
3475            name: Identifier::new(name),
3476            schema: None,
3477            catalog: None,
3478            alias: None,
3479            alias_explicit_as: false,
3480            column_aliases: Vec::new(),
3481            leading_comments: Vec::new(),
3482            trailing_comments: Vec::new(),
3483            when: None,
3484            only: false,
3485            final_: false,
3486            table_sample: None,
3487            hints: Vec::new(),
3488            system_time: None,
3489            partitions: Vec::new(),
3490            identifier_func: None,
3491            changes: None,
3492            version: None,
3493            span: None,
3494        }
3495    }
3496
3497    /// Create with a schema qualifier.
3498    pub fn new_with_schema(name: impl Into<String>, schema: impl Into<String>) -> Self {
3499        let mut t = Self::new(name);
3500        t.schema = Some(Identifier::new(schema));
3501        t
3502    }
3503
3504    /// Create with catalog and schema qualifiers.
3505    pub fn new_with_catalog(
3506        name: impl Into<String>,
3507        schema: impl Into<String>,
3508        catalog: impl Into<String>,
3509    ) -> Self {
3510        let mut t = Self::new(name);
3511        t.schema = Some(Identifier::new(schema));
3512        t.catalog = Some(Identifier::new(catalog));
3513        t
3514    }
3515
3516    /// Create from an Identifier, preserving the quoted flag
3517    pub fn from_identifier(name: Identifier) -> Self {
3518        Self {
3519            name,
3520            schema: None,
3521            catalog: None,
3522            alias: None,
3523            alias_explicit_as: false,
3524            column_aliases: Vec::new(),
3525            leading_comments: Vec::new(),
3526            trailing_comments: Vec::new(),
3527            when: None,
3528            only: false,
3529            final_: false,
3530            table_sample: None,
3531            hints: Vec::new(),
3532            system_time: None,
3533            partitions: Vec::new(),
3534            identifier_func: None,
3535            changes: None,
3536            version: None,
3537            span: None,
3538        }
3539    }
3540
3541    pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
3542        self.alias = Some(Identifier::new(alias));
3543        self
3544    }
3545
3546    pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
3547        self.schema = Some(Identifier::new(schema));
3548        self
3549    }
3550}
3551
3552/// Represent a wildcard star expression (`*`, `table.*`).
3553///
3554/// Supports the EXCEPT/EXCLUDE, REPLACE, and RENAME modifiers found in
3555/// DuckDB, BigQuery, and Snowflake (e.g. `SELECT * EXCEPT (id) FROM t`).
3556#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3557#[cfg_attr(feature = "bindings", derive(TS))]
3558pub struct Star {
3559    /// Optional table qualifier (e.g. `t` in `t.*`).
3560    pub table: Option<Identifier>,
3561    /// EXCLUDE / EXCEPT columns (DuckDB, BigQuery, Snowflake)
3562    pub except: Option<Vec<Identifier>>,
3563    /// REPLACE expressions (BigQuery, Snowflake)
3564    pub replace: Option<Vec<Alias>>,
3565    /// RENAME columns (Snowflake)
3566    pub rename: Option<Vec<(Identifier, Identifier)>>,
3567    /// Trailing comments that appeared after the star
3568    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3569    pub trailing_comments: Vec<String>,
3570    /// Source position span
3571    #[serde(default, skip_serializing_if = "Option::is_none")]
3572    pub span: Option<Span>,
3573}
3574
3575/// Represent a complete SELECT statement.
3576///
3577/// This is the most feature-rich AST node, covering the full surface area of
3578/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3579/// `Vec` are omitted from the generated SQL when absent.
3580///
3581/// # Key Fields
3582///
3583/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3584/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3585/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3586/// - `where_clause` -- the WHERE predicate.
3587/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3588/// - `having` -- HAVING predicate.
3589/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3590/// - `limit` / `offset` / `fetch` -- result set limiting.
3591/// - `with` -- Common Table Expressions (CTEs).
3592/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3593/// - `windows` -- named window definitions (WINDOW w AS ...).
3594///
3595/// Dialect-specific extensions are supported via fields like `prewhere`
3596/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3597/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3598#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3599#[cfg_attr(feature = "bindings", derive(TS))]
3600pub struct Select {
3601    /// The select-list: columns, expressions, aliases, and wildcards.
3602    pub expressions: Vec<Expression>,
3603    /// The FROM clause, containing one or more table sources.
3604    pub from: Option<From>,
3605    /// JOIN clauses applied after the FROM source.
3606    pub joins: Vec<Join>,
3607    pub lateral_views: Vec<LateralView>,
3608    /// ClickHouse PREWHERE clause
3609    #[serde(default, skip_serializing_if = "Option::is_none")]
3610    pub prewhere: Option<Expression>,
3611    pub where_clause: Option<Where>,
3612    pub group_by: Option<GroupBy>,
3613    pub having: Option<Having>,
3614    pub qualify: Option<Qualify>,
3615    pub order_by: Option<OrderBy>,
3616    pub distribute_by: Option<DistributeBy>,
3617    pub cluster_by: Option<ClusterBy>,
3618    pub sort_by: Option<SortBy>,
3619    pub limit: Option<Limit>,
3620    pub offset: Option<Offset>,
3621    /// ClickHouse LIMIT BY clause expressions
3622    #[serde(default, skip_serializing_if = "Option::is_none")]
3623    pub limit_by: Option<Vec<Expression>>,
3624    pub fetch: Option<Fetch>,
3625    pub distinct: bool,
3626    pub distinct_on: Option<Vec<Expression>>,
3627    pub top: Option<Top>,
3628    pub with: Option<With>,
3629    pub sample: Option<Sample>,
3630    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3631    #[serde(default, skip_serializing_if = "Option::is_none")]
3632    pub settings: Option<Vec<Expression>>,
3633    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3634    #[serde(default, skip_serializing_if = "Option::is_none")]
3635    pub format: Option<Expression>,
3636    pub windows: Option<Vec<NamedWindow>>,
3637    pub hint: Option<Hint>,
3638    /// Oracle CONNECT BY clause for hierarchical queries
3639    pub connect: Option<Connect>,
3640    /// SELECT ... INTO table_name for creating tables
3641    pub into: Option<SelectInto>,
3642    /// FOR UPDATE/SHARE locking clauses
3643    #[serde(default)]
3644    pub locks: Vec<Lock>,
3645    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3646    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3647    pub for_xml: Vec<Expression>,
3648    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3649    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3650    pub for_json: Vec<Expression>,
3651    /// Leading comments before the statement
3652    #[serde(default)]
3653    pub leading_comments: Vec<String>,
3654    /// Comments that appear after SELECT keyword (before expressions)
3655    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3656    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3657    pub post_select_comments: Vec<String>,
3658    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3659    #[serde(default, skip_serializing_if = "Option::is_none")]
3660    pub kind: Option<String>,
3661    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3662    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3663    pub operation_modifiers: Vec<String>,
3664    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3665    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3666    pub qualify_after_window: bool,
3667    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3668    #[serde(default, skip_serializing_if = "Option::is_none")]
3669    pub option: Option<String>,
3670    /// Redshift-style EXCLUDE clause at the end of the projection list
3671    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3672    #[serde(default, skip_serializing_if = "Option::is_none")]
3673    pub exclude: Option<Vec<Expression>>,
3674}
3675
3676impl Select {
3677    pub fn new() -> Self {
3678        Self {
3679            expressions: Vec::new(),
3680            from: None,
3681            joins: Vec::new(),
3682            lateral_views: Vec::new(),
3683            prewhere: None,
3684            where_clause: None,
3685            group_by: None,
3686            having: None,
3687            qualify: None,
3688            order_by: None,
3689            distribute_by: None,
3690            cluster_by: None,
3691            sort_by: None,
3692            limit: None,
3693            offset: None,
3694            limit_by: None,
3695            fetch: None,
3696            distinct: false,
3697            distinct_on: None,
3698            top: None,
3699            with: None,
3700            sample: None,
3701            settings: None,
3702            format: None,
3703            windows: None,
3704            hint: None,
3705            connect: None,
3706            into: None,
3707            locks: Vec::new(),
3708            for_xml: Vec::new(),
3709            for_json: Vec::new(),
3710            leading_comments: Vec::new(),
3711            post_select_comments: Vec::new(),
3712            kind: None,
3713            operation_modifiers: Vec::new(),
3714            qualify_after_window: false,
3715            option: None,
3716            exclude: None,
3717        }
3718    }
3719
3720    /// Add a column to select
3721    pub fn column(mut self, expr: Expression) -> Self {
3722        self.expressions.push(expr);
3723        self
3724    }
3725
3726    /// Set the FROM clause
3727    pub fn from(mut self, table: Expression) -> Self {
3728        self.from = Some(From {
3729            expressions: vec![table],
3730        });
3731        self
3732    }
3733
3734    /// Add a WHERE clause
3735    pub fn where_(mut self, condition: Expression) -> Self {
3736        self.where_clause = Some(Where { this: condition });
3737        self
3738    }
3739
3740    /// Set DISTINCT
3741    pub fn distinct(mut self) -> Self {
3742        self.distinct = true;
3743        self
3744    }
3745
3746    /// Add a JOIN
3747    pub fn join(mut self, join: Join) -> Self {
3748        self.joins.push(join);
3749        self
3750    }
3751
3752    /// Set ORDER BY
3753    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
3754        self.order_by = Some(OrderBy {
3755            expressions,
3756            siblings: false,
3757            comments: Vec::new(),
3758        });
3759        self
3760    }
3761
3762    /// Set LIMIT
3763    pub fn limit(mut self, n: Expression) -> Self {
3764        self.limit = Some(Limit {
3765            this: n,
3766            percent: false,
3767            comments: Vec::new(),
3768        });
3769        self
3770    }
3771
3772    /// Set OFFSET
3773    pub fn offset(mut self, n: Expression) -> Self {
3774        self.offset = Some(Offset {
3775            this: n,
3776            rows: None,
3777        });
3778        self
3779    }
3780}
3781
3782impl Default for Select {
3783    fn default() -> Self {
3784        Self::new()
3785    }
3786}
3787
3788/// Represent a UNION set operation between two query expressions.
3789///
3790/// When `all` is true, duplicate rows are preserved (UNION ALL).
3791/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
3792/// Supports DuckDB's BY NAME modifier and BigQuery's CORRESPONDING modifier.
3793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3794#[cfg_attr(feature = "bindings", derive(TS))]
3795pub struct Union {
3796    /// The left-hand query operand.
3797    pub left: Expression,
3798    /// The right-hand query operand.
3799    pub right: Expression,
3800    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
3801    pub all: bool,
3802    /// Whether DISTINCT was explicitly specified
3803    #[serde(default)]
3804    pub distinct: bool,
3805    /// Optional WITH clause
3806    pub with: Option<With>,
3807    /// ORDER BY applied to entire UNION result
3808    pub order_by: Option<OrderBy>,
3809    /// LIMIT applied to entire UNION result
3810    pub limit: Option<Box<Expression>>,
3811    /// OFFSET applied to entire UNION result
3812    pub offset: Option<Box<Expression>>,
3813    /// DISTRIBUTE BY clause (Hive/Spark)
3814    #[serde(default, skip_serializing_if = "Option::is_none")]
3815    pub distribute_by: Option<DistributeBy>,
3816    /// SORT BY clause (Hive/Spark)
3817    #[serde(default, skip_serializing_if = "Option::is_none")]
3818    pub sort_by: Option<SortBy>,
3819    /// CLUSTER BY clause (Hive/Spark)
3820    #[serde(default, skip_serializing_if = "Option::is_none")]
3821    pub cluster_by: Option<ClusterBy>,
3822    /// DuckDB BY NAME modifier
3823    #[serde(default)]
3824    pub by_name: bool,
3825    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3826    #[serde(default, skip_serializing_if = "Option::is_none")]
3827    pub side: Option<String>,
3828    /// BigQuery: Set operation kind (INNER)
3829    #[serde(default, skip_serializing_if = "Option::is_none")]
3830    pub kind: Option<String>,
3831    /// BigQuery: CORRESPONDING modifier
3832    #[serde(default)]
3833    pub corresponding: bool,
3834    /// BigQuery: STRICT modifier (before CORRESPONDING)
3835    #[serde(default)]
3836    pub strict: bool,
3837    /// BigQuery: BY (columns) after CORRESPONDING
3838    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3839    pub on_columns: Vec<Expression>,
3840}
3841
3842/// Iteratively flatten the left-recursive chain to prevent stack overflow
3843/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3844impl Drop for Union {
3845    fn drop(&mut self) {
3846        loop {
3847            if let Expression::Union(ref mut inner) = self.left {
3848                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3849                let old_left = std::mem::replace(&mut self.left, next_left);
3850                drop(old_left);
3851            } else {
3852                break;
3853            }
3854        }
3855    }
3856}
3857
3858/// Represent an INTERSECT set operation between two query expressions.
3859///
3860/// Returns only rows that appear in both operands. When `all` is true,
3861/// duplicates are preserved according to their multiplicity.
3862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3863#[cfg_attr(feature = "bindings", derive(TS))]
3864pub struct Intersect {
3865    /// The left-hand query operand.
3866    pub left: Expression,
3867    /// The right-hand query operand.
3868    pub right: Expression,
3869    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
3870    pub all: bool,
3871    /// Whether DISTINCT was explicitly specified
3872    #[serde(default)]
3873    pub distinct: bool,
3874    /// Optional WITH clause
3875    pub with: Option<With>,
3876    /// ORDER BY applied to entire INTERSECT result
3877    pub order_by: Option<OrderBy>,
3878    /// LIMIT applied to entire INTERSECT result
3879    pub limit: Option<Box<Expression>>,
3880    /// OFFSET applied to entire INTERSECT result
3881    pub offset: Option<Box<Expression>>,
3882    /// DISTRIBUTE BY clause (Hive/Spark)
3883    #[serde(default, skip_serializing_if = "Option::is_none")]
3884    pub distribute_by: Option<DistributeBy>,
3885    /// SORT BY clause (Hive/Spark)
3886    #[serde(default, skip_serializing_if = "Option::is_none")]
3887    pub sort_by: Option<SortBy>,
3888    /// CLUSTER BY clause (Hive/Spark)
3889    #[serde(default, skip_serializing_if = "Option::is_none")]
3890    pub cluster_by: Option<ClusterBy>,
3891    /// DuckDB BY NAME modifier
3892    #[serde(default)]
3893    pub by_name: bool,
3894    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3895    #[serde(default, skip_serializing_if = "Option::is_none")]
3896    pub side: Option<String>,
3897    /// BigQuery: Set operation kind (INNER)
3898    #[serde(default, skip_serializing_if = "Option::is_none")]
3899    pub kind: Option<String>,
3900    /// BigQuery: CORRESPONDING modifier
3901    #[serde(default)]
3902    pub corresponding: bool,
3903    /// BigQuery: STRICT modifier (before CORRESPONDING)
3904    #[serde(default)]
3905    pub strict: bool,
3906    /// BigQuery: BY (columns) after CORRESPONDING
3907    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3908    pub on_columns: Vec<Expression>,
3909}
3910
3911impl Drop for Intersect {
3912    fn drop(&mut self) {
3913        loop {
3914            if let Expression::Intersect(ref mut inner) = self.left {
3915                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3916                let old_left = std::mem::replace(&mut self.left, next_left);
3917                drop(old_left);
3918            } else {
3919                break;
3920            }
3921        }
3922    }
3923}
3924
3925/// Represent an EXCEPT (MINUS) set operation between two query expressions.
3926///
3927/// Returns rows from the left operand that do not appear in the right operand.
3928/// When `all` is true, duplicates are subtracted according to their multiplicity.
3929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3930#[cfg_attr(feature = "bindings", derive(TS))]
3931pub struct Except {
3932    /// The left-hand query operand.
3933    pub left: Expression,
3934    /// The right-hand query operand (rows to subtract).
3935    pub right: Expression,
3936    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
3937    pub all: bool,
3938    /// Whether DISTINCT was explicitly specified
3939    #[serde(default)]
3940    pub distinct: bool,
3941    /// Optional WITH clause
3942    pub with: Option<With>,
3943    /// ORDER BY applied to entire EXCEPT result
3944    pub order_by: Option<OrderBy>,
3945    /// LIMIT applied to entire EXCEPT result
3946    pub limit: Option<Box<Expression>>,
3947    /// OFFSET applied to entire EXCEPT result
3948    pub offset: Option<Box<Expression>>,
3949    /// DISTRIBUTE BY clause (Hive/Spark)
3950    #[serde(default, skip_serializing_if = "Option::is_none")]
3951    pub distribute_by: Option<DistributeBy>,
3952    /// SORT BY clause (Hive/Spark)
3953    #[serde(default, skip_serializing_if = "Option::is_none")]
3954    pub sort_by: Option<SortBy>,
3955    /// CLUSTER BY clause (Hive/Spark)
3956    #[serde(default, skip_serializing_if = "Option::is_none")]
3957    pub cluster_by: Option<ClusterBy>,
3958    /// DuckDB BY NAME modifier
3959    #[serde(default)]
3960    pub by_name: bool,
3961    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3962    #[serde(default, skip_serializing_if = "Option::is_none")]
3963    pub side: Option<String>,
3964    /// BigQuery: Set operation kind (INNER)
3965    #[serde(default, skip_serializing_if = "Option::is_none")]
3966    pub kind: Option<String>,
3967    /// BigQuery: CORRESPONDING modifier
3968    #[serde(default)]
3969    pub corresponding: bool,
3970    /// BigQuery: STRICT modifier (before CORRESPONDING)
3971    #[serde(default)]
3972    pub strict: bool,
3973    /// BigQuery: BY (columns) after CORRESPONDING
3974    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3975    pub on_columns: Vec<Expression>,
3976}
3977
3978impl Drop for Except {
3979    fn drop(&mut self) {
3980        loop {
3981            if let Expression::Except(ref mut inner) = self.left {
3982                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3983                let old_left = std::mem::replace(&mut self.left, next_left);
3984                drop(old_left);
3985            } else {
3986                break;
3987            }
3988        }
3989    }
3990}
3991
3992/// INTO clause for SELECT INTO statements
3993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3994#[cfg_attr(feature = "bindings", derive(TS))]
3995pub struct SelectInto {
3996    /// Target table or variable (used when single target)
3997    pub this: Expression,
3998    /// Whether TEMPORARY keyword was used
3999    #[serde(default)]
4000    pub temporary: bool,
4001    /// Whether UNLOGGED keyword was used (PostgreSQL)
4002    #[serde(default)]
4003    pub unlogged: bool,
4004    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4005    #[serde(default)]
4006    pub bulk_collect: bool,
4007    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4008    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4009    pub expressions: Vec<Expression>,
4010}
4011
4012/// Represent a parenthesized subquery expression.
4013///
4014/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4015/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4016/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4017/// modifiers are rendered inside or outside the parentheses.
4018///
4019/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4020/// scalar subqueries in select-lists, and derived tables.
4021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4022#[cfg_attr(feature = "bindings", derive(TS))]
4023pub struct Subquery {
4024    /// The inner query expression.
4025    pub this: Expression,
4026    /// Optional alias for the derived table.
4027    pub alias: Option<Identifier>,
4028    /// Optional column aliases: AS t(c1, c2)
4029    pub column_aliases: Vec<Identifier>,
4030    /// Whether AS keyword was explicitly used for the alias.
4031    #[serde(default)]
4032    pub alias_explicit_as: bool,
4033    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4034    #[serde(skip_serializing_if = "Option::is_none", default)]
4035    pub alias_keyword: Option<String>,
4036    /// ORDER BY clause (for parenthesized queries)
4037    pub order_by: Option<OrderBy>,
4038    /// LIMIT clause
4039    pub limit: Option<Limit>,
4040    /// OFFSET clause
4041    pub offset: Option<Offset>,
4042    /// DISTRIBUTE BY clause (Hive/Spark)
4043    #[serde(default, skip_serializing_if = "Option::is_none")]
4044    pub distribute_by: Option<DistributeBy>,
4045    /// SORT BY clause (Hive/Spark)
4046    #[serde(default, skip_serializing_if = "Option::is_none")]
4047    pub sort_by: Option<SortBy>,
4048    /// CLUSTER BY clause (Hive/Spark)
4049    #[serde(default, skip_serializing_if = "Option::is_none")]
4050    pub cluster_by: Option<ClusterBy>,
4051    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4052    #[serde(default)]
4053    pub lateral: bool,
4054    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4055    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4056    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4057    #[serde(default)]
4058    pub modifiers_inside: bool,
4059    /// Trailing comments after the closing paren
4060    #[serde(default)]
4061    pub trailing_comments: Vec<String>,
4062    /// Inferred data type from type annotation
4063    #[serde(default, skip_serializing_if = "Option::is_none")]
4064    #[ast(skip)]
4065    pub inferred_type: Option<DataType>,
4066}
4067
4068/// Pipe operator expression: query |> transform
4069///
4070/// Used in DataFusion and BigQuery pipe syntax:
4071///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4072#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4073#[cfg_attr(feature = "bindings", derive(TS))]
4074pub struct PipeOperator {
4075    /// The input query/expression (left side of |>)
4076    pub this: Expression,
4077    /// The piped operation (right side of |>)
4078    pub expression: Expression,
4079}
4080
4081/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4083#[cfg_attr(feature = "bindings", derive(TS))]
4084pub struct Values {
4085    /// The rows of values
4086    pub expressions: Vec<Tuple>,
4087    /// Optional alias for the table
4088    pub alias: Option<Identifier>,
4089    /// Optional column aliases: AS t(c1, c2)
4090    pub column_aliases: Vec<Identifier>,
4091}
4092
4093/// PIVOT operation - supports both standard and DuckDB simplified syntax
4094///
4095/// Standard syntax (in FROM clause):
4096///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4097///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4098///
4099/// DuckDB simplified syntax (statement-level):
4100///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4101///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4103#[cfg_attr(feature = "bindings", derive(TS))]
4104pub struct Pivot {
4105    /// Source table/expression
4106    pub this: Expression,
4107    /// For standard PIVOT: the aggregation function(s) (first is primary)
4108    /// For DuckDB simplified: unused (use `using` instead)
4109    #[serde(default)]
4110    pub expressions: Vec<Expression>,
4111    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4112    #[serde(default)]
4113    pub fields: Vec<Expression>,
4114    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4115    #[serde(default)]
4116    pub using: Vec<Expression>,
4117    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4118    #[serde(default)]
4119    pub group: Option<Box<Expression>>,
4120    /// Whether this is an UNPIVOT (vs PIVOT)
4121    #[serde(default)]
4122    pub unpivot: bool,
4123    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4124    #[serde(default)]
4125    pub into: Option<Box<Expression>>,
4126    /// Optional alias
4127    #[serde(default)]
4128    pub alias: Option<Identifier>,
4129    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4130    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4131    pub alias_columns: Vec<Identifier>,
4132    /// Include/exclude nulls (for UNPIVOT)
4133    #[serde(default)]
4134    pub include_nulls: Option<bool>,
4135    /// Default on null value (Snowflake)
4136    #[serde(default)]
4137    pub default_on_null: Option<Box<Expression>>,
4138    /// WITH clause (CTEs)
4139    #[serde(default, skip_serializing_if = "Option::is_none")]
4140    pub with: Option<With>,
4141}
4142
4143/// UNPIVOT operation
4144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4145#[cfg_attr(feature = "bindings", derive(TS))]
4146pub struct Unpivot {
4147    pub this: Expression,
4148    pub value_column: Identifier,
4149    pub name_column: Identifier,
4150    pub columns: Vec<Expression>,
4151    pub alias: Option<Identifier>,
4152    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4153    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4154    pub alias_columns: Vec<Identifier>,
4155    /// Whether the value_column was parenthesized in the original SQL
4156    #[serde(default)]
4157    pub value_column_parenthesized: bool,
4158    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4159    #[serde(default)]
4160    pub include_nulls: Option<bool>,
4161    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4162    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4163    pub extra_value_columns: Vec<Identifier>,
4164}
4165
4166/// PIVOT alias for aliasing pivot expressions
4167/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4168#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4169#[cfg_attr(feature = "bindings", derive(TS))]
4170pub struct PivotAlias {
4171    pub this: Expression,
4172    pub alias: Expression,
4173}
4174
4175/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4176#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4177#[cfg_attr(feature = "bindings", derive(TS))]
4178pub struct PreWhere {
4179    pub this: Expression,
4180}
4181
4182/// STREAM definition (Snowflake) - for change data capture
4183#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4184#[cfg_attr(feature = "bindings", derive(TS))]
4185pub struct Stream {
4186    pub this: Expression,
4187    #[serde(skip_serializing_if = "Option::is_none")]
4188    pub on: Option<Expression>,
4189    #[serde(skip_serializing_if = "Option::is_none")]
4190    pub show_initial_rows: Option<bool>,
4191}
4192
4193/// USING DATA clause for data import statements
4194#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4195#[cfg_attr(feature = "bindings", derive(TS))]
4196pub struct UsingData {
4197    pub this: Expression,
4198}
4199
4200/// XML Namespace declaration
4201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4202#[cfg_attr(feature = "bindings", derive(TS))]
4203pub struct XmlNamespace {
4204    pub this: Expression,
4205    #[serde(skip_serializing_if = "Option::is_none")]
4206    pub alias: Option<Identifier>,
4207}
4208
4209/// ROW FORMAT clause for Hive/Spark
4210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4211#[cfg_attr(feature = "bindings", derive(TS))]
4212pub struct RowFormat {
4213    pub delimited: bool,
4214    pub fields_terminated_by: Option<String>,
4215    pub collection_items_terminated_by: Option<String>,
4216    pub map_keys_terminated_by: Option<String>,
4217    pub lines_terminated_by: Option<String>,
4218    pub null_defined_as: Option<String>,
4219}
4220
4221/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4222#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4223#[cfg_attr(feature = "bindings", derive(TS))]
4224pub struct DirectoryInsert {
4225    pub local: bool,
4226    pub path: String,
4227    pub row_format: Option<RowFormat>,
4228    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4229    #[serde(default)]
4230    pub stored_as: Option<String>,
4231}
4232
4233/// INSERT statement
4234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4235#[cfg_attr(feature = "bindings", derive(TS))]
4236pub struct Insert {
4237    pub table: TableRef,
4238    pub columns: Vec<Identifier>,
4239    pub values: Vec<Vec<Expression>>,
4240    pub query: Option<Expression>,
4241    /// INSERT OVERWRITE for Hive/Spark
4242    pub overwrite: bool,
4243    /// PARTITION clause for Hive/Spark
4244    pub partition: Vec<(Identifier, Option<Expression>)>,
4245    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4246    #[serde(default)]
4247    pub directory: Option<DirectoryInsert>,
4248    /// RETURNING clause (PostgreSQL, SQLite)
4249    #[serde(default)]
4250    pub returning: Vec<Expression>,
4251    /// OUTPUT clause (TSQL)
4252    #[serde(default)]
4253    pub output: Option<OutputClause>,
4254    /// ON CONFLICT clause (PostgreSQL, SQLite)
4255    #[serde(default)]
4256    pub on_conflict: Option<Box<Expression>>,
4257    /// Leading comments before the statement
4258    #[serde(default)]
4259    pub leading_comments: Vec<String>,
4260    /// IF EXISTS clause (Hive)
4261    #[serde(default)]
4262    pub if_exists: bool,
4263    /// WITH clause (CTEs)
4264    #[serde(default)]
4265    pub with: Option<With>,
4266    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4267    #[serde(default)]
4268    pub ignore: bool,
4269    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4270    #[serde(default)]
4271    pub source_alias: Option<Identifier>,
4272    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4273    #[serde(default)]
4274    pub alias: Option<Identifier>,
4275    /// Whether the alias uses explicit AS keyword
4276    #[serde(default)]
4277    pub alias_explicit_as: bool,
4278    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4279    #[serde(default)]
4280    pub default_values: bool,
4281    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4282    #[serde(default)]
4283    pub by_name: bool,
4284    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4285    #[serde(default, skip_serializing_if = "Option::is_none")]
4286    pub conflict_action: Option<String>,
4287    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4288    #[serde(default)]
4289    pub is_replace: bool,
4290    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4291    #[serde(default, skip_serializing_if = "Option::is_none")]
4292    pub hint: Option<Hint>,
4293    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4294    #[serde(default)]
4295    pub replace_where: Option<Box<Expression>>,
4296    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4297    #[serde(default)]
4298    pub source: Option<Box<Expression>>,
4299    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4300    #[serde(default, skip_serializing_if = "Option::is_none")]
4301    pub function_target: Option<Box<Expression>>,
4302    /// ClickHouse: PARTITION BY expr
4303    #[serde(default, skip_serializing_if = "Option::is_none")]
4304    pub partition_by: Option<Box<Expression>>,
4305    /// ClickHouse: SETTINGS key = val, ...
4306    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4307    pub settings: Vec<Expression>,
4308}
4309
4310/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4312#[cfg_attr(feature = "bindings", derive(TS))]
4313pub struct OutputClause {
4314    /// Columns/expressions to output
4315    pub columns: Vec<Expression>,
4316    /// Optional INTO target table or table variable
4317    #[serde(default)]
4318    pub into_table: Option<Expression>,
4319}
4320
4321/// UPDATE statement
4322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4323#[cfg_attr(feature = "bindings", derive(TS))]
4324pub struct Update {
4325    pub table: TableRef,
4326    #[serde(default)]
4327    pub hint: Option<Hint>,
4328    /// Additional tables for multi-table UPDATE (MySQL syntax)
4329    #[serde(default)]
4330    pub extra_tables: Vec<TableRef>,
4331    /// JOINs attached to the table list (MySQL multi-table syntax)
4332    #[serde(default)]
4333    pub table_joins: Vec<Join>,
4334    pub set: Vec<(Identifier, Expression)>,
4335    pub from_clause: Option<From>,
4336    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4337    #[serde(default)]
4338    pub from_joins: Vec<Join>,
4339    pub where_clause: Option<Where>,
4340    /// RETURNING clause (PostgreSQL, SQLite)
4341    #[serde(default)]
4342    pub returning: Vec<Expression>,
4343    /// OUTPUT clause (TSQL)
4344    #[serde(default)]
4345    pub output: Option<OutputClause>,
4346    /// WITH clause (CTEs)
4347    #[serde(default)]
4348    pub with: Option<With>,
4349    /// Leading comments before the statement
4350    #[serde(default)]
4351    pub leading_comments: Vec<String>,
4352    /// LIMIT clause (MySQL)
4353    #[serde(default)]
4354    pub limit: Option<Expression>,
4355    /// ORDER BY clause (MySQL)
4356    #[serde(default)]
4357    pub order_by: Option<OrderBy>,
4358    /// Whether FROM clause appears before SET (Snowflake syntax)
4359    #[serde(default)]
4360    pub from_before_set: bool,
4361}
4362
4363/// DELETE statement
4364#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4365#[cfg_attr(feature = "bindings", derive(TS))]
4366pub struct Delete {
4367    pub table: TableRef,
4368    #[serde(default)]
4369    pub hint: Option<Hint>,
4370    /// ClickHouse: ON CLUSTER clause for distributed DDL
4371    #[serde(default, skip_serializing_if = "Option::is_none")]
4372    pub on_cluster: Option<OnCluster>,
4373    /// Optional alias for the table
4374    pub alias: Option<Identifier>,
4375    /// Whether the alias was declared with explicit AS keyword
4376    #[serde(default)]
4377    pub alias_explicit_as: bool,
4378    /// PostgreSQL/DuckDB USING clause - additional tables to join
4379    pub using: Vec<TableRef>,
4380    pub where_clause: Option<Where>,
4381    /// OUTPUT clause (TSQL)
4382    #[serde(default)]
4383    pub output: Option<OutputClause>,
4384    /// Leading comments before the statement
4385    #[serde(default)]
4386    pub leading_comments: Vec<String>,
4387    /// WITH clause (CTEs)
4388    #[serde(default)]
4389    pub with: Option<With>,
4390    /// LIMIT clause (MySQL)
4391    #[serde(default)]
4392    pub limit: Option<Expression>,
4393    /// ORDER BY clause (MySQL)
4394    #[serde(default)]
4395    pub order_by: Option<OrderBy>,
4396    /// RETURNING clause (PostgreSQL)
4397    #[serde(default)]
4398    pub returning: Vec<Expression>,
4399    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4400    /// These are the target tables to delete from
4401    #[serde(default)]
4402    pub tables: Vec<TableRef>,
4403    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4404    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4405    #[serde(default)]
4406    pub tables_from_using: bool,
4407    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4408    #[serde(default)]
4409    pub joins: Vec<Join>,
4410    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4411    #[serde(default)]
4412    pub force_index: Option<String>,
4413    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4414    #[serde(default)]
4415    pub no_from: bool,
4416}
4417
4418/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4420#[cfg_attr(feature = "bindings", derive(TS))]
4421pub struct CopyStmt {
4422    /// Target table or query
4423    pub this: Expression,
4424    /// True for FROM (loading into table), false for TO (exporting)
4425    pub kind: bool,
4426    /// Source/destination file(s) or stage
4427    pub files: Vec<Expression>,
4428    /// Copy parameters
4429    #[serde(default)]
4430    pub params: Vec<CopyParameter>,
4431    /// Credentials for external access
4432    #[serde(default)]
4433    pub credentials: Option<Box<Credentials>>,
4434    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4435    #[serde(default)]
4436    pub is_into: bool,
4437    /// Whether parameters are wrapped in WITH (...) syntax
4438    #[serde(default)]
4439    pub with_wrapped: bool,
4440}
4441
4442/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4444#[cfg_attr(feature = "bindings", derive(TS))]
4445pub struct CopyParameter {
4446    pub name: String,
4447    pub value: Option<Expression>,
4448    pub values: Vec<Expression>,
4449    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4450    #[serde(default)]
4451    pub eq: bool,
4452}
4453
4454/// Credentials for external access (S3, Azure, etc.)
4455#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4456#[cfg_attr(feature = "bindings", derive(TS))]
4457pub struct Credentials {
4458    pub credentials: Vec<(String, String)>,
4459    pub encryption: Option<String>,
4460    pub storage: Option<String>,
4461}
4462
4463/// PUT statement (Snowflake)
4464#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4465#[cfg_attr(feature = "bindings", derive(TS))]
4466pub struct PutStmt {
4467    /// Source file path
4468    pub source: String,
4469    /// Whether source was quoted in the original SQL
4470    #[serde(default)]
4471    pub source_quoted: bool,
4472    /// Target stage
4473    pub target: Expression,
4474    /// PUT parameters
4475    #[serde(default)]
4476    pub params: Vec<CopyParameter>,
4477}
4478
4479/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4481#[cfg_attr(feature = "bindings", derive(TS))]
4482pub struct StageReference {
4483    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4484    pub name: String,
4485    /// Optional path within the stage (e.g., "/path/to/file.csv")
4486    #[serde(default)]
4487    pub path: Option<String>,
4488    /// Optional FILE_FORMAT parameter
4489    #[serde(default)]
4490    pub file_format: Option<Expression>,
4491    /// Optional PATTERN parameter
4492    #[serde(default)]
4493    pub pattern: Option<String>,
4494    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4495    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4496    pub quoted: bool,
4497}
4498
4499/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4500#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4501#[cfg_attr(feature = "bindings", derive(TS))]
4502pub struct HistoricalData {
4503    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4504    pub this: Box<Expression>,
4505    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4506    pub kind: String,
4507    /// The expression value (e.g., the statement ID or timestamp)
4508    pub expression: Box<Expression>,
4509}
4510
4511/// Represent an aliased expression (`expr AS name`).
4512///
4513/// Used for column aliases in select-lists, table aliases on subqueries,
4514/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4516#[cfg_attr(feature = "bindings", derive(TS))]
4517pub struct Alias {
4518    /// The expression being aliased.
4519    pub this: Expression,
4520    /// The alias name (required for simple aliases, optional when only column aliases provided)
4521    pub alias: Identifier,
4522    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4523    #[serde(default)]
4524    pub column_aliases: Vec<Identifier>,
4525    /// Whether AS keyword was explicitly used for the alias.
4526    #[serde(default)]
4527    pub alias_explicit_as: bool,
4528    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4529    #[serde(skip_serializing_if = "Option::is_none", default)]
4530    pub alias_keyword: Option<String>,
4531    /// Comments that appeared between the expression and AS keyword
4532    #[serde(default)]
4533    pub pre_alias_comments: Vec<String>,
4534    /// Trailing comments that appeared after the alias
4535    #[serde(default)]
4536    pub trailing_comments: Vec<String>,
4537    /// Inferred data type from type annotation
4538    #[serde(default, skip_serializing_if = "Option::is_none")]
4539    #[ast(skip)]
4540    pub inferred_type: Option<DataType>,
4541}
4542
4543impl Alias {
4544    /// Create a simple alias
4545    pub fn new(this: Expression, alias: Identifier) -> Self {
4546        Self {
4547            this,
4548            alias,
4549            column_aliases: Vec::new(),
4550            alias_explicit_as: false,
4551            alias_keyword: None,
4552            pre_alias_comments: Vec::new(),
4553            trailing_comments: Vec::new(),
4554            inferred_type: None,
4555        }
4556    }
4557
4558    /// Create an alias with column aliases only (no table alias name)
4559    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4560        Self {
4561            this,
4562            alias: Identifier::empty(),
4563            column_aliases,
4564            alias_explicit_as: false,
4565            alias_keyword: None,
4566            pre_alias_comments: Vec::new(),
4567            trailing_comments: Vec::new(),
4568            inferred_type: None,
4569        }
4570    }
4571}
4572
4573/// Represent a type cast expression.
4574///
4575/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4576/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4577/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4578/// CONVERSION ERROR (Oracle) clauses.
4579#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4580#[cfg_attr(feature = "bindings", derive(TS))]
4581pub struct Cast {
4582    /// The expression being cast.
4583    pub this: Expression,
4584    /// The target data type.
4585    pub to: DataType,
4586    #[serde(default)]
4587    pub trailing_comments: Vec<String>,
4588    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4589    #[serde(default)]
4590    pub double_colon_syntax: bool,
4591    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4592    #[serde(skip_serializing_if = "Option::is_none", default)]
4593    pub format: Option<Box<Expression>>,
4594    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4595    #[serde(skip_serializing_if = "Option::is_none", default)]
4596    pub default: Option<Box<Expression>>,
4597    /// Inferred data type from type annotation
4598    #[serde(default, skip_serializing_if = "Option::is_none")]
4599    #[ast(skip)]
4600    pub inferred_type: Option<DataType>,
4601}
4602
4603///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4604#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4605#[cfg_attr(feature = "bindings", derive(TS))]
4606pub struct CollationExpr {
4607    pub this: Expression,
4608    pub collation: String,
4609    /// True if the collation was single-quoted in the original SQL (string literal)
4610    #[serde(default)]
4611    pub quoted: bool,
4612    /// True if the collation was double-quoted in the original SQL (identifier)
4613    #[serde(default)]
4614    pub double_quoted: bool,
4615}
4616
4617/// Represent a CASE expression (both simple and searched forms).
4618///
4619/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4620/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4621/// Each entry in `whens` is a `(condition, result)` pair.
4622#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4623#[cfg_attr(feature = "bindings", derive(TS))]
4624pub struct Case {
4625    /// The operand for simple CASE, or `None` for searched CASE.
4626    pub operand: Option<Expression>,
4627    /// Pairs of (WHEN condition, THEN result).
4628    pub whens: Vec<(Expression, Expression)>,
4629    /// Optional ELSE result.
4630    pub else_: Option<Expression>,
4631    /// Comments from the CASE keyword (emitted after END)
4632    #[serde(default)]
4633    #[serde(skip_serializing_if = "Vec::is_empty")]
4634    pub comments: Vec<String>,
4635    /// Inferred data type from type annotation
4636    #[serde(default, skip_serializing_if = "Option::is_none")]
4637    #[ast(skip)]
4638    pub inferred_type: Option<DataType>,
4639}
4640
4641/// Represent a binary operation (two operands separated by an operator).
4642///
4643/// This is the shared payload struct for all binary operator variants in the
4644/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4645/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4646/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4647/// preservation of inline comments around operators.
4648#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4649#[cfg_attr(feature = "bindings", derive(TS))]
4650pub struct BinaryOp {
4651    pub left: Expression,
4652    pub right: Expression,
4653    /// Comments after the left operand (before the operator)
4654    #[serde(default)]
4655    pub left_comments: Vec<String>,
4656    /// Comments after the operator (before the right operand)
4657    #[serde(default)]
4658    pub operator_comments: Vec<String>,
4659    /// Comments after the right operand
4660    #[serde(default)]
4661    pub trailing_comments: Vec<String>,
4662    /// Inferred data type from type annotation
4663    #[serde(default, skip_serializing_if = "Option::is_none")]
4664    #[ast(skip)]
4665    pub inferred_type: Option<DataType>,
4666}
4667
4668impl BinaryOp {
4669    pub fn new(left: Expression, right: Expression) -> Self {
4670        Self {
4671            left,
4672            right,
4673            left_comments: Vec::new(),
4674            operator_comments: Vec::new(),
4675            trailing_comments: Vec::new(),
4676            inferred_type: None,
4677        }
4678    }
4679}
4680
4681/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4683#[cfg_attr(feature = "bindings", derive(TS))]
4684pub struct LikeOp {
4685    pub left: Expression,
4686    pub right: Expression,
4687    /// ESCAPE character/expression
4688    #[serde(default)]
4689    pub escape: Option<Expression>,
4690    /// Quantifier: ANY, ALL, or SOME
4691    #[serde(default)]
4692    pub quantifier: Option<String>,
4693    /// Inferred data type from type annotation
4694    #[serde(default, skip_serializing_if = "Option::is_none")]
4695    #[ast(skip)]
4696    pub inferred_type: Option<DataType>,
4697}
4698
4699impl LikeOp {
4700    pub fn new(left: Expression, right: Expression) -> Self {
4701        Self {
4702            left,
4703            right,
4704            escape: None,
4705            quantifier: None,
4706            inferred_type: None,
4707        }
4708    }
4709
4710    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4711        Self {
4712            left,
4713            right,
4714            escape: Some(escape),
4715            quantifier: None,
4716            inferred_type: None,
4717        }
4718    }
4719}
4720
4721/// Represent a unary operation (single operand with a prefix operator).
4722///
4723/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4725#[cfg_attr(feature = "bindings", derive(TS))]
4726pub struct UnaryOp {
4727    /// The operand expression.
4728    pub this: Expression,
4729    /// Inferred data type from type annotation
4730    #[serde(default, skip_serializing_if = "Option::is_none")]
4731    #[ast(skip)]
4732    pub inferred_type: Option<DataType>,
4733}
4734
4735impl UnaryOp {
4736    pub fn new(this: Expression) -> Self {
4737        Self {
4738            this,
4739            inferred_type: None,
4740        }
4741    }
4742}
4743
4744/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4745///
4746/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4747/// but not both. When `not` is true, the predicate is `NOT IN`.
4748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4749#[cfg_attr(feature = "bindings", derive(TS))]
4750pub struct In {
4751    /// The expression being tested.
4752    pub this: Expression,
4753    /// The value list (mutually exclusive with `query`).
4754    pub expressions: Vec<Expression>,
4755    /// A subquery (mutually exclusive with `expressions`).
4756    pub query: Option<Expression>,
4757    /// Whether this is NOT IN.
4758    pub not: bool,
4759    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4760    pub global: bool,
4761    /// BigQuery: IN UNNEST(expr)
4762    #[serde(default, skip_serializing_if = "Option::is_none")]
4763    pub unnest: Option<Box<Expression>>,
4764    /// Whether the right side is a bare field reference (no parentheses).
4765    /// Matches Python sqlglot's `field` attribute on `In` expression.
4766    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4767    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4768    pub is_field: bool,
4769}
4770
4771/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4772#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4773#[cfg_attr(feature = "bindings", derive(TS))]
4774pub struct Between {
4775    /// The expression being tested.
4776    pub this: Expression,
4777    /// The lower bound.
4778    pub low: Expression,
4779    /// The upper bound.
4780    pub high: Expression,
4781    /// Whether this is NOT BETWEEN.
4782    pub not: bool,
4783    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4784    #[serde(default)]
4785    pub symmetric: Option<bool>,
4786}
4787
4788/// IS NULL predicate
4789#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4790#[cfg_attr(feature = "bindings", derive(TS))]
4791pub struct IsNull {
4792    pub this: Expression,
4793    pub not: bool,
4794    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4795    #[serde(default)]
4796    pub postfix_form: bool,
4797}
4798
4799/// IS TRUE / IS FALSE predicate
4800#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4801#[cfg_attr(feature = "bindings", derive(TS))]
4802pub struct IsTrueFalse {
4803    pub this: Expression,
4804    pub not: bool,
4805}
4806
4807/// IS JSON predicate (SQL standard)
4808/// Checks if a value is valid JSON
4809#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4810#[cfg_attr(feature = "bindings", derive(TS))]
4811pub struct IsJson {
4812    pub this: Expression,
4813    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4814    pub json_type: Option<String>,
4815    /// Key uniqueness constraint
4816    pub unique_keys: Option<JsonUniqueKeys>,
4817    /// Whether IS NOT JSON
4818    pub negated: bool,
4819}
4820
4821/// JSON unique keys constraint variants
4822#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4823#[cfg_attr(feature = "bindings", derive(TS))]
4824pub enum JsonUniqueKeys {
4825    /// WITH UNIQUE KEYS
4826    With,
4827    /// WITHOUT UNIQUE KEYS
4828    Without,
4829    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4830    Shorthand,
4831}
4832
4833/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4835#[cfg_attr(feature = "bindings", derive(TS))]
4836pub struct Exists {
4837    /// The subquery expression.
4838    pub this: Expression,
4839    /// Whether this is NOT EXISTS.
4840    pub not: bool,
4841}
4842
4843/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
4844///
4845/// This is the generic function node. Well-known aggregates, window functions,
4846/// and built-in functions each have their own dedicated `Expression` variants
4847/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
4848/// not recognize as built-ins are represented with this struct.
4849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4850#[cfg_attr(feature = "bindings", derive(TS))]
4851pub struct Function {
4852    /// The function name, as originally written (may be schema-qualified).
4853    pub name: String,
4854    /// Positional arguments to the function.
4855    pub args: Vec<Expression>,
4856    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
4857    pub distinct: bool,
4858    #[serde(default)]
4859    pub trailing_comments: Vec<String>,
4860    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
4861    #[serde(default)]
4862    pub use_bracket_syntax: bool,
4863    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
4864    #[serde(default)]
4865    pub no_parens: bool,
4866    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
4867    #[serde(default)]
4868    pub quoted: bool,
4869    /// Source position span
4870    #[serde(default, skip_serializing_if = "Option::is_none")]
4871    pub span: Option<Span>,
4872    /// Inferred data type from type annotation
4873    #[serde(default, skip_serializing_if = "Option::is_none")]
4874    #[ast(skip)]
4875    pub inferred_type: Option<DataType>,
4876}
4877
4878impl Default for Function {
4879    fn default() -> Self {
4880        Self {
4881            name: String::new(),
4882            args: Vec::new(),
4883            distinct: false,
4884            trailing_comments: Vec::new(),
4885            use_bracket_syntax: false,
4886            no_parens: false,
4887            quoted: false,
4888            span: None,
4889            inferred_type: None,
4890        }
4891    }
4892}
4893
4894impl Function {
4895    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
4896        Self {
4897            name: name.into(),
4898            args,
4899            distinct: false,
4900            trailing_comments: Vec::new(),
4901            use_bracket_syntax: false,
4902            no_parens: false,
4903            quoted: false,
4904            span: None,
4905            inferred_type: None,
4906        }
4907    }
4908}
4909
4910/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
4911///
4912/// This struct is used for aggregate function calls that are not covered by
4913/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
4914/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
4915/// IGNORE NULLS / RESPECT NULLS modifiers.
4916#[derive(
4917    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
4918)]
4919#[cfg_attr(feature = "bindings", derive(TS))]
4920pub struct AggregateFunction {
4921    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
4922    pub name: String,
4923    /// Positional arguments.
4924    pub args: Vec<Expression>,
4925    /// Whether DISTINCT was specified.
4926    pub distinct: bool,
4927    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
4928    pub filter: Option<Expression>,
4929    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
4930    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4931    pub order_by: Vec<Ordered>,
4932    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
4933    #[serde(default, skip_serializing_if = "Option::is_none")]
4934    pub limit: Option<Box<Expression>>,
4935    /// IGNORE NULLS / RESPECT NULLS
4936    #[serde(default, skip_serializing_if = "Option::is_none")]
4937    pub ignore_nulls: Option<bool>,
4938    /// Inferred data type from type annotation
4939    #[serde(default, skip_serializing_if = "Option::is_none")]
4940    #[ast(skip)]
4941    pub inferred_type: Option<DataType>,
4942}
4943
4944/// Represent a window function call with its OVER clause.
4945///
4946/// The inner `this` expression is typically a window-specific expression
4947/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
4948/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
4949/// frame specification.
4950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4951#[cfg_attr(feature = "bindings", derive(TS))]
4952pub struct WindowFunction {
4953    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
4954    pub this: Expression,
4955    /// The OVER clause defining the window partitioning, ordering, and frame.
4956    pub over: Over,
4957    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
4958    #[serde(default, skip_serializing_if = "Option::is_none")]
4959    pub keep: Option<Keep>,
4960    /// Inferred data type from type annotation
4961    #[serde(default, skip_serializing_if = "Option::is_none")]
4962    #[ast(skip)]
4963    pub inferred_type: Option<DataType>,
4964}
4965
4966/// Oracle KEEP clause for aggregate functions
4967/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
4968#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4969#[cfg_attr(feature = "bindings", derive(TS))]
4970pub struct Keep {
4971    /// true = FIRST, false = LAST
4972    pub first: bool,
4973    /// ORDER BY clause inside KEEP
4974    pub order_by: Vec<Ordered>,
4975}
4976
4977/// WITHIN GROUP clause (for ordered-set aggregate functions)
4978#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4979#[cfg_attr(feature = "bindings", derive(TS))]
4980pub struct WithinGroup {
4981    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
4982    pub this: Expression,
4983    /// The ORDER BY clause within the group
4984    pub order_by: Vec<Ordered>,
4985}
4986
4987/// Represent the FROM clause of a SELECT statement.
4988///
4989/// Contains one or more table sources (tables, subqueries, table-valued
4990/// functions, etc.). Multiple entries represent comma-separated implicit joins.
4991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4992#[cfg_attr(feature = "bindings", derive(TS))]
4993pub struct From {
4994    /// The table source expressions.
4995    pub expressions: Vec<Expression>,
4996}
4997
4998/// Represent a JOIN clause between two table sources.
4999///
5000/// The join condition can be specified via `on` (ON predicate) or `using`
5001/// (USING column list), but not both. The `kind` field determines the join
5002/// type (INNER, LEFT, CROSS, etc.).
5003#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5004#[cfg_attr(feature = "bindings", derive(TS))]
5005pub struct Join {
5006    /// The right-hand table expression being joined.
5007    pub this: Expression,
5008    /// The ON condition (mutually exclusive with `using`).
5009    pub on: Option<Expression>,
5010    /// The USING column list (mutually exclusive with `on`).
5011    pub using: Vec<Identifier>,
5012    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5013    pub kind: JoinKind,
5014    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5015    pub use_inner_keyword: bool,
5016    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5017    pub use_outer_keyword: bool,
5018    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5019    pub deferred_condition: bool,
5020    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5021    #[serde(default, skip_serializing_if = "Option::is_none")]
5022    pub join_hint: Option<String>,
5023    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5024    #[serde(default, skip_serializing_if = "Option::is_none")]
5025    pub match_condition: Option<Expression>,
5026    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5027    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5028    pub pivots: Vec<Expression>,
5029    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5030    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5031    pub comments: Vec<String>,
5032    /// Nesting group identifier for nested join pretty-printing.
5033    /// Joins in the same group were parsed together; group boundaries come from
5034    /// deferred condition resolution phases.
5035    #[serde(default)]
5036    pub nesting_group: usize,
5037    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5038    #[serde(default)]
5039    pub directed: bool,
5040}
5041
5042/// Enumerate all supported SQL join types.
5043///
5044/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5045/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5046/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5047/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5048#[derive(
5049    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5050)]
5051#[cfg_attr(feature = "bindings", derive(TS))]
5052pub enum JoinKind {
5053    Inner,
5054    Left,
5055    Right,
5056    Full,
5057    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5058    Cross,
5059    Natural,
5060    NaturalLeft,
5061    NaturalRight,
5062    NaturalFull,
5063    Semi,
5064    Anti,
5065    // Directional SEMI/ANTI joins
5066    LeftSemi,
5067    LeftAnti,
5068    RightSemi,
5069    RightAnti,
5070    // SQL Server specific
5071    CrossApply,
5072    OuterApply,
5073    // Time-series specific
5074    AsOf,
5075    AsOfLeft,
5076    AsOfRight,
5077    // Lateral join
5078    Lateral,
5079    LeftLateral,
5080    // MySQL specific
5081    Straight,
5082    // Implicit join (comma-separated tables: FROM a, b)
5083    Implicit,
5084    // ClickHouse ARRAY JOIN
5085    Array,
5086    LeftArray,
5087    // ClickHouse PASTE JOIN (positional join)
5088    Paste,
5089    // DuckDB POSITIONAL JOIN
5090    Positional,
5091}
5092
5093impl Default for JoinKind {
5094    fn default() -> Self {
5095        JoinKind::Inner
5096    }
5097}
5098
5099/// Parenthesized table expression with joins
5100/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5101#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5102#[cfg_attr(feature = "bindings", derive(TS))]
5103pub struct JoinedTable {
5104    /// The left-hand side table expression
5105    pub left: Expression,
5106    /// The joins applied to the left table
5107    pub joins: Vec<Join>,
5108    /// LATERAL VIEW clauses (Hive/Spark)
5109    pub lateral_views: Vec<LateralView>,
5110    /// Optional alias for the joined table expression
5111    pub alias: Option<Identifier>,
5112}
5113
5114/// Represent a WHERE clause containing a boolean filter predicate.
5115#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5116#[cfg_attr(feature = "bindings", derive(TS))]
5117pub struct Where {
5118    /// The filter predicate expression.
5119    pub this: Expression,
5120}
5121
5122/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5123///
5124/// The `expressions` list may contain plain columns, ordinal positions,
5125/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5127#[cfg_attr(feature = "bindings", derive(TS))]
5128pub struct GroupBy {
5129    /// The grouping expressions.
5130    pub expressions: Vec<Expression>,
5131    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5132    #[serde(default)]
5133    pub all: Option<bool>,
5134    /// ClickHouse: WITH TOTALS modifier
5135    #[serde(default)]
5136    pub totals: bool,
5137    /// Leading comments that appeared before the GROUP BY keyword
5138    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5139    pub comments: Vec<String>,
5140}
5141
5142/// Represent a HAVING clause containing a predicate over aggregate results.
5143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5144#[cfg_attr(feature = "bindings", derive(TS))]
5145pub struct Having {
5146    /// The filter predicate, typically involving aggregate functions.
5147    pub this: Expression,
5148    /// Leading comments that appeared before the HAVING keyword
5149    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5150    pub comments: Vec<String>,
5151}
5152
5153/// Represent an ORDER BY clause containing one or more sort specifications.
5154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5155#[cfg_attr(feature = "bindings", derive(TS))]
5156pub struct OrderBy {
5157    /// The sort specifications, each with direction and null ordering.
5158    pub expressions: Vec<Ordered>,
5159    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5160    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5161    pub siblings: bool,
5162    /// Leading comments that appeared before the ORDER BY keyword
5163    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5164    pub comments: Vec<String>,
5165}
5166
5167/// Represent an expression with sort direction and null ordering.
5168///
5169/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5170/// When `desc` is false the sort is ascending. The `nulls_first` field
5171/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5172/// (database default).
5173#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5174#[cfg_attr(feature = "bindings", derive(TS))]
5175pub struct Ordered {
5176    /// The expression to sort by.
5177    pub this: Expression,
5178    /// Whether the sort direction is descending (true) or ascending (false).
5179    pub desc: bool,
5180    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5181    pub nulls_first: Option<bool>,
5182    /// Whether ASC was explicitly written (not just implied)
5183    #[serde(default)]
5184    pub explicit_asc: bool,
5185    /// ClickHouse WITH FILL clause
5186    #[serde(default, skip_serializing_if = "Option::is_none")]
5187    pub with_fill: Option<Box<WithFill>>,
5188}
5189
5190impl Ordered {
5191    pub fn asc(expr: Expression) -> Self {
5192        Self {
5193            this: expr,
5194            desc: false,
5195            nulls_first: None,
5196            explicit_asc: false,
5197            with_fill: None,
5198        }
5199    }
5200
5201    pub fn desc(expr: Expression) -> Self {
5202        Self {
5203            this: expr,
5204            desc: true,
5205            nulls_first: None,
5206            explicit_asc: false,
5207            with_fill: None,
5208        }
5209    }
5210}
5211
5212/// DISTRIBUTE BY clause (Hive/Spark)
5213/// Controls how rows are distributed across reducers
5214#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5215#[cfg_attr(feature = "bindings", derive(TS))]
5216#[cfg_attr(feature = "bindings", ts(export))]
5217pub struct DistributeBy {
5218    pub expressions: Vec<Expression>,
5219}
5220
5221/// CLUSTER BY clause (Hive/Spark)
5222/// Combines DISTRIBUTE BY and SORT BY on the same columns
5223#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5224#[cfg_attr(feature = "bindings", derive(TS))]
5225#[cfg_attr(feature = "bindings", ts(export))]
5226pub struct ClusterBy {
5227    pub expressions: Vec<Ordered>,
5228}
5229
5230/// SORT BY clause (Hive/Spark)
5231/// Sorts data within each reducer (local sort, not global)
5232#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5233#[cfg_attr(feature = "bindings", derive(TS))]
5234#[cfg_attr(feature = "bindings", ts(export))]
5235pub struct SortBy {
5236    pub expressions: Vec<Ordered>,
5237}
5238
5239/// LATERAL VIEW clause (Hive/Spark)
5240/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5242#[cfg_attr(feature = "bindings", derive(TS))]
5243#[cfg_attr(feature = "bindings", ts(export))]
5244pub struct LateralView {
5245    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5246    pub this: Expression,
5247    /// Table alias for the generated table
5248    pub table_alias: Option<Identifier>,
5249    /// Column aliases for the generated columns
5250    pub column_aliases: Vec<Identifier>,
5251    /// OUTER keyword - preserve nulls when input is empty/null
5252    pub outer: bool,
5253}
5254
5255/// Query hint
5256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5257#[cfg_attr(feature = "bindings", derive(TS))]
5258#[cfg_attr(feature = "bindings", ts(export))]
5259pub struct Hint {
5260    pub expressions: Vec<HintExpression>,
5261}
5262
5263/// Individual hint expression
5264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5265#[cfg_attr(feature = "bindings", derive(TS))]
5266#[cfg_attr(feature = "bindings", ts(export))]
5267pub enum HintExpression {
5268    /// Function-style hint: USE_HASH(table)
5269    Function { name: String, args: Vec<Expression> },
5270    /// Simple identifier hint: PARALLEL
5271    Identifier(String),
5272    /// Raw hint text (unparsed)
5273    Raw(String),
5274}
5275
5276/// Pseudocolumn type
5277#[derive(
5278    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5279)]
5280#[cfg_attr(feature = "bindings", derive(TS))]
5281#[cfg_attr(feature = "bindings", ts(export))]
5282pub enum PseudocolumnType {
5283    Rownum,      // Oracle ROWNUM
5284    Rowid,       // Oracle ROWID
5285    Level,       // Oracle LEVEL (for CONNECT BY)
5286    Sysdate,     // Oracle SYSDATE
5287    ObjectId,    // Oracle OBJECT_ID
5288    ObjectValue, // Oracle OBJECT_VALUE
5289}
5290
5291impl PseudocolumnType {
5292    pub fn as_str(&self) -> &'static str {
5293        match self {
5294            PseudocolumnType::Rownum => "ROWNUM",
5295            PseudocolumnType::Rowid => "ROWID",
5296            PseudocolumnType::Level => "LEVEL",
5297            PseudocolumnType::Sysdate => "SYSDATE",
5298            PseudocolumnType::ObjectId => "OBJECT_ID",
5299            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5300        }
5301    }
5302
5303    pub fn from_str(s: &str) -> Option<Self> {
5304        match s.to_uppercase().as_str() {
5305            "ROWNUM" => Some(PseudocolumnType::Rownum),
5306            "ROWID" => Some(PseudocolumnType::Rowid),
5307            "LEVEL" => Some(PseudocolumnType::Level),
5308            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5309            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5310            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5311            _ => None,
5312        }
5313    }
5314}
5315
5316/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5317/// These are special identifiers that should not be quoted
5318#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5319#[cfg_attr(feature = "bindings", derive(TS))]
5320#[cfg_attr(feature = "bindings", ts(export))]
5321pub struct Pseudocolumn {
5322    pub kind: PseudocolumnType,
5323}
5324
5325impl Pseudocolumn {
5326    pub fn rownum() -> Self {
5327        Self {
5328            kind: PseudocolumnType::Rownum,
5329        }
5330    }
5331
5332    pub fn rowid() -> Self {
5333        Self {
5334            kind: PseudocolumnType::Rowid,
5335        }
5336    }
5337
5338    pub fn level() -> Self {
5339        Self {
5340            kind: PseudocolumnType::Level,
5341        }
5342    }
5343}
5344
5345/// Oracle CONNECT BY clause for hierarchical queries
5346#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5347#[cfg_attr(feature = "bindings", derive(TS))]
5348#[cfg_attr(feature = "bindings", ts(export))]
5349pub struct Connect {
5350    /// START WITH condition (optional, can come before or after CONNECT BY)
5351    pub start: Option<Expression>,
5352    /// CONNECT BY condition (required, contains PRIOR references)
5353    pub connect: Expression,
5354    /// NOCYCLE keyword to prevent infinite loops
5355    pub nocycle: bool,
5356}
5357
5358/// Oracle PRIOR expression - references parent row's value in CONNECT BY
5359#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5360#[cfg_attr(feature = "bindings", derive(TS))]
5361#[cfg_attr(feature = "bindings", ts(export))]
5362pub struct Prior {
5363    pub this: Expression,
5364}
5365
5366/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5367#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5368#[cfg_attr(feature = "bindings", derive(TS))]
5369#[cfg_attr(feature = "bindings", ts(export))]
5370pub struct ConnectByRoot {
5371    pub this: Expression,
5372}
5373
5374/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5376#[cfg_attr(feature = "bindings", derive(TS))]
5377#[cfg_attr(feature = "bindings", ts(export))]
5378pub struct MatchRecognize {
5379    /// Source table/expression
5380    pub this: Option<Box<Expression>>,
5381    /// PARTITION BY expressions
5382    pub partition_by: Option<Vec<Expression>>,
5383    /// ORDER BY expressions
5384    pub order_by: Option<Vec<Ordered>>,
5385    /// MEASURES definitions
5386    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5387    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5388    pub rows: Option<MatchRecognizeRows>,
5389    /// AFTER MATCH SKIP behavior
5390    pub after: Option<MatchRecognizeAfter>,
5391    /// PATTERN definition (stored as raw string for complex regex patterns)
5392    pub pattern: Option<String>,
5393    /// DEFINE clauses (pattern variable definitions)
5394    pub define: Option<Vec<(Identifier, Expression)>>,
5395    /// Optional alias for the result
5396    pub alias: Option<Identifier>,
5397    /// Whether AS keyword was explicitly present before alias
5398    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5399    pub alias_explicit_as: bool,
5400}
5401
5402/// MEASURES expression with optional RUNNING/FINAL semantics
5403#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5404#[cfg_attr(feature = "bindings", derive(TS))]
5405#[cfg_attr(feature = "bindings", ts(export))]
5406pub struct MatchRecognizeMeasure {
5407    /// The measure expression
5408    pub this: Expression,
5409    /// RUNNING or FINAL semantics (Snowflake-specific)
5410    pub window_frame: Option<MatchRecognizeSemantics>,
5411}
5412
5413/// Semantics for MEASURES in MATCH_RECOGNIZE
5414#[derive(
5415    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5416)]
5417#[cfg_attr(feature = "bindings", derive(TS))]
5418#[cfg_attr(feature = "bindings", ts(export))]
5419pub enum MatchRecognizeSemantics {
5420    Running,
5421    Final,
5422}
5423
5424/// Row output semantics for MATCH_RECOGNIZE
5425#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5426#[cfg_attr(feature = "bindings", derive(TS))]
5427#[cfg_attr(feature = "bindings", ts(export))]
5428pub enum MatchRecognizeRows {
5429    OneRowPerMatch,
5430    AllRowsPerMatch,
5431    AllRowsPerMatchShowEmptyMatches,
5432    AllRowsPerMatchOmitEmptyMatches,
5433    AllRowsPerMatchWithUnmatchedRows,
5434}
5435
5436/// AFTER MATCH SKIP behavior
5437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5438#[cfg_attr(feature = "bindings", derive(TS))]
5439#[cfg_attr(feature = "bindings", ts(export))]
5440pub enum MatchRecognizeAfter {
5441    PastLastRow,
5442    ToNextRow,
5443    ToFirst(Identifier),
5444    ToLast(Identifier),
5445}
5446
5447/// Represent a LIMIT clause that restricts the number of returned rows.
5448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5449#[cfg_attr(feature = "bindings", derive(TS))]
5450pub struct Limit {
5451    /// The limit count expression.
5452    pub this: Expression,
5453    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5454    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5455    pub percent: bool,
5456    /// Comments from before the LIMIT keyword (emitted after the limit value)
5457    #[serde(default)]
5458    #[serde(skip_serializing_if = "Vec::is_empty")]
5459    pub comments: Vec<String>,
5460}
5461
5462/// OFFSET clause
5463#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5464#[cfg_attr(feature = "bindings", derive(TS))]
5465pub struct Offset {
5466    pub this: Expression,
5467    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5468    #[serde(skip_serializing_if = "Option::is_none", default)]
5469    pub rows: Option<bool>,
5470}
5471
5472/// TOP clause (SQL Server)
5473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5474#[cfg_attr(feature = "bindings", derive(TS))]
5475pub struct Top {
5476    pub this: Expression,
5477    pub percent: bool,
5478    pub with_ties: bool,
5479    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5480    #[serde(default)]
5481    pub parenthesized: bool,
5482}
5483
5484/// FETCH FIRST/NEXT clause (SQL standard)
5485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5486#[cfg_attr(feature = "bindings", derive(TS))]
5487pub struct Fetch {
5488    /// FIRST or NEXT
5489    pub direction: String,
5490    /// Count expression (optional)
5491    pub count: Option<Expression>,
5492    /// PERCENT modifier
5493    pub percent: bool,
5494    /// ROWS or ROW keyword present
5495    pub rows: bool,
5496    /// WITH TIES modifier
5497    pub with_ties: bool,
5498}
5499
5500/// Represent a QUALIFY clause for filtering on window function results.
5501///
5502/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5503/// typically references a window function (e.g.
5504/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5505#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5506#[cfg_attr(feature = "bindings", derive(TS))]
5507pub struct Qualify {
5508    /// The filter predicate over window function results.
5509    pub this: Expression,
5510}
5511
5512/// SAMPLE / TABLESAMPLE clause
5513#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5514#[cfg_attr(feature = "bindings", derive(TS))]
5515pub struct Sample {
5516    pub method: SampleMethod,
5517    pub size: Expression,
5518    pub seed: Option<Expression>,
5519    /// ClickHouse OFFSET expression after SAMPLE size
5520    #[serde(default)]
5521    pub offset: Option<Expression>,
5522    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5523    pub unit_after_size: bool,
5524    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5525    #[serde(default)]
5526    pub use_sample_keyword: bool,
5527    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5528    #[serde(default)]
5529    pub explicit_method: bool,
5530    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5531    #[serde(default)]
5532    pub method_before_size: bool,
5533    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5534    #[serde(default)]
5535    pub use_seed_keyword: bool,
5536    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5537    pub bucket_numerator: Option<Box<Expression>>,
5538    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5539    pub bucket_denominator: Option<Box<Expression>>,
5540    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5541    pub bucket_field: Option<Box<Expression>>,
5542    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5543    #[serde(default)]
5544    pub is_using_sample: bool,
5545    /// Whether the unit was explicitly PERCENT (vs ROWS)
5546    #[serde(default)]
5547    pub is_percent: bool,
5548    /// Whether to suppress method output (for cross-dialect transpilation)
5549    #[serde(default)]
5550    pub suppress_method_output: bool,
5551}
5552
5553/// Sample method
5554#[derive(
5555    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5556)]
5557#[cfg_attr(feature = "bindings", derive(TS))]
5558pub enum SampleMethod {
5559    Bernoulli,
5560    System,
5561    Block,
5562    Row,
5563    Percent,
5564    /// Hive bucket sampling
5565    Bucket,
5566    /// DuckDB reservoir sampling
5567    Reservoir,
5568}
5569
5570/// Named window definition (WINDOW w AS (...))
5571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5572#[cfg_attr(feature = "bindings", derive(TS))]
5573pub struct NamedWindow {
5574    pub name: Identifier,
5575    pub spec: Over,
5576}
5577
5578/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5579///
5580/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5581/// that reference themselves. Each CTE is defined in the `ctes` vector and
5582/// can be referenced by name in subsequent CTEs and in the main query body.
5583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5584#[cfg_attr(feature = "bindings", derive(TS))]
5585pub struct With {
5586    /// The list of CTE definitions, in order.
5587    pub ctes: Vec<Cte>,
5588    /// Whether the WITH RECURSIVE keyword was used.
5589    pub recursive: bool,
5590    /// Leading comments before the statement
5591    #[serde(default)]
5592    pub leading_comments: Vec<String>,
5593    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5594    #[serde(default, skip_serializing_if = "Option::is_none")]
5595    pub search: Option<Box<Expression>>,
5596}
5597
5598/// Represent a single Common Table Expression definition.
5599///
5600/// A CTE has a name (`alias`), an optional column list, and a body query.
5601/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5602/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5603/// the expression comes before the alias (`alias_first`).
5604#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5605#[cfg_attr(feature = "bindings", derive(TS))]
5606pub struct Cte {
5607    /// The CTE name.
5608    pub alias: Identifier,
5609    /// The CTE body (typically a SELECT, UNION, etc.).
5610    pub this: Expression,
5611    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5612    pub columns: Vec<Identifier>,
5613    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5614    pub materialized: Option<bool>,
5615    /// USING KEY (columns) for DuckDB recursive CTEs
5616    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5617    pub key_expressions: Vec<Identifier>,
5618    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5619    #[serde(default)]
5620    pub alias_first: bool,
5621    /// Comments associated with this CTE (placed after alias name, before AS)
5622    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5623    pub comments: Vec<String>,
5624}
5625
5626/// Window specification
5627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5628#[cfg_attr(feature = "bindings", derive(TS))]
5629pub struct WindowSpec {
5630    pub partition_by: Vec<Expression>,
5631    pub order_by: Vec<Ordered>,
5632    pub frame: Option<WindowFrame>,
5633}
5634
5635/// OVER clause
5636#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5637#[cfg_attr(feature = "bindings", derive(TS))]
5638pub struct Over {
5639    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
5640    pub window_name: Option<Identifier>,
5641    pub partition_by: Vec<Expression>,
5642    pub order_by: Vec<Ordered>,
5643    pub frame: Option<WindowFrame>,
5644    pub alias: Option<Identifier>,
5645}
5646
5647/// Window frame
5648#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5649#[cfg_attr(feature = "bindings", derive(TS))]
5650pub struct WindowFrame {
5651    pub kind: WindowFrameKind,
5652    pub start: WindowFrameBound,
5653    pub end: Option<WindowFrameBound>,
5654    pub exclude: Option<WindowFrameExclude>,
5655    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
5656    #[serde(default, skip_serializing_if = "Option::is_none")]
5657    pub kind_text: Option<String>,
5658    /// Original text of the start bound side keyword (e.g. "preceding")
5659    #[serde(default, skip_serializing_if = "Option::is_none")]
5660    pub start_side_text: Option<String>,
5661    /// Original text of the end bound side keyword
5662    #[serde(default, skip_serializing_if = "Option::is_none")]
5663    pub end_side_text: Option<String>,
5664}
5665
5666#[derive(
5667    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5668)]
5669#[cfg_attr(feature = "bindings", derive(TS))]
5670pub enum WindowFrameKind {
5671    Rows,
5672    Range,
5673    Groups,
5674}
5675
5676/// EXCLUDE clause for window frames
5677#[derive(
5678    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5679)]
5680#[cfg_attr(feature = "bindings", derive(TS))]
5681pub enum WindowFrameExclude {
5682    CurrentRow,
5683    Group,
5684    Ties,
5685    NoOthers,
5686}
5687
5688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5689#[cfg_attr(feature = "bindings", derive(TS))]
5690pub enum WindowFrameBound {
5691    CurrentRow,
5692    UnboundedPreceding,
5693    UnboundedFollowing,
5694    Preceding(Box<Expression>),
5695    Following(Box<Expression>),
5696    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
5697    BarePreceding,
5698    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
5699    BareFollowing,
5700    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
5701    Value(Box<Expression>),
5702}
5703
5704/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
5705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5706#[cfg_attr(feature = "bindings", derive(TS))]
5707pub struct StructField {
5708    pub name: String,
5709    pub data_type: DataType,
5710    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5711    pub options: Vec<Expression>,
5712    #[serde(default, skip_serializing_if = "Option::is_none")]
5713    pub comment: Option<String>,
5714}
5715
5716impl StructField {
5717    /// Create a new struct field without options
5718    pub fn new(name: String, data_type: DataType) -> Self {
5719        Self {
5720            name,
5721            data_type,
5722            options: Vec::new(),
5723            comment: None,
5724        }
5725    }
5726
5727    /// Create a new struct field with options
5728    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
5729        Self {
5730            name,
5731            data_type,
5732            options,
5733            comment: None,
5734        }
5735    }
5736
5737    /// Create a new struct field with options and comment
5738    pub fn with_options_and_comment(
5739        name: String,
5740        data_type: DataType,
5741        options: Vec<Expression>,
5742        comment: Option<String>,
5743    ) -> Self {
5744        Self {
5745            name,
5746            data_type,
5747            options,
5748            comment,
5749        }
5750    }
5751}
5752
5753/// Enumerate all SQL data types recognized by the parser.
5754///
5755/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
5756/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
5757/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
5758///
5759/// This enum is used in CAST expressions, column definitions, function return
5760/// types, and anywhere a data type specification appears in SQL.
5761///
5762/// Types that do not match any known variant fall through to `Custom { name }`,
5763/// preserving the original type name for round-trip fidelity.
5764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5765#[cfg_attr(feature = "bindings", derive(TS))]
5766#[serde(tag = "data_type", rename_all = "snake_case")]
5767pub enum DataType {
5768    // Numeric
5769    Boolean,
5770    TinyInt {
5771        length: Option<u32>,
5772    },
5773    SmallInt {
5774        length: Option<u32>,
5775    },
5776    /// Int type with optional length. `integer_spelling` indicates whether the original
5777    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
5778    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
5779    Int {
5780        length: Option<u32>,
5781        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5782        integer_spelling: bool,
5783    },
5784    BigInt {
5785        length: Option<u32>,
5786    },
5787    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
5788    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
5789    /// preserve the original spelling.
5790    Float {
5791        precision: Option<u32>,
5792        scale: Option<u32>,
5793        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5794        real_spelling: bool,
5795    },
5796    Double {
5797        precision: Option<u32>,
5798        scale: Option<u32>,
5799    },
5800    Decimal {
5801        precision: Option<u32>,
5802        scale: Option<u32>,
5803    },
5804
5805    // String
5806    Char {
5807        length: Option<u32>,
5808    },
5809    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
5810    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
5811    VarChar {
5812        length: Option<u32>,
5813        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5814        parenthesized_length: bool,
5815    },
5816    /// String type with optional max length (BigQuery STRING(n))
5817    String {
5818        length: Option<u32>,
5819    },
5820    Text,
5821    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
5822    TextWithLength {
5823        length: u32,
5824    },
5825
5826    // Binary
5827    Binary {
5828        length: Option<u32>,
5829    },
5830    VarBinary {
5831        length: Option<u32>,
5832    },
5833    Blob,
5834
5835    // Bit
5836    Bit {
5837        length: Option<u32>,
5838    },
5839    VarBit {
5840        length: Option<u32>,
5841    },
5842
5843    // Date/Time
5844    Date,
5845    Time {
5846        precision: Option<u32>,
5847        #[serde(default)]
5848        timezone: bool,
5849    },
5850    Timestamp {
5851        precision: Option<u32>,
5852        timezone: bool,
5853    },
5854    Interval {
5855        unit: Option<String>,
5856        /// For range intervals like INTERVAL DAY TO HOUR
5857        #[serde(default, skip_serializing_if = "Option::is_none")]
5858        to: Option<String>,
5859    },
5860
5861    // JSON
5862    Json,
5863    JsonB,
5864
5865    // UUID
5866    Uuid,
5867
5868    // Array
5869    Array {
5870        element_type: Box<DataType>,
5871        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
5872        #[serde(default, skip_serializing_if = "Option::is_none")]
5873        dimension: Option<u32>,
5874    },
5875
5876    /// List type (Materialize): INT LIST, TEXT LIST LIST
5877    /// Uses postfix LIST syntax instead of ARRAY<T>
5878    List {
5879        element_type: Box<DataType>,
5880    },
5881
5882    // Struct/Map
5883    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
5884    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
5885    Struct {
5886        fields: Vec<StructField>,
5887        nested: bool,
5888    },
5889    Map {
5890        key_type: Box<DataType>,
5891        value_type: Box<DataType>,
5892    },
5893
5894    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
5895    Enum {
5896        values: Vec<String>,
5897        #[serde(default, skip_serializing_if = "Vec::is_empty")]
5898        assignments: Vec<Option<String>>,
5899    },
5900
5901    // Set type (MySQL): SET('a', 'b', 'c')
5902    Set {
5903        values: Vec<String>,
5904    },
5905
5906    // Union type (DuckDB): UNION(num INT, str TEXT)
5907    Union {
5908        fields: Vec<(String, DataType)>,
5909    },
5910
5911    // Vector (Snowflake / SingleStore)
5912    Vector {
5913        #[serde(default)]
5914        element_type: Option<Box<DataType>>,
5915        dimension: Option<u32>,
5916    },
5917
5918    // Object (Snowflake structured type)
5919    // fields: Vec of (field_name, field_type, not_null)
5920    Object {
5921        fields: Vec<(String, DataType, bool)>,
5922        modifier: Option<String>,
5923    },
5924
5925    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
5926    Nullable {
5927        inner: Box<DataType>,
5928    },
5929
5930    // Custom/User-defined
5931    Custom {
5932        name: String,
5933    },
5934
5935    // Spatial types
5936    Geometry {
5937        subtype: Option<String>,
5938        srid: Option<u32>,
5939    },
5940    Geography {
5941        subtype: Option<String>,
5942        srid: Option<u32>,
5943    },
5944
5945    // Character Set (for CONVERT USING in MySQL)
5946    // Renders as CHAR CHARACTER SET {name} in cast target
5947    CharacterSet {
5948        name: String,
5949    },
5950
5951    // Unknown
5952    Unknown,
5953}
5954
5955/// Array expression
5956#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5957#[cfg_attr(feature = "bindings", derive(TS))]
5958#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
5959pub struct Array {
5960    pub expressions: Vec<Expression>,
5961}
5962
5963/// Struct expression
5964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5965#[cfg_attr(feature = "bindings", derive(TS))]
5966pub struct Struct {
5967    pub fields: Vec<(Option<String>, Expression)>,
5968}
5969
5970/// Tuple expression
5971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5972#[cfg_attr(feature = "bindings", derive(TS))]
5973pub struct Tuple {
5974    pub expressions: Vec<Expression>,
5975}
5976
5977/// Interval expression
5978#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5979#[cfg_attr(feature = "bindings", derive(TS))]
5980pub struct Interval {
5981    /// The value expression (e.g., '1', 5, column_ref)
5982    pub this: Option<Expression>,
5983    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
5984    pub unit: Option<IntervalUnitSpec>,
5985}
5986
5987/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
5988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5989#[cfg_attr(feature = "bindings", derive(TS))]
5990#[serde(tag = "type", rename_all = "snake_case")]
5991pub enum IntervalUnitSpec {
5992    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
5993    Simple {
5994        unit: IntervalUnit,
5995        /// Whether to use plural form (e.g., DAYS vs DAY)
5996        use_plural: bool,
5997    },
5998    /// Interval span (e.g., HOUR TO SECOND)
5999    Span(IntervalSpan),
6000    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6001    /// The start and end can be expressions like function calls with precision
6002    ExprSpan(IntervalSpanExpr),
6003    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6004    Expr(Box<Expression>),
6005}
6006
6007/// Interval span for ranges like HOUR TO SECOND
6008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6009#[cfg_attr(feature = "bindings", derive(TS))]
6010pub struct IntervalSpan {
6011    /// Start unit (e.g., HOUR)
6012    pub this: IntervalUnit,
6013    /// End unit (e.g., SECOND)
6014    pub expression: IntervalUnit,
6015}
6016
6017/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6018/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6019#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6020#[cfg_attr(feature = "bindings", derive(TS))]
6021pub struct IntervalSpanExpr {
6022    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6023    pub this: Box<Expression>,
6024    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6025    pub expression: Box<Expression>,
6026}
6027
6028#[derive(
6029    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6030)]
6031#[cfg_attr(feature = "bindings", derive(TS))]
6032pub enum IntervalUnit {
6033    Year,
6034    Quarter,
6035    Month,
6036    Week,
6037    Day,
6038    Hour,
6039    Minute,
6040    Second,
6041    Millisecond,
6042    Microsecond,
6043    Nanosecond,
6044}
6045
6046/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6047#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6048#[cfg_attr(feature = "bindings", derive(TS))]
6049pub struct Command {
6050    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6051    pub this: String,
6052}
6053
6054/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6055/// Syntax: PREPARE name [(type, ...)] AS statement
6056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6057#[cfg_attr(feature = "bindings", derive(TS))]
6058pub struct PrepareStatement {
6059    /// The prepared statement name.
6060    pub name: Identifier,
6061    /// Optional PostgreSQL parameter type list.
6062    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6063    pub parameter_types: Vec<DataType>,
6064    /// The statement to execute when the prepared statement is invoked.
6065    pub statement: Expression,
6066}
6067
6068/// T-SQL TRY/CATCH block.
6069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6070#[cfg_attr(feature = "bindings", derive(TS))]
6071pub struct TryCatch {
6072    /// Statements inside BEGIN TRY ... END TRY.
6073    #[serde(default)]
6074    pub try_body: Vec<Expression>,
6075    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6076    #[serde(default, skip_serializing_if = "Option::is_none")]
6077    pub catch_body: Option<Vec<Expression>>,
6078}
6079
6080/// EXEC/EXECUTE statement (TSQL stored procedure call)
6081/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6083#[cfg_attr(feature = "bindings", derive(TS))]
6084pub struct ExecuteStatement {
6085    /// The procedure name (can be qualified: schema.proc_name)
6086    pub this: Expression,
6087    /// Named parameters: @param=value pairs
6088    #[serde(default)]
6089    pub parameters: Vec<ExecuteParameter>,
6090    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6091    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6092    pub arguments: Vec<Expression>,
6093    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6094    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6095    pub prepared: bool,
6096    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6097    #[serde(default, skip_serializing_if = "Option::is_none")]
6098    pub suffix: Option<String>,
6099}
6100
6101/// Named parameter in EXEC statement: @name=value
6102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6103#[cfg_attr(feature = "bindings", derive(TS))]
6104pub struct ExecuteParameter {
6105    /// Parameter name (including @)
6106    pub name: String,
6107    /// Parameter value
6108    pub value: Expression,
6109    /// Whether this is a positional parameter (no = sign)
6110    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6111    pub positional: bool,
6112    /// TSQL OUTPUT modifier on parameter
6113    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6114    pub output: bool,
6115}
6116
6117/// KILL statement (MySQL/MariaDB)
6118/// KILL [CONNECTION | QUERY] <id>
6119#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6120#[cfg_attr(feature = "bindings", derive(TS))]
6121pub struct Kill {
6122    /// The target (process ID or connection ID)
6123    pub this: Expression,
6124    /// Optional kind: "CONNECTION" or "QUERY"
6125    pub kind: Option<String>,
6126}
6127
6128/// Snowflake CREATE TASK statement
6129#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6130#[cfg_attr(feature = "bindings", derive(TS))]
6131pub struct CreateTask {
6132    pub or_replace: bool,
6133    pub if_not_exists: bool,
6134    /// Task name (possibly qualified: db.schema.task)
6135    pub name: String,
6136    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6137    pub properties: String,
6138    /// The SQL statement body after AS
6139    pub body: Expression,
6140}
6141
6142/// Raw/unparsed SQL
6143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6144#[cfg_attr(feature = "bindings", derive(TS))]
6145pub struct Raw {
6146    pub sql: String,
6147}
6148
6149// ============================================================================
6150// Function expression types
6151// ============================================================================
6152
6153/// Generic unary function (takes a single argument)
6154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6155#[cfg_attr(feature = "bindings", derive(TS))]
6156pub struct UnaryFunc {
6157    pub this: Expression,
6158    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6159    #[serde(skip_serializing_if = "Option::is_none", default)]
6160    pub original_name: Option<String>,
6161    /// Inferred data type from type annotation
6162    #[serde(default, skip_serializing_if = "Option::is_none")]
6163    #[ast(skip)]
6164    pub inferred_type: Option<DataType>,
6165}
6166
6167impl UnaryFunc {
6168    /// Create a new UnaryFunc with no original_name
6169    pub fn new(this: Expression) -> Self {
6170        Self {
6171            this,
6172            original_name: None,
6173            inferred_type: None,
6174        }
6175    }
6176
6177    /// Create a new UnaryFunc with an original name for round-trip preservation
6178    pub fn with_name(this: Expression, name: String) -> Self {
6179        Self {
6180            this,
6181            original_name: Some(name),
6182            inferred_type: None,
6183        }
6184    }
6185}
6186
6187/// CHAR/CHR function with multiple args and optional USING charset
6188/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6189/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6191#[cfg_attr(feature = "bindings", derive(TS))]
6192pub struct CharFunc {
6193    pub args: Vec<Expression>,
6194    #[serde(skip_serializing_if = "Option::is_none", default)]
6195    pub charset: Option<String>,
6196    /// Original function name (CHAR or CHR), defaults to CHAR
6197    #[serde(skip_serializing_if = "Option::is_none", default)]
6198    pub name: Option<String>,
6199}
6200
6201/// Generic binary function (takes two arguments)
6202#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6203#[cfg_attr(feature = "bindings", derive(TS))]
6204pub struct BinaryFunc {
6205    pub this: Expression,
6206    pub expression: Expression,
6207    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6208    #[serde(skip_serializing_if = "Option::is_none", default)]
6209    pub original_name: Option<String>,
6210    /// Inferred data type from type annotation
6211    #[serde(default, skip_serializing_if = "Option::is_none")]
6212    #[ast(skip)]
6213    pub inferred_type: Option<DataType>,
6214}
6215
6216/// Variable argument function
6217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6218#[cfg_attr(feature = "bindings", derive(TS))]
6219pub struct VarArgFunc {
6220    pub expressions: Vec<Expression>,
6221    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6222    #[serde(skip_serializing_if = "Option::is_none", default)]
6223    pub original_name: Option<String>,
6224    /// Inferred data type from type annotation
6225    #[serde(default, skip_serializing_if = "Option::is_none")]
6226    #[ast(skip)]
6227    pub inferred_type: Option<DataType>,
6228}
6229
6230/// CONCAT_WS function
6231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6232#[cfg_attr(feature = "bindings", derive(TS))]
6233pub struct ConcatWs {
6234    pub separator: Expression,
6235    pub expressions: Vec<Expression>,
6236}
6237
6238/// SUBSTRING function
6239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6240#[cfg_attr(feature = "bindings", derive(TS))]
6241pub struct SubstringFunc {
6242    pub this: Expression,
6243    pub start: Expression,
6244    pub length: Option<Expression>,
6245    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6246    #[serde(default)]
6247    pub from_for_syntax: bool,
6248}
6249
6250/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6251#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6252#[cfg_attr(feature = "bindings", derive(TS))]
6253pub struct OverlayFunc {
6254    pub this: Expression,
6255    pub replacement: Expression,
6256    pub from: Expression,
6257    pub length: Option<Expression>,
6258}
6259
6260/// TRIM function
6261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6262#[cfg_attr(feature = "bindings", derive(TS))]
6263pub struct TrimFunc {
6264    pub this: Expression,
6265    pub characters: Option<Expression>,
6266    pub position: TrimPosition,
6267    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6268    #[serde(default)]
6269    pub sql_standard_syntax: bool,
6270    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6271    #[serde(default)]
6272    pub position_explicit: bool,
6273}
6274
6275#[derive(
6276    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6277)]
6278#[cfg_attr(feature = "bindings", derive(TS))]
6279pub enum TrimPosition {
6280    Both,
6281    Leading,
6282    Trailing,
6283}
6284
6285/// REPLACE function
6286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6287#[cfg_attr(feature = "bindings", derive(TS))]
6288pub struct ReplaceFunc {
6289    pub this: Expression,
6290    pub old: Expression,
6291    pub new: Expression,
6292}
6293
6294/// LEFT/RIGHT function
6295#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6296#[cfg_attr(feature = "bindings", derive(TS))]
6297pub struct LeftRightFunc {
6298    pub this: Expression,
6299    pub length: Expression,
6300}
6301
6302/// REPEAT function
6303#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6304#[cfg_attr(feature = "bindings", derive(TS))]
6305pub struct RepeatFunc {
6306    pub this: Expression,
6307    pub times: Expression,
6308}
6309
6310/// LPAD/RPAD function
6311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6312#[cfg_attr(feature = "bindings", derive(TS))]
6313pub struct PadFunc {
6314    pub this: Expression,
6315    pub length: Expression,
6316    pub fill: Option<Expression>,
6317}
6318
6319/// SPLIT function
6320#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6321#[cfg_attr(feature = "bindings", derive(TS))]
6322pub struct SplitFunc {
6323    pub this: Expression,
6324    pub delimiter: Expression,
6325}
6326
6327/// REGEXP_LIKE function
6328#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6329#[cfg_attr(feature = "bindings", derive(TS))]
6330pub struct RegexpFunc {
6331    pub this: Expression,
6332    pub pattern: Expression,
6333    pub flags: Option<Expression>,
6334}
6335
6336/// REGEXP_REPLACE function
6337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6338#[cfg_attr(feature = "bindings", derive(TS))]
6339pub struct RegexpReplaceFunc {
6340    pub this: Expression,
6341    pub pattern: Expression,
6342    pub replacement: Expression,
6343    pub flags: Option<Expression>,
6344}
6345
6346/// REGEXP_EXTRACT function
6347#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6348#[cfg_attr(feature = "bindings", derive(TS))]
6349pub struct RegexpExtractFunc {
6350    pub this: Expression,
6351    pub pattern: Expression,
6352    pub group: Option<Expression>,
6353}
6354
6355/// ROUND function
6356#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6357#[cfg_attr(feature = "bindings", derive(TS))]
6358pub struct RoundFunc {
6359    pub this: Expression,
6360    pub decimals: Option<Expression>,
6361}
6362
6363/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6364#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6365#[cfg_attr(feature = "bindings", derive(TS))]
6366pub struct FloorFunc {
6367    pub this: Expression,
6368    pub scale: Option<Expression>,
6369    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6370    #[serde(skip_serializing_if = "Option::is_none", default)]
6371    pub to: Option<Expression>,
6372}
6373
6374/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6376#[cfg_attr(feature = "bindings", derive(TS))]
6377pub struct CeilFunc {
6378    pub this: Expression,
6379    #[serde(skip_serializing_if = "Option::is_none", default)]
6380    pub decimals: Option<Expression>,
6381    /// Time unit for Druid-style CEIL(time TO unit) syntax
6382    #[serde(skip_serializing_if = "Option::is_none", default)]
6383    pub to: Option<Expression>,
6384}
6385
6386/// LOG function
6387#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6388#[cfg_attr(feature = "bindings", derive(TS))]
6389pub struct LogFunc {
6390    pub this: Expression,
6391    pub base: Option<Expression>,
6392}
6393
6394/// CURRENT_DATE (no arguments)
6395#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6396#[cfg_attr(feature = "bindings", derive(TS))]
6397pub struct CurrentDate;
6398
6399/// CURRENT_TIME
6400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6401#[cfg_attr(feature = "bindings", derive(TS))]
6402pub struct CurrentTime {
6403    pub precision: Option<u32>,
6404}
6405
6406/// CURRENT_TIMESTAMP
6407#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6408#[cfg_attr(feature = "bindings", derive(TS))]
6409pub struct CurrentTimestamp {
6410    pub precision: Option<u32>,
6411    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6412    #[serde(default)]
6413    pub sysdate: bool,
6414}
6415
6416/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6417#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6418#[cfg_attr(feature = "bindings", derive(TS))]
6419pub struct CurrentTimestampLTZ {
6420    pub precision: Option<u32>,
6421}
6422
6423/// AT TIME ZONE expression for timezone conversion
6424#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6425#[cfg_attr(feature = "bindings", derive(TS))]
6426pub struct AtTimeZone {
6427    /// The expression to convert
6428    pub this: Expression,
6429    /// The target timezone
6430    pub zone: Expression,
6431}
6432
6433/// DATE_ADD / DATE_SUB function
6434#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6435#[cfg_attr(feature = "bindings", derive(TS))]
6436pub struct DateAddFunc {
6437    pub this: Expression,
6438    pub interval: Expression,
6439    pub unit: IntervalUnit,
6440}
6441
6442/// DATEDIFF function
6443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6444#[cfg_attr(feature = "bindings", derive(TS))]
6445pub struct DateDiffFunc {
6446    pub this: Expression,
6447    pub expression: Expression,
6448    pub unit: Option<IntervalUnit>,
6449}
6450
6451/// DATE_TRUNC function
6452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6453#[cfg_attr(feature = "bindings", derive(TS))]
6454pub struct DateTruncFunc {
6455    pub this: Expression,
6456    pub unit: DateTimeField,
6457}
6458
6459/// EXTRACT function
6460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6461#[cfg_attr(feature = "bindings", derive(TS))]
6462pub struct ExtractFunc {
6463    pub this: Expression,
6464    pub field: DateTimeField,
6465}
6466
6467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6468#[cfg_attr(feature = "bindings", derive(TS))]
6469pub enum DateTimeField {
6470    Year,
6471    Month,
6472    Day,
6473    Hour,
6474    Minute,
6475    Second,
6476    Millisecond,
6477    Microsecond,
6478    DayOfWeek,
6479    DayOfYear,
6480    Week,
6481    /// Week with a modifier like WEEK(monday), WEEK(sunday)
6482    WeekWithModifier(String),
6483    Quarter,
6484    Epoch,
6485    Timezone,
6486    TimezoneHour,
6487    TimezoneMinute,
6488    Date,
6489    Time,
6490    /// Custom datetime field for dialect-specific or arbitrary fields
6491    Custom(String),
6492}
6493
6494/// TO_DATE function
6495#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6496#[cfg_attr(feature = "bindings", derive(TS))]
6497pub struct ToDateFunc {
6498    pub this: Expression,
6499    pub format: Option<Expression>,
6500}
6501
6502/// TO_TIMESTAMP function
6503#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6504#[cfg_attr(feature = "bindings", derive(TS))]
6505pub struct ToTimestampFunc {
6506    pub this: Expression,
6507    pub format: Option<Expression>,
6508}
6509
6510/// IF function
6511#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6512#[cfg_attr(feature = "bindings", derive(TS))]
6513pub struct IfFunc {
6514    pub condition: Expression,
6515    pub true_value: Expression,
6516    pub false_value: Option<Expression>,
6517    /// Original function name (IF, IFF, IIF) for round-trip preservation
6518    #[serde(skip_serializing_if = "Option::is_none", default)]
6519    pub original_name: Option<String>,
6520    /// Inferred data type from type annotation
6521    #[serde(default, skip_serializing_if = "Option::is_none")]
6522    #[ast(skip)]
6523    pub inferred_type: Option<DataType>,
6524}
6525
6526/// NVL2 function
6527#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6528#[cfg_attr(feature = "bindings", derive(TS))]
6529pub struct Nvl2Func {
6530    pub this: Expression,
6531    pub true_value: Expression,
6532    pub false_value: Expression,
6533    /// Inferred data type from type annotation
6534    #[serde(default, skip_serializing_if = "Option::is_none")]
6535    #[ast(skip)]
6536    pub inferred_type: Option<DataType>,
6537}
6538
6539// ============================================================================
6540// Typed Aggregate Function types
6541// ============================================================================
6542
6543/// Generic aggregate function base type
6544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6545#[cfg_attr(feature = "bindings", derive(TS))]
6546pub struct AggFunc {
6547    pub this: Expression,
6548    pub distinct: bool,
6549    pub filter: Option<Expression>,
6550    pub order_by: Vec<Ordered>,
6551    /// Original function name (case-preserving) when parsed from SQL
6552    #[serde(skip_serializing_if = "Option::is_none", default)]
6553    pub name: Option<String>,
6554    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
6555    #[serde(skip_serializing_if = "Option::is_none", default)]
6556    pub ignore_nulls: Option<bool>,
6557    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
6558    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
6559    #[serde(skip_serializing_if = "Option::is_none", default)]
6560    pub having_max: Option<(Box<Expression>, bool)>,
6561    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
6562    #[serde(skip_serializing_if = "Option::is_none", default)]
6563    pub limit: Option<Box<Expression>>,
6564    /// Inferred data type from type annotation
6565    #[serde(default, skip_serializing_if = "Option::is_none")]
6566    #[ast(skip)]
6567    pub inferred_type: Option<DataType>,
6568}
6569
6570/// COUNT function with optional star
6571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6572#[cfg_attr(feature = "bindings", derive(TS))]
6573pub struct CountFunc {
6574    pub this: Option<Expression>,
6575    pub star: bool,
6576    pub distinct: bool,
6577    pub filter: Option<Expression>,
6578    /// IGNORE NULLS (true) or RESPECT NULLS (false)
6579    #[serde(default, skip_serializing_if = "Option::is_none")]
6580    pub ignore_nulls: Option<bool>,
6581    /// Original function name for case preservation (e.g., "count" or "COUNT")
6582    #[serde(default, skip_serializing_if = "Option::is_none")]
6583    pub original_name: Option<String>,
6584    /// Inferred data type from type annotation
6585    #[serde(default, skip_serializing_if = "Option::is_none")]
6586    #[ast(skip)]
6587    pub inferred_type: Option<DataType>,
6588}
6589
6590/// GROUP_CONCAT function (MySQL style)
6591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6592#[cfg_attr(feature = "bindings", derive(TS))]
6593pub struct GroupConcatFunc {
6594    pub this: Expression,
6595    pub separator: Option<Expression>,
6596    pub order_by: Option<Vec<Ordered>>,
6597    pub distinct: bool,
6598    pub filter: Option<Expression>,
6599    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
6600    #[serde(default, skip_serializing_if = "Option::is_none")]
6601    pub limit: Option<Box<Expression>>,
6602    /// Inferred data type from type annotation
6603    #[serde(default, skip_serializing_if = "Option::is_none")]
6604    #[ast(skip)]
6605    pub inferred_type: Option<DataType>,
6606}
6607
6608/// STRING_AGG function (PostgreSQL/Standard SQL)
6609#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6610#[cfg_attr(feature = "bindings", derive(TS))]
6611pub struct StringAggFunc {
6612    pub this: Expression,
6613    #[serde(default)]
6614    pub separator: Option<Expression>,
6615    #[serde(default)]
6616    pub order_by: Option<Vec<Ordered>>,
6617    #[serde(default)]
6618    pub distinct: bool,
6619    #[serde(default)]
6620    pub filter: Option<Expression>,
6621    /// BigQuery LIMIT inside STRING_AGG
6622    #[serde(default, skip_serializing_if = "Option::is_none")]
6623    pub limit: Option<Box<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/// LISTAGG function (Oracle style)
6631#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6632#[cfg_attr(feature = "bindings", derive(TS))]
6633pub struct ListAggFunc {
6634    pub this: Expression,
6635    pub separator: Option<Expression>,
6636    pub on_overflow: Option<ListAggOverflow>,
6637    pub order_by: Option<Vec<Ordered>>,
6638    pub distinct: bool,
6639    pub filter: Option<Expression>,
6640    /// Inferred data type from type annotation
6641    #[serde(default, skip_serializing_if = "Option::is_none")]
6642    #[ast(skip)]
6643    pub inferred_type: Option<DataType>,
6644}
6645
6646/// LISTAGG ON OVERFLOW behavior
6647#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6648#[cfg_attr(feature = "bindings", derive(TS))]
6649pub enum ListAggOverflow {
6650    Error,
6651    Truncate {
6652        filler: Option<Expression>,
6653        with_count: bool,
6654    },
6655}
6656
6657/// SUM_IF / COUNT_IF function
6658#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6659#[cfg_attr(feature = "bindings", derive(TS))]
6660pub struct SumIfFunc {
6661    pub this: Expression,
6662    pub condition: Expression,
6663    pub filter: Option<Expression>,
6664    /// Inferred data type from type annotation
6665    #[serde(default, skip_serializing_if = "Option::is_none")]
6666    #[ast(skip)]
6667    pub inferred_type: Option<DataType>,
6668}
6669
6670/// APPROX_PERCENTILE function
6671#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6672#[cfg_attr(feature = "bindings", derive(TS))]
6673pub struct ApproxPercentileFunc {
6674    pub this: Expression,
6675    pub percentile: Expression,
6676    pub accuracy: Option<Expression>,
6677    pub filter: Option<Expression>,
6678}
6679
6680/// PERCENTILE_CONT / PERCENTILE_DISC function
6681#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6682#[cfg_attr(feature = "bindings", derive(TS))]
6683pub struct PercentileFunc {
6684    pub this: Expression,
6685    pub percentile: Expression,
6686    pub order_by: Option<Vec<Ordered>>,
6687    pub filter: Option<Expression>,
6688}
6689
6690// ============================================================================
6691// Typed Window Function types
6692// ============================================================================
6693
6694/// ROW_NUMBER function (no arguments)
6695#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6696#[cfg_attr(feature = "bindings", derive(TS))]
6697pub struct RowNumber;
6698
6699/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6700#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6701#[cfg_attr(feature = "bindings", derive(TS))]
6702pub struct Rank {
6703    /// DuckDB: RANK(ORDER BY col) - order by inside function
6704    #[serde(default, skip_serializing_if = "Option::is_none")]
6705    pub order_by: Option<Vec<Ordered>>,
6706    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6707    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6708    pub args: Vec<Expression>,
6709}
6710
6711/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
6712#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6713#[cfg_attr(feature = "bindings", derive(TS))]
6714pub struct DenseRank {
6715    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6716    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6717    pub args: Vec<Expression>,
6718}
6719
6720/// NTILE function (DuckDB allows ORDER BY inside)
6721#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6722#[cfg_attr(feature = "bindings", derive(TS))]
6723pub struct NTileFunc {
6724    /// num_buckets is optional to support Databricks NTILE() without arguments
6725    #[serde(default, skip_serializing_if = "Option::is_none")]
6726    pub num_buckets: Option<Expression>,
6727    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
6728    #[serde(default, skip_serializing_if = "Option::is_none")]
6729    pub order_by: Option<Vec<Ordered>>,
6730}
6731
6732/// LEAD / LAG function
6733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6734#[cfg_attr(feature = "bindings", derive(TS))]
6735pub struct LeadLagFunc {
6736    pub this: Expression,
6737    pub offset: Option<Expression>,
6738    pub default: Option<Expression>,
6739    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6740    #[serde(default, skip_serializing_if = "Option::is_none")]
6741    pub ignore_nulls: Option<bool>,
6742}
6743
6744/// FIRST_VALUE / LAST_VALUE function
6745#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6746#[cfg_attr(feature = "bindings", derive(TS))]
6747pub struct ValueFunc {
6748    pub this: Expression,
6749    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6750    #[serde(default, skip_serializing_if = "Option::is_none")]
6751    pub ignore_nulls: Option<bool>,
6752    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
6753    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6754    pub order_by: Vec<Ordered>,
6755}
6756
6757/// NTH_VALUE function
6758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6759#[cfg_attr(feature = "bindings", derive(TS))]
6760pub struct NthValueFunc {
6761    pub this: Expression,
6762    pub offset: Expression,
6763    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6764    #[serde(default, skip_serializing_if = "Option::is_none")]
6765    pub ignore_nulls: Option<bool>,
6766    /// Snowflake FROM FIRST / FROM LAST clause
6767    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
6768    #[serde(default, skip_serializing_if = "Option::is_none")]
6769    pub from_first: Option<bool>,
6770}
6771
6772/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6774#[cfg_attr(feature = "bindings", derive(TS))]
6775pub struct PercentRank {
6776    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
6777    #[serde(default, skip_serializing_if = "Option::is_none")]
6778    pub order_by: Option<Vec<Ordered>>,
6779    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6780    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6781    pub args: Vec<Expression>,
6782}
6783
6784/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6786#[cfg_attr(feature = "bindings", derive(TS))]
6787pub struct CumeDist {
6788    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
6789    #[serde(default, skip_serializing_if = "Option::is_none")]
6790    pub order_by: Option<Vec<Ordered>>,
6791    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6792    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6793    pub args: Vec<Expression>,
6794}
6795
6796// ============================================================================
6797// Additional String Function types
6798// ============================================================================
6799
6800/// POSITION/INSTR function
6801#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6802#[cfg_attr(feature = "bindings", derive(TS))]
6803pub struct PositionFunc {
6804    pub substring: Expression,
6805    pub string: Expression,
6806    pub start: Option<Expression>,
6807}
6808
6809// ============================================================================
6810// Additional Math Function types
6811// ============================================================================
6812
6813/// RANDOM function (no arguments)
6814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6815#[cfg_attr(feature = "bindings", derive(TS))]
6816pub struct Random;
6817
6818/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
6819#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6820#[cfg_attr(feature = "bindings", derive(TS))]
6821pub struct Rand {
6822    pub seed: Option<Box<Expression>>,
6823    /// Teradata RANDOM lower bound
6824    #[serde(default)]
6825    pub lower: Option<Box<Expression>>,
6826    /// Teradata RANDOM upper bound
6827    #[serde(default)]
6828    pub upper: Option<Box<Expression>>,
6829}
6830
6831/// TRUNCATE / TRUNC function
6832#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6833#[cfg_attr(feature = "bindings", derive(TS))]
6834pub struct TruncateFunc {
6835    pub this: Expression,
6836    pub decimals: Option<Expression>,
6837}
6838
6839/// PI function (no arguments)
6840#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6841#[cfg_attr(feature = "bindings", derive(TS))]
6842pub struct Pi;
6843
6844// ============================================================================
6845// Control Flow Function types
6846// ============================================================================
6847
6848/// DECODE function (Oracle style)
6849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6850#[cfg_attr(feature = "bindings", derive(TS))]
6851pub struct DecodeFunc {
6852    pub this: Expression,
6853    pub search_results: Vec<(Expression, Expression)>,
6854    pub default: Option<Expression>,
6855}
6856
6857// ============================================================================
6858// Additional Date/Time Function types
6859// ============================================================================
6860
6861/// DATE_FORMAT / FORMAT_DATE function
6862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6863#[cfg_attr(feature = "bindings", derive(TS))]
6864pub struct DateFormatFunc {
6865    pub this: Expression,
6866    pub format: Expression,
6867}
6868
6869/// FROM_UNIXTIME function
6870#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6871#[cfg_attr(feature = "bindings", derive(TS))]
6872pub struct FromUnixtimeFunc {
6873    pub this: Expression,
6874    pub format: Option<Expression>,
6875}
6876
6877/// UNIX_TIMESTAMP function
6878#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6879#[cfg_attr(feature = "bindings", derive(TS))]
6880pub struct UnixTimestampFunc {
6881    pub this: Option<Expression>,
6882    pub format: Option<Expression>,
6883}
6884
6885/// MAKE_DATE function
6886#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6887#[cfg_attr(feature = "bindings", derive(TS))]
6888pub struct MakeDateFunc {
6889    pub year: Expression,
6890    pub month: Expression,
6891    pub day: Expression,
6892}
6893
6894/// MAKE_TIMESTAMP function
6895#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6896#[cfg_attr(feature = "bindings", derive(TS))]
6897pub struct MakeTimestampFunc {
6898    pub year: Expression,
6899    pub month: Expression,
6900    pub day: Expression,
6901    pub hour: Expression,
6902    pub minute: Expression,
6903    pub second: Expression,
6904    pub timezone: Option<Expression>,
6905}
6906
6907/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
6908#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6909#[cfg_attr(feature = "bindings", derive(TS))]
6910pub struct LastDayFunc {
6911    pub this: Expression,
6912    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
6913    #[serde(skip_serializing_if = "Option::is_none", default)]
6914    pub unit: Option<DateTimeField>,
6915}
6916
6917// ============================================================================
6918// Array Function types
6919// ============================================================================
6920
6921/// ARRAY constructor
6922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6923#[cfg_attr(feature = "bindings", derive(TS))]
6924pub struct ArrayConstructor {
6925    pub expressions: Vec<Expression>,
6926    pub bracket_notation: bool,
6927    /// True if LIST keyword was used instead of ARRAY (DuckDB)
6928    pub use_list_keyword: bool,
6929}
6930
6931/// ARRAY_SORT function
6932#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6933#[cfg_attr(feature = "bindings", derive(TS))]
6934pub struct ArraySortFunc {
6935    pub this: Expression,
6936    pub comparator: Option<Expression>,
6937    pub desc: bool,
6938    pub nulls_first: Option<bool>,
6939}
6940
6941/// ARRAY_JOIN / ARRAY_TO_STRING function
6942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6943#[cfg_attr(feature = "bindings", derive(TS))]
6944pub struct ArrayJoinFunc {
6945    pub this: Expression,
6946    pub separator: Expression,
6947    pub null_replacement: Option<Expression>,
6948}
6949
6950/// UNNEST function
6951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6952#[cfg_attr(feature = "bindings", derive(TS))]
6953pub struct UnnestFunc {
6954    pub this: Expression,
6955    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
6956    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6957    pub expressions: Vec<Expression>,
6958    pub with_ordinality: bool,
6959    pub alias: Option<Identifier>,
6960    /// BigQuery: offset alias for WITH OFFSET AS <name>
6961    #[serde(default, skip_serializing_if = "Option::is_none")]
6962    pub offset_alias: Option<Identifier>,
6963}
6964
6965/// ARRAY_FILTER function (with lambda)
6966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6967#[cfg_attr(feature = "bindings", derive(TS))]
6968pub struct ArrayFilterFunc {
6969    pub this: Expression,
6970    pub filter: Expression,
6971}
6972
6973/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
6974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6975#[cfg_attr(feature = "bindings", derive(TS))]
6976pub struct ArrayTransformFunc {
6977    pub this: Expression,
6978    pub transform: Expression,
6979}
6980
6981/// SEQUENCE / GENERATE_SERIES function
6982#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6983#[cfg_attr(feature = "bindings", derive(TS))]
6984pub struct SequenceFunc {
6985    pub start: Expression,
6986    pub stop: Expression,
6987    pub step: Option<Expression>,
6988}
6989
6990// ============================================================================
6991// Struct Function types
6992// ============================================================================
6993
6994/// STRUCT constructor
6995#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6996#[cfg_attr(feature = "bindings", derive(TS))]
6997pub struct StructConstructor {
6998    pub fields: Vec<(Option<Identifier>, Expression)>,
6999}
7000
7001/// STRUCT_EXTRACT function
7002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7003#[cfg_attr(feature = "bindings", derive(TS))]
7004pub struct StructExtractFunc {
7005    pub this: Expression,
7006    pub field: Identifier,
7007}
7008
7009/// NAMED_STRUCT function
7010#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7011#[cfg_attr(feature = "bindings", derive(TS))]
7012pub struct NamedStructFunc {
7013    pub pairs: Vec<(Expression, Expression)>,
7014}
7015
7016// ============================================================================
7017// Map Function types
7018// ============================================================================
7019
7020/// MAP constructor
7021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7022#[cfg_attr(feature = "bindings", derive(TS))]
7023pub struct MapConstructor {
7024    pub keys: Vec<Expression>,
7025    pub values: Vec<Expression>,
7026    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7027    #[serde(default)]
7028    pub curly_brace_syntax: bool,
7029    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7030    #[serde(default)]
7031    pub with_map_keyword: bool,
7032}
7033
7034/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7035#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7036#[cfg_attr(feature = "bindings", derive(TS))]
7037pub struct TransformFunc {
7038    pub this: Expression,
7039    pub transform: Expression,
7040}
7041
7042/// Function call with EMITS clause (Exasol)
7043/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7045#[cfg_attr(feature = "bindings", derive(TS))]
7046pub struct FunctionEmits {
7047    /// The function call expression
7048    pub this: Expression,
7049    /// The EMITS schema definition
7050    pub emits: Expression,
7051}
7052
7053// ============================================================================
7054// JSON Function types
7055// ============================================================================
7056
7057/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7059#[cfg_attr(feature = "bindings", derive(TS))]
7060pub struct JsonExtractFunc {
7061    pub this: Expression,
7062    pub path: Expression,
7063    pub returning: Option<DataType>,
7064    /// True if parsed from -> or ->> operator syntax
7065    #[serde(default)]
7066    pub arrow_syntax: bool,
7067    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7068    #[serde(default)]
7069    pub hash_arrow_syntax: bool,
7070    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7071    #[serde(default)]
7072    pub wrapper_option: Option<String>,
7073    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7074    #[serde(default)]
7075    pub quotes_option: Option<String>,
7076    /// ON SCALAR STRING flag
7077    #[serde(default)]
7078    pub on_scalar_string: bool,
7079    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7080    #[serde(default)]
7081    pub on_error: Option<String>,
7082}
7083
7084/// JSON path extraction
7085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7086#[cfg_attr(feature = "bindings", derive(TS))]
7087pub struct JsonPathFunc {
7088    pub this: Expression,
7089    pub paths: Vec<Expression>,
7090}
7091
7092/// JSON_OBJECT function
7093#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7094#[cfg_attr(feature = "bindings", derive(TS))]
7095pub struct JsonObjectFunc {
7096    pub pairs: Vec<(Expression, Expression)>,
7097    pub null_handling: Option<JsonNullHandling>,
7098    #[serde(default)]
7099    pub with_unique_keys: bool,
7100    #[serde(default)]
7101    pub returning_type: Option<DataType>,
7102    #[serde(default)]
7103    pub format_json: bool,
7104    #[serde(default)]
7105    pub encoding: Option<String>,
7106    /// For JSON_OBJECT(*) syntax
7107    #[serde(default)]
7108    pub star: bool,
7109}
7110
7111/// JSON null handling options
7112#[derive(
7113    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7114)]
7115#[cfg_attr(feature = "bindings", derive(TS))]
7116pub enum JsonNullHandling {
7117    NullOnNull,
7118    AbsentOnNull,
7119}
7120
7121/// JSON_SET / JSON_INSERT function
7122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7123#[cfg_attr(feature = "bindings", derive(TS))]
7124pub struct JsonModifyFunc {
7125    pub this: Expression,
7126    pub path_values: Vec<(Expression, Expression)>,
7127}
7128
7129/// JSON_ARRAYAGG function
7130#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7131#[cfg_attr(feature = "bindings", derive(TS))]
7132pub struct JsonArrayAggFunc {
7133    pub this: Expression,
7134    pub order_by: Option<Vec<Ordered>>,
7135    pub null_handling: Option<JsonNullHandling>,
7136    pub filter: Option<Expression>,
7137}
7138
7139/// JSON_OBJECTAGG function
7140#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7141#[cfg_attr(feature = "bindings", derive(TS))]
7142pub struct JsonObjectAggFunc {
7143    pub key: Expression,
7144    pub value: Expression,
7145    pub null_handling: Option<JsonNullHandling>,
7146    pub filter: Option<Expression>,
7147}
7148
7149// ============================================================================
7150// Type Casting Function types
7151// ============================================================================
7152
7153/// CONVERT function (SQL Server style)
7154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7155#[cfg_attr(feature = "bindings", derive(TS))]
7156pub struct ConvertFunc {
7157    pub this: Expression,
7158    pub to: DataType,
7159    pub style: Option<Expression>,
7160}
7161
7162// ============================================================================
7163// Additional Expression types
7164// ============================================================================
7165
7166/// Lambda expression
7167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7168#[cfg_attr(feature = "bindings", derive(TS))]
7169pub struct LambdaExpr {
7170    pub parameters: Vec<Identifier>,
7171    pub body: Expression,
7172    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7173    #[serde(default)]
7174    pub colon: bool,
7175    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7176    /// Maps parameter index to data type
7177    #[serde(default)]
7178    pub parameter_types: Vec<Option<DataType>>,
7179}
7180
7181/// Parameter (parameterized queries)
7182#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7183#[cfg_attr(feature = "bindings", derive(TS))]
7184pub struct Parameter {
7185    pub name: Option<String>,
7186    pub index: Option<u32>,
7187    pub style: ParameterStyle,
7188    /// Whether the name was quoted (e.g., @"x" vs @x)
7189    #[serde(default)]
7190    pub quoted: bool,
7191    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7192    #[serde(default)]
7193    pub string_quoted: bool,
7194    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7195    #[serde(default)]
7196    pub expression: Option<String>,
7197}
7198
7199/// Parameter placeholder styles
7200#[derive(
7201    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7202)]
7203#[cfg_attr(feature = "bindings", derive(TS))]
7204pub enum ParameterStyle {
7205    Question,     // ?
7206    Dollar,       // $1, $2
7207    DollarBrace,  // ${name} (Databricks, Hive template variables)
7208    Brace,        // {name} (Spark/Databricks widget/template variables)
7209    Colon,        // :name
7210    At,           // @name
7211    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7212    DoubleDollar, // $$name
7213    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7214}
7215
7216/// Placeholder expression
7217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7218#[cfg_attr(feature = "bindings", derive(TS))]
7219pub struct Placeholder {
7220    pub index: Option<u32>,
7221}
7222
7223/// Named argument in function call: name => value or name := value
7224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7225#[cfg_attr(feature = "bindings", derive(TS))]
7226pub struct NamedArgument {
7227    pub name: Identifier,
7228    pub value: Expression,
7229    /// The separator used: `=>`, `:=`, or `=`
7230    pub separator: NamedArgSeparator,
7231}
7232
7233/// Separator style for named arguments
7234#[derive(
7235    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7236)]
7237#[cfg_attr(feature = "bindings", derive(TS))]
7238pub enum NamedArgSeparator {
7239    /// `=>` (standard SQL, Snowflake, BigQuery)
7240    DArrow,
7241    /// `:=` (Oracle, MySQL)
7242    ColonEq,
7243    /// `=` (simple equals, some dialects)
7244    Eq,
7245}
7246
7247/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7248/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7249#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7250#[cfg_attr(feature = "bindings", derive(TS))]
7251pub struct TableArgument {
7252    /// The keyword prefix: "TABLE" or "MODEL"
7253    pub prefix: String,
7254    /// The table/model reference expression
7255    pub this: Expression,
7256}
7257
7258/// SQL Comment preservation
7259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7260#[cfg_attr(feature = "bindings", derive(TS))]
7261pub struct SqlComment {
7262    pub text: String,
7263    pub is_block: bool,
7264}
7265
7266// ============================================================================
7267// Additional Predicate types
7268// ============================================================================
7269
7270/// SIMILAR TO expression
7271#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7272#[cfg_attr(feature = "bindings", derive(TS))]
7273pub struct SimilarToExpr {
7274    pub this: Expression,
7275    pub pattern: Expression,
7276    pub escape: Option<Expression>,
7277    pub not: bool,
7278}
7279
7280/// ANY / ALL quantified expression
7281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7282#[cfg_attr(feature = "bindings", derive(TS))]
7283pub struct QuantifiedExpr {
7284    pub this: Expression,
7285    pub subquery: Expression,
7286    pub op: Option<QuantifiedOp>,
7287}
7288
7289/// Comparison operator for quantified expressions
7290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7291#[cfg_attr(feature = "bindings", derive(TS))]
7292pub enum QuantifiedOp {
7293    Eq,
7294    Neq,
7295    Lt,
7296    Lte,
7297    Gt,
7298    Gte,
7299}
7300
7301/// OVERLAPS expression
7302/// Supports two forms:
7303/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7304/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7306#[cfg_attr(feature = "bindings", derive(TS))]
7307pub struct OverlapsExpr {
7308    /// Left operand for simple binary form
7309    #[serde(skip_serializing_if = "Option::is_none")]
7310    pub this: Option<Expression>,
7311    /// Right operand for simple binary form
7312    #[serde(skip_serializing_if = "Option::is_none")]
7313    pub expression: Option<Expression>,
7314    /// Left range start for full ANSI form
7315    #[serde(skip_serializing_if = "Option::is_none")]
7316    pub left_start: Option<Expression>,
7317    /// Left range end for full ANSI form
7318    #[serde(skip_serializing_if = "Option::is_none")]
7319    pub left_end: Option<Expression>,
7320    /// Right range start for full ANSI form
7321    #[serde(skip_serializing_if = "Option::is_none")]
7322    pub right_start: Option<Expression>,
7323    /// Right range end for full ANSI form
7324    #[serde(skip_serializing_if = "Option::is_none")]
7325    pub right_end: Option<Expression>,
7326}
7327
7328// ============================================================================
7329// Array/Struct/Map access
7330// ============================================================================
7331
7332/// Subscript access (array[index] or map[key])
7333#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7334#[cfg_attr(feature = "bindings", derive(TS))]
7335pub struct Subscript {
7336    pub this: Expression,
7337    pub index: Expression,
7338}
7339
7340/// Dot access (struct.field)
7341#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7342#[cfg_attr(feature = "bindings", derive(TS))]
7343pub struct DotAccess {
7344    pub this: Expression,
7345    pub field: Identifier,
7346}
7347
7348/// Method call (expr.method(args))
7349#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7350#[cfg_attr(feature = "bindings", derive(TS))]
7351pub struct MethodCall {
7352    pub this: Expression,
7353    pub method: Identifier,
7354    pub args: Vec<Expression>,
7355}
7356
7357/// Array slice (array[start:end])
7358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7359#[cfg_attr(feature = "bindings", derive(TS))]
7360pub struct ArraySlice {
7361    pub this: Expression,
7362    pub start: Option<Expression>,
7363    pub end: Option<Expression>,
7364}
7365
7366// ============================================================================
7367// DDL (Data Definition Language) Statements
7368// ============================================================================
7369
7370/// ON COMMIT behavior for temporary tables
7371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7372#[cfg_attr(feature = "bindings", derive(TS))]
7373pub enum OnCommit {
7374    /// ON COMMIT PRESERVE ROWS
7375    PreserveRows,
7376    /// ON COMMIT DELETE ROWS
7377    DeleteRows,
7378}
7379
7380/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
7381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7382#[cfg_attr(feature = "bindings", derive(TS))]
7383pub struct TiDBAutoRandom {
7384    #[serde(default, skip_serializing_if = "Option::is_none")]
7385    pub shard_bits: Option<u64>,
7386    #[serde(default, skip_serializing_if = "Option::is_none")]
7387    pub range_bits: Option<u64>,
7388    /// Whether the attribute was wrapped in a TiDB executable comment.
7389    #[serde(default)]
7390    pub executable_comment: bool,
7391}
7392
7393/// A TiDB-specific table option and its source syntax.
7394#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7395#[cfg_attr(feature = "bindings", derive(TS))]
7396pub struct TiDBTableOption {
7397    pub kind: TiDBTableOptionKind,
7398    /// Whether the option was wrapped in a TiDB executable comment.
7399    #[serde(default)]
7400    pub executable_comment: bool,
7401}
7402
7403/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
7404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7405#[cfg_attr(feature = "bindings", derive(TS))]
7406#[serde(tag = "type", rename_all = "snake_case")]
7407pub enum TiDBTableOptionKind {
7408    ShardRowIdBits {
7409        bits: u64,
7410    },
7411    PreSplitRegions {
7412        regions: u64,
7413    },
7414    AutoRandomBase {
7415        value: u64,
7416    },
7417    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
7418    PlacementPolicy {
7419        policy: Option<Identifier>,
7420    },
7421    Ttl {
7422        column: Identifier,
7423        interval: Interval,
7424        #[serde(default, skip_serializing_if = "Option::is_none")]
7425        enabled: Option<bool>,
7426    },
7427    TtlEnable {
7428        enabled: bool,
7429    },
7430    TtlJobInterval {
7431        interval: String,
7432    },
7433}
7434
7435/// CREATE TABLE statement
7436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7437#[cfg_attr(feature = "bindings", derive(TS))]
7438pub struct CreateTable {
7439    pub name: TableRef,
7440    /// ClickHouse: ON CLUSTER clause for distributed DDL
7441    #[serde(default, skip_serializing_if = "Option::is_none")]
7442    pub on_cluster: Option<OnCluster>,
7443    pub columns: Vec<ColumnDef>,
7444    pub constraints: Vec<TableConstraint>,
7445    pub if_not_exists: bool,
7446    pub temporary: bool,
7447    pub or_replace: bool,
7448    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
7449    #[serde(default, skip_serializing_if = "Option::is_none")]
7450    pub table_modifier: Option<String>,
7451    pub as_select: Option<Expression>,
7452    /// Whether the AS SELECT was wrapped in parentheses
7453    #[serde(default)]
7454    pub as_select_parenthesized: bool,
7455    /// ON COMMIT behavior for temporary tables
7456    #[serde(default)]
7457    pub on_commit: Option<OnCommit>,
7458    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
7459    #[serde(default)]
7460    pub clone_source: Option<TableRef>,
7461    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
7462    #[serde(default, skip_serializing_if = "Option::is_none")]
7463    pub clone_at_clause: Option<Expression>,
7464    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
7465    #[serde(default)]
7466    pub is_copy: bool,
7467    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
7468    #[serde(default)]
7469    pub shallow_clone: bool,
7470    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
7471    #[serde(default)]
7472    pub deep_clone: bool,
7473    /// Leading comments before the statement
7474    #[serde(default)]
7475    pub leading_comments: Vec<String>,
7476    /// WITH properties (e.g., WITH (FORMAT='parquet'))
7477    #[serde(default)]
7478    pub with_properties: Vec<(String, String)>,
7479    /// Teradata: table options after name before columns (comma-separated)
7480    #[serde(default)]
7481    pub teradata_post_name_options: Vec<String>,
7482    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
7483    #[serde(default)]
7484    pub with_data: Option<bool>,
7485    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
7486    #[serde(default)]
7487    pub with_statistics: Option<bool>,
7488    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
7489    #[serde(default)]
7490    pub teradata_indexes: Vec<TeradataIndex>,
7491    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
7492    #[serde(default)]
7493    pub with_cte: Option<With>,
7494    /// Table properties like DEFAULT COLLATE (BigQuery)
7495    #[serde(default)]
7496    pub properties: Vec<Expression>,
7497    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
7498    #[serde(default, skip_serializing_if = "Option::is_none")]
7499    pub partition_of: Option<Expression>,
7500    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
7501    #[serde(default)]
7502    pub post_table_properties: Vec<Expression>,
7503    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
7504    #[serde(default)]
7505    pub mysql_table_options: Vec<(String, String)>,
7506    /// TiDB-specific table options after column definitions.
7507    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7508    pub tidb_table_options: Vec<TiDBTableOption>,
7509    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
7510    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7511    pub inherits: Vec<TableRef>,
7512    /// TSQL ON filegroup or ON filegroup (partition_column) clause
7513    #[serde(default, skip_serializing_if = "Option::is_none")]
7514    pub on_property: Option<OnProperty>,
7515    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
7516    #[serde(default)]
7517    pub copy_grants: bool,
7518    /// Snowflake: USING TEMPLATE expression for schema inference
7519    #[serde(default, skip_serializing_if = "Option::is_none")]
7520    pub using_template: Option<Box<Expression>>,
7521    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
7522    #[serde(default, skip_serializing_if = "Option::is_none")]
7523    pub rollup: Option<RollupProperty>,
7524    /// ClickHouse: UUID 'xxx' clause after table name
7525    #[serde(default, skip_serializing_if = "Option::is_none")]
7526    pub uuid: Option<String>,
7527    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
7528    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
7529    /// could appear in other engines.
7530    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7531    pub with_partition_columns: Vec<ColumnDef>,
7532    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
7533    /// for external tables that reference a Cloud Resource connection.
7534    #[serde(default, skip_serializing_if = "Option::is_none")]
7535    pub with_connection: Option<TableRef>,
7536}
7537
7538/// Teradata index specification for CREATE TABLE
7539#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7540#[cfg_attr(feature = "bindings", derive(TS))]
7541pub struct TeradataIndex {
7542    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
7543    pub kind: TeradataIndexKind,
7544    /// Optional index name
7545    pub name: Option<String>,
7546    /// Optional column list
7547    pub columns: Vec<String>,
7548}
7549
7550/// Kind of Teradata index
7551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7552#[cfg_attr(feature = "bindings", derive(TS))]
7553pub enum TeradataIndexKind {
7554    /// NO PRIMARY INDEX
7555    NoPrimary,
7556    /// PRIMARY INDEX
7557    Primary,
7558    /// PRIMARY AMP INDEX
7559    PrimaryAmp,
7560    /// UNIQUE INDEX
7561    Unique,
7562    /// UNIQUE PRIMARY INDEX
7563    UniquePrimary,
7564    /// INDEX (secondary, non-primary)
7565    Secondary,
7566}
7567
7568impl CreateTable {
7569    pub fn new(name: impl Into<String>) -> Self {
7570        Self {
7571            name: TableRef::new(name),
7572            on_cluster: None,
7573            columns: Vec::new(),
7574            constraints: Vec::new(),
7575            if_not_exists: false,
7576            temporary: false,
7577            or_replace: false,
7578            table_modifier: None,
7579            as_select: None,
7580            as_select_parenthesized: false,
7581            on_commit: None,
7582            clone_source: None,
7583            clone_at_clause: None,
7584            shallow_clone: false,
7585            deep_clone: false,
7586            is_copy: false,
7587            leading_comments: Vec::new(),
7588            with_properties: Vec::new(),
7589            teradata_post_name_options: Vec::new(),
7590            with_data: None,
7591            with_statistics: None,
7592            teradata_indexes: Vec::new(),
7593            with_cte: None,
7594            properties: Vec::new(),
7595            partition_of: None,
7596            post_table_properties: Vec::new(),
7597            mysql_table_options: Vec::new(),
7598            tidb_table_options: Vec::new(),
7599            inherits: Vec::new(),
7600            on_property: None,
7601            copy_grants: false,
7602            using_template: None,
7603            rollup: None,
7604            uuid: None,
7605            with_partition_columns: Vec::new(),
7606            with_connection: None,
7607        }
7608    }
7609}
7610
7611/// Sort order for PRIMARY KEY ASC/DESC
7612#[derive(
7613    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
7614)]
7615#[cfg_attr(feature = "bindings", derive(TS))]
7616pub enum SortOrder {
7617    Asc,
7618    Desc,
7619}
7620
7621/// Type of column constraint for tracking order
7622#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7623#[cfg_attr(feature = "bindings", derive(TS))]
7624pub enum ConstraintType {
7625    NotNull,
7626    Null,
7627    PrimaryKey,
7628    Unique,
7629    Default,
7630    AutoIncrement,
7631    AutoRandom,
7632    Collate,
7633    Comment,
7634    References,
7635    Check,
7636    GeneratedAsIdentity,
7637    /// Snowflake: TAG (key='value', ...)
7638    Tags,
7639    /// Computed/generated column
7640    ComputedColumn,
7641    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
7642    GeneratedAsRow,
7643    /// MySQL: ON UPDATE expression
7644    OnUpdate,
7645    /// PATH constraint for XMLTABLE/JSON_TABLE columns
7646    Path,
7647    /// Redshift: ENCODE encoding_type
7648    Encode,
7649}
7650
7651/// Column definition in CREATE TABLE
7652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7653#[cfg_attr(feature = "bindings", derive(TS))]
7654pub struct ColumnDef {
7655    pub name: Identifier,
7656    pub data_type: DataType,
7657    pub nullable: Option<bool>,
7658    pub default: Option<Expression>,
7659    pub primary_key: bool,
7660    /// Sort order for PRIMARY KEY (ASC/DESC)
7661    #[serde(default)]
7662    pub primary_key_order: Option<SortOrder>,
7663    pub unique: bool,
7664    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
7665    #[serde(default)]
7666    pub unique_nulls_not_distinct: bool,
7667    pub auto_increment: bool,
7668    /// TiDB distributed primary-key allocation attribute.
7669    #[serde(default, skip_serializing_if = "Option::is_none")]
7670    pub auto_random: Option<TiDBAutoRandom>,
7671    pub comment: Option<String>,
7672    pub constraints: Vec<ColumnConstraint>,
7673    /// Track original order of constraints for accurate regeneration
7674    #[serde(default)]
7675    pub constraint_order: Vec<ConstraintType>,
7676    /// Teradata: FORMAT 'pattern'
7677    #[serde(default)]
7678    pub format: Option<String>,
7679    /// Teradata: TITLE 'title'
7680    #[serde(default)]
7681    pub title: Option<String>,
7682    /// Teradata: INLINE LENGTH n
7683    #[serde(default)]
7684    pub inline_length: Option<u64>,
7685    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
7686    #[serde(default)]
7687    pub compress: Option<Vec<Expression>>,
7688    /// Teradata: CHARACTER SET name
7689    #[serde(default)]
7690    pub character_set: Option<String>,
7691    /// Teradata: UPPERCASE
7692    #[serde(default)]
7693    pub uppercase: bool,
7694    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
7695    #[serde(default)]
7696    pub casespecific: Option<bool>,
7697    /// Snowflake: AUTOINCREMENT START value
7698    #[serde(default)]
7699    pub auto_increment_start: Option<Box<Expression>>,
7700    /// Snowflake: AUTOINCREMENT INCREMENT value
7701    #[serde(default)]
7702    pub auto_increment_increment: Option<Box<Expression>>,
7703    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
7704    #[serde(default)]
7705    pub auto_increment_order: Option<bool>,
7706    /// MySQL: UNSIGNED modifier
7707    #[serde(default)]
7708    pub unsigned: bool,
7709    /// MySQL: ZEROFILL modifier
7710    #[serde(default)]
7711    pub zerofill: bool,
7712    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
7713    #[serde(default, skip_serializing_if = "Option::is_none")]
7714    pub on_update: Option<Expression>,
7715    /// MySQL: column VISIBLE/INVISIBLE modifier.
7716    #[serde(default, skip_serializing_if = "Option::is_none")]
7717    pub visible: Option<bool>,
7718    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
7719    #[serde(default, skip_serializing_if = "Option::is_none")]
7720    pub unique_constraint_name: Option<String>,
7721    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
7722    #[serde(default, skip_serializing_if = "Option::is_none")]
7723    pub not_null_constraint_name: Option<String>,
7724    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
7725    #[serde(default, skip_serializing_if = "Option::is_none")]
7726    pub primary_key_constraint_name: Option<String>,
7727    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
7728    #[serde(default, skip_serializing_if = "Option::is_none")]
7729    pub check_constraint_name: Option<String>,
7730    /// BigQuery: OPTIONS (key=value, ...) on column
7731    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7732    pub options: Vec<Expression>,
7733    /// SQLite: Column definition without explicit type
7734    #[serde(default)]
7735    pub no_type: bool,
7736    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
7737    #[serde(default, skip_serializing_if = "Option::is_none")]
7738    pub encoding: Option<String>,
7739    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
7740    #[serde(default, skip_serializing_if = "Option::is_none")]
7741    pub codec: Option<String>,
7742    /// ClickHouse: EPHEMERAL [expr] modifier
7743    #[serde(default, skip_serializing_if = "Option::is_none")]
7744    pub ephemeral: Option<Option<Box<Expression>>>,
7745    /// ClickHouse: MATERIALIZED expr modifier
7746    #[serde(default, skip_serializing_if = "Option::is_none")]
7747    pub materialized_expr: Option<Box<Expression>>,
7748    /// ClickHouse: ALIAS expr modifier
7749    #[serde(default, skip_serializing_if = "Option::is_none")]
7750    pub alias_expr: Option<Box<Expression>>,
7751    /// ClickHouse: TTL expr modifier on columns
7752    #[serde(default, skip_serializing_if = "Option::is_none")]
7753    pub ttl_expr: Option<Box<Expression>>,
7754    /// TSQL: NOT FOR REPLICATION
7755    #[serde(default)]
7756    pub not_for_replication: bool,
7757}
7758
7759impl ColumnDef {
7760    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
7761        Self {
7762            name: Identifier::new(name),
7763            data_type,
7764            nullable: None,
7765            default: None,
7766            primary_key: false,
7767            primary_key_order: None,
7768            unique: false,
7769            unique_nulls_not_distinct: false,
7770            auto_increment: false,
7771            auto_random: None,
7772            comment: None,
7773            constraints: Vec::new(),
7774            constraint_order: Vec::new(),
7775            format: None,
7776            title: None,
7777            inline_length: None,
7778            compress: None,
7779            character_set: None,
7780            uppercase: false,
7781            casespecific: None,
7782            auto_increment_start: None,
7783            auto_increment_increment: None,
7784            auto_increment_order: None,
7785            unsigned: false,
7786            zerofill: false,
7787            on_update: None,
7788            visible: None,
7789            unique_constraint_name: None,
7790            not_null_constraint_name: None,
7791            primary_key_constraint_name: None,
7792            check_constraint_name: None,
7793            options: Vec::new(),
7794            no_type: false,
7795            encoding: None,
7796            codec: None,
7797            ephemeral: None,
7798            materialized_expr: None,
7799            alias_expr: None,
7800            ttl_expr: None,
7801            not_for_replication: false,
7802        }
7803    }
7804}
7805
7806/// Column-level constraint
7807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7808#[cfg_attr(feature = "bindings", derive(TS))]
7809pub enum ColumnConstraint {
7810    NotNull,
7811    Null,
7812    Unique,
7813    PrimaryKey,
7814    Default(Expression),
7815    Check(Expression),
7816    References(ForeignKeyRef),
7817    GeneratedAsIdentity(GeneratedAsIdentity),
7818    Collate(Identifier),
7819    Comment(String),
7820    /// Snowflake: TAG (key='value', ...)
7821    Tags(Tags),
7822    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
7823    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
7824    ComputedColumn(ComputedColumn),
7825    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7826    GeneratedAsRow(GeneratedAsRow),
7827    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
7828    Path(Expression),
7829}
7830
7831/// Computed/generated column constraint
7832#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7833#[cfg_attr(feature = "bindings", derive(TS))]
7834pub struct ComputedColumn {
7835    /// The expression that computes the column value
7836    pub expression: Box<Expression>,
7837    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
7838    #[serde(default)]
7839    pub persisted: bool,
7840    /// NOT NULL (TSQL computed columns)
7841    #[serde(default)]
7842    pub not_null: bool,
7843    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
7844    /// When None, defaults to dialect-appropriate output
7845    #[serde(default)]
7846    pub persistence_kind: Option<String>,
7847    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
7848    #[serde(default, skip_serializing_if = "Option::is_none")]
7849    pub data_type: Option<DataType>,
7850}
7851
7852/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
7853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7854#[cfg_attr(feature = "bindings", derive(TS))]
7855pub struct GeneratedAsRow {
7856    /// true = ROW START, false = ROW END
7857    pub start: bool,
7858    /// HIDDEN modifier
7859    #[serde(default)]
7860    pub hidden: bool,
7861}
7862
7863/// Generated identity column constraint
7864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7865#[cfg_attr(feature = "bindings", derive(TS))]
7866pub struct GeneratedAsIdentity {
7867    /// True for ALWAYS, False for BY DEFAULT
7868    pub always: bool,
7869    /// ON NULL (only valid with BY DEFAULT)
7870    pub on_null: bool,
7871    /// START WITH value
7872    pub start: Option<Box<Expression>>,
7873    /// INCREMENT BY value
7874    pub increment: Option<Box<Expression>>,
7875    /// MINVALUE
7876    pub minvalue: Option<Box<Expression>>,
7877    /// MAXVALUE
7878    pub maxvalue: Option<Box<Expression>>,
7879    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
7880    pub cycle: Option<bool>,
7881}
7882
7883/// Constraint modifiers (shared between table-level constraints)
7884#[derive(
7885    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
7886)]
7887#[cfg_attr(feature = "bindings", derive(TS))]
7888pub struct ConstraintModifiers {
7889    /// ENFORCED / NOT ENFORCED
7890    pub enforced: Option<bool>,
7891    /// DEFERRABLE / NOT DEFERRABLE
7892    pub deferrable: Option<bool>,
7893    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
7894    pub initially_deferred: Option<bool>,
7895    /// NORELY (Oracle)
7896    pub norely: bool,
7897    /// RELY (Oracle)
7898    pub rely: bool,
7899    /// USING index type (MySQL): BTREE or HASH
7900    #[serde(default)]
7901    pub using: Option<String>,
7902    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
7903    #[serde(default)]
7904    pub using_before_columns: bool,
7905    /// MySQL index COMMENT 'text'
7906    #[serde(default, skip_serializing_if = "Option::is_none")]
7907    pub comment: Option<String>,
7908    /// MySQL index VISIBLE/INVISIBLE
7909    #[serde(default, skip_serializing_if = "Option::is_none")]
7910    pub visible: Option<bool>,
7911    /// MySQL ENGINE_ATTRIBUTE = 'value'
7912    #[serde(default, skip_serializing_if = "Option::is_none")]
7913    pub engine_attribute: Option<String>,
7914    /// MySQL WITH PARSER name
7915    #[serde(default, skip_serializing_if = "Option::is_none")]
7916    pub with_parser: Option<String>,
7917    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
7918    #[serde(default)]
7919    pub not_valid: bool,
7920    /// TSQL CLUSTERED/NONCLUSTERED modifier
7921    #[serde(default, skip_serializing_if = "Option::is_none")]
7922    pub clustered: Option<String>,
7923    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
7924    #[serde(default, skip_serializing_if = "Option::is_none")]
7925    pub on_conflict: Option<String>,
7926    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
7927    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7928    pub with_options: Vec<(String, String)>,
7929    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
7930    #[serde(default, skip_serializing_if = "Option::is_none")]
7931    pub on_filegroup: Option<Identifier>,
7932}
7933
7934/// Table-level constraint
7935#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7936#[cfg_attr(feature = "bindings", derive(TS))]
7937pub enum TableConstraint {
7938    PrimaryKey {
7939        name: Option<Identifier>,
7940        columns: Vec<Identifier>,
7941        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
7942        #[serde(default)]
7943        include_columns: Vec<Identifier>,
7944        #[serde(default)]
7945        modifiers: ConstraintModifiers,
7946        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
7947        #[serde(default)]
7948        has_constraint_keyword: bool,
7949    },
7950    Unique {
7951        name: Option<Identifier>,
7952        columns: Vec<Identifier>,
7953        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
7954        #[serde(default)]
7955        columns_parenthesized: bool,
7956        #[serde(default)]
7957        modifiers: ConstraintModifiers,
7958        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
7959        #[serde(default)]
7960        has_constraint_keyword: bool,
7961        /// PostgreSQL 15+: NULLS NOT DISTINCT
7962        #[serde(default)]
7963        nulls_not_distinct: bool,
7964    },
7965    ForeignKey {
7966        name: Option<Identifier>,
7967        columns: Vec<Identifier>,
7968        #[serde(default)]
7969        references: Option<ForeignKeyRef>,
7970        /// ON DELETE action when REFERENCES is absent
7971        #[serde(default)]
7972        on_delete: Option<ReferentialAction>,
7973        /// ON UPDATE action when REFERENCES is absent
7974        #[serde(default)]
7975        on_update: Option<ReferentialAction>,
7976        #[serde(default)]
7977        modifiers: ConstraintModifiers,
7978    },
7979    Check {
7980        name: Option<Identifier>,
7981        expression: Expression,
7982        #[serde(default)]
7983        modifiers: ConstraintModifiers,
7984    },
7985    /// ClickHouse ASSUME constraint (query optimization assumption)
7986    Assume {
7987        name: Option<Identifier>,
7988        expression: Expression,
7989    },
7990    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
7991    Default {
7992        name: Option<Identifier>,
7993        expression: Expression,
7994        column: Identifier,
7995    },
7996    /// INDEX / KEY constraint (MySQL)
7997    Index {
7998        name: Option<Identifier>,
7999        columns: Vec<Identifier>,
8000        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8001        #[serde(default)]
8002        kind: Option<String>,
8003        #[serde(default)]
8004        modifiers: ConstraintModifiers,
8005        /// True if KEY keyword was used instead of INDEX
8006        #[serde(default)]
8007        use_key_keyword: bool,
8008        /// ClickHouse: indexed expression (instead of columns)
8009        #[serde(default, skip_serializing_if = "Option::is_none")]
8010        expression: Option<Box<Expression>>,
8011        /// ClickHouse: TYPE type_func(args)
8012        #[serde(default, skip_serializing_if = "Option::is_none")]
8013        index_type: Option<Box<Expression>>,
8014        /// ClickHouse: GRANULARITY n
8015        #[serde(default, skip_serializing_if = "Option::is_none")]
8016        granularity: Option<Box<Expression>>,
8017    },
8018    /// ClickHouse PROJECTION definition
8019    Projection {
8020        name: Identifier,
8021        expression: Expression,
8022    },
8023    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8024    Like {
8025        source: TableRef,
8026        /// Options as (INCLUDING|EXCLUDING, property) pairs
8027        options: Vec<(LikeOptionAction, String)>,
8028    },
8029    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8030    PeriodForSystemTime {
8031        start_col: Identifier,
8032        end_col: Identifier,
8033    },
8034    /// PostgreSQL EXCLUDE constraint
8035    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8036    Exclude {
8037        name: Option<Identifier>,
8038        /// Index access method (gist, btree, etc.)
8039        #[serde(default)]
8040        using: Option<String>,
8041        /// Elements: (expression, operator) pairs
8042        elements: Vec<ExcludeElement>,
8043        /// INCLUDE columns
8044        #[serde(default)]
8045        include_columns: Vec<Identifier>,
8046        /// WHERE predicate
8047        #[serde(default)]
8048        where_clause: Option<Box<Expression>>,
8049        /// WITH (storage_parameters)
8050        #[serde(default)]
8051        with_params: Vec<(String, String)>,
8052        /// USING INDEX TABLESPACE tablespace_name
8053        #[serde(default)]
8054        using_index_tablespace: Option<String>,
8055        #[serde(default)]
8056        modifiers: ConstraintModifiers,
8057    },
8058    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8059    Tags(Tags),
8060    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8061    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8062    /// for all deferrable constraints in the table
8063    InitiallyDeferred {
8064        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8065        deferred: bool,
8066    },
8067}
8068
8069/// Element in an EXCLUDE constraint: expression WITH operator
8070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8071#[cfg_attr(feature = "bindings", derive(TS))]
8072pub struct ExcludeElement {
8073    /// The column expression (may include operator class, ordering, nulls)
8074    pub expression: String,
8075    /// The operator (e.g., &&, =)
8076    pub operator: String,
8077}
8078
8079/// Action for LIKE clause options
8080#[derive(
8081    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8082)]
8083#[cfg_attr(feature = "bindings", derive(TS))]
8084pub enum LikeOptionAction {
8085    Including,
8086    Excluding,
8087}
8088
8089/// MATCH type for foreign keys
8090#[derive(
8091    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8092)]
8093#[cfg_attr(feature = "bindings", derive(TS))]
8094pub enum MatchType {
8095    Full,
8096    Partial,
8097    Simple,
8098}
8099
8100/// Foreign key reference
8101#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8102#[cfg_attr(feature = "bindings", derive(TS))]
8103pub struct ForeignKeyRef {
8104    pub table: TableRef,
8105    pub columns: Vec<Identifier>,
8106    pub on_delete: Option<ReferentialAction>,
8107    pub on_update: Option<ReferentialAction>,
8108    /// True if ON UPDATE appears before ON DELETE in the original SQL
8109    #[serde(default)]
8110    pub on_update_first: bool,
8111    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8112    #[serde(default)]
8113    pub match_type: Option<MatchType>,
8114    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8115    #[serde(default)]
8116    pub match_after_actions: bool,
8117    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8118    #[serde(default)]
8119    pub constraint_name: Option<String>,
8120    /// DEFERRABLE / NOT DEFERRABLE
8121    #[serde(default)]
8122    pub deferrable: Option<bool>,
8123    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8124    #[serde(default)]
8125    pub has_foreign_key_keywords: bool,
8126}
8127
8128/// Referential action for foreign keys
8129#[derive(
8130    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8131)]
8132#[cfg_attr(feature = "bindings", derive(TS))]
8133pub enum ReferentialAction {
8134    Cascade,
8135    SetNull,
8136    SetDefault,
8137    Restrict,
8138    NoAction,
8139}
8140
8141/// DROP TABLE statement
8142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8143#[cfg_attr(feature = "bindings", derive(TS))]
8144pub struct DropTable {
8145    pub names: Vec<TableRef>,
8146    pub if_exists: bool,
8147    pub cascade: bool,
8148    /// Oracle: CASCADE CONSTRAINTS
8149    #[serde(default)]
8150    pub cascade_constraints: bool,
8151    /// Oracle: PURGE
8152    #[serde(default)]
8153    pub purge: bool,
8154    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8155    #[serde(default)]
8156    pub leading_comments: Vec<String>,
8157    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8158    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8159    #[serde(default, skip_serializing_if = "Option::is_none")]
8160    pub object_id_args: Option<String>,
8161    /// ClickHouse: SYNC modifier
8162    #[serde(default)]
8163    pub sync: bool,
8164    /// Snowflake: DROP ICEBERG TABLE
8165    #[serde(default)]
8166    pub iceberg: bool,
8167    /// RESTRICT modifier (opposite of CASCADE)
8168    #[serde(default)]
8169    pub restrict: bool,
8170}
8171
8172impl DropTable {
8173    pub fn new(name: impl Into<String>) -> Self {
8174        Self {
8175            names: vec![TableRef::new(name)],
8176            if_exists: false,
8177            cascade: false,
8178            cascade_constraints: false,
8179            purge: false,
8180            leading_comments: Vec::new(),
8181            object_id_args: None,
8182            sync: false,
8183            iceberg: false,
8184            restrict: false,
8185        }
8186    }
8187}
8188
8189/// UNDROP object statement (Snowflake, ClickHouse)
8190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8191#[cfg_attr(feature = "bindings", derive(TS))]
8192pub struct Undrop {
8193    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8194    pub kind: String,
8195    /// The object name
8196    pub name: TableRef,
8197    /// IF EXISTS clause
8198    #[serde(default)]
8199    pub if_exists: bool,
8200    /// Snowflake: optional RENAME TO target
8201    #[serde(default, skip_serializing_if = "Option::is_none")]
8202    pub rename_to: Option<TableRef>,
8203}
8204
8205/// Partition scope for a TiDB `SPLIT TABLE` statement.
8206#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8207#[cfg_attr(feature = "bindings", derive(TS))]
8208#[serde(tag = "type", rename_all = "snake_case")]
8209pub enum SplitTablePartitionScope {
8210    Table,
8211    AllPartitions,
8212    Partitions { names: Vec<Identifier> },
8213}
8214
8215/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8217#[cfg_attr(feature = "bindings", derive(TS))]
8218#[serde(tag = "type", rename_all = "snake_case")]
8219pub enum SplitTableMode {
8220    Between {
8221        lower: Vec<Expression>,
8222        upper: Vec<Expression>,
8223        regions: u64,
8224    },
8225    By {
8226        points: Vec<Vec<Expression>>,
8227    },
8228}
8229
8230/// TiDB `SPLIT [PARTITION] TABLE` statement.
8231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8232#[cfg_attr(feature = "bindings", derive(TS))]
8233pub struct SplitTable {
8234    pub table: TableRef,
8235    pub partition_scope: SplitTablePartitionScope,
8236    #[serde(default, skip_serializing_if = "Option::is_none")]
8237    pub index: Option<Identifier>,
8238    pub mode: SplitTableMode,
8239}
8240
8241/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
8242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8243#[cfg_attr(feature = "bindings", derive(TS))]
8244pub struct FlashbackTable {
8245    pub table: TableRef,
8246    #[serde(default, skip_serializing_if = "Option::is_none")]
8247    pub rename_to: Option<Identifier>,
8248}
8249
8250/// ALTER TABLE statement
8251#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8252#[cfg_attr(feature = "bindings", derive(TS))]
8253pub struct AlterTable {
8254    pub name: TableRef,
8255    pub actions: Vec<AlterTableAction>,
8256    /// IF EXISTS clause
8257    #[serde(default)]
8258    pub if_exists: bool,
8259    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8260    #[serde(default, skip_serializing_if = "Option::is_none")]
8261    pub algorithm: Option<String>,
8262    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8263    #[serde(default, skip_serializing_if = "Option::is_none")]
8264    pub lock: Option<String>,
8265    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8266    #[serde(default, skip_serializing_if = "Option::is_none")]
8267    pub with_check: Option<String>,
8268    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8269    #[serde(default, skip_serializing_if = "Option::is_none")]
8270    pub partition: Option<Vec<(Identifier, Expression)>>,
8271    /// ClickHouse: ON CLUSTER clause for distributed DDL
8272    #[serde(default, skip_serializing_if = "Option::is_none")]
8273    pub on_cluster: Option<OnCluster>,
8274    /// Snowflake: ALTER ICEBERG TABLE
8275    #[serde(default, skip_serializing_if = "Option::is_none")]
8276    pub table_modifier: Option<String>,
8277}
8278
8279impl AlterTable {
8280    pub fn new(name: impl Into<String>) -> Self {
8281        Self {
8282            name: TableRef::new(name),
8283            actions: Vec::new(),
8284            if_exists: false,
8285            algorithm: None,
8286            lock: None,
8287            with_check: None,
8288            partition: None,
8289            on_cluster: None,
8290            table_modifier: None,
8291        }
8292    }
8293}
8294
8295/// Column position for ADD COLUMN (MySQL/MariaDB)
8296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8297#[cfg_attr(feature = "bindings", derive(TS))]
8298pub enum ColumnPosition {
8299    First,
8300    After(Identifier),
8301}
8302
8303/// Actions for ALTER TABLE
8304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8305#[cfg_attr(feature = "bindings", derive(TS))]
8306pub enum AlterTableAction {
8307    AddColumn {
8308        column: ColumnDef,
8309        if_not_exists: bool,
8310        position: Option<ColumnPosition>,
8311    },
8312    DropColumn {
8313        name: Identifier,
8314        if_exists: bool,
8315        cascade: bool,
8316    },
8317    RenameColumn {
8318        old_name: Identifier,
8319        new_name: Identifier,
8320        if_exists: bool,
8321    },
8322    AlterColumn {
8323        name: Identifier,
8324        action: AlterColumnAction,
8325        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8326        #[serde(default)]
8327        use_modify_keyword: bool,
8328    },
8329    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
8330    ModifyColumn {
8331        column: ColumnDef,
8332        if_exists: bool,
8333        position: Option<ColumnPosition>,
8334    },
8335    RenameTable(TableRef),
8336    AddConstraint(TableConstraint),
8337    DropConstraint {
8338        name: Identifier,
8339        if_exists: bool,
8340    },
8341    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8342    DropForeignKey {
8343        name: Identifier,
8344    },
8345    /// DROP PARTITION action (Hive/BigQuery)
8346    DropPartition {
8347        /// List of partitions to drop (each partition is a list of key=value pairs)
8348        partitions: Vec<Vec<(Identifier, Expression)>>,
8349        if_exists: bool,
8350    },
8351    /// ADD PARTITION action (Hive/Spark)
8352    AddPartition {
8353        /// The partition expression
8354        partition: Expression,
8355        if_not_exists: bool,
8356        location: Option<Expression>,
8357    },
8358    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8359    Delete {
8360        where_clause: Expression,
8361    },
8362    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8363    SwapWith(TableRef),
8364    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8365    SetProperty {
8366        properties: Vec<(String, Expression)>,
8367    },
8368    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8369    UnsetProperty {
8370        properties: Vec<String>,
8371    },
8372    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8373    ClusterBy {
8374        expressions: Vec<Expression>,
8375    },
8376    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8377    SetTag {
8378        expressions: Vec<(String, Expression)>,
8379    },
8380    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8381    UnsetTag {
8382        names: Vec<String>,
8383    },
8384    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8385    SetOptions {
8386        expressions: Vec<Expression>,
8387    },
8388    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8389    AlterIndex {
8390        name: Identifier,
8391        visible: bool,
8392    },
8393    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8394    SetAttribute {
8395        attribute: String,
8396    },
8397    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8398    SetStageFileFormat {
8399        options: Option<Expression>,
8400    },
8401    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8402    SetStageCopyOptions {
8403        options: Option<Expression>,
8404    },
8405    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8406    AddColumns {
8407        columns: Vec<ColumnDef>,
8408        cascade: bool,
8409    },
8410    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8411    DropColumns {
8412        names: Vec<Identifier>,
8413    },
8414    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8415    /// In SingleStore, data_type can be omitted for simple column renames
8416    ChangeColumn {
8417        old_name: Identifier,
8418        new_name: Identifier,
8419        #[serde(default, skip_serializing_if = "Option::is_none")]
8420        data_type: Option<DataType>,
8421        comment: Option<String>,
8422        #[serde(default)]
8423        cascade: bool,
8424    },
8425    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
8426    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
8427    AlterSortKey {
8428        /// AUTO or NONE keyword
8429        this: Option<String>,
8430        /// Column list for (col1, col2) syntax
8431        expressions: Vec<Expression>,
8432        /// Whether COMPOUND keyword was present
8433        compound: bool,
8434    },
8435    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
8436    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
8437    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
8438    AlterDistStyle {
8439        /// Distribution style: ALL, EVEN, AUTO, or KEY
8440        style: String,
8441        /// DISTKEY column (only when style is KEY)
8442        distkey: Option<Identifier>,
8443    },
8444    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
8445    SetTableProperties {
8446        properties: Vec<(Expression, Expression)>,
8447    },
8448    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
8449    SetLocation {
8450        location: String,
8451    },
8452    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
8453    SetFileFormat {
8454        format: String,
8455    },
8456    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
8457    ReplacePartition {
8458        partition: Expression,
8459        source: Option<Box<Expression>>,
8460    },
8461    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
8462    SetTiDBTableOption {
8463        option: TiDBTableOption,
8464        #[serde(default)]
8465        force: bool,
8466    },
8467    /// TiDB `REMOVE TTL`.
8468    RemoveTiDBTtl {
8469        #[serde(default)]
8470        executable_comment: bool,
8471    },
8472    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
8473    Raw {
8474        sql: String,
8475    },
8476}
8477
8478/// Actions for ALTER COLUMN
8479#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8480#[cfg_attr(feature = "bindings", derive(TS))]
8481pub enum AlterColumnAction {
8482    SetDataType {
8483        data_type: DataType,
8484        /// USING expression for type conversion (PostgreSQL)
8485        using: Option<Expression>,
8486        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
8487        #[serde(default, skip_serializing_if = "Option::is_none")]
8488        collate: Option<String>,
8489    },
8490    SetDefault(Expression),
8491    DropDefault,
8492    SetNotNull,
8493    DropNotNull,
8494    /// Set column comment
8495    Comment(String),
8496    /// MySQL: SET VISIBLE
8497    SetVisible,
8498    /// MySQL: SET INVISIBLE
8499    SetInvisible,
8500}
8501
8502/// CREATE INDEX statement
8503#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8504#[cfg_attr(feature = "bindings", derive(TS))]
8505pub struct CreateIndex {
8506    pub name: Identifier,
8507    pub table: TableRef,
8508    pub columns: Vec<IndexColumn>,
8509    pub unique: bool,
8510    pub if_not_exists: bool,
8511    pub using: Option<String>,
8512    /// TSQL CLUSTERED/NONCLUSTERED modifier
8513    #[serde(default)]
8514    pub clustered: Option<String>,
8515    /// PostgreSQL CONCURRENTLY modifier
8516    #[serde(default)]
8517    pub concurrently: bool,
8518    /// PostgreSQL WHERE clause for partial indexes
8519    #[serde(default)]
8520    pub where_clause: Option<Box<Expression>>,
8521    /// PostgreSQL INCLUDE columns
8522    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8523    pub include_columns: Vec<Identifier>,
8524    /// TSQL WITH options (e.g., allow_page_locks=on)
8525    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8526    pub with_options: Vec<(String, String)>,
8527    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
8528    #[serde(default)]
8529    pub on_filegroup: Option<String>,
8530}
8531
8532impl CreateIndex {
8533    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
8534        Self {
8535            name: Identifier::new(name),
8536            table: TableRef::new(table),
8537            columns: Vec::new(),
8538            unique: false,
8539            if_not_exists: false,
8540            using: None,
8541            clustered: None,
8542            concurrently: false,
8543            where_clause: None,
8544            include_columns: Vec::new(),
8545            with_options: Vec::new(),
8546            on_filegroup: None,
8547        }
8548    }
8549}
8550
8551/// Index column specification
8552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8553#[cfg_attr(feature = "bindings", derive(TS))]
8554pub struct IndexColumn {
8555    pub column: Identifier,
8556    pub desc: bool,
8557    /// Explicit ASC keyword was present
8558    #[serde(default)]
8559    pub asc: bool,
8560    pub nulls_first: Option<bool>,
8561    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
8562    #[serde(default, skip_serializing_if = "Option::is_none")]
8563    pub opclass: Option<String>,
8564}
8565
8566/// DROP INDEX statement
8567#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8568#[cfg_attr(feature = "bindings", derive(TS))]
8569pub struct DropIndex {
8570    pub name: TableRef,
8571    pub table: Option<TableRef>,
8572    pub if_exists: bool,
8573    /// PostgreSQL CONCURRENTLY modifier
8574    #[serde(default)]
8575    pub concurrently: bool,
8576}
8577
8578impl DropIndex {
8579    pub fn new(name: impl Into<String>) -> Self {
8580        Self {
8581            name: TableRef::new(name),
8582            table: None,
8583            if_exists: false,
8584            concurrently: false,
8585        }
8586    }
8587}
8588
8589/// View column definition with optional COMMENT and OPTIONS (BigQuery)
8590#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8591#[cfg_attr(feature = "bindings", derive(TS))]
8592pub struct ViewColumn {
8593    pub name: Identifier,
8594    pub comment: Option<String>,
8595    /// BigQuery: OPTIONS (key=value, ...) on column
8596    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8597    pub options: Vec<Expression>,
8598}
8599
8600impl ViewColumn {
8601    pub fn new(name: impl Into<String>) -> Self {
8602        Self {
8603            name: Identifier::new(name),
8604            comment: None,
8605            options: Vec::new(),
8606        }
8607    }
8608
8609    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
8610        Self {
8611            name: Identifier::new(name),
8612            comment: Some(comment.into()),
8613            options: Vec::new(),
8614        }
8615    }
8616}
8617
8618/// CREATE VIEW statement
8619#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8620#[cfg_attr(feature = "bindings", derive(TS))]
8621pub struct CreateView {
8622    pub name: TableRef,
8623    pub columns: Vec<ViewColumn>,
8624    pub query: Expression,
8625    pub or_replace: bool,
8626    /// TSQL: CREATE OR ALTER
8627    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
8628    pub or_alter: bool,
8629    pub if_not_exists: bool,
8630    pub materialized: bool,
8631    pub temporary: bool,
8632    /// Snowflake: SECURE VIEW
8633    #[serde(default)]
8634    pub secure: bool,
8635    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
8636    #[serde(skip_serializing_if = "Option::is_none")]
8637    pub algorithm: Option<String>,
8638    /// MySQL: DEFINER=user@host
8639    #[serde(skip_serializing_if = "Option::is_none")]
8640    pub definer: Option<String>,
8641    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
8642    #[serde(skip_serializing_if = "Option::is_none")]
8643    pub security: Option<FunctionSecurity>,
8644    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
8645    #[serde(default = "default_true")]
8646    pub security_sql_style: bool,
8647    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
8648    #[serde(default)]
8649    pub security_after_name: bool,
8650    /// Whether the query was parenthesized: AS (SELECT ...)
8651    #[serde(default)]
8652    pub query_parenthesized: bool,
8653    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
8654    #[serde(skip_serializing_if = "Option::is_none")]
8655    pub locking_mode: Option<String>,
8656    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
8657    #[serde(skip_serializing_if = "Option::is_none")]
8658    pub locking_access: Option<String>,
8659    /// Snowflake: COPY GRANTS
8660    #[serde(default)]
8661    pub copy_grants: bool,
8662    /// Snowflake: COMMENT = 'text'
8663    #[serde(skip_serializing_if = "Option::is_none", default)]
8664    pub comment: Option<String>,
8665    /// Snowflake: WITH ROW ACCESS POLICY ... clause
8666    #[serde(skip_serializing_if = "Option::is_none", default)]
8667    pub row_access_policy: Option<String>,
8668    /// Snowflake: TAG (name='value', ...)
8669    #[serde(default)]
8670    pub tags: Vec<(String, String)>,
8671    /// BigQuery: OPTIONS (key=value, ...)
8672    #[serde(default)]
8673    pub options: Vec<Expression>,
8674    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
8675    #[serde(skip_serializing_if = "Option::is_none", default)]
8676    pub build: Option<String>,
8677    /// Doris: REFRESH property for materialized views
8678    #[serde(skip_serializing_if = "Option::is_none", default)]
8679    pub refresh: Option<Box<RefreshTriggerProperty>>,
8680    /// Doris: Schema with typed column definitions for materialized views
8681    /// This is used instead of `columns` when the view has typed column definitions
8682    #[serde(skip_serializing_if = "Option::is_none", default)]
8683    pub schema: Option<Box<Schema>>,
8684    /// Doris: KEY (columns) for materialized views
8685    #[serde(skip_serializing_if = "Option::is_none", default)]
8686    pub unique_key: Option<Box<UniqueKeyProperty>>,
8687    /// Redshift: WITH NO SCHEMA BINDING
8688    #[serde(default)]
8689    pub no_schema_binding: bool,
8690    /// Redshift: AUTO REFRESH YES|NO for materialized views
8691    #[serde(skip_serializing_if = "Option::is_none", default)]
8692    pub auto_refresh: Option<bool>,
8693    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
8694    #[serde(skip_serializing_if = "Option::is_none", default)]
8695    pub clickhouse_population: Option<String>,
8696    /// ClickHouse: ON CLUSTER clause
8697    #[serde(default, skip_serializing_if = "Option::is_none")]
8698    pub on_cluster: Option<OnCluster>,
8699    /// ClickHouse: TO destination_table
8700    #[serde(default, skip_serializing_if = "Option::is_none")]
8701    pub to_table: Option<TableRef>,
8702    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
8703    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8704    pub table_properties: Vec<Expression>,
8705}
8706
8707impl CreateView {
8708    pub fn new(name: impl Into<String>, query: Expression) -> Self {
8709        Self {
8710            name: TableRef::new(name),
8711            columns: Vec::new(),
8712            query,
8713            or_replace: false,
8714            or_alter: false,
8715            if_not_exists: false,
8716            materialized: false,
8717            temporary: false,
8718            secure: false,
8719            algorithm: None,
8720            definer: None,
8721            security: None,
8722            security_sql_style: true,
8723            security_after_name: false,
8724            query_parenthesized: false,
8725            locking_mode: None,
8726            locking_access: None,
8727            copy_grants: false,
8728            comment: None,
8729            row_access_policy: None,
8730            tags: Vec::new(),
8731            options: Vec::new(),
8732            build: None,
8733            refresh: None,
8734            schema: None,
8735            unique_key: None,
8736            no_schema_binding: false,
8737            auto_refresh: None,
8738            clickhouse_population: None,
8739            on_cluster: None,
8740            to_table: None,
8741            table_properties: Vec::new(),
8742        }
8743    }
8744}
8745
8746/// DROP VIEW statement
8747#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8748#[cfg_attr(feature = "bindings", derive(TS))]
8749pub struct DropView {
8750    pub name: TableRef,
8751    pub if_exists: bool,
8752    pub materialized: bool,
8753}
8754
8755impl DropView {
8756    pub fn new(name: impl Into<String>) -> Self {
8757        Self {
8758            name: TableRef::new(name),
8759            if_exists: false,
8760            materialized: false,
8761        }
8762    }
8763}
8764
8765/// TRUNCATE TABLE statement
8766#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8767#[cfg_attr(feature = "bindings", derive(TS))]
8768pub struct Truncate {
8769    /// Target of TRUNCATE (TABLE vs DATABASE)
8770    #[serde(default)]
8771    pub target: TruncateTarget,
8772    /// IF EXISTS clause
8773    #[serde(default)]
8774    pub if_exists: bool,
8775    pub table: TableRef,
8776    /// ClickHouse: ON CLUSTER clause for distributed DDL
8777    #[serde(default, skip_serializing_if = "Option::is_none")]
8778    pub on_cluster: Option<OnCluster>,
8779    pub cascade: bool,
8780    /// Additional tables for multi-table TRUNCATE
8781    #[serde(default)]
8782    pub extra_tables: Vec<TruncateTableEntry>,
8783    /// RESTART IDENTITY or CONTINUE IDENTITY
8784    #[serde(default)]
8785    pub identity: Option<TruncateIdentity>,
8786    /// RESTRICT option (alternative to CASCADE)
8787    #[serde(default)]
8788    pub restrict: bool,
8789    /// Hive PARTITION clause: PARTITION(key=value, ...)
8790    #[serde(default, skip_serializing_if = "Option::is_none")]
8791    pub partition: Option<Box<Expression>>,
8792}
8793
8794/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
8795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8796#[cfg_attr(feature = "bindings", derive(TS))]
8797pub struct TruncateTableEntry {
8798    pub table: TableRef,
8799    /// Whether the table has a * suffix (inherit children)
8800    #[serde(default)]
8801    pub star: bool,
8802}
8803
8804/// TRUNCATE target type
8805#[derive(
8806    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8807)]
8808#[cfg_attr(feature = "bindings", derive(TS))]
8809pub enum TruncateTarget {
8810    Table,
8811    Database,
8812}
8813
8814impl Default for TruncateTarget {
8815    fn default() -> Self {
8816        TruncateTarget::Table
8817    }
8818}
8819
8820/// TRUNCATE identity option
8821#[derive(
8822    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8823)]
8824#[cfg_attr(feature = "bindings", derive(TS))]
8825pub enum TruncateIdentity {
8826    Restart,
8827    Continue,
8828}
8829
8830impl Truncate {
8831    pub fn new(table: impl Into<String>) -> Self {
8832        Self {
8833            target: TruncateTarget::Table,
8834            if_exists: false,
8835            table: TableRef::new(table),
8836            on_cluster: None,
8837            cascade: false,
8838            extra_tables: Vec::new(),
8839            identity: None,
8840            restrict: false,
8841            partition: None,
8842        }
8843    }
8844}
8845
8846/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
8847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8848#[cfg_attr(feature = "bindings", derive(TS))]
8849pub struct Use {
8850    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
8851    pub kind: Option<UseKind>,
8852    /// The name of the object
8853    pub this: Identifier,
8854}
8855
8856/// Kind of USE statement
8857#[derive(
8858    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8859)]
8860#[cfg_attr(feature = "bindings", derive(TS))]
8861pub enum UseKind {
8862    Database,
8863    Schema,
8864    Role,
8865    Warehouse,
8866    Catalog,
8867    /// Snowflake: USE SECONDARY ROLES ALL|NONE
8868    SecondaryRoles,
8869}
8870
8871/// SET variable statement
8872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8873#[cfg_attr(feature = "bindings", derive(TS))]
8874pub struct SetStatement {
8875    /// The items being set
8876    pub items: Vec<SetItem>,
8877}
8878
8879/// A single SET item (variable assignment)
8880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8881#[cfg_attr(feature = "bindings", derive(TS))]
8882pub struct SetItem {
8883    /// The variable name
8884    pub name: Expression,
8885    /// The value to set
8886    pub value: Expression,
8887    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
8888    pub kind: Option<String>,
8889    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
8890    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
8891    pub no_equals: bool,
8892}
8893
8894/// CACHE TABLE statement (Spark)
8895#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8896#[cfg_attr(feature = "bindings", derive(TS))]
8897pub struct Cache {
8898    /// The table to cache
8899    pub table: Identifier,
8900    /// LAZY keyword - defer caching until first use
8901    pub lazy: bool,
8902    /// Optional OPTIONS clause (key-value pairs)
8903    pub options: Vec<(Expression, Expression)>,
8904    /// Optional AS clause with query
8905    pub query: Option<Expression>,
8906}
8907
8908/// UNCACHE TABLE statement (Spark)
8909#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8910#[cfg_attr(feature = "bindings", derive(TS))]
8911pub struct Uncache {
8912    /// The table to uncache
8913    pub table: Identifier,
8914    /// IF EXISTS clause
8915    pub if_exists: bool,
8916}
8917
8918/// LOAD DATA statement (Hive)
8919#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8920#[cfg_attr(feature = "bindings", derive(TS))]
8921pub struct LoadData {
8922    /// LOCAL keyword - load from local filesystem
8923    pub local: bool,
8924    /// The path to load data from (INPATH value)
8925    pub inpath: String,
8926    /// Whether to overwrite existing data
8927    pub overwrite: bool,
8928    /// The target table
8929    pub table: Expression,
8930    /// Optional PARTITION clause with key-value pairs
8931    pub partition: Vec<(Identifier, Expression)>,
8932    /// Optional INPUTFORMAT clause
8933    pub input_format: Option<String>,
8934    /// Optional SERDE clause
8935    pub serde: Option<String>,
8936}
8937
8938/// PRAGMA statement (SQLite)
8939#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8940#[cfg_attr(feature = "bindings", derive(TS))]
8941pub struct Pragma {
8942    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
8943    pub schema: Option<Identifier>,
8944    /// The pragma name
8945    pub name: Identifier,
8946    /// Optional value for assignment (PRAGMA name = value)
8947    pub value: Option<Expression>,
8948    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
8949    pub args: Vec<Expression>,
8950    /// Whether this pragma should be generated using assignment syntax.
8951    #[serde(default)]
8952    pub use_assignment_syntax: bool,
8953}
8954
8955/// A privilege with optional column list for GRANT/REVOKE
8956/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
8957#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8958#[cfg_attr(feature = "bindings", derive(TS))]
8959pub struct Privilege {
8960    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
8961    pub name: String,
8962    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
8963    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8964    pub columns: Vec<String>,
8965}
8966
8967/// Principal in GRANT/REVOKE (user, role, etc.)
8968#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8969#[cfg_attr(feature = "bindings", derive(TS))]
8970pub struct GrantPrincipal {
8971    /// The name of the principal
8972    pub name: Identifier,
8973    /// Whether prefixed with ROLE keyword
8974    pub is_role: bool,
8975    /// Whether prefixed with GROUP keyword (Redshift)
8976    #[serde(default)]
8977    pub is_group: bool,
8978    /// Whether prefixed with SHARE keyword (Snowflake)
8979    #[serde(default)]
8980    pub is_share: bool,
8981}
8982
8983/// GRANT statement
8984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8985#[cfg_attr(feature = "bindings", derive(TS))]
8986pub struct Grant {
8987    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
8988    pub privileges: Vec<Privilege>,
8989    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
8990    pub kind: Option<String>,
8991    /// The object to grant on
8992    pub securable: Identifier,
8993    /// Function parameter types (for FUNCTION kind)
8994    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8995    pub function_params: Vec<String>,
8996    /// The grantees
8997    pub principals: Vec<GrantPrincipal>,
8998    /// WITH GRANT OPTION
8999    pub grant_option: bool,
9000    /// TSQL: AS principal (the grantor role)
9001    #[serde(default, skip_serializing_if = "Option::is_none")]
9002    pub as_principal: Option<Identifier>,
9003}
9004
9005/// REVOKE statement
9006#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9007#[cfg_attr(feature = "bindings", derive(TS))]
9008pub struct Revoke {
9009    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9010    pub privileges: Vec<Privilege>,
9011    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9012    pub kind: Option<String>,
9013    /// The object to revoke from
9014    pub securable: Identifier,
9015    /// Function parameter types (for FUNCTION kind)
9016    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9017    pub function_params: Vec<String>,
9018    /// The grantees
9019    pub principals: Vec<GrantPrincipal>,
9020    /// GRANT OPTION FOR
9021    pub grant_option: bool,
9022    /// CASCADE
9023    pub cascade: bool,
9024    /// RESTRICT
9025    #[serde(default)]
9026    pub restrict: bool,
9027}
9028
9029/// COMMENT ON statement
9030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9031#[cfg_attr(feature = "bindings", derive(TS))]
9032pub struct Comment {
9033    /// The object being commented on
9034    pub this: Expression,
9035    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9036    pub kind: String,
9037    /// The comment text expression
9038    pub expression: Expression,
9039    /// IF EXISTS clause
9040    pub exists: bool,
9041    /// MATERIALIZED keyword
9042    pub materialized: bool,
9043}
9044
9045// ============================================================================
9046// Phase 4: Additional DDL Statements
9047// ============================================================================
9048
9049/// ALTER VIEW statement
9050#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9051#[cfg_attr(feature = "bindings", derive(TS))]
9052pub struct AlterView {
9053    pub name: TableRef,
9054    pub actions: Vec<AlterViewAction>,
9055    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9056    #[serde(default, skip_serializing_if = "Option::is_none")]
9057    pub algorithm: Option<String>,
9058    /// MySQL: DEFINER = 'user'@'host'
9059    #[serde(default, skip_serializing_if = "Option::is_none")]
9060    pub definer: Option<String>,
9061    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9062    #[serde(default, skip_serializing_if = "Option::is_none")]
9063    pub sql_security: Option<String>,
9064    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9065    #[serde(default, skip_serializing_if = "Option::is_none")]
9066    pub with_option: Option<String>,
9067    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9068    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9069    pub columns: Vec<ViewColumn>,
9070}
9071
9072/// Actions for ALTER VIEW
9073#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9074#[cfg_attr(feature = "bindings", derive(TS))]
9075pub enum AlterViewAction {
9076    /// Rename the view
9077    Rename(TableRef),
9078    /// Change owner
9079    OwnerTo(Identifier),
9080    /// Set schema
9081    SetSchema(Identifier),
9082    /// Set authorization (Trino/Presto)
9083    SetAuthorization(String),
9084    /// Alter column
9085    AlterColumn {
9086        name: Identifier,
9087        action: AlterColumnAction,
9088    },
9089    /// Redefine view as query (SELECT, UNION, etc.)
9090    AsSelect(Box<Expression>),
9091    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9092    SetTblproperties(Vec<(String, String)>),
9093    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9094    UnsetTblproperties(Vec<String>),
9095}
9096
9097impl AlterView {
9098    pub fn new(name: impl Into<String>) -> Self {
9099        Self {
9100            name: TableRef::new(name),
9101            actions: Vec::new(),
9102            algorithm: None,
9103            definer: None,
9104            sql_security: None,
9105            with_option: None,
9106            columns: Vec::new(),
9107        }
9108    }
9109}
9110
9111/// ALTER INDEX statement
9112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9113#[cfg_attr(feature = "bindings", derive(TS))]
9114pub struct AlterIndex {
9115    pub name: Identifier,
9116    pub table: Option<TableRef>,
9117    pub actions: Vec<AlterIndexAction>,
9118}
9119
9120/// Actions for ALTER INDEX
9121#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9122#[cfg_attr(feature = "bindings", derive(TS))]
9123pub enum AlterIndexAction {
9124    /// Rename the index
9125    Rename(Identifier),
9126    /// Set tablespace
9127    SetTablespace(Identifier),
9128    /// Set visibility (MySQL)
9129    Visible(bool),
9130}
9131
9132impl AlterIndex {
9133    pub fn new(name: impl Into<String>) -> Self {
9134        Self {
9135            name: Identifier::new(name),
9136            table: None,
9137            actions: Vec::new(),
9138        }
9139    }
9140}
9141
9142/// CREATE SCHEMA statement
9143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9144#[cfg_attr(feature = "bindings", derive(TS))]
9145pub struct CreateSchema {
9146    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9147    pub name: Vec<Identifier>,
9148    pub if_not_exists: bool,
9149    pub authorization: Option<Identifier>,
9150    /// CLONE source parts, possibly dot-qualified
9151    #[serde(default)]
9152    pub clone_from: Option<Vec<Identifier>>,
9153    /// AT/BEFORE clause for time travel (Snowflake)
9154    #[serde(default)]
9155    pub at_clause: Option<Expression>,
9156    /// Schema properties like DEFAULT COLLATE
9157    #[serde(default)]
9158    pub properties: Vec<Expression>,
9159    /// Leading comments before the statement
9160    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9161    pub leading_comments: Vec<String>,
9162}
9163
9164impl CreateSchema {
9165    pub fn new(name: impl Into<String>) -> Self {
9166        Self {
9167            name: vec![Identifier::new(name)],
9168            if_not_exists: false,
9169            authorization: None,
9170            clone_from: None,
9171            at_clause: None,
9172            properties: Vec::new(),
9173            leading_comments: Vec::new(),
9174        }
9175    }
9176}
9177
9178/// DROP SCHEMA statement
9179#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9180#[cfg_attr(feature = "bindings", derive(TS))]
9181pub struct DropSchema {
9182    pub name: Identifier,
9183    pub if_exists: bool,
9184    pub cascade: bool,
9185}
9186
9187impl DropSchema {
9188    pub fn new(name: impl Into<String>) -> Self {
9189        Self {
9190            name: Identifier::new(name),
9191            if_exists: false,
9192            cascade: false,
9193        }
9194    }
9195}
9196
9197/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9198#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9199#[cfg_attr(feature = "bindings", derive(TS))]
9200pub struct DropNamespace {
9201    pub name: Identifier,
9202    pub if_exists: bool,
9203    pub cascade: bool,
9204}
9205
9206impl DropNamespace {
9207    pub fn new(name: impl Into<String>) -> Self {
9208        Self {
9209            name: Identifier::new(name),
9210            if_exists: false,
9211            cascade: false,
9212        }
9213    }
9214}
9215
9216/// CREATE DATABASE statement
9217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9218#[cfg_attr(feature = "bindings", derive(TS))]
9219pub struct CreateDatabase {
9220    pub name: Identifier,
9221    pub if_not_exists: bool,
9222    pub options: Vec<DatabaseOption>,
9223    /// Snowflake CLONE source
9224    #[serde(default)]
9225    pub clone_from: Option<Identifier>,
9226    /// AT/BEFORE clause for time travel (Snowflake)
9227    #[serde(default)]
9228    pub at_clause: Option<Expression>,
9229}
9230
9231/// Database option
9232#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9233#[cfg_attr(feature = "bindings", derive(TS))]
9234pub enum DatabaseOption {
9235    CharacterSet(String),
9236    Collate(String),
9237    Owner(Identifier),
9238    Template(Identifier),
9239    Encoding(String),
9240    Location(String),
9241}
9242
9243impl CreateDatabase {
9244    pub fn new(name: impl Into<String>) -> Self {
9245        Self {
9246            name: Identifier::new(name),
9247            if_not_exists: false,
9248            options: Vec::new(),
9249            clone_from: None,
9250            at_clause: None,
9251        }
9252    }
9253}
9254
9255/// DROP DATABASE statement
9256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9257#[cfg_attr(feature = "bindings", derive(TS))]
9258pub struct DropDatabase {
9259    pub name: Identifier,
9260    pub if_exists: bool,
9261    /// ClickHouse: SYNC modifier
9262    #[serde(default)]
9263    pub sync: bool,
9264}
9265
9266impl DropDatabase {
9267    pub fn new(name: impl Into<String>) -> Self {
9268        Self {
9269            name: Identifier::new(name),
9270            if_exists: false,
9271            sync: false,
9272        }
9273    }
9274}
9275
9276/// CREATE FUNCTION statement
9277#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9278#[cfg_attr(feature = "bindings", derive(TS))]
9279pub struct CreateFunction {
9280    pub name: TableRef,
9281    pub parameters: Vec<FunctionParameter>,
9282    pub return_type: Option<DataType>,
9283    pub body: Option<FunctionBody>,
9284    pub or_replace: bool,
9285    /// TSQL: CREATE OR ALTER
9286    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9287    pub or_alter: bool,
9288    pub if_not_exists: bool,
9289    pub temporary: bool,
9290    pub language: Option<String>,
9291    pub deterministic: Option<bool>,
9292    pub returns_null_on_null_input: Option<bool>,
9293    pub security: Option<FunctionSecurity>,
9294    /// Whether parentheses were present in the original syntax
9295    #[serde(default = "default_true")]
9296    pub has_parens: bool,
9297    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9298    #[serde(default)]
9299    pub sql_data_access: Option<SqlDataAccess>,
9300    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9301    #[serde(default, skip_serializing_if = "Option::is_none")]
9302    pub returns_table_body: Option<String>,
9303    /// True if LANGUAGE clause appears before RETURNS clause
9304    #[serde(default)]
9305    pub language_first: bool,
9306    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9307    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9308    pub set_options: Vec<FunctionSetOption>,
9309    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9310    #[serde(default)]
9311    pub strict: bool,
9312    /// BigQuery: OPTIONS (key=value, ...)
9313    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9314    pub options: Vec<Expression>,
9315    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9316    #[serde(default)]
9317    pub is_table_function: bool,
9318    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9319    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9320    pub property_order: Vec<FunctionPropertyKind>,
9321    /// Hive: USING JAR|FILE|ARCHIVE '...'
9322    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9323    pub using_resources: Vec<FunctionUsingResource>,
9324    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9325    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9326    pub environment: Vec<Expression>,
9327    /// HANDLER 'handler_function' clause (Databricks)
9328    #[serde(default, skip_serializing_if = "Option::is_none")]
9329    pub handler: Option<String>,
9330    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9331    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9332    pub handler_uses_eq: bool,
9333    /// Snowflake: RUNTIME_VERSION='3.11'
9334    #[serde(default, skip_serializing_if = "Option::is_none")]
9335    pub runtime_version: Option<String>,
9336    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9337    #[serde(default, skip_serializing_if = "Option::is_none")]
9338    pub packages: Option<Vec<String>>,
9339    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9340    #[serde(default, skip_serializing_if = "Option::is_none")]
9341    pub parameter_style: Option<String>,
9342}
9343
9344/// A SET option in CREATE FUNCTION (PostgreSQL)
9345#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9346#[cfg_attr(feature = "bindings", derive(TS))]
9347pub struct FunctionSetOption {
9348    pub name: String,
9349    pub value: FunctionSetValue,
9350}
9351
9352/// The value of a SET option
9353#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9354#[cfg_attr(feature = "bindings", derive(TS))]
9355pub enum FunctionSetValue {
9356    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9357    Value { value: String, use_to: bool },
9358    /// SET key FROM CURRENT
9359    FromCurrent,
9360}
9361
9362/// SQL data access characteristics for functions
9363#[derive(
9364    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9365)]
9366#[cfg_attr(feature = "bindings", derive(TS))]
9367pub enum SqlDataAccess {
9368    /// NO SQL
9369    NoSql,
9370    /// CONTAINS SQL
9371    ContainsSql,
9372    /// READS SQL DATA
9373    ReadsSqlData,
9374    /// MODIFIES SQL DATA
9375    ModifiesSqlData,
9376}
9377
9378/// Types of properties in CREATE FUNCTION for tracking their original order
9379#[derive(
9380    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9381)]
9382#[cfg_attr(feature = "bindings", derive(TS))]
9383pub enum FunctionPropertyKind {
9384    /// SET option
9385    Set,
9386    /// AS body
9387    As,
9388    /// Hive: USING JAR|FILE|ARCHIVE ...
9389    Using,
9390    /// LANGUAGE clause
9391    Language,
9392    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9393    Determinism,
9394    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
9395    NullInput,
9396    /// SECURITY DEFINER/INVOKER
9397    Security,
9398    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
9399    SqlDataAccess,
9400    /// OPTIONS clause (BigQuery)
9401    Options,
9402    /// ENVIRONMENT clause (Databricks)
9403    Environment,
9404    /// HANDLER clause (Databricks)
9405    Handler,
9406    /// Snowflake: RUNTIME_VERSION='...'
9407    RuntimeVersion,
9408    /// Snowflake: PACKAGES=(...)
9409    Packages,
9410    /// PARAMETER STYLE clause (Databricks)
9411    ParameterStyle,
9412}
9413
9414/// Hive CREATE FUNCTION resource in a USING clause
9415#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9416#[cfg_attr(feature = "bindings", derive(TS))]
9417pub struct FunctionUsingResource {
9418    pub kind: String,
9419    pub uri: String,
9420}
9421
9422/// Function parameter
9423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9424#[cfg_attr(feature = "bindings", derive(TS))]
9425pub struct FunctionParameter {
9426    pub name: Option<Identifier>,
9427    pub data_type: DataType,
9428    pub mode: Option<ParameterMode>,
9429    pub default: Option<Expression>,
9430    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
9431    #[serde(default, skip_serializing_if = "Option::is_none")]
9432    pub mode_text: Option<String>,
9433}
9434
9435/// Parameter mode (IN, OUT, INOUT, VARIADIC)
9436#[derive(
9437    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9438)]
9439#[cfg_attr(feature = "bindings", derive(TS))]
9440pub enum ParameterMode {
9441    In,
9442    Out,
9443    InOut,
9444    Variadic,
9445}
9446
9447/// Function body
9448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9449#[cfg_attr(feature = "bindings", derive(TS))]
9450pub enum FunctionBody {
9451    /// AS $$ ... $$ (dollar-quoted)
9452    Block(String),
9453    /// AS 'string' (single-quoted string literal body)
9454    StringLiteral(String),
9455    /// AS 'expression'
9456    Expression(Expression),
9457    /// EXTERNAL NAME 'library'
9458    External(String),
9459    /// RETURN expression
9460    Return(Expression),
9461    /// BEGIN ... END block with parsed statements
9462    Statements(Vec<Expression>),
9463    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
9464    /// Stores (content, optional_tag)
9465    DollarQuoted {
9466        content: String,
9467        tag: Option<String>,
9468    },
9469    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
9470    RawBlock(String),
9471}
9472
9473/// Function security (DEFINER, INVOKER, or NONE)
9474#[derive(
9475    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9476)]
9477#[cfg_attr(feature = "bindings", derive(TS))]
9478pub enum FunctionSecurity {
9479    Definer,
9480    Invoker,
9481    /// StarRocks/MySQL: SECURITY NONE
9482    None,
9483}
9484
9485impl CreateFunction {
9486    pub fn new(name: impl Into<String>) -> Self {
9487        Self {
9488            name: TableRef::new(name),
9489            parameters: Vec::new(),
9490            return_type: None,
9491            body: None,
9492            or_replace: false,
9493            or_alter: false,
9494            if_not_exists: false,
9495            temporary: false,
9496            language: None,
9497            deterministic: None,
9498            returns_null_on_null_input: None,
9499            security: None,
9500            has_parens: true,
9501            sql_data_access: None,
9502            returns_table_body: None,
9503            language_first: false,
9504            set_options: Vec::new(),
9505            strict: false,
9506            options: Vec::new(),
9507            is_table_function: false,
9508            property_order: Vec::new(),
9509            using_resources: Vec::new(),
9510            environment: Vec::new(),
9511            handler: None,
9512            handler_uses_eq: false,
9513            runtime_version: None,
9514            packages: None,
9515            parameter_style: None,
9516        }
9517    }
9518}
9519
9520/// DROP FUNCTION statement
9521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9522#[cfg_attr(feature = "bindings", derive(TS))]
9523pub struct DropFunction {
9524    pub name: TableRef,
9525    pub parameters: Option<Vec<DataType>>,
9526    pub if_exists: bool,
9527    pub cascade: bool,
9528}
9529
9530impl DropFunction {
9531    pub fn new(name: impl Into<String>) -> Self {
9532        Self {
9533            name: TableRef::new(name),
9534            parameters: None,
9535            if_exists: false,
9536            cascade: false,
9537        }
9538    }
9539}
9540
9541/// CREATE PROCEDURE statement
9542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9543#[cfg_attr(feature = "bindings", derive(TS))]
9544pub struct CreateProcedure {
9545    pub name: TableRef,
9546    pub parameters: Vec<FunctionParameter>,
9547    pub body: Option<FunctionBody>,
9548    pub or_replace: bool,
9549    /// TSQL: CREATE OR ALTER
9550    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9551    pub or_alter: bool,
9552    pub if_not_exists: bool,
9553    pub language: Option<String>,
9554    pub security: Option<FunctionSecurity>,
9555    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
9556    #[serde(default)]
9557    pub return_type: Option<DataType>,
9558    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
9559    #[serde(default)]
9560    pub execute_as: Option<String>,
9561    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
9562    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9563    pub with_options: Vec<String>,
9564    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
9565    #[serde(default = "default_true", skip_serializing_if = "is_true")]
9566    pub has_parens: bool,
9567    /// Whether the short form PROC was used (instead of PROCEDURE)
9568    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9569    pub use_proc_keyword: bool,
9570}
9571
9572impl CreateProcedure {
9573    pub fn new(name: impl Into<String>) -> Self {
9574        Self {
9575            name: TableRef::new(name),
9576            parameters: Vec::new(),
9577            body: None,
9578            or_replace: false,
9579            or_alter: false,
9580            if_not_exists: false,
9581            language: None,
9582            security: None,
9583            return_type: None,
9584            execute_as: None,
9585            with_options: Vec::new(),
9586            has_parens: true,
9587            use_proc_keyword: false,
9588        }
9589    }
9590}
9591
9592/// DROP PROCEDURE statement
9593#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9594#[cfg_attr(feature = "bindings", derive(TS))]
9595pub struct DropProcedure {
9596    pub name: TableRef,
9597    pub parameters: Option<Vec<DataType>>,
9598    pub if_exists: bool,
9599    pub cascade: bool,
9600}
9601
9602impl DropProcedure {
9603    pub fn new(name: impl Into<String>) -> Self {
9604        Self {
9605            name: TableRef::new(name),
9606            parameters: None,
9607            if_exists: false,
9608            cascade: false,
9609        }
9610    }
9611}
9612
9613/// Sequence property tag for ordering
9614#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9615#[cfg_attr(feature = "bindings", derive(TS))]
9616pub enum SeqPropKind {
9617    Start,
9618    Increment,
9619    Minvalue,
9620    Maxvalue,
9621    Cache,
9622    NoCache,
9623    Cycle,
9624    NoCycle,
9625    OwnedBy,
9626    Order,
9627    NoOrder,
9628    Comment,
9629    /// SHARING=<value> (Oracle)
9630    Sharing,
9631    /// KEEP (Oracle)
9632    Keep,
9633    /// NOKEEP (Oracle)
9634    NoKeep,
9635    /// SCALE [EXTEND|NOEXTEND] (Oracle)
9636    Scale,
9637    /// NOSCALE (Oracle)
9638    NoScale,
9639    /// SHARD [EXTEND|NOEXTEND] (Oracle)
9640    Shard,
9641    /// NOSHARD (Oracle)
9642    NoShard,
9643    /// SESSION (Oracle)
9644    Session,
9645    /// GLOBAL (Oracle)
9646    Global,
9647    /// NOCACHE (single word, Oracle)
9648    NoCacheWord,
9649    /// NOCYCLE (single word, Oracle)
9650    NoCycleWord,
9651    /// NOMINVALUE (single word, Oracle)
9652    NoMinvalueWord,
9653    /// NOMAXVALUE (single word, Oracle)
9654    NoMaxvalueWord,
9655}
9656
9657/// CREATE SYNONYM statement (TSQL)
9658#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9659#[cfg_attr(feature = "bindings", derive(TS))]
9660pub struct CreateSynonym {
9661    /// The synonym name (can be qualified: schema.synonym_name)
9662    pub name: TableRef,
9663    /// The target object the synonym refers to
9664    pub target: TableRef,
9665}
9666
9667/// CREATE SEQUENCE statement
9668#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9669#[cfg_attr(feature = "bindings", derive(TS))]
9670pub struct CreateSequence {
9671    pub name: TableRef,
9672    pub if_not_exists: bool,
9673    pub temporary: bool,
9674    #[serde(default)]
9675    pub or_replace: bool,
9676    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
9677    #[serde(default, skip_serializing_if = "Option::is_none")]
9678    pub as_type: Option<DataType>,
9679    pub increment: Option<i64>,
9680    pub minvalue: Option<SequenceBound>,
9681    pub maxvalue: Option<SequenceBound>,
9682    pub start: Option<i64>,
9683    pub cache: Option<i64>,
9684    pub cycle: bool,
9685    pub owned_by: Option<TableRef>,
9686    /// Whether OWNED BY NONE was specified
9687    #[serde(default)]
9688    pub owned_by_none: bool,
9689    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
9690    #[serde(default)]
9691    pub order: Option<bool>,
9692    /// Snowflake: COMMENT = 'value'
9693    #[serde(default)]
9694    pub comment: Option<String>,
9695    /// SHARING=<value> (Oracle)
9696    #[serde(default, skip_serializing_if = "Option::is_none")]
9697    pub sharing: Option<String>,
9698    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
9699    #[serde(default, skip_serializing_if = "Option::is_none")]
9700    pub scale_modifier: Option<String>,
9701    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
9702    #[serde(default, skip_serializing_if = "Option::is_none")]
9703    pub shard_modifier: Option<String>,
9704    /// Tracks the order in which properties appeared in the source
9705    #[serde(default)]
9706    pub property_order: Vec<SeqPropKind>,
9707}
9708
9709/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
9710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9711#[cfg_attr(feature = "bindings", derive(TS))]
9712pub enum SequenceBound {
9713    Value(i64),
9714    None,
9715}
9716
9717impl CreateSequence {
9718    pub fn new(name: impl Into<String>) -> Self {
9719        Self {
9720            name: TableRef::new(name),
9721            if_not_exists: false,
9722            temporary: false,
9723            or_replace: false,
9724            as_type: None,
9725            increment: None,
9726            minvalue: None,
9727            maxvalue: None,
9728            start: None,
9729            cache: None,
9730            cycle: false,
9731            owned_by: None,
9732            owned_by_none: false,
9733            order: None,
9734            comment: None,
9735            sharing: None,
9736            scale_modifier: None,
9737            shard_modifier: None,
9738            property_order: Vec::new(),
9739        }
9740    }
9741}
9742
9743/// DROP SEQUENCE statement
9744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9745#[cfg_attr(feature = "bindings", derive(TS))]
9746pub struct DropSequence {
9747    pub name: TableRef,
9748    pub if_exists: bool,
9749    pub cascade: bool,
9750}
9751
9752impl DropSequence {
9753    pub fn new(name: impl Into<String>) -> Self {
9754        Self {
9755            name: TableRef::new(name),
9756            if_exists: false,
9757            cascade: false,
9758        }
9759    }
9760}
9761
9762/// ALTER SEQUENCE statement
9763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9764#[cfg_attr(feature = "bindings", derive(TS))]
9765pub struct AlterSequence {
9766    pub name: TableRef,
9767    pub if_exists: bool,
9768    pub increment: Option<i64>,
9769    pub minvalue: Option<SequenceBound>,
9770    pub maxvalue: Option<SequenceBound>,
9771    pub start: Option<i64>,
9772    pub restart: Option<Option<i64>>,
9773    pub cache: Option<i64>,
9774    pub cycle: Option<bool>,
9775    pub owned_by: Option<Option<TableRef>>,
9776}
9777
9778impl AlterSequence {
9779    pub fn new(name: impl Into<String>) -> Self {
9780        Self {
9781            name: TableRef::new(name),
9782            if_exists: false,
9783            increment: None,
9784            minvalue: None,
9785            maxvalue: None,
9786            start: None,
9787            restart: None,
9788            cache: None,
9789            cycle: None,
9790            owned_by: None,
9791        }
9792    }
9793}
9794
9795/// CREATE TRIGGER statement
9796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9797#[cfg_attr(feature = "bindings", derive(TS))]
9798pub struct CreateTrigger {
9799    pub name: Identifier,
9800    pub table: TableRef,
9801    pub timing: TriggerTiming,
9802    pub events: Vec<TriggerEvent>,
9803    #[serde(default, skip_serializing_if = "Option::is_none")]
9804    pub for_each: Option<TriggerForEach>,
9805    pub when: Option<Expression>,
9806    /// Whether the WHEN clause was parenthesized in the original SQL
9807    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9808    pub when_paren: bool,
9809    pub body: TriggerBody,
9810    pub or_replace: bool,
9811    /// TSQL: CREATE OR ALTER
9812    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9813    pub or_alter: bool,
9814    pub constraint: bool,
9815    pub deferrable: Option<bool>,
9816    pub initially_deferred: Option<bool>,
9817    pub referencing: Option<TriggerReferencing>,
9818}
9819
9820/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
9821#[derive(
9822    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9823)]
9824#[cfg_attr(feature = "bindings", derive(TS))]
9825pub enum TriggerTiming {
9826    Before,
9827    After,
9828    InsteadOf,
9829}
9830
9831/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
9832#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9833#[cfg_attr(feature = "bindings", derive(TS))]
9834pub enum TriggerEvent {
9835    Insert,
9836    Update(Option<Vec<Identifier>>),
9837    Delete,
9838    Truncate,
9839}
9840
9841/// Trigger FOR EACH clause
9842#[derive(
9843    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9844)]
9845#[cfg_attr(feature = "bindings", derive(TS))]
9846pub enum TriggerForEach {
9847    Row,
9848    Statement,
9849}
9850
9851/// Trigger body
9852#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9853#[cfg_attr(feature = "bindings", derive(TS))]
9854pub enum TriggerBody {
9855    /// EXECUTE FUNCTION/PROCEDURE name(args)
9856    Execute {
9857        function: TableRef,
9858        args: Vec<Expression>,
9859    },
9860    /// BEGIN ... END block
9861    Block(String),
9862}
9863
9864/// Trigger REFERENCING clause
9865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9866#[cfg_attr(feature = "bindings", derive(TS))]
9867pub struct TriggerReferencing {
9868    pub old_table: Option<Identifier>,
9869    pub new_table: Option<Identifier>,
9870    pub old_row: Option<Identifier>,
9871    pub new_row: Option<Identifier>,
9872}
9873
9874impl CreateTrigger {
9875    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
9876        Self {
9877            name: Identifier::new(name),
9878            table: TableRef::new(table),
9879            timing: TriggerTiming::Before,
9880            events: Vec::new(),
9881            for_each: Some(TriggerForEach::Row),
9882            when: None,
9883            when_paren: false,
9884            body: TriggerBody::Execute {
9885                function: TableRef::new(""),
9886                args: Vec::new(),
9887            },
9888            or_replace: false,
9889            or_alter: false,
9890            constraint: false,
9891            deferrable: None,
9892            initially_deferred: None,
9893            referencing: None,
9894        }
9895    }
9896}
9897
9898/// DROP TRIGGER statement
9899#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9900#[cfg_attr(feature = "bindings", derive(TS))]
9901pub struct DropTrigger {
9902    pub name: Identifier,
9903    pub table: Option<TableRef>,
9904    pub if_exists: bool,
9905    pub cascade: bool,
9906}
9907
9908impl DropTrigger {
9909    pub fn new(name: impl Into<String>) -> Self {
9910        Self {
9911            name: Identifier::new(name),
9912            table: None,
9913            if_exists: false,
9914            cascade: false,
9915        }
9916    }
9917}
9918
9919/// CREATE TYPE statement
9920#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9921#[cfg_attr(feature = "bindings", derive(TS))]
9922pub struct CreateType {
9923    pub name: TableRef,
9924    pub definition: TypeDefinition,
9925    pub if_not_exists: bool,
9926}
9927
9928/// Type definition
9929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9930#[cfg_attr(feature = "bindings", derive(TS))]
9931pub enum TypeDefinition {
9932    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
9933    Enum(Vec<String>),
9934    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
9935    Composite(Vec<TypeAttribute>),
9936    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
9937    Range {
9938        subtype: DataType,
9939        subtype_diff: Option<String>,
9940        canonical: Option<String>,
9941    },
9942    /// Base type (for advanced usage)
9943    Base {
9944        input: String,
9945        output: String,
9946        internallength: Option<i32>,
9947    },
9948    /// Domain type
9949    Domain {
9950        base_type: DataType,
9951        default: Option<Expression>,
9952        constraints: Vec<DomainConstraint>,
9953    },
9954}
9955
9956/// Type attribute for composite types
9957#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9958#[cfg_attr(feature = "bindings", derive(TS))]
9959pub struct TypeAttribute {
9960    pub name: Identifier,
9961    pub data_type: DataType,
9962    pub collate: Option<Identifier>,
9963}
9964
9965/// Domain constraint
9966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9967#[cfg_attr(feature = "bindings", derive(TS))]
9968pub struct DomainConstraint {
9969    pub name: Option<Identifier>,
9970    pub check: Expression,
9971}
9972
9973impl CreateType {
9974    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
9975        Self {
9976            name: TableRef::new(name),
9977            definition: TypeDefinition::Enum(values),
9978            if_not_exists: false,
9979        }
9980    }
9981
9982    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
9983        Self {
9984            name: TableRef::new(name),
9985            definition: TypeDefinition::Composite(attributes),
9986            if_not_exists: false,
9987        }
9988    }
9989}
9990
9991/// DROP TYPE statement
9992#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9993#[cfg_attr(feature = "bindings", derive(TS))]
9994pub struct DropType {
9995    pub name: TableRef,
9996    pub if_exists: bool,
9997    pub cascade: bool,
9998}
9999
10000impl DropType {
10001    pub fn new(name: impl Into<String>) -> Self {
10002        Self {
10003            name: TableRef::new(name),
10004            if_exists: false,
10005            cascade: false,
10006        }
10007    }
10008}
10009
10010/// DESCRIBE statement - shows table structure or query plan
10011#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10012#[cfg_attr(feature = "bindings", derive(TS))]
10013pub struct Describe {
10014    /// The target to describe (table name or query)
10015    pub target: Expression,
10016    /// EXTENDED format
10017    pub extended: bool,
10018    /// FORMATTED format
10019    pub formatted: bool,
10020    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10021    #[serde(default)]
10022    pub kind: Option<String>,
10023    /// Properties like type=stage
10024    #[serde(default)]
10025    pub properties: Vec<(String, String)>,
10026    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10027    #[serde(default, skip_serializing_if = "Option::is_none")]
10028    pub style: Option<String>,
10029    /// Partition specification for DESCRIBE PARTITION
10030    #[serde(default)]
10031    pub partition: Option<Box<Expression>>,
10032    /// Leading comments before the statement
10033    #[serde(default)]
10034    pub leading_comments: Vec<String>,
10035    /// AS JSON suffix (Databricks)
10036    #[serde(default)]
10037    pub as_json: bool,
10038    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10039    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10040    pub params: Vec<String>,
10041}
10042
10043impl Describe {
10044    pub fn new(target: Expression) -> Self {
10045        Self {
10046            target,
10047            extended: false,
10048            formatted: false,
10049            kind: None,
10050            properties: Vec::new(),
10051            style: None,
10052            partition: None,
10053            leading_comments: Vec::new(),
10054            as_json: false,
10055            params: Vec::new(),
10056        }
10057    }
10058}
10059
10060/// SHOW statement - displays database objects
10061#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10062#[cfg_attr(feature = "bindings", derive(TS))]
10063pub struct Show {
10064    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10065    pub this: String,
10066    /// Whether TERSE was specified
10067    #[serde(default)]
10068    pub terse: bool,
10069    /// Whether HISTORY was specified
10070    #[serde(default)]
10071    pub history: bool,
10072    /// LIKE pattern
10073    pub like: Option<Expression>,
10074    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10075    pub scope_kind: Option<String>,
10076    /// IN scope object
10077    pub scope: Option<Expression>,
10078    /// STARTS WITH pattern
10079    pub starts_with: Option<Expression>,
10080    /// LIMIT clause
10081    pub limit: Option<Box<Limit>>,
10082    /// FROM clause (for specific object)
10083    pub from: Option<Expression>,
10084    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10085    #[serde(default, skip_serializing_if = "Option::is_none")]
10086    pub where_clause: Option<Expression>,
10087    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10088    #[serde(default, skip_serializing_if = "Option::is_none")]
10089    pub for_target: Option<Expression>,
10090    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10091    #[serde(default, skip_serializing_if = "Option::is_none")]
10092    pub db: Option<Expression>,
10093    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10094    #[serde(default, skip_serializing_if = "Option::is_none")]
10095    pub target: Option<Expression>,
10096    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10097    #[serde(default, skip_serializing_if = "Option::is_none")]
10098    pub mutex: Option<bool>,
10099    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10100    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10101    pub privileges: Vec<String>,
10102}
10103
10104impl Show {
10105    pub fn new(this: impl Into<String>) -> Self {
10106        Self {
10107            this: this.into(),
10108            terse: false,
10109            history: false,
10110            like: None,
10111            scope_kind: None,
10112            scope: None,
10113            starts_with: None,
10114            limit: None,
10115            from: None,
10116            where_clause: None,
10117            for_target: None,
10118            db: None,
10119            target: None,
10120            mutex: None,
10121            privileges: Vec::new(),
10122        }
10123    }
10124}
10125
10126/// Represent an explicit parenthesized expression for grouping precedence.
10127///
10128/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10129/// correctly instead of being flattened to `a + b * c`.
10130#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10131#[cfg_attr(feature = "bindings", derive(TS))]
10132pub struct Paren {
10133    /// The inner expression wrapped by parentheses.
10134    pub this: Expression,
10135    #[serde(default)]
10136    pub trailing_comments: Vec<String>,
10137}
10138
10139/// Expression annotated with trailing comments (for round-trip preservation)
10140#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10141#[cfg_attr(feature = "bindings", derive(TS))]
10142pub struct Annotated {
10143    pub this: Expression,
10144    pub trailing_comments: Vec<String>,
10145}
10146
10147// === BATCH GENERATED STRUCT DEFINITIONS ===
10148// Generated from Python sqlglot expressions.py
10149
10150/// Refresh
10151#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10152#[cfg_attr(feature = "bindings", derive(TS))]
10153pub struct Refresh {
10154    pub this: Box<Expression>,
10155    pub kind: String,
10156}
10157
10158/// LockingStatement
10159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10160#[cfg_attr(feature = "bindings", derive(TS))]
10161pub struct LockingStatement {
10162    pub this: Box<Expression>,
10163    pub expression: Box<Expression>,
10164}
10165
10166/// SequenceProperties
10167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10168#[cfg_attr(feature = "bindings", derive(TS))]
10169pub struct SequenceProperties {
10170    #[serde(default)]
10171    pub increment: Option<Box<Expression>>,
10172    #[serde(default)]
10173    pub minvalue: Option<Box<Expression>>,
10174    #[serde(default)]
10175    pub maxvalue: Option<Box<Expression>>,
10176    #[serde(default)]
10177    pub cache: Option<Box<Expression>>,
10178    #[serde(default)]
10179    pub start: Option<Box<Expression>>,
10180    #[serde(default)]
10181    pub owned: Option<Box<Expression>>,
10182    #[serde(default)]
10183    pub options: Vec<Expression>,
10184}
10185
10186/// TruncateTable
10187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10188#[cfg_attr(feature = "bindings", derive(TS))]
10189pub struct TruncateTable {
10190    #[serde(default)]
10191    pub expressions: Vec<Expression>,
10192    #[serde(default)]
10193    pub is_database: Option<Box<Expression>>,
10194    #[serde(default)]
10195    pub exists: bool,
10196    #[serde(default)]
10197    pub only: Option<Box<Expression>>,
10198    #[serde(default)]
10199    pub cluster: Option<Box<Expression>>,
10200    #[serde(default)]
10201    pub identity: Option<Box<Expression>>,
10202    #[serde(default)]
10203    pub option: Option<Box<Expression>>,
10204    #[serde(default)]
10205    pub partition: Option<Box<Expression>>,
10206}
10207
10208/// Clone
10209#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10210#[cfg_attr(feature = "bindings", derive(TS))]
10211pub struct Clone {
10212    pub this: Box<Expression>,
10213    #[serde(default)]
10214    pub shallow: Option<Box<Expression>>,
10215    #[serde(default)]
10216    pub copy: Option<Box<Expression>>,
10217}
10218
10219/// Attach
10220#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10221#[cfg_attr(feature = "bindings", derive(TS))]
10222pub struct Attach {
10223    pub this: Box<Expression>,
10224    #[serde(default)]
10225    pub exists: bool,
10226    #[serde(default)]
10227    pub expressions: Vec<Expression>,
10228}
10229
10230/// Detach
10231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10232#[cfg_attr(feature = "bindings", derive(TS))]
10233pub struct Detach {
10234    pub this: Box<Expression>,
10235    #[serde(default)]
10236    pub exists: bool,
10237}
10238
10239/// Install
10240#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10241#[cfg_attr(feature = "bindings", derive(TS))]
10242pub struct Install {
10243    pub this: Box<Expression>,
10244    #[serde(default)]
10245    pub from_: Option<Box<Expression>>,
10246    #[serde(default)]
10247    pub force: Option<Box<Expression>>,
10248}
10249
10250/// Summarize
10251#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10252#[cfg_attr(feature = "bindings", derive(TS))]
10253pub struct Summarize {
10254    pub this: Box<Expression>,
10255    #[serde(default)]
10256    pub table: Option<Box<Expression>>,
10257}
10258
10259/// Declare
10260#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10261#[cfg_attr(feature = "bindings", derive(TS))]
10262pub struct Declare {
10263    #[serde(default)]
10264    pub expressions: Vec<Expression>,
10265    #[serde(default)]
10266    pub replace: bool,
10267}
10268
10269/// DeclareItem
10270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10271#[cfg_attr(feature = "bindings", derive(TS))]
10272pub struct DeclareItem {
10273    pub this: Box<Expression>,
10274    #[serde(default)]
10275    pub kind: Option<String>,
10276    #[serde(default)]
10277    pub default: Option<Box<Expression>>,
10278    #[serde(default)]
10279    pub has_as: bool,
10280    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10281    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10282    pub additional_names: Vec<Expression>,
10283}
10284
10285/// Set
10286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10287#[cfg_attr(feature = "bindings", derive(TS))]
10288pub struct Set {
10289    #[serde(default)]
10290    pub expressions: Vec<Expression>,
10291    #[serde(default)]
10292    pub unset: Option<Box<Expression>>,
10293    #[serde(default)]
10294    pub tag: Option<Box<Expression>>,
10295}
10296
10297/// Heredoc
10298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10299#[cfg_attr(feature = "bindings", derive(TS))]
10300pub struct Heredoc {
10301    pub this: Box<Expression>,
10302    #[serde(default)]
10303    pub tag: Option<Box<Expression>>,
10304}
10305
10306/// QueryBand
10307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10308#[cfg_attr(feature = "bindings", derive(TS))]
10309pub struct QueryBand {
10310    pub this: Box<Expression>,
10311    #[serde(default)]
10312    pub scope: Option<Box<Expression>>,
10313    #[serde(default)]
10314    pub update: Option<Box<Expression>>,
10315}
10316
10317/// UserDefinedFunction
10318#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10319#[cfg_attr(feature = "bindings", derive(TS))]
10320pub struct UserDefinedFunction {
10321    pub this: Box<Expression>,
10322    #[serde(default)]
10323    pub expressions: Vec<Expression>,
10324    #[serde(default)]
10325    pub wrapped: Option<Box<Expression>>,
10326}
10327
10328/// RecursiveWithSearch
10329#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10330#[cfg_attr(feature = "bindings", derive(TS))]
10331pub struct RecursiveWithSearch {
10332    pub kind: String,
10333    pub this: Box<Expression>,
10334    pub expression: Box<Expression>,
10335    #[serde(default)]
10336    pub using: Option<Box<Expression>>,
10337}
10338
10339/// ProjectionDef
10340#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10341#[cfg_attr(feature = "bindings", derive(TS))]
10342pub struct ProjectionDef {
10343    pub this: Box<Expression>,
10344    pub expression: Box<Expression>,
10345}
10346
10347/// TableAlias
10348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10349#[cfg_attr(feature = "bindings", derive(TS))]
10350pub struct TableAlias {
10351    #[serde(default)]
10352    pub this: Option<Box<Expression>>,
10353    #[serde(default)]
10354    pub columns: Vec<Expression>,
10355}
10356
10357/// ByteString
10358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10359#[cfg_attr(feature = "bindings", derive(TS))]
10360pub struct ByteString {
10361    pub this: Box<Expression>,
10362    #[serde(default)]
10363    pub is_bytes: Option<Box<Expression>>,
10364}
10365
10366/// HexStringExpr - Hex string expression (not literal)
10367/// BigQuery: converts to FROM_HEX(this)
10368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10369#[cfg_attr(feature = "bindings", derive(TS))]
10370pub struct HexStringExpr {
10371    pub this: Box<Expression>,
10372    #[serde(default)]
10373    pub is_integer: Option<bool>,
10374}
10375
10376/// UnicodeString
10377#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10378#[cfg_attr(feature = "bindings", derive(TS))]
10379pub struct UnicodeString {
10380    pub this: Box<Expression>,
10381    #[serde(default)]
10382    pub escape: Option<Box<Expression>>,
10383}
10384
10385/// AlterColumn
10386#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10387#[cfg_attr(feature = "bindings", derive(TS))]
10388pub struct AlterColumn {
10389    pub this: Box<Expression>,
10390    #[serde(default)]
10391    pub dtype: Option<Box<Expression>>,
10392    #[serde(default)]
10393    pub collate: Option<Box<Expression>>,
10394    #[serde(default)]
10395    pub using: Option<Box<Expression>>,
10396    #[serde(default)]
10397    pub default: Option<Box<Expression>>,
10398    #[serde(default)]
10399    pub drop: Option<Box<Expression>>,
10400    #[serde(default)]
10401    pub comment: Option<Box<Expression>>,
10402    #[serde(default)]
10403    pub allow_null: Option<Box<Expression>>,
10404    #[serde(default)]
10405    pub visible: Option<Box<Expression>>,
10406    #[serde(default)]
10407    pub rename_to: Option<Box<Expression>>,
10408}
10409
10410/// AlterSortKey
10411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10412#[cfg_attr(feature = "bindings", derive(TS))]
10413pub struct AlterSortKey {
10414    #[serde(default)]
10415    pub this: Option<Box<Expression>>,
10416    #[serde(default)]
10417    pub expressions: Vec<Expression>,
10418    #[serde(default)]
10419    pub compound: Option<Box<Expression>>,
10420}
10421
10422/// AlterSet
10423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10424#[cfg_attr(feature = "bindings", derive(TS))]
10425pub struct AlterSet {
10426    #[serde(default)]
10427    pub expressions: Vec<Expression>,
10428    #[serde(default)]
10429    pub option: Option<Box<Expression>>,
10430    #[serde(default)]
10431    pub tablespace: Option<Box<Expression>>,
10432    #[serde(default)]
10433    pub access_method: Option<Box<Expression>>,
10434    #[serde(default)]
10435    pub file_format: Option<Box<Expression>>,
10436    #[serde(default)]
10437    pub copy_options: Option<Box<Expression>>,
10438    #[serde(default)]
10439    pub tag: Option<Box<Expression>>,
10440    #[serde(default)]
10441    pub location: Option<Box<Expression>>,
10442    #[serde(default)]
10443    pub serde: Option<Box<Expression>>,
10444}
10445
10446/// RenameColumn
10447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10448#[cfg_attr(feature = "bindings", derive(TS))]
10449pub struct RenameColumn {
10450    pub this: Box<Expression>,
10451    #[serde(default)]
10452    pub to: Option<Box<Expression>>,
10453    #[serde(default)]
10454    pub exists: bool,
10455}
10456
10457/// Comprehension
10458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10459#[cfg_attr(feature = "bindings", derive(TS))]
10460pub struct Comprehension {
10461    pub this: Box<Expression>,
10462    pub expression: Box<Expression>,
10463    #[serde(default)]
10464    pub position: Option<Box<Expression>>,
10465    #[serde(default)]
10466    pub iterator: Option<Box<Expression>>,
10467    #[serde(default)]
10468    pub condition: Option<Box<Expression>>,
10469}
10470
10471/// MergeTreeTTLAction
10472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10473#[cfg_attr(feature = "bindings", derive(TS))]
10474pub struct MergeTreeTTLAction {
10475    pub this: Box<Expression>,
10476    #[serde(default)]
10477    pub delete: Option<Box<Expression>>,
10478    #[serde(default)]
10479    pub recompress: Option<Box<Expression>>,
10480    #[serde(default)]
10481    pub to_disk: Option<Box<Expression>>,
10482    #[serde(default)]
10483    pub to_volume: Option<Box<Expression>>,
10484}
10485
10486/// MergeTreeTTL
10487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10488#[cfg_attr(feature = "bindings", derive(TS))]
10489pub struct MergeTreeTTL {
10490    #[serde(default)]
10491    pub expressions: Vec<Expression>,
10492    #[serde(default)]
10493    pub where_: Option<Box<Expression>>,
10494    #[serde(default)]
10495    pub group: Option<Box<Expression>>,
10496    #[serde(default)]
10497    pub aggregates: Option<Box<Expression>>,
10498}
10499
10500/// IndexConstraintOption
10501#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10502#[cfg_attr(feature = "bindings", derive(TS))]
10503pub struct IndexConstraintOption {
10504    #[serde(default)]
10505    pub key_block_size: Option<Box<Expression>>,
10506    #[serde(default)]
10507    pub using: Option<Box<Expression>>,
10508    #[serde(default)]
10509    pub parser: Option<Box<Expression>>,
10510    #[serde(default)]
10511    pub comment: Option<Box<Expression>>,
10512    #[serde(default)]
10513    pub visible: Option<Box<Expression>>,
10514    #[serde(default)]
10515    pub engine_attr: Option<Box<Expression>>,
10516    #[serde(default)]
10517    pub secondary_engine_attr: Option<Box<Expression>>,
10518}
10519
10520/// PeriodForSystemTimeConstraint
10521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10522#[cfg_attr(feature = "bindings", derive(TS))]
10523pub struct PeriodForSystemTimeConstraint {
10524    pub this: Box<Expression>,
10525    pub expression: Box<Expression>,
10526}
10527
10528/// CaseSpecificColumnConstraint
10529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10530#[cfg_attr(feature = "bindings", derive(TS))]
10531pub struct CaseSpecificColumnConstraint {
10532    #[serde(default)]
10533    pub not_: Option<Box<Expression>>,
10534}
10535
10536/// CharacterSetColumnConstraint
10537#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10538#[cfg_attr(feature = "bindings", derive(TS))]
10539pub struct CharacterSetColumnConstraint {
10540    pub this: Box<Expression>,
10541}
10542
10543/// CheckColumnConstraint
10544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10545#[cfg_attr(feature = "bindings", derive(TS))]
10546pub struct CheckColumnConstraint {
10547    pub this: Box<Expression>,
10548    #[serde(default)]
10549    pub enforced: Option<Box<Expression>>,
10550}
10551
10552/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
10553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10554#[cfg_attr(feature = "bindings", derive(TS))]
10555pub struct AssumeColumnConstraint {
10556    pub this: Box<Expression>,
10557}
10558
10559/// CompressColumnConstraint
10560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10561#[cfg_attr(feature = "bindings", derive(TS))]
10562pub struct CompressColumnConstraint {
10563    #[serde(default)]
10564    pub this: Option<Box<Expression>>,
10565}
10566
10567/// DateFormatColumnConstraint
10568#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10569#[cfg_attr(feature = "bindings", derive(TS))]
10570pub struct DateFormatColumnConstraint {
10571    pub this: Box<Expression>,
10572}
10573
10574/// EphemeralColumnConstraint
10575#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10576#[cfg_attr(feature = "bindings", derive(TS))]
10577pub struct EphemeralColumnConstraint {
10578    #[serde(default)]
10579    pub this: Option<Box<Expression>>,
10580}
10581
10582/// WithOperator
10583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10584#[cfg_attr(feature = "bindings", derive(TS))]
10585pub struct WithOperator {
10586    pub this: Box<Expression>,
10587    pub op: String,
10588}
10589
10590/// GeneratedAsIdentityColumnConstraint
10591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10592#[cfg_attr(feature = "bindings", derive(TS))]
10593pub struct GeneratedAsIdentityColumnConstraint {
10594    #[serde(default)]
10595    pub this: Option<Box<Expression>>,
10596    #[serde(default)]
10597    pub expression: Option<Box<Expression>>,
10598    #[serde(default)]
10599    pub on_null: Option<Box<Expression>>,
10600    #[serde(default)]
10601    pub start: Option<Box<Expression>>,
10602    #[serde(default)]
10603    pub increment: Option<Box<Expression>>,
10604    #[serde(default)]
10605    pub minvalue: Option<Box<Expression>>,
10606    #[serde(default)]
10607    pub maxvalue: Option<Box<Expression>>,
10608    #[serde(default)]
10609    pub cycle: Option<Box<Expression>>,
10610    #[serde(default)]
10611    pub order: Option<Box<Expression>>,
10612}
10613
10614/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
10615/// TSQL: outputs "IDENTITY"
10616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10617#[cfg_attr(feature = "bindings", derive(TS))]
10618pub struct AutoIncrementColumnConstraint;
10619
10620/// CommentColumnConstraint - Column comment marker
10621#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10622#[cfg_attr(feature = "bindings", derive(TS))]
10623pub struct CommentColumnConstraint;
10624
10625/// GeneratedAsRowColumnConstraint
10626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10627#[cfg_attr(feature = "bindings", derive(TS))]
10628pub struct GeneratedAsRowColumnConstraint {
10629    #[serde(default)]
10630    pub start: Option<Box<Expression>>,
10631    #[serde(default)]
10632    pub hidden: Option<Box<Expression>>,
10633}
10634
10635/// IndexColumnConstraint
10636#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10637#[cfg_attr(feature = "bindings", derive(TS))]
10638pub struct IndexColumnConstraint {
10639    #[serde(default)]
10640    pub this: Option<Box<Expression>>,
10641    #[serde(default)]
10642    pub expressions: Vec<Expression>,
10643    #[serde(default)]
10644    pub kind: Option<String>,
10645    #[serde(default)]
10646    pub index_type: Option<Box<Expression>>,
10647    #[serde(default)]
10648    pub options: Vec<Expression>,
10649    #[serde(default)]
10650    pub expression: Option<Box<Expression>>,
10651    #[serde(default)]
10652    pub granularity: Option<Box<Expression>>,
10653}
10654
10655/// MaskingPolicyColumnConstraint
10656#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10657#[cfg_attr(feature = "bindings", derive(TS))]
10658pub struct MaskingPolicyColumnConstraint {
10659    pub this: Box<Expression>,
10660    #[serde(default)]
10661    pub expressions: Vec<Expression>,
10662}
10663
10664/// NotNullColumnConstraint
10665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10666#[cfg_attr(feature = "bindings", derive(TS))]
10667pub struct NotNullColumnConstraint {
10668    #[serde(default)]
10669    pub allow_null: Option<Box<Expression>>,
10670}
10671
10672/// DefaultColumnConstraint - DEFAULT value for a column
10673#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10674#[cfg_attr(feature = "bindings", derive(TS))]
10675pub struct DefaultColumnConstraint {
10676    pub this: Box<Expression>,
10677    /// TSQL: DEFAULT value FOR column (table-level default constraint)
10678    #[serde(default, skip_serializing_if = "Option::is_none")]
10679    pub for_column: Option<Identifier>,
10680}
10681
10682/// PrimaryKeyColumnConstraint
10683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10684#[cfg_attr(feature = "bindings", derive(TS))]
10685pub struct PrimaryKeyColumnConstraint {
10686    #[serde(default)]
10687    pub desc: Option<Box<Expression>>,
10688    #[serde(default)]
10689    pub options: Vec<Expression>,
10690}
10691
10692/// UniqueColumnConstraint
10693#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10694#[cfg_attr(feature = "bindings", derive(TS))]
10695pub struct UniqueColumnConstraint {
10696    #[serde(default)]
10697    pub this: Option<Box<Expression>>,
10698    #[serde(default)]
10699    pub index_type: Option<Box<Expression>>,
10700    #[serde(default)]
10701    pub on_conflict: Option<Box<Expression>>,
10702    #[serde(default)]
10703    pub nulls: Option<Box<Expression>>,
10704    #[serde(default)]
10705    pub options: Vec<Expression>,
10706}
10707
10708/// WatermarkColumnConstraint
10709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10710#[cfg_attr(feature = "bindings", derive(TS))]
10711pub struct WatermarkColumnConstraint {
10712    pub this: Box<Expression>,
10713    pub expression: Box<Expression>,
10714}
10715
10716/// ComputedColumnConstraint
10717#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10718#[cfg_attr(feature = "bindings", derive(TS))]
10719pub struct ComputedColumnConstraint {
10720    pub this: Box<Expression>,
10721    #[serde(default)]
10722    pub persisted: Option<Box<Expression>>,
10723    #[serde(default)]
10724    pub not_null: Option<Box<Expression>>,
10725    #[serde(default)]
10726    pub data_type: Option<Box<Expression>>,
10727}
10728
10729/// InOutColumnConstraint
10730#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10731#[cfg_attr(feature = "bindings", derive(TS))]
10732pub struct InOutColumnConstraint {
10733    #[serde(default)]
10734    pub input_: Option<Box<Expression>>,
10735    #[serde(default)]
10736    pub output: Option<Box<Expression>>,
10737}
10738
10739/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
10740#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10741#[cfg_attr(feature = "bindings", derive(TS))]
10742pub struct PathColumnConstraint {
10743    pub this: Box<Expression>,
10744}
10745
10746/// Constraint
10747#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10748#[cfg_attr(feature = "bindings", derive(TS))]
10749pub struct Constraint {
10750    pub this: Box<Expression>,
10751    #[serde(default)]
10752    pub expressions: Vec<Expression>,
10753}
10754
10755/// Export
10756#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10757#[cfg_attr(feature = "bindings", derive(TS))]
10758pub struct Export {
10759    pub this: Box<Expression>,
10760    #[serde(default)]
10761    pub connection: Option<Box<Expression>>,
10762    #[serde(default)]
10763    pub options: Vec<Expression>,
10764}
10765
10766/// Filter
10767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10768#[cfg_attr(feature = "bindings", derive(TS))]
10769pub struct Filter {
10770    pub this: Box<Expression>,
10771    pub expression: Box<Expression>,
10772}
10773
10774/// Changes
10775#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10776#[cfg_attr(feature = "bindings", derive(TS))]
10777pub struct Changes {
10778    #[serde(default)]
10779    pub information: Option<Box<Expression>>,
10780    #[serde(default)]
10781    pub at_before: Option<Box<Expression>>,
10782    #[serde(default)]
10783    pub end: Option<Box<Expression>>,
10784}
10785
10786/// Directory
10787#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10788#[cfg_attr(feature = "bindings", derive(TS))]
10789pub struct Directory {
10790    pub this: Box<Expression>,
10791    #[serde(default)]
10792    pub local: Option<Box<Expression>>,
10793    #[serde(default)]
10794    pub row_format: Option<Box<Expression>>,
10795}
10796
10797/// ForeignKey
10798#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10799#[cfg_attr(feature = "bindings", derive(TS))]
10800pub struct ForeignKey {
10801    #[serde(default)]
10802    pub expressions: Vec<Expression>,
10803    #[serde(default)]
10804    pub reference: Option<Box<Expression>>,
10805    #[serde(default)]
10806    pub delete: Option<Box<Expression>>,
10807    #[serde(default)]
10808    pub update: Option<Box<Expression>>,
10809    #[serde(default)]
10810    pub options: Vec<Expression>,
10811}
10812
10813/// ColumnPrefix
10814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10815#[cfg_attr(feature = "bindings", derive(TS))]
10816pub struct ColumnPrefix {
10817    pub this: Box<Expression>,
10818    pub expression: Box<Expression>,
10819}
10820
10821/// PrimaryKey
10822#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10823#[cfg_attr(feature = "bindings", derive(TS))]
10824pub struct PrimaryKey {
10825    #[serde(default)]
10826    pub this: Option<Box<Expression>>,
10827    #[serde(default)]
10828    pub expressions: Vec<Expression>,
10829    #[serde(default)]
10830    pub options: Vec<Expression>,
10831    #[serde(default)]
10832    pub include: Option<Box<Expression>>,
10833}
10834
10835/// Into
10836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10837#[cfg_attr(feature = "bindings", derive(TS))]
10838pub struct IntoClause {
10839    #[serde(default)]
10840    pub this: Option<Box<Expression>>,
10841    #[serde(default)]
10842    pub temporary: bool,
10843    #[serde(default)]
10844    pub unlogged: Option<Box<Expression>>,
10845    #[serde(default)]
10846    pub bulk_collect: Option<Box<Expression>>,
10847    #[serde(default)]
10848    pub expressions: Vec<Expression>,
10849}
10850
10851/// JoinHint
10852#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10853#[cfg_attr(feature = "bindings", derive(TS))]
10854pub struct JoinHint {
10855    pub this: Box<Expression>,
10856    #[serde(default)]
10857    pub expressions: Vec<Expression>,
10858}
10859
10860/// Opclass
10861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10862#[cfg_attr(feature = "bindings", derive(TS))]
10863pub struct Opclass {
10864    pub this: Box<Expression>,
10865    pub expression: Box<Expression>,
10866}
10867
10868/// Index
10869#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10870#[cfg_attr(feature = "bindings", derive(TS))]
10871pub struct Index {
10872    #[serde(default)]
10873    pub this: Option<Box<Expression>>,
10874    #[serde(default)]
10875    pub table: Option<Box<Expression>>,
10876    #[serde(default)]
10877    pub unique: bool,
10878    #[serde(default)]
10879    pub primary: Option<Box<Expression>>,
10880    #[serde(default)]
10881    pub amp: Option<Box<Expression>>,
10882    #[serde(default)]
10883    pub params: Vec<Expression>,
10884}
10885
10886/// IndexParameters
10887#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10888#[cfg_attr(feature = "bindings", derive(TS))]
10889pub struct IndexParameters {
10890    #[serde(default)]
10891    pub using: Option<Box<Expression>>,
10892    #[serde(default)]
10893    pub include: Option<Box<Expression>>,
10894    #[serde(default)]
10895    pub columns: Vec<Expression>,
10896    #[serde(default)]
10897    pub with_storage: Option<Box<Expression>>,
10898    #[serde(default)]
10899    pub partition_by: Option<Box<Expression>>,
10900    #[serde(default)]
10901    pub tablespace: Option<Box<Expression>>,
10902    #[serde(default)]
10903    pub where_: Option<Box<Expression>>,
10904    #[serde(default)]
10905    pub on: Option<Box<Expression>>,
10906}
10907
10908/// ConditionalInsert
10909#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10910#[cfg_attr(feature = "bindings", derive(TS))]
10911pub struct ConditionalInsert {
10912    pub this: Box<Expression>,
10913    #[serde(default)]
10914    pub expression: Option<Box<Expression>>,
10915    #[serde(default)]
10916    pub else_: Option<Box<Expression>>,
10917}
10918
10919/// MultitableInserts
10920#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10921#[cfg_attr(feature = "bindings", derive(TS))]
10922pub struct MultitableInserts {
10923    #[serde(default)]
10924    pub expressions: Vec<Expression>,
10925    pub kind: String,
10926    #[serde(default)]
10927    pub source: Option<Box<Expression>>,
10928    /// Leading comments before the statement
10929    #[serde(default)]
10930    pub leading_comments: Vec<String>,
10931    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
10932    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10933    pub overwrite: bool,
10934}
10935
10936/// OnConflict
10937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10938#[cfg_attr(feature = "bindings", derive(TS))]
10939pub struct OnConflict {
10940    #[serde(default)]
10941    pub duplicate: Option<Box<Expression>>,
10942    #[serde(default)]
10943    pub expressions: Vec<Expression>,
10944    #[serde(default)]
10945    pub action: Option<Box<Expression>>,
10946    #[serde(default)]
10947    pub conflict_keys: Option<Box<Expression>>,
10948    #[serde(default)]
10949    pub index_predicate: Option<Box<Expression>>,
10950    #[serde(default)]
10951    pub constraint: Option<Box<Expression>>,
10952    #[serde(default)]
10953    pub where_: Option<Box<Expression>>,
10954}
10955
10956/// OnCondition
10957#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10958#[cfg_attr(feature = "bindings", derive(TS))]
10959pub struct OnCondition {
10960    #[serde(default)]
10961    pub error: Option<Box<Expression>>,
10962    #[serde(default)]
10963    pub empty: Option<Box<Expression>>,
10964    #[serde(default)]
10965    pub null: Option<Box<Expression>>,
10966}
10967
10968/// Returning
10969#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10970#[cfg_attr(feature = "bindings", derive(TS))]
10971pub struct Returning {
10972    #[serde(default)]
10973    pub expressions: Vec<Expression>,
10974    #[serde(default)]
10975    pub into: Option<Box<Expression>>,
10976}
10977
10978/// Introducer
10979#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10980#[cfg_attr(feature = "bindings", derive(TS))]
10981pub struct Introducer {
10982    pub this: Box<Expression>,
10983    pub expression: Box<Expression>,
10984}
10985
10986/// PartitionRange
10987#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10988#[cfg_attr(feature = "bindings", derive(TS))]
10989pub struct PartitionRange {
10990    pub this: Box<Expression>,
10991    #[serde(default)]
10992    pub expression: Option<Box<Expression>>,
10993    #[serde(default)]
10994    pub expressions: Vec<Expression>,
10995}
10996
10997/// Group
10998#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10999#[cfg_attr(feature = "bindings", derive(TS))]
11000pub struct Group {
11001    #[serde(default)]
11002    pub expressions: Vec<Expression>,
11003    #[serde(default)]
11004    pub grouping_sets: Option<Box<Expression>>,
11005    #[serde(default)]
11006    pub cube: Option<Box<Expression>>,
11007    #[serde(default)]
11008    pub rollup: Option<Box<Expression>>,
11009    #[serde(default)]
11010    pub totals: Option<Box<Expression>>,
11011    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11012    #[serde(default)]
11013    pub all: Option<bool>,
11014}
11015
11016/// Cube
11017#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11018#[cfg_attr(feature = "bindings", derive(TS))]
11019pub struct Cube {
11020    #[serde(default)]
11021    pub expressions: Vec<Expression>,
11022}
11023
11024/// Rollup
11025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11026#[cfg_attr(feature = "bindings", derive(TS))]
11027pub struct Rollup {
11028    #[serde(default)]
11029    pub expressions: Vec<Expression>,
11030}
11031
11032/// GroupingSets
11033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11034#[cfg_attr(feature = "bindings", derive(TS))]
11035pub struct GroupingSets {
11036    #[serde(default)]
11037    pub expressions: Vec<Expression>,
11038}
11039
11040/// LimitOptions
11041#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11042#[cfg_attr(feature = "bindings", derive(TS))]
11043pub struct LimitOptions {
11044    #[serde(default)]
11045    pub percent: Option<Box<Expression>>,
11046    #[serde(default)]
11047    pub rows: Option<Box<Expression>>,
11048    #[serde(default)]
11049    pub with_ties: Option<Box<Expression>>,
11050}
11051
11052/// Lateral
11053#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11054#[cfg_attr(feature = "bindings", derive(TS))]
11055pub struct Lateral {
11056    pub this: Box<Expression>,
11057    #[serde(default)]
11058    pub view: Option<Box<Expression>>,
11059    #[serde(default)]
11060    pub outer: Option<Box<Expression>>,
11061    #[serde(default)]
11062    pub alias: Option<String>,
11063    /// Whether the alias was originally quoted (backtick/double-quote)
11064    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11065    pub alias_quoted: bool,
11066    #[serde(default)]
11067    pub cross_apply: Option<Box<Expression>>,
11068    #[serde(default)]
11069    pub ordinality: Option<Box<Expression>>,
11070    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11071    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11072    pub column_aliases: Vec<String>,
11073}
11074
11075/// TableFromRows
11076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11077#[cfg_attr(feature = "bindings", derive(TS))]
11078pub struct TableFromRows {
11079    pub this: Box<Expression>,
11080    #[serde(default)]
11081    pub alias: Option<String>,
11082    #[serde(default)]
11083    pub joins: Vec<Expression>,
11084    #[serde(default)]
11085    pub pivots: Option<Box<Expression>>,
11086    #[serde(default)]
11087    pub sample: Option<Box<Expression>>,
11088}
11089
11090/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11091/// Used for set-returning functions with typed column definitions
11092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11093#[cfg_attr(feature = "bindings", derive(TS))]
11094pub struct RowsFrom {
11095    /// List of function expressions, each potentially with an alias and typed columns
11096    pub expressions: Vec<Expression>,
11097    /// WITH ORDINALITY modifier
11098    #[serde(default)]
11099    pub ordinality: bool,
11100    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11101    #[serde(default)]
11102    pub alias: Option<Box<Expression>>,
11103}
11104
11105/// WithFill
11106#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11107#[cfg_attr(feature = "bindings", derive(TS))]
11108pub struct WithFill {
11109    #[serde(default)]
11110    pub from_: Option<Box<Expression>>,
11111    #[serde(default)]
11112    pub to: Option<Box<Expression>>,
11113    #[serde(default)]
11114    pub step: Option<Box<Expression>>,
11115    #[serde(default)]
11116    pub staleness: Option<Box<Expression>>,
11117    #[serde(default)]
11118    pub interpolate: Option<Box<Expression>>,
11119}
11120
11121/// Property
11122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11123#[cfg_attr(feature = "bindings", derive(TS))]
11124pub struct Property {
11125    pub this: Box<Expression>,
11126    #[serde(default)]
11127    pub value: Option<Box<Expression>>,
11128}
11129
11130/// GrantPrivilege
11131#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11132#[cfg_attr(feature = "bindings", derive(TS))]
11133pub struct GrantPrivilege {
11134    pub this: Box<Expression>,
11135    #[serde(default)]
11136    pub expressions: Vec<Expression>,
11137}
11138
11139/// AllowedValuesProperty
11140#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11141#[cfg_attr(feature = "bindings", derive(TS))]
11142pub struct AllowedValuesProperty {
11143    #[serde(default)]
11144    pub expressions: Vec<Expression>,
11145}
11146
11147/// AlgorithmProperty
11148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11149#[cfg_attr(feature = "bindings", derive(TS))]
11150pub struct AlgorithmProperty {
11151    pub this: Box<Expression>,
11152}
11153
11154/// AutoIncrementProperty
11155#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11156#[cfg_attr(feature = "bindings", derive(TS))]
11157pub struct AutoIncrementProperty {
11158    pub this: Box<Expression>,
11159}
11160
11161/// AutoRefreshProperty
11162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11163#[cfg_attr(feature = "bindings", derive(TS))]
11164pub struct AutoRefreshProperty {
11165    pub this: Box<Expression>,
11166}
11167
11168/// BackupProperty
11169#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11170#[cfg_attr(feature = "bindings", derive(TS))]
11171pub struct BackupProperty {
11172    pub this: Box<Expression>,
11173}
11174
11175/// BuildProperty
11176#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11177#[cfg_attr(feature = "bindings", derive(TS))]
11178pub struct BuildProperty {
11179    pub this: Box<Expression>,
11180}
11181
11182/// BlockCompressionProperty
11183#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11184#[cfg_attr(feature = "bindings", derive(TS))]
11185pub struct BlockCompressionProperty {
11186    #[serde(default)]
11187    pub autotemp: Option<Box<Expression>>,
11188    #[serde(default)]
11189    pub always: Option<Box<Expression>>,
11190    #[serde(default)]
11191    pub default: Option<Box<Expression>>,
11192    #[serde(default)]
11193    pub manual: Option<Box<Expression>>,
11194    #[serde(default)]
11195    pub never: Option<Box<Expression>>,
11196}
11197
11198/// CharacterSetProperty
11199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11200#[cfg_attr(feature = "bindings", derive(TS))]
11201pub struct CharacterSetProperty {
11202    pub this: Box<Expression>,
11203    #[serde(default)]
11204    pub default: Option<Box<Expression>>,
11205}
11206
11207/// ChecksumProperty
11208#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11209#[cfg_attr(feature = "bindings", derive(TS))]
11210pub struct ChecksumProperty {
11211    #[serde(default)]
11212    pub on: Option<Box<Expression>>,
11213    #[serde(default)]
11214    pub default: Option<Box<Expression>>,
11215}
11216
11217/// CollateProperty
11218#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11219#[cfg_attr(feature = "bindings", derive(TS))]
11220pub struct CollateProperty {
11221    pub this: Box<Expression>,
11222    #[serde(default)]
11223    pub default: Option<Box<Expression>>,
11224}
11225
11226/// DataBlocksizeProperty
11227#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11228#[cfg_attr(feature = "bindings", derive(TS))]
11229pub struct DataBlocksizeProperty {
11230    #[serde(default)]
11231    pub size: Option<i64>,
11232    #[serde(default)]
11233    pub units: Option<Box<Expression>>,
11234    #[serde(default)]
11235    pub minimum: Option<Box<Expression>>,
11236    #[serde(default)]
11237    pub maximum: Option<Box<Expression>>,
11238    #[serde(default)]
11239    pub default: Option<Box<Expression>>,
11240}
11241
11242/// DataDeletionProperty
11243#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11244#[cfg_attr(feature = "bindings", derive(TS))]
11245pub struct DataDeletionProperty {
11246    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11247    #[ast(skip)]
11248    pub on: Box<Expression>,
11249    #[serde(default)]
11250    pub filter_column: Option<Box<Expression>>,
11251    #[serde(default)]
11252    pub retention_period: Option<Box<Expression>>,
11253}
11254
11255/// DefinerProperty
11256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11257#[cfg_attr(feature = "bindings", derive(TS))]
11258pub struct DefinerProperty {
11259    pub this: Box<Expression>,
11260}
11261
11262/// DistKeyProperty
11263#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11264#[cfg_attr(feature = "bindings", derive(TS))]
11265pub struct DistKeyProperty {
11266    pub this: Box<Expression>,
11267}
11268
11269/// DistributedByProperty
11270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11271#[cfg_attr(feature = "bindings", derive(TS))]
11272pub struct DistributedByProperty {
11273    #[serde(default)]
11274    pub expressions: Vec<Expression>,
11275    pub kind: String,
11276    #[serde(default)]
11277    pub buckets: Option<Box<Expression>>,
11278    #[serde(default)]
11279    pub order: Option<Box<Expression>>,
11280}
11281
11282/// DistStyleProperty
11283#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11284#[cfg_attr(feature = "bindings", derive(TS))]
11285pub struct DistStyleProperty {
11286    pub this: Box<Expression>,
11287}
11288
11289/// DuplicateKeyProperty
11290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11291#[cfg_attr(feature = "bindings", derive(TS))]
11292pub struct DuplicateKeyProperty {
11293    #[serde(default)]
11294    pub expressions: Vec<Expression>,
11295}
11296
11297/// EngineProperty
11298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11299#[cfg_attr(feature = "bindings", derive(TS))]
11300pub struct EngineProperty {
11301    pub this: Box<Expression>,
11302}
11303
11304/// ToTableProperty
11305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11306#[cfg_attr(feature = "bindings", derive(TS))]
11307pub struct ToTableProperty {
11308    pub this: Box<Expression>,
11309}
11310
11311/// ExecuteAsProperty
11312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11313#[cfg_attr(feature = "bindings", derive(TS))]
11314pub struct ExecuteAsProperty {
11315    pub this: Box<Expression>,
11316}
11317
11318/// ExternalProperty
11319#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11320#[cfg_attr(feature = "bindings", derive(TS))]
11321pub struct ExternalProperty {
11322    #[serde(default)]
11323    pub this: Option<Box<Expression>>,
11324}
11325
11326/// FallbackProperty
11327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11328#[cfg_attr(feature = "bindings", derive(TS))]
11329pub struct FallbackProperty {
11330    #[serde(default)]
11331    pub no: Option<Box<Expression>>,
11332    #[serde(default)]
11333    pub protection: Option<Box<Expression>>,
11334}
11335
11336/// FileFormatProperty
11337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11338#[cfg_attr(feature = "bindings", derive(TS))]
11339pub struct FileFormatProperty {
11340    #[serde(default)]
11341    pub this: Option<Box<Expression>>,
11342    #[serde(default)]
11343    pub expressions: Vec<Expression>,
11344    #[serde(default)]
11345    pub hive_format: Option<Box<Expression>>,
11346}
11347
11348/// CredentialsProperty
11349#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11350#[cfg_attr(feature = "bindings", derive(TS))]
11351pub struct CredentialsProperty {
11352    #[serde(default)]
11353    pub expressions: Vec<Expression>,
11354}
11355
11356/// FreespaceProperty
11357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11358#[cfg_attr(feature = "bindings", derive(TS))]
11359pub struct FreespaceProperty {
11360    pub this: Box<Expression>,
11361    #[serde(default)]
11362    pub percent: Option<Box<Expression>>,
11363}
11364
11365/// InheritsProperty
11366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11367#[cfg_attr(feature = "bindings", derive(TS))]
11368pub struct InheritsProperty {
11369    #[serde(default)]
11370    pub expressions: Vec<Expression>,
11371}
11372
11373/// InputModelProperty
11374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11375#[cfg_attr(feature = "bindings", derive(TS))]
11376pub struct InputModelProperty {
11377    pub this: Box<Expression>,
11378}
11379
11380/// OutputModelProperty
11381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11382#[cfg_attr(feature = "bindings", derive(TS))]
11383pub struct OutputModelProperty {
11384    pub this: Box<Expression>,
11385}
11386
11387/// IsolatedLoadingProperty
11388#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11389#[cfg_attr(feature = "bindings", derive(TS))]
11390pub struct IsolatedLoadingProperty {
11391    #[serde(default)]
11392    pub no: Option<Box<Expression>>,
11393    #[serde(default)]
11394    pub concurrent: Option<Box<Expression>>,
11395    #[serde(default)]
11396    pub target: Option<Box<Expression>>,
11397}
11398
11399/// JournalProperty
11400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11401#[cfg_attr(feature = "bindings", derive(TS))]
11402pub struct JournalProperty {
11403    #[serde(default)]
11404    pub no: Option<Box<Expression>>,
11405    #[serde(default)]
11406    pub dual: Option<Box<Expression>>,
11407    #[serde(default)]
11408    pub before: Option<Box<Expression>>,
11409    #[serde(default)]
11410    pub local: Option<Box<Expression>>,
11411    #[serde(default)]
11412    pub after: Option<Box<Expression>>,
11413}
11414
11415/// LanguageProperty
11416#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11417#[cfg_attr(feature = "bindings", derive(TS))]
11418pub struct LanguageProperty {
11419    pub this: Box<Expression>,
11420}
11421
11422/// EnviromentProperty
11423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11424#[cfg_attr(feature = "bindings", derive(TS))]
11425pub struct EnviromentProperty {
11426    #[serde(default)]
11427    pub expressions: Vec<Expression>,
11428}
11429
11430/// ClusteredByProperty
11431#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11432#[cfg_attr(feature = "bindings", derive(TS))]
11433pub struct ClusteredByProperty {
11434    #[serde(default)]
11435    pub expressions: Vec<Expression>,
11436    #[serde(default)]
11437    pub sorted_by: Option<Box<Expression>>,
11438    #[serde(default)]
11439    pub buckets: Option<Box<Expression>>,
11440}
11441
11442/// DictProperty
11443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11444#[cfg_attr(feature = "bindings", derive(TS))]
11445pub struct DictProperty {
11446    pub this: Box<Expression>,
11447    pub kind: String,
11448    #[serde(default)]
11449    pub settings: Option<Box<Expression>>,
11450}
11451
11452/// DictRange
11453#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11454#[cfg_attr(feature = "bindings", derive(TS))]
11455pub struct DictRange {
11456    pub this: Box<Expression>,
11457    #[serde(default)]
11458    pub min: Option<Box<Expression>>,
11459    #[serde(default)]
11460    pub max: Option<Box<Expression>>,
11461}
11462
11463/// OnCluster
11464#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11465#[cfg_attr(feature = "bindings", derive(TS))]
11466pub struct OnCluster {
11467    pub this: Box<Expression>,
11468}
11469
11470/// LikeProperty
11471#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11472#[cfg_attr(feature = "bindings", derive(TS))]
11473pub struct LikeProperty {
11474    pub this: Box<Expression>,
11475    #[serde(default)]
11476    pub expressions: Vec<Expression>,
11477}
11478
11479/// LocationProperty
11480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11481#[cfg_attr(feature = "bindings", derive(TS))]
11482pub struct LocationProperty {
11483    pub this: Box<Expression>,
11484}
11485
11486/// LockProperty
11487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11488#[cfg_attr(feature = "bindings", derive(TS))]
11489pub struct LockProperty {
11490    pub this: Box<Expression>,
11491}
11492
11493/// LockingProperty
11494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11495#[cfg_attr(feature = "bindings", derive(TS))]
11496pub struct LockingProperty {
11497    #[serde(default)]
11498    pub this: Option<Box<Expression>>,
11499    pub kind: String,
11500    #[serde(default)]
11501    pub for_or_in: Option<Box<Expression>>,
11502    #[serde(default)]
11503    pub lock_type: Option<Box<Expression>>,
11504    #[serde(default)]
11505    pub override_: Option<Box<Expression>>,
11506}
11507
11508/// LogProperty
11509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11510#[cfg_attr(feature = "bindings", derive(TS))]
11511pub struct LogProperty {
11512    #[serde(default)]
11513    pub no: Option<Box<Expression>>,
11514}
11515
11516/// MaterializedProperty
11517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11518#[cfg_attr(feature = "bindings", derive(TS))]
11519pub struct MaterializedProperty {
11520    #[serde(default)]
11521    pub this: Option<Box<Expression>>,
11522}
11523
11524/// MergeBlockRatioProperty
11525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11526#[cfg_attr(feature = "bindings", derive(TS))]
11527pub struct MergeBlockRatioProperty {
11528    #[serde(default)]
11529    pub this: Option<Box<Expression>>,
11530    #[serde(default)]
11531    pub no: Option<Box<Expression>>,
11532    #[serde(default)]
11533    pub default: Option<Box<Expression>>,
11534    #[serde(default)]
11535    pub percent: Option<Box<Expression>>,
11536}
11537
11538/// OnProperty
11539#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11540#[cfg_attr(feature = "bindings", derive(TS))]
11541pub struct OnProperty {
11542    pub this: Box<Expression>,
11543}
11544
11545/// OnCommitProperty
11546#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11547#[cfg_attr(feature = "bindings", derive(TS))]
11548pub struct OnCommitProperty {
11549    #[serde(default)]
11550    pub delete: Option<Box<Expression>>,
11551}
11552
11553/// PartitionedByProperty
11554#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11555#[cfg_attr(feature = "bindings", derive(TS))]
11556pub struct PartitionedByProperty {
11557    pub this: Box<Expression>,
11558}
11559
11560/// BigQuery PARTITION BY property in CREATE TABLE statements.
11561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11562#[cfg_attr(feature = "bindings", derive(TS))]
11563pub struct PartitionByProperty {
11564    #[serde(default)]
11565    pub expressions: Vec<Expression>,
11566}
11567
11568/// PartitionedByBucket
11569#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11570#[cfg_attr(feature = "bindings", derive(TS))]
11571pub struct PartitionedByBucket {
11572    pub this: Box<Expression>,
11573    pub expression: Box<Expression>,
11574}
11575
11576/// BigQuery CLUSTER BY property in CREATE TABLE statements.
11577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11578#[cfg_attr(feature = "bindings", derive(TS))]
11579pub struct ClusterByColumnsProperty {
11580    #[serde(default)]
11581    pub columns: Vec<Identifier>,
11582}
11583
11584/// PartitionByTruncate
11585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11586#[cfg_attr(feature = "bindings", derive(TS))]
11587pub struct PartitionByTruncate {
11588    pub this: Box<Expression>,
11589    pub expression: Box<Expression>,
11590}
11591
11592/// PartitionByRangeProperty
11593#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11594#[cfg_attr(feature = "bindings", derive(TS))]
11595pub struct PartitionByRangeProperty {
11596    #[serde(default)]
11597    pub partition_expressions: Option<Box<Expression>>,
11598    #[serde(default)]
11599    pub create_expressions: Option<Box<Expression>>,
11600}
11601
11602/// PartitionByRangePropertyDynamic
11603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11604#[cfg_attr(feature = "bindings", derive(TS))]
11605pub struct PartitionByRangePropertyDynamic {
11606    #[serde(default)]
11607    pub this: Option<Box<Expression>>,
11608    #[serde(default)]
11609    pub start: Option<Box<Expression>>,
11610    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
11611    #[serde(default)]
11612    pub use_start_end: bool,
11613    #[serde(default)]
11614    pub end: Option<Box<Expression>>,
11615    #[serde(default)]
11616    pub every: Option<Box<Expression>>,
11617}
11618
11619/// PartitionByListProperty
11620#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11621#[cfg_attr(feature = "bindings", derive(TS))]
11622pub struct PartitionByListProperty {
11623    #[serde(default)]
11624    pub partition_expressions: Option<Box<Expression>>,
11625    #[serde(default)]
11626    pub create_expressions: Option<Box<Expression>>,
11627}
11628
11629/// PartitionList
11630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11631#[cfg_attr(feature = "bindings", derive(TS))]
11632pub struct PartitionList {
11633    pub this: Box<Expression>,
11634    #[serde(default)]
11635    pub expressions: Vec<Expression>,
11636}
11637
11638/// Partition - represents PARTITION/SUBPARTITION clause
11639#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11640#[cfg_attr(feature = "bindings", derive(TS))]
11641pub struct Partition {
11642    pub expressions: Vec<Expression>,
11643    #[serde(default)]
11644    pub subpartition: bool,
11645}
11646
11647/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
11648/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
11649#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11650#[cfg_attr(feature = "bindings", derive(TS))]
11651pub struct RefreshTriggerProperty {
11652    /// Method: COMPLETE or AUTO
11653    pub method: String,
11654    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
11655    #[serde(default)]
11656    pub kind: Option<String>,
11657    /// For SCHEDULE: EVERY n (the number)
11658    #[serde(default)]
11659    pub every: Option<Box<Expression>>,
11660    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
11661    #[serde(default)]
11662    pub unit: Option<String>,
11663    /// For SCHEDULE: STARTS 'datetime'
11664    #[serde(default)]
11665    pub starts: Option<Box<Expression>>,
11666}
11667
11668/// UniqueKeyProperty
11669#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11670#[cfg_attr(feature = "bindings", derive(TS))]
11671pub struct UniqueKeyProperty {
11672    #[serde(default)]
11673    pub expressions: Vec<Expression>,
11674}
11675
11676/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
11677#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11678#[cfg_attr(feature = "bindings", derive(TS))]
11679pub struct RollupProperty {
11680    pub expressions: Vec<RollupIndex>,
11681}
11682
11683/// RollupIndex - A single rollup index: name(col1, col2)
11684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11685#[cfg_attr(feature = "bindings", derive(TS))]
11686pub struct RollupIndex {
11687    pub name: Identifier,
11688    pub expressions: Vec<Identifier>,
11689}
11690
11691/// PartitionBoundSpec
11692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11693#[cfg_attr(feature = "bindings", derive(TS))]
11694pub struct PartitionBoundSpec {
11695    #[serde(default)]
11696    pub this: Option<Box<Expression>>,
11697    #[serde(default)]
11698    pub expression: Option<Box<Expression>>,
11699    #[serde(default)]
11700    pub from_expressions: Option<Box<Expression>>,
11701    #[serde(default)]
11702    pub to_expressions: Option<Box<Expression>>,
11703}
11704
11705/// PartitionedOfProperty
11706#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11707#[cfg_attr(feature = "bindings", derive(TS))]
11708pub struct PartitionedOfProperty {
11709    pub this: Box<Expression>,
11710    pub expression: Box<Expression>,
11711}
11712
11713/// RemoteWithConnectionModelProperty
11714#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11715#[cfg_attr(feature = "bindings", derive(TS))]
11716pub struct RemoteWithConnectionModelProperty {
11717    pub this: Box<Expression>,
11718}
11719
11720/// ReturnsProperty
11721#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11722#[cfg_attr(feature = "bindings", derive(TS))]
11723pub struct ReturnsProperty {
11724    #[serde(default)]
11725    pub this: Option<Box<Expression>>,
11726    #[serde(default)]
11727    pub is_table: Option<Box<Expression>>,
11728    #[serde(default)]
11729    pub table: Option<Box<Expression>>,
11730    #[serde(default)]
11731    pub null: Option<Box<Expression>>,
11732}
11733
11734/// RowFormatProperty
11735#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11736#[cfg_attr(feature = "bindings", derive(TS))]
11737pub struct RowFormatProperty {
11738    pub this: Box<Expression>,
11739}
11740
11741/// RowFormatDelimitedProperty
11742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11743#[cfg_attr(feature = "bindings", derive(TS))]
11744pub struct RowFormatDelimitedProperty {
11745    #[serde(default)]
11746    pub fields: Option<Box<Expression>>,
11747    #[serde(default)]
11748    pub escaped: Option<Box<Expression>>,
11749    #[serde(default)]
11750    pub collection_items: Option<Box<Expression>>,
11751    #[serde(default)]
11752    pub map_keys: Option<Box<Expression>>,
11753    #[serde(default)]
11754    pub lines: Option<Box<Expression>>,
11755    #[serde(default)]
11756    pub null: Option<Box<Expression>>,
11757    #[serde(default)]
11758    pub serde: Option<Box<Expression>>,
11759}
11760
11761/// RowFormatSerdeProperty
11762#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11763#[cfg_attr(feature = "bindings", derive(TS))]
11764pub struct RowFormatSerdeProperty {
11765    pub this: Box<Expression>,
11766    #[serde(default)]
11767    pub serde_properties: Option<Box<Expression>>,
11768}
11769
11770/// QueryTransform
11771#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11772#[cfg_attr(feature = "bindings", derive(TS))]
11773pub struct QueryTransform {
11774    #[serde(default)]
11775    pub expressions: Vec<Expression>,
11776    #[serde(default)]
11777    pub command_script: Option<Box<Expression>>,
11778    #[serde(default)]
11779    pub schema: Option<Box<Expression>>,
11780    #[serde(default)]
11781    pub row_format_before: Option<Box<Expression>>,
11782    #[serde(default)]
11783    pub record_writer: Option<Box<Expression>>,
11784    #[serde(default)]
11785    pub row_format_after: Option<Box<Expression>>,
11786    #[serde(default)]
11787    pub record_reader: Option<Box<Expression>>,
11788}
11789
11790/// SampleProperty
11791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11792#[cfg_attr(feature = "bindings", derive(TS))]
11793pub struct SampleProperty {
11794    pub this: Box<Expression>,
11795}
11796
11797/// SecurityProperty
11798#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11799#[cfg_attr(feature = "bindings", derive(TS))]
11800pub struct SecurityProperty {
11801    pub this: Box<Expression>,
11802}
11803
11804/// SchemaCommentProperty
11805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11806#[cfg_attr(feature = "bindings", derive(TS))]
11807pub struct SchemaCommentProperty {
11808    pub this: Box<Expression>,
11809}
11810
11811/// SemanticView
11812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11813#[cfg_attr(feature = "bindings", derive(TS))]
11814pub struct SemanticView {
11815    pub this: Box<Expression>,
11816    #[serde(default)]
11817    pub metrics: Option<Box<Expression>>,
11818    #[serde(default)]
11819    pub dimensions: Option<Box<Expression>>,
11820    #[serde(default)]
11821    pub facts: Option<Box<Expression>>,
11822    #[serde(default)]
11823    pub where_: Option<Box<Expression>>,
11824}
11825
11826/// SerdeProperties
11827#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11828#[cfg_attr(feature = "bindings", derive(TS))]
11829pub struct SerdeProperties {
11830    #[serde(default)]
11831    pub expressions: Vec<Expression>,
11832    #[serde(default)]
11833    pub with_: Option<Box<Expression>>,
11834}
11835
11836/// SetProperty
11837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11838#[cfg_attr(feature = "bindings", derive(TS))]
11839pub struct SetProperty {
11840    #[serde(default)]
11841    pub multi: Option<Box<Expression>>,
11842}
11843
11844/// SharingProperty
11845#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11846#[cfg_attr(feature = "bindings", derive(TS))]
11847pub struct SharingProperty {
11848    #[serde(default)]
11849    pub this: Option<Box<Expression>>,
11850}
11851
11852/// SetConfigProperty
11853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11854#[cfg_attr(feature = "bindings", derive(TS))]
11855pub struct SetConfigProperty {
11856    pub this: Box<Expression>,
11857}
11858
11859/// SettingsProperty
11860#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11861#[cfg_attr(feature = "bindings", derive(TS))]
11862pub struct SettingsProperty {
11863    #[serde(default)]
11864    pub expressions: Vec<Expression>,
11865}
11866
11867/// SortKeyProperty
11868#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11869#[cfg_attr(feature = "bindings", derive(TS))]
11870pub struct SortKeyProperty {
11871    pub this: Box<Expression>,
11872    #[serde(default)]
11873    pub compound: Option<Box<Expression>>,
11874}
11875
11876/// SqlReadWriteProperty
11877#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11878#[cfg_attr(feature = "bindings", derive(TS))]
11879pub struct SqlReadWriteProperty {
11880    pub this: Box<Expression>,
11881}
11882
11883/// SqlSecurityProperty
11884#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11885#[cfg_attr(feature = "bindings", derive(TS))]
11886pub struct SqlSecurityProperty {
11887    pub this: Box<Expression>,
11888}
11889
11890/// StabilityProperty
11891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11892#[cfg_attr(feature = "bindings", derive(TS))]
11893pub struct StabilityProperty {
11894    pub this: Box<Expression>,
11895}
11896
11897/// StorageHandlerProperty
11898#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11899#[cfg_attr(feature = "bindings", derive(TS))]
11900pub struct StorageHandlerProperty {
11901    pub this: Box<Expression>,
11902}
11903
11904/// TemporaryProperty
11905#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11906#[cfg_attr(feature = "bindings", derive(TS))]
11907pub struct TemporaryProperty {
11908    #[serde(default)]
11909    pub this: Option<Box<Expression>>,
11910}
11911
11912/// Tags
11913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11914#[cfg_attr(feature = "bindings", derive(TS))]
11915pub struct Tags {
11916    #[serde(default)]
11917    pub expressions: Vec<Expression>,
11918}
11919
11920/// TransformModelProperty
11921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11922#[cfg_attr(feature = "bindings", derive(TS))]
11923pub struct TransformModelProperty {
11924    #[serde(default)]
11925    pub expressions: Vec<Expression>,
11926}
11927
11928/// TransientProperty
11929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11930#[cfg_attr(feature = "bindings", derive(TS))]
11931pub struct TransientProperty {
11932    #[serde(default)]
11933    pub this: Option<Box<Expression>>,
11934}
11935
11936/// UsingTemplateProperty
11937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11938#[cfg_attr(feature = "bindings", derive(TS))]
11939pub struct UsingTemplateProperty {
11940    pub this: Box<Expression>,
11941}
11942
11943/// ViewAttributeProperty
11944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11945#[cfg_attr(feature = "bindings", derive(TS))]
11946pub struct ViewAttributeProperty {
11947    pub this: Box<Expression>,
11948}
11949
11950/// VolatileProperty
11951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11952#[cfg_attr(feature = "bindings", derive(TS))]
11953pub struct VolatileProperty {
11954    #[serde(default)]
11955    pub this: Option<Box<Expression>>,
11956}
11957
11958/// WithDataProperty
11959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11960#[cfg_attr(feature = "bindings", derive(TS))]
11961pub struct WithDataProperty {
11962    #[serde(default)]
11963    pub no: Option<Box<Expression>>,
11964    #[serde(default)]
11965    pub statistics: Option<Box<Expression>>,
11966}
11967
11968/// WithJournalTableProperty
11969#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11970#[cfg_attr(feature = "bindings", derive(TS))]
11971pub struct WithJournalTableProperty {
11972    pub this: Box<Expression>,
11973}
11974
11975/// WithSchemaBindingProperty
11976#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11977#[cfg_attr(feature = "bindings", derive(TS))]
11978pub struct WithSchemaBindingProperty {
11979    pub this: Box<Expression>,
11980}
11981
11982/// WithSystemVersioningProperty
11983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11984#[cfg_attr(feature = "bindings", derive(TS))]
11985pub struct WithSystemVersioningProperty {
11986    #[serde(default)]
11987    pub on: Option<Box<Expression>>,
11988    #[serde(default)]
11989    pub this: Option<Box<Expression>>,
11990    #[serde(default)]
11991    pub data_consistency: Option<Box<Expression>>,
11992    #[serde(default)]
11993    pub retention_period: Option<Box<Expression>>,
11994    #[serde(default)]
11995    pub with_: Option<Box<Expression>>,
11996}
11997
11998/// WithProcedureOptions
11999#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12000#[cfg_attr(feature = "bindings", derive(TS))]
12001pub struct WithProcedureOptions {
12002    #[serde(default)]
12003    pub expressions: Vec<Expression>,
12004}
12005
12006/// EncodeProperty
12007#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12008#[cfg_attr(feature = "bindings", derive(TS))]
12009pub struct EncodeProperty {
12010    pub this: Box<Expression>,
12011    #[serde(default)]
12012    pub properties: Vec<Expression>,
12013    #[serde(default)]
12014    pub key: Option<Box<Expression>>,
12015}
12016
12017/// IncludeProperty
12018#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12019#[cfg_attr(feature = "bindings", derive(TS))]
12020pub struct IncludeProperty {
12021    pub this: Box<Expression>,
12022    #[serde(default)]
12023    pub alias: Option<String>,
12024    #[serde(default)]
12025    pub column_def: Option<Box<Expression>>,
12026}
12027
12028/// Properties
12029#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12030#[cfg_attr(feature = "bindings", derive(TS))]
12031pub struct Properties {
12032    #[serde(default)]
12033    pub expressions: Vec<Expression>,
12034}
12035
12036/// Key/value pair in a BigQuery OPTIONS (...) clause.
12037#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12038#[cfg_attr(feature = "bindings", derive(TS))]
12039pub struct OptionEntry {
12040    pub key: Identifier,
12041    pub value: Expression,
12042}
12043
12044/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12046#[cfg_attr(feature = "bindings", derive(TS))]
12047pub struct OptionsProperty {
12048    #[serde(default)]
12049    pub entries: Vec<OptionEntry>,
12050}
12051
12052/// InputOutputFormat
12053#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12054#[cfg_attr(feature = "bindings", derive(TS))]
12055pub struct InputOutputFormat {
12056    #[serde(default)]
12057    pub input_format: Option<Box<Expression>>,
12058    #[serde(default)]
12059    pub output_format: Option<Box<Expression>>,
12060}
12061
12062/// Reference
12063#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12064#[cfg_attr(feature = "bindings", derive(TS))]
12065pub struct Reference {
12066    pub this: Box<Expression>,
12067    #[serde(default)]
12068    pub expressions: Vec<Expression>,
12069    #[serde(default)]
12070    pub options: Vec<Expression>,
12071}
12072
12073/// QueryOption
12074#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12075#[cfg_attr(feature = "bindings", derive(TS))]
12076pub struct QueryOption {
12077    pub this: Box<Expression>,
12078    #[serde(default)]
12079    pub expression: Option<Box<Expression>>,
12080}
12081
12082/// WithTableHint
12083#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12084#[cfg_attr(feature = "bindings", derive(TS))]
12085pub struct WithTableHint {
12086    #[serde(default)]
12087    pub expressions: Vec<Expression>,
12088}
12089
12090/// IndexTableHint
12091#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12092#[cfg_attr(feature = "bindings", derive(TS))]
12093pub struct IndexTableHint {
12094    pub this: Box<Expression>,
12095    #[serde(default)]
12096    pub expressions: Vec<Expression>,
12097    #[serde(default)]
12098    pub target: Option<Box<Expression>>,
12099}
12100
12101/// Get
12102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12103#[cfg_attr(feature = "bindings", derive(TS))]
12104pub struct Get {
12105    pub this: Box<Expression>,
12106    #[serde(default)]
12107    pub target: Option<Box<Expression>>,
12108    #[serde(default)]
12109    pub properties: Vec<Expression>,
12110}
12111
12112/// SetOperation
12113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12114#[cfg_attr(feature = "bindings", derive(TS))]
12115pub struct SetOperation {
12116    #[serde(default)]
12117    pub with_: Option<Box<Expression>>,
12118    pub this: Box<Expression>,
12119    pub expression: Box<Expression>,
12120    #[serde(default)]
12121    pub distinct: bool,
12122    #[serde(default)]
12123    pub by_name: Option<Box<Expression>>,
12124    #[serde(default)]
12125    pub side: Option<Box<Expression>>,
12126    #[serde(default)]
12127    pub kind: Option<String>,
12128    #[serde(default)]
12129    pub on: Option<Box<Expression>>,
12130}
12131
12132/// Var - Simple variable reference (for SQL variables, keywords as values)
12133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12134#[cfg_attr(feature = "bindings", derive(TS))]
12135pub struct Var {
12136    pub this: String,
12137}
12138
12139/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12140#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12141#[cfg_attr(feature = "bindings", derive(TS))]
12142pub struct Variadic {
12143    pub this: Box<Expression>,
12144}
12145
12146/// Version
12147#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12148#[cfg_attr(feature = "bindings", derive(TS))]
12149pub struct Version {
12150    pub this: Box<Expression>,
12151    pub kind: String,
12152    #[serde(default)]
12153    pub expression: Option<Box<Expression>>,
12154}
12155
12156/// Schema
12157#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12158#[cfg_attr(feature = "bindings", derive(TS))]
12159pub struct Schema {
12160    #[serde(default)]
12161    pub this: Option<Box<Expression>>,
12162    #[serde(default)]
12163    pub expressions: Vec<Expression>,
12164}
12165
12166/// Lock
12167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12168#[cfg_attr(feature = "bindings", derive(TS))]
12169pub struct Lock {
12170    #[serde(default)]
12171    pub update: Option<Box<Expression>>,
12172    #[serde(default)]
12173    pub expressions: Vec<Expression>,
12174    #[serde(default)]
12175    pub wait: Option<Box<Expression>>,
12176    #[serde(default)]
12177    pub key: Option<Box<Expression>>,
12178}
12179
12180/// TableSample - wraps an expression with a TABLESAMPLE clause
12181/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12182#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12183#[cfg_attr(feature = "bindings", derive(TS))]
12184pub struct TableSample {
12185    /// The expression being sampled (subquery, function, etc.)
12186    #[serde(default, skip_serializing_if = "Option::is_none")]
12187    pub this: Option<Box<Expression>>,
12188    /// The sample specification
12189    #[serde(default, skip_serializing_if = "Option::is_none")]
12190    pub sample: Option<Box<Sample>>,
12191    #[serde(default)]
12192    pub expressions: Vec<Expression>,
12193    #[serde(default)]
12194    pub method: Option<String>,
12195    #[serde(default)]
12196    pub bucket_numerator: Option<Box<Expression>>,
12197    #[serde(default)]
12198    pub bucket_denominator: Option<Box<Expression>>,
12199    #[serde(default)]
12200    pub bucket_field: Option<Box<Expression>>,
12201    #[serde(default)]
12202    pub percent: Option<Box<Expression>>,
12203    #[serde(default)]
12204    pub rows: Option<Box<Expression>>,
12205    #[serde(default)]
12206    pub size: Option<i64>,
12207    #[serde(default)]
12208    pub seed: Option<Box<Expression>>,
12209}
12210
12211/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12213#[cfg_attr(feature = "bindings", derive(TS))]
12214pub struct Tag {
12215    #[serde(default)]
12216    pub this: Option<Box<Expression>>,
12217    #[serde(default)]
12218    pub prefix: Option<Box<Expression>>,
12219    #[serde(default)]
12220    pub postfix: Option<Box<Expression>>,
12221}
12222
12223/// UnpivotColumns
12224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12225#[cfg_attr(feature = "bindings", derive(TS))]
12226pub struct UnpivotColumns {
12227    pub this: Box<Expression>,
12228    #[serde(default)]
12229    pub expressions: Vec<Expression>,
12230}
12231
12232/// SessionParameter
12233#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12234#[cfg_attr(feature = "bindings", derive(TS))]
12235pub struct SessionParameter {
12236    pub this: Box<Expression>,
12237    #[serde(default)]
12238    pub kind: Option<String>,
12239}
12240
12241/// PseudoType
12242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12243#[cfg_attr(feature = "bindings", derive(TS))]
12244pub struct PseudoType {
12245    pub this: Box<Expression>,
12246}
12247
12248/// ObjectIdentifier
12249#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12250#[cfg_attr(feature = "bindings", derive(TS))]
12251pub struct ObjectIdentifier {
12252    pub this: Box<Expression>,
12253}
12254
12255/// Transaction
12256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12257#[cfg_attr(feature = "bindings", derive(TS))]
12258pub struct Transaction {
12259    #[serde(default)]
12260    pub this: Option<Box<Expression>>,
12261    #[serde(default)]
12262    pub modes: Option<Box<Expression>>,
12263    #[serde(default)]
12264    pub mark: Option<Box<Expression>>,
12265}
12266
12267/// Commit
12268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12269#[cfg_attr(feature = "bindings", derive(TS))]
12270pub struct Commit {
12271    #[serde(default)]
12272    pub chain: Option<Box<Expression>>,
12273    #[serde(default)]
12274    pub this: Option<Box<Expression>>,
12275    #[serde(default)]
12276    pub durability: Option<Box<Expression>>,
12277}
12278
12279/// Rollback
12280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12281#[cfg_attr(feature = "bindings", derive(TS))]
12282pub struct Rollback {
12283    #[serde(default)]
12284    pub savepoint: Option<Box<Expression>>,
12285    #[serde(default)]
12286    pub this: Option<Box<Expression>>,
12287}
12288
12289/// AlterSession
12290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12291#[cfg_attr(feature = "bindings", derive(TS))]
12292pub struct AlterSession {
12293    #[serde(default)]
12294    pub expressions: Vec<Expression>,
12295    #[serde(default)]
12296    pub unset: Option<Box<Expression>>,
12297}
12298
12299/// Analyze
12300#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12301#[cfg_attr(feature = "bindings", derive(TS))]
12302pub struct Analyze {
12303    #[serde(default)]
12304    pub kind: Option<String>,
12305    #[serde(default)]
12306    pub this: Option<Box<Expression>>,
12307    #[serde(default)]
12308    pub options: Vec<Expression>,
12309    #[serde(default)]
12310    pub mode: Option<Box<Expression>>,
12311    #[serde(default)]
12312    pub partition: Option<Box<Expression>>,
12313    #[serde(default)]
12314    pub expression: Option<Box<Expression>>,
12315    #[serde(default)]
12316    pub properties: Vec<Expression>,
12317    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12318    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12319    pub columns: Vec<String>,
12320}
12321
12322/// AnalyzeStatistics
12323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12324#[cfg_attr(feature = "bindings", derive(TS))]
12325pub struct AnalyzeStatistics {
12326    pub kind: String,
12327    #[serde(default)]
12328    pub option: Option<Box<Expression>>,
12329    #[serde(default)]
12330    pub this: Option<Box<Expression>>,
12331    #[serde(default)]
12332    pub expressions: Vec<Expression>,
12333}
12334
12335/// AnalyzeHistogram
12336#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12337#[cfg_attr(feature = "bindings", derive(TS))]
12338pub struct AnalyzeHistogram {
12339    pub this: Box<Expression>,
12340    #[serde(default)]
12341    pub expressions: Vec<Expression>,
12342    #[serde(default)]
12343    pub expression: Option<Box<Expression>>,
12344    #[serde(default)]
12345    pub update_options: Option<Box<Expression>>,
12346}
12347
12348/// AnalyzeSample
12349#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12350#[cfg_attr(feature = "bindings", derive(TS))]
12351pub struct AnalyzeSample {
12352    pub kind: String,
12353    #[serde(default)]
12354    pub sample: Option<Box<Expression>>,
12355}
12356
12357/// AnalyzeListChainedRows
12358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12359#[cfg_attr(feature = "bindings", derive(TS))]
12360pub struct AnalyzeListChainedRows {
12361    #[serde(default)]
12362    pub expression: Option<Box<Expression>>,
12363}
12364
12365/// AnalyzeDelete
12366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12367#[cfg_attr(feature = "bindings", derive(TS))]
12368pub struct AnalyzeDelete {
12369    #[serde(default)]
12370    pub kind: Option<String>,
12371}
12372
12373/// AnalyzeWith
12374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12375#[cfg_attr(feature = "bindings", derive(TS))]
12376pub struct AnalyzeWith {
12377    #[serde(default)]
12378    pub expressions: Vec<Expression>,
12379}
12380
12381/// AnalyzeValidate
12382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12383#[cfg_attr(feature = "bindings", derive(TS))]
12384pub struct AnalyzeValidate {
12385    pub kind: String,
12386    #[serde(default)]
12387    pub this: Option<Box<Expression>>,
12388    #[serde(default)]
12389    pub expression: Option<Box<Expression>>,
12390}
12391
12392/// AddPartition
12393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12394#[cfg_attr(feature = "bindings", derive(TS))]
12395pub struct AddPartition {
12396    pub this: Box<Expression>,
12397    #[serde(default)]
12398    pub exists: bool,
12399    #[serde(default)]
12400    pub location: Option<Box<Expression>>,
12401}
12402
12403/// AttachOption
12404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12405#[cfg_attr(feature = "bindings", derive(TS))]
12406pub struct AttachOption {
12407    pub this: Box<Expression>,
12408    #[serde(default)]
12409    pub expression: Option<Box<Expression>>,
12410}
12411
12412/// DropPartition
12413#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12414#[cfg_attr(feature = "bindings", derive(TS))]
12415pub struct DropPartition {
12416    #[serde(default)]
12417    pub expressions: Vec<Expression>,
12418    #[serde(default)]
12419    pub exists: bool,
12420}
12421
12422/// ReplacePartition
12423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12424#[cfg_attr(feature = "bindings", derive(TS))]
12425pub struct ReplacePartition {
12426    pub expression: Box<Expression>,
12427    #[serde(default)]
12428    pub source: Option<Box<Expression>>,
12429}
12430
12431/// DPipe
12432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12433#[cfg_attr(feature = "bindings", derive(TS))]
12434pub struct DPipe {
12435    pub this: Box<Expression>,
12436    pub expression: Box<Expression>,
12437    #[serde(default)]
12438    pub safe: Option<Box<Expression>>,
12439}
12440
12441/// Operator
12442#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12443#[cfg_attr(feature = "bindings", derive(TS))]
12444pub struct Operator {
12445    pub this: Box<Expression>,
12446    #[serde(default)]
12447    pub operator: Option<Box<Expression>>,
12448    pub expression: Box<Expression>,
12449    /// Comments between OPERATOR() and the RHS expression
12450    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12451    pub comments: Vec<String>,
12452}
12453
12454/// PivotAny
12455#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12456#[cfg_attr(feature = "bindings", derive(TS))]
12457pub struct PivotAny {
12458    #[serde(default)]
12459    pub this: Option<Box<Expression>>,
12460}
12461
12462/// Aliases
12463#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12464#[cfg_attr(feature = "bindings", derive(TS))]
12465pub struct Aliases {
12466    pub this: Box<Expression>,
12467    #[serde(default)]
12468    pub expressions: Vec<Expression>,
12469}
12470
12471/// AtIndex
12472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12473#[cfg_attr(feature = "bindings", derive(TS))]
12474pub struct AtIndex {
12475    pub this: Box<Expression>,
12476    pub expression: Box<Expression>,
12477}
12478
12479/// FromTimeZone
12480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12481#[cfg_attr(feature = "bindings", derive(TS))]
12482pub struct FromTimeZone {
12483    pub this: Box<Expression>,
12484    #[serde(default)]
12485    pub zone: Option<Box<Expression>>,
12486}
12487
12488/// Format override for a column in Teradata
12489#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12490#[cfg_attr(feature = "bindings", derive(TS))]
12491pub struct FormatPhrase {
12492    pub this: Box<Expression>,
12493    pub format: String,
12494}
12495
12496/// ForIn
12497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12498#[cfg_attr(feature = "bindings", derive(TS))]
12499pub struct ForIn {
12500    pub this: Box<Expression>,
12501    pub expression: Box<Expression>,
12502}
12503
12504/// Automatically converts unit arg into a var.
12505#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12506#[cfg_attr(feature = "bindings", derive(TS))]
12507pub struct TimeUnit {
12508    #[serde(default)]
12509    pub unit: Option<String>,
12510}
12511
12512/// IntervalOp
12513#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12514#[cfg_attr(feature = "bindings", derive(TS))]
12515pub struct IntervalOp {
12516    #[serde(default)]
12517    pub unit: Option<String>,
12518    pub expression: Box<Expression>,
12519}
12520
12521/// HavingMax
12522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12523#[cfg_attr(feature = "bindings", derive(TS))]
12524pub struct HavingMax {
12525    pub this: Box<Expression>,
12526    pub expression: Box<Expression>,
12527    #[serde(default)]
12528    pub max: Option<Box<Expression>>,
12529}
12530
12531/// CosineDistance
12532#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12533#[cfg_attr(feature = "bindings", derive(TS))]
12534pub struct CosineDistance {
12535    pub this: Box<Expression>,
12536    pub expression: Box<Expression>,
12537}
12538
12539/// DotProduct
12540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12541#[cfg_attr(feature = "bindings", derive(TS))]
12542pub struct DotProduct {
12543    pub this: Box<Expression>,
12544    pub expression: Box<Expression>,
12545}
12546
12547/// EuclideanDistance
12548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12549#[cfg_attr(feature = "bindings", derive(TS))]
12550pub struct EuclideanDistance {
12551    pub this: Box<Expression>,
12552    pub expression: Box<Expression>,
12553}
12554
12555/// ManhattanDistance
12556#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12557#[cfg_attr(feature = "bindings", derive(TS))]
12558pub struct ManhattanDistance {
12559    pub this: Box<Expression>,
12560    pub expression: Box<Expression>,
12561}
12562
12563/// JarowinklerSimilarity
12564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12565#[cfg_attr(feature = "bindings", derive(TS))]
12566pub struct JarowinklerSimilarity {
12567    pub this: Box<Expression>,
12568    pub expression: Box<Expression>,
12569}
12570
12571/// Booland
12572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12573#[cfg_attr(feature = "bindings", derive(TS))]
12574pub struct Booland {
12575    pub this: Box<Expression>,
12576    pub expression: Box<Expression>,
12577}
12578
12579/// Boolor
12580#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12581#[cfg_attr(feature = "bindings", derive(TS))]
12582pub struct Boolor {
12583    pub this: Box<Expression>,
12584    pub expression: Box<Expression>,
12585}
12586
12587/// ParameterizedAgg
12588#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12589#[cfg_attr(feature = "bindings", derive(TS))]
12590pub struct ParameterizedAgg {
12591    pub this: Box<Expression>,
12592    #[serde(default)]
12593    pub expressions: Vec<Expression>,
12594    #[serde(default)]
12595    pub params: Vec<Expression>,
12596}
12597
12598/// ArgMax
12599#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12600#[cfg_attr(feature = "bindings", derive(TS))]
12601pub struct ArgMax {
12602    pub this: Box<Expression>,
12603    pub expression: Box<Expression>,
12604    #[serde(default)]
12605    pub count: Option<Box<Expression>>,
12606}
12607
12608/// ArgMin
12609#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12610#[cfg_attr(feature = "bindings", derive(TS))]
12611pub struct ArgMin {
12612    pub this: Box<Expression>,
12613    pub expression: Box<Expression>,
12614    #[serde(default)]
12615    pub count: Option<Box<Expression>>,
12616}
12617
12618/// ApproxTopK
12619#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12620#[cfg_attr(feature = "bindings", derive(TS))]
12621pub struct ApproxTopK {
12622    pub this: Box<Expression>,
12623    #[serde(default)]
12624    pub expression: Option<Box<Expression>>,
12625    #[serde(default)]
12626    pub counters: Option<Box<Expression>>,
12627}
12628
12629/// ApproxTopKAccumulate
12630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12631#[cfg_attr(feature = "bindings", derive(TS))]
12632pub struct ApproxTopKAccumulate {
12633    pub this: Box<Expression>,
12634    #[serde(default)]
12635    pub expression: Option<Box<Expression>>,
12636}
12637
12638/// ApproxTopKCombine
12639#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12640#[cfg_attr(feature = "bindings", derive(TS))]
12641pub struct ApproxTopKCombine {
12642    pub this: Box<Expression>,
12643    #[serde(default)]
12644    pub expression: Option<Box<Expression>>,
12645}
12646
12647/// ApproxTopKEstimate
12648#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12649#[cfg_attr(feature = "bindings", derive(TS))]
12650pub struct ApproxTopKEstimate {
12651    pub this: Box<Expression>,
12652    #[serde(default)]
12653    pub expression: Option<Box<Expression>>,
12654}
12655
12656/// ApproxTopSum
12657#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12658#[cfg_attr(feature = "bindings", derive(TS))]
12659pub struct ApproxTopSum {
12660    pub this: Box<Expression>,
12661    pub expression: Box<Expression>,
12662    #[serde(default)]
12663    pub count: Option<Box<Expression>>,
12664}
12665
12666/// ApproxQuantiles
12667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12668#[cfg_attr(feature = "bindings", derive(TS))]
12669pub struct ApproxQuantiles {
12670    pub this: Box<Expression>,
12671    #[serde(default)]
12672    pub expression: Option<Box<Expression>>,
12673}
12674
12675/// Minhash
12676#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12677#[cfg_attr(feature = "bindings", derive(TS))]
12678pub struct Minhash {
12679    pub this: Box<Expression>,
12680    #[serde(default)]
12681    pub expressions: Vec<Expression>,
12682}
12683
12684/// FarmFingerprint
12685#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12686#[cfg_attr(feature = "bindings", derive(TS))]
12687pub struct FarmFingerprint {
12688    #[serde(default)]
12689    pub expressions: Vec<Expression>,
12690}
12691
12692/// Float64
12693#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12694#[cfg_attr(feature = "bindings", derive(TS))]
12695pub struct Float64 {
12696    pub this: Box<Expression>,
12697    #[serde(default)]
12698    pub expression: Option<Box<Expression>>,
12699}
12700
12701/// Transform
12702#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12703#[cfg_attr(feature = "bindings", derive(TS))]
12704pub struct Transform {
12705    pub this: Box<Expression>,
12706    pub expression: Box<Expression>,
12707}
12708
12709/// Translate
12710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12711#[cfg_attr(feature = "bindings", derive(TS))]
12712pub struct Translate {
12713    pub this: Box<Expression>,
12714    #[serde(default)]
12715    pub from_: Option<Box<Expression>>,
12716    #[serde(default)]
12717    pub to: Option<Box<Expression>>,
12718}
12719
12720/// Grouping
12721#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12722#[cfg_attr(feature = "bindings", derive(TS))]
12723pub struct Grouping {
12724    #[serde(default)]
12725    pub expressions: Vec<Expression>,
12726}
12727
12728/// GroupingId
12729#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12730#[cfg_attr(feature = "bindings", derive(TS))]
12731pub struct GroupingId {
12732    #[serde(default)]
12733    pub expressions: Vec<Expression>,
12734}
12735
12736/// Anonymous
12737#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12738#[cfg_attr(feature = "bindings", derive(TS))]
12739pub struct Anonymous {
12740    pub this: Box<Expression>,
12741    #[serde(default)]
12742    pub expressions: Vec<Expression>,
12743}
12744
12745/// AnonymousAggFunc
12746#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12747#[cfg_attr(feature = "bindings", derive(TS))]
12748pub struct AnonymousAggFunc {
12749    pub this: Box<Expression>,
12750    #[serde(default)]
12751    pub expressions: Vec<Expression>,
12752}
12753
12754/// CombinedAggFunc
12755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12756#[cfg_attr(feature = "bindings", derive(TS))]
12757pub struct CombinedAggFunc {
12758    pub this: Box<Expression>,
12759    #[serde(default)]
12760    pub expressions: Vec<Expression>,
12761}
12762
12763/// CombinedParameterizedAgg
12764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12765#[cfg_attr(feature = "bindings", derive(TS))]
12766pub struct CombinedParameterizedAgg {
12767    pub this: Box<Expression>,
12768    #[serde(default)]
12769    pub expressions: Vec<Expression>,
12770    #[serde(default)]
12771    pub params: Vec<Expression>,
12772}
12773
12774/// HashAgg
12775#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12776#[cfg_attr(feature = "bindings", derive(TS))]
12777pub struct HashAgg {
12778    pub this: Box<Expression>,
12779    #[serde(default)]
12780    pub expressions: Vec<Expression>,
12781}
12782
12783/// Hll
12784#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12785#[cfg_attr(feature = "bindings", derive(TS))]
12786pub struct Hll {
12787    pub this: Box<Expression>,
12788    #[serde(default)]
12789    pub expressions: Vec<Expression>,
12790}
12791
12792/// Apply
12793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12794#[cfg_attr(feature = "bindings", derive(TS))]
12795pub struct Apply {
12796    pub this: Box<Expression>,
12797    pub expression: Box<Expression>,
12798}
12799
12800/// ToBoolean
12801#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12802#[cfg_attr(feature = "bindings", derive(TS))]
12803pub struct ToBoolean {
12804    pub this: Box<Expression>,
12805    #[serde(default)]
12806    pub safe: Option<Box<Expression>>,
12807}
12808
12809/// List
12810#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12811#[cfg_attr(feature = "bindings", derive(TS))]
12812pub struct List {
12813    #[serde(default)]
12814    pub expressions: Vec<Expression>,
12815}
12816
12817/// ToMap - Materialize-style map constructor
12818/// Can hold either:
12819/// - A SELECT subquery (MAP(SELECT 'a', 1))
12820/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
12821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12822#[cfg_attr(feature = "bindings", derive(TS))]
12823pub struct ToMap {
12824    /// Either a Select subquery or a Struct containing PropertyEQ entries
12825    pub this: Box<Expression>,
12826}
12827
12828/// Pad
12829#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12830#[cfg_attr(feature = "bindings", derive(TS))]
12831pub struct Pad {
12832    pub this: Box<Expression>,
12833    pub expression: Box<Expression>,
12834    #[serde(default)]
12835    pub fill_pattern: Option<Box<Expression>>,
12836    #[serde(default)]
12837    pub is_left: Option<Box<Expression>>,
12838}
12839
12840/// ToChar
12841#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12842#[cfg_attr(feature = "bindings", derive(TS))]
12843pub struct ToChar {
12844    pub this: Box<Expression>,
12845    #[serde(default)]
12846    pub format: Option<String>,
12847    #[serde(default)]
12848    pub nlsparam: Option<Box<Expression>>,
12849    #[serde(default)]
12850    pub is_numeric: Option<Box<Expression>>,
12851}
12852
12853/// StringFunc - String type conversion function (BigQuery STRING)
12854#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12855#[cfg_attr(feature = "bindings", derive(TS))]
12856pub struct StringFunc {
12857    pub this: Box<Expression>,
12858    #[serde(default)]
12859    pub zone: Option<Box<Expression>>,
12860}
12861
12862/// ToNumber
12863#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12864#[cfg_attr(feature = "bindings", derive(TS))]
12865pub struct ToNumber {
12866    pub this: Box<Expression>,
12867    #[serde(default)]
12868    pub format: Option<Box<Expression>>,
12869    #[serde(default)]
12870    pub nlsparam: Option<Box<Expression>>,
12871    #[serde(default)]
12872    pub precision: Option<Box<Expression>>,
12873    #[serde(default)]
12874    pub scale: Option<Box<Expression>>,
12875    #[serde(default)]
12876    pub safe: Option<Box<Expression>>,
12877    #[serde(default)]
12878    pub safe_name: Option<Box<Expression>>,
12879}
12880
12881/// ToDouble
12882#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12883#[cfg_attr(feature = "bindings", derive(TS))]
12884pub struct ToDouble {
12885    pub this: Box<Expression>,
12886    #[serde(default)]
12887    pub format: Option<String>,
12888    #[serde(default)]
12889    pub safe: Option<Box<Expression>>,
12890}
12891
12892/// ToDecfloat
12893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12894#[cfg_attr(feature = "bindings", derive(TS))]
12895pub struct ToDecfloat {
12896    pub this: Box<Expression>,
12897    #[serde(default)]
12898    pub format: Option<String>,
12899}
12900
12901/// TryToDecfloat
12902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12903#[cfg_attr(feature = "bindings", derive(TS))]
12904pub struct TryToDecfloat {
12905    pub this: Box<Expression>,
12906    #[serde(default)]
12907    pub format: Option<String>,
12908}
12909
12910/// ToFile
12911#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12912#[cfg_attr(feature = "bindings", derive(TS))]
12913pub struct ToFile {
12914    pub this: Box<Expression>,
12915    #[serde(default)]
12916    pub path: Option<Box<Expression>>,
12917    #[serde(default)]
12918    pub safe: Option<Box<Expression>>,
12919}
12920
12921/// Columns
12922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12923#[cfg_attr(feature = "bindings", derive(TS))]
12924pub struct Columns {
12925    pub this: Box<Expression>,
12926    #[serde(default)]
12927    pub unpack: Option<Box<Expression>>,
12928}
12929
12930/// ConvertToCharset
12931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12932#[cfg_attr(feature = "bindings", derive(TS))]
12933pub struct ConvertToCharset {
12934    pub this: Box<Expression>,
12935    #[serde(default)]
12936    pub dest: Option<Box<Expression>>,
12937    #[serde(default)]
12938    pub source: Option<Box<Expression>>,
12939}
12940
12941/// ConvertTimezone
12942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12943#[cfg_attr(feature = "bindings", derive(TS))]
12944pub struct ConvertTimezone {
12945    #[serde(default)]
12946    pub source_tz: Option<Box<Expression>>,
12947    #[serde(default)]
12948    pub target_tz: Option<Box<Expression>>,
12949    #[serde(default)]
12950    pub timestamp: Option<Box<Expression>>,
12951    #[serde(default)]
12952    pub options: Vec<Expression>,
12953}
12954
12955/// GenerateSeries
12956#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12957#[cfg_attr(feature = "bindings", derive(TS))]
12958pub struct GenerateSeries {
12959    #[serde(default)]
12960    pub start: Option<Box<Expression>>,
12961    #[serde(default)]
12962    pub end: Option<Box<Expression>>,
12963    #[serde(default)]
12964    pub step: Option<Box<Expression>>,
12965    #[serde(default)]
12966    pub is_end_exclusive: Option<Box<Expression>>,
12967}
12968
12969/// AIAgg
12970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12971#[cfg_attr(feature = "bindings", derive(TS))]
12972pub struct AIAgg {
12973    pub this: Box<Expression>,
12974    pub expression: Box<Expression>,
12975}
12976
12977/// AIClassify
12978#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12979#[cfg_attr(feature = "bindings", derive(TS))]
12980pub struct AIClassify {
12981    pub this: Box<Expression>,
12982    #[serde(default)]
12983    pub categories: Option<Box<Expression>>,
12984    #[serde(default)]
12985    pub config: Option<Box<Expression>>,
12986}
12987
12988/// ArrayAll
12989#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12990#[cfg_attr(feature = "bindings", derive(TS))]
12991pub struct ArrayAll {
12992    pub this: Box<Expression>,
12993    pub expression: Box<Expression>,
12994}
12995
12996/// ArrayAny
12997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12998#[cfg_attr(feature = "bindings", derive(TS))]
12999pub struct ArrayAny {
13000    pub this: Box<Expression>,
13001    pub expression: Box<Expression>,
13002}
13003
13004/// ArrayConstructCompact
13005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13006#[cfg_attr(feature = "bindings", derive(TS))]
13007pub struct ArrayConstructCompact {
13008    #[serde(default)]
13009    pub expressions: Vec<Expression>,
13010}
13011
13012/// StPoint
13013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13014#[cfg_attr(feature = "bindings", derive(TS))]
13015pub struct StPoint {
13016    pub this: Box<Expression>,
13017    pub expression: Box<Expression>,
13018    #[serde(default)]
13019    pub null: Option<Box<Expression>>,
13020}
13021
13022/// StDistance
13023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13024#[cfg_attr(feature = "bindings", derive(TS))]
13025pub struct StDistance {
13026    pub this: Box<Expression>,
13027    pub expression: Box<Expression>,
13028    #[serde(default)]
13029    pub use_spheroid: Option<Box<Expression>>,
13030}
13031
13032/// StringToArray
13033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13034#[cfg_attr(feature = "bindings", derive(TS))]
13035pub struct StringToArray {
13036    pub this: Box<Expression>,
13037    #[serde(default)]
13038    pub expression: Option<Box<Expression>>,
13039    #[serde(default)]
13040    pub null: Option<Box<Expression>>,
13041}
13042
13043/// ArraySum
13044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13045#[cfg_attr(feature = "bindings", derive(TS))]
13046pub struct ArraySum {
13047    pub this: Box<Expression>,
13048    #[serde(default)]
13049    pub expression: Option<Box<Expression>>,
13050}
13051
13052/// ObjectAgg
13053#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13054#[cfg_attr(feature = "bindings", derive(TS))]
13055pub struct ObjectAgg {
13056    pub this: Box<Expression>,
13057    pub expression: Box<Expression>,
13058}
13059
13060/// CastToStrType
13061#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13062#[cfg_attr(feature = "bindings", derive(TS))]
13063pub struct CastToStrType {
13064    pub this: Box<Expression>,
13065    #[serde(default)]
13066    pub to: Option<Box<Expression>>,
13067}
13068
13069/// CheckJson
13070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13071#[cfg_attr(feature = "bindings", derive(TS))]
13072pub struct CheckJson {
13073    pub this: Box<Expression>,
13074}
13075
13076/// CheckXml
13077#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13078#[cfg_attr(feature = "bindings", derive(TS))]
13079pub struct CheckXml {
13080    pub this: Box<Expression>,
13081    #[serde(default)]
13082    pub disable_auto_convert: Option<Box<Expression>>,
13083}
13084
13085/// TranslateCharacters
13086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13087#[cfg_attr(feature = "bindings", derive(TS))]
13088pub struct TranslateCharacters {
13089    pub this: Box<Expression>,
13090    pub expression: Box<Expression>,
13091    #[serde(default)]
13092    pub with_error: Option<Box<Expression>>,
13093}
13094
13095/// CurrentSchemas
13096#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13097#[cfg_attr(feature = "bindings", derive(TS))]
13098pub struct CurrentSchemas {
13099    #[serde(default)]
13100    pub this: Option<Box<Expression>>,
13101}
13102
13103/// CurrentDatetime
13104#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13105#[cfg_attr(feature = "bindings", derive(TS))]
13106pub struct CurrentDatetime {
13107    #[serde(default)]
13108    pub this: Option<Box<Expression>>,
13109}
13110
13111/// Localtime
13112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13113#[cfg_attr(feature = "bindings", derive(TS))]
13114pub struct Localtime {
13115    #[serde(default)]
13116    pub this: Option<Box<Expression>>,
13117}
13118
13119/// Localtimestamp
13120#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13121#[cfg_attr(feature = "bindings", derive(TS))]
13122pub struct Localtimestamp {
13123    #[serde(default)]
13124    pub this: Option<Box<Expression>>,
13125}
13126
13127/// Systimestamp
13128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13129#[cfg_attr(feature = "bindings", derive(TS))]
13130pub struct Systimestamp {
13131    #[serde(default)]
13132    pub this: Option<Box<Expression>>,
13133}
13134
13135/// CurrentSchema
13136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13137#[cfg_attr(feature = "bindings", derive(TS))]
13138pub struct CurrentSchema {
13139    #[serde(default)]
13140    pub this: Option<Box<Expression>>,
13141}
13142
13143/// CurrentUser
13144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13145#[cfg_attr(feature = "bindings", derive(TS))]
13146pub struct CurrentUser {
13147    #[serde(default)]
13148    pub this: Option<Box<Expression>>,
13149}
13150
13151/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13152#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13153#[cfg_attr(feature = "bindings", derive(TS))]
13154pub struct SessionUser;
13155
13156/// JSONPathRoot - Represents $ in JSON path expressions
13157#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13158#[cfg_attr(feature = "bindings", derive(TS))]
13159pub struct JSONPathRoot;
13160
13161/// UtcTime
13162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13163#[cfg_attr(feature = "bindings", derive(TS))]
13164pub struct UtcTime {
13165    #[serde(default)]
13166    pub this: Option<Box<Expression>>,
13167}
13168
13169/// UtcTimestamp
13170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13171#[cfg_attr(feature = "bindings", derive(TS))]
13172pub struct UtcTimestamp {
13173    #[serde(default)]
13174    pub this: Option<Box<Expression>>,
13175}
13176
13177/// TimestampFunc - TIMESTAMP constructor function
13178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13179#[cfg_attr(feature = "bindings", derive(TS))]
13180pub struct TimestampFunc {
13181    #[serde(default)]
13182    pub this: Option<Box<Expression>>,
13183    #[serde(default)]
13184    pub zone: Option<Box<Expression>>,
13185    #[serde(default)]
13186    pub with_tz: Option<bool>,
13187    #[serde(default)]
13188    pub safe: Option<bool>,
13189}
13190
13191/// DateBin
13192#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13193#[cfg_attr(feature = "bindings", derive(TS))]
13194pub struct DateBin {
13195    pub this: Box<Expression>,
13196    pub expression: Box<Expression>,
13197    #[serde(default)]
13198    pub unit: Option<String>,
13199    #[serde(default)]
13200    pub zone: Option<Box<Expression>>,
13201    #[serde(default)]
13202    pub origin: Option<Box<Expression>>,
13203}
13204
13205/// Datetime
13206#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13207#[cfg_attr(feature = "bindings", derive(TS))]
13208pub struct Datetime {
13209    pub this: Box<Expression>,
13210    #[serde(default)]
13211    pub expression: Option<Box<Expression>>,
13212}
13213
13214/// DatetimeAdd
13215#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13216#[cfg_attr(feature = "bindings", derive(TS))]
13217pub struct DatetimeAdd {
13218    pub this: Box<Expression>,
13219    pub expression: Box<Expression>,
13220    #[serde(default)]
13221    pub unit: Option<String>,
13222}
13223
13224/// DatetimeSub
13225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13226#[cfg_attr(feature = "bindings", derive(TS))]
13227pub struct DatetimeSub {
13228    pub this: Box<Expression>,
13229    pub expression: Box<Expression>,
13230    #[serde(default)]
13231    pub unit: Option<String>,
13232}
13233
13234/// DatetimeDiff
13235#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13236#[cfg_attr(feature = "bindings", derive(TS))]
13237pub struct DatetimeDiff {
13238    pub this: Box<Expression>,
13239    pub expression: Box<Expression>,
13240    #[serde(default)]
13241    pub unit: Option<String>,
13242}
13243
13244/// DatetimeTrunc
13245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13246#[cfg_attr(feature = "bindings", derive(TS))]
13247pub struct DatetimeTrunc {
13248    pub this: Box<Expression>,
13249    pub unit: String,
13250    #[serde(default)]
13251    pub zone: Option<Box<Expression>>,
13252}
13253
13254/// Dayname
13255#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13256#[cfg_attr(feature = "bindings", derive(TS))]
13257pub struct Dayname {
13258    pub this: Box<Expression>,
13259    #[serde(default)]
13260    pub abbreviated: Option<Box<Expression>>,
13261}
13262
13263/// MakeInterval
13264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13265#[cfg_attr(feature = "bindings", derive(TS))]
13266pub struct MakeInterval {
13267    #[serde(default)]
13268    pub year: Option<Box<Expression>>,
13269    #[serde(default)]
13270    pub month: Option<Box<Expression>>,
13271    #[serde(default)]
13272    pub week: Option<Box<Expression>>,
13273    #[serde(default)]
13274    pub day: Option<Box<Expression>>,
13275    #[serde(default)]
13276    pub hour: Option<Box<Expression>>,
13277    #[serde(default)]
13278    pub minute: Option<Box<Expression>>,
13279    #[serde(default)]
13280    pub second: Option<Box<Expression>>,
13281}
13282
13283/// PreviousDay
13284#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13285#[cfg_attr(feature = "bindings", derive(TS))]
13286pub struct PreviousDay {
13287    pub this: Box<Expression>,
13288    pub expression: Box<Expression>,
13289}
13290
13291/// Elt
13292#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13293#[cfg_attr(feature = "bindings", derive(TS))]
13294pub struct Elt {
13295    pub this: Box<Expression>,
13296    #[serde(default)]
13297    pub expressions: Vec<Expression>,
13298}
13299
13300/// TimestampAdd
13301#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13302#[cfg_attr(feature = "bindings", derive(TS))]
13303pub struct TimestampAdd {
13304    pub this: Box<Expression>,
13305    pub expression: Box<Expression>,
13306    #[serde(default)]
13307    pub unit: Option<String>,
13308}
13309
13310/// TimestampSub
13311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13312#[cfg_attr(feature = "bindings", derive(TS))]
13313pub struct TimestampSub {
13314    pub this: Box<Expression>,
13315    pub expression: Box<Expression>,
13316    #[serde(default)]
13317    pub unit: Option<String>,
13318}
13319
13320/// TimestampDiff
13321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13322#[cfg_attr(feature = "bindings", derive(TS))]
13323pub struct TimestampDiff {
13324    pub this: Box<Expression>,
13325    pub expression: Box<Expression>,
13326    #[serde(default)]
13327    pub unit: Option<String>,
13328}
13329
13330/// TimeSlice
13331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13332#[cfg_attr(feature = "bindings", derive(TS))]
13333pub struct TimeSlice {
13334    pub this: Box<Expression>,
13335    pub expression: Box<Expression>,
13336    pub unit: String,
13337    #[serde(default)]
13338    pub kind: Option<String>,
13339}
13340
13341/// TimeAdd
13342#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13343#[cfg_attr(feature = "bindings", derive(TS))]
13344pub struct TimeAdd {
13345    pub this: Box<Expression>,
13346    pub expression: Box<Expression>,
13347    #[serde(default)]
13348    pub unit: Option<String>,
13349}
13350
13351/// TimeSub
13352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13353#[cfg_attr(feature = "bindings", derive(TS))]
13354pub struct TimeSub {
13355    pub this: Box<Expression>,
13356    pub expression: Box<Expression>,
13357    #[serde(default)]
13358    pub unit: Option<String>,
13359}
13360
13361/// TimeDiff
13362#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13363#[cfg_attr(feature = "bindings", derive(TS))]
13364pub struct TimeDiff {
13365    pub this: Box<Expression>,
13366    pub expression: Box<Expression>,
13367    #[serde(default)]
13368    pub unit: Option<String>,
13369}
13370
13371/// TimeTrunc
13372#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13373#[cfg_attr(feature = "bindings", derive(TS))]
13374pub struct TimeTrunc {
13375    pub this: Box<Expression>,
13376    pub unit: String,
13377    #[serde(default)]
13378    pub zone: Option<Box<Expression>>,
13379}
13380
13381/// DateFromParts
13382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13383#[cfg_attr(feature = "bindings", derive(TS))]
13384pub struct DateFromParts {
13385    #[serde(default)]
13386    pub year: Option<Box<Expression>>,
13387    #[serde(default)]
13388    pub month: Option<Box<Expression>>,
13389    #[serde(default)]
13390    pub day: Option<Box<Expression>>,
13391    #[serde(default)]
13392    pub allow_overflow: Option<Box<Expression>>,
13393}
13394
13395/// TimeFromParts
13396#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13397#[cfg_attr(feature = "bindings", derive(TS))]
13398pub struct TimeFromParts {
13399    #[serde(default)]
13400    pub hour: Option<Box<Expression>>,
13401    #[serde(default)]
13402    pub min: Option<Box<Expression>>,
13403    #[serde(default)]
13404    pub sec: Option<Box<Expression>>,
13405    #[serde(default)]
13406    pub nano: Option<Box<Expression>>,
13407    #[serde(default)]
13408    pub fractions: Option<Box<Expression>>,
13409    #[serde(default)]
13410    pub precision: Option<i64>,
13411}
13412
13413/// DecodeCase
13414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13415#[cfg_attr(feature = "bindings", derive(TS))]
13416pub struct DecodeCase {
13417    #[serde(default)]
13418    pub expressions: Vec<Expression>,
13419}
13420
13421/// Decrypt
13422#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13423#[cfg_attr(feature = "bindings", derive(TS))]
13424pub struct Decrypt {
13425    pub this: Box<Expression>,
13426    #[serde(default)]
13427    pub passphrase: Option<Box<Expression>>,
13428    #[serde(default)]
13429    pub aad: Option<Box<Expression>>,
13430    #[serde(default)]
13431    pub encryption_method: Option<Box<Expression>>,
13432    #[serde(default)]
13433    pub safe: Option<Box<Expression>>,
13434}
13435
13436/// DecryptRaw
13437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13438#[cfg_attr(feature = "bindings", derive(TS))]
13439pub struct DecryptRaw {
13440    pub this: Box<Expression>,
13441    #[serde(default)]
13442    pub key: Option<Box<Expression>>,
13443    #[serde(default)]
13444    pub iv: Option<Box<Expression>>,
13445    #[serde(default)]
13446    pub aad: Option<Box<Expression>>,
13447    #[serde(default)]
13448    pub encryption_method: Option<Box<Expression>>,
13449    #[serde(default)]
13450    pub aead: Option<Box<Expression>>,
13451    #[serde(default)]
13452    pub safe: Option<Box<Expression>>,
13453}
13454
13455/// Encode
13456#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13457#[cfg_attr(feature = "bindings", derive(TS))]
13458pub struct Encode {
13459    pub this: Box<Expression>,
13460    #[serde(default)]
13461    pub charset: Option<Box<Expression>>,
13462}
13463
13464/// Encrypt
13465#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13466#[cfg_attr(feature = "bindings", derive(TS))]
13467pub struct Encrypt {
13468    pub this: Box<Expression>,
13469    #[serde(default)]
13470    pub passphrase: Option<Box<Expression>>,
13471    #[serde(default)]
13472    pub aad: Option<Box<Expression>>,
13473    #[serde(default)]
13474    pub encryption_method: Option<Box<Expression>>,
13475}
13476
13477/// EncryptRaw
13478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13479#[cfg_attr(feature = "bindings", derive(TS))]
13480pub struct EncryptRaw {
13481    pub this: Box<Expression>,
13482    #[serde(default)]
13483    pub key: Option<Box<Expression>>,
13484    #[serde(default)]
13485    pub iv: Option<Box<Expression>>,
13486    #[serde(default)]
13487    pub aad: Option<Box<Expression>>,
13488    #[serde(default)]
13489    pub encryption_method: Option<Box<Expression>>,
13490}
13491
13492/// EqualNull
13493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13494#[cfg_attr(feature = "bindings", derive(TS))]
13495pub struct EqualNull {
13496    pub this: Box<Expression>,
13497    pub expression: Box<Expression>,
13498}
13499
13500/// ToBinary
13501#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13502#[cfg_attr(feature = "bindings", derive(TS))]
13503pub struct ToBinary {
13504    pub this: Box<Expression>,
13505    #[serde(default)]
13506    pub format: Option<String>,
13507    #[serde(default)]
13508    pub safe: Option<Box<Expression>>,
13509}
13510
13511/// Base64DecodeBinary
13512#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13513#[cfg_attr(feature = "bindings", derive(TS))]
13514pub struct Base64DecodeBinary {
13515    pub this: Box<Expression>,
13516    #[serde(default)]
13517    pub alphabet: Option<Box<Expression>>,
13518}
13519
13520/// Base64DecodeString
13521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13522#[cfg_attr(feature = "bindings", derive(TS))]
13523pub struct Base64DecodeString {
13524    pub this: Box<Expression>,
13525    #[serde(default)]
13526    pub alphabet: Option<Box<Expression>>,
13527}
13528
13529/// Base64Encode
13530#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13531#[cfg_attr(feature = "bindings", derive(TS))]
13532pub struct Base64Encode {
13533    pub this: Box<Expression>,
13534    #[serde(default)]
13535    pub max_line_length: Option<Box<Expression>>,
13536    #[serde(default)]
13537    pub alphabet: Option<Box<Expression>>,
13538}
13539
13540/// TryBase64DecodeBinary
13541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13542#[cfg_attr(feature = "bindings", derive(TS))]
13543pub struct TryBase64DecodeBinary {
13544    pub this: Box<Expression>,
13545    #[serde(default)]
13546    pub alphabet: Option<Box<Expression>>,
13547}
13548
13549/// TryBase64DecodeString
13550#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13551#[cfg_attr(feature = "bindings", derive(TS))]
13552pub struct TryBase64DecodeString {
13553    pub this: Box<Expression>,
13554    #[serde(default)]
13555    pub alphabet: Option<Box<Expression>>,
13556}
13557
13558/// GapFill
13559#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13560#[cfg_attr(feature = "bindings", derive(TS))]
13561pub struct GapFill {
13562    pub this: Box<Expression>,
13563    #[serde(default)]
13564    pub ts_column: Option<Box<Expression>>,
13565    #[serde(default)]
13566    pub bucket_width: Option<Box<Expression>>,
13567    #[serde(default)]
13568    pub partitioning_columns: Option<Box<Expression>>,
13569    #[serde(default)]
13570    pub value_columns: Option<Box<Expression>>,
13571    #[serde(default)]
13572    pub origin: Option<Box<Expression>>,
13573    #[serde(default)]
13574    pub ignore_nulls: Option<Box<Expression>>,
13575}
13576
13577/// GenerateDateArray
13578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13579#[cfg_attr(feature = "bindings", derive(TS))]
13580pub struct GenerateDateArray {
13581    #[serde(default)]
13582    pub start: Option<Box<Expression>>,
13583    #[serde(default)]
13584    pub end: Option<Box<Expression>>,
13585    #[serde(default)]
13586    pub step: Option<Box<Expression>>,
13587}
13588
13589/// GenerateTimestampArray
13590#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13591#[cfg_attr(feature = "bindings", derive(TS))]
13592pub struct GenerateTimestampArray {
13593    #[serde(default)]
13594    pub start: Option<Box<Expression>>,
13595    #[serde(default)]
13596    pub end: Option<Box<Expression>>,
13597    #[serde(default)]
13598    pub step: Option<Box<Expression>>,
13599}
13600
13601/// GetExtract
13602#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13603#[cfg_attr(feature = "bindings", derive(TS))]
13604pub struct GetExtract {
13605    pub this: Box<Expression>,
13606    pub expression: Box<Expression>,
13607}
13608
13609/// Getbit
13610#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13611#[cfg_attr(feature = "bindings", derive(TS))]
13612pub struct Getbit {
13613    pub this: Box<Expression>,
13614    pub expression: Box<Expression>,
13615    #[serde(default)]
13616    pub zero_is_msb: Option<Box<Expression>>,
13617}
13618
13619/// OverflowTruncateBehavior
13620#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13621#[cfg_attr(feature = "bindings", derive(TS))]
13622pub struct OverflowTruncateBehavior {
13623    #[serde(default)]
13624    pub this: Option<Box<Expression>>,
13625    #[serde(default)]
13626    pub with_count: Option<Box<Expression>>,
13627}
13628
13629/// HexEncode
13630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13631#[cfg_attr(feature = "bindings", derive(TS))]
13632pub struct HexEncode {
13633    pub this: Box<Expression>,
13634    #[serde(default)]
13635    pub case: Option<Box<Expression>>,
13636}
13637
13638/// Compress
13639#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13640#[cfg_attr(feature = "bindings", derive(TS))]
13641pub struct Compress {
13642    pub this: Box<Expression>,
13643    #[serde(default)]
13644    pub method: Option<String>,
13645}
13646
13647/// DecompressBinary
13648#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13649#[cfg_attr(feature = "bindings", derive(TS))]
13650pub struct DecompressBinary {
13651    pub this: Box<Expression>,
13652    pub method: String,
13653}
13654
13655/// DecompressString
13656#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13657#[cfg_attr(feature = "bindings", derive(TS))]
13658pub struct DecompressString {
13659    pub this: Box<Expression>,
13660    pub method: String,
13661}
13662
13663/// Xor
13664#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13665#[cfg_attr(feature = "bindings", derive(TS))]
13666pub struct Xor {
13667    #[serde(default)]
13668    pub this: Option<Box<Expression>>,
13669    #[serde(default)]
13670    pub expression: Option<Box<Expression>>,
13671    #[serde(default)]
13672    pub expressions: Vec<Expression>,
13673}
13674
13675/// Nullif
13676#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13677#[cfg_attr(feature = "bindings", derive(TS))]
13678pub struct Nullif {
13679    pub this: Box<Expression>,
13680    pub expression: Box<Expression>,
13681}
13682
13683/// JSON
13684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13685#[cfg_attr(feature = "bindings", derive(TS))]
13686pub struct JSON {
13687    #[serde(default)]
13688    pub this: Option<Box<Expression>>,
13689    #[serde(default)]
13690    pub with_: Option<Box<Expression>>,
13691    #[serde(default)]
13692    pub unique: bool,
13693}
13694
13695/// JSONPath
13696#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13697#[cfg_attr(feature = "bindings", derive(TS))]
13698pub struct JSONPath {
13699    #[serde(default)]
13700    pub expressions: Vec<Expression>,
13701    #[serde(default)]
13702    pub escape: Option<Box<Expression>>,
13703}
13704
13705/// JSONPathFilter
13706#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13707#[cfg_attr(feature = "bindings", derive(TS))]
13708pub struct JSONPathFilter {
13709    pub this: Box<Expression>,
13710}
13711
13712/// JSONPathKey
13713#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13714#[cfg_attr(feature = "bindings", derive(TS))]
13715pub struct JSONPathKey {
13716    pub this: Box<Expression>,
13717}
13718
13719/// JSONPathRecursive
13720#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13721#[cfg_attr(feature = "bindings", derive(TS))]
13722pub struct JSONPathRecursive {
13723    #[serde(default)]
13724    pub this: Option<Box<Expression>>,
13725}
13726
13727/// JSONPathScript
13728#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13729#[cfg_attr(feature = "bindings", derive(TS))]
13730pub struct JSONPathScript {
13731    pub this: Box<Expression>,
13732}
13733
13734/// JSONPathSlice
13735#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13736#[cfg_attr(feature = "bindings", derive(TS))]
13737pub struct JSONPathSlice {
13738    #[serde(default)]
13739    pub start: Option<Box<Expression>>,
13740    #[serde(default)]
13741    pub end: Option<Box<Expression>>,
13742    #[serde(default)]
13743    pub step: Option<Box<Expression>>,
13744}
13745
13746/// JSONPathSelector
13747#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13748#[cfg_attr(feature = "bindings", derive(TS))]
13749pub struct JSONPathSelector {
13750    pub this: Box<Expression>,
13751}
13752
13753/// JSONPathSubscript
13754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13755#[cfg_attr(feature = "bindings", derive(TS))]
13756pub struct JSONPathSubscript {
13757    pub this: Box<Expression>,
13758}
13759
13760/// JSONPathUnion
13761#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13762#[cfg_attr(feature = "bindings", derive(TS))]
13763pub struct JSONPathUnion {
13764    #[serde(default)]
13765    pub expressions: Vec<Expression>,
13766}
13767
13768/// Format
13769#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13770#[cfg_attr(feature = "bindings", derive(TS))]
13771pub struct Format {
13772    pub this: Box<Expression>,
13773    #[serde(default)]
13774    pub expressions: Vec<Expression>,
13775}
13776
13777/// JSONKeys
13778#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13779#[cfg_attr(feature = "bindings", derive(TS))]
13780pub struct JSONKeys {
13781    pub this: Box<Expression>,
13782    #[serde(default)]
13783    pub expression: Option<Box<Expression>>,
13784    #[serde(default)]
13785    pub expressions: Vec<Expression>,
13786}
13787
13788/// JSONKeyValue
13789#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13790#[cfg_attr(feature = "bindings", derive(TS))]
13791pub struct JSONKeyValue {
13792    pub this: Box<Expression>,
13793    pub expression: Box<Expression>,
13794}
13795
13796/// JSONKeysAtDepth
13797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13798#[cfg_attr(feature = "bindings", derive(TS))]
13799pub struct JSONKeysAtDepth {
13800    pub this: Box<Expression>,
13801    #[serde(default)]
13802    pub expression: Option<Box<Expression>>,
13803    #[serde(default)]
13804    pub mode: Option<Box<Expression>>,
13805}
13806
13807/// JSONObject
13808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13809#[cfg_attr(feature = "bindings", derive(TS))]
13810pub struct JSONObject {
13811    #[serde(default)]
13812    pub expressions: Vec<Expression>,
13813    #[serde(default)]
13814    pub null_handling: Option<Box<Expression>>,
13815    #[serde(default)]
13816    pub unique_keys: Option<Box<Expression>>,
13817    #[serde(default)]
13818    pub return_type: Option<Box<Expression>>,
13819    #[serde(default)]
13820    pub encoding: Option<Box<Expression>>,
13821}
13822
13823/// JSONObjectAgg
13824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13825#[cfg_attr(feature = "bindings", derive(TS))]
13826pub struct JSONObjectAgg {
13827    #[serde(default)]
13828    pub expressions: Vec<Expression>,
13829    #[serde(default)]
13830    pub null_handling: Option<Box<Expression>>,
13831    #[serde(default)]
13832    pub unique_keys: Option<Box<Expression>>,
13833    #[serde(default)]
13834    pub return_type: Option<Box<Expression>>,
13835    #[serde(default)]
13836    pub encoding: Option<Box<Expression>>,
13837}
13838
13839/// JSONBObjectAgg
13840#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13841#[cfg_attr(feature = "bindings", derive(TS))]
13842pub struct JSONBObjectAgg {
13843    pub this: Box<Expression>,
13844    pub expression: Box<Expression>,
13845}
13846
13847/// JSONArray
13848#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13849#[cfg_attr(feature = "bindings", derive(TS))]
13850pub struct JSONArray {
13851    #[serde(default)]
13852    pub expressions: Vec<Expression>,
13853    #[serde(default)]
13854    pub null_handling: Option<Box<Expression>>,
13855    #[serde(default)]
13856    pub return_type: Option<Box<Expression>>,
13857    #[serde(default)]
13858    pub strict: Option<Box<Expression>>,
13859}
13860
13861/// JSONArrayAgg
13862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13863#[cfg_attr(feature = "bindings", derive(TS))]
13864pub struct JSONArrayAgg {
13865    pub this: Box<Expression>,
13866    #[serde(default)]
13867    pub order: Option<Box<Expression>>,
13868    #[serde(default)]
13869    pub null_handling: Option<Box<Expression>>,
13870    #[serde(default)]
13871    pub return_type: Option<Box<Expression>>,
13872    #[serde(default)]
13873    pub strict: Option<Box<Expression>>,
13874}
13875
13876/// JSONExists
13877#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13878#[cfg_attr(feature = "bindings", derive(TS))]
13879pub struct JSONExists {
13880    pub this: Box<Expression>,
13881    #[serde(default)]
13882    pub path: Option<Box<Expression>>,
13883    #[serde(default)]
13884    pub passing: Option<Box<Expression>>,
13885    #[serde(default)]
13886    pub on_condition: Option<Box<Expression>>,
13887    #[serde(default)]
13888    pub from_dcolonqmark: Option<Box<Expression>>,
13889}
13890
13891/// JSONColumnDef
13892#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13893#[cfg_attr(feature = "bindings", derive(TS))]
13894pub struct JSONColumnDef {
13895    #[serde(default)]
13896    pub this: Option<Box<Expression>>,
13897    #[serde(default)]
13898    pub kind: Option<String>,
13899    #[serde(default)]
13900    pub format_json: bool,
13901    #[serde(default)]
13902    pub path: Option<Box<Expression>>,
13903    #[serde(default)]
13904    pub nested_schema: Option<Box<Expression>>,
13905    #[serde(default)]
13906    pub ordinality: Option<Box<Expression>>,
13907}
13908
13909/// JSONSchema
13910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13911#[cfg_attr(feature = "bindings", derive(TS))]
13912pub struct JSONSchema {
13913    #[serde(default)]
13914    pub expressions: Vec<Expression>,
13915}
13916
13917/// JSONSet
13918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13919#[cfg_attr(feature = "bindings", derive(TS))]
13920pub struct JSONSet {
13921    pub this: Box<Expression>,
13922    #[serde(default)]
13923    pub expressions: Vec<Expression>,
13924}
13925
13926/// JSONStripNulls
13927#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13928#[cfg_attr(feature = "bindings", derive(TS))]
13929pub struct JSONStripNulls {
13930    pub this: Box<Expression>,
13931    #[serde(default)]
13932    pub expression: Option<Box<Expression>>,
13933    #[serde(default)]
13934    pub include_arrays: Option<Box<Expression>>,
13935    #[serde(default)]
13936    pub remove_empty: Option<Box<Expression>>,
13937}
13938
13939/// JSONValue
13940#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13941#[cfg_attr(feature = "bindings", derive(TS))]
13942pub struct JSONValue {
13943    pub this: Box<Expression>,
13944    #[serde(default)]
13945    pub path: Option<Box<Expression>>,
13946    #[serde(default)]
13947    pub returning: Option<Box<Expression>>,
13948    #[serde(default)]
13949    pub on_condition: Option<Box<Expression>>,
13950}
13951
13952/// JSONValueArray
13953#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13954#[cfg_attr(feature = "bindings", derive(TS))]
13955pub struct JSONValueArray {
13956    pub this: Box<Expression>,
13957    #[serde(default)]
13958    pub expression: Option<Box<Expression>>,
13959}
13960
13961/// JSONRemove
13962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13963#[cfg_attr(feature = "bindings", derive(TS))]
13964pub struct JSONRemove {
13965    pub this: Box<Expression>,
13966    #[serde(default)]
13967    pub expressions: Vec<Expression>,
13968}
13969
13970/// JSONTable
13971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13972#[cfg_attr(feature = "bindings", derive(TS))]
13973pub struct JSONTable {
13974    pub this: Box<Expression>,
13975    #[serde(default)]
13976    pub schema: Option<Box<Expression>>,
13977    #[serde(default)]
13978    pub path: Option<Box<Expression>>,
13979    #[serde(default)]
13980    pub error_handling: Option<Box<Expression>>,
13981    #[serde(default)]
13982    pub empty_handling: Option<Box<Expression>>,
13983}
13984
13985/// JSONType
13986#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13987#[cfg_attr(feature = "bindings", derive(TS))]
13988pub struct JSONType {
13989    pub this: Box<Expression>,
13990    #[serde(default)]
13991    pub expression: Option<Box<Expression>>,
13992}
13993
13994/// ObjectInsert
13995#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13996#[cfg_attr(feature = "bindings", derive(TS))]
13997pub struct ObjectInsert {
13998    pub this: Box<Expression>,
13999    #[serde(default)]
14000    pub key: Option<Box<Expression>>,
14001    #[serde(default)]
14002    pub value: Option<Box<Expression>>,
14003    #[serde(default)]
14004    pub update_flag: Option<Box<Expression>>,
14005}
14006
14007/// OpenJSONColumnDef
14008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14009#[cfg_attr(feature = "bindings", derive(TS))]
14010pub struct OpenJSONColumnDef {
14011    pub this: Box<Expression>,
14012    pub kind: String,
14013    #[serde(default)]
14014    pub path: Option<Box<Expression>>,
14015    #[serde(default)]
14016    pub as_json: Option<Box<Expression>>,
14017    /// The parsed data type for proper generation
14018    #[serde(default, skip_serializing_if = "Option::is_none")]
14019    pub data_type: Option<DataType>,
14020}
14021
14022/// OpenJSON
14023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14024#[cfg_attr(feature = "bindings", derive(TS))]
14025pub struct OpenJSON {
14026    pub this: Box<Expression>,
14027    #[serde(default)]
14028    pub path: Option<Box<Expression>>,
14029    #[serde(default)]
14030    pub expressions: Vec<Expression>,
14031}
14032
14033/// JSONBExists
14034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14035#[cfg_attr(feature = "bindings", derive(TS))]
14036pub struct JSONBExists {
14037    pub this: Box<Expression>,
14038    #[serde(default)]
14039    pub path: Option<Box<Expression>>,
14040}
14041
14042/// JSONCast
14043#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14044#[cfg_attr(feature = "bindings", derive(TS))]
14045pub struct JSONCast {
14046    pub this: Box<Expression>,
14047    pub to: DataType,
14048}
14049
14050/// JSONExtract
14051#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14052#[cfg_attr(feature = "bindings", derive(TS))]
14053pub struct JSONExtract {
14054    pub this: Box<Expression>,
14055    pub expression: Box<Expression>,
14056    #[serde(default)]
14057    pub only_json_types: Option<Box<Expression>>,
14058    #[serde(default)]
14059    pub expressions: Vec<Expression>,
14060    #[serde(default)]
14061    pub variant_extract: Option<Box<Expression>>,
14062    #[serde(default)]
14063    pub json_query: Option<Box<Expression>>,
14064    #[serde(default)]
14065    pub option: Option<Box<Expression>>,
14066    #[serde(default)]
14067    pub quote: Option<Box<Expression>>,
14068    #[serde(default)]
14069    pub on_condition: Option<Box<Expression>>,
14070    #[serde(default)]
14071    pub requires_json: Option<Box<Expression>>,
14072}
14073
14074/// JSONExtractQuote
14075#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14076#[cfg_attr(feature = "bindings", derive(TS))]
14077pub struct JSONExtractQuote {
14078    #[serde(default)]
14079    pub option: Option<Box<Expression>>,
14080    #[serde(default)]
14081    pub scalar: Option<Box<Expression>>,
14082}
14083
14084/// JSONExtractArray
14085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14086#[cfg_attr(feature = "bindings", derive(TS))]
14087pub struct JSONExtractArray {
14088    pub this: Box<Expression>,
14089    #[serde(default)]
14090    pub expression: Option<Box<Expression>>,
14091}
14092
14093/// JSONExtractScalar
14094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14095#[cfg_attr(feature = "bindings", derive(TS))]
14096pub struct JSONExtractScalar {
14097    pub this: Box<Expression>,
14098    pub expression: Box<Expression>,
14099    #[serde(default)]
14100    pub only_json_types: Option<Box<Expression>>,
14101    #[serde(default)]
14102    pub expressions: Vec<Expression>,
14103    #[serde(default)]
14104    pub json_type: Option<Box<Expression>>,
14105    #[serde(default)]
14106    pub scalar_only: Option<Box<Expression>>,
14107}
14108
14109/// JSONBExtractScalar
14110#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14111#[cfg_attr(feature = "bindings", derive(TS))]
14112pub struct JSONBExtractScalar {
14113    pub this: Box<Expression>,
14114    pub expression: Box<Expression>,
14115    #[serde(default)]
14116    pub json_type: Option<Box<Expression>>,
14117}
14118
14119/// JSONFormat
14120#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14121#[cfg_attr(feature = "bindings", derive(TS))]
14122pub struct JSONFormat {
14123    #[serde(default)]
14124    pub this: Option<Box<Expression>>,
14125    #[serde(default)]
14126    pub options: Vec<Expression>,
14127    #[serde(default)]
14128    pub is_json: Option<Box<Expression>>,
14129    #[serde(default)]
14130    pub to_json: Option<Box<Expression>>,
14131}
14132
14133/// JSONArrayAppend
14134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14135#[cfg_attr(feature = "bindings", derive(TS))]
14136pub struct JSONArrayAppend {
14137    pub this: Box<Expression>,
14138    #[serde(default)]
14139    pub expressions: Vec<Expression>,
14140}
14141
14142/// JSONArrayContains
14143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14144#[cfg_attr(feature = "bindings", derive(TS))]
14145pub struct JSONArrayContains {
14146    pub this: Box<Expression>,
14147    pub expression: Box<Expression>,
14148    #[serde(default)]
14149    pub json_type: Option<Box<Expression>>,
14150}
14151
14152/// JSONArrayInsert
14153#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14154#[cfg_attr(feature = "bindings", derive(TS))]
14155pub struct JSONArrayInsert {
14156    pub this: Box<Expression>,
14157    #[serde(default)]
14158    pub expressions: Vec<Expression>,
14159}
14160
14161/// ParseJSON
14162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14163#[cfg_attr(feature = "bindings", derive(TS))]
14164pub struct ParseJSON {
14165    pub this: Box<Expression>,
14166    #[serde(default)]
14167    pub expression: Option<Box<Expression>>,
14168    #[serde(default)]
14169    pub safe: Option<Box<Expression>>,
14170}
14171
14172/// ParseUrl
14173#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14174#[cfg_attr(feature = "bindings", derive(TS))]
14175pub struct ParseUrl {
14176    pub this: Box<Expression>,
14177    #[serde(default)]
14178    pub part_to_extract: Option<Box<Expression>>,
14179    #[serde(default)]
14180    pub key: Option<Box<Expression>>,
14181    #[serde(default)]
14182    pub permissive: Option<Box<Expression>>,
14183}
14184
14185/// ParseIp
14186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14187#[cfg_attr(feature = "bindings", derive(TS))]
14188pub struct ParseIp {
14189    pub this: Box<Expression>,
14190    #[serde(default)]
14191    pub type_: Option<Box<Expression>>,
14192    #[serde(default)]
14193    pub permissive: Option<Box<Expression>>,
14194}
14195
14196/// ParseTime
14197#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14198#[cfg_attr(feature = "bindings", derive(TS))]
14199pub struct ParseTime {
14200    pub this: Box<Expression>,
14201    pub format: String,
14202}
14203
14204/// ParseDatetime
14205#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14206#[cfg_attr(feature = "bindings", derive(TS))]
14207pub struct ParseDatetime {
14208    pub this: Box<Expression>,
14209    #[serde(default)]
14210    pub format: Option<String>,
14211    #[serde(default)]
14212    pub zone: Option<Box<Expression>>,
14213}
14214
14215/// Map
14216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14217#[cfg_attr(feature = "bindings", derive(TS))]
14218pub struct Map {
14219    #[serde(default)]
14220    pub keys: Vec<Expression>,
14221    #[serde(default)]
14222    pub values: Vec<Expression>,
14223}
14224
14225/// MapCat
14226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14227#[cfg_attr(feature = "bindings", derive(TS))]
14228pub struct MapCat {
14229    pub this: Box<Expression>,
14230    pub expression: Box<Expression>,
14231}
14232
14233/// MapDelete
14234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14235#[cfg_attr(feature = "bindings", derive(TS))]
14236pub struct MapDelete {
14237    pub this: Box<Expression>,
14238    #[serde(default)]
14239    pub expressions: Vec<Expression>,
14240}
14241
14242/// MapInsert
14243#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14244#[cfg_attr(feature = "bindings", derive(TS))]
14245pub struct MapInsert {
14246    pub this: Box<Expression>,
14247    #[serde(default)]
14248    pub key: Option<Box<Expression>>,
14249    #[serde(default)]
14250    pub value: Option<Box<Expression>>,
14251    #[serde(default)]
14252    pub update_flag: Option<Box<Expression>>,
14253}
14254
14255/// MapPick
14256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14257#[cfg_attr(feature = "bindings", derive(TS))]
14258pub struct MapPick {
14259    pub this: Box<Expression>,
14260    #[serde(default)]
14261    pub expressions: Vec<Expression>,
14262}
14263
14264/// ScopeResolution
14265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14266#[cfg_attr(feature = "bindings", derive(TS))]
14267pub struct ScopeResolution {
14268    #[serde(default)]
14269    pub this: Option<Box<Expression>>,
14270    pub expression: Box<Expression>,
14271}
14272
14273/// Slice
14274#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14275#[cfg_attr(feature = "bindings", derive(TS))]
14276pub struct Slice {
14277    #[serde(default)]
14278    pub this: Option<Box<Expression>>,
14279    #[serde(default)]
14280    pub expression: Option<Box<Expression>>,
14281    #[serde(default)]
14282    pub step: Option<Box<Expression>>,
14283}
14284
14285/// VarMap
14286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14287#[cfg_attr(feature = "bindings", derive(TS))]
14288pub struct VarMap {
14289    #[serde(default)]
14290    pub keys: Vec<Expression>,
14291    #[serde(default)]
14292    pub values: Vec<Expression>,
14293}
14294
14295/// MatchAgainst
14296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14297#[cfg_attr(feature = "bindings", derive(TS))]
14298pub struct MatchAgainst {
14299    pub this: Box<Expression>,
14300    #[serde(default)]
14301    pub expressions: Vec<Expression>,
14302    #[serde(default)]
14303    pub modifier: Option<Box<Expression>>,
14304}
14305
14306/// MD5Digest
14307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14308#[cfg_attr(feature = "bindings", derive(TS))]
14309pub struct MD5Digest {
14310    pub this: Box<Expression>,
14311    #[serde(default)]
14312    pub expressions: Vec<Expression>,
14313}
14314
14315/// Monthname
14316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14317#[cfg_attr(feature = "bindings", derive(TS))]
14318pub struct Monthname {
14319    pub this: Box<Expression>,
14320    #[serde(default)]
14321    pub abbreviated: Option<Box<Expression>>,
14322}
14323
14324/// Ntile
14325#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14326#[cfg_attr(feature = "bindings", derive(TS))]
14327pub struct Ntile {
14328    #[serde(default)]
14329    pub this: Option<Box<Expression>>,
14330}
14331
14332/// Normalize
14333#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14334#[cfg_attr(feature = "bindings", derive(TS))]
14335pub struct Normalize {
14336    pub this: Box<Expression>,
14337    #[serde(default)]
14338    pub form: Option<Box<Expression>>,
14339    #[serde(default)]
14340    pub is_casefold: Option<Box<Expression>>,
14341}
14342
14343/// Normal
14344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14345#[cfg_attr(feature = "bindings", derive(TS))]
14346pub struct Normal {
14347    pub this: Box<Expression>,
14348    #[serde(default)]
14349    pub stddev: Option<Box<Expression>>,
14350    #[serde(default)]
14351    pub gen: Option<Box<Expression>>,
14352}
14353
14354/// Predict
14355#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14356#[cfg_attr(feature = "bindings", derive(TS))]
14357pub struct Predict {
14358    pub this: Box<Expression>,
14359    pub expression: Box<Expression>,
14360    #[serde(default)]
14361    pub params_struct: Option<Box<Expression>>,
14362}
14363
14364/// MLTranslate
14365#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14366#[cfg_attr(feature = "bindings", derive(TS))]
14367pub struct MLTranslate {
14368    pub this: Box<Expression>,
14369    pub expression: Box<Expression>,
14370    #[serde(default)]
14371    pub params_struct: Option<Box<Expression>>,
14372}
14373
14374/// FeaturesAtTime
14375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14376#[cfg_attr(feature = "bindings", derive(TS))]
14377pub struct FeaturesAtTime {
14378    pub this: Box<Expression>,
14379    #[serde(default)]
14380    pub time: Option<Box<Expression>>,
14381    #[serde(default)]
14382    pub num_rows: Option<Box<Expression>>,
14383    #[serde(default)]
14384    pub ignore_feature_nulls: Option<Box<Expression>>,
14385}
14386
14387/// GenerateEmbedding
14388#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14389#[cfg_attr(feature = "bindings", derive(TS))]
14390pub struct GenerateEmbedding {
14391    pub this: Box<Expression>,
14392    pub expression: Box<Expression>,
14393    #[serde(default)]
14394    pub params_struct: Option<Box<Expression>>,
14395    #[serde(default)]
14396    pub is_text: Option<Box<Expression>>,
14397}
14398
14399/// MLForecast
14400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14401#[cfg_attr(feature = "bindings", derive(TS))]
14402pub struct MLForecast {
14403    pub this: Box<Expression>,
14404    #[serde(default)]
14405    pub expression: Option<Box<Expression>>,
14406    #[serde(default)]
14407    pub params_struct: Option<Box<Expression>>,
14408}
14409
14410/// ModelAttribute
14411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14412#[cfg_attr(feature = "bindings", derive(TS))]
14413pub struct ModelAttribute {
14414    pub this: Box<Expression>,
14415    pub expression: Box<Expression>,
14416}
14417
14418/// VectorSearch
14419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14420#[cfg_attr(feature = "bindings", derive(TS))]
14421pub struct VectorSearch {
14422    pub this: Box<Expression>,
14423    #[serde(default)]
14424    pub column_to_search: Option<Box<Expression>>,
14425    #[serde(default)]
14426    pub query_table: Option<Box<Expression>>,
14427    #[serde(default)]
14428    pub query_column_to_search: Option<Box<Expression>>,
14429    #[serde(default)]
14430    pub top_k: Option<Box<Expression>>,
14431    #[serde(default)]
14432    pub distance_type: Option<Box<Expression>>,
14433    #[serde(default)]
14434    pub options: Vec<Expression>,
14435}
14436
14437/// Quantile
14438#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14439#[cfg_attr(feature = "bindings", derive(TS))]
14440pub struct Quantile {
14441    pub this: Box<Expression>,
14442    #[serde(default)]
14443    pub quantile: Option<Box<Expression>>,
14444}
14445
14446/// ApproxQuantile
14447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14448#[cfg_attr(feature = "bindings", derive(TS))]
14449pub struct ApproxQuantile {
14450    pub this: Box<Expression>,
14451    #[serde(default)]
14452    pub quantile: Option<Box<Expression>>,
14453    #[serde(default)]
14454    pub accuracy: Option<Box<Expression>>,
14455    #[serde(default)]
14456    pub weight: Option<Box<Expression>>,
14457    #[serde(default)]
14458    pub error_tolerance: Option<Box<Expression>>,
14459}
14460
14461/// ApproxPercentileEstimate
14462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14463#[cfg_attr(feature = "bindings", derive(TS))]
14464pub struct ApproxPercentileEstimate {
14465    pub this: Box<Expression>,
14466    #[serde(default)]
14467    pub percentile: Option<Box<Expression>>,
14468}
14469
14470/// Randn
14471#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14472#[cfg_attr(feature = "bindings", derive(TS))]
14473pub struct Randn {
14474    #[serde(default)]
14475    pub this: Option<Box<Expression>>,
14476}
14477
14478/// Randstr
14479#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14480#[cfg_attr(feature = "bindings", derive(TS))]
14481pub struct Randstr {
14482    pub this: Box<Expression>,
14483    #[serde(default)]
14484    pub generator: Option<Box<Expression>>,
14485}
14486
14487/// RangeN
14488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14489#[cfg_attr(feature = "bindings", derive(TS))]
14490pub struct RangeN {
14491    pub this: Box<Expression>,
14492    #[serde(default)]
14493    pub expressions: Vec<Expression>,
14494    #[serde(default)]
14495    pub each: Option<Box<Expression>>,
14496}
14497
14498/// RangeBucket
14499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14500#[cfg_attr(feature = "bindings", derive(TS))]
14501pub struct RangeBucket {
14502    pub this: Box<Expression>,
14503    pub expression: Box<Expression>,
14504}
14505
14506/// ReadCSV
14507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14508#[cfg_attr(feature = "bindings", derive(TS))]
14509pub struct ReadCSV {
14510    pub this: Box<Expression>,
14511    #[serde(default)]
14512    pub expressions: Vec<Expression>,
14513}
14514
14515/// ReadParquet
14516#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14517#[cfg_attr(feature = "bindings", derive(TS))]
14518pub struct ReadParquet {
14519    #[serde(default)]
14520    pub expressions: Vec<Expression>,
14521}
14522
14523/// Reduce
14524#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14525#[cfg_attr(feature = "bindings", derive(TS))]
14526pub struct Reduce {
14527    pub this: Box<Expression>,
14528    #[serde(default)]
14529    pub initial: Option<Box<Expression>>,
14530    #[serde(default)]
14531    pub merge: Option<Box<Expression>>,
14532    #[serde(default)]
14533    pub finish: Option<Box<Expression>>,
14534}
14535
14536/// RegexpExtractAll
14537#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14538#[cfg_attr(feature = "bindings", derive(TS))]
14539pub struct RegexpExtractAll {
14540    pub this: Box<Expression>,
14541    pub expression: Box<Expression>,
14542    #[serde(default)]
14543    pub group: Option<Box<Expression>>,
14544    #[serde(default)]
14545    pub parameters: Option<Box<Expression>>,
14546    #[serde(default)]
14547    pub position: Option<Box<Expression>>,
14548    #[serde(default)]
14549    pub occurrence: Option<Box<Expression>>,
14550}
14551
14552/// RegexpILike
14553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14554#[cfg_attr(feature = "bindings", derive(TS))]
14555pub struct RegexpILike {
14556    pub this: Box<Expression>,
14557    pub expression: Box<Expression>,
14558    #[serde(default)]
14559    pub flag: Option<Box<Expression>>,
14560}
14561
14562/// RegexpFullMatch
14563#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14564#[cfg_attr(feature = "bindings", derive(TS))]
14565pub struct RegexpFullMatch {
14566    pub this: Box<Expression>,
14567    pub expression: Box<Expression>,
14568    #[serde(default)]
14569    pub options: Vec<Expression>,
14570}
14571
14572/// RegexpInstr
14573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14574#[cfg_attr(feature = "bindings", derive(TS))]
14575pub struct RegexpInstr {
14576    pub this: Box<Expression>,
14577    pub expression: Box<Expression>,
14578    #[serde(default)]
14579    pub position: Option<Box<Expression>>,
14580    #[serde(default)]
14581    pub occurrence: Option<Box<Expression>>,
14582    #[serde(default)]
14583    pub option: Option<Box<Expression>>,
14584    #[serde(default)]
14585    pub parameters: Option<Box<Expression>>,
14586    #[serde(default)]
14587    pub group: Option<Box<Expression>>,
14588}
14589
14590/// RegexpSplit
14591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14592#[cfg_attr(feature = "bindings", derive(TS))]
14593pub struct RegexpSplit {
14594    pub this: Box<Expression>,
14595    pub expression: Box<Expression>,
14596    #[serde(default)]
14597    pub limit: Option<Box<Expression>>,
14598}
14599
14600/// RegexpCount
14601#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14602#[cfg_attr(feature = "bindings", derive(TS))]
14603pub struct RegexpCount {
14604    pub this: Box<Expression>,
14605    pub expression: Box<Expression>,
14606    #[serde(default)]
14607    pub position: Option<Box<Expression>>,
14608    #[serde(default)]
14609    pub parameters: Option<Box<Expression>>,
14610}
14611
14612/// RegrValx
14613#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14614#[cfg_attr(feature = "bindings", derive(TS))]
14615pub struct RegrValx {
14616    pub this: Box<Expression>,
14617    pub expression: Box<Expression>,
14618}
14619
14620/// RegrValy
14621#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14622#[cfg_attr(feature = "bindings", derive(TS))]
14623pub struct RegrValy {
14624    pub this: Box<Expression>,
14625    pub expression: Box<Expression>,
14626}
14627
14628/// RegrAvgy
14629#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14630#[cfg_attr(feature = "bindings", derive(TS))]
14631pub struct RegrAvgy {
14632    pub this: Box<Expression>,
14633    pub expression: Box<Expression>,
14634}
14635
14636/// RegrAvgx
14637#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14638#[cfg_attr(feature = "bindings", derive(TS))]
14639pub struct RegrAvgx {
14640    pub this: Box<Expression>,
14641    pub expression: Box<Expression>,
14642}
14643
14644/// RegrCount
14645#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14646#[cfg_attr(feature = "bindings", derive(TS))]
14647pub struct RegrCount {
14648    pub this: Box<Expression>,
14649    pub expression: Box<Expression>,
14650}
14651
14652/// RegrIntercept
14653#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14654#[cfg_attr(feature = "bindings", derive(TS))]
14655pub struct RegrIntercept {
14656    pub this: Box<Expression>,
14657    pub expression: Box<Expression>,
14658}
14659
14660/// RegrR2
14661#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14662#[cfg_attr(feature = "bindings", derive(TS))]
14663pub struct RegrR2 {
14664    pub this: Box<Expression>,
14665    pub expression: Box<Expression>,
14666}
14667
14668/// RegrSxx
14669#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14670#[cfg_attr(feature = "bindings", derive(TS))]
14671pub struct RegrSxx {
14672    pub this: Box<Expression>,
14673    pub expression: Box<Expression>,
14674}
14675
14676/// RegrSxy
14677#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14678#[cfg_attr(feature = "bindings", derive(TS))]
14679pub struct RegrSxy {
14680    pub this: Box<Expression>,
14681    pub expression: Box<Expression>,
14682}
14683
14684/// RegrSyy
14685#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14686#[cfg_attr(feature = "bindings", derive(TS))]
14687pub struct RegrSyy {
14688    pub this: Box<Expression>,
14689    pub expression: Box<Expression>,
14690}
14691
14692/// RegrSlope
14693#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14694#[cfg_attr(feature = "bindings", derive(TS))]
14695pub struct RegrSlope {
14696    pub this: Box<Expression>,
14697    pub expression: Box<Expression>,
14698}
14699
14700/// SafeAdd
14701#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14702#[cfg_attr(feature = "bindings", derive(TS))]
14703pub struct SafeAdd {
14704    pub this: Box<Expression>,
14705    pub expression: Box<Expression>,
14706}
14707
14708/// SafeDivide
14709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14710#[cfg_attr(feature = "bindings", derive(TS))]
14711pub struct SafeDivide {
14712    pub this: Box<Expression>,
14713    pub expression: Box<Expression>,
14714}
14715
14716/// SafeMultiply
14717#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14718#[cfg_attr(feature = "bindings", derive(TS))]
14719pub struct SafeMultiply {
14720    pub this: Box<Expression>,
14721    pub expression: Box<Expression>,
14722}
14723
14724/// SafeSubtract
14725#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14726#[cfg_attr(feature = "bindings", derive(TS))]
14727pub struct SafeSubtract {
14728    pub this: Box<Expression>,
14729    pub expression: Box<Expression>,
14730}
14731
14732/// SHA2
14733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14734#[cfg_attr(feature = "bindings", derive(TS))]
14735pub struct SHA2 {
14736    pub this: Box<Expression>,
14737    #[serde(default)]
14738    pub length: Option<i64>,
14739}
14740
14741/// SHA2Digest
14742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14743#[cfg_attr(feature = "bindings", derive(TS))]
14744pub struct SHA2Digest {
14745    pub this: Box<Expression>,
14746    #[serde(default)]
14747    pub length: Option<i64>,
14748}
14749
14750/// SortArray
14751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14752#[cfg_attr(feature = "bindings", derive(TS))]
14753pub struct SortArray {
14754    pub this: Box<Expression>,
14755    #[serde(default)]
14756    pub asc: Option<Box<Expression>>,
14757    #[serde(default)]
14758    pub nulls_first: Option<Box<Expression>>,
14759}
14760
14761/// SplitPart
14762#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14763#[cfg_attr(feature = "bindings", derive(TS))]
14764pub struct SplitPart {
14765    pub this: Box<Expression>,
14766    #[serde(default)]
14767    pub delimiter: Option<Box<Expression>>,
14768    #[serde(default)]
14769    pub part_index: Option<Box<Expression>>,
14770}
14771
14772/// SUBSTRING_INDEX(str, delim, count)
14773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14774#[cfg_attr(feature = "bindings", derive(TS))]
14775pub struct SubstringIndex {
14776    pub this: Box<Expression>,
14777    #[serde(default)]
14778    pub delimiter: Option<Box<Expression>>,
14779    #[serde(default)]
14780    pub count: Option<Box<Expression>>,
14781}
14782
14783/// StandardHash
14784#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14785#[cfg_attr(feature = "bindings", derive(TS))]
14786pub struct StandardHash {
14787    pub this: Box<Expression>,
14788    #[serde(default)]
14789    pub expression: Option<Box<Expression>>,
14790}
14791
14792/// StrPosition
14793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14794#[cfg_attr(feature = "bindings", derive(TS))]
14795pub struct StrPosition {
14796    pub this: Box<Expression>,
14797    #[serde(default)]
14798    pub substr: Option<Box<Expression>>,
14799    #[serde(default)]
14800    pub position: Option<Box<Expression>>,
14801    #[serde(default)]
14802    pub occurrence: Option<Box<Expression>>,
14803}
14804
14805/// Search
14806#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14807#[cfg_attr(feature = "bindings", derive(TS))]
14808pub struct Search {
14809    pub this: Box<Expression>,
14810    pub expression: Box<Expression>,
14811    #[serde(default)]
14812    pub json_scope: Option<Box<Expression>>,
14813    #[serde(default)]
14814    pub analyzer: Option<Box<Expression>>,
14815    #[serde(default)]
14816    pub analyzer_options: Option<Box<Expression>>,
14817    #[serde(default)]
14818    pub search_mode: Option<Box<Expression>>,
14819}
14820
14821/// SearchIp
14822#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14823#[cfg_attr(feature = "bindings", derive(TS))]
14824pub struct SearchIp {
14825    pub this: Box<Expression>,
14826    pub expression: Box<Expression>,
14827}
14828
14829/// StrToDate
14830#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14831#[cfg_attr(feature = "bindings", derive(TS))]
14832pub struct StrToDate {
14833    pub this: Box<Expression>,
14834    #[serde(default)]
14835    pub format: Option<String>,
14836    #[serde(default)]
14837    pub safe: Option<Box<Expression>>,
14838}
14839
14840/// StrToTime
14841#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14842#[cfg_attr(feature = "bindings", derive(TS))]
14843pub struct StrToTime {
14844    pub this: Box<Expression>,
14845    pub format: String,
14846    #[serde(default)]
14847    pub zone: Option<Box<Expression>>,
14848    #[serde(default)]
14849    pub safe: Option<Box<Expression>>,
14850    #[serde(default)]
14851    pub target_type: Option<Box<Expression>>,
14852}
14853
14854/// StrToUnix
14855#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14856#[cfg_attr(feature = "bindings", derive(TS))]
14857pub struct StrToUnix {
14858    #[serde(default)]
14859    pub this: Option<Box<Expression>>,
14860    #[serde(default)]
14861    pub format: Option<String>,
14862}
14863
14864/// StrToMap
14865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14866#[cfg_attr(feature = "bindings", derive(TS))]
14867pub struct StrToMap {
14868    pub this: Box<Expression>,
14869    #[serde(default)]
14870    pub pair_delim: Option<Box<Expression>>,
14871    #[serde(default)]
14872    pub key_value_delim: Option<Box<Expression>>,
14873    #[serde(default)]
14874    pub duplicate_resolution_callback: Option<Box<Expression>>,
14875}
14876
14877/// NumberToStr
14878#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14879#[cfg_attr(feature = "bindings", derive(TS))]
14880pub struct NumberToStr {
14881    pub this: Box<Expression>,
14882    pub format: String,
14883    #[serde(default)]
14884    pub culture: Option<Box<Expression>>,
14885}
14886
14887/// FromBase
14888#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14889#[cfg_attr(feature = "bindings", derive(TS))]
14890pub struct FromBase {
14891    pub this: Box<Expression>,
14892    pub expression: Box<Expression>,
14893}
14894
14895/// Stuff
14896#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14897#[cfg_attr(feature = "bindings", derive(TS))]
14898pub struct Stuff {
14899    pub this: Box<Expression>,
14900    #[serde(default)]
14901    pub start: Option<Box<Expression>>,
14902    #[serde(default)]
14903    pub length: Option<i64>,
14904    pub expression: Box<Expression>,
14905}
14906
14907/// TimeToStr
14908#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14909#[cfg_attr(feature = "bindings", derive(TS))]
14910pub struct TimeToStr {
14911    pub this: Box<Expression>,
14912    pub format: String,
14913    #[serde(default)]
14914    pub culture: Option<Box<Expression>>,
14915    #[serde(default)]
14916    pub zone: Option<Box<Expression>>,
14917}
14918
14919/// TimeStrToTime
14920#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14921#[cfg_attr(feature = "bindings", derive(TS))]
14922pub struct TimeStrToTime {
14923    pub this: Box<Expression>,
14924    #[serde(default)]
14925    pub zone: Option<Box<Expression>>,
14926}
14927
14928/// TsOrDsAdd
14929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14930#[cfg_attr(feature = "bindings", derive(TS))]
14931pub struct TsOrDsAdd {
14932    pub this: Box<Expression>,
14933    pub expression: Box<Expression>,
14934    #[serde(default)]
14935    pub unit: Option<String>,
14936    #[serde(default)]
14937    pub return_type: Option<Box<Expression>>,
14938}
14939
14940/// TsOrDsDiff
14941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14942#[cfg_attr(feature = "bindings", derive(TS))]
14943pub struct TsOrDsDiff {
14944    pub this: Box<Expression>,
14945    pub expression: Box<Expression>,
14946    #[serde(default)]
14947    pub unit: Option<String>,
14948}
14949
14950/// TsOrDsToDate
14951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14952#[cfg_attr(feature = "bindings", derive(TS))]
14953pub struct TsOrDsToDate {
14954    pub this: Box<Expression>,
14955    #[serde(default)]
14956    pub format: Option<String>,
14957    #[serde(default)]
14958    pub safe: Option<Box<Expression>>,
14959}
14960
14961/// TsOrDsToTime
14962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14963#[cfg_attr(feature = "bindings", derive(TS))]
14964pub struct TsOrDsToTime {
14965    pub this: Box<Expression>,
14966    #[serde(default)]
14967    pub format: Option<String>,
14968    #[serde(default)]
14969    pub safe: Option<Box<Expression>>,
14970}
14971
14972/// Unhex
14973#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14974#[cfg_attr(feature = "bindings", derive(TS))]
14975pub struct Unhex {
14976    pub this: Box<Expression>,
14977    #[serde(default)]
14978    pub expression: Option<Box<Expression>>,
14979}
14980
14981/// Uniform
14982#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14983#[cfg_attr(feature = "bindings", derive(TS))]
14984pub struct Uniform {
14985    pub this: Box<Expression>,
14986    pub expression: Box<Expression>,
14987    #[serde(default)]
14988    pub gen: Option<Box<Expression>>,
14989    #[serde(default)]
14990    pub seed: Option<Box<Expression>>,
14991}
14992
14993/// UnixToStr
14994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14995#[cfg_attr(feature = "bindings", derive(TS))]
14996pub struct UnixToStr {
14997    pub this: Box<Expression>,
14998    #[serde(default)]
14999    pub format: Option<String>,
15000}
15001
15002/// UnixToTime
15003#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15004#[cfg_attr(feature = "bindings", derive(TS))]
15005pub struct UnixToTime {
15006    pub this: Box<Expression>,
15007    #[serde(default)]
15008    pub scale: Option<i64>,
15009    #[serde(default)]
15010    pub zone: Option<Box<Expression>>,
15011    #[serde(default)]
15012    pub hours: Option<Box<Expression>>,
15013    #[serde(default)]
15014    pub minutes: Option<Box<Expression>>,
15015    #[serde(default)]
15016    pub format: Option<String>,
15017    #[serde(default)]
15018    pub target_type: Option<Box<Expression>>,
15019}
15020
15021/// Uuid
15022#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15023#[cfg_attr(feature = "bindings", derive(TS))]
15024pub struct Uuid {
15025    #[serde(default)]
15026    pub this: Option<Box<Expression>>,
15027    #[serde(default)]
15028    pub name: Option<String>,
15029    #[serde(default)]
15030    pub is_string: Option<Box<Expression>>,
15031}
15032
15033/// TimestampFromParts
15034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15035#[cfg_attr(feature = "bindings", derive(TS))]
15036pub struct TimestampFromParts {
15037    #[serde(default)]
15038    pub zone: Option<Box<Expression>>,
15039    #[serde(default)]
15040    pub milli: Option<Box<Expression>>,
15041    #[serde(default)]
15042    pub this: Option<Box<Expression>>,
15043    #[serde(default)]
15044    pub expression: Option<Box<Expression>>,
15045}
15046
15047/// TimestampTzFromParts
15048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15049#[cfg_attr(feature = "bindings", derive(TS))]
15050pub struct TimestampTzFromParts {
15051    #[serde(default)]
15052    pub zone: Option<Box<Expression>>,
15053}
15054
15055/// Corr
15056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15057#[cfg_attr(feature = "bindings", derive(TS))]
15058pub struct Corr {
15059    pub this: Box<Expression>,
15060    pub expression: Box<Expression>,
15061    #[serde(default)]
15062    pub null_on_zero_variance: Option<Box<Expression>>,
15063}
15064
15065/// WidthBucket
15066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15067#[cfg_attr(feature = "bindings", derive(TS))]
15068pub struct WidthBucket {
15069    pub this: Box<Expression>,
15070    #[serde(default)]
15071    pub min_value: Option<Box<Expression>>,
15072    #[serde(default)]
15073    pub max_value: Option<Box<Expression>>,
15074    #[serde(default)]
15075    pub num_buckets: Option<Box<Expression>>,
15076    #[serde(default)]
15077    pub threshold: Option<Box<Expression>>,
15078}
15079
15080/// CovarSamp
15081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15082#[cfg_attr(feature = "bindings", derive(TS))]
15083pub struct CovarSamp {
15084    pub this: Box<Expression>,
15085    pub expression: Box<Expression>,
15086}
15087
15088/// CovarPop
15089#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15090#[cfg_attr(feature = "bindings", derive(TS))]
15091pub struct CovarPop {
15092    pub this: Box<Expression>,
15093    pub expression: Box<Expression>,
15094}
15095
15096/// Week
15097#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15098#[cfg_attr(feature = "bindings", derive(TS))]
15099pub struct Week {
15100    pub this: Box<Expression>,
15101    #[serde(default)]
15102    pub mode: Option<Box<Expression>>,
15103}
15104
15105/// XMLElement
15106#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15107#[cfg_attr(feature = "bindings", derive(TS))]
15108pub struct XMLElement {
15109    pub this: Box<Expression>,
15110    #[serde(default)]
15111    pub expressions: Vec<Expression>,
15112    #[serde(default)]
15113    pub evalname: Option<Box<Expression>>,
15114}
15115
15116/// XMLGet
15117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15118#[cfg_attr(feature = "bindings", derive(TS))]
15119pub struct XMLGet {
15120    pub this: Box<Expression>,
15121    pub expression: Box<Expression>,
15122    #[serde(default)]
15123    pub instance: Option<Box<Expression>>,
15124}
15125
15126/// XMLTable
15127#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15128#[cfg_attr(feature = "bindings", derive(TS))]
15129pub struct XMLTable {
15130    pub this: Box<Expression>,
15131    #[serde(default)]
15132    pub namespaces: Option<Box<Expression>>,
15133    #[serde(default)]
15134    pub passing: Option<Box<Expression>>,
15135    #[serde(default)]
15136    pub columns: Vec<Expression>,
15137    #[serde(default)]
15138    pub by_ref: Option<Box<Expression>>,
15139}
15140
15141/// XMLKeyValueOption
15142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15143#[cfg_attr(feature = "bindings", derive(TS))]
15144pub struct XMLKeyValueOption {
15145    pub this: Box<Expression>,
15146    #[serde(default)]
15147    pub expression: Option<Box<Expression>>,
15148}
15149
15150/// Zipf
15151#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15152#[cfg_attr(feature = "bindings", derive(TS))]
15153pub struct Zipf {
15154    pub this: Box<Expression>,
15155    #[serde(default)]
15156    pub elementcount: Option<Box<Expression>>,
15157    #[serde(default)]
15158    pub gen: Option<Box<Expression>>,
15159}
15160
15161/// Merge
15162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15163#[cfg_attr(feature = "bindings", derive(TS))]
15164pub struct Merge {
15165    pub this: Box<Expression>,
15166    pub using: Box<Expression>,
15167    #[serde(default)]
15168    pub on: Option<Box<Expression>>,
15169    #[serde(default)]
15170    pub using_cond: Option<Box<Expression>>,
15171    #[serde(default)]
15172    pub whens: Option<Box<Expression>>,
15173    #[serde(default)]
15174    pub with_: Option<Box<Expression>>,
15175    #[serde(default)]
15176    pub returning: Option<Box<Expression>>,
15177}
15178
15179/// When
15180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15181#[cfg_attr(feature = "bindings", derive(TS))]
15182pub struct When {
15183    #[serde(default)]
15184    pub matched: Option<Box<Expression>>,
15185    #[serde(default)]
15186    pub source: Option<Box<Expression>>,
15187    #[serde(default)]
15188    pub condition: Option<Box<Expression>>,
15189    pub then: Box<Expression>,
15190}
15191
15192/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15194#[cfg_attr(feature = "bindings", derive(TS))]
15195pub struct Whens {
15196    #[serde(default)]
15197    pub expressions: Vec<Expression>,
15198}
15199
15200/// NextValueFor
15201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15202#[cfg_attr(feature = "bindings", derive(TS))]
15203pub struct NextValueFor {
15204    pub this: Box<Expression>,
15205    #[serde(default)]
15206    pub order: Option<Box<Expression>>,
15207}
15208
15209#[cfg(test)]
15210mod tests {
15211    use super::*;
15212
15213    #[test]
15214    #[cfg(feature = "bindings")]
15215    fn export_typescript_types() {
15216        // This test exports TypeScript types to the generated directory
15217        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
15218        Expression::export_all(&ts_rs::Config::default())
15219            .expect("Failed to export Expression types");
15220    }
15221
15222    #[test]
15223    fn test_simple_select_builder() {
15224        let select = Select::new()
15225            .column(Expression::star())
15226            .from(Expression::Table(Box::new(TableRef::new("users"))));
15227
15228        assert_eq!(select.expressions.len(), 1);
15229        assert!(select.from.is_some());
15230    }
15231
15232    #[test]
15233    fn test_expression_alias() {
15234        let expr = Expression::column("id").alias("user_id");
15235
15236        match expr {
15237            Expression::Alias(a) => {
15238                assert_eq!(a.alias.name, "user_id");
15239            }
15240            _ => panic!("Expected Alias"),
15241        }
15242    }
15243
15244    #[test]
15245    fn test_literal_creation() {
15246        let num = Expression::number(42);
15247        let str = Expression::string("hello");
15248
15249        match num {
15250            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
15251                let Literal::Number(n) = lit.as_ref() else {
15252                    unreachable!()
15253                };
15254                assert_eq!(n, "42")
15255            }
15256            _ => panic!("Expected Number"),
15257        }
15258
15259        match str {
15260            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
15261                let Literal::String(s) = lit.as_ref() else {
15262                    unreachable!()
15263                };
15264                assert_eq!(s, "hello")
15265            }
15266            _ => panic!("Expected String"),
15267        }
15268    }
15269
15270    #[test]
15271    fn test_expression_sql() {
15272        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
15273        assert_eq!(expr.sql(), "SELECT 1 + 2");
15274    }
15275
15276    #[test]
15277    fn test_expression_sql_for() {
15278        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
15279        let sql = expr.sql_for(crate::DialectType::Generic);
15280        // Generic mode normalizes IF() to CASE WHEN
15281        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
15282    }
15283}