Skip to main content

polyglot_sql/
expressions.rs

1//! SQL Expression AST (Abstract Syntax Tree).
2//!
3//! This module defines all the AST node types used to represent parsed SQL
4//! statements and expressions. The design follows Python sqlglot's expression
5//! hierarchy, ported to a Rust enum-based AST.
6//!
7//! # Architecture
8//!
9//! The central type is [`Expression`], a large tagged enum with one variant per
10//! SQL construct. Inner structs carry the fields for each variant. Most
11//! heap-allocated variants are wrapped in `Box` to keep the enum size small.
12//!
13//! # Variant Groups
14//!
15//! | Group | Examples | Purpose |
16//! |---|---|---|
17//! | **Queries** | `Select`, `Union`, `Intersect`, `Except`, `Subquery` | Top-level query structures |
18//! | **DML** | `Insert`, `Update`, `Delete`, `Merge`, `Copy` | Data manipulation |
19//! | **DDL** | `CreateTable`, `AlterTable`, `DropView`, `CreateIndex` | Schema definition |
20//! | **Clauses** | `From`, `Join`, `Where`, `GroupBy`, `OrderBy`, `With` | Query clauses |
21//! | **Operators** | `And`, `Or`, `Add`, `Eq`, `Like`, `Not` | Binary and unary operations |
22//! | **Functions** | `Function`, `AggregateFunction`, `WindowFunction`, `Count`, `Sum` | Scalar, aggregate, and window functions |
23//! | **Literals** | `Literal`, `Boolean`, `Null`, `Interval` | Constant values |
24//! | **Types** | `DataType`, `Cast`, `TryCast`, `SafeCast` | Data types and casts |
25//! | **Identifiers** | `Identifier`, `Column`, `Table`, `Star` | Name references |
26//!
27//! # SQL Generation
28//!
29//! Every `Expression` can be rendered back to SQL via [`Expression::sql()`]
30//! (generic dialect) or [`Expression::sql_for()`] (specific dialect). The
31//! actual generation logic lives in the `generator` module.
32
33use crate::tokens::Span;
34use serde::{Deserialize, Serialize};
35use std::fmt;
36#[cfg(feature = "bindings")]
37use ts_rs::TS;
38
39/// Helper function for serde default value
40fn default_true() -> bool {
41    true
42}
43
44fn is_true(v: &bool) -> bool {
45    *v
46}
47
48/// Represent any SQL expression or statement as a single, recursive AST node.
49///
50/// `Expression` is the root type of the polyglot AST. Every parsed SQL
51/// construct -- from a simple integer literal to a multi-CTE query with
52/// window functions -- is represented as a variant of this enum.
53///
54/// Variants are organized into logical groups (see the module-level docs).
55/// Most non-trivial variants box their payload so that `size_of::<Expression>()`
56/// stays small (currently two words: tag + pointer).
57///
58/// # Constructing Expressions
59///
60/// Use the convenience constructors on `impl Expression` for common cases:
61///
62/// ```rust,ignore
63/// use polyglot_sql::expressions::Expression;
64///
65/// let col  = Expression::column("id");
66/// let lit  = Expression::number(42);
67/// let star = Expression::star();
68/// ```
69///
70/// # Generating SQL
71///
72/// ```rust,ignore
73/// let expr = Expression::column("name");
74/// assert_eq!(expr.sql(), "name");
75/// ```
76#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
77#[cfg_attr(feature = "bindings", derive(TS))]
78#[serde(rename_all = "snake_case")]
79#[cfg_attr(feature = "bindings", ts(export))]
80pub enum Expression {
81    // Literals
82    Literal(Box<Literal>),
83    Boolean(BooleanLiteral),
84    Null(Null),
85
86    // Identifiers
87    Identifier(Identifier),
88    Column(Box<Column>),
89    Table(Box<TableRef>),
90    Star(Star),
91    /// Snowflake braced wildcard syntax: {*}, {tbl.*}, {* EXCLUDE (...)}, {* ILIKE '...'}
92    BracedWildcard(Box<Expression>),
93
94    // Queries
95    Select(Box<Select>),
96    Union(Box<Union>),
97    Intersect(Box<Intersect>),
98    Except(Box<Except>),
99    Subquery(Box<Subquery>),
100    PipeOperator(Box<PipeOperator>),
101    Pivot(Box<Pivot>),
102    PivotAlias(Box<PivotAlias>),
103    Unpivot(Box<Unpivot>),
104    Values(Box<Values>),
105    PreWhere(Box<PreWhere>),
106    Stream(Box<Stream>),
107    UsingData(Box<UsingData>),
108    XmlNamespace(Box<XmlNamespace>),
109
110    // DML
111    Insert(Box<Insert>),
112    Update(Box<Update>),
113    Delete(Box<Delete>),
114    Copy(Box<CopyStmt>),
115    Put(Box<PutStmt>),
116    StageReference(Box<StageReference>),
117    TryCatch(Box<TryCatch>),
118
119    // Expressions
120    Alias(Box<Alias>),
121    Cast(Box<Cast>),
122    Collation(Box<CollationExpr>),
123    Case(Box<Case>),
124
125    // Binary operations
126    And(Box<BinaryOp>),
127    Or(Box<BinaryOp>),
128    Add(Box<BinaryOp>),
129    Sub(Box<BinaryOp>),
130    Mul(Box<BinaryOp>),
131    Div(Box<BinaryOp>),
132    Mod(Box<BinaryOp>),
133    Eq(Box<BinaryOp>),
134    Neq(Box<BinaryOp>),
135    Lt(Box<BinaryOp>),
136    Lte(Box<BinaryOp>),
137    Gt(Box<BinaryOp>),
138    Gte(Box<BinaryOp>),
139    Like(Box<LikeOp>),
140    ILike(Box<LikeOp>),
141    /// SQLite MATCH operator (FTS)
142    Match(Box<BinaryOp>),
143    BitwiseAnd(Box<BinaryOp>),
144    BitwiseOr(Box<BinaryOp>),
145    BitwiseXor(Box<BinaryOp>),
146    Concat(Box<BinaryOp>),
147    Adjacent(Box<BinaryOp>),   // PostgreSQL range adjacency operator (-|-)
148    TsMatch(Box<BinaryOp>),    // PostgreSQL text search match operator (@@)
149    PropertyEQ(Box<BinaryOp>), // := assignment operator (MySQL @var := val, DuckDB named args)
150
151    // PostgreSQL array/JSONB operators
152    ArrayContainsAll(Box<BinaryOp>), // @> operator (array contains all)
153    ArrayContainedBy(Box<BinaryOp>), // <@ operator (array contained by)
154    ArrayOverlaps(Box<BinaryOp>),    // && operator (array overlaps)
155    JSONBContainsAllTopKeys(Box<BinaryOp>), // ?& operator (JSONB contains all keys)
156    JSONBContainsAnyTopKeys(Box<BinaryOp>), // ?| operator (JSONB contains any key)
157    JSONBDeleteAtPath(Box<BinaryOp>), // #- operator (JSONB delete at path)
158    ExtendsLeft(Box<BinaryOp>),      // &< operator (PostgreSQL range extends left)
159    ExtendsRight(Box<BinaryOp>),     // &> operator (PostgreSQL range extends right)
160
161    // Unary operations
162    Not(Box<UnaryOp>),
163    Neg(Box<UnaryOp>),
164    BitwiseNot(Box<UnaryOp>),
165
166    // Predicates
167    In(Box<In>),
168    Between(Box<Between>),
169    IsNull(Box<IsNull>),
170    IsTrue(Box<IsTrueFalse>),
171    IsFalse(Box<IsTrueFalse>),
172    IsJson(Box<IsJson>),
173    Is(Box<BinaryOp>), // General IS expression (e.g., a IS ?)
174    Exists(Box<Exists>),
175    /// MySQL MEMBER OF operator: expr MEMBER OF(json_array)
176    MemberOf(Box<BinaryOp>),
177
178    // Functions
179    Function(Box<Function>),
180    AggregateFunction(Box<AggregateFunction>),
181    WindowFunction(Box<WindowFunction>),
182
183    // Clauses
184    From(Box<From>),
185    Join(Box<Join>),
186    JoinedTable(Box<JoinedTable>),
187    Where(Box<Where>),
188    GroupBy(Box<GroupBy>),
189    Having(Box<Having>),
190    OrderBy(Box<OrderBy>),
191    Limit(Box<Limit>),
192    Offset(Box<Offset>),
193    Qualify(Box<Qualify>),
194    With(Box<With>),
195    Cte(Box<Cte>),
196    DistributeBy(Box<DistributeBy>),
197    ClusterBy(Box<ClusterBy>),
198    SortBy(Box<SortBy>),
199    LateralView(Box<LateralView>),
200    Hint(Box<Hint>),
201    Pseudocolumn(Pseudocolumn),
202
203    // Oracle hierarchical queries (CONNECT BY)
204    Connect(Box<Connect>),
205    Prior(Box<Prior>),
206    ConnectByRoot(Box<ConnectByRoot>),
207
208    // Pattern matching (MATCH_RECOGNIZE)
209    MatchRecognize(Box<MatchRecognize>),
210
211    // Order expressions
212    Ordered(Box<Ordered>),
213
214    // Window specifications
215    Window(Box<WindowSpec>),
216    Over(Box<Over>),
217    WithinGroup(Box<WithinGroup>),
218
219    // Data types
220    DataType(DataType),
221
222    // Arrays and structs
223    Array(Box<Array>),
224    Struct(Box<Struct>),
225    Tuple(Box<Tuple>),
226
227    // Interval
228    Interval(Box<Interval>),
229
230    // String functions
231    ConcatWs(Box<ConcatWs>),
232    Substring(Box<SubstringFunc>),
233    Upper(Box<UnaryFunc>),
234    Lower(Box<UnaryFunc>),
235    Length(Box<UnaryFunc>),
236    Trim(Box<TrimFunc>),
237    LTrim(Box<UnaryFunc>),
238    RTrim(Box<UnaryFunc>),
239    Replace(Box<ReplaceFunc>),
240    Reverse(Box<UnaryFunc>),
241    Left(Box<LeftRightFunc>),
242    Right(Box<LeftRightFunc>),
243    Repeat(Box<RepeatFunc>),
244    Lpad(Box<PadFunc>),
245    Rpad(Box<PadFunc>),
246    Split(Box<SplitFunc>),
247    RegexpLike(Box<RegexpFunc>),
248    RegexpReplace(Box<RegexpReplaceFunc>),
249    RegexpExtract(Box<RegexpExtractFunc>),
250    Overlay(Box<OverlayFunc>),
251
252    // Math functions
253    Abs(Box<UnaryFunc>),
254    Round(Box<RoundFunc>),
255    Floor(Box<FloorFunc>),
256    Ceil(Box<CeilFunc>),
257    Power(Box<BinaryFunc>),
258    Sqrt(Box<UnaryFunc>),
259    Cbrt(Box<UnaryFunc>),
260    Ln(Box<UnaryFunc>),
261    Log(Box<LogFunc>),
262    Exp(Box<UnaryFunc>),
263    Sign(Box<UnaryFunc>),
264    Greatest(Box<VarArgFunc>),
265    Least(Box<VarArgFunc>),
266
267    // Date/time functions
268    CurrentDate(CurrentDate),
269    CurrentTime(CurrentTime),
270    CurrentTimestamp(CurrentTimestamp),
271    CurrentTimestampLTZ(CurrentTimestampLTZ),
272    AtTimeZone(Box<AtTimeZone>),
273    DateAdd(Box<DateAddFunc>),
274    DateSub(Box<DateAddFunc>),
275    DateDiff(Box<DateDiffFunc>),
276    DateTrunc(Box<DateTruncFunc>),
277    Extract(Box<ExtractFunc>),
278    ToDate(Box<ToDateFunc>),
279    ToTimestamp(Box<ToTimestampFunc>),
280    Date(Box<UnaryFunc>),
281    Time(Box<UnaryFunc>),
282    DateFromUnixDate(Box<UnaryFunc>),
283    UnixDate(Box<UnaryFunc>),
284    UnixSeconds(Box<UnaryFunc>),
285    UnixMillis(Box<UnaryFunc>),
286    UnixMicros(Box<UnaryFunc>),
287    UnixToTimeStr(Box<BinaryFunc>),
288    TimeStrToDate(Box<UnaryFunc>),
289    DateToDi(Box<UnaryFunc>),
290    DiToDate(Box<UnaryFunc>),
291    TsOrDiToDi(Box<UnaryFunc>),
292    TsOrDsToDatetime(Box<UnaryFunc>),
293    TsOrDsToTimestamp(Box<UnaryFunc>),
294    YearOfWeek(Box<UnaryFunc>),
295    YearOfWeekIso(Box<UnaryFunc>),
296
297    // Control flow functions
298    Coalesce(Box<VarArgFunc>),
299    NullIf(Box<BinaryFunc>),
300    IfFunc(Box<IfFunc>),
301    IfNull(Box<BinaryFunc>),
302    Nvl(Box<BinaryFunc>),
303    Nvl2(Box<Nvl2Func>),
304
305    // Type conversion
306    TryCast(Box<Cast>),
307    SafeCast(Box<Cast>),
308
309    // Typed aggregate functions
310    Count(Box<CountFunc>),
311    Sum(Box<AggFunc>),
312    Avg(Box<AggFunc>),
313    Min(Box<AggFunc>),
314    Max(Box<AggFunc>),
315    GroupConcat(Box<GroupConcatFunc>),
316    StringAgg(Box<StringAggFunc>),
317    ListAgg(Box<ListAggFunc>),
318    ArrayAgg(Box<AggFunc>),
319    CountIf(Box<AggFunc>),
320    SumIf(Box<SumIfFunc>),
321    Stddev(Box<AggFunc>),
322    StddevPop(Box<AggFunc>),
323    StddevSamp(Box<AggFunc>),
324    Variance(Box<AggFunc>),
325    VarPop(Box<AggFunc>),
326    VarSamp(Box<AggFunc>),
327    Median(Box<AggFunc>),
328    Mode(Box<AggFunc>),
329    First(Box<AggFunc>),
330    Last(Box<AggFunc>),
331    AnyValue(Box<AggFunc>),
332    ApproxDistinct(Box<AggFunc>),
333    ApproxCountDistinct(Box<AggFunc>),
334    ApproxPercentile(Box<ApproxPercentileFunc>),
335    Percentile(Box<PercentileFunc>),
336    LogicalAnd(Box<AggFunc>),
337    LogicalOr(Box<AggFunc>),
338    Skewness(Box<AggFunc>),
339    BitwiseCount(Box<UnaryFunc>),
340    ArrayConcatAgg(Box<AggFunc>),
341    ArrayUniqueAgg(Box<AggFunc>),
342    BoolXorAgg(Box<AggFunc>),
343
344    // Typed window functions
345    RowNumber(RowNumber),
346    Rank(Rank),
347    DenseRank(DenseRank),
348    NTile(Box<NTileFunc>),
349    Lead(Box<LeadLagFunc>),
350    Lag(Box<LeadLagFunc>),
351    FirstValue(Box<ValueFunc>),
352    LastValue(Box<ValueFunc>),
353    NthValue(Box<NthValueFunc>),
354    PercentRank(PercentRank),
355    CumeDist(CumeDist),
356    PercentileCont(Box<PercentileFunc>),
357    PercentileDisc(Box<PercentileFunc>),
358
359    // Additional string functions
360    Contains(Box<BinaryFunc>),
361    StartsWith(Box<BinaryFunc>),
362    EndsWith(Box<BinaryFunc>),
363    Position(Box<PositionFunc>),
364    Initcap(Box<UnaryFunc>),
365    Ascii(Box<UnaryFunc>),
366    Chr(Box<UnaryFunc>),
367    /// MySQL CHAR function with multiple args and optional USING charset
368    CharFunc(Box<CharFunc>),
369    Soundex(Box<UnaryFunc>),
370    Levenshtein(Box<BinaryFunc>),
371    ByteLength(Box<UnaryFunc>),
372    Hex(Box<UnaryFunc>),
373    LowerHex(Box<UnaryFunc>),
374    Unicode(Box<UnaryFunc>),
375
376    // Additional math functions
377    ModFunc(Box<BinaryFunc>),
378    Random(Random),
379    Rand(Box<Rand>),
380    TruncFunc(Box<TruncateFunc>),
381    Pi(Pi),
382    Radians(Box<UnaryFunc>),
383    Degrees(Box<UnaryFunc>),
384    Sin(Box<UnaryFunc>),
385    Cos(Box<UnaryFunc>),
386    Tan(Box<UnaryFunc>),
387    Asin(Box<UnaryFunc>),
388    Acos(Box<UnaryFunc>),
389    Atan(Box<UnaryFunc>),
390    Atan2(Box<BinaryFunc>),
391    IsNan(Box<UnaryFunc>),
392    IsInf(Box<UnaryFunc>),
393    IntDiv(Box<BinaryFunc>),
394
395    // Control flow
396    Decode(Box<DecodeFunc>),
397
398    // Additional date/time functions
399    DateFormat(Box<DateFormatFunc>),
400    FormatDate(Box<DateFormatFunc>),
401    Year(Box<UnaryFunc>),
402    Month(Box<UnaryFunc>),
403    Day(Box<UnaryFunc>),
404    Hour(Box<UnaryFunc>),
405    Minute(Box<UnaryFunc>),
406    Second(Box<UnaryFunc>),
407    DayOfWeek(Box<UnaryFunc>),
408    DayOfWeekIso(Box<UnaryFunc>),
409    DayOfMonth(Box<UnaryFunc>),
410    DayOfYear(Box<UnaryFunc>),
411    WeekOfYear(Box<UnaryFunc>),
412    Quarter(Box<UnaryFunc>),
413    AddMonths(Box<BinaryFunc>),
414    MonthsBetween(Box<BinaryFunc>),
415    LastDay(Box<LastDayFunc>),
416    NextDay(Box<BinaryFunc>),
417    Epoch(Box<UnaryFunc>),
418    EpochMs(Box<UnaryFunc>),
419    FromUnixtime(Box<FromUnixtimeFunc>),
420    UnixTimestamp(Box<UnixTimestampFunc>),
421    MakeDate(Box<MakeDateFunc>),
422    MakeTimestamp(Box<MakeTimestampFunc>),
423    TimestampTrunc(Box<DateTruncFunc>),
424    TimeStrToUnix(Box<UnaryFunc>),
425
426    // Session/User functions
427    SessionUser(SessionUser),
428
429    // Hash/Crypto functions
430    SHA(Box<UnaryFunc>),
431    SHA1Digest(Box<UnaryFunc>),
432
433    // Time conversion functions
434    TimeToUnix(Box<UnaryFunc>),
435
436    // Array functions
437    ArrayFunc(Box<ArrayConstructor>),
438    ArrayLength(Box<UnaryFunc>),
439    ArraySize(Box<UnaryFunc>),
440    Cardinality(Box<UnaryFunc>),
441    ArrayContains(Box<BinaryFunc>),
442    ArrayPosition(Box<BinaryFunc>),
443    ArrayAppend(Box<BinaryFunc>),
444    ArrayPrepend(Box<BinaryFunc>),
445    ArrayConcat(Box<VarArgFunc>),
446    ArraySort(Box<ArraySortFunc>),
447    ArrayReverse(Box<UnaryFunc>),
448    ArrayDistinct(Box<UnaryFunc>),
449    ArrayJoin(Box<ArrayJoinFunc>),
450    ArrayToString(Box<ArrayJoinFunc>),
451    Unnest(Box<UnnestFunc>),
452    Explode(Box<UnaryFunc>),
453    ExplodeOuter(Box<UnaryFunc>),
454    ArrayFilter(Box<ArrayFilterFunc>),
455    ArrayTransform(Box<ArrayTransformFunc>),
456    ArrayFlatten(Box<UnaryFunc>),
457    ArrayCompact(Box<UnaryFunc>),
458    ArrayIntersect(Box<VarArgFunc>),
459    ArrayUnion(Box<BinaryFunc>),
460    ArrayExcept(Box<BinaryFunc>),
461    ArrayRemove(Box<BinaryFunc>),
462    ArrayZip(Box<VarArgFunc>),
463    Sequence(Box<SequenceFunc>),
464    Generate(Box<SequenceFunc>),
465    ExplodingGenerateSeries(Box<SequenceFunc>),
466    ToArray(Box<UnaryFunc>),
467    StarMap(Box<BinaryFunc>),
468
469    // Struct functions
470    StructFunc(Box<StructConstructor>),
471    StructExtract(Box<StructExtractFunc>),
472    NamedStruct(Box<NamedStructFunc>),
473
474    // Map functions
475    MapFunc(Box<MapConstructor>),
476    MapFromEntries(Box<UnaryFunc>),
477    MapFromArrays(Box<BinaryFunc>),
478    MapKeys(Box<UnaryFunc>),
479    MapValues(Box<UnaryFunc>),
480    MapContainsKey(Box<BinaryFunc>),
481    MapConcat(Box<VarArgFunc>),
482    ElementAt(Box<BinaryFunc>),
483    TransformKeys(Box<TransformFunc>),
484    TransformValues(Box<TransformFunc>),
485
486    // Exasol: function call with EMITS clause
487    FunctionEmits(Box<FunctionEmits>),
488
489    // JSON functions
490    JsonExtract(Box<JsonExtractFunc>),
491    JsonExtractScalar(Box<JsonExtractFunc>),
492    JsonExtractPath(Box<JsonPathFunc>),
493    JsonArray(Box<VarArgFunc>),
494    JsonObject(Box<JsonObjectFunc>),
495    JsonQuery(Box<JsonExtractFunc>),
496    JsonValue(Box<JsonExtractFunc>),
497    JsonArrayLength(Box<UnaryFunc>),
498    JsonKeys(Box<UnaryFunc>),
499    JsonType(Box<UnaryFunc>),
500    ParseJson(Box<UnaryFunc>),
501    ToJson(Box<UnaryFunc>),
502    JsonSet(Box<JsonModifyFunc>),
503    JsonInsert(Box<JsonModifyFunc>),
504    JsonRemove(Box<JsonPathFunc>),
505    JsonMergePatch(Box<BinaryFunc>),
506    JsonArrayAgg(Box<JsonArrayAggFunc>),
507    JsonObjectAgg(Box<JsonObjectAggFunc>),
508
509    // Type casting/conversion
510    Convert(Box<ConvertFunc>),
511    Typeof(Box<UnaryFunc>),
512
513    // Additional expressions
514    Lambda(Box<LambdaExpr>),
515    Parameter(Box<Parameter>),
516    Placeholder(Placeholder),
517    NamedArgument(Box<NamedArgument>),
518    /// TABLE ref or MODEL ref used as a function argument (BigQuery)
519    /// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
520    TableArgument(Box<TableArgument>),
521    SqlComment(Box<SqlComment>),
522
523    // Additional predicates
524    NullSafeEq(Box<BinaryOp>),
525    NullSafeNeq(Box<BinaryOp>),
526    Glob(Box<BinaryOp>),
527    SimilarTo(Box<SimilarToExpr>),
528    Any(Box<QuantifiedExpr>),
529    All(Box<QuantifiedExpr>),
530    Overlaps(Box<OverlapsExpr>),
531
532    // Bitwise operations
533    BitwiseLeftShift(Box<BinaryOp>),
534    BitwiseRightShift(Box<BinaryOp>),
535    BitwiseAndAgg(Box<AggFunc>),
536    BitwiseOrAgg(Box<AggFunc>),
537    BitwiseXorAgg(Box<AggFunc>),
538
539    // Array/struct/map access
540    Subscript(Box<Subscript>),
541    Dot(Box<DotAccess>),
542    MethodCall(Box<MethodCall>),
543    ArraySlice(Box<ArraySlice>),
544
545    // DDL statements
546    CreateTable(Box<CreateTable>),
547    DropTable(Box<DropTable>),
548    Undrop(Box<Undrop>),
549    AlterTable(Box<AlterTable>),
550    SplitTable(Box<SplitTable>),
551    FlashbackTable(Box<FlashbackTable>),
552    CreateIndex(Box<CreateIndex>),
553    DropIndex(Box<DropIndex>),
554    CreateView(Box<CreateView>),
555    DropView(Box<DropView>),
556    AlterView(Box<AlterView>),
557    AlterIndex(Box<AlterIndex>),
558    Truncate(Box<Truncate>),
559    Use(Box<Use>),
560    Cache(Box<Cache>),
561    Uncache(Box<Uncache>),
562    LoadData(Box<LoadData>),
563    Pragma(Box<Pragma>),
564    Grant(Box<Grant>),
565    Revoke(Box<Revoke>),
566    Comment(Box<Comment>),
567    SetStatement(Box<SetStatement>),
568    // Phase 4: Additional DDL statements
569    CreateSchema(Box<CreateSchema>),
570    DropSchema(Box<DropSchema>),
571    DropNamespace(Box<DropNamespace>),
572    CreateDatabase(Box<CreateDatabase>),
573    DropDatabase(Box<DropDatabase>),
574    CreateFunction(Box<CreateFunction>),
575    DropFunction(Box<DropFunction>),
576    CreateProcedure(Box<CreateProcedure>),
577    DropProcedure(Box<DropProcedure>),
578    CreateSequence(Box<CreateSequence>),
579    CreateSynonym(Box<CreateSynonym>),
580    DropSequence(Box<DropSequence>),
581    AlterSequence(Box<AlterSequence>),
582    CreateTrigger(Box<CreateTrigger>),
583    DropTrigger(Box<DropTrigger>),
584    CreateType(Box<CreateType>),
585    DropType(Box<DropType>),
586    Describe(Box<Describe>),
587    Show(Box<Show>),
588
589    // Transaction and other commands
590    Command(Box<Command>),
591    Kill(Box<Kill>),
592    /// PREPARE statement (PostgreSQL/generic prepared statement definition)
593    Prepare(Box<PrepareStatement>),
594    /// EXEC/EXECUTE statement (TSQL stored procedure call)
595    Execute(Box<ExecuteStatement>),
596
597    /// Snowflake CREATE TASK statement
598    CreateTask(Box<CreateTask>),
599
600    // Placeholder for unparsed/raw SQL
601    Raw(Raw),
602
603    // Paren for grouping
604    Paren(Box<Paren>),
605
606    // Expression with trailing comments (for round-trip preservation)
607    Annotated(Box<Annotated>),
608
609    // === BATCH GENERATED EXPRESSION TYPES ===
610    // Generated from Python sqlglot expressions.py
611    Refresh(Box<Refresh>),
612    LockingStatement(Box<LockingStatement>),
613    SequenceProperties(Box<SequenceProperties>),
614    TruncateTable(Box<TruncateTable>),
615    Clone(Box<Clone>),
616    Attach(Box<Attach>),
617    Detach(Box<Detach>),
618    Install(Box<Install>),
619    Summarize(Box<Summarize>),
620    Declare(Box<Declare>),
621    DeclareItem(Box<DeclareItem>),
622    Set(Box<Set>),
623    Heredoc(Box<Heredoc>),
624    SetItem(Box<SetItem>),
625    QueryBand(Box<QueryBand>),
626    UserDefinedFunction(Box<UserDefinedFunction>),
627    RecursiveWithSearch(Box<RecursiveWithSearch>),
628    ProjectionDef(Box<ProjectionDef>),
629    TableAlias(Box<TableAlias>),
630    ByteString(Box<ByteString>),
631    HexStringExpr(Box<HexStringExpr>),
632    UnicodeString(Box<UnicodeString>),
633    ColumnPosition(Box<ColumnPosition>),
634    ColumnDef(Box<ColumnDef>),
635    AlterColumn(Box<AlterColumn>),
636    AlterSortKey(Box<AlterSortKey>),
637    AlterSet(Box<AlterSet>),
638    RenameColumn(Box<RenameColumn>),
639    Comprehension(Box<Comprehension>),
640    MergeTreeTTLAction(Box<MergeTreeTTLAction>),
641    MergeTreeTTL(Box<MergeTreeTTL>),
642    IndexConstraintOption(Box<IndexConstraintOption>),
643    ColumnConstraint(Box<ColumnConstraint>),
644    PeriodForSystemTimeConstraint(Box<PeriodForSystemTimeConstraint>),
645    CaseSpecificColumnConstraint(Box<CaseSpecificColumnConstraint>),
646    CharacterSetColumnConstraint(Box<CharacterSetColumnConstraint>),
647    CheckColumnConstraint(Box<CheckColumnConstraint>),
648    AssumeColumnConstraint(Box<AssumeColumnConstraint>),
649    CompressColumnConstraint(Box<CompressColumnConstraint>),
650    DateFormatColumnConstraint(Box<DateFormatColumnConstraint>),
651    EphemeralColumnConstraint(Box<EphemeralColumnConstraint>),
652    WithOperator(Box<WithOperator>),
653    GeneratedAsIdentityColumnConstraint(Box<GeneratedAsIdentityColumnConstraint>),
654    AutoIncrementColumnConstraint(AutoIncrementColumnConstraint),
655    CommentColumnConstraint(CommentColumnConstraint),
656    GeneratedAsRowColumnConstraint(Box<GeneratedAsRowColumnConstraint>),
657    IndexColumnConstraint(Box<IndexColumnConstraint>),
658    MaskingPolicyColumnConstraint(Box<MaskingPolicyColumnConstraint>),
659    NotNullColumnConstraint(Box<NotNullColumnConstraint>),
660    PrimaryKeyColumnConstraint(Box<PrimaryKeyColumnConstraint>),
661    UniqueColumnConstraint(Box<UniqueColumnConstraint>),
662    WatermarkColumnConstraint(Box<WatermarkColumnConstraint>),
663    ComputedColumnConstraint(Box<ComputedColumnConstraint>),
664    InOutColumnConstraint(Box<InOutColumnConstraint>),
665    DefaultColumnConstraint(Box<DefaultColumnConstraint>),
666    PathColumnConstraint(Box<PathColumnConstraint>),
667    Constraint(Box<Constraint>),
668    Export(Box<Export>),
669    Filter(Box<Filter>),
670    Changes(Box<Changes>),
671    CopyParameter(Box<CopyParameter>),
672    Credentials(Box<Credentials>),
673    Directory(Box<Directory>),
674    ForeignKey(Box<ForeignKey>),
675    ColumnPrefix(Box<ColumnPrefix>),
676    PrimaryKey(Box<PrimaryKey>),
677    IntoClause(Box<IntoClause>),
678    JoinHint(Box<JoinHint>),
679    Opclass(Box<Opclass>),
680    Index(Box<Index>),
681    IndexParameters(Box<IndexParameters>),
682    ConditionalInsert(Box<ConditionalInsert>),
683    MultitableInserts(Box<MultitableInserts>),
684    OnConflict(Box<OnConflict>),
685    OnCondition(Box<OnCondition>),
686    Returning(Box<Returning>),
687    Introducer(Box<Introducer>),
688    PartitionRange(Box<PartitionRange>),
689    Fetch(Box<Fetch>),
690    Group(Box<Group>),
691    Cube(Box<Cube>),
692    Rollup(Box<Rollup>),
693    GroupingSets(Box<GroupingSets>),
694    LimitOptions(Box<LimitOptions>),
695    Lateral(Box<Lateral>),
696    TableFromRows(Box<TableFromRows>),
697    RowsFrom(Box<RowsFrom>),
698    MatchRecognizeMeasure(Box<MatchRecognizeMeasure>),
699    WithFill(Box<WithFill>),
700    Property(Box<Property>),
701    GrantPrivilege(Box<GrantPrivilege>),
702    GrantPrincipal(Box<GrantPrincipal>),
703    AllowedValuesProperty(Box<AllowedValuesProperty>),
704    AlgorithmProperty(Box<AlgorithmProperty>),
705    AutoIncrementProperty(Box<AutoIncrementProperty>),
706    AutoRefreshProperty(Box<AutoRefreshProperty>),
707    BackupProperty(Box<BackupProperty>),
708    BuildProperty(Box<BuildProperty>),
709    BlockCompressionProperty(Box<BlockCompressionProperty>),
710    CharacterSetProperty(Box<CharacterSetProperty>),
711    ChecksumProperty(Box<ChecksumProperty>),
712    CollateProperty(Box<CollateProperty>),
713    DataBlocksizeProperty(Box<DataBlocksizeProperty>),
714    DataDeletionProperty(Box<DataDeletionProperty>),
715    DefinerProperty(Box<DefinerProperty>),
716    DistKeyProperty(Box<DistKeyProperty>),
717    DistributedByProperty(Box<DistributedByProperty>),
718    DistStyleProperty(Box<DistStyleProperty>),
719    DuplicateKeyProperty(Box<DuplicateKeyProperty>),
720    EngineProperty(Box<EngineProperty>),
721    ToTableProperty(Box<ToTableProperty>),
722    ExecuteAsProperty(Box<ExecuteAsProperty>),
723    ExternalProperty(Box<ExternalProperty>),
724    FallbackProperty(Box<FallbackProperty>),
725    FileFormatProperty(Box<FileFormatProperty>),
726    CredentialsProperty(Box<CredentialsProperty>),
727    FreespaceProperty(Box<FreespaceProperty>),
728    InheritsProperty(Box<InheritsProperty>),
729    InputModelProperty(Box<InputModelProperty>),
730    OutputModelProperty(Box<OutputModelProperty>),
731    IsolatedLoadingProperty(Box<IsolatedLoadingProperty>),
732    JournalProperty(Box<JournalProperty>),
733    LanguageProperty(Box<LanguageProperty>),
734    EnviromentProperty(Box<EnviromentProperty>),
735    ClusteredByProperty(Box<ClusteredByProperty>),
736    DictProperty(Box<DictProperty>),
737    DictRange(Box<DictRange>),
738    OnCluster(Box<OnCluster>),
739    LikeProperty(Box<LikeProperty>),
740    LocationProperty(Box<LocationProperty>),
741    LockProperty(Box<LockProperty>),
742    LockingProperty(Box<LockingProperty>),
743    LogProperty(Box<LogProperty>),
744    MaterializedProperty(Box<MaterializedProperty>),
745    MergeBlockRatioProperty(Box<MergeBlockRatioProperty>),
746    OnProperty(Box<OnProperty>),
747    OnCommitProperty(Box<OnCommitProperty>),
748    PartitionedByProperty(Box<PartitionedByProperty>),
749    PartitionByProperty(Box<PartitionByProperty>),
750    PartitionedByBucket(Box<PartitionedByBucket>),
751    ClusterByColumnsProperty(Box<ClusterByColumnsProperty>),
752    PartitionByTruncate(Box<PartitionByTruncate>),
753    PartitionByRangeProperty(Box<PartitionByRangeProperty>),
754    PartitionByRangePropertyDynamic(Box<PartitionByRangePropertyDynamic>),
755    PartitionByListProperty(Box<PartitionByListProperty>),
756    PartitionList(Box<PartitionList>),
757    Partition(Box<Partition>),
758    RefreshTriggerProperty(Box<RefreshTriggerProperty>),
759    UniqueKeyProperty(Box<UniqueKeyProperty>),
760    RollupProperty(Box<RollupProperty>),
761    PartitionBoundSpec(Box<PartitionBoundSpec>),
762    PartitionedOfProperty(Box<PartitionedOfProperty>),
763    RemoteWithConnectionModelProperty(Box<RemoteWithConnectionModelProperty>),
764    ReturnsProperty(Box<ReturnsProperty>),
765    RowFormatProperty(Box<RowFormatProperty>),
766    RowFormatDelimitedProperty(Box<RowFormatDelimitedProperty>),
767    RowFormatSerdeProperty(Box<RowFormatSerdeProperty>),
768    QueryTransform(Box<QueryTransform>),
769    SampleProperty(Box<SampleProperty>),
770    SecurityProperty(Box<SecurityProperty>),
771    SchemaCommentProperty(Box<SchemaCommentProperty>),
772    SemanticView(Box<SemanticView>),
773    SerdeProperties(Box<SerdeProperties>),
774    SetProperty(Box<SetProperty>),
775    SharingProperty(Box<SharingProperty>),
776    SetConfigProperty(Box<SetConfigProperty>),
777    SettingsProperty(Box<SettingsProperty>),
778    SortKeyProperty(Box<SortKeyProperty>),
779    SqlReadWriteProperty(Box<SqlReadWriteProperty>),
780    SqlSecurityProperty(Box<SqlSecurityProperty>),
781    StabilityProperty(Box<StabilityProperty>),
782    StorageHandlerProperty(Box<StorageHandlerProperty>),
783    TemporaryProperty(Box<TemporaryProperty>),
784    Tags(Box<Tags>),
785    TransformModelProperty(Box<TransformModelProperty>),
786    TransientProperty(Box<TransientProperty>),
787    UsingTemplateProperty(Box<UsingTemplateProperty>),
788    ViewAttributeProperty(Box<ViewAttributeProperty>),
789    VolatileProperty(Box<VolatileProperty>),
790    WithDataProperty(Box<WithDataProperty>),
791    WithJournalTableProperty(Box<WithJournalTableProperty>),
792    WithSchemaBindingProperty(Box<WithSchemaBindingProperty>),
793    WithSystemVersioningProperty(Box<WithSystemVersioningProperty>),
794    WithProcedureOptions(Box<WithProcedureOptions>),
795    EncodeProperty(Box<EncodeProperty>),
796    IncludeProperty(Box<IncludeProperty>),
797    Properties(Box<Properties>),
798    OptionsProperty(Box<OptionsProperty>),
799    InputOutputFormat(Box<InputOutputFormat>),
800    Reference(Box<Reference>),
801    QueryOption(Box<QueryOption>),
802    WithTableHint(Box<WithTableHint>),
803    IndexTableHint(Box<IndexTableHint>),
804    HistoricalData(Box<HistoricalData>),
805    Get(Box<Get>),
806    SetOperation(Box<SetOperation>),
807    Var(Box<Var>),
808    Variadic(Box<Variadic>),
809    Version(Box<Version>),
810    Schema(Box<Schema>),
811    Lock(Box<Lock>),
812    TableSample(Box<TableSample>),
813    Tag(Box<Tag>),
814    UnpivotColumns(Box<UnpivotColumns>),
815    WindowSpec(Box<WindowSpec>),
816    SessionParameter(Box<SessionParameter>),
817    PseudoType(Box<PseudoType>),
818    ObjectIdentifier(Box<ObjectIdentifier>),
819    Transaction(Box<Transaction>),
820    Commit(Box<Commit>),
821    Rollback(Box<Rollback>),
822    AlterSession(Box<AlterSession>),
823    Analyze(Box<Analyze>),
824    AnalyzeStatistics(Box<AnalyzeStatistics>),
825    AnalyzeHistogram(Box<AnalyzeHistogram>),
826    AnalyzeSample(Box<AnalyzeSample>),
827    AnalyzeListChainedRows(Box<AnalyzeListChainedRows>),
828    AnalyzeDelete(Box<AnalyzeDelete>),
829    AnalyzeWith(Box<AnalyzeWith>),
830    AnalyzeValidate(Box<AnalyzeValidate>),
831    AddPartition(Box<AddPartition>),
832    AttachOption(Box<AttachOption>),
833    DropPartition(Box<DropPartition>),
834    ReplacePartition(Box<ReplacePartition>),
835    DPipe(Box<DPipe>),
836    Operator(Box<Operator>),
837    PivotAny(Box<PivotAny>),
838    Aliases(Box<Aliases>),
839    AtIndex(Box<AtIndex>),
840    FromTimeZone(Box<FromTimeZone>),
841    FormatPhrase(Box<FormatPhrase>),
842    ForIn(Box<ForIn>),
843    TimeUnit(Box<TimeUnit>),
844    IntervalOp(Box<IntervalOp>),
845    IntervalSpan(Box<IntervalSpan>),
846    HavingMax(Box<HavingMax>),
847    CosineDistance(Box<CosineDistance>),
848    DotProduct(Box<DotProduct>),
849    EuclideanDistance(Box<EuclideanDistance>),
850    ManhattanDistance(Box<ManhattanDistance>),
851    JarowinklerSimilarity(Box<JarowinklerSimilarity>),
852    Booland(Box<Booland>),
853    Boolor(Box<Boolor>),
854    ParameterizedAgg(Box<ParameterizedAgg>),
855    ArgMax(Box<ArgMax>),
856    ArgMin(Box<ArgMin>),
857    ApproxTopK(Box<ApproxTopK>),
858    ApproxTopKAccumulate(Box<ApproxTopKAccumulate>),
859    ApproxTopKCombine(Box<ApproxTopKCombine>),
860    ApproxTopKEstimate(Box<ApproxTopKEstimate>),
861    ApproxTopSum(Box<ApproxTopSum>),
862    ApproxQuantiles(Box<ApproxQuantiles>),
863    Minhash(Box<Minhash>),
864    FarmFingerprint(Box<FarmFingerprint>),
865    Float64(Box<Float64>),
866    Transform(Box<Transform>),
867    Translate(Box<Translate>),
868    Grouping(Box<Grouping>),
869    GroupingId(Box<GroupingId>),
870    Anonymous(Box<Anonymous>),
871    AnonymousAggFunc(Box<AnonymousAggFunc>),
872    CombinedAggFunc(Box<CombinedAggFunc>),
873    CombinedParameterizedAgg(Box<CombinedParameterizedAgg>),
874    HashAgg(Box<HashAgg>),
875    Hll(Box<Hll>),
876    Apply(Box<Apply>),
877    ToBoolean(Box<ToBoolean>),
878    List(Box<List>),
879    ToMap(Box<ToMap>),
880    Pad(Box<Pad>),
881    ToChar(Box<ToChar>),
882    ToNumber(Box<ToNumber>),
883    ToDouble(Box<ToDouble>),
884    Int64(Box<UnaryFunc>),
885    StringFunc(Box<StringFunc>),
886    ToDecfloat(Box<ToDecfloat>),
887    TryToDecfloat(Box<TryToDecfloat>),
888    ToFile(Box<ToFile>),
889    Columns(Box<Columns>),
890    ConvertToCharset(Box<ConvertToCharset>),
891    ConvertTimezone(Box<ConvertTimezone>),
892    GenerateSeries(Box<GenerateSeries>),
893    AIAgg(Box<AIAgg>),
894    AIClassify(Box<AIClassify>),
895    ArrayAll(Box<ArrayAll>),
896    ArrayAny(Box<ArrayAny>),
897    ArrayConstructCompact(Box<ArrayConstructCompact>),
898    StPoint(Box<StPoint>),
899    StDistance(Box<StDistance>),
900    StringToArray(Box<StringToArray>),
901    ArraySum(Box<ArraySum>),
902    ObjectAgg(Box<ObjectAgg>),
903    CastToStrType(Box<CastToStrType>),
904    CheckJson(Box<CheckJson>),
905    CheckXml(Box<CheckXml>),
906    TranslateCharacters(Box<TranslateCharacters>),
907    CurrentSchemas(Box<CurrentSchemas>),
908    CurrentDatetime(Box<CurrentDatetime>),
909    Localtime(Box<Localtime>),
910    Localtimestamp(Box<Localtimestamp>),
911    Systimestamp(Box<Systimestamp>),
912    CurrentSchema(Box<CurrentSchema>),
913    CurrentUser(Box<CurrentUser>),
914    UtcTime(Box<UtcTime>),
915    UtcTimestamp(Box<UtcTimestamp>),
916    Timestamp(Box<TimestampFunc>),
917    DateBin(Box<DateBin>),
918    Datetime(Box<Datetime>),
919    DatetimeAdd(Box<DatetimeAdd>),
920    DatetimeSub(Box<DatetimeSub>),
921    DatetimeDiff(Box<DatetimeDiff>),
922    DatetimeTrunc(Box<DatetimeTrunc>),
923    Dayname(Box<Dayname>),
924    MakeInterval(Box<MakeInterval>),
925    PreviousDay(Box<PreviousDay>),
926    Elt(Box<Elt>),
927    TimestampAdd(Box<TimestampAdd>),
928    TimestampSub(Box<TimestampSub>),
929    TimestampDiff(Box<TimestampDiff>),
930    TimeSlice(Box<TimeSlice>),
931    TimeAdd(Box<TimeAdd>),
932    TimeSub(Box<TimeSub>),
933    TimeDiff(Box<TimeDiff>),
934    TimeTrunc(Box<TimeTrunc>),
935    DateFromParts(Box<DateFromParts>),
936    TimeFromParts(Box<TimeFromParts>),
937    DecodeCase(Box<DecodeCase>),
938    Decrypt(Box<Decrypt>),
939    DecryptRaw(Box<DecryptRaw>),
940    Encode(Box<Encode>),
941    Encrypt(Box<Encrypt>),
942    EncryptRaw(Box<EncryptRaw>),
943    EqualNull(Box<EqualNull>),
944    ToBinary(Box<ToBinary>),
945    Base64DecodeBinary(Box<Base64DecodeBinary>),
946    Base64DecodeString(Box<Base64DecodeString>),
947    Base64Encode(Box<Base64Encode>),
948    TryBase64DecodeBinary(Box<TryBase64DecodeBinary>),
949    TryBase64DecodeString(Box<TryBase64DecodeString>),
950    GapFill(Box<GapFill>),
951    GenerateDateArray(Box<GenerateDateArray>),
952    GenerateTimestampArray(Box<GenerateTimestampArray>),
953    GetExtract(Box<GetExtract>),
954    Getbit(Box<Getbit>),
955    OverflowTruncateBehavior(Box<OverflowTruncateBehavior>),
956    HexEncode(Box<HexEncode>),
957    Compress(Box<Compress>),
958    DecompressBinary(Box<DecompressBinary>),
959    DecompressString(Box<DecompressString>),
960    Xor(Box<Xor>),
961    Nullif(Box<Nullif>),
962    JSON(Box<JSON>),
963    JSONPath(Box<JSONPath>),
964    JSONPathFilter(Box<JSONPathFilter>),
965    JSONPathKey(Box<JSONPathKey>),
966    JSONPathRecursive(Box<JSONPathRecursive>),
967    JSONPathScript(Box<JSONPathScript>),
968    JSONPathSlice(Box<JSONPathSlice>),
969    JSONPathSelector(Box<JSONPathSelector>),
970    JSONPathSubscript(Box<JSONPathSubscript>),
971    JSONPathUnion(Box<JSONPathUnion>),
972    Format(Box<Format>),
973    JSONKeys(Box<JSONKeys>),
974    JSONKeyValue(Box<JSONKeyValue>),
975    JSONKeysAtDepth(Box<JSONKeysAtDepth>),
976    JSONObject(Box<JSONObject>),
977    JSONObjectAgg(Box<JSONObjectAgg>),
978    JSONBObjectAgg(Box<JSONBObjectAgg>),
979    JSONArray(Box<JSONArray>),
980    JSONArrayAgg(Box<JSONArrayAgg>),
981    JSONExists(Box<JSONExists>),
982    JSONColumnDef(Box<JSONColumnDef>),
983    JSONSchema(Box<JSONSchema>),
984    JSONSet(Box<JSONSet>),
985    JSONStripNulls(Box<JSONStripNulls>),
986    JSONValue(Box<JSONValue>),
987    JSONValueArray(Box<JSONValueArray>),
988    JSONRemove(Box<JSONRemove>),
989    JSONTable(Box<JSONTable>),
990    JSONType(Box<JSONType>),
991    ObjectInsert(Box<ObjectInsert>),
992    OpenJSONColumnDef(Box<OpenJSONColumnDef>),
993    OpenJSON(Box<OpenJSON>),
994    JSONBExists(Box<JSONBExists>),
995    JSONBContains(Box<BinaryFunc>),
996    JSONBExtract(Box<BinaryFunc>),
997    JSONCast(Box<JSONCast>),
998    JSONExtract(Box<JSONExtract>),
999    JSONExtractQuote(Box<JSONExtractQuote>),
1000    JSONExtractArray(Box<JSONExtractArray>),
1001    JSONExtractScalar(Box<JSONExtractScalar>),
1002    JSONBExtractScalar(Box<JSONBExtractScalar>),
1003    JSONFormat(Box<JSONFormat>),
1004    JSONBool(Box<UnaryFunc>),
1005    JSONPathRoot(JSONPathRoot),
1006    JSONArrayAppend(Box<JSONArrayAppend>),
1007    JSONArrayContains(Box<JSONArrayContains>),
1008    JSONArrayInsert(Box<JSONArrayInsert>),
1009    ParseJSON(Box<ParseJSON>),
1010    ParseUrl(Box<ParseUrl>),
1011    ParseIp(Box<ParseIp>),
1012    ParseTime(Box<ParseTime>),
1013    ParseDatetime(Box<ParseDatetime>),
1014    Map(Box<Map>),
1015    MapCat(Box<MapCat>),
1016    MapDelete(Box<MapDelete>),
1017    MapInsert(Box<MapInsert>),
1018    MapPick(Box<MapPick>),
1019    ScopeResolution(Box<ScopeResolution>),
1020    Slice(Box<Slice>),
1021    VarMap(Box<VarMap>),
1022    MatchAgainst(Box<MatchAgainst>),
1023    MD5Digest(Box<MD5Digest>),
1024    MD5NumberLower64(Box<UnaryFunc>),
1025    MD5NumberUpper64(Box<UnaryFunc>),
1026    Monthname(Box<Monthname>),
1027    Ntile(Box<Ntile>),
1028    Normalize(Box<Normalize>),
1029    Normal(Box<Normal>),
1030    Predict(Box<Predict>),
1031    MLTranslate(Box<MLTranslate>),
1032    FeaturesAtTime(Box<FeaturesAtTime>),
1033    GenerateEmbedding(Box<GenerateEmbedding>),
1034    MLForecast(Box<MLForecast>),
1035    ModelAttribute(Box<ModelAttribute>),
1036    VectorSearch(Box<VectorSearch>),
1037    Quantile(Box<Quantile>),
1038    ApproxQuantile(Box<ApproxQuantile>),
1039    ApproxPercentileEstimate(Box<ApproxPercentileEstimate>),
1040    Randn(Box<Randn>),
1041    Randstr(Box<Randstr>),
1042    RangeN(Box<RangeN>),
1043    RangeBucket(Box<RangeBucket>),
1044    ReadCSV(Box<ReadCSV>),
1045    ReadParquet(Box<ReadParquet>),
1046    Reduce(Box<Reduce>),
1047    RegexpExtractAll(Box<RegexpExtractAll>),
1048    RegexpILike(Box<RegexpILike>),
1049    RegexpFullMatch(Box<RegexpFullMatch>),
1050    RegexpInstr(Box<RegexpInstr>),
1051    RegexpSplit(Box<RegexpSplit>),
1052    RegexpCount(Box<RegexpCount>),
1053    RegrValx(Box<RegrValx>),
1054    RegrValy(Box<RegrValy>),
1055    RegrAvgy(Box<RegrAvgy>),
1056    RegrAvgx(Box<RegrAvgx>),
1057    RegrCount(Box<RegrCount>),
1058    RegrIntercept(Box<RegrIntercept>),
1059    RegrR2(Box<RegrR2>),
1060    RegrSxx(Box<RegrSxx>),
1061    RegrSxy(Box<RegrSxy>),
1062    RegrSyy(Box<RegrSyy>),
1063    RegrSlope(Box<RegrSlope>),
1064    SafeAdd(Box<SafeAdd>),
1065    SafeDivide(Box<SafeDivide>),
1066    SafeMultiply(Box<SafeMultiply>),
1067    SafeSubtract(Box<SafeSubtract>),
1068    SHA2(Box<SHA2>),
1069    SHA2Digest(Box<SHA2Digest>),
1070    SortArray(Box<SortArray>),
1071    SplitPart(Box<SplitPart>),
1072    SubstringIndex(Box<SubstringIndex>),
1073    StandardHash(Box<StandardHash>),
1074    StrPosition(Box<StrPosition>),
1075    Search(Box<Search>),
1076    SearchIp(Box<SearchIp>),
1077    StrToDate(Box<StrToDate>),
1078    DateStrToDate(Box<UnaryFunc>),
1079    DateToDateStr(Box<UnaryFunc>),
1080    StrToTime(Box<StrToTime>),
1081    StrToUnix(Box<StrToUnix>),
1082    StrToMap(Box<StrToMap>),
1083    NumberToStr(Box<NumberToStr>),
1084    FromBase(Box<FromBase>),
1085    Stuff(Box<Stuff>),
1086    TimeToStr(Box<TimeToStr>),
1087    TimeStrToTime(Box<TimeStrToTime>),
1088    TsOrDsAdd(Box<TsOrDsAdd>),
1089    TsOrDsDiff(Box<TsOrDsDiff>),
1090    TsOrDsToDate(Box<TsOrDsToDate>),
1091    TsOrDsToTime(Box<TsOrDsToTime>),
1092    Unhex(Box<Unhex>),
1093    Uniform(Box<Uniform>),
1094    UnixToStr(Box<UnixToStr>),
1095    UnixToTime(Box<UnixToTime>),
1096    Uuid(Box<Uuid>),
1097    TimestampFromParts(Box<TimestampFromParts>),
1098    TimestampTzFromParts(Box<TimestampTzFromParts>),
1099    Corr(Box<Corr>),
1100    WidthBucket(Box<WidthBucket>),
1101    CovarSamp(Box<CovarSamp>),
1102    CovarPop(Box<CovarPop>),
1103    Week(Box<Week>),
1104    XMLElement(Box<XMLElement>),
1105    XMLGet(Box<XMLGet>),
1106    XMLTable(Box<XMLTable>),
1107    XMLKeyValueOption(Box<XMLKeyValueOption>),
1108    Zipf(Box<Zipf>),
1109    Merge(Box<Merge>),
1110    When(Box<When>),
1111    Whens(Box<Whens>),
1112    NextValueFor(Box<NextValueFor>),
1113    /// RETURN statement (DuckDB stored procedures)
1114    ReturnStmt(Box<Expression>),
1115}
1116
1117impl Expression {
1118    /// Create a `Column` variant, boxing the value automatically.
1119    #[inline]
1120    pub fn boxed_column(col: Column) -> Self {
1121        Expression::Column(Box::new(col))
1122    }
1123
1124    /// Create a `Table` variant, boxing the value automatically.
1125    #[inline]
1126    pub fn boxed_table(t: TableRef) -> Self {
1127        Expression::Table(Box::new(t))
1128    }
1129
1130    /// Returns `true` if this expression is a valid top-level SQL statement.
1131    ///
1132    /// Bare expressions like identifiers, literals, and function calls are not
1133    /// valid statements. This is used by `validate()` to reject inputs like
1134    /// `SELECT scooby dooby doo` which the parser splits into `SELECT scooby AS dooby`
1135    /// plus the bare identifier `doo`.
1136    pub fn is_statement(&self) -> bool {
1137        match self {
1138            // Queries
1139            Expression::Select(_)
1140            | Expression::Union(_)
1141            | Expression::Intersect(_)
1142            | Expression::Except(_)
1143            | Expression::Subquery(_)
1144            | Expression::Values(_)
1145            | Expression::PipeOperator(_)
1146
1147            // DML
1148            | Expression::Insert(_)
1149            | Expression::Update(_)
1150            | Expression::Delete(_)
1151            | Expression::Copy(_)
1152            | Expression::Put(_)
1153            | Expression::Merge(_)
1154            | Expression::TryCatch(_)
1155
1156            // DDL
1157            | Expression::CreateTable(_)
1158            | Expression::DropTable(_)
1159            | Expression::Undrop(_)
1160            | Expression::AlterTable(_)
1161            | Expression::SplitTable(_)
1162            | Expression::FlashbackTable(_)
1163            | Expression::CreateIndex(_)
1164            | Expression::DropIndex(_)
1165            | Expression::CreateView(_)
1166            | Expression::DropView(_)
1167            | Expression::AlterView(_)
1168            | Expression::AlterIndex(_)
1169            | Expression::Truncate(_)
1170            | Expression::TruncateTable(_)
1171            | Expression::CreateSchema(_)
1172            | Expression::DropSchema(_)
1173            | Expression::DropNamespace(_)
1174            | Expression::CreateDatabase(_)
1175            | Expression::DropDatabase(_)
1176            | Expression::CreateFunction(_)
1177            | Expression::DropFunction(_)
1178            | Expression::CreateProcedure(_)
1179            | Expression::DropProcedure(_)
1180            | Expression::CreateSequence(_)
1181            | Expression::CreateSynonym(_)
1182            | Expression::DropSequence(_)
1183            | Expression::AlterSequence(_)
1184            | Expression::CreateTrigger(_)
1185            | Expression::DropTrigger(_)
1186            | Expression::CreateType(_)
1187            | Expression::DropType(_)
1188            | Expression::Comment(_)
1189
1190            // Session/Transaction/Control
1191            | Expression::Use(_)
1192            | Expression::Set(_)
1193            | Expression::SetStatement(_)
1194            | Expression::Transaction(_)
1195            | Expression::Commit(_)
1196            | Expression::Rollback(_)
1197            | Expression::Grant(_)
1198            | Expression::Revoke(_)
1199            | Expression::Cache(_)
1200            | Expression::Uncache(_)
1201            | Expression::LoadData(_)
1202            | Expression::Pragma(_)
1203            | Expression::Describe(_)
1204            | Expression::Show(_)
1205            | Expression::Kill(_)
1206            | Expression::Prepare(_)
1207            | Expression::Execute(_)
1208            | Expression::Declare(_)
1209            | Expression::Refresh(_)
1210            | Expression::AlterSession(_)
1211            | Expression::LockingStatement(_)
1212
1213            // Analyze
1214            | Expression::Analyze(_)
1215            | Expression::AnalyzeStatistics(_)
1216            | Expression::AnalyzeHistogram(_)
1217            | Expression::AnalyzeSample(_)
1218            | Expression::AnalyzeListChainedRows(_)
1219            | Expression::AnalyzeDelete(_)
1220
1221            // Attach/Detach/Install/Summarize
1222            | Expression::Attach(_)
1223            | Expression::Detach(_)
1224            | Expression::Install(_)
1225            | Expression::Summarize(_)
1226
1227            // Pivot at statement level
1228            | Expression::Pivot(_)
1229            | Expression::Unpivot(_)
1230
1231            // Command (raw/unparsed statements)
1232            | Expression::Command(_)
1233            | Expression::Raw(_)
1234            | Expression::CreateTask(_)
1235
1236            // Return statement
1237            | Expression::ReturnStmt(_) => true,
1238
1239            // Annotated wraps another expression with comments — check inner
1240            Expression::Annotated(a) => a.this.is_statement(),
1241
1242            // Alias at top level can wrap a statement (e.g., parenthesized subquery with alias)
1243            Expression::Alias(a) => a.this.is_statement(),
1244
1245            // Everything else (identifiers, literals, operators, functions, etc.)
1246            _ => false,
1247        }
1248    }
1249
1250    /// Create a literal number expression from an integer.
1251    pub fn number(n: i64) -> Self {
1252        Expression::Literal(Box::new(Literal::Number(n.to_string())))
1253    }
1254
1255    /// Create a single-quoted literal string expression.
1256    pub fn string(s: impl Into<String>) -> Self {
1257        Expression::Literal(Box::new(Literal::String(s.into())))
1258    }
1259
1260    /// Create a literal number expression from a float.
1261    pub fn float(f: f64) -> Self {
1262        Expression::Literal(Box::new(Literal::Number(f.to_string())))
1263    }
1264
1265    /// Get the inferred type annotation, if present.
1266    ///
1267    /// For value-producing expressions with an `inferred_type` field, returns
1268    /// the stored type. For literals and boolean constants, computes the type
1269    /// on the fly from the variant. For DDL/clause expressions, returns `None`.
1270    pub fn inferred_type(&self) -> Option<&DataType> {
1271        match self {
1272            // Structs with inferred_type field
1273            Expression::And(op)
1274            | Expression::Or(op)
1275            | Expression::Add(op)
1276            | Expression::Sub(op)
1277            | Expression::Mul(op)
1278            | Expression::Div(op)
1279            | Expression::Mod(op)
1280            | Expression::Eq(op)
1281            | Expression::Neq(op)
1282            | Expression::Lt(op)
1283            | Expression::Lte(op)
1284            | Expression::Gt(op)
1285            | Expression::Gte(op)
1286            | Expression::Concat(op)
1287            | Expression::BitwiseAnd(op)
1288            | Expression::BitwiseOr(op)
1289            | Expression::BitwiseXor(op)
1290            | Expression::Adjacent(op)
1291            | Expression::TsMatch(op)
1292            | Expression::PropertyEQ(op)
1293            | Expression::ArrayContainsAll(op)
1294            | Expression::ArrayContainedBy(op)
1295            | Expression::ArrayOverlaps(op)
1296            | Expression::JSONBContainsAllTopKeys(op)
1297            | Expression::JSONBContainsAnyTopKeys(op)
1298            | Expression::JSONBDeleteAtPath(op)
1299            | Expression::ExtendsLeft(op)
1300            | Expression::ExtendsRight(op)
1301            | Expression::Is(op)
1302            | Expression::MemberOf(op)
1303            | Expression::Match(op)
1304            | Expression::NullSafeEq(op)
1305            | Expression::NullSafeNeq(op)
1306            | Expression::Glob(op)
1307            | Expression::BitwiseLeftShift(op)
1308            | Expression::BitwiseRightShift(op) => op.inferred_type.as_ref(),
1309
1310            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1311                op.inferred_type.as_ref()
1312            }
1313
1314            Expression::Like(op) | Expression::ILike(op) => op.inferred_type.as_ref(),
1315
1316            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1317                c.inferred_type.as_ref()
1318            }
1319
1320            Expression::Column(c) => c.inferred_type.as_ref(),
1321            Expression::Dot(dot) => dot.inferred_type.as_ref(),
1322            Expression::Function(f) => f.inferred_type.as_ref(),
1323            Expression::AggregateFunction(f) => f.inferred_type.as_ref(),
1324            Expression::WindowFunction(f) => f.inferred_type.as_ref(),
1325            Expression::Case(c) => c.inferred_type.as_ref(),
1326            Expression::Array(a) => a.inferred_type.as_ref(),
1327            Expression::ArrayFunc(a) => a.inferred_type.as_ref(),
1328            Expression::Paren(p) => p.this.inferred_type(),
1329            Expression::Annotated(a) => a.this.inferred_type(),
1330            Expression::Subquery(s) => s.inferred_type.as_ref(),
1331            Expression::Alias(a) => a.inferred_type.as_ref(),
1332            Expression::Unnest(u) => u.inferred_type.as_ref(),
1333            Expression::IfFunc(f) => f.inferred_type.as_ref(),
1334            Expression::Nvl2(f) => f.inferred_type.as_ref(),
1335            Expression::Count(f) => f.inferred_type.as_ref(),
1336            Expression::GroupConcat(f) => f.inferred_type.as_ref(),
1337            Expression::StringAgg(f) => f.inferred_type.as_ref(),
1338            Expression::ListAgg(f) => f.inferred_type.as_ref(),
1339            Expression::SumIf(f) => f.inferred_type.as_ref(),
1340            Expression::Trim(f) => f.inferred_type.as_ref(),
1341
1342            // UnaryFunc variants
1343            Expression::Upper(f)
1344            | Expression::Lower(f)
1345            | Expression::Length(f)
1346            | Expression::LTrim(f)
1347            | Expression::RTrim(f)
1348            | Expression::Reverse(f)
1349            | Expression::Abs(f)
1350            | Expression::Sqrt(f)
1351            | Expression::Cbrt(f)
1352            | Expression::Ln(f)
1353            | Expression::Exp(f)
1354            | Expression::Sign(f)
1355            | Expression::Date(f)
1356            | Expression::Time(f)
1357            | Expression::Initcap(f)
1358            | Expression::Ascii(f)
1359            | Expression::Chr(f)
1360            | Expression::Soundex(f)
1361            | Expression::ByteLength(f)
1362            | Expression::Hex(f)
1363            | Expression::LowerHex(f)
1364            | Expression::Unicode(f)
1365            | Expression::Typeof(f)
1366            | Expression::Explode(f)
1367            | Expression::ExplodeOuter(f)
1368            | Expression::MapFromEntries(f)
1369            | Expression::MapKeys(f)
1370            | Expression::MapValues(f)
1371            | Expression::ArrayLength(f)
1372            | Expression::ArraySize(f)
1373            | Expression::Cardinality(f)
1374            | Expression::ArrayReverse(f)
1375            | Expression::ArrayDistinct(f)
1376            | Expression::ArrayFlatten(f)
1377            | Expression::ArrayCompact(f)
1378            | Expression::ToArray(f)
1379            | Expression::JsonArrayLength(f)
1380            | Expression::JsonKeys(f)
1381            | Expression::JsonType(f)
1382            | Expression::ParseJson(f)
1383            | Expression::ToJson(f)
1384            | Expression::Radians(f)
1385            | Expression::Degrees(f)
1386            | Expression::Sin(f)
1387            | Expression::Cos(f)
1388            | Expression::Tan(f)
1389            | Expression::Asin(f)
1390            | Expression::Acos(f)
1391            | Expression::Atan(f)
1392            | Expression::IsNan(f)
1393            | Expression::IsInf(f)
1394            | Expression::Year(f)
1395            | Expression::Month(f)
1396            | Expression::Day(f)
1397            | Expression::Hour(f)
1398            | Expression::Minute(f)
1399            | Expression::Second(f)
1400            | Expression::DayOfWeek(f)
1401            | Expression::DayOfWeekIso(f)
1402            | Expression::DayOfMonth(f)
1403            | Expression::DayOfYear(f)
1404            | Expression::WeekOfYear(f)
1405            | Expression::Quarter(f)
1406            | Expression::Epoch(f)
1407            | Expression::EpochMs(f)
1408            | Expression::BitwiseCount(f)
1409            | Expression::DateFromUnixDate(f)
1410            | Expression::UnixDate(f)
1411            | Expression::UnixSeconds(f)
1412            | Expression::UnixMillis(f)
1413            | Expression::UnixMicros(f)
1414            | Expression::TimeStrToDate(f)
1415            | Expression::DateToDi(f)
1416            | Expression::DiToDate(f)
1417            | Expression::TsOrDiToDi(f)
1418            | Expression::TsOrDsToDatetime(f)
1419            | Expression::TsOrDsToTimestamp(f)
1420            | Expression::YearOfWeek(f)
1421            | Expression::YearOfWeekIso(f)
1422            | Expression::SHA(f)
1423            | Expression::SHA1Digest(f)
1424            | Expression::TimeToUnix(f)
1425            | Expression::TimeStrToUnix(f) => f.inferred_type.as_ref(),
1426
1427            // BinaryFunc variants
1428            Expression::Power(f)
1429            | Expression::NullIf(f)
1430            | Expression::IfNull(f)
1431            | Expression::Nvl(f)
1432            | Expression::Contains(f)
1433            | Expression::StartsWith(f)
1434            | Expression::EndsWith(f)
1435            | Expression::Levenshtein(f)
1436            | Expression::ModFunc(f)
1437            | Expression::IntDiv(f)
1438            | Expression::Atan2(f)
1439            | Expression::AddMonths(f)
1440            | Expression::MonthsBetween(f)
1441            | Expression::NextDay(f)
1442            | Expression::UnixToTimeStr(f)
1443            | Expression::ArrayContains(f)
1444            | Expression::ArrayPosition(f)
1445            | Expression::ArrayAppend(f)
1446            | Expression::ArrayPrepend(f)
1447            | Expression::ArrayUnion(f)
1448            | Expression::ArrayExcept(f)
1449            | Expression::ArrayRemove(f)
1450            | Expression::StarMap(f)
1451            | Expression::MapFromArrays(f)
1452            | Expression::MapContainsKey(f)
1453            | Expression::ElementAt(f)
1454            | Expression::JsonMergePatch(f) => f.inferred_type.as_ref(),
1455
1456            // VarArgFunc variants
1457            Expression::Coalesce(f)
1458            | Expression::Greatest(f)
1459            | Expression::Least(f)
1460            | Expression::ArrayConcat(f)
1461            | Expression::ArrayIntersect(f)
1462            | Expression::ArrayZip(f)
1463            | Expression::MapConcat(f)
1464            | Expression::JsonArray(f) => f.inferred_type.as_ref(),
1465
1466            // AggFunc variants
1467            Expression::Sum(f)
1468            | Expression::Avg(f)
1469            | Expression::Min(f)
1470            | Expression::Max(f)
1471            | Expression::ArrayAgg(f)
1472            | Expression::CountIf(f)
1473            | Expression::Stddev(f)
1474            | Expression::StddevPop(f)
1475            | Expression::StddevSamp(f)
1476            | Expression::Variance(f)
1477            | Expression::VarPop(f)
1478            | Expression::VarSamp(f)
1479            | Expression::Median(f)
1480            | Expression::Mode(f)
1481            | Expression::First(f)
1482            | Expression::Last(f)
1483            | Expression::AnyValue(f)
1484            | Expression::ApproxDistinct(f)
1485            | Expression::ApproxCountDistinct(f)
1486            | Expression::LogicalAnd(f)
1487            | Expression::LogicalOr(f)
1488            | Expression::Skewness(f)
1489            | Expression::ArrayConcatAgg(f)
1490            | Expression::ArrayUniqueAgg(f)
1491            | Expression::BoolXorAgg(f)
1492            | Expression::BitwiseAndAgg(f)
1493            | Expression::BitwiseOrAgg(f)
1494            | Expression::BitwiseXorAgg(f) => f.inferred_type.as_ref(),
1495
1496            // Everything else: no inferred_type field
1497            _ => None,
1498        }
1499    }
1500
1501    /// Set the inferred type annotation on this expression.
1502    ///
1503    /// Only has an effect on value-producing expressions with an `inferred_type`
1504    /// field. For other expression types, this is a no-op.
1505    pub fn set_inferred_type(&mut self, dt: DataType) {
1506        match self {
1507            Expression::And(op)
1508            | Expression::Or(op)
1509            | Expression::Add(op)
1510            | Expression::Sub(op)
1511            | Expression::Mul(op)
1512            | Expression::Div(op)
1513            | Expression::Mod(op)
1514            | Expression::Eq(op)
1515            | Expression::Neq(op)
1516            | Expression::Lt(op)
1517            | Expression::Lte(op)
1518            | Expression::Gt(op)
1519            | Expression::Gte(op)
1520            | Expression::Concat(op)
1521            | Expression::BitwiseAnd(op)
1522            | Expression::BitwiseOr(op)
1523            | Expression::BitwiseXor(op)
1524            | Expression::Adjacent(op)
1525            | Expression::TsMatch(op)
1526            | Expression::PropertyEQ(op)
1527            | Expression::ArrayContainsAll(op)
1528            | Expression::ArrayContainedBy(op)
1529            | Expression::ArrayOverlaps(op)
1530            | Expression::JSONBContainsAllTopKeys(op)
1531            | Expression::JSONBContainsAnyTopKeys(op)
1532            | Expression::JSONBDeleteAtPath(op)
1533            | Expression::ExtendsLeft(op)
1534            | Expression::ExtendsRight(op)
1535            | Expression::Is(op)
1536            | Expression::MemberOf(op)
1537            | Expression::Match(op)
1538            | Expression::NullSafeEq(op)
1539            | Expression::NullSafeNeq(op)
1540            | Expression::Glob(op)
1541            | Expression::BitwiseLeftShift(op)
1542            | Expression::BitwiseRightShift(op) => op.inferred_type = Some(dt),
1543
1544            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1545                op.inferred_type = Some(dt)
1546            }
1547
1548            Expression::Like(op) | Expression::ILike(op) => op.inferred_type = Some(dt),
1549
1550            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1551                c.inferred_type = Some(dt)
1552            }
1553
1554            Expression::Column(c) => c.inferred_type = Some(dt),
1555            Expression::Dot(dot) => dot.inferred_type = Some(dt),
1556            Expression::Function(f) => f.inferred_type = Some(dt),
1557            Expression::AggregateFunction(f) => f.inferred_type = Some(dt),
1558            Expression::WindowFunction(f) => f.inferred_type = Some(dt),
1559            Expression::Case(c) => c.inferred_type = Some(dt),
1560            Expression::Array(a) => a.inferred_type = Some(dt),
1561            Expression::ArrayFunc(a) => a.inferred_type = Some(dt),
1562            Expression::Paren(p) => p.this.set_inferred_type(dt),
1563            Expression::Annotated(a) => a.this.set_inferred_type(dt),
1564            Expression::Subquery(s) => s.inferred_type = Some(dt),
1565            Expression::Alias(a) => a.inferred_type = Some(dt),
1566            Expression::Unnest(u) => u.inferred_type = Some(dt),
1567            Expression::IfFunc(f) => f.inferred_type = Some(dt),
1568            Expression::Nvl2(f) => f.inferred_type = Some(dt),
1569            Expression::Count(f) => f.inferred_type = Some(dt),
1570            Expression::GroupConcat(f) => f.inferred_type = Some(dt),
1571            Expression::StringAgg(f) => f.inferred_type = Some(dt),
1572            Expression::ListAgg(f) => f.inferred_type = Some(dt),
1573            Expression::SumIf(f) => f.inferred_type = Some(dt),
1574            Expression::Trim(f) => f.inferred_type = Some(dt),
1575
1576            // UnaryFunc variants
1577            Expression::Upper(f)
1578            | Expression::Lower(f)
1579            | Expression::Length(f)
1580            | Expression::LTrim(f)
1581            | Expression::RTrim(f)
1582            | Expression::Reverse(f)
1583            | Expression::Abs(f)
1584            | Expression::Sqrt(f)
1585            | Expression::Cbrt(f)
1586            | Expression::Ln(f)
1587            | Expression::Exp(f)
1588            | Expression::Sign(f)
1589            | Expression::Date(f)
1590            | Expression::Time(f)
1591            | Expression::Initcap(f)
1592            | Expression::Ascii(f)
1593            | Expression::Chr(f)
1594            | Expression::Soundex(f)
1595            | Expression::ByteLength(f)
1596            | Expression::Hex(f)
1597            | Expression::LowerHex(f)
1598            | Expression::Unicode(f)
1599            | Expression::Typeof(f)
1600            | Expression::Explode(f)
1601            | Expression::ExplodeOuter(f)
1602            | Expression::MapFromEntries(f)
1603            | Expression::MapKeys(f)
1604            | Expression::MapValues(f)
1605            | Expression::ArrayLength(f)
1606            | Expression::ArraySize(f)
1607            | Expression::Cardinality(f)
1608            | Expression::ArrayReverse(f)
1609            | Expression::ArrayDistinct(f)
1610            | Expression::ArrayFlatten(f)
1611            | Expression::ArrayCompact(f)
1612            | Expression::ToArray(f)
1613            | Expression::JsonArrayLength(f)
1614            | Expression::JsonKeys(f)
1615            | Expression::JsonType(f)
1616            | Expression::ParseJson(f)
1617            | Expression::ToJson(f)
1618            | Expression::Radians(f)
1619            | Expression::Degrees(f)
1620            | Expression::Sin(f)
1621            | Expression::Cos(f)
1622            | Expression::Tan(f)
1623            | Expression::Asin(f)
1624            | Expression::Acos(f)
1625            | Expression::Atan(f)
1626            | Expression::IsNan(f)
1627            | Expression::IsInf(f)
1628            | Expression::Year(f)
1629            | Expression::Month(f)
1630            | Expression::Day(f)
1631            | Expression::Hour(f)
1632            | Expression::Minute(f)
1633            | Expression::Second(f)
1634            | Expression::DayOfWeek(f)
1635            | Expression::DayOfWeekIso(f)
1636            | Expression::DayOfMonth(f)
1637            | Expression::DayOfYear(f)
1638            | Expression::WeekOfYear(f)
1639            | Expression::Quarter(f)
1640            | Expression::Epoch(f)
1641            | Expression::EpochMs(f)
1642            | Expression::BitwiseCount(f)
1643            | Expression::DateFromUnixDate(f)
1644            | Expression::UnixDate(f)
1645            | Expression::UnixSeconds(f)
1646            | Expression::UnixMillis(f)
1647            | Expression::UnixMicros(f)
1648            | Expression::TimeStrToDate(f)
1649            | Expression::DateToDi(f)
1650            | Expression::DiToDate(f)
1651            | Expression::TsOrDiToDi(f)
1652            | Expression::TsOrDsToDatetime(f)
1653            | Expression::TsOrDsToTimestamp(f)
1654            | Expression::YearOfWeek(f)
1655            | Expression::YearOfWeekIso(f)
1656            | Expression::SHA(f)
1657            | Expression::SHA1Digest(f)
1658            | Expression::TimeToUnix(f)
1659            | Expression::TimeStrToUnix(f) => f.inferred_type = Some(dt),
1660
1661            // BinaryFunc variants
1662            Expression::Power(f)
1663            | Expression::NullIf(f)
1664            | Expression::IfNull(f)
1665            | Expression::Nvl(f)
1666            | Expression::Contains(f)
1667            | Expression::StartsWith(f)
1668            | Expression::EndsWith(f)
1669            | Expression::Levenshtein(f)
1670            | Expression::ModFunc(f)
1671            | Expression::IntDiv(f)
1672            | Expression::Atan2(f)
1673            | Expression::AddMonths(f)
1674            | Expression::MonthsBetween(f)
1675            | Expression::NextDay(f)
1676            | Expression::UnixToTimeStr(f)
1677            | Expression::ArrayContains(f)
1678            | Expression::ArrayPosition(f)
1679            | Expression::ArrayAppend(f)
1680            | Expression::ArrayPrepend(f)
1681            | Expression::ArrayUnion(f)
1682            | Expression::ArrayExcept(f)
1683            | Expression::ArrayRemove(f)
1684            | Expression::StarMap(f)
1685            | Expression::MapFromArrays(f)
1686            | Expression::MapContainsKey(f)
1687            | Expression::ElementAt(f)
1688            | Expression::JsonMergePatch(f) => f.inferred_type = Some(dt),
1689
1690            // VarArgFunc variants
1691            Expression::Coalesce(f)
1692            | Expression::Greatest(f)
1693            | Expression::Least(f)
1694            | Expression::ArrayConcat(f)
1695            | Expression::ArrayIntersect(f)
1696            | Expression::ArrayZip(f)
1697            | Expression::MapConcat(f)
1698            | Expression::JsonArray(f) => f.inferred_type = Some(dt),
1699
1700            // AggFunc variants
1701            Expression::Sum(f)
1702            | Expression::Avg(f)
1703            | Expression::Min(f)
1704            | Expression::Max(f)
1705            | Expression::ArrayAgg(f)
1706            | Expression::CountIf(f)
1707            | Expression::Stddev(f)
1708            | Expression::StddevPop(f)
1709            | Expression::StddevSamp(f)
1710            | Expression::Variance(f)
1711            | Expression::VarPop(f)
1712            | Expression::VarSamp(f)
1713            | Expression::Median(f)
1714            | Expression::Mode(f)
1715            | Expression::First(f)
1716            | Expression::Last(f)
1717            | Expression::AnyValue(f)
1718            | Expression::ApproxDistinct(f)
1719            | Expression::ApproxCountDistinct(f)
1720            | Expression::LogicalAnd(f)
1721            | Expression::LogicalOr(f)
1722            | Expression::Skewness(f)
1723            | Expression::ArrayConcatAgg(f)
1724            | Expression::ArrayUniqueAgg(f)
1725            | Expression::BoolXorAgg(f)
1726            | Expression::BitwiseAndAgg(f)
1727            | Expression::BitwiseOrAgg(f)
1728            | Expression::BitwiseXorAgg(f) => f.inferred_type = Some(dt),
1729
1730            // Expressions without inferred_type field - no-op
1731            _ => {}
1732        }
1733    }
1734
1735    /// Create an unqualified column reference (e.g. `name`).
1736    pub fn column(name: impl Into<String>) -> Self {
1737        Expression::Column(Box::new(Column {
1738            name: Identifier::new(name),
1739            table: None,
1740            join_mark: false,
1741            trailing_comments: Vec::new(),
1742            span: None,
1743            inferred_type: None,
1744        }))
1745    }
1746
1747    /// Create a qualified column reference (`table.column`).
1748    pub fn qualified_column(table: impl Into<String>, column: impl Into<String>) -> Self {
1749        Expression::Column(Box::new(Column {
1750            name: Identifier::new(column),
1751            table: Some(Identifier::new(table)),
1752            join_mark: false,
1753            trailing_comments: Vec::new(),
1754            span: None,
1755            inferred_type: None,
1756        }))
1757    }
1758
1759    /// Create a bare identifier expression (not a column reference).
1760    pub fn identifier(name: impl Into<String>) -> Self {
1761        Expression::Identifier(Identifier::new(name))
1762    }
1763
1764    /// Create a NULL expression
1765    pub fn null() -> Self {
1766        Expression::Null(Null)
1767    }
1768
1769    /// Create a TRUE expression
1770    pub fn true_() -> Self {
1771        Expression::Boolean(BooleanLiteral { value: true })
1772    }
1773
1774    /// Create a FALSE expression
1775    pub fn false_() -> Self {
1776        Expression::Boolean(BooleanLiteral { value: false })
1777    }
1778
1779    /// Create a wildcard star (`*`) expression with no EXCEPT/REPLACE/RENAME modifiers.
1780    pub fn star() -> Self {
1781        Expression::Star(Star {
1782            table: None,
1783            except: None,
1784            replace: None,
1785            rename: None,
1786            trailing_comments: Vec::new(),
1787            span: None,
1788        })
1789    }
1790
1791    /// Wrap this expression in an `AS` alias (e.g. `expr AS name`).
1792    pub fn alias(self, name: impl Into<String>) -> Self {
1793        Expression::Alias(Box::new(Alias::new(self, Identifier::new(name))))
1794    }
1795
1796    /// Check if this is a SELECT expression
1797    pub fn is_select(&self) -> bool {
1798        matches!(self, Expression::Select(_))
1799    }
1800
1801    /// Try to get as a Select
1802    pub fn as_select(&self) -> Option<&Select> {
1803        match self {
1804            Expression::Select(s) => Some(s),
1805            _ => None,
1806        }
1807    }
1808
1809    /// Try to get as a mutable Select
1810    pub fn as_select_mut(&mut self) -> Option<&mut Select> {
1811        match self {
1812            Expression::Select(s) => Some(s),
1813            _ => None,
1814        }
1815    }
1816
1817    /// Generate a SQL string for this expression using the generic (dialect-agnostic) generator.
1818    ///
1819    /// Returns an empty string if generation fails. For dialect-specific output,
1820    /// use [`sql_for()`](Self::sql_for) instead.
1821    #[cfg(feature = "generate")]
1822    pub fn sql(&self) -> String {
1823        crate::generator::Generator::sql(self).unwrap_or_default()
1824    }
1825
1826    /// Generate a SQL string for this expression targeting a specific dialect.
1827    ///
1828    /// Dialect-specific rules (identifier quoting, function names, type mappings,
1829    /// syntax variations) are applied automatically.  Returns an empty string if
1830    /// generation fails.
1831    #[cfg(feature = "generate")]
1832    pub fn sql_for(&self, dialect: crate::dialects::DialectType) -> String {
1833        crate::generate(self, dialect).unwrap_or_default()
1834    }
1835}
1836
1837// === Python API accessor methods ===
1838
1839impl Expression {
1840    /// Returns the serde-compatible snake_case variant name without serialization.
1841    /// This is much faster than serializing to JSON and extracting the key.
1842    pub fn variant_name(&self) -> &'static str {
1843        match self {
1844            Expression::Literal(_) => "literal",
1845            Expression::Boolean(_) => "boolean",
1846            Expression::Null(_) => "null",
1847            Expression::Identifier(_) => "identifier",
1848            Expression::Column(_) => "column",
1849            Expression::Table(_) => "table",
1850            Expression::Star(_) => "star",
1851            Expression::BracedWildcard(_) => "braced_wildcard",
1852            Expression::Select(_) => "select",
1853            Expression::Union(_) => "union",
1854            Expression::Intersect(_) => "intersect",
1855            Expression::Except(_) => "except",
1856            Expression::Subquery(_) => "subquery",
1857            Expression::PipeOperator(_) => "pipe_operator",
1858            Expression::Pivot(_) => "pivot",
1859            Expression::PivotAlias(_) => "pivot_alias",
1860            Expression::Unpivot(_) => "unpivot",
1861            Expression::Values(_) => "values",
1862            Expression::PreWhere(_) => "pre_where",
1863            Expression::Stream(_) => "stream",
1864            Expression::UsingData(_) => "using_data",
1865            Expression::XmlNamespace(_) => "xml_namespace",
1866            Expression::Insert(_) => "insert",
1867            Expression::Update(_) => "update",
1868            Expression::Delete(_) => "delete",
1869            Expression::Copy(_) => "copy",
1870            Expression::Put(_) => "put",
1871            Expression::StageReference(_) => "stage_reference",
1872            Expression::Alias(_) => "alias",
1873            Expression::Cast(_) => "cast",
1874            Expression::Collation(_) => "collation",
1875            Expression::Case(_) => "case",
1876            Expression::And(_) => "and",
1877            Expression::Or(_) => "or",
1878            Expression::Add(_) => "add",
1879            Expression::Sub(_) => "sub",
1880            Expression::Mul(_) => "mul",
1881            Expression::Div(_) => "div",
1882            Expression::Mod(_) => "mod",
1883            Expression::Eq(_) => "eq",
1884            Expression::Neq(_) => "neq",
1885            Expression::Lt(_) => "lt",
1886            Expression::Lte(_) => "lte",
1887            Expression::Gt(_) => "gt",
1888            Expression::Gte(_) => "gte",
1889            Expression::Like(_) => "like",
1890            Expression::ILike(_) => "i_like",
1891            Expression::Match(_) => "match",
1892            Expression::BitwiseAnd(_) => "bitwise_and",
1893            Expression::BitwiseOr(_) => "bitwise_or",
1894            Expression::BitwiseXor(_) => "bitwise_xor",
1895            Expression::Concat(_) => "concat",
1896            Expression::Adjacent(_) => "adjacent",
1897            Expression::TsMatch(_) => "ts_match",
1898            Expression::PropertyEQ(_) => "property_e_q",
1899            Expression::ArrayContainsAll(_) => "array_contains_all",
1900            Expression::ArrayContainedBy(_) => "array_contained_by",
1901            Expression::ArrayOverlaps(_) => "array_overlaps",
1902            Expression::JSONBContainsAllTopKeys(_) => "j_s_o_n_b_contains_all_top_keys",
1903            Expression::JSONBContainsAnyTopKeys(_) => "j_s_o_n_b_contains_any_top_keys",
1904            Expression::JSONBDeleteAtPath(_) => "j_s_o_n_b_delete_at_path",
1905            Expression::ExtendsLeft(_) => "extends_left",
1906            Expression::ExtendsRight(_) => "extends_right",
1907            Expression::Not(_) => "not",
1908            Expression::Neg(_) => "neg",
1909            Expression::BitwiseNot(_) => "bitwise_not",
1910            Expression::In(_) => "in",
1911            Expression::Between(_) => "between",
1912            Expression::IsNull(_) => "is_null",
1913            Expression::IsTrue(_) => "is_true",
1914            Expression::IsFalse(_) => "is_false",
1915            Expression::IsJson(_) => "is_json",
1916            Expression::Is(_) => "is",
1917            Expression::Exists(_) => "exists",
1918            Expression::MemberOf(_) => "member_of",
1919            Expression::Function(_) => "function",
1920            Expression::AggregateFunction(_) => "aggregate_function",
1921            Expression::WindowFunction(_) => "window_function",
1922            Expression::From(_) => "from",
1923            Expression::Join(_) => "join",
1924            Expression::JoinedTable(_) => "joined_table",
1925            Expression::Where(_) => "where",
1926            Expression::GroupBy(_) => "group_by",
1927            Expression::Having(_) => "having",
1928            Expression::OrderBy(_) => "order_by",
1929            Expression::Limit(_) => "limit",
1930            Expression::Offset(_) => "offset",
1931            Expression::Qualify(_) => "qualify",
1932            Expression::With(_) => "with",
1933            Expression::Cte(_) => "cte",
1934            Expression::DistributeBy(_) => "distribute_by",
1935            Expression::ClusterBy(_) => "cluster_by",
1936            Expression::SortBy(_) => "sort_by",
1937            Expression::LateralView(_) => "lateral_view",
1938            Expression::Hint(_) => "hint",
1939            Expression::Pseudocolumn(_) => "pseudocolumn",
1940            Expression::Connect(_) => "connect",
1941            Expression::Prior(_) => "prior",
1942            Expression::ConnectByRoot(_) => "connect_by_root",
1943            Expression::MatchRecognize(_) => "match_recognize",
1944            Expression::Ordered(_) => "ordered",
1945            Expression::Window(_) => "window",
1946            Expression::Over(_) => "over",
1947            Expression::WithinGroup(_) => "within_group",
1948            Expression::DataType(_) => "data_type",
1949            Expression::Array(_) => "array",
1950            Expression::Struct(_) => "struct",
1951            Expression::Tuple(_) => "tuple",
1952            Expression::Interval(_) => "interval",
1953            Expression::ConcatWs(_) => "concat_ws",
1954            Expression::Substring(_) => "substring",
1955            Expression::Upper(_) => "upper",
1956            Expression::Lower(_) => "lower",
1957            Expression::Length(_) => "length",
1958            Expression::Trim(_) => "trim",
1959            Expression::LTrim(_) => "l_trim",
1960            Expression::RTrim(_) => "r_trim",
1961            Expression::Replace(_) => "replace",
1962            Expression::Reverse(_) => "reverse",
1963            Expression::Left(_) => "left",
1964            Expression::Right(_) => "right",
1965            Expression::Repeat(_) => "repeat",
1966            Expression::Lpad(_) => "lpad",
1967            Expression::Rpad(_) => "rpad",
1968            Expression::Split(_) => "split",
1969            Expression::RegexpLike(_) => "regexp_like",
1970            Expression::RegexpReplace(_) => "regexp_replace",
1971            Expression::RegexpExtract(_) => "regexp_extract",
1972            Expression::Overlay(_) => "overlay",
1973            Expression::Abs(_) => "abs",
1974            Expression::Round(_) => "round",
1975            Expression::Floor(_) => "floor",
1976            Expression::Ceil(_) => "ceil",
1977            Expression::Power(_) => "power",
1978            Expression::Sqrt(_) => "sqrt",
1979            Expression::Cbrt(_) => "cbrt",
1980            Expression::Ln(_) => "ln",
1981            Expression::Log(_) => "log",
1982            Expression::Exp(_) => "exp",
1983            Expression::Sign(_) => "sign",
1984            Expression::Greatest(_) => "greatest",
1985            Expression::Least(_) => "least",
1986            Expression::CurrentDate(_) => "current_date",
1987            Expression::CurrentTime(_) => "current_time",
1988            Expression::CurrentTimestamp(_) => "current_timestamp",
1989            Expression::CurrentTimestampLTZ(_) => "current_timestamp_l_t_z",
1990            Expression::AtTimeZone(_) => "at_time_zone",
1991            Expression::DateAdd(_) => "date_add",
1992            Expression::DateSub(_) => "date_sub",
1993            Expression::DateDiff(_) => "date_diff",
1994            Expression::DateTrunc(_) => "date_trunc",
1995            Expression::Extract(_) => "extract",
1996            Expression::ToDate(_) => "to_date",
1997            Expression::ToTimestamp(_) => "to_timestamp",
1998            Expression::Date(_) => "date",
1999            Expression::Time(_) => "time",
2000            Expression::DateFromUnixDate(_) => "date_from_unix_date",
2001            Expression::UnixDate(_) => "unix_date",
2002            Expression::UnixSeconds(_) => "unix_seconds",
2003            Expression::UnixMillis(_) => "unix_millis",
2004            Expression::UnixMicros(_) => "unix_micros",
2005            Expression::UnixToTimeStr(_) => "unix_to_time_str",
2006            Expression::TimeStrToDate(_) => "time_str_to_date",
2007            Expression::DateToDi(_) => "date_to_di",
2008            Expression::DiToDate(_) => "di_to_date",
2009            Expression::TsOrDiToDi(_) => "ts_or_di_to_di",
2010            Expression::TsOrDsToDatetime(_) => "ts_or_ds_to_datetime",
2011            Expression::TsOrDsToTimestamp(_) => "ts_or_ds_to_timestamp",
2012            Expression::YearOfWeek(_) => "year_of_week",
2013            Expression::YearOfWeekIso(_) => "year_of_week_iso",
2014            Expression::Coalesce(_) => "coalesce",
2015            Expression::NullIf(_) => "null_if",
2016            Expression::IfFunc(_) => "if_func",
2017            Expression::IfNull(_) => "if_null",
2018            Expression::Nvl(_) => "nvl",
2019            Expression::Nvl2(_) => "nvl2",
2020            Expression::TryCast(_) => "try_cast",
2021            Expression::SafeCast(_) => "safe_cast",
2022            Expression::Count(_) => "count",
2023            Expression::Sum(_) => "sum",
2024            Expression::Avg(_) => "avg",
2025            Expression::Min(_) => "min",
2026            Expression::Max(_) => "max",
2027            Expression::GroupConcat(_) => "group_concat",
2028            Expression::StringAgg(_) => "string_agg",
2029            Expression::ListAgg(_) => "list_agg",
2030            Expression::ArrayAgg(_) => "array_agg",
2031            Expression::CountIf(_) => "count_if",
2032            Expression::SumIf(_) => "sum_if",
2033            Expression::Stddev(_) => "stddev",
2034            Expression::StddevPop(_) => "stddev_pop",
2035            Expression::StddevSamp(_) => "stddev_samp",
2036            Expression::Variance(_) => "variance",
2037            Expression::VarPop(_) => "var_pop",
2038            Expression::VarSamp(_) => "var_samp",
2039            Expression::Median(_) => "median",
2040            Expression::Mode(_) => "mode",
2041            Expression::First(_) => "first",
2042            Expression::Last(_) => "last",
2043            Expression::AnyValue(_) => "any_value",
2044            Expression::ApproxDistinct(_) => "approx_distinct",
2045            Expression::ApproxCountDistinct(_) => "approx_count_distinct",
2046            Expression::ApproxPercentile(_) => "approx_percentile",
2047            Expression::Percentile(_) => "percentile",
2048            Expression::LogicalAnd(_) => "logical_and",
2049            Expression::LogicalOr(_) => "logical_or",
2050            Expression::Skewness(_) => "skewness",
2051            Expression::BitwiseCount(_) => "bitwise_count",
2052            Expression::ArrayConcatAgg(_) => "array_concat_agg",
2053            Expression::ArrayUniqueAgg(_) => "array_unique_agg",
2054            Expression::BoolXorAgg(_) => "bool_xor_agg",
2055            Expression::RowNumber(_) => "row_number",
2056            Expression::Rank(_) => "rank",
2057            Expression::DenseRank(_) => "dense_rank",
2058            Expression::NTile(_) => "n_tile",
2059            Expression::Lead(_) => "lead",
2060            Expression::Lag(_) => "lag",
2061            Expression::FirstValue(_) => "first_value",
2062            Expression::LastValue(_) => "last_value",
2063            Expression::NthValue(_) => "nth_value",
2064            Expression::PercentRank(_) => "percent_rank",
2065            Expression::CumeDist(_) => "cume_dist",
2066            Expression::PercentileCont(_) => "percentile_cont",
2067            Expression::PercentileDisc(_) => "percentile_disc",
2068            Expression::Contains(_) => "contains",
2069            Expression::StartsWith(_) => "starts_with",
2070            Expression::EndsWith(_) => "ends_with",
2071            Expression::Position(_) => "position",
2072            Expression::Initcap(_) => "initcap",
2073            Expression::Ascii(_) => "ascii",
2074            Expression::Chr(_) => "chr",
2075            Expression::CharFunc(_) => "char_func",
2076            Expression::Soundex(_) => "soundex",
2077            Expression::Levenshtein(_) => "levenshtein",
2078            Expression::ByteLength(_) => "byte_length",
2079            Expression::Hex(_) => "hex",
2080            Expression::LowerHex(_) => "lower_hex",
2081            Expression::Unicode(_) => "unicode",
2082            Expression::ModFunc(_) => "mod_func",
2083            Expression::Random(_) => "random",
2084            Expression::Rand(_) => "rand",
2085            Expression::TruncFunc(_) => "trunc_func",
2086            Expression::Pi(_) => "pi",
2087            Expression::Radians(_) => "radians",
2088            Expression::Degrees(_) => "degrees",
2089            Expression::Sin(_) => "sin",
2090            Expression::Cos(_) => "cos",
2091            Expression::Tan(_) => "tan",
2092            Expression::Asin(_) => "asin",
2093            Expression::Acos(_) => "acos",
2094            Expression::Atan(_) => "atan",
2095            Expression::Atan2(_) => "atan2",
2096            Expression::IsNan(_) => "is_nan",
2097            Expression::IsInf(_) => "is_inf",
2098            Expression::IntDiv(_) => "int_div",
2099            Expression::Decode(_) => "decode",
2100            Expression::DateFormat(_) => "date_format",
2101            Expression::FormatDate(_) => "format_date",
2102            Expression::Year(_) => "year",
2103            Expression::Month(_) => "month",
2104            Expression::Day(_) => "day",
2105            Expression::Hour(_) => "hour",
2106            Expression::Minute(_) => "minute",
2107            Expression::Second(_) => "second",
2108            Expression::DayOfWeek(_) => "day_of_week",
2109            Expression::DayOfWeekIso(_) => "day_of_week_iso",
2110            Expression::DayOfMonth(_) => "day_of_month",
2111            Expression::DayOfYear(_) => "day_of_year",
2112            Expression::WeekOfYear(_) => "week_of_year",
2113            Expression::Quarter(_) => "quarter",
2114            Expression::AddMonths(_) => "add_months",
2115            Expression::MonthsBetween(_) => "months_between",
2116            Expression::LastDay(_) => "last_day",
2117            Expression::NextDay(_) => "next_day",
2118            Expression::Epoch(_) => "epoch",
2119            Expression::EpochMs(_) => "epoch_ms",
2120            Expression::FromUnixtime(_) => "from_unixtime",
2121            Expression::UnixTimestamp(_) => "unix_timestamp",
2122            Expression::MakeDate(_) => "make_date",
2123            Expression::MakeTimestamp(_) => "make_timestamp",
2124            Expression::TimestampTrunc(_) => "timestamp_trunc",
2125            Expression::TimeStrToUnix(_) => "time_str_to_unix",
2126            Expression::SessionUser(_) => "session_user",
2127            Expression::SHA(_) => "s_h_a",
2128            Expression::SHA1Digest(_) => "s_h_a1_digest",
2129            Expression::TimeToUnix(_) => "time_to_unix",
2130            Expression::ArrayFunc(_) => "array_func",
2131            Expression::ArrayLength(_) => "array_length",
2132            Expression::ArraySize(_) => "array_size",
2133            Expression::Cardinality(_) => "cardinality",
2134            Expression::ArrayContains(_) => "array_contains",
2135            Expression::ArrayPosition(_) => "array_position",
2136            Expression::ArrayAppend(_) => "array_append",
2137            Expression::ArrayPrepend(_) => "array_prepend",
2138            Expression::ArrayConcat(_) => "array_concat",
2139            Expression::ArraySort(_) => "array_sort",
2140            Expression::ArrayReverse(_) => "array_reverse",
2141            Expression::ArrayDistinct(_) => "array_distinct",
2142            Expression::ArrayJoin(_) => "array_join",
2143            Expression::ArrayToString(_) => "array_to_string",
2144            Expression::Unnest(_) => "unnest",
2145            Expression::Explode(_) => "explode",
2146            Expression::ExplodeOuter(_) => "explode_outer",
2147            Expression::ArrayFilter(_) => "array_filter",
2148            Expression::ArrayTransform(_) => "array_transform",
2149            Expression::ArrayFlatten(_) => "array_flatten",
2150            Expression::ArrayCompact(_) => "array_compact",
2151            Expression::ArrayIntersect(_) => "array_intersect",
2152            Expression::ArrayUnion(_) => "array_union",
2153            Expression::ArrayExcept(_) => "array_except",
2154            Expression::ArrayRemove(_) => "array_remove",
2155            Expression::ArrayZip(_) => "array_zip",
2156            Expression::Sequence(_) => "sequence",
2157            Expression::Generate(_) => "generate",
2158            Expression::ExplodingGenerateSeries(_) => "exploding_generate_series",
2159            Expression::ToArray(_) => "to_array",
2160            Expression::StarMap(_) => "star_map",
2161            Expression::StructFunc(_) => "struct_func",
2162            Expression::StructExtract(_) => "struct_extract",
2163            Expression::NamedStruct(_) => "named_struct",
2164            Expression::MapFunc(_) => "map_func",
2165            Expression::MapFromEntries(_) => "map_from_entries",
2166            Expression::MapFromArrays(_) => "map_from_arrays",
2167            Expression::MapKeys(_) => "map_keys",
2168            Expression::MapValues(_) => "map_values",
2169            Expression::MapContainsKey(_) => "map_contains_key",
2170            Expression::MapConcat(_) => "map_concat",
2171            Expression::ElementAt(_) => "element_at",
2172            Expression::TransformKeys(_) => "transform_keys",
2173            Expression::TransformValues(_) => "transform_values",
2174            Expression::FunctionEmits(_) => "function_emits",
2175            Expression::JsonExtract(_) => "json_extract",
2176            Expression::JsonExtractScalar(_) => "json_extract_scalar",
2177            Expression::JsonExtractPath(_) => "json_extract_path",
2178            Expression::JsonArray(_) => "json_array",
2179            Expression::JsonObject(_) => "json_object",
2180            Expression::JsonQuery(_) => "json_query",
2181            Expression::JsonValue(_) => "json_value",
2182            Expression::JsonArrayLength(_) => "json_array_length",
2183            Expression::JsonKeys(_) => "json_keys",
2184            Expression::JsonType(_) => "json_type",
2185            Expression::ParseJson(_) => "parse_json",
2186            Expression::ToJson(_) => "to_json",
2187            Expression::JsonSet(_) => "json_set",
2188            Expression::JsonInsert(_) => "json_insert",
2189            Expression::JsonRemove(_) => "json_remove",
2190            Expression::JsonMergePatch(_) => "json_merge_patch",
2191            Expression::JsonArrayAgg(_) => "json_array_agg",
2192            Expression::JsonObjectAgg(_) => "json_object_agg",
2193            Expression::Convert(_) => "convert",
2194            Expression::Typeof(_) => "typeof",
2195            Expression::Lambda(_) => "lambda",
2196            Expression::Parameter(_) => "parameter",
2197            Expression::Placeholder(_) => "placeholder",
2198            Expression::NamedArgument(_) => "named_argument",
2199            Expression::TableArgument(_) => "table_argument",
2200            Expression::SqlComment(_) => "sql_comment",
2201            Expression::NullSafeEq(_) => "null_safe_eq",
2202            Expression::NullSafeNeq(_) => "null_safe_neq",
2203            Expression::Glob(_) => "glob",
2204            Expression::SimilarTo(_) => "similar_to",
2205            Expression::Any(_) => "any",
2206            Expression::All(_) => "all",
2207            Expression::Overlaps(_) => "overlaps",
2208            Expression::BitwiseLeftShift(_) => "bitwise_left_shift",
2209            Expression::BitwiseRightShift(_) => "bitwise_right_shift",
2210            Expression::BitwiseAndAgg(_) => "bitwise_and_agg",
2211            Expression::BitwiseOrAgg(_) => "bitwise_or_agg",
2212            Expression::BitwiseXorAgg(_) => "bitwise_xor_agg",
2213            Expression::Subscript(_) => "subscript",
2214            Expression::Dot(_) => "dot",
2215            Expression::MethodCall(_) => "method_call",
2216            Expression::ArraySlice(_) => "array_slice",
2217            Expression::CreateTable(_) => "create_table",
2218            Expression::DropTable(_) => "drop_table",
2219            Expression::Undrop(_) => "undrop",
2220            Expression::AlterTable(_) => "alter_table",
2221            Expression::SplitTable(_) => "split_table",
2222            Expression::FlashbackTable(_) => "flashback_table",
2223            Expression::CreateIndex(_) => "create_index",
2224            Expression::DropIndex(_) => "drop_index",
2225            Expression::CreateView(_) => "create_view",
2226            Expression::DropView(_) => "drop_view",
2227            Expression::AlterView(_) => "alter_view",
2228            Expression::AlterIndex(_) => "alter_index",
2229            Expression::Truncate(_) => "truncate",
2230            Expression::Use(_) => "use",
2231            Expression::Cache(_) => "cache",
2232            Expression::Uncache(_) => "uncache",
2233            Expression::LoadData(_) => "load_data",
2234            Expression::Pragma(_) => "pragma",
2235            Expression::Grant(_) => "grant",
2236            Expression::Revoke(_) => "revoke",
2237            Expression::Comment(_) => "comment",
2238            Expression::SetStatement(_) => "set_statement",
2239            Expression::CreateSchema(_) => "create_schema",
2240            Expression::DropSchema(_) => "drop_schema",
2241            Expression::DropNamespace(_) => "drop_namespace",
2242            Expression::CreateDatabase(_) => "create_database",
2243            Expression::DropDatabase(_) => "drop_database",
2244            Expression::CreateFunction(_) => "create_function",
2245            Expression::DropFunction(_) => "drop_function",
2246            Expression::CreateProcedure(_) => "create_procedure",
2247            Expression::DropProcedure(_) => "drop_procedure",
2248            Expression::CreateSequence(_) => "create_sequence",
2249            Expression::CreateSynonym(_) => "create_synonym",
2250            Expression::DropSequence(_) => "drop_sequence",
2251            Expression::AlterSequence(_) => "alter_sequence",
2252            Expression::CreateTrigger(_) => "create_trigger",
2253            Expression::DropTrigger(_) => "drop_trigger",
2254            Expression::CreateType(_) => "create_type",
2255            Expression::DropType(_) => "drop_type",
2256            Expression::Describe(_) => "describe",
2257            Expression::Show(_) => "show",
2258            Expression::Command(_) => "command",
2259            Expression::TryCatch(_) => "try_catch",
2260            Expression::Kill(_) => "kill",
2261            Expression::Prepare(_) => "prepare",
2262            Expression::Execute(_) => "execute",
2263            Expression::Raw(_) => "raw",
2264            Expression::CreateTask(_) => "create_task",
2265            Expression::Paren(_) => "paren",
2266            Expression::Annotated(_) => "annotated",
2267            Expression::Refresh(_) => "refresh",
2268            Expression::LockingStatement(_) => "locking_statement",
2269            Expression::SequenceProperties(_) => "sequence_properties",
2270            Expression::TruncateTable(_) => "truncate_table",
2271            Expression::Clone(_) => "clone",
2272            Expression::Attach(_) => "attach",
2273            Expression::Detach(_) => "detach",
2274            Expression::Install(_) => "install",
2275            Expression::Summarize(_) => "summarize",
2276            Expression::Declare(_) => "declare",
2277            Expression::DeclareItem(_) => "declare_item",
2278            Expression::Set(_) => "set",
2279            Expression::Heredoc(_) => "heredoc",
2280            Expression::SetItem(_) => "set_item",
2281            Expression::QueryBand(_) => "query_band",
2282            Expression::UserDefinedFunction(_) => "user_defined_function",
2283            Expression::RecursiveWithSearch(_) => "recursive_with_search",
2284            Expression::ProjectionDef(_) => "projection_def",
2285            Expression::TableAlias(_) => "table_alias",
2286            Expression::ByteString(_) => "byte_string",
2287            Expression::HexStringExpr(_) => "hex_string_expr",
2288            Expression::UnicodeString(_) => "unicode_string",
2289            Expression::ColumnPosition(_) => "column_position",
2290            Expression::ColumnDef(_) => "column_def",
2291            Expression::AlterColumn(_) => "alter_column",
2292            Expression::AlterSortKey(_) => "alter_sort_key",
2293            Expression::AlterSet(_) => "alter_set",
2294            Expression::RenameColumn(_) => "rename_column",
2295            Expression::Comprehension(_) => "comprehension",
2296            Expression::MergeTreeTTLAction(_) => "merge_tree_t_t_l_action",
2297            Expression::MergeTreeTTL(_) => "merge_tree_t_t_l",
2298            Expression::IndexConstraintOption(_) => "index_constraint_option",
2299            Expression::ColumnConstraint(_) => "column_constraint",
2300            Expression::PeriodForSystemTimeConstraint(_) => "period_for_system_time_constraint",
2301            Expression::CaseSpecificColumnConstraint(_) => "case_specific_column_constraint",
2302            Expression::CharacterSetColumnConstraint(_) => "character_set_column_constraint",
2303            Expression::CheckColumnConstraint(_) => "check_column_constraint",
2304            Expression::AssumeColumnConstraint(_) => "assume_column_constraint",
2305            Expression::CompressColumnConstraint(_) => "compress_column_constraint",
2306            Expression::DateFormatColumnConstraint(_) => "date_format_column_constraint",
2307            Expression::EphemeralColumnConstraint(_) => "ephemeral_column_constraint",
2308            Expression::WithOperator(_) => "with_operator",
2309            Expression::GeneratedAsIdentityColumnConstraint(_) => {
2310                "generated_as_identity_column_constraint"
2311            }
2312            Expression::AutoIncrementColumnConstraint(_) => "auto_increment_column_constraint",
2313            Expression::CommentColumnConstraint(_) => "comment_column_constraint",
2314            Expression::GeneratedAsRowColumnConstraint(_) => "generated_as_row_column_constraint",
2315            Expression::IndexColumnConstraint(_) => "index_column_constraint",
2316            Expression::MaskingPolicyColumnConstraint(_) => "masking_policy_column_constraint",
2317            Expression::NotNullColumnConstraint(_) => "not_null_column_constraint",
2318            Expression::PrimaryKeyColumnConstraint(_) => "primary_key_column_constraint",
2319            Expression::UniqueColumnConstraint(_) => "unique_column_constraint",
2320            Expression::WatermarkColumnConstraint(_) => "watermark_column_constraint",
2321            Expression::ComputedColumnConstraint(_) => "computed_column_constraint",
2322            Expression::InOutColumnConstraint(_) => "in_out_column_constraint",
2323            Expression::DefaultColumnConstraint(_) => "default_column_constraint",
2324            Expression::PathColumnConstraint(_) => "path_column_constraint",
2325            Expression::Constraint(_) => "constraint",
2326            Expression::Export(_) => "export",
2327            Expression::Filter(_) => "filter",
2328            Expression::Changes(_) => "changes",
2329            Expression::CopyParameter(_) => "copy_parameter",
2330            Expression::Credentials(_) => "credentials",
2331            Expression::Directory(_) => "directory",
2332            Expression::ForeignKey(_) => "foreign_key",
2333            Expression::ColumnPrefix(_) => "column_prefix",
2334            Expression::PrimaryKey(_) => "primary_key",
2335            Expression::IntoClause(_) => "into_clause",
2336            Expression::JoinHint(_) => "join_hint",
2337            Expression::Opclass(_) => "opclass",
2338            Expression::Index(_) => "index",
2339            Expression::IndexParameters(_) => "index_parameters",
2340            Expression::ConditionalInsert(_) => "conditional_insert",
2341            Expression::MultitableInserts(_) => "multitable_inserts",
2342            Expression::OnConflict(_) => "on_conflict",
2343            Expression::OnCondition(_) => "on_condition",
2344            Expression::Returning(_) => "returning",
2345            Expression::Introducer(_) => "introducer",
2346            Expression::PartitionRange(_) => "partition_range",
2347            Expression::Fetch(_) => "fetch",
2348            Expression::Group(_) => "group",
2349            Expression::Cube(_) => "cube",
2350            Expression::Rollup(_) => "rollup",
2351            Expression::GroupingSets(_) => "grouping_sets",
2352            Expression::LimitOptions(_) => "limit_options",
2353            Expression::Lateral(_) => "lateral",
2354            Expression::TableFromRows(_) => "table_from_rows",
2355            Expression::RowsFrom(_) => "rows_from",
2356            Expression::MatchRecognizeMeasure(_) => "match_recognize_measure",
2357            Expression::WithFill(_) => "with_fill",
2358            Expression::Property(_) => "property",
2359            Expression::GrantPrivilege(_) => "grant_privilege",
2360            Expression::GrantPrincipal(_) => "grant_principal",
2361            Expression::AllowedValuesProperty(_) => "allowed_values_property",
2362            Expression::AlgorithmProperty(_) => "algorithm_property",
2363            Expression::AutoIncrementProperty(_) => "auto_increment_property",
2364            Expression::AutoRefreshProperty(_) => "auto_refresh_property",
2365            Expression::BackupProperty(_) => "backup_property",
2366            Expression::BuildProperty(_) => "build_property",
2367            Expression::BlockCompressionProperty(_) => "block_compression_property",
2368            Expression::CharacterSetProperty(_) => "character_set_property",
2369            Expression::ChecksumProperty(_) => "checksum_property",
2370            Expression::CollateProperty(_) => "collate_property",
2371            Expression::DataBlocksizeProperty(_) => "data_blocksize_property",
2372            Expression::DataDeletionProperty(_) => "data_deletion_property",
2373            Expression::DefinerProperty(_) => "definer_property",
2374            Expression::DistKeyProperty(_) => "dist_key_property",
2375            Expression::DistributedByProperty(_) => "distributed_by_property",
2376            Expression::DistStyleProperty(_) => "dist_style_property",
2377            Expression::DuplicateKeyProperty(_) => "duplicate_key_property",
2378            Expression::EngineProperty(_) => "engine_property",
2379            Expression::ToTableProperty(_) => "to_table_property",
2380            Expression::ExecuteAsProperty(_) => "execute_as_property",
2381            Expression::ExternalProperty(_) => "external_property",
2382            Expression::FallbackProperty(_) => "fallback_property",
2383            Expression::FileFormatProperty(_) => "file_format_property",
2384            Expression::CredentialsProperty(_) => "credentials_property",
2385            Expression::FreespaceProperty(_) => "freespace_property",
2386            Expression::InheritsProperty(_) => "inherits_property",
2387            Expression::InputModelProperty(_) => "input_model_property",
2388            Expression::OutputModelProperty(_) => "output_model_property",
2389            Expression::IsolatedLoadingProperty(_) => "isolated_loading_property",
2390            Expression::JournalProperty(_) => "journal_property",
2391            Expression::LanguageProperty(_) => "language_property",
2392            Expression::EnviromentProperty(_) => "enviroment_property",
2393            Expression::ClusteredByProperty(_) => "clustered_by_property",
2394            Expression::DictProperty(_) => "dict_property",
2395            Expression::DictRange(_) => "dict_range",
2396            Expression::OnCluster(_) => "on_cluster",
2397            Expression::LikeProperty(_) => "like_property",
2398            Expression::LocationProperty(_) => "location_property",
2399            Expression::LockProperty(_) => "lock_property",
2400            Expression::LockingProperty(_) => "locking_property",
2401            Expression::LogProperty(_) => "log_property",
2402            Expression::MaterializedProperty(_) => "materialized_property",
2403            Expression::MergeBlockRatioProperty(_) => "merge_block_ratio_property",
2404            Expression::OnProperty(_) => "on_property",
2405            Expression::OnCommitProperty(_) => "on_commit_property",
2406            Expression::PartitionedByProperty(_) => "partitioned_by_property",
2407            Expression::PartitionByProperty(_) => "partition_by_property",
2408            Expression::PartitionedByBucket(_) => "partitioned_by_bucket",
2409            Expression::ClusterByColumnsProperty(_) => "cluster_by_columns_property",
2410            Expression::PartitionByTruncate(_) => "partition_by_truncate",
2411            Expression::PartitionByRangeProperty(_) => "partition_by_range_property",
2412            Expression::PartitionByRangePropertyDynamic(_) => "partition_by_range_property_dynamic",
2413            Expression::PartitionByListProperty(_) => "partition_by_list_property",
2414            Expression::PartitionList(_) => "partition_list",
2415            Expression::Partition(_) => "partition",
2416            Expression::RefreshTriggerProperty(_) => "refresh_trigger_property",
2417            Expression::UniqueKeyProperty(_) => "unique_key_property",
2418            Expression::RollupProperty(_) => "rollup_property",
2419            Expression::PartitionBoundSpec(_) => "partition_bound_spec",
2420            Expression::PartitionedOfProperty(_) => "partitioned_of_property",
2421            Expression::RemoteWithConnectionModelProperty(_) => {
2422                "remote_with_connection_model_property"
2423            }
2424            Expression::ReturnsProperty(_) => "returns_property",
2425            Expression::RowFormatProperty(_) => "row_format_property",
2426            Expression::RowFormatDelimitedProperty(_) => "row_format_delimited_property",
2427            Expression::RowFormatSerdeProperty(_) => "row_format_serde_property",
2428            Expression::QueryTransform(_) => "query_transform",
2429            Expression::SampleProperty(_) => "sample_property",
2430            Expression::SecurityProperty(_) => "security_property",
2431            Expression::SchemaCommentProperty(_) => "schema_comment_property",
2432            Expression::SemanticView(_) => "semantic_view",
2433            Expression::SerdeProperties(_) => "serde_properties",
2434            Expression::SetProperty(_) => "set_property",
2435            Expression::SharingProperty(_) => "sharing_property",
2436            Expression::SetConfigProperty(_) => "set_config_property",
2437            Expression::SettingsProperty(_) => "settings_property",
2438            Expression::SortKeyProperty(_) => "sort_key_property",
2439            Expression::SqlReadWriteProperty(_) => "sql_read_write_property",
2440            Expression::SqlSecurityProperty(_) => "sql_security_property",
2441            Expression::StabilityProperty(_) => "stability_property",
2442            Expression::StorageHandlerProperty(_) => "storage_handler_property",
2443            Expression::TemporaryProperty(_) => "temporary_property",
2444            Expression::Tags(_) => "tags",
2445            Expression::TransformModelProperty(_) => "transform_model_property",
2446            Expression::TransientProperty(_) => "transient_property",
2447            Expression::UsingTemplateProperty(_) => "using_template_property",
2448            Expression::ViewAttributeProperty(_) => "view_attribute_property",
2449            Expression::VolatileProperty(_) => "volatile_property",
2450            Expression::WithDataProperty(_) => "with_data_property",
2451            Expression::WithJournalTableProperty(_) => "with_journal_table_property",
2452            Expression::WithSchemaBindingProperty(_) => "with_schema_binding_property",
2453            Expression::WithSystemVersioningProperty(_) => "with_system_versioning_property",
2454            Expression::WithProcedureOptions(_) => "with_procedure_options",
2455            Expression::EncodeProperty(_) => "encode_property",
2456            Expression::IncludeProperty(_) => "include_property",
2457            Expression::Properties(_) => "properties",
2458            Expression::OptionsProperty(_) => "options_property",
2459            Expression::InputOutputFormat(_) => "input_output_format",
2460            Expression::Reference(_) => "reference",
2461            Expression::QueryOption(_) => "query_option",
2462            Expression::WithTableHint(_) => "with_table_hint",
2463            Expression::IndexTableHint(_) => "index_table_hint",
2464            Expression::HistoricalData(_) => "historical_data",
2465            Expression::Get(_) => "get",
2466            Expression::SetOperation(_) => "set_operation",
2467            Expression::Var(_) => "var",
2468            Expression::Variadic(_) => "variadic",
2469            Expression::Version(_) => "version",
2470            Expression::Schema(_) => "schema",
2471            Expression::Lock(_) => "lock",
2472            Expression::TableSample(_) => "table_sample",
2473            Expression::Tag(_) => "tag",
2474            Expression::UnpivotColumns(_) => "unpivot_columns",
2475            Expression::WindowSpec(_) => "window_spec",
2476            Expression::SessionParameter(_) => "session_parameter",
2477            Expression::PseudoType(_) => "pseudo_type",
2478            Expression::ObjectIdentifier(_) => "object_identifier",
2479            Expression::Transaction(_) => "transaction",
2480            Expression::Commit(_) => "commit",
2481            Expression::Rollback(_) => "rollback",
2482            Expression::AlterSession(_) => "alter_session",
2483            Expression::Analyze(_) => "analyze",
2484            Expression::AnalyzeStatistics(_) => "analyze_statistics",
2485            Expression::AnalyzeHistogram(_) => "analyze_histogram",
2486            Expression::AnalyzeSample(_) => "analyze_sample",
2487            Expression::AnalyzeListChainedRows(_) => "analyze_list_chained_rows",
2488            Expression::AnalyzeDelete(_) => "analyze_delete",
2489            Expression::AnalyzeWith(_) => "analyze_with",
2490            Expression::AnalyzeValidate(_) => "analyze_validate",
2491            Expression::AddPartition(_) => "add_partition",
2492            Expression::AttachOption(_) => "attach_option",
2493            Expression::DropPartition(_) => "drop_partition",
2494            Expression::ReplacePartition(_) => "replace_partition",
2495            Expression::DPipe(_) => "d_pipe",
2496            Expression::Operator(_) => "operator",
2497            Expression::PivotAny(_) => "pivot_any",
2498            Expression::Aliases(_) => "aliases",
2499            Expression::AtIndex(_) => "at_index",
2500            Expression::FromTimeZone(_) => "from_time_zone",
2501            Expression::FormatPhrase(_) => "format_phrase",
2502            Expression::ForIn(_) => "for_in",
2503            Expression::TimeUnit(_) => "time_unit",
2504            Expression::IntervalOp(_) => "interval_op",
2505            Expression::IntervalSpan(_) => "interval_span",
2506            Expression::HavingMax(_) => "having_max",
2507            Expression::CosineDistance(_) => "cosine_distance",
2508            Expression::DotProduct(_) => "dot_product",
2509            Expression::EuclideanDistance(_) => "euclidean_distance",
2510            Expression::ManhattanDistance(_) => "manhattan_distance",
2511            Expression::JarowinklerSimilarity(_) => "jarowinkler_similarity",
2512            Expression::Booland(_) => "booland",
2513            Expression::Boolor(_) => "boolor",
2514            Expression::ParameterizedAgg(_) => "parameterized_agg",
2515            Expression::ArgMax(_) => "arg_max",
2516            Expression::ArgMin(_) => "arg_min",
2517            Expression::ApproxTopK(_) => "approx_top_k",
2518            Expression::ApproxTopKAccumulate(_) => "approx_top_k_accumulate",
2519            Expression::ApproxTopKCombine(_) => "approx_top_k_combine",
2520            Expression::ApproxTopKEstimate(_) => "approx_top_k_estimate",
2521            Expression::ApproxTopSum(_) => "approx_top_sum",
2522            Expression::ApproxQuantiles(_) => "approx_quantiles",
2523            Expression::Minhash(_) => "minhash",
2524            Expression::FarmFingerprint(_) => "farm_fingerprint",
2525            Expression::Float64(_) => "float64",
2526            Expression::Transform(_) => "transform",
2527            Expression::Translate(_) => "translate",
2528            Expression::Grouping(_) => "grouping",
2529            Expression::GroupingId(_) => "grouping_id",
2530            Expression::Anonymous(_) => "anonymous",
2531            Expression::AnonymousAggFunc(_) => "anonymous_agg_func",
2532            Expression::CombinedAggFunc(_) => "combined_agg_func",
2533            Expression::CombinedParameterizedAgg(_) => "combined_parameterized_agg",
2534            Expression::HashAgg(_) => "hash_agg",
2535            Expression::Hll(_) => "hll",
2536            Expression::Apply(_) => "apply",
2537            Expression::ToBoolean(_) => "to_boolean",
2538            Expression::List(_) => "list",
2539            Expression::ToMap(_) => "to_map",
2540            Expression::Pad(_) => "pad",
2541            Expression::ToChar(_) => "to_char",
2542            Expression::ToNumber(_) => "to_number",
2543            Expression::ToDouble(_) => "to_double",
2544            Expression::Int64(_) => "int64",
2545            Expression::StringFunc(_) => "string_func",
2546            Expression::ToDecfloat(_) => "to_decfloat",
2547            Expression::TryToDecfloat(_) => "try_to_decfloat",
2548            Expression::ToFile(_) => "to_file",
2549            Expression::Columns(_) => "columns",
2550            Expression::ConvertToCharset(_) => "convert_to_charset",
2551            Expression::ConvertTimezone(_) => "convert_timezone",
2552            Expression::GenerateSeries(_) => "generate_series",
2553            Expression::AIAgg(_) => "a_i_agg",
2554            Expression::AIClassify(_) => "a_i_classify",
2555            Expression::ArrayAll(_) => "array_all",
2556            Expression::ArrayAny(_) => "array_any",
2557            Expression::ArrayConstructCompact(_) => "array_construct_compact",
2558            Expression::StPoint(_) => "st_point",
2559            Expression::StDistance(_) => "st_distance",
2560            Expression::StringToArray(_) => "string_to_array",
2561            Expression::ArraySum(_) => "array_sum",
2562            Expression::ObjectAgg(_) => "object_agg",
2563            Expression::CastToStrType(_) => "cast_to_str_type",
2564            Expression::CheckJson(_) => "check_json",
2565            Expression::CheckXml(_) => "check_xml",
2566            Expression::TranslateCharacters(_) => "translate_characters",
2567            Expression::CurrentSchemas(_) => "current_schemas",
2568            Expression::CurrentDatetime(_) => "current_datetime",
2569            Expression::Localtime(_) => "localtime",
2570            Expression::Localtimestamp(_) => "localtimestamp",
2571            Expression::Systimestamp(_) => "systimestamp",
2572            Expression::CurrentSchema(_) => "current_schema",
2573            Expression::CurrentUser(_) => "current_user",
2574            Expression::UtcTime(_) => "utc_time",
2575            Expression::UtcTimestamp(_) => "utc_timestamp",
2576            Expression::Timestamp(_) => "timestamp",
2577            Expression::DateBin(_) => "date_bin",
2578            Expression::Datetime(_) => "datetime",
2579            Expression::DatetimeAdd(_) => "datetime_add",
2580            Expression::DatetimeSub(_) => "datetime_sub",
2581            Expression::DatetimeDiff(_) => "datetime_diff",
2582            Expression::DatetimeTrunc(_) => "datetime_trunc",
2583            Expression::Dayname(_) => "dayname",
2584            Expression::MakeInterval(_) => "make_interval",
2585            Expression::PreviousDay(_) => "previous_day",
2586            Expression::Elt(_) => "elt",
2587            Expression::TimestampAdd(_) => "timestamp_add",
2588            Expression::TimestampSub(_) => "timestamp_sub",
2589            Expression::TimestampDiff(_) => "timestamp_diff",
2590            Expression::TimeSlice(_) => "time_slice",
2591            Expression::TimeAdd(_) => "time_add",
2592            Expression::TimeSub(_) => "time_sub",
2593            Expression::TimeDiff(_) => "time_diff",
2594            Expression::TimeTrunc(_) => "time_trunc",
2595            Expression::DateFromParts(_) => "date_from_parts",
2596            Expression::TimeFromParts(_) => "time_from_parts",
2597            Expression::DecodeCase(_) => "decode_case",
2598            Expression::Decrypt(_) => "decrypt",
2599            Expression::DecryptRaw(_) => "decrypt_raw",
2600            Expression::Encode(_) => "encode",
2601            Expression::Encrypt(_) => "encrypt",
2602            Expression::EncryptRaw(_) => "encrypt_raw",
2603            Expression::EqualNull(_) => "equal_null",
2604            Expression::ToBinary(_) => "to_binary",
2605            Expression::Base64DecodeBinary(_) => "base64_decode_binary",
2606            Expression::Base64DecodeString(_) => "base64_decode_string",
2607            Expression::Base64Encode(_) => "base64_encode",
2608            Expression::TryBase64DecodeBinary(_) => "try_base64_decode_binary",
2609            Expression::TryBase64DecodeString(_) => "try_base64_decode_string",
2610            Expression::GapFill(_) => "gap_fill",
2611            Expression::GenerateDateArray(_) => "generate_date_array",
2612            Expression::GenerateTimestampArray(_) => "generate_timestamp_array",
2613            Expression::GetExtract(_) => "get_extract",
2614            Expression::Getbit(_) => "getbit",
2615            Expression::OverflowTruncateBehavior(_) => "overflow_truncate_behavior",
2616            Expression::HexEncode(_) => "hex_encode",
2617            Expression::Compress(_) => "compress",
2618            Expression::DecompressBinary(_) => "decompress_binary",
2619            Expression::DecompressString(_) => "decompress_string",
2620            Expression::Xor(_) => "xor",
2621            Expression::Nullif(_) => "nullif",
2622            Expression::JSON(_) => "j_s_o_n",
2623            Expression::JSONPath(_) => "j_s_o_n_path",
2624            Expression::JSONPathFilter(_) => "j_s_o_n_path_filter",
2625            Expression::JSONPathKey(_) => "j_s_o_n_path_key",
2626            Expression::JSONPathRecursive(_) => "j_s_o_n_path_recursive",
2627            Expression::JSONPathScript(_) => "j_s_o_n_path_script",
2628            Expression::JSONPathSlice(_) => "j_s_o_n_path_slice",
2629            Expression::JSONPathSelector(_) => "j_s_o_n_path_selector",
2630            Expression::JSONPathSubscript(_) => "j_s_o_n_path_subscript",
2631            Expression::JSONPathUnion(_) => "j_s_o_n_path_union",
2632            Expression::Format(_) => "format",
2633            Expression::JSONKeys(_) => "j_s_o_n_keys",
2634            Expression::JSONKeyValue(_) => "j_s_o_n_key_value",
2635            Expression::JSONKeysAtDepth(_) => "j_s_o_n_keys_at_depth",
2636            Expression::JSONObject(_) => "j_s_o_n_object",
2637            Expression::JSONObjectAgg(_) => "j_s_o_n_object_agg",
2638            Expression::JSONBObjectAgg(_) => "j_s_o_n_b_object_agg",
2639            Expression::JSONArray(_) => "j_s_o_n_array",
2640            Expression::JSONArrayAgg(_) => "j_s_o_n_array_agg",
2641            Expression::JSONExists(_) => "j_s_o_n_exists",
2642            Expression::JSONColumnDef(_) => "j_s_o_n_column_def",
2643            Expression::JSONSchema(_) => "j_s_o_n_schema",
2644            Expression::JSONSet(_) => "j_s_o_n_set",
2645            Expression::JSONStripNulls(_) => "j_s_o_n_strip_nulls",
2646            Expression::JSONValue(_) => "j_s_o_n_value",
2647            Expression::JSONValueArray(_) => "j_s_o_n_value_array",
2648            Expression::JSONRemove(_) => "j_s_o_n_remove",
2649            Expression::JSONTable(_) => "j_s_o_n_table",
2650            Expression::JSONType(_) => "j_s_o_n_type",
2651            Expression::ObjectInsert(_) => "object_insert",
2652            Expression::OpenJSONColumnDef(_) => "open_j_s_o_n_column_def",
2653            Expression::OpenJSON(_) => "open_j_s_o_n",
2654            Expression::JSONBExists(_) => "j_s_o_n_b_exists",
2655            Expression::JSONBContains(_) => "j_s_o_n_b_contains",
2656            Expression::JSONBExtract(_) => "j_s_o_n_b_extract",
2657            Expression::JSONCast(_) => "j_s_o_n_cast",
2658            Expression::JSONExtract(_) => "j_s_o_n_extract",
2659            Expression::JSONExtractQuote(_) => "j_s_o_n_extract_quote",
2660            Expression::JSONExtractArray(_) => "j_s_o_n_extract_array",
2661            Expression::JSONExtractScalar(_) => "j_s_o_n_extract_scalar",
2662            Expression::JSONBExtractScalar(_) => "j_s_o_n_b_extract_scalar",
2663            Expression::JSONFormat(_) => "j_s_o_n_format",
2664            Expression::JSONBool(_) => "j_s_o_n_bool",
2665            Expression::JSONPathRoot(_) => "j_s_o_n_path_root",
2666            Expression::JSONArrayAppend(_) => "j_s_o_n_array_append",
2667            Expression::JSONArrayContains(_) => "j_s_o_n_array_contains",
2668            Expression::JSONArrayInsert(_) => "j_s_o_n_array_insert",
2669            Expression::ParseJSON(_) => "parse_j_s_o_n",
2670            Expression::ParseUrl(_) => "parse_url",
2671            Expression::ParseIp(_) => "parse_ip",
2672            Expression::ParseTime(_) => "parse_time",
2673            Expression::ParseDatetime(_) => "parse_datetime",
2674            Expression::Map(_) => "map",
2675            Expression::MapCat(_) => "map_cat",
2676            Expression::MapDelete(_) => "map_delete",
2677            Expression::MapInsert(_) => "map_insert",
2678            Expression::MapPick(_) => "map_pick",
2679            Expression::ScopeResolution(_) => "scope_resolution",
2680            Expression::Slice(_) => "slice",
2681            Expression::VarMap(_) => "var_map",
2682            Expression::MatchAgainst(_) => "match_against",
2683            Expression::MD5Digest(_) => "m_d5_digest",
2684            Expression::MD5NumberLower64(_) => "m_d5_number_lower64",
2685            Expression::MD5NumberUpper64(_) => "m_d5_number_upper64",
2686            Expression::Monthname(_) => "monthname",
2687            Expression::Ntile(_) => "ntile",
2688            Expression::Normalize(_) => "normalize",
2689            Expression::Normal(_) => "normal",
2690            Expression::Predict(_) => "predict",
2691            Expression::MLTranslate(_) => "m_l_translate",
2692            Expression::FeaturesAtTime(_) => "features_at_time",
2693            Expression::GenerateEmbedding(_) => "generate_embedding",
2694            Expression::MLForecast(_) => "m_l_forecast",
2695            Expression::ModelAttribute(_) => "model_attribute",
2696            Expression::VectorSearch(_) => "vector_search",
2697            Expression::Quantile(_) => "quantile",
2698            Expression::ApproxQuantile(_) => "approx_quantile",
2699            Expression::ApproxPercentileEstimate(_) => "approx_percentile_estimate",
2700            Expression::Randn(_) => "randn",
2701            Expression::Randstr(_) => "randstr",
2702            Expression::RangeN(_) => "range_n",
2703            Expression::RangeBucket(_) => "range_bucket",
2704            Expression::ReadCSV(_) => "read_c_s_v",
2705            Expression::ReadParquet(_) => "read_parquet",
2706            Expression::Reduce(_) => "reduce",
2707            Expression::RegexpExtractAll(_) => "regexp_extract_all",
2708            Expression::RegexpILike(_) => "regexp_i_like",
2709            Expression::RegexpFullMatch(_) => "regexp_full_match",
2710            Expression::RegexpInstr(_) => "regexp_instr",
2711            Expression::RegexpSplit(_) => "regexp_split",
2712            Expression::RegexpCount(_) => "regexp_count",
2713            Expression::RegrValx(_) => "regr_valx",
2714            Expression::RegrValy(_) => "regr_valy",
2715            Expression::RegrAvgy(_) => "regr_avgy",
2716            Expression::RegrAvgx(_) => "regr_avgx",
2717            Expression::RegrCount(_) => "regr_count",
2718            Expression::RegrIntercept(_) => "regr_intercept",
2719            Expression::RegrR2(_) => "regr_r2",
2720            Expression::RegrSxx(_) => "regr_sxx",
2721            Expression::RegrSxy(_) => "regr_sxy",
2722            Expression::RegrSyy(_) => "regr_syy",
2723            Expression::RegrSlope(_) => "regr_slope",
2724            Expression::SafeAdd(_) => "safe_add",
2725            Expression::SafeDivide(_) => "safe_divide",
2726            Expression::SafeMultiply(_) => "safe_multiply",
2727            Expression::SafeSubtract(_) => "safe_subtract",
2728            Expression::SHA2(_) => "s_h_a2",
2729            Expression::SHA2Digest(_) => "s_h_a2_digest",
2730            Expression::SortArray(_) => "sort_array",
2731            Expression::SplitPart(_) => "split_part",
2732            Expression::SubstringIndex(_) => "substring_index",
2733            Expression::StandardHash(_) => "standard_hash",
2734            Expression::StrPosition(_) => "str_position",
2735            Expression::Search(_) => "search",
2736            Expression::SearchIp(_) => "search_ip",
2737            Expression::StrToDate(_) => "str_to_date",
2738            Expression::DateStrToDate(_) => "date_str_to_date",
2739            Expression::DateToDateStr(_) => "date_to_date_str",
2740            Expression::StrToTime(_) => "str_to_time",
2741            Expression::StrToUnix(_) => "str_to_unix",
2742            Expression::StrToMap(_) => "str_to_map",
2743            Expression::NumberToStr(_) => "number_to_str",
2744            Expression::FromBase(_) => "from_base",
2745            Expression::Stuff(_) => "stuff",
2746            Expression::TimeToStr(_) => "time_to_str",
2747            Expression::TimeStrToTime(_) => "time_str_to_time",
2748            Expression::TsOrDsAdd(_) => "ts_or_ds_add",
2749            Expression::TsOrDsDiff(_) => "ts_or_ds_diff",
2750            Expression::TsOrDsToDate(_) => "ts_or_ds_to_date",
2751            Expression::TsOrDsToTime(_) => "ts_or_ds_to_time",
2752            Expression::Unhex(_) => "unhex",
2753            Expression::Uniform(_) => "uniform",
2754            Expression::UnixToStr(_) => "unix_to_str",
2755            Expression::UnixToTime(_) => "unix_to_time",
2756            Expression::Uuid(_) => "uuid",
2757            Expression::TimestampFromParts(_) => "timestamp_from_parts",
2758            Expression::TimestampTzFromParts(_) => "timestamp_tz_from_parts",
2759            Expression::Corr(_) => "corr",
2760            Expression::WidthBucket(_) => "width_bucket",
2761            Expression::CovarSamp(_) => "covar_samp",
2762            Expression::CovarPop(_) => "covar_pop",
2763            Expression::Week(_) => "week",
2764            Expression::XMLElement(_) => "x_m_l_element",
2765            Expression::XMLGet(_) => "x_m_l_get",
2766            Expression::XMLTable(_) => "x_m_l_table",
2767            Expression::XMLKeyValueOption(_) => "x_m_l_key_value_option",
2768            Expression::Zipf(_) => "zipf",
2769            Expression::Merge(_) => "merge",
2770            Expression::When(_) => "when",
2771            Expression::Whens(_) => "whens",
2772            Expression::NextValueFor(_) => "next_value_for",
2773            Expression::ReturnStmt(_) => "return_stmt",
2774        }
2775    }
2776
2777    /// Returns the primary child expression (".this" in sqlglot).
2778    pub fn get_this(&self) -> Option<&Expression> {
2779        match self {
2780            // Unary ops
2781            Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this),
2782            // UnaryFunc variants
2783            Expression::Upper(f)
2784            | Expression::Lower(f)
2785            | Expression::Length(f)
2786            | Expression::LTrim(f)
2787            | Expression::RTrim(f)
2788            | Expression::Reverse(f)
2789            | Expression::Abs(f)
2790            | Expression::Sqrt(f)
2791            | Expression::Cbrt(f)
2792            | Expression::Ln(f)
2793            | Expression::Exp(f)
2794            | Expression::Sign(f)
2795            | Expression::Date(f)
2796            | Expression::Time(f)
2797            | Expression::Initcap(f)
2798            | Expression::Ascii(f)
2799            | Expression::Chr(f)
2800            | Expression::Soundex(f)
2801            | Expression::ByteLength(f)
2802            | Expression::Hex(f)
2803            | Expression::LowerHex(f)
2804            | Expression::Unicode(f)
2805            | Expression::Typeof(f)
2806            | Expression::Explode(f)
2807            | Expression::ExplodeOuter(f)
2808            | Expression::MapFromEntries(f)
2809            | Expression::MapKeys(f)
2810            | Expression::MapValues(f)
2811            | Expression::ArrayLength(f)
2812            | Expression::ArraySize(f)
2813            | Expression::Cardinality(f)
2814            | Expression::ArrayReverse(f)
2815            | Expression::ArrayDistinct(f)
2816            | Expression::ArrayFlatten(f)
2817            | Expression::ArrayCompact(f)
2818            | Expression::ToArray(f)
2819            | Expression::JsonArrayLength(f)
2820            | Expression::JsonKeys(f)
2821            | Expression::JsonType(f)
2822            | Expression::ParseJson(f)
2823            | Expression::ToJson(f)
2824            | Expression::Radians(f)
2825            | Expression::Degrees(f)
2826            | Expression::Sin(f)
2827            | Expression::Cos(f)
2828            | Expression::Tan(f)
2829            | Expression::Asin(f)
2830            | Expression::Acos(f)
2831            | Expression::Atan(f)
2832            | Expression::IsNan(f)
2833            | Expression::IsInf(f)
2834            | Expression::Year(f)
2835            | Expression::Month(f)
2836            | Expression::Day(f)
2837            | Expression::Hour(f)
2838            | Expression::Minute(f)
2839            | Expression::Second(f)
2840            | Expression::DayOfWeek(f)
2841            | Expression::DayOfWeekIso(f)
2842            | Expression::DayOfMonth(f)
2843            | Expression::DayOfYear(f)
2844            | Expression::WeekOfYear(f)
2845            | Expression::Quarter(f)
2846            | Expression::Epoch(f)
2847            | Expression::EpochMs(f)
2848            | Expression::BitwiseCount(f)
2849            | Expression::DateFromUnixDate(f)
2850            | Expression::UnixDate(f)
2851            | Expression::UnixSeconds(f)
2852            | Expression::UnixMillis(f)
2853            | Expression::UnixMicros(f)
2854            | Expression::TimeStrToDate(f)
2855            | Expression::DateToDi(f)
2856            | Expression::DiToDate(f)
2857            | Expression::TsOrDiToDi(f)
2858            | Expression::TsOrDsToDatetime(f)
2859            | Expression::TsOrDsToTimestamp(f)
2860            | Expression::YearOfWeek(f)
2861            | Expression::YearOfWeekIso(f)
2862            | Expression::SHA(f)
2863            | Expression::SHA1Digest(f)
2864            | Expression::TimeToUnix(f)
2865            | Expression::TimeStrToUnix(f)
2866            | Expression::Int64(f)
2867            | Expression::JSONBool(f)
2868            | Expression::MD5NumberLower64(f)
2869            | Expression::MD5NumberUpper64(f)
2870            | Expression::DateStrToDate(f)
2871            | Expression::DateToDateStr(f) => Some(&f.this),
2872            // BinaryFunc - this is the primary child
2873            Expression::Power(f)
2874            | Expression::NullIf(f)
2875            | Expression::IfNull(f)
2876            | Expression::Nvl(f)
2877            | Expression::Contains(f)
2878            | Expression::StartsWith(f)
2879            | Expression::EndsWith(f)
2880            | Expression::Levenshtein(f)
2881            | Expression::ModFunc(f)
2882            | Expression::IntDiv(f)
2883            | Expression::Atan2(f)
2884            | Expression::AddMonths(f)
2885            | Expression::MonthsBetween(f)
2886            | Expression::NextDay(f)
2887            | Expression::UnixToTimeStr(f)
2888            | Expression::ArrayContains(f)
2889            | Expression::ArrayPosition(f)
2890            | Expression::ArrayAppend(f)
2891            | Expression::ArrayPrepend(f)
2892            | Expression::ArrayUnion(f)
2893            | Expression::ArrayExcept(f)
2894            | Expression::ArrayRemove(f)
2895            | Expression::StarMap(f)
2896            | Expression::MapFromArrays(f)
2897            | Expression::MapContainsKey(f)
2898            | Expression::ElementAt(f)
2899            | Expression::JsonMergePatch(f)
2900            | Expression::JSONBContains(f)
2901            | Expression::JSONBExtract(f) => Some(&f.this),
2902            // AggFunc - this is the primary child
2903            Expression::Sum(af)
2904            | Expression::Avg(af)
2905            | Expression::Min(af)
2906            | Expression::Max(af)
2907            | Expression::ArrayAgg(af)
2908            | Expression::CountIf(af)
2909            | Expression::Stddev(af)
2910            | Expression::StddevPop(af)
2911            | Expression::StddevSamp(af)
2912            | Expression::Variance(af)
2913            | Expression::VarPop(af)
2914            | Expression::VarSamp(af)
2915            | Expression::Median(af)
2916            | Expression::Mode(af)
2917            | Expression::First(af)
2918            | Expression::Last(af)
2919            | Expression::AnyValue(af)
2920            | Expression::ApproxDistinct(af)
2921            | Expression::ApproxCountDistinct(af)
2922            | Expression::LogicalAnd(af)
2923            | Expression::LogicalOr(af)
2924            | Expression::Skewness(af)
2925            | Expression::ArrayConcatAgg(af)
2926            | Expression::ArrayUniqueAgg(af)
2927            | Expression::BoolXorAgg(af)
2928            | Expression::BitwiseAndAgg(af)
2929            | Expression::BitwiseOrAgg(af)
2930            | Expression::BitwiseXorAgg(af) => Some(&af.this),
2931            // Binary operations - left is "this" in sqlglot
2932            Expression::And(op)
2933            | Expression::Or(op)
2934            | Expression::Add(op)
2935            | Expression::Sub(op)
2936            | Expression::Mul(op)
2937            | Expression::Div(op)
2938            | Expression::Mod(op)
2939            | Expression::Eq(op)
2940            | Expression::Neq(op)
2941            | Expression::Lt(op)
2942            | Expression::Lte(op)
2943            | Expression::Gt(op)
2944            | Expression::Gte(op)
2945            | Expression::BitwiseAnd(op)
2946            | Expression::BitwiseOr(op)
2947            | Expression::BitwiseXor(op)
2948            | Expression::Concat(op)
2949            | Expression::Adjacent(op)
2950            | Expression::TsMatch(op)
2951            | Expression::PropertyEQ(op)
2952            | Expression::ArrayContainsAll(op)
2953            | Expression::ArrayContainedBy(op)
2954            | Expression::ArrayOverlaps(op)
2955            | Expression::JSONBContainsAllTopKeys(op)
2956            | Expression::JSONBContainsAnyTopKeys(op)
2957            | Expression::JSONBDeleteAtPath(op)
2958            | Expression::ExtendsLeft(op)
2959            | Expression::ExtendsRight(op)
2960            | Expression::Is(op)
2961            | Expression::MemberOf(op)
2962            | Expression::Match(op)
2963            | Expression::NullSafeEq(op)
2964            | Expression::NullSafeNeq(op)
2965            | Expression::Glob(op)
2966            | Expression::BitwiseLeftShift(op)
2967            | Expression::BitwiseRightShift(op) => Some(&op.left),
2968            // Like operations - left is "this"
2969            Expression::Like(op) | Expression::ILike(op) => Some(&op.left),
2970            // Structural types with .this
2971            Expression::Alias(a) => Some(&a.this),
2972            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => Some(&c.this),
2973            Expression::Paren(p) => Some(&p.this),
2974            Expression::Annotated(a) => Some(&a.this),
2975            Expression::Subquery(s) => Some(&s.this),
2976            Expression::Where(w) => Some(&w.this),
2977            Expression::Having(h) => Some(&h.this),
2978            Expression::Qualify(q) => Some(&q.this),
2979            Expression::IsNull(i) => Some(&i.this),
2980            Expression::Exists(e) => Some(&e.this),
2981            Expression::Ordered(o) => Some(&o.this),
2982            Expression::WindowFunction(wf) => Some(&wf.this),
2983            Expression::Cte(cte) => Some(&cte.this),
2984            Expression::Between(b) => Some(&b.this),
2985            Expression::In(i) => Some(&i.this),
2986            Expression::ReturnStmt(e) => Some(e),
2987            _ => None,
2988        }
2989    }
2990
2991    /// Returns the secondary child expression (".expression" in sqlglot).
2992    pub fn get_expression(&self) -> Option<&Expression> {
2993        match self {
2994            // Binary operations - right is "expression"
2995            Expression::And(op)
2996            | Expression::Or(op)
2997            | Expression::Add(op)
2998            | Expression::Sub(op)
2999            | Expression::Mul(op)
3000            | Expression::Div(op)
3001            | Expression::Mod(op)
3002            | Expression::Eq(op)
3003            | Expression::Neq(op)
3004            | Expression::Lt(op)
3005            | Expression::Lte(op)
3006            | Expression::Gt(op)
3007            | Expression::Gte(op)
3008            | Expression::BitwiseAnd(op)
3009            | Expression::BitwiseOr(op)
3010            | Expression::BitwiseXor(op)
3011            | Expression::Concat(op)
3012            | Expression::Adjacent(op)
3013            | Expression::TsMatch(op)
3014            | Expression::PropertyEQ(op)
3015            | Expression::ArrayContainsAll(op)
3016            | Expression::ArrayContainedBy(op)
3017            | Expression::ArrayOverlaps(op)
3018            | Expression::JSONBContainsAllTopKeys(op)
3019            | Expression::JSONBContainsAnyTopKeys(op)
3020            | Expression::JSONBDeleteAtPath(op)
3021            | Expression::ExtendsLeft(op)
3022            | Expression::ExtendsRight(op)
3023            | Expression::Is(op)
3024            | Expression::MemberOf(op)
3025            | Expression::Match(op)
3026            | Expression::NullSafeEq(op)
3027            | Expression::NullSafeNeq(op)
3028            | Expression::Glob(op)
3029            | Expression::BitwiseLeftShift(op)
3030            | Expression::BitwiseRightShift(op) => Some(&op.right),
3031            // Like operations - right is "expression"
3032            Expression::Like(op) | Expression::ILike(op) => Some(&op.right),
3033            // BinaryFunc - expression is the secondary
3034            Expression::Power(f)
3035            | Expression::NullIf(f)
3036            | Expression::IfNull(f)
3037            | Expression::Nvl(f)
3038            | Expression::Contains(f)
3039            | Expression::StartsWith(f)
3040            | Expression::EndsWith(f)
3041            | Expression::Levenshtein(f)
3042            | Expression::ModFunc(f)
3043            | Expression::IntDiv(f)
3044            | Expression::Atan2(f)
3045            | Expression::AddMonths(f)
3046            | Expression::MonthsBetween(f)
3047            | Expression::NextDay(f)
3048            | Expression::UnixToTimeStr(f)
3049            | Expression::ArrayContains(f)
3050            | Expression::ArrayPosition(f)
3051            | Expression::ArrayAppend(f)
3052            | Expression::ArrayPrepend(f)
3053            | Expression::ArrayUnion(f)
3054            | Expression::ArrayExcept(f)
3055            | Expression::ArrayRemove(f)
3056            | Expression::StarMap(f)
3057            | Expression::MapFromArrays(f)
3058            | Expression::MapContainsKey(f)
3059            | Expression::ElementAt(f)
3060            | Expression::JsonMergePatch(f)
3061            | Expression::JSONBContains(f)
3062            | Expression::JSONBExtract(f) => Some(&f.expression),
3063            _ => None,
3064        }
3065    }
3066
3067    /// Returns the list of child expressions (".expressions" in sqlglot).
3068    pub fn get_expressions(&self) -> &[Expression] {
3069        match self {
3070            Expression::Select(s) => &s.expressions,
3071            Expression::Function(f) => &f.args,
3072            Expression::AggregateFunction(f) => &f.args,
3073            Expression::From(f) => &f.expressions,
3074            Expression::GroupBy(g) => &g.expressions,
3075            Expression::In(i) => &i.expressions,
3076            Expression::Array(a) => &a.expressions,
3077            Expression::ArrayFunc(a) => &a.expressions,
3078            Expression::Tuple(t) => &t.expressions,
3079            Expression::Coalesce(f)
3080            | Expression::Greatest(f)
3081            | Expression::Least(f)
3082            | Expression::ArrayConcat(f)
3083            | Expression::ArrayIntersect(f)
3084            | Expression::ArrayZip(f)
3085            | Expression::MapConcat(f)
3086            | Expression::JsonArray(f) => &f.expressions,
3087            _ => &[],
3088        }
3089    }
3090
3091    /// Returns the name of this expression as a string slice.
3092    pub fn get_name(&self) -> &str {
3093        match self {
3094            Expression::Identifier(id) => &id.name,
3095            Expression::Column(col) => &col.name.name,
3096            Expression::Table(t) => &t.name.name,
3097            Expression::Literal(lit) => lit.value_str(),
3098            Expression::Star(_) => "*",
3099            Expression::Function(f) => &f.name,
3100            Expression::AggregateFunction(f) => &f.name,
3101            Expression::Alias(a) => a.this.get_name(),
3102            Expression::Boolean(b) => {
3103                if b.value {
3104                    "TRUE"
3105                } else {
3106                    "FALSE"
3107                }
3108            }
3109            Expression::Null(_) => "NULL",
3110            _ => "",
3111        }
3112    }
3113
3114    /// Returns the alias name if this expression has one.
3115    pub fn get_alias(&self) -> &str {
3116        match self {
3117            Expression::Alias(a) => &a.alias.name,
3118            Expression::Table(t) => t.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3119            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3120            _ => "",
3121        }
3122    }
3123
3124    /// Returns the output name of this expression (what it shows up as in a SELECT).
3125    pub fn get_output_name(&self) -> &str {
3126        match self {
3127            Expression::Alias(a) => &a.alias.name,
3128            Expression::Column(c) => &c.name.name,
3129            Expression::Identifier(id) => &id.name,
3130            Expression::Literal(lit) => lit.value_str(),
3131            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3132            Expression::Star(_) => "*",
3133            _ => "",
3134        }
3135    }
3136
3137    /// Returns comments attached to this expression.
3138    pub fn get_comments(&self) -> Vec<&str> {
3139        match self {
3140            Expression::Identifier(id) => id.trailing_comments.iter().map(|s| s.as_str()).collect(),
3141            Expression::Column(c) => c.trailing_comments.iter().map(|s| s.as_str()).collect(),
3142            Expression::Star(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3143            Expression::Paren(p) => p.trailing_comments.iter().map(|s| s.as_str()).collect(),
3144            Expression::Annotated(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3145            Expression::Alias(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3146            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
3147                c.trailing_comments.iter().map(|s| s.as_str()).collect()
3148            }
3149            Expression::And(op)
3150            | Expression::Or(op)
3151            | Expression::Add(op)
3152            | Expression::Sub(op)
3153            | Expression::Mul(op)
3154            | Expression::Div(op)
3155            | Expression::Mod(op)
3156            | Expression::Eq(op)
3157            | Expression::Neq(op)
3158            | Expression::Lt(op)
3159            | Expression::Lte(op)
3160            | Expression::Gt(op)
3161            | Expression::Gte(op)
3162            | Expression::Concat(op)
3163            | Expression::BitwiseAnd(op)
3164            | Expression::BitwiseOr(op)
3165            | Expression::BitwiseXor(op) => {
3166                op.trailing_comments.iter().map(|s| s.as_str()).collect()
3167            }
3168            Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(),
3169            Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3170            _ => Vec::new(),
3171        }
3172    }
3173}
3174
3175impl fmt::Display for Expression {
3176    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3177        // Basic display - full SQL generation is in generator module
3178        match self {
3179            Expression::Literal(lit) => write!(f, "{}", lit),
3180            Expression::Identifier(id) => write!(f, "{}", id),
3181            Expression::Column(col) => write!(f, "{}", col),
3182            Expression::Star(_) => write!(f, "*"),
3183            Expression::Null(_) => write!(f, "NULL"),
3184            Expression::Boolean(b) => write!(f, "{}", if b.value { "TRUE" } else { "FALSE" }),
3185            Expression::Select(_) => write!(f, "SELECT ..."),
3186            _ => write!(f, "{:?}", self),
3187        }
3188    }
3189}
3190
3191/// Represent a SQL literal value.
3192///
3193/// Numeric values are stored as their original text representation (not parsed
3194/// to `i64`/`f64`) so that precision, trailing zeros, and hex notation are
3195/// preserved across round-trips.
3196///
3197/// Dialect-specific literal forms (triple-quoted strings, dollar-quoted
3198/// strings, raw strings, etc.) each have a dedicated variant so that the
3199/// generator can emit them with the correct syntax.
3200#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3201#[cfg_attr(feature = "bindings", derive(TS))]
3202#[serde(tag = "literal_type", content = "value", rename_all = "snake_case")]
3203pub enum Literal {
3204    /// Single-quoted string literal: `'hello'`
3205    String(String),
3206    /// Numeric literal, stored as the original text: `42`, `3.14`, `1e10`
3207    Number(String),
3208    /// Hex string literal: `X'FF'`
3209    HexString(String),
3210    /// Hex number: 0xA, 0xFF (BigQuery, SQLite style) - represents an integer in hex notation
3211    HexNumber(String),
3212    BitString(String),
3213    /// Byte string: b"..." (BigQuery style)
3214    ByteString(String),
3215    /// National string: N'abc'
3216    NationalString(String),
3217    /// DATE literal: DATE '2024-01-15'
3218    Date(String),
3219    /// TIME literal: TIME '10:30:00'
3220    Time(String),
3221    /// TIMESTAMP literal: TIMESTAMP '2024-01-15 10:30:00'
3222    Timestamp(String),
3223    /// DATETIME literal: DATETIME '2024-01-15 10:30:00' (BigQuery)
3224    Datetime(String),
3225    /// Triple-quoted string: """...""" or '''...'''
3226    /// Contains (content, quote_char) where quote_char is '"' or '\''
3227    TripleQuotedString(String, char),
3228    /// Escape string: E'...' (PostgreSQL)
3229    EscapeString(String),
3230    /// Dollar-quoted string: $$...$$  (PostgreSQL)
3231    DollarString(String),
3232    /// Raw string: r"..." or r'...' (BigQuery, Spark, Databricks)
3233    /// In raw strings, backslashes are literal and not escape characters.
3234    /// When converting to a regular string, backslashes must be doubled.
3235    RawString(String),
3236}
3237
3238impl Literal {
3239    /// Returns the inner value as a string slice, regardless of literal type.
3240    pub fn value_str(&self) -> &str {
3241        match self {
3242            Literal::String(s)
3243            | Literal::Number(s)
3244            | Literal::HexString(s)
3245            | Literal::HexNumber(s)
3246            | Literal::BitString(s)
3247            | Literal::ByteString(s)
3248            | Literal::NationalString(s)
3249            | Literal::Date(s)
3250            | Literal::Time(s)
3251            | Literal::Timestamp(s)
3252            | Literal::Datetime(s)
3253            | Literal::EscapeString(s)
3254            | Literal::DollarString(s)
3255            | Literal::RawString(s) => s.as_str(),
3256            Literal::TripleQuotedString(s, _) => s.as_str(),
3257        }
3258    }
3259
3260    /// Returns `true` if this is a string-type literal.
3261    pub fn is_string(&self) -> bool {
3262        matches!(
3263            self,
3264            Literal::String(_)
3265                | Literal::NationalString(_)
3266                | Literal::EscapeString(_)
3267                | Literal::DollarString(_)
3268                | Literal::RawString(_)
3269                | Literal::TripleQuotedString(_, _)
3270        )
3271    }
3272
3273    /// Returns `true` if this is a numeric literal.
3274    pub fn is_number(&self) -> bool {
3275        matches!(self, Literal::Number(_) | Literal::HexNumber(_))
3276    }
3277}
3278
3279impl fmt::Display for Literal {
3280    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3281        match self {
3282            Literal::String(s) => write!(f, "'{}'", s),
3283            Literal::Number(n) => write!(f, "{}", n),
3284            Literal::HexString(h) => write!(f, "X'{}'", h),
3285            Literal::HexNumber(h) => write!(f, "0x{}", h),
3286            Literal::BitString(b) => write!(f, "B'{}'", b),
3287            Literal::ByteString(b) => write!(f, "b'{}'", b),
3288            Literal::NationalString(s) => write!(f, "N'{}'", s),
3289            Literal::Date(d) => write!(f, "DATE '{}'", d),
3290            Literal::Time(t) => write!(f, "TIME '{}'", t),
3291            Literal::Timestamp(ts) => write!(f, "TIMESTAMP '{}'", ts),
3292            Literal::Datetime(dt) => write!(f, "DATETIME '{}'", dt),
3293            Literal::TripleQuotedString(s, q) => {
3294                write!(f, "{0}{0}{0}{1}{0}{0}{0}", q, s)
3295            }
3296            Literal::EscapeString(s) => write!(f, "E'{}'", s),
3297            Literal::DollarString(s) => write!(f, "$${}$$", s),
3298            Literal::RawString(s) => write!(f, "r'{}'", s),
3299        }
3300    }
3301}
3302
3303/// Boolean literal
3304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3305#[cfg_attr(feature = "bindings", derive(TS))]
3306pub struct BooleanLiteral {
3307    pub value: bool,
3308}
3309
3310/// NULL literal
3311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3312#[cfg_attr(feature = "bindings", derive(TS))]
3313pub struct Null;
3314
3315/// Represent a SQL identifier (table name, column name, alias, keyword-as-name, etc.).
3316///
3317/// The `quoted` flag indicates whether the identifier was originally delimited
3318/// (double-quoted, backtick-quoted, or bracket-quoted depending on the
3319/// dialect). The generator uses this flag to decide whether to emit quoting
3320/// characters.
3321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, Serialize, Deserialize)]
3322#[cfg_attr(feature = "bindings", derive(TS))]
3323pub struct Identifier {
3324    /// The raw text of the identifier, without any quoting characters.
3325    pub name: String,
3326    /// Whether the identifier was quoted in the source SQL.
3327    pub quoted: bool,
3328    #[serde(default)]
3329    pub trailing_comments: Vec<String>,
3330    /// Original source range, including quoting delimiters. Absent for synthetic
3331    /// or programmatically constructed identifiers. Not part of structural equality.
3332    #[serde(default, skip_serializing_if = "Option::is_none")]
3333    pub span: Option<Span>,
3334}
3335
3336impl PartialEq for Identifier {
3337    fn eq(&self, other: &Self) -> bool {
3338        self.name == other.name
3339            && self.quoted == other.quoted
3340            && self.trailing_comments == other.trailing_comments
3341    }
3342}
3343
3344impl Identifier {
3345    pub fn new(name: impl Into<String>) -> Self {
3346        Self {
3347            name: name.into(),
3348            quoted: false,
3349            trailing_comments: Vec::new(),
3350            span: None,
3351        }
3352    }
3353
3354    pub fn quoted(name: impl Into<String>) -> Self {
3355        Self {
3356            name: name.into(),
3357            quoted: true,
3358            trailing_comments: Vec::new(),
3359            span: None,
3360        }
3361    }
3362
3363    pub fn empty() -> Self {
3364        Self {
3365            name: String::new(),
3366            quoted: false,
3367            trailing_comments: Vec::new(),
3368            span: None,
3369        }
3370    }
3371
3372    pub fn is_empty(&self) -> bool {
3373        self.name.is_empty()
3374    }
3375
3376    /// Preserve quoting in the legacy string representation of named type fields.
3377    /// Always use SQL-standard delimiters internally, independent of the source dialect.
3378    pub(crate) fn to_type_field_name(&self) -> String {
3379        if self.quoted {
3380            format!("\"{}\"", self.name.replace('"', "\"\""))
3381        } else {
3382            self.name.clone()
3383        }
3384    }
3385
3386    /// Set the source span on this identifier
3387    pub fn with_span(mut self, span: Span) -> Self {
3388        self.span = Some(span);
3389        self
3390    }
3391}
3392
3393impl fmt::Display for Identifier {
3394    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3395        if self.quoted {
3396            write!(f, "\"{}\"", self.name)
3397        } else {
3398            write!(f, "{}", self.name)
3399        }
3400    }
3401}
3402
3403/// Represent a column reference, optionally qualified by a table name.
3404///
3405/// Renders as `name` when unqualified, or `table.name` when qualified.
3406/// Use [`Expression::column()`] or [`Expression::qualified_column()`] for
3407/// convenient construction.
3408#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, Serialize, Deserialize)]
3409#[cfg_attr(feature = "bindings", derive(TS))]
3410pub struct Column {
3411    /// The column name.
3412    pub name: Identifier,
3413    /// Optional table qualifier (e.g. `t` in `t.col`).
3414    pub table: Option<Identifier>,
3415    /// Oracle-style join marker (+) for outer joins
3416    #[serde(default)]
3417    pub join_mark: bool,
3418    /// Trailing comments that appeared after this column reference
3419    #[serde(default)]
3420    pub trailing_comments: Vec<String>,
3421    /// Original column-reference range, including its qualifier when present.
3422    /// Absent for synthetic references. Not part of structural equality.
3423    #[serde(default, skip_serializing_if = "Option::is_none")]
3424    pub span: Option<Span>,
3425    /// Inferred data type from type annotation
3426    #[serde(default, skip_serializing_if = "Option::is_none")]
3427    #[ast(skip)]
3428    pub inferred_type: Option<DataType>,
3429}
3430
3431impl PartialEq for Column {
3432    fn eq(&self, other: &Self) -> bool {
3433        self.name == other.name
3434            && self.table == other.table
3435            && self.join_mark == other.join_mark
3436            && self.trailing_comments == other.trailing_comments
3437            && self.inferred_type == other.inferred_type
3438    }
3439}
3440
3441impl fmt::Display for Column {
3442    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3443        if let Some(table) = &self.table {
3444            write!(f, "{}.{}", table, self.name)
3445        } else {
3446            write!(f, "{}", self.name)
3447        }
3448    }
3449}
3450
3451/// Represent a table reference with optional schema and catalog qualifiers.
3452///
3453/// Renders as `name`, `schema.name`, or `catalog.schema.name` depending on
3454/// which qualifiers are present. Supports aliases, column alias lists,
3455/// time-travel clauses (Snowflake, BigQuery), table hints (TSQL), and
3456/// several other dialect-specific extensions.
3457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3458#[cfg_attr(feature = "bindings", derive(TS))]
3459pub struct TableRef {
3460    /// The unqualified table name.
3461    pub name: Identifier,
3462    /// Optional schema qualifier (e.g. `public` in `public.users`).
3463    pub schema: Option<Identifier>,
3464    /// Optional catalog qualifier (e.g. `mydb` in `mydb.public.users`).
3465    pub catalog: Option<Identifier>,
3466    /// Optional table alias (e.g. `t` in `FROM users AS t`).
3467    pub alias: Option<Identifier>,
3468    /// Whether AS keyword was explicitly used for the alias
3469    #[serde(default)]
3470    pub alias_explicit_as: bool,
3471    /// Column aliases for table alias: AS t(c1, c2)
3472    #[serde(default)]
3473    pub column_aliases: Vec<Identifier>,
3474    /// Leading comments that appeared before this table reference in a FROM clause
3475    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3476    pub leading_comments: Vec<String>,
3477    /// Trailing comments that appeared after this table reference
3478    #[serde(default)]
3479    pub trailing_comments: Vec<String>,
3480    /// Snowflake time travel: BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
3481    #[serde(default)]
3482    pub when: Option<Box<HistoricalData>>,
3483    /// PostgreSQL ONLY modifier: prevents scanning child tables in inheritance hierarchy
3484    #[serde(default)]
3485    pub only: bool,
3486    /// ClickHouse FINAL modifier: forces final aggregation for MergeTree tables
3487    #[serde(default)]
3488    pub final_: bool,
3489    /// TABLESAMPLE clause attached to this table reference (DuckDB, BigQuery)
3490    #[serde(default, skip_serializing_if = "Option::is_none")]
3491    pub table_sample: Option<Box<Sample>>,
3492    /// TSQL table hints: WITH (TABLOCK, INDEX(myindex), ...)
3493    #[serde(default)]
3494    pub hints: Vec<Expression>,
3495    /// TSQL: FOR SYSTEM_TIME temporal clause
3496    /// Contains the full clause text, e.g., "FOR SYSTEM_TIME BETWEEN c AND d"
3497    #[serde(default, skip_serializing_if = "Option::is_none")]
3498    pub system_time: Option<String>,
3499    /// MySQL: PARTITION(p0, p1, ...) hint for reading from specific partitions
3500    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3501    pub partitions: Vec<Identifier>,
3502    /// Snowflake IDENTIFIER() function: dynamic table name from string/variable
3503    /// When set, this is used instead of the name field
3504    #[serde(default, skip_serializing_if = "Option::is_none")]
3505    pub identifier_func: Option<Box<Expression>>,
3506    /// Snowflake CHANGES clause: CHANGES (INFORMATION => ...) AT (...) END (...)
3507    #[serde(default, skip_serializing_if = "Option::is_none")]
3508    pub changes: Option<Box<Changes>>,
3509    /// Time travel version clause: FOR VERSION AS OF / FOR TIMESTAMP AS OF (Presto/Trino, BigQuery, Databricks)
3510    #[serde(default, skip_serializing_if = "Option::is_none")]
3511    pub version: Option<Box<Version>>,
3512    /// Source position span
3513    #[serde(default, skip_serializing_if = "Option::is_none")]
3514    pub span: Option<Span>,
3515}
3516
3517impl TableRef {
3518    pub fn new(name: impl Into<String>) -> Self {
3519        Self {
3520            name: Identifier::new(name),
3521            schema: None,
3522            catalog: None,
3523            alias: None,
3524            alias_explicit_as: false,
3525            column_aliases: Vec::new(),
3526            leading_comments: Vec::new(),
3527            trailing_comments: Vec::new(),
3528            when: None,
3529            only: false,
3530            final_: false,
3531            table_sample: None,
3532            hints: Vec::new(),
3533            system_time: None,
3534            partitions: Vec::new(),
3535            identifier_func: None,
3536            changes: None,
3537            version: None,
3538            span: None,
3539        }
3540    }
3541
3542    /// Create with a schema qualifier.
3543    pub fn new_with_schema(name: impl Into<String>, schema: impl Into<String>) -> Self {
3544        let mut t = Self::new(name);
3545        t.schema = Some(Identifier::new(schema));
3546        t
3547    }
3548
3549    /// Create with catalog and schema qualifiers.
3550    pub fn new_with_catalog(
3551        name: impl Into<String>,
3552        schema: impl Into<String>,
3553        catalog: impl Into<String>,
3554    ) -> Self {
3555        let mut t = Self::new(name);
3556        t.schema = Some(Identifier::new(schema));
3557        t.catalog = Some(Identifier::new(catalog));
3558        t
3559    }
3560
3561    /// Create from an Identifier, preserving the quoted flag
3562    pub fn from_identifier(name: Identifier) -> Self {
3563        Self {
3564            name,
3565            schema: None,
3566            catalog: None,
3567            alias: None,
3568            alias_explicit_as: false,
3569            column_aliases: Vec::new(),
3570            leading_comments: Vec::new(),
3571            trailing_comments: Vec::new(),
3572            when: None,
3573            only: false,
3574            final_: false,
3575            table_sample: None,
3576            hints: Vec::new(),
3577            system_time: None,
3578            partitions: Vec::new(),
3579            identifier_func: None,
3580            changes: None,
3581            version: None,
3582            span: None,
3583        }
3584    }
3585
3586    pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
3587        self.alias = Some(Identifier::new(alias));
3588        self
3589    }
3590
3591    pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
3592        self.schema = Some(Identifier::new(schema));
3593        self
3594    }
3595}
3596
3597/// Represent a wildcard star expression (`*`, `table.*`).
3598///
3599/// Supports the EXCEPT/EXCLUDE, REPLACE, and RENAME modifiers found in
3600/// DuckDB, BigQuery, and Snowflake (e.g. `SELECT * EXCEPT (id) FROM t`).
3601#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3602#[cfg_attr(feature = "bindings", derive(TS))]
3603pub struct Star {
3604    /// Optional table qualifier (e.g. `t` in `t.*`).
3605    pub table: Option<Identifier>,
3606    /// EXCLUDE / EXCEPT columns (DuckDB, BigQuery, Snowflake)
3607    pub except: Option<Vec<Identifier>>,
3608    /// REPLACE expressions (BigQuery, Snowflake)
3609    pub replace: Option<Vec<Alias>>,
3610    /// RENAME columns (Snowflake)
3611    pub rename: Option<Vec<(Identifier, Identifier)>>,
3612    /// Trailing comments that appeared after the star
3613    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3614    pub trailing_comments: Vec<String>,
3615    /// Source position span
3616    #[serde(default, skip_serializing_if = "Option::is_none")]
3617    pub span: Option<Span>,
3618}
3619
3620/// Represent a complete SELECT statement.
3621///
3622/// This is the most feature-rich AST node, covering the full surface area of
3623/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3624/// `Vec` are omitted from the generated SQL when absent.
3625///
3626/// # Key Fields
3627///
3628/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3629/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3630/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3631/// - `where_clause` -- the WHERE predicate.
3632/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3633/// - `having` -- HAVING predicate.
3634/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3635/// - `limit` / `offset` / `fetch` -- result set limiting.
3636/// - `with` -- Common Table Expressions (CTEs).
3637/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3638/// - `windows` -- named window definitions (WINDOW w AS ...).
3639///
3640/// Dialect-specific extensions are supported via fields like `prewhere`
3641/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3642/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3644#[cfg_attr(feature = "bindings", derive(TS))]
3645pub struct Select {
3646    /// The select-list: columns, expressions, aliases, and wildcards.
3647    pub expressions: Vec<Expression>,
3648    /// The FROM clause, containing one or more table sources.
3649    pub from: Option<From>,
3650    /// JOIN clauses applied after the FROM source.
3651    pub joins: Vec<Join>,
3652    pub lateral_views: Vec<LateralView>,
3653    /// ClickHouse PREWHERE clause
3654    #[serde(default, skip_serializing_if = "Option::is_none")]
3655    pub prewhere: Option<Expression>,
3656    pub where_clause: Option<Where>,
3657    pub group_by: Option<GroupBy>,
3658    pub having: Option<Having>,
3659    pub qualify: Option<Qualify>,
3660    pub order_by: Option<OrderBy>,
3661    pub distribute_by: Option<DistributeBy>,
3662    pub cluster_by: Option<ClusterBy>,
3663    pub sort_by: Option<SortBy>,
3664    pub limit: Option<Limit>,
3665    pub offset: Option<Offset>,
3666    /// ClickHouse LIMIT BY clause expressions
3667    #[serde(default, skip_serializing_if = "Option::is_none")]
3668    pub limit_by: Option<Vec<Expression>>,
3669    pub fetch: Option<Fetch>,
3670    pub distinct: bool,
3671    pub distinct_on: Option<Vec<Expression>>,
3672    pub top: Option<Top>,
3673    pub with: Option<With>,
3674    pub sample: Option<Sample>,
3675    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3676    #[serde(default, skip_serializing_if = "Option::is_none")]
3677    pub settings: Option<Vec<Expression>>,
3678    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3679    #[serde(default, skip_serializing_if = "Option::is_none")]
3680    pub format: Option<Expression>,
3681    pub windows: Option<Vec<NamedWindow>>,
3682    pub hint: Option<Hint>,
3683    /// Oracle CONNECT BY clause for hierarchical queries
3684    pub connect: Option<Connect>,
3685    /// SELECT ... INTO table_name for creating tables
3686    pub into: Option<SelectInto>,
3687    /// FOR UPDATE/SHARE locking clauses
3688    #[serde(default)]
3689    pub locks: Vec<Lock>,
3690    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3691    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3692    pub for_xml: Vec<Expression>,
3693    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3694    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3695    pub for_json: Vec<Expression>,
3696    /// Leading comments before the statement
3697    #[serde(default)]
3698    pub leading_comments: Vec<String>,
3699    /// Comments that appear after SELECT keyword (before expressions)
3700    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3701    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3702    pub post_select_comments: Vec<String>,
3703    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3704    #[serde(default, skip_serializing_if = "Option::is_none")]
3705    pub kind: Option<String>,
3706    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3707    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3708    pub operation_modifiers: Vec<String>,
3709    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3710    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3711    pub qualify_after_window: bool,
3712    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3713    #[serde(default, skip_serializing_if = "Option::is_none")]
3714    pub option: Option<String>,
3715    /// Redshift-style EXCLUDE clause at the end of the projection list
3716    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3717    #[serde(default, skip_serializing_if = "Option::is_none")]
3718    pub exclude: Option<Vec<Expression>>,
3719}
3720
3721impl Select {
3722    pub fn new() -> Self {
3723        Self {
3724            expressions: Vec::new(),
3725            from: None,
3726            joins: Vec::new(),
3727            lateral_views: Vec::new(),
3728            prewhere: None,
3729            where_clause: None,
3730            group_by: None,
3731            having: None,
3732            qualify: None,
3733            order_by: None,
3734            distribute_by: None,
3735            cluster_by: None,
3736            sort_by: None,
3737            limit: None,
3738            offset: None,
3739            limit_by: None,
3740            fetch: None,
3741            distinct: false,
3742            distinct_on: None,
3743            top: None,
3744            with: None,
3745            sample: None,
3746            settings: None,
3747            format: None,
3748            windows: None,
3749            hint: None,
3750            connect: None,
3751            into: None,
3752            locks: Vec::new(),
3753            for_xml: Vec::new(),
3754            for_json: Vec::new(),
3755            leading_comments: Vec::new(),
3756            post_select_comments: Vec::new(),
3757            kind: None,
3758            operation_modifiers: Vec::new(),
3759            qualify_after_window: false,
3760            option: None,
3761            exclude: None,
3762        }
3763    }
3764
3765    /// Add a column to select
3766    pub fn column(mut self, expr: Expression) -> Self {
3767        self.expressions.push(expr);
3768        self
3769    }
3770
3771    /// Set the FROM clause
3772    pub fn from(mut self, table: Expression) -> Self {
3773        self.from = Some(From {
3774            expressions: vec![table],
3775        });
3776        self
3777    }
3778
3779    /// Add a WHERE clause
3780    pub fn where_(mut self, condition: Expression) -> Self {
3781        self.where_clause = Some(Where { this: condition });
3782        self
3783    }
3784
3785    /// Set DISTINCT
3786    pub fn distinct(mut self) -> Self {
3787        self.distinct = true;
3788        self
3789    }
3790
3791    /// Add a JOIN
3792    pub fn join(mut self, join: Join) -> Self {
3793        self.joins.push(join);
3794        self
3795    }
3796
3797    /// Set ORDER BY
3798    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
3799        self.order_by = Some(OrderBy {
3800            expressions,
3801            siblings: false,
3802            comments: Vec::new(),
3803        });
3804        self
3805    }
3806
3807    /// Set LIMIT
3808    pub fn limit(mut self, n: Expression) -> Self {
3809        self.limit = Some(Limit {
3810            this: n,
3811            percent: false,
3812            comments: Vec::new(),
3813        });
3814        self
3815    }
3816
3817    /// Set OFFSET
3818    pub fn offset(mut self, n: Expression) -> Self {
3819        self.offset = Some(Offset {
3820            this: n,
3821            rows: None,
3822        });
3823        self
3824    }
3825}
3826
3827impl Default for Select {
3828    fn default() -> Self {
3829        Self::new()
3830    }
3831}
3832
3833/// Represent a UNION set operation between two query expressions.
3834///
3835/// When `all` is true, duplicate rows are preserved (UNION ALL).
3836/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
3837/// Supports DuckDB/Snowflake BY NAME and BigQuery BY NAME/CORRESPONDING modifiers.
3838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3839#[cfg_attr(feature = "bindings", derive(TS))]
3840pub struct Union {
3841    /// The left-hand query operand.
3842    pub left: Expression,
3843    /// The right-hand query operand.
3844    pub right: Expression,
3845    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
3846    pub all: bool,
3847    /// Whether DISTINCT was explicitly specified
3848    #[serde(default)]
3849    pub distinct: bool,
3850    /// Optional WITH clause
3851    pub with: Option<With>,
3852    /// ORDER BY applied to entire UNION result
3853    pub order_by: Option<OrderBy>,
3854    /// LIMIT applied to entire UNION result
3855    pub limit: Option<Box<Expression>>,
3856    /// OFFSET applied to entire UNION result
3857    pub offset: Option<Box<Expression>>,
3858    /// DISTRIBUTE BY clause (Hive/Spark)
3859    #[serde(default, skip_serializing_if = "Option::is_none")]
3860    pub distribute_by: Option<DistributeBy>,
3861    /// SORT BY clause (Hive/Spark)
3862    #[serde(default, skip_serializing_if = "Option::is_none")]
3863    pub sort_by: Option<SortBy>,
3864    /// CLUSTER BY clause (Hive/Spark)
3865    #[serde(default, skip_serializing_if = "Option::is_none")]
3866    pub cluster_by: Option<ClusterBy>,
3867    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3868    #[serde(default)]
3869    pub by_name: bool,
3870    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3871    #[serde(default, skip_serializing_if = "Option::is_none")]
3872    pub side: Option<String>,
3873    /// BigQuery: Set operation kind (INNER)
3874    #[serde(default, skip_serializing_if = "Option::is_none")]
3875    pub kind: Option<String>,
3876    /// BigQuery: CORRESPONDING modifier
3877    #[serde(default)]
3878    pub corresponding: bool,
3879    /// BigQuery: STRICT modifier (before CORRESPONDING)
3880    #[serde(default)]
3881    pub strict: bool,
3882    /// BigQuery: BY (columns) after CORRESPONDING
3883    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3884    pub on_columns: Vec<Expression>,
3885}
3886
3887/// Iteratively flatten the left-recursive chain to prevent stack overflow
3888/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3889impl Drop for Union {
3890    fn drop(&mut self) {
3891        loop {
3892            if let Expression::Union(ref mut inner) = self.left {
3893                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3894                let old_left = std::mem::replace(&mut self.left, next_left);
3895                drop(old_left);
3896            } else {
3897                break;
3898            }
3899        }
3900    }
3901}
3902
3903/// Represent an INTERSECT set operation between two query expressions.
3904///
3905/// Returns only rows that appear in both operands. When `all` is true,
3906/// duplicates are preserved according to their multiplicity.
3907#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3908#[cfg_attr(feature = "bindings", derive(TS))]
3909pub struct Intersect {
3910    /// The left-hand query operand.
3911    pub left: Expression,
3912    /// The right-hand query operand.
3913    pub right: Expression,
3914    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
3915    pub all: bool,
3916    /// Whether DISTINCT was explicitly specified
3917    #[serde(default)]
3918    pub distinct: bool,
3919    /// Optional WITH clause
3920    pub with: Option<With>,
3921    /// ORDER BY applied to entire INTERSECT result
3922    pub order_by: Option<OrderBy>,
3923    /// LIMIT applied to entire INTERSECT result
3924    pub limit: Option<Box<Expression>>,
3925    /// OFFSET applied to entire INTERSECT result
3926    pub offset: Option<Box<Expression>>,
3927    /// DISTRIBUTE BY clause (Hive/Spark)
3928    #[serde(default, skip_serializing_if = "Option::is_none")]
3929    pub distribute_by: Option<DistributeBy>,
3930    /// SORT BY clause (Hive/Spark)
3931    #[serde(default, skip_serializing_if = "Option::is_none")]
3932    pub sort_by: Option<SortBy>,
3933    /// CLUSTER BY clause (Hive/Spark)
3934    #[serde(default, skip_serializing_if = "Option::is_none")]
3935    pub cluster_by: Option<ClusterBy>,
3936    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3937    #[serde(default)]
3938    pub by_name: bool,
3939    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3940    #[serde(default, skip_serializing_if = "Option::is_none")]
3941    pub side: Option<String>,
3942    /// BigQuery: Set operation kind (INNER)
3943    #[serde(default, skip_serializing_if = "Option::is_none")]
3944    pub kind: Option<String>,
3945    /// BigQuery: CORRESPONDING modifier
3946    #[serde(default)]
3947    pub corresponding: bool,
3948    /// BigQuery: STRICT modifier (before CORRESPONDING)
3949    #[serde(default)]
3950    pub strict: bool,
3951    /// BigQuery: BY (columns) after CORRESPONDING
3952    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3953    pub on_columns: Vec<Expression>,
3954}
3955
3956impl Drop for Intersect {
3957    fn drop(&mut self) {
3958        loop {
3959            if let Expression::Intersect(ref mut inner) = self.left {
3960                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3961                let old_left = std::mem::replace(&mut self.left, next_left);
3962                drop(old_left);
3963            } else {
3964                break;
3965            }
3966        }
3967    }
3968}
3969
3970/// Represent an EXCEPT (MINUS) set operation between two query expressions.
3971///
3972/// Returns rows from the left operand that do not appear in the right operand.
3973/// When `all` is true, duplicates are subtracted according to their multiplicity.
3974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3975#[cfg_attr(feature = "bindings", derive(TS))]
3976pub struct Except {
3977    /// The left-hand query operand.
3978    pub left: Expression,
3979    /// The right-hand query operand (rows to subtract).
3980    pub right: Expression,
3981    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
3982    pub all: bool,
3983    /// Whether DISTINCT was explicitly specified
3984    #[serde(default)]
3985    pub distinct: bool,
3986    /// Optional WITH clause
3987    pub with: Option<With>,
3988    /// ORDER BY applied to entire EXCEPT result
3989    pub order_by: Option<OrderBy>,
3990    /// LIMIT applied to entire EXCEPT result
3991    pub limit: Option<Box<Expression>>,
3992    /// OFFSET applied to entire EXCEPT result
3993    pub offset: Option<Box<Expression>>,
3994    /// DISTRIBUTE BY clause (Hive/Spark)
3995    #[serde(default, skip_serializing_if = "Option::is_none")]
3996    pub distribute_by: Option<DistributeBy>,
3997    /// SORT BY clause (Hive/Spark)
3998    #[serde(default, skip_serializing_if = "Option::is_none")]
3999    pub sort_by: Option<SortBy>,
4000    /// CLUSTER BY clause (Hive/Spark)
4001    #[serde(default, skip_serializing_if = "Option::is_none")]
4002    pub cluster_by: Option<ClusterBy>,
4003    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4004    #[serde(default)]
4005    pub by_name: bool,
4006    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4007    #[serde(default, skip_serializing_if = "Option::is_none")]
4008    pub side: Option<String>,
4009    /// BigQuery: Set operation kind (INNER)
4010    #[serde(default, skip_serializing_if = "Option::is_none")]
4011    pub kind: Option<String>,
4012    /// BigQuery: CORRESPONDING modifier
4013    #[serde(default)]
4014    pub corresponding: bool,
4015    /// BigQuery: STRICT modifier (before CORRESPONDING)
4016    #[serde(default)]
4017    pub strict: bool,
4018    /// BigQuery: BY (columns) after CORRESPONDING
4019    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4020    pub on_columns: Vec<Expression>,
4021}
4022
4023impl Drop for Except {
4024    fn drop(&mut self) {
4025        loop {
4026            if let Expression::Except(ref mut inner) = self.left {
4027                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4028                let old_left = std::mem::replace(&mut self.left, next_left);
4029                drop(old_left);
4030            } else {
4031                break;
4032            }
4033        }
4034    }
4035}
4036
4037/// INTO clause for SELECT INTO statements
4038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4039#[cfg_attr(feature = "bindings", derive(TS))]
4040pub struct SelectInto {
4041    /// Target table or variable (used when single target)
4042    pub this: Expression,
4043    /// Whether TEMPORARY keyword was used
4044    #[serde(default)]
4045    pub temporary: bool,
4046    /// Whether UNLOGGED keyword was used (PostgreSQL)
4047    #[serde(default)]
4048    pub unlogged: bool,
4049    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4050    #[serde(default)]
4051    pub bulk_collect: bool,
4052    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4053    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4054    pub expressions: Vec<Expression>,
4055}
4056
4057/// Represent a parenthesized subquery expression.
4058///
4059/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4060/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4061/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4062/// modifiers are rendered inside or outside the parentheses.
4063///
4064/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4065/// scalar subqueries in select-lists, and derived tables.
4066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4067#[cfg_attr(feature = "bindings", derive(TS))]
4068pub struct Subquery {
4069    /// The inner query expression.
4070    pub this: Expression,
4071    /// Optional alias for the derived table.
4072    pub alias: Option<Identifier>,
4073    /// Optional column aliases: AS t(c1, c2)
4074    pub column_aliases: Vec<Identifier>,
4075    /// Whether AS keyword was explicitly used for the alias.
4076    #[serde(default)]
4077    pub alias_explicit_as: bool,
4078    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4079    #[serde(skip_serializing_if = "Option::is_none", default)]
4080    pub alias_keyword: Option<String>,
4081    /// ORDER BY clause (for parenthesized queries)
4082    pub order_by: Option<OrderBy>,
4083    /// LIMIT clause
4084    pub limit: Option<Limit>,
4085    /// OFFSET clause
4086    pub offset: Option<Offset>,
4087    /// DISTRIBUTE BY clause (Hive/Spark)
4088    #[serde(default, skip_serializing_if = "Option::is_none")]
4089    pub distribute_by: Option<DistributeBy>,
4090    /// SORT BY clause (Hive/Spark)
4091    #[serde(default, skip_serializing_if = "Option::is_none")]
4092    pub sort_by: Option<SortBy>,
4093    /// CLUSTER BY clause (Hive/Spark)
4094    #[serde(default, skip_serializing_if = "Option::is_none")]
4095    pub cluster_by: Option<ClusterBy>,
4096    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4097    #[serde(default)]
4098    pub lateral: bool,
4099    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4100    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4101    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4102    #[serde(default)]
4103    pub modifiers_inside: bool,
4104    /// Trailing comments after the closing paren
4105    #[serde(default)]
4106    pub trailing_comments: Vec<String>,
4107    /// Inferred data type from type annotation
4108    #[serde(default, skip_serializing_if = "Option::is_none")]
4109    #[ast(skip)]
4110    pub inferred_type: Option<DataType>,
4111}
4112
4113/// Pipe operator expression: query |> transform
4114///
4115/// Used in DataFusion and BigQuery pipe syntax:
4116///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4118#[cfg_attr(feature = "bindings", derive(TS))]
4119pub struct PipeOperator {
4120    /// The input query/expression (left side of |>)
4121    pub this: Expression,
4122    /// The piped operation (right side of |>)
4123    pub expression: Expression,
4124}
4125
4126/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4127#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4128#[cfg_attr(feature = "bindings", derive(TS))]
4129pub struct Values {
4130    /// The rows of values
4131    pub expressions: Vec<Tuple>,
4132    /// Optional alias for the table
4133    pub alias: Option<Identifier>,
4134    /// Optional column aliases: AS t(c1, c2)
4135    pub column_aliases: Vec<Identifier>,
4136}
4137
4138/// PIVOT operation - supports both standard and DuckDB simplified syntax
4139///
4140/// Standard syntax (in FROM clause):
4141///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4142///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4143///
4144/// DuckDB simplified syntax (statement-level):
4145///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4146///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4147#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4148#[cfg_attr(feature = "bindings", derive(TS))]
4149pub struct Pivot {
4150    /// Source table/expression
4151    pub this: Expression,
4152    /// For standard PIVOT: the aggregation function(s) (first is primary)
4153    /// For DuckDB simplified: unused (use `using` instead)
4154    #[serde(default)]
4155    pub expressions: Vec<Expression>,
4156    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4157    #[serde(default)]
4158    pub fields: Vec<Expression>,
4159    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4160    #[serde(default)]
4161    pub using: Vec<Expression>,
4162    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4163    #[serde(default)]
4164    pub group: Option<Box<Expression>>,
4165    /// Whether this is an UNPIVOT (vs PIVOT)
4166    #[serde(default)]
4167    pub unpivot: bool,
4168    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4169    #[serde(default)]
4170    pub into: Option<Box<Expression>>,
4171    /// Optional alias
4172    #[serde(default)]
4173    pub alias: Option<Identifier>,
4174    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4175    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4176    pub alias_columns: Vec<Identifier>,
4177    /// Include/exclude nulls (for UNPIVOT)
4178    #[serde(default)]
4179    pub include_nulls: Option<bool>,
4180    /// Default on null value (Snowflake)
4181    #[serde(default)]
4182    pub default_on_null: Option<Box<Expression>>,
4183    /// WITH clause (CTEs)
4184    #[serde(default, skip_serializing_if = "Option::is_none")]
4185    pub with: Option<With>,
4186}
4187
4188/// UNPIVOT operation
4189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4190#[cfg_attr(feature = "bindings", derive(TS))]
4191pub struct Unpivot {
4192    pub this: Expression,
4193    pub value_column: Identifier,
4194    pub name_column: Identifier,
4195    pub columns: Vec<Expression>,
4196    pub alias: Option<Identifier>,
4197    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4198    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4199    pub alias_columns: Vec<Identifier>,
4200    /// Whether the value_column was parenthesized in the original SQL
4201    #[serde(default)]
4202    pub value_column_parenthesized: bool,
4203    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4204    #[serde(default)]
4205    pub include_nulls: Option<bool>,
4206    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4207    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4208    pub extra_value_columns: Vec<Identifier>,
4209}
4210
4211/// PIVOT alias for aliasing pivot expressions
4212/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4213#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4214#[cfg_attr(feature = "bindings", derive(TS))]
4215pub struct PivotAlias {
4216    pub this: Expression,
4217    pub alias: Expression,
4218}
4219
4220/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4222#[cfg_attr(feature = "bindings", derive(TS))]
4223pub struct PreWhere {
4224    pub this: Expression,
4225}
4226
4227/// STREAM definition (Snowflake) - for change data capture
4228#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4229#[cfg_attr(feature = "bindings", derive(TS))]
4230pub struct Stream {
4231    pub this: Expression,
4232    #[serde(skip_serializing_if = "Option::is_none")]
4233    pub on: Option<Expression>,
4234    #[serde(skip_serializing_if = "Option::is_none")]
4235    pub show_initial_rows: Option<bool>,
4236}
4237
4238/// USING DATA clause for data import statements
4239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4240#[cfg_attr(feature = "bindings", derive(TS))]
4241pub struct UsingData {
4242    pub this: Expression,
4243}
4244
4245/// XML Namespace declaration
4246#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4247#[cfg_attr(feature = "bindings", derive(TS))]
4248pub struct XmlNamespace {
4249    pub this: Expression,
4250    #[serde(skip_serializing_if = "Option::is_none")]
4251    pub alias: Option<Identifier>,
4252}
4253
4254/// ROW FORMAT clause for Hive/Spark
4255#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4256#[cfg_attr(feature = "bindings", derive(TS))]
4257pub struct RowFormat {
4258    pub delimited: bool,
4259    pub fields_terminated_by: Option<String>,
4260    pub collection_items_terminated_by: Option<String>,
4261    pub map_keys_terminated_by: Option<String>,
4262    pub lines_terminated_by: Option<String>,
4263    pub null_defined_as: Option<String>,
4264}
4265
4266/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4267#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4268#[cfg_attr(feature = "bindings", derive(TS))]
4269pub struct DirectoryInsert {
4270    pub local: bool,
4271    pub path: String,
4272    pub row_format: Option<RowFormat>,
4273    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4274    #[serde(default)]
4275    pub stored_as: Option<String>,
4276}
4277
4278/// INSERT statement
4279#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4280#[cfg_attr(feature = "bindings", derive(TS))]
4281pub struct Insert {
4282    pub table: TableRef,
4283    pub columns: Vec<Identifier>,
4284    pub values: Vec<Vec<Expression>>,
4285    pub query: Option<Expression>,
4286    /// INSERT OVERWRITE for Hive/Spark
4287    pub overwrite: bool,
4288    /// PARTITION clause for Hive/Spark
4289    pub partition: Vec<(Identifier, Option<Expression>)>,
4290    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4291    #[serde(default)]
4292    pub directory: Option<DirectoryInsert>,
4293    /// RETURNING clause (PostgreSQL, SQLite)
4294    #[serde(default)]
4295    pub returning: Vec<Expression>,
4296    /// OUTPUT clause (TSQL)
4297    #[serde(default)]
4298    pub output: Option<OutputClause>,
4299    /// ON CONFLICT clause (PostgreSQL, SQLite)
4300    #[serde(default)]
4301    pub on_conflict: Option<Box<Expression>>,
4302    /// Leading comments before the statement
4303    #[serde(default)]
4304    pub leading_comments: Vec<String>,
4305    /// IF EXISTS clause (Hive)
4306    #[serde(default)]
4307    pub if_exists: bool,
4308    /// WITH clause (CTEs)
4309    #[serde(default)]
4310    pub with: Option<With>,
4311    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4312    #[serde(default)]
4313    pub ignore: bool,
4314    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4315    #[serde(default)]
4316    pub source_alias: Option<Identifier>,
4317    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4318    #[serde(default)]
4319    pub alias: Option<Identifier>,
4320    /// Whether the alias uses explicit AS keyword
4321    #[serde(default)]
4322    pub alias_explicit_as: bool,
4323    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4324    #[serde(default)]
4325    pub default_values: bool,
4326    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4327    #[serde(default)]
4328    pub by_name: bool,
4329    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4330    #[serde(default, skip_serializing_if = "Option::is_none")]
4331    pub conflict_action: Option<String>,
4332    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4333    #[serde(default)]
4334    pub is_replace: bool,
4335    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4336    #[serde(default, skip_serializing_if = "Option::is_none")]
4337    pub hint: Option<Hint>,
4338    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4339    #[serde(default)]
4340    pub replace_where: Option<Box<Expression>>,
4341    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4342    #[serde(default)]
4343    pub source: Option<Box<Expression>>,
4344    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4345    #[serde(default, skip_serializing_if = "Option::is_none")]
4346    pub function_target: Option<Box<Expression>>,
4347    /// ClickHouse: PARTITION BY expr
4348    #[serde(default, skip_serializing_if = "Option::is_none")]
4349    pub partition_by: Option<Box<Expression>>,
4350    /// ClickHouse: SETTINGS key = val, ...
4351    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4352    pub settings: Vec<Expression>,
4353}
4354
4355/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4356#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4357#[cfg_attr(feature = "bindings", derive(TS))]
4358pub struct OutputClause {
4359    /// Columns/expressions to output
4360    pub columns: Vec<Expression>,
4361    /// Optional INTO target table or table variable
4362    #[serde(default)]
4363    pub into_table: Option<Expression>,
4364}
4365
4366/// UPDATE statement
4367#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4368#[cfg_attr(feature = "bindings", derive(TS))]
4369pub struct Update {
4370    pub table: TableRef,
4371    #[serde(default)]
4372    pub hint: Option<Hint>,
4373    /// Additional tables for multi-table UPDATE (MySQL syntax)
4374    #[serde(default)]
4375    pub extra_tables: Vec<TableRef>,
4376    /// JOINs attached to the table list (MySQL multi-table syntax)
4377    #[serde(default)]
4378    pub table_joins: Vec<Join>,
4379    pub set: Vec<(Identifier, Expression)>,
4380    pub from_clause: Option<From>,
4381    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4382    #[serde(default)]
4383    pub from_joins: Vec<Join>,
4384    pub where_clause: Option<Where>,
4385    /// RETURNING clause (PostgreSQL, SQLite)
4386    #[serde(default)]
4387    pub returning: Vec<Expression>,
4388    /// OUTPUT clause (TSQL)
4389    #[serde(default)]
4390    pub output: Option<OutputClause>,
4391    /// WITH clause (CTEs)
4392    #[serde(default)]
4393    pub with: Option<With>,
4394    /// Leading comments before the statement
4395    #[serde(default)]
4396    pub leading_comments: Vec<String>,
4397    /// LIMIT clause (MySQL)
4398    #[serde(default)]
4399    pub limit: Option<Expression>,
4400    /// ORDER BY clause (MySQL)
4401    #[serde(default)]
4402    pub order_by: Option<OrderBy>,
4403    /// Whether FROM clause appears before SET (Snowflake syntax)
4404    #[serde(default)]
4405    pub from_before_set: bool,
4406}
4407
4408/// DELETE statement
4409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4410#[cfg_attr(feature = "bindings", derive(TS))]
4411pub struct Delete {
4412    pub table: TableRef,
4413    #[serde(default)]
4414    pub hint: Option<Hint>,
4415    /// ClickHouse: ON CLUSTER clause for distributed DDL
4416    #[serde(default, skip_serializing_if = "Option::is_none")]
4417    pub on_cluster: Option<OnCluster>,
4418    /// Optional alias for the table
4419    pub alias: Option<Identifier>,
4420    /// Whether the alias was declared with explicit AS keyword
4421    #[serde(default)]
4422    pub alias_explicit_as: bool,
4423    /// PostgreSQL/DuckDB USING clause - additional tables to join
4424    pub using: Vec<TableRef>,
4425    pub where_clause: Option<Where>,
4426    /// OUTPUT clause (TSQL)
4427    #[serde(default)]
4428    pub output: Option<OutputClause>,
4429    /// Leading comments before the statement
4430    #[serde(default)]
4431    pub leading_comments: Vec<String>,
4432    /// WITH clause (CTEs)
4433    #[serde(default)]
4434    pub with: Option<With>,
4435    /// LIMIT clause (MySQL)
4436    #[serde(default)]
4437    pub limit: Option<Expression>,
4438    /// ORDER BY clause (MySQL)
4439    #[serde(default)]
4440    pub order_by: Option<OrderBy>,
4441    /// RETURNING clause (PostgreSQL)
4442    #[serde(default)]
4443    pub returning: Vec<Expression>,
4444    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4445    /// These are the target tables to delete from
4446    #[serde(default)]
4447    pub tables: Vec<TableRef>,
4448    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4449    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4450    #[serde(default)]
4451    pub tables_from_using: bool,
4452    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4453    #[serde(default)]
4454    pub joins: Vec<Join>,
4455    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4456    #[serde(default)]
4457    pub force_index: Option<String>,
4458    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4459    #[serde(default)]
4460    pub no_from: bool,
4461}
4462
4463/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4464#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4465#[cfg_attr(feature = "bindings", derive(TS))]
4466pub struct CopyStmt {
4467    /// Target table or query
4468    pub this: Expression,
4469    /// True for FROM (loading into table), false for TO (exporting)
4470    pub kind: bool,
4471    /// Source/destination file(s) or stage
4472    pub files: Vec<Expression>,
4473    /// Copy parameters
4474    #[serde(default)]
4475    pub params: Vec<CopyParameter>,
4476    /// Credentials for external access
4477    #[serde(default)]
4478    pub credentials: Option<Box<Credentials>>,
4479    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4480    #[serde(default)]
4481    pub is_into: bool,
4482    /// Whether parameters are wrapped in WITH (...) syntax
4483    #[serde(default)]
4484    pub with_wrapped: bool,
4485}
4486
4487/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4489#[cfg_attr(feature = "bindings", derive(TS))]
4490pub struct CopyParameter {
4491    pub name: String,
4492    pub value: Option<Expression>,
4493    pub values: Vec<Expression>,
4494    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4495    #[serde(default)]
4496    pub eq: bool,
4497}
4498
4499/// Credentials for external access (S3, Azure, etc.)
4500#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4501#[cfg_attr(feature = "bindings", derive(TS))]
4502pub struct Credentials {
4503    pub credentials: Vec<(String, String)>,
4504    pub encryption: Option<String>,
4505    pub storage: Option<String>,
4506}
4507
4508/// PUT statement (Snowflake)
4509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4510#[cfg_attr(feature = "bindings", derive(TS))]
4511pub struct PutStmt {
4512    /// Source file path
4513    pub source: String,
4514    /// Whether source was quoted in the original SQL
4515    #[serde(default)]
4516    pub source_quoted: bool,
4517    /// Target stage
4518    pub target: Expression,
4519    /// PUT parameters
4520    #[serde(default)]
4521    pub params: Vec<CopyParameter>,
4522}
4523
4524/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4526#[cfg_attr(feature = "bindings", derive(TS))]
4527pub struct StageReference {
4528    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4529    pub name: String,
4530    /// Optional path within the stage (e.g., "/path/to/file.csv")
4531    #[serde(default)]
4532    pub path: Option<String>,
4533    /// Optional FILE_FORMAT parameter
4534    #[serde(default)]
4535    pub file_format: Option<Expression>,
4536    /// Optional PATTERN parameter
4537    #[serde(default)]
4538    pub pattern: Option<String>,
4539    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4540    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4541    pub quoted: bool,
4542}
4543
4544/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4545#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4546#[cfg_attr(feature = "bindings", derive(TS))]
4547pub struct HistoricalData {
4548    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4549    pub this: Box<Expression>,
4550    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4551    pub kind: String,
4552    /// The expression value (e.g., the statement ID or timestamp)
4553    pub expression: Box<Expression>,
4554}
4555
4556/// Represent an aliased expression (`expr AS name`).
4557///
4558/// Used for column aliases in select-lists, table aliases on subqueries,
4559/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4561#[cfg_attr(feature = "bindings", derive(TS))]
4562pub struct Alias {
4563    /// The expression being aliased.
4564    pub this: Expression,
4565    /// The alias name (required for simple aliases, optional when only column aliases provided)
4566    pub alias: Identifier,
4567    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4568    #[serde(default)]
4569    pub column_aliases: Vec<Identifier>,
4570    /// Whether AS keyword was explicitly used for the alias.
4571    #[serde(default)]
4572    pub alias_explicit_as: bool,
4573    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4574    #[serde(skip_serializing_if = "Option::is_none", default)]
4575    pub alias_keyword: Option<String>,
4576    /// Comments that appeared between the expression and AS keyword
4577    #[serde(default)]
4578    pub pre_alias_comments: Vec<String>,
4579    /// Trailing comments that appeared after the alias
4580    #[serde(default)]
4581    pub trailing_comments: Vec<String>,
4582    /// Inferred data type from type annotation
4583    #[serde(default, skip_serializing_if = "Option::is_none")]
4584    #[ast(skip)]
4585    pub inferred_type: Option<DataType>,
4586}
4587
4588impl Alias {
4589    /// Create a simple alias
4590    pub fn new(this: Expression, alias: Identifier) -> Self {
4591        Self {
4592            this,
4593            alias,
4594            column_aliases: Vec::new(),
4595            alias_explicit_as: false,
4596            alias_keyword: None,
4597            pre_alias_comments: Vec::new(),
4598            trailing_comments: Vec::new(),
4599            inferred_type: None,
4600        }
4601    }
4602
4603    /// Create an alias with column aliases only (no table alias name)
4604    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4605        Self {
4606            this,
4607            alias: Identifier::empty(),
4608            column_aliases,
4609            alias_explicit_as: false,
4610            alias_keyword: None,
4611            pre_alias_comments: Vec::new(),
4612            trailing_comments: Vec::new(),
4613            inferred_type: None,
4614        }
4615    }
4616}
4617
4618/// Represent a type cast expression.
4619///
4620/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4621/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4622/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4623/// CONVERSION ERROR (Oracle) clauses.
4624#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4625#[cfg_attr(feature = "bindings", derive(TS))]
4626pub struct Cast {
4627    /// The expression being cast.
4628    pub this: Expression,
4629    /// The target data type.
4630    pub to: DataType,
4631    #[serde(default)]
4632    pub trailing_comments: Vec<String>,
4633    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4634    #[serde(default)]
4635    pub double_colon_syntax: bool,
4636    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4637    #[serde(skip_serializing_if = "Option::is_none", default)]
4638    pub format: Option<Box<Expression>>,
4639    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4640    #[serde(skip_serializing_if = "Option::is_none", default)]
4641    pub default: Option<Box<Expression>>,
4642    /// Inferred data type from type annotation
4643    #[serde(default, skip_serializing_if = "Option::is_none")]
4644    #[ast(skip)]
4645    pub inferred_type: Option<DataType>,
4646}
4647
4648///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4649#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4650#[cfg_attr(feature = "bindings", derive(TS))]
4651pub struct CollationExpr {
4652    pub this: Expression,
4653    pub collation: String,
4654    /// True if the collation was single-quoted in the original SQL (string literal)
4655    #[serde(default)]
4656    pub quoted: bool,
4657    /// True if the collation was double-quoted in the original SQL (identifier)
4658    #[serde(default)]
4659    pub double_quoted: bool,
4660}
4661
4662/// Represent a CASE expression (both simple and searched forms).
4663///
4664/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4665/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4666/// Each entry in `whens` is a `(condition, result)` pair.
4667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4668#[cfg_attr(feature = "bindings", derive(TS))]
4669pub struct Case {
4670    /// The operand for simple CASE, or `None` for searched CASE.
4671    pub operand: Option<Expression>,
4672    /// Pairs of (WHEN condition, THEN result).
4673    pub whens: Vec<(Expression, Expression)>,
4674    /// Optional ELSE result.
4675    pub else_: Option<Expression>,
4676    /// Comments from the CASE keyword (emitted after END)
4677    #[serde(default)]
4678    #[serde(skip_serializing_if = "Vec::is_empty")]
4679    pub comments: Vec<String>,
4680    /// Inferred data type from type annotation
4681    #[serde(default, skip_serializing_if = "Option::is_none")]
4682    #[ast(skip)]
4683    pub inferred_type: Option<DataType>,
4684}
4685
4686/// Represent a binary operation (two operands separated by an operator).
4687///
4688/// This is the shared payload struct for all binary operator variants in the
4689/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4690/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4691/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4692/// preservation of inline comments around operators.
4693#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4694#[cfg_attr(feature = "bindings", derive(TS))]
4695pub struct BinaryOp {
4696    pub left: Expression,
4697    pub right: Expression,
4698    /// Comments after the left operand (before the operator)
4699    #[serde(default)]
4700    pub left_comments: Vec<String>,
4701    /// Comments after the operator (before the right operand)
4702    #[serde(default)]
4703    pub operator_comments: Vec<String>,
4704    /// Comments after the right operand
4705    #[serde(default)]
4706    pub trailing_comments: Vec<String>,
4707    /// Inferred data type from type annotation
4708    #[serde(default, skip_serializing_if = "Option::is_none")]
4709    #[ast(skip)]
4710    pub inferred_type: Option<DataType>,
4711}
4712
4713impl BinaryOp {
4714    pub fn new(left: Expression, right: Expression) -> Self {
4715        Self {
4716            left,
4717            right,
4718            left_comments: Vec::new(),
4719            operator_comments: Vec::new(),
4720            trailing_comments: Vec::new(),
4721            inferred_type: None,
4722        }
4723    }
4724}
4725
4726/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4727#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4728#[cfg_attr(feature = "bindings", derive(TS))]
4729pub struct LikeOp {
4730    pub left: Expression,
4731    pub right: Expression,
4732    /// ESCAPE character/expression
4733    #[serde(default)]
4734    pub escape: Option<Expression>,
4735    /// Quantifier: ANY, ALL, or SOME
4736    #[serde(default)]
4737    pub quantifier: Option<String>,
4738    /// Inferred data type from type annotation
4739    #[serde(default, skip_serializing_if = "Option::is_none")]
4740    #[ast(skip)]
4741    pub inferred_type: Option<DataType>,
4742}
4743
4744impl LikeOp {
4745    pub fn new(left: Expression, right: Expression) -> Self {
4746        Self {
4747            left,
4748            right,
4749            escape: None,
4750            quantifier: None,
4751            inferred_type: None,
4752        }
4753    }
4754
4755    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4756        Self {
4757            left,
4758            right,
4759            escape: Some(escape),
4760            quantifier: None,
4761            inferred_type: None,
4762        }
4763    }
4764}
4765
4766/// Represent a unary operation (single operand with a prefix operator).
4767///
4768/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4769#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4770#[cfg_attr(feature = "bindings", derive(TS))]
4771pub struct UnaryOp {
4772    /// The operand expression.
4773    pub this: Expression,
4774    /// Inferred data type from type annotation
4775    #[serde(default, skip_serializing_if = "Option::is_none")]
4776    #[ast(skip)]
4777    pub inferred_type: Option<DataType>,
4778}
4779
4780impl UnaryOp {
4781    pub fn new(this: Expression) -> Self {
4782        Self {
4783            this,
4784            inferred_type: None,
4785        }
4786    }
4787}
4788
4789/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4790///
4791/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4792/// but not both. When `not` is true, the predicate is `NOT IN`.
4793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4794#[cfg_attr(feature = "bindings", derive(TS))]
4795pub struct In {
4796    /// The expression being tested.
4797    pub this: Expression,
4798    /// The value list (mutually exclusive with `query`).
4799    pub expressions: Vec<Expression>,
4800    /// A subquery (mutually exclusive with `expressions`).
4801    pub query: Option<Expression>,
4802    /// Whether this is NOT IN.
4803    pub not: bool,
4804    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4805    pub global: bool,
4806    /// BigQuery: IN UNNEST(expr)
4807    #[serde(default, skip_serializing_if = "Option::is_none")]
4808    pub unnest: Option<Box<Expression>>,
4809    /// Whether the right side is a bare field reference (no parentheses).
4810    /// Matches Python sqlglot's `field` attribute on `In` expression.
4811    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4812    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4813    pub is_field: bool,
4814}
4815
4816/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4817#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4818#[cfg_attr(feature = "bindings", derive(TS))]
4819pub struct Between {
4820    /// The expression being tested.
4821    pub this: Expression,
4822    /// The lower bound.
4823    pub low: Expression,
4824    /// The upper bound.
4825    pub high: Expression,
4826    /// Whether this is NOT BETWEEN.
4827    pub not: bool,
4828    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4829    #[serde(default)]
4830    pub symmetric: Option<bool>,
4831}
4832
4833/// IS NULL predicate
4834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4835#[cfg_attr(feature = "bindings", derive(TS))]
4836pub struct IsNull {
4837    pub this: Expression,
4838    pub not: bool,
4839    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4840    #[serde(default)]
4841    pub postfix_form: bool,
4842}
4843
4844/// IS TRUE / IS FALSE predicate
4845#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4846#[cfg_attr(feature = "bindings", derive(TS))]
4847pub struct IsTrueFalse {
4848    pub this: Expression,
4849    pub not: bool,
4850}
4851
4852/// IS JSON predicate (SQL standard)
4853/// Checks if a value is valid JSON
4854#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4855#[cfg_attr(feature = "bindings", derive(TS))]
4856pub struct IsJson {
4857    pub this: Expression,
4858    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4859    pub json_type: Option<String>,
4860    /// Key uniqueness constraint
4861    pub unique_keys: Option<JsonUniqueKeys>,
4862    /// Whether IS NOT JSON
4863    pub negated: bool,
4864}
4865
4866/// JSON unique keys constraint variants
4867#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4868#[cfg_attr(feature = "bindings", derive(TS))]
4869pub enum JsonUniqueKeys {
4870    /// WITH UNIQUE KEYS
4871    With,
4872    /// WITHOUT UNIQUE KEYS
4873    Without,
4874    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4875    Shorthand,
4876}
4877
4878/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4880#[cfg_attr(feature = "bindings", derive(TS))]
4881pub struct Exists {
4882    /// The subquery expression.
4883    pub this: Expression,
4884    /// Whether this is NOT EXISTS.
4885    pub not: bool,
4886}
4887
4888/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
4889///
4890/// This is the generic function node. Well-known aggregates, window functions,
4891/// and built-in functions each have their own dedicated `Expression` variants
4892/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
4893/// not recognize as built-ins are represented with this struct.
4894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4895#[cfg_attr(feature = "bindings", derive(TS))]
4896pub struct Function {
4897    /// The function name, as originally written (may be schema-qualified).
4898    pub name: String,
4899    /// Positional arguments to the function.
4900    pub args: Vec<Expression>,
4901    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
4902    pub distinct: bool,
4903    #[serde(default)]
4904    pub trailing_comments: Vec<String>,
4905    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
4906    #[serde(default)]
4907    pub use_bracket_syntax: bool,
4908    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
4909    #[serde(default)]
4910    pub no_parens: bool,
4911    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
4912    #[serde(default)]
4913    pub quoted: bool,
4914    /// Source position span
4915    #[serde(default, skip_serializing_if = "Option::is_none")]
4916    pub span: Option<Span>,
4917    /// Inferred data type from type annotation
4918    #[serde(default, skip_serializing_if = "Option::is_none")]
4919    #[ast(skip)]
4920    pub inferred_type: Option<DataType>,
4921}
4922
4923impl Default for Function {
4924    fn default() -> Self {
4925        Self {
4926            name: String::new(),
4927            args: Vec::new(),
4928            distinct: false,
4929            trailing_comments: Vec::new(),
4930            use_bracket_syntax: false,
4931            no_parens: false,
4932            quoted: false,
4933            span: None,
4934            inferred_type: None,
4935        }
4936    }
4937}
4938
4939impl Function {
4940    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
4941        Self {
4942            name: name.into(),
4943            args,
4944            distinct: false,
4945            trailing_comments: Vec::new(),
4946            use_bracket_syntax: false,
4947            no_parens: false,
4948            quoted: false,
4949            span: None,
4950            inferred_type: None,
4951        }
4952    }
4953}
4954
4955/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
4956///
4957/// This struct is used for aggregate function calls that are not covered by
4958/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
4959/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
4960/// IGNORE NULLS / RESPECT NULLS modifiers.
4961#[derive(
4962    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
4963)]
4964#[cfg_attr(feature = "bindings", derive(TS))]
4965pub struct AggregateFunction {
4966    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
4967    pub name: String,
4968    /// Positional arguments.
4969    pub args: Vec<Expression>,
4970    /// Whether DISTINCT was specified.
4971    pub distinct: bool,
4972    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
4973    pub filter: Option<Expression>,
4974    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
4975    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4976    pub order_by: Vec<Ordered>,
4977    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
4978    #[serde(default, skip_serializing_if = "Option::is_none")]
4979    pub limit: Option<Box<Expression>>,
4980    /// IGNORE NULLS / RESPECT NULLS
4981    #[serde(default, skip_serializing_if = "Option::is_none")]
4982    pub ignore_nulls: Option<bool>,
4983    /// Inferred data type from type annotation
4984    #[serde(default, skip_serializing_if = "Option::is_none")]
4985    #[ast(skip)]
4986    pub inferred_type: Option<DataType>,
4987}
4988
4989/// Represent a window function call with its OVER clause.
4990///
4991/// The inner `this` expression is typically a window-specific expression
4992/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
4993/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
4994/// frame specification.
4995#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4996#[cfg_attr(feature = "bindings", derive(TS))]
4997pub struct WindowFunction {
4998    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
4999    pub this: Expression,
5000    /// The OVER clause defining the window partitioning, ordering, and frame.
5001    pub over: Over,
5002    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
5003    #[serde(default, skip_serializing_if = "Option::is_none")]
5004    pub keep: Option<Keep>,
5005    /// Inferred data type from type annotation
5006    #[serde(default, skip_serializing_if = "Option::is_none")]
5007    #[ast(skip)]
5008    pub inferred_type: Option<DataType>,
5009}
5010
5011/// Oracle KEEP clause for aggregate functions
5012/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
5013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5014#[cfg_attr(feature = "bindings", derive(TS))]
5015pub struct Keep {
5016    /// true = FIRST, false = LAST
5017    pub first: bool,
5018    /// ORDER BY clause inside KEEP
5019    pub order_by: Vec<Ordered>,
5020}
5021
5022/// WITHIN GROUP clause (for ordered-set aggregate functions)
5023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5024#[cfg_attr(feature = "bindings", derive(TS))]
5025pub struct WithinGroup {
5026    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
5027    pub this: Expression,
5028    /// The ORDER BY clause within the group
5029    pub order_by: Vec<Ordered>,
5030}
5031
5032/// Represent the FROM clause of a SELECT statement.
5033///
5034/// Contains one or more table sources (tables, subqueries, table-valued
5035/// functions, etc.). Multiple entries represent comma-separated implicit joins.
5036#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5037#[cfg_attr(feature = "bindings", derive(TS))]
5038pub struct From {
5039    /// The table source expressions.
5040    pub expressions: Vec<Expression>,
5041}
5042
5043/// Represent a JOIN clause between two table sources.
5044///
5045/// The join condition can be specified via `on` (ON predicate) or `using`
5046/// (USING column list), but not both. The `kind` field determines the join
5047/// type (INNER, LEFT, CROSS, etc.).
5048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5049#[cfg_attr(feature = "bindings", derive(TS))]
5050pub struct Join {
5051    /// The right-hand table expression being joined.
5052    pub this: Expression,
5053    /// The ON condition (mutually exclusive with `using`).
5054    pub on: Option<Expression>,
5055    /// The USING column list (mutually exclusive with `on`).
5056    pub using: Vec<Identifier>,
5057    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5058    pub kind: JoinKind,
5059    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5060    pub use_inner_keyword: bool,
5061    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5062    pub use_outer_keyword: bool,
5063    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5064    pub deferred_condition: bool,
5065    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5066    #[serde(default, skip_serializing_if = "Option::is_none")]
5067    pub join_hint: Option<String>,
5068    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5069    #[serde(default, skip_serializing_if = "Option::is_none")]
5070    pub match_condition: Option<Expression>,
5071    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5072    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5073    pub pivots: Vec<Expression>,
5074    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5075    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5076    pub comments: Vec<String>,
5077    /// Nesting group identifier for nested join pretty-printing.
5078    /// Joins in the same group were parsed together; group boundaries come from
5079    /// deferred condition resolution phases.
5080    #[serde(default)]
5081    pub nesting_group: usize,
5082    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5083    #[serde(default)]
5084    pub directed: bool,
5085}
5086
5087/// Enumerate all supported SQL join types.
5088///
5089/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5090/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5091/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5092/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5093#[derive(
5094    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5095)]
5096#[cfg_attr(feature = "bindings", derive(TS))]
5097pub enum JoinKind {
5098    Inner,
5099    Left,
5100    Right,
5101    Full,
5102    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5103    Cross,
5104    Natural,
5105    NaturalLeft,
5106    NaturalRight,
5107    NaturalFull,
5108    Semi,
5109    Anti,
5110    // Directional SEMI/ANTI joins
5111    LeftSemi,
5112    LeftAnti,
5113    RightSemi,
5114    RightAnti,
5115    // SQL Server specific
5116    CrossApply,
5117    OuterApply,
5118    // Time-series specific
5119    AsOf,
5120    AsOfLeft,
5121    AsOfRight,
5122    // Lateral join
5123    Lateral,
5124    LeftLateral,
5125    // MySQL specific
5126    Straight,
5127    // Implicit join (comma-separated tables: FROM a, b)
5128    Implicit,
5129    // ClickHouse ARRAY JOIN
5130    Array,
5131    LeftArray,
5132    // ClickHouse PASTE JOIN (positional join)
5133    Paste,
5134    // DuckDB POSITIONAL JOIN
5135    Positional,
5136}
5137
5138impl Default for JoinKind {
5139    fn default() -> Self {
5140        JoinKind::Inner
5141    }
5142}
5143
5144/// Parenthesized table expression with joins
5145/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5147#[cfg_attr(feature = "bindings", derive(TS))]
5148pub struct JoinedTable {
5149    /// The left-hand side table expression
5150    pub left: Expression,
5151    /// The joins applied to the left table
5152    pub joins: Vec<Join>,
5153    /// LATERAL VIEW clauses (Hive/Spark)
5154    pub lateral_views: Vec<LateralView>,
5155    /// Optional alias for the joined table expression
5156    pub alias: Option<Identifier>,
5157}
5158
5159/// Represent a WHERE clause containing a boolean filter predicate.
5160#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5161#[cfg_attr(feature = "bindings", derive(TS))]
5162pub struct Where {
5163    /// The filter predicate expression.
5164    pub this: Expression,
5165}
5166
5167/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5168///
5169/// The `expressions` list may contain plain columns, ordinal positions,
5170/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5171#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5172#[cfg_attr(feature = "bindings", derive(TS))]
5173pub struct GroupBy {
5174    /// The grouping expressions.
5175    pub expressions: Vec<Expression>,
5176    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5177    #[serde(default)]
5178    pub all: Option<bool>,
5179    /// ClickHouse: WITH TOTALS modifier
5180    #[serde(default)]
5181    pub totals: bool,
5182    /// Leading comments that appeared before the GROUP BY keyword
5183    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5184    pub comments: Vec<String>,
5185}
5186
5187/// Represent a HAVING clause containing a predicate over aggregate results.
5188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5189#[cfg_attr(feature = "bindings", derive(TS))]
5190pub struct Having {
5191    /// The filter predicate, typically involving aggregate functions.
5192    pub this: Expression,
5193    /// Leading comments that appeared before the HAVING keyword
5194    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5195    pub comments: Vec<String>,
5196}
5197
5198/// Represent an ORDER BY clause containing one or more sort specifications.
5199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5200#[cfg_attr(feature = "bindings", derive(TS))]
5201pub struct OrderBy {
5202    /// The sort specifications, each with direction and null ordering.
5203    pub expressions: Vec<Ordered>,
5204    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5205    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5206    pub siblings: bool,
5207    /// Leading comments that appeared before the ORDER BY keyword
5208    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5209    pub comments: Vec<String>,
5210}
5211
5212/// Represent an expression with sort direction and null ordering.
5213///
5214/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5215/// When `desc` is false the sort is ascending. The `nulls_first` field
5216/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5217/// (database default).
5218#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5219#[cfg_attr(feature = "bindings", derive(TS))]
5220pub struct Ordered {
5221    /// The expression to sort by.
5222    pub this: Expression,
5223    /// Whether the sort direction is descending (true) or ascending (false).
5224    pub desc: bool,
5225    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5226    pub nulls_first: Option<bool>,
5227    /// Whether ASC was explicitly written (not just implied)
5228    #[serde(default)]
5229    pub explicit_asc: bool,
5230    /// ClickHouse WITH FILL clause
5231    #[serde(default, skip_serializing_if = "Option::is_none")]
5232    pub with_fill: Option<Box<WithFill>>,
5233}
5234
5235impl Ordered {
5236    pub fn asc(expr: Expression) -> Self {
5237        Self {
5238            this: expr,
5239            desc: false,
5240            nulls_first: None,
5241            explicit_asc: false,
5242            with_fill: None,
5243        }
5244    }
5245
5246    pub fn desc(expr: Expression) -> Self {
5247        Self {
5248            this: expr,
5249            desc: true,
5250            nulls_first: None,
5251            explicit_asc: false,
5252            with_fill: None,
5253        }
5254    }
5255}
5256
5257/// DISTRIBUTE BY clause (Hive/Spark)
5258/// Controls how rows are distributed across reducers
5259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5260#[cfg_attr(feature = "bindings", derive(TS))]
5261#[cfg_attr(feature = "bindings", ts(export))]
5262pub struct DistributeBy {
5263    pub expressions: Vec<Expression>,
5264}
5265
5266/// CLUSTER BY clause (Hive/Spark)
5267/// Combines DISTRIBUTE BY and SORT BY on the same columns
5268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5269#[cfg_attr(feature = "bindings", derive(TS))]
5270#[cfg_attr(feature = "bindings", ts(export))]
5271pub struct ClusterBy {
5272    pub expressions: Vec<Ordered>,
5273}
5274
5275/// SORT BY clause (Hive/Spark)
5276/// Sorts data within each reducer (local sort, not global)
5277#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5278#[cfg_attr(feature = "bindings", derive(TS))]
5279#[cfg_attr(feature = "bindings", ts(export))]
5280pub struct SortBy {
5281    pub expressions: Vec<Ordered>,
5282}
5283
5284/// LATERAL VIEW clause (Hive/Spark)
5285/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5287#[cfg_attr(feature = "bindings", derive(TS))]
5288#[cfg_attr(feature = "bindings", ts(export))]
5289pub struct LateralView {
5290    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5291    pub this: Expression,
5292    /// Table alias for the generated table
5293    pub table_alias: Option<Identifier>,
5294    /// Column aliases for the generated columns
5295    pub column_aliases: Vec<Identifier>,
5296    /// OUTER keyword - preserve nulls when input is empty/null
5297    pub outer: bool,
5298}
5299
5300/// Query hint
5301#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5302#[cfg_attr(feature = "bindings", derive(TS))]
5303#[cfg_attr(feature = "bindings", ts(export))]
5304pub struct Hint {
5305    pub expressions: Vec<HintExpression>,
5306}
5307
5308/// Individual hint expression
5309#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5310#[cfg_attr(feature = "bindings", derive(TS))]
5311#[cfg_attr(feature = "bindings", ts(export))]
5312pub enum HintExpression {
5313    /// Function-style hint: USE_HASH(table)
5314    Function { name: String, args: Vec<Expression> },
5315    /// Simple identifier hint: PARALLEL
5316    Identifier(String),
5317    /// Raw hint text (unparsed)
5318    Raw(String),
5319}
5320
5321/// Pseudocolumn type
5322#[derive(
5323    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5324)]
5325#[cfg_attr(feature = "bindings", derive(TS))]
5326#[cfg_attr(feature = "bindings", ts(export))]
5327pub enum PseudocolumnType {
5328    Rownum,      // Oracle ROWNUM
5329    Rowid,       // Oracle ROWID
5330    Level,       // Oracle LEVEL (for CONNECT BY)
5331    Sysdate,     // Oracle SYSDATE
5332    ObjectId,    // Oracle OBJECT_ID
5333    ObjectValue, // Oracle OBJECT_VALUE
5334}
5335
5336impl PseudocolumnType {
5337    pub fn as_str(&self) -> &'static str {
5338        match self {
5339            PseudocolumnType::Rownum => "ROWNUM",
5340            PseudocolumnType::Rowid => "ROWID",
5341            PseudocolumnType::Level => "LEVEL",
5342            PseudocolumnType::Sysdate => "SYSDATE",
5343            PseudocolumnType::ObjectId => "OBJECT_ID",
5344            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5345        }
5346    }
5347
5348    pub fn from_str(s: &str) -> Option<Self> {
5349        match s.to_uppercase().as_str() {
5350            "ROWNUM" => Some(PseudocolumnType::Rownum),
5351            "ROWID" => Some(PseudocolumnType::Rowid),
5352            "LEVEL" => Some(PseudocolumnType::Level),
5353            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5354            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5355            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5356            _ => None,
5357        }
5358    }
5359}
5360
5361/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5362/// These are special identifiers that should not be quoted
5363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5364#[cfg_attr(feature = "bindings", derive(TS))]
5365#[cfg_attr(feature = "bindings", ts(export))]
5366pub struct Pseudocolumn {
5367    pub kind: PseudocolumnType,
5368}
5369
5370impl Pseudocolumn {
5371    pub fn rownum() -> Self {
5372        Self {
5373            kind: PseudocolumnType::Rownum,
5374        }
5375    }
5376
5377    pub fn rowid() -> Self {
5378        Self {
5379            kind: PseudocolumnType::Rowid,
5380        }
5381    }
5382
5383    pub fn level() -> Self {
5384        Self {
5385            kind: PseudocolumnType::Level,
5386        }
5387    }
5388}
5389
5390/// Oracle CONNECT BY clause for hierarchical queries
5391#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5392#[cfg_attr(feature = "bindings", derive(TS))]
5393#[cfg_attr(feature = "bindings", ts(export))]
5394pub struct Connect {
5395    /// START WITH condition (optional, can come before or after CONNECT BY)
5396    pub start: Option<Expression>,
5397    /// CONNECT BY condition (required, contains PRIOR references)
5398    pub connect: Expression,
5399    /// NOCYCLE keyword to prevent infinite loops
5400    pub nocycle: bool,
5401}
5402
5403/// Oracle PRIOR expression - references parent row's value in CONNECT BY
5404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5405#[cfg_attr(feature = "bindings", derive(TS))]
5406#[cfg_attr(feature = "bindings", ts(export))]
5407pub struct Prior {
5408    pub this: Expression,
5409}
5410
5411/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5413#[cfg_attr(feature = "bindings", derive(TS))]
5414#[cfg_attr(feature = "bindings", ts(export))]
5415pub struct ConnectByRoot {
5416    pub this: Expression,
5417}
5418
5419/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5420#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5421#[cfg_attr(feature = "bindings", derive(TS))]
5422#[cfg_attr(feature = "bindings", ts(export))]
5423pub struct MatchRecognize {
5424    /// Source table/expression
5425    pub this: Option<Box<Expression>>,
5426    /// PARTITION BY expressions
5427    pub partition_by: Option<Vec<Expression>>,
5428    /// ORDER BY expressions
5429    pub order_by: Option<Vec<Ordered>>,
5430    /// MEASURES definitions
5431    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5432    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5433    pub rows: Option<MatchRecognizeRows>,
5434    /// AFTER MATCH SKIP behavior
5435    pub after: Option<MatchRecognizeAfter>,
5436    /// PATTERN definition (stored as raw string for complex regex patterns)
5437    pub pattern: Option<String>,
5438    /// DEFINE clauses (pattern variable definitions)
5439    pub define: Option<Vec<(Identifier, Expression)>>,
5440    /// Optional alias for the result
5441    pub alias: Option<Identifier>,
5442    /// Whether AS keyword was explicitly present before alias
5443    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5444    pub alias_explicit_as: bool,
5445}
5446
5447/// MEASURES expression with optional RUNNING/FINAL semantics
5448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5449#[cfg_attr(feature = "bindings", derive(TS))]
5450#[cfg_attr(feature = "bindings", ts(export))]
5451pub struct MatchRecognizeMeasure {
5452    /// The measure expression
5453    pub this: Expression,
5454    /// RUNNING or FINAL semantics (Snowflake-specific)
5455    pub window_frame: Option<MatchRecognizeSemantics>,
5456}
5457
5458/// Semantics for MEASURES in MATCH_RECOGNIZE
5459#[derive(
5460    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5461)]
5462#[cfg_attr(feature = "bindings", derive(TS))]
5463#[cfg_attr(feature = "bindings", ts(export))]
5464pub enum MatchRecognizeSemantics {
5465    Running,
5466    Final,
5467}
5468
5469/// Row output semantics for MATCH_RECOGNIZE
5470#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5471#[cfg_attr(feature = "bindings", derive(TS))]
5472#[cfg_attr(feature = "bindings", ts(export))]
5473pub enum MatchRecognizeRows {
5474    OneRowPerMatch,
5475    AllRowsPerMatch,
5476    AllRowsPerMatchShowEmptyMatches,
5477    AllRowsPerMatchOmitEmptyMatches,
5478    AllRowsPerMatchWithUnmatchedRows,
5479}
5480
5481/// AFTER MATCH SKIP behavior
5482#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5483#[cfg_attr(feature = "bindings", derive(TS))]
5484#[cfg_attr(feature = "bindings", ts(export))]
5485pub enum MatchRecognizeAfter {
5486    PastLastRow,
5487    ToNextRow,
5488    ToFirst(Identifier),
5489    ToLast(Identifier),
5490}
5491
5492/// Represent a LIMIT clause that restricts the number of returned rows.
5493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5494#[cfg_attr(feature = "bindings", derive(TS))]
5495pub struct Limit {
5496    /// The limit count expression.
5497    pub this: Expression,
5498    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5499    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5500    pub percent: bool,
5501    /// Comments from before the LIMIT keyword (emitted after the limit value)
5502    #[serde(default)]
5503    #[serde(skip_serializing_if = "Vec::is_empty")]
5504    pub comments: Vec<String>,
5505}
5506
5507/// OFFSET clause
5508#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5509#[cfg_attr(feature = "bindings", derive(TS))]
5510pub struct Offset {
5511    pub this: Expression,
5512    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5513    #[serde(skip_serializing_if = "Option::is_none", default)]
5514    pub rows: Option<bool>,
5515}
5516
5517/// TOP clause (SQL Server)
5518#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5519#[cfg_attr(feature = "bindings", derive(TS))]
5520pub struct Top {
5521    pub this: Expression,
5522    pub percent: bool,
5523    pub with_ties: bool,
5524    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5525    #[serde(default)]
5526    pub parenthesized: bool,
5527}
5528
5529/// FETCH FIRST/NEXT clause (SQL standard)
5530#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5531#[cfg_attr(feature = "bindings", derive(TS))]
5532pub struct Fetch {
5533    /// FIRST or NEXT
5534    pub direction: String,
5535    /// Count expression (optional)
5536    pub count: Option<Expression>,
5537    /// PERCENT modifier
5538    pub percent: bool,
5539    /// ROWS or ROW keyword present
5540    pub rows: bool,
5541    /// WITH TIES modifier
5542    pub with_ties: bool,
5543}
5544
5545/// Represent a QUALIFY clause for filtering on window function results.
5546///
5547/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5548/// typically references a window function (e.g.
5549/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5550#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5551#[cfg_attr(feature = "bindings", derive(TS))]
5552pub struct Qualify {
5553    /// The filter predicate over window function results.
5554    pub this: Expression,
5555}
5556
5557/// SAMPLE / TABLESAMPLE clause
5558#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5559#[cfg_attr(feature = "bindings", derive(TS))]
5560pub struct Sample {
5561    pub method: SampleMethod,
5562    pub size: Expression,
5563    pub seed: Option<Expression>,
5564    /// ClickHouse OFFSET expression after SAMPLE size
5565    #[serde(default)]
5566    pub offset: Option<Expression>,
5567    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5568    pub unit_after_size: bool,
5569    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5570    #[serde(default)]
5571    pub use_sample_keyword: bool,
5572    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5573    #[serde(default)]
5574    pub explicit_method: bool,
5575    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5576    #[serde(default)]
5577    pub method_before_size: bool,
5578    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5579    #[serde(default)]
5580    pub use_seed_keyword: bool,
5581    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5582    pub bucket_numerator: Option<Box<Expression>>,
5583    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5584    pub bucket_denominator: Option<Box<Expression>>,
5585    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5586    pub bucket_field: Option<Box<Expression>>,
5587    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5588    #[serde(default)]
5589    pub is_using_sample: bool,
5590    /// Whether the unit was explicitly PERCENT (vs ROWS)
5591    #[serde(default)]
5592    pub is_percent: bool,
5593    /// Whether to suppress method output (for cross-dialect transpilation)
5594    #[serde(default)]
5595    pub suppress_method_output: bool,
5596}
5597
5598/// Sample method
5599#[derive(
5600    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5601)]
5602#[cfg_attr(feature = "bindings", derive(TS))]
5603pub enum SampleMethod {
5604    Bernoulli,
5605    System,
5606    Block,
5607    Row,
5608    Percent,
5609    /// Hive bucket sampling
5610    Bucket,
5611    /// DuckDB reservoir sampling
5612    Reservoir,
5613}
5614
5615/// Named window definition (WINDOW w AS (...))
5616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5617#[cfg_attr(feature = "bindings", derive(TS))]
5618pub struct NamedWindow {
5619    pub name: Identifier,
5620    pub spec: Over,
5621}
5622
5623/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5624///
5625/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5626/// that reference themselves. Each CTE is defined in the `ctes` vector and
5627/// can be referenced by name in subsequent CTEs and in the main query body.
5628#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5629#[cfg_attr(feature = "bindings", derive(TS))]
5630pub struct With {
5631    /// The list of CTE definitions, in order.
5632    pub ctes: Vec<Cte>,
5633    /// Whether the WITH RECURSIVE keyword was used.
5634    pub recursive: bool,
5635    /// Leading comments before the statement
5636    #[serde(default)]
5637    pub leading_comments: Vec<String>,
5638    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5639    #[serde(default, skip_serializing_if = "Option::is_none")]
5640    pub search: Option<Box<Expression>>,
5641}
5642
5643/// Represent a single Common Table Expression definition.
5644///
5645/// A CTE has a name (`alias`), an optional column list, and a body query.
5646/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5647/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5648/// the expression comes before the alias (`alias_first`).
5649#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5650#[cfg_attr(feature = "bindings", derive(TS))]
5651pub struct Cte {
5652    /// The CTE name.
5653    pub alias: Identifier,
5654    /// The CTE body (typically a SELECT, UNION, etc.).
5655    pub this: Expression,
5656    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5657    pub columns: Vec<Identifier>,
5658    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5659    pub materialized: Option<bool>,
5660    /// USING KEY (columns) for DuckDB recursive CTEs
5661    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5662    pub key_expressions: Vec<Identifier>,
5663    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5664    #[serde(default)]
5665    pub alias_first: bool,
5666    /// Comments associated with this CTE (placed after alias name, before AS)
5667    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5668    pub comments: Vec<String>,
5669}
5670
5671/// Window specification
5672#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5673#[cfg_attr(feature = "bindings", derive(TS))]
5674pub struct WindowSpec {
5675    pub partition_by: Vec<Expression>,
5676    pub order_by: Vec<Ordered>,
5677    pub frame: Option<WindowFrame>,
5678}
5679
5680/// OVER clause
5681#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5682#[cfg_attr(feature = "bindings", derive(TS))]
5683pub struct Over {
5684    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
5685    pub window_name: Option<Identifier>,
5686    pub partition_by: Vec<Expression>,
5687    pub order_by: Vec<Ordered>,
5688    pub frame: Option<WindowFrame>,
5689    pub alias: Option<Identifier>,
5690}
5691
5692/// Window frame
5693#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5694#[cfg_attr(feature = "bindings", derive(TS))]
5695pub struct WindowFrame {
5696    pub kind: WindowFrameKind,
5697    pub start: WindowFrameBound,
5698    pub end: Option<WindowFrameBound>,
5699    pub exclude: Option<WindowFrameExclude>,
5700    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
5701    #[serde(default, skip_serializing_if = "Option::is_none")]
5702    pub kind_text: Option<String>,
5703    /// Original text of the start bound side keyword (e.g. "preceding")
5704    #[serde(default, skip_serializing_if = "Option::is_none")]
5705    pub start_side_text: Option<String>,
5706    /// Original text of the end bound side keyword
5707    #[serde(default, skip_serializing_if = "Option::is_none")]
5708    pub end_side_text: Option<String>,
5709}
5710
5711#[derive(
5712    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5713)]
5714#[cfg_attr(feature = "bindings", derive(TS))]
5715pub enum WindowFrameKind {
5716    Rows,
5717    Range,
5718    Groups,
5719}
5720
5721/// EXCLUDE clause for window frames
5722#[derive(
5723    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5724)]
5725#[cfg_attr(feature = "bindings", derive(TS))]
5726pub enum WindowFrameExclude {
5727    CurrentRow,
5728    Group,
5729    Ties,
5730    NoOthers,
5731}
5732
5733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5734#[cfg_attr(feature = "bindings", derive(TS))]
5735pub enum WindowFrameBound {
5736    CurrentRow,
5737    UnboundedPreceding,
5738    UnboundedFollowing,
5739    Preceding(Box<Expression>),
5740    Following(Box<Expression>),
5741    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
5742    BarePreceding,
5743    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
5744    BareFollowing,
5745    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
5746    Value(Box<Expression>),
5747}
5748
5749/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
5750#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5751#[cfg_attr(feature = "bindings", derive(TS))]
5752pub struct StructField {
5753    /// A raw field name, or a delimited identifier for compatibility with parsed ASTs.
5754    /// Parsed quoted names use double quotes with doubled internal quotes. An empty
5755    /// string denotes an anonymous field. Generation selects the target dialect's quotes.
5756    pub name: String,
5757    pub data_type: DataType,
5758    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5759    pub options: Vec<Expression>,
5760    #[serde(default, skip_serializing_if = "Option::is_none")]
5761    pub comment: Option<String>,
5762}
5763
5764impl StructField {
5765    /// Create a new struct field without options
5766    pub fn new(name: String, data_type: DataType) -> Self {
5767        Self {
5768            name,
5769            data_type,
5770            options: Vec::new(),
5771            comment: None,
5772        }
5773    }
5774
5775    /// Create a new struct field with options
5776    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
5777        Self {
5778            name,
5779            data_type,
5780            options,
5781            comment: None,
5782        }
5783    }
5784
5785    /// Create a new struct field with options and comment
5786    pub fn with_options_and_comment(
5787        name: String,
5788        data_type: DataType,
5789        options: Vec<Expression>,
5790        comment: Option<String>,
5791    ) -> Self {
5792        Self {
5793            name,
5794            data_type,
5795            options,
5796            comment,
5797        }
5798    }
5799}
5800
5801/// Oracle-specific data types whose semantics cannot be represented losslessly by the
5802/// generic [`DataType`] variants.
5803///
5804/// Keeping these types structured allows the Oracle parser to retain details such as a
5805/// negative `NUMBER` scale, `BYTE`/`CHAR` length semantics, interval precisions, and
5806/// `TIMESTAMP WITH LOCAL TIME ZONE` until the target dialect is known.
5807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5808#[cfg_attr(feature = "bindings", derive(TS))]
5809#[serde(tag = "oracle_data_type", rename_all = "snake_case")]
5810pub enum OracleDataType {
5811    Number {
5812        precision: Option<u32>,
5813        scale: Option<i32>,
5814    },
5815    BinaryFloat,
5816    BinaryDouble,
5817    Float {
5818        precision: Option<u32>,
5819    },
5820    Character {
5821        kind: OracleCharacterKind,
5822        length: Option<u32>,
5823        semantics: Option<OracleCharacterLengthSemantics>,
5824    },
5825    Date,
5826    Timestamp {
5827        precision: Option<u32>,
5828        timezone: OracleTimestampTimeZone,
5829    },
5830    IntervalYearToMonth {
5831        year_precision: Option<u32>,
5832    },
5833    IntervalDayToSecond {
5834        day_precision: Option<u32>,
5835        fractional_seconds_precision: Option<u32>,
5836    },
5837    Clob {
5838        national: bool,
5839    },
5840    Blob,
5841    Raw {
5842        length: Option<u32>,
5843    },
5844    Long {
5845        raw: bool,
5846    },
5847    RowId,
5848}
5849
5850#[derive(
5851    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5852)]
5853#[cfg_attr(feature = "bindings", derive(TS))]
5854#[serde(rename_all = "snake_case")]
5855pub enum OracleCharacterKind {
5856    Char,
5857    VarChar,
5858    NChar,
5859    NVarChar,
5860}
5861
5862#[derive(
5863    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5864)]
5865#[cfg_attr(feature = "bindings", derive(TS))]
5866#[serde(rename_all = "snake_case")]
5867pub enum OracleCharacterLengthSemantics {
5868    Byte,
5869    Char,
5870}
5871
5872#[derive(
5873    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5874)]
5875#[cfg_attr(feature = "bindings", derive(TS))]
5876#[serde(rename_all = "snake_case")]
5877pub enum OracleTimestampTimeZone {
5878    None,
5879    WithTimeZone,
5880    WithLocalTimeZone,
5881}
5882
5883/// Enumerate all SQL data types recognized by the parser.
5884///
5885/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
5886/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
5887/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
5888///
5889/// This enum is used in CAST expressions, column definitions, function return
5890/// types, and anywhere a data type specification appears in SQL.
5891///
5892/// Types that do not match any known variant fall through to `Custom { name }`,
5893/// preserving the original type name for round-trip fidelity.
5894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5895#[cfg_attr(feature = "bindings", derive(TS))]
5896#[serde(tag = "data_type", rename_all = "snake_case")]
5897pub enum DataType {
5898    // Numeric
5899    Boolean,
5900    TinyInt {
5901        length: Option<u32>,
5902    },
5903    SmallInt {
5904        length: Option<u32>,
5905    },
5906    /// Int type with optional length. `integer_spelling` indicates whether the original
5907    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
5908    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
5909    Int {
5910        length: Option<u32>,
5911        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5912        integer_spelling: bool,
5913    },
5914    BigInt {
5915        length: Option<u32>,
5916    },
5917    /// Signed 128-bit integer (DuckDB HUGEINT, ClickHouse Int128, StarRocks LARGEINT).
5918    Int128,
5919    /// Unsigned 8-bit integer (DuckDB UTINYINT, ClickHouse UInt8).
5920    #[serde(rename = "uint8")]
5921    UInt8,
5922    /// Unsigned 16-bit integer (DuckDB USMALLINT, ClickHouse UInt16).
5923    #[serde(rename = "uint16")]
5924    UInt16,
5925    /// Unsigned 32-bit integer (DuckDB UINTEGER, ClickHouse UInt32).
5926    #[serde(rename = "uint32")]
5927    UInt32,
5928    /// Unsigned 64-bit integer (DuckDB UBIGINT, ClickHouse UInt64).
5929    #[serde(rename = "uint64")]
5930    UInt64,
5931    /// Unsigned 128-bit integer (DuckDB UHUGEINT, ClickHouse UInt128).
5932    #[serde(rename = "uint128")]
5933    UInt128,
5934    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
5935    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
5936    /// preserve the original spelling.
5937    Float {
5938        precision: Option<u32>,
5939        scale: Option<u32>,
5940        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5941        real_spelling: bool,
5942    },
5943    Double {
5944        precision: Option<u32>,
5945        scale: Option<u32>,
5946    },
5947    Decimal {
5948        precision: Option<u32>,
5949        scale: Option<u32>,
5950    },
5951    /// Structured Oracle data type retained until the target dialect is known.
5952    Oracle {
5953        oracle_type: OracleDataType,
5954    },
5955
5956    // String
5957    Char {
5958        length: Option<u32>,
5959    },
5960    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
5961    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
5962    VarChar {
5963        length: Option<u32>,
5964        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5965        parenthesized_length: bool,
5966    },
5967    /// String type with optional max length (BigQuery STRING(n))
5968    String {
5969        length: Option<u32>,
5970    },
5971    Text,
5972    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
5973    TextWithLength {
5974        length: u32,
5975    },
5976
5977    // Binary
5978    Binary {
5979        length: Option<u32>,
5980    },
5981    VarBinary {
5982        length: Option<u32>,
5983    },
5984    Blob,
5985
5986    // Bit
5987    Bit {
5988        length: Option<u32>,
5989    },
5990    VarBit {
5991        length: Option<u32>,
5992    },
5993
5994    // Date/Time
5995    Date,
5996    Time {
5997        precision: Option<u32>,
5998        #[serde(default)]
5999        timezone: bool,
6000    },
6001    Timestamp {
6002        precision: Option<u32>,
6003        timezone: bool,
6004    },
6005    Interval {
6006        unit: Option<String>,
6007        /// For range intervals like INTERVAL DAY TO HOUR
6008        #[serde(default, skip_serializing_if = "Option::is_none")]
6009        to: Option<String>,
6010    },
6011
6012    // JSON
6013    Json,
6014    JsonB,
6015
6016    // UUID
6017    Uuid,
6018
6019    // Array
6020    Array {
6021        element_type: Box<DataType>,
6022        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
6023        #[serde(default, skip_serializing_if = "Option::is_none")]
6024        dimension: Option<u32>,
6025    },
6026
6027    /// List type (Materialize): INT LIST, TEXT LIST LIST
6028    /// Uses postfix LIST syntax instead of ARRAY<T>
6029    List {
6030        element_type: Box<DataType>,
6031    },
6032
6033    // Struct/Map
6034    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
6035    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
6036    Struct {
6037        fields: Vec<StructField>,
6038        nested: bool,
6039    },
6040    Map {
6041        key_type: Box<DataType>,
6042        value_type: Box<DataType>,
6043    },
6044
6045    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
6046    Enum {
6047        values: Vec<String>,
6048        #[serde(default, skip_serializing_if = "Vec::is_empty")]
6049        assignments: Vec<Option<String>>,
6050    },
6051
6052    // Set type (MySQL): SET('a', 'b', 'c')
6053    Set {
6054        values: Vec<String>,
6055    },
6056
6057    // Union type (DuckDB): UNION(num INT, str TEXT)
6058    Union {
6059        fields: Vec<(String, DataType)>,
6060    },
6061
6062    // Vector (Snowflake / SingleStore)
6063    Vector {
6064        #[serde(default)]
6065        element_type: Option<Box<DataType>>,
6066        dimension: Option<u32>,
6067    },
6068
6069    // Object (Snowflake structured type)
6070    // fields: Vec of (field_name, field_type, not_null)
6071    Object {
6072        fields: Vec<(String, DataType, bool)>,
6073        modifier: Option<String>,
6074    },
6075
6076    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
6077    Nullable {
6078        inner: Box<DataType>,
6079    },
6080
6081    // Custom/User-defined
6082    Custom {
6083        name: String,
6084    },
6085
6086    // Spatial types
6087    Geometry {
6088        subtype: Option<String>,
6089        srid: Option<u32>,
6090    },
6091    Geography {
6092        subtype: Option<String>,
6093        srid: Option<u32>,
6094    },
6095
6096    // Character Set (for CONVERT USING in MySQL)
6097    // Renders as CHAR CHARACTER SET {name} in cast target
6098    CharacterSet {
6099        name: String,
6100    },
6101
6102    // Unknown
6103    Unknown,
6104}
6105
6106impl DataType {
6107    /// Canonical unsigned names and their bit-width aliases. Parser entry points
6108    /// and legacy Custom-type normalization share this mapping.
6109    pub(crate) fn from_unsigned_name(name: &str) -> Option<Self> {
6110        match name.to_ascii_uppercase().as_str() {
6111            "UTINYINT" | "UINT8" => Some(Self::UInt8),
6112            "USMALLINT" | "UINT16" => Some(Self::UInt16),
6113            "UINTEGER" | "UINT32" => Some(Self::UInt32),
6114            "UBIGINT" | "UINT64" => Some(Self::UInt64),
6115            "UHUGEINT" | "UINT128" => Some(Self::UInt128),
6116            _ => None,
6117        }
6118    }
6119}
6120
6121/// Array expression
6122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6123#[cfg_attr(feature = "bindings", derive(TS))]
6124#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
6125pub struct Array {
6126    pub expressions: Vec<Expression>,
6127    /// Inferred array data type from type annotation
6128    #[serde(default, skip_serializing_if = "Option::is_none")]
6129    #[ast(skip)]
6130    pub inferred_type: Option<DataType>,
6131}
6132
6133/// Struct expression
6134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6135#[cfg_attr(feature = "bindings", derive(TS))]
6136pub struct Struct {
6137    pub fields: Vec<(Option<String>, Expression)>,
6138}
6139
6140/// Tuple expression
6141#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6142#[cfg_attr(feature = "bindings", derive(TS))]
6143pub struct Tuple {
6144    pub expressions: Vec<Expression>,
6145}
6146
6147/// Interval expression
6148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6149#[cfg_attr(feature = "bindings", derive(TS))]
6150pub struct Interval {
6151    /// The value expression (e.g., '1', 5, column_ref)
6152    pub this: Option<Expression>,
6153    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
6154    pub unit: Option<IntervalUnitSpec>,
6155}
6156
6157/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
6158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6159#[cfg_attr(feature = "bindings", derive(TS))]
6160#[serde(tag = "type", rename_all = "snake_case")]
6161pub enum IntervalUnitSpec {
6162    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
6163    Simple {
6164        unit: IntervalUnit,
6165        /// Whether to use plural form (e.g., DAYS vs DAY)
6166        use_plural: bool,
6167    },
6168    /// Interval span (e.g., HOUR TO SECOND)
6169    Span(IntervalSpan),
6170    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6171    /// The start and end can be expressions like function calls with precision
6172    ExprSpan(IntervalSpanExpr),
6173    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6174    Expr(Box<Expression>),
6175}
6176
6177/// Interval span for ranges like HOUR TO SECOND
6178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6179#[cfg_attr(feature = "bindings", derive(TS))]
6180pub struct IntervalSpan {
6181    /// Start unit (e.g., HOUR)
6182    pub this: IntervalUnit,
6183    /// End unit (e.g., SECOND)
6184    pub expression: IntervalUnit,
6185}
6186
6187/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6188/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6190#[cfg_attr(feature = "bindings", derive(TS))]
6191pub struct IntervalSpanExpr {
6192    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6193    pub this: Box<Expression>,
6194    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6195    pub expression: Box<Expression>,
6196}
6197
6198#[derive(
6199    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6200)]
6201#[cfg_attr(feature = "bindings", derive(TS))]
6202pub enum IntervalUnit {
6203    Year,
6204    Quarter,
6205    Month,
6206    Week,
6207    Day,
6208    Hour,
6209    Minute,
6210    Second,
6211    Millisecond,
6212    Microsecond,
6213    Nanosecond,
6214}
6215
6216/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6217#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6218#[cfg_attr(feature = "bindings", derive(TS))]
6219pub struct Command {
6220    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6221    pub this: String,
6222}
6223
6224/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6225/// Syntax: PREPARE name [(type, ...)] AS statement
6226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6227#[cfg_attr(feature = "bindings", derive(TS))]
6228pub struct PrepareStatement {
6229    /// The prepared statement name.
6230    pub name: Identifier,
6231    /// Optional PostgreSQL parameter type list.
6232    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6233    pub parameter_types: Vec<DataType>,
6234    /// The statement to execute when the prepared statement is invoked.
6235    pub statement: Expression,
6236}
6237
6238/// T-SQL TRY/CATCH block.
6239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6240#[cfg_attr(feature = "bindings", derive(TS))]
6241pub struct TryCatch {
6242    /// Statements inside BEGIN TRY ... END TRY.
6243    #[serde(default)]
6244    pub try_body: Vec<Expression>,
6245    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6246    #[serde(default, skip_serializing_if = "Option::is_none")]
6247    pub catch_body: Option<Vec<Expression>>,
6248}
6249
6250/// EXEC/EXECUTE statement (TSQL stored procedure call)
6251/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6252#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6253#[cfg_attr(feature = "bindings", derive(TS))]
6254pub struct ExecuteStatement {
6255    /// The procedure name (can be qualified: schema.proc_name)
6256    pub this: Expression,
6257    /// Optional T-SQL return-status variable (`EXECUTE @status = procedure`).
6258    #[serde(default, skip_serializing_if = "Option::is_none")]
6259    pub return_status: Option<String>,
6260    /// Named parameters: @param=value pairs
6261    #[serde(default)]
6262    pub parameters: Vec<ExecuteParameter>,
6263    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6264    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6265    pub arguments: Vec<Expression>,
6266    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6267    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6268    pub prepared: bool,
6269    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6270    #[serde(default, skip_serializing_if = "Option::is_none")]
6271    pub suffix: Option<String>,
6272}
6273
6274/// Named parameter in EXEC statement: @name=value
6275#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6276#[cfg_attr(feature = "bindings", derive(TS))]
6277pub struct ExecuteParameter {
6278    /// Parameter name (including @)
6279    pub name: String,
6280    /// Parameter value
6281    pub value: Expression,
6282    /// Whether this is a positional parameter (no = sign)
6283    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6284    pub positional: bool,
6285    /// TSQL OUTPUT modifier on parameter
6286    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6287    pub output: bool,
6288}
6289
6290/// KILL statement (MySQL/MariaDB)
6291/// KILL [CONNECTION | QUERY] <id>
6292#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6293#[cfg_attr(feature = "bindings", derive(TS))]
6294pub struct Kill {
6295    /// The target (process ID or connection ID)
6296    pub this: Expression,
6297    /// Optional kind: "CONNECTION" or "QUERY"
6298    pub kind: Option<String>,
6299}
6300
6301/// Snowflake CREATE TASK statement
6302#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6303#[cfg_attr(feature = "bindings", derive(TS))]
6304pub struct CreateTask {
6305    pub or_replace: bool,
6306    pub if_not_exists: bool,
6307    /// Task name (possibly qualified: db.schema.task)
6308    pub name: String,
6309    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6310    pub properties: String,
6311    /// The SQL statement body after AS
6312    pub body: Expression,
6313}
6314
6315/// Raw/unparsed SQL
6316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6317#[cfg_attr(feature = "bindings", derive(TS))]
6318pub struct Raw {
6319    pub sql: String,
6320}
6321
6322// ============================================================================
6323// Function expression types
6324// ============================================================================
6325
6326/// Generic unary function (takes a single argument)
6327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6328#[cfg_attr(feature = "bindings", derive(TS))]
6329pub struct UnaryFunc {
6330    pub this: Expression,
6331    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6332    #[serde(skip_serializing_if = "Option::is_none", default)]
6333    pub original_name: Option<String>,
6334    /// Inferred data type from type annotation
6335    #[serde(default, skip_serializing_if = "Option::is_none")]
6336    #[ast(skip)]
6337    pub inferred_type: Option<DataType>,
6338}
6339
6340impl UnaryFunc {
6341    /// Create a new UnaryFunc with no original_name
6342    pub fn new(this: Expression) -> Self {
6343        Self {
6344            this,
6345            original_name: None,
6346            inferred_type: None,
6347        }
6348    }
6349
6350    /// Create a new UnaryFunc with an original name for round-trip preservation
6351    pub fn with_name(this: Expression, name: String) -> Self {
6352        Self {
6353            this,
6354            original_name: Some(name),
6355            inferred_type: None,
6356        }
6357    }
6358}
6359
6360/// CHAR/CHR function with multiple args and optional USING charset
6361/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6362/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6364#[cfg_attr(feature = "bindings", derive(TS))]
6365pub struct CharFunc {
6366    pub args: Vec<Expression>,
6367    #[serde(skip_serializing_if = "Option::is_none", default)]
6368    pub charset: Option<String>,
6369    /// Original function name (CHAR or CHR), defaults to CHAR
6370    #[serde(skip_serializing_if = "Option::is_none", default)]
6371    pub name: Option<String>,
6372}
6373
6374/// Generic binary function (takes two arguments)
6375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6376#[cfg_attr(feature = "bindings", derive(TS))]
6377pub struct BinaryFunc {
6378    pub this: Expression,
6379    pub expression: Expression,
6380    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6381    #[serde(skip_serializing_if = "Option::is_none", default)]
6382    pub original_name: Option<String>,
6383    /// Inferred data type from type annotation
6384    #[serde(default, skip_serializing_if = "Option::is_none")]
6385    #[ast(skip)]
6386    pub inferred_type: Option<DataType>,
6387}
6388
6389/// Variable argument function
6390#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6391#[cfg_attr(feature = "bindings", derive(TS))]
6392pub struct VarArgFunc {
6393    pub expressions: Vec<Expression>,
6394    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6395    #[serde(skip_serializing_if = "Option::is_none", default)]
6396    pub original_name: Option<String>,
6397    /// Inferred data type from type annotation
6398    #[serde(default, skip_serializing_if = "Option::is_none")]
6399    #[ast(skip)]
6400    pub inferred_type: Option<DataType>,
6401}
6402
6403/// CONCAT_WS function
6404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6405#[cfg_attr(feature = "bindings", derive(TS))]
6406pub struct ConcatWs {
6407    pub separator: Expression,
6408    pub expressions: Vec<Expression>,
6409}
6410
6411/// SUBSTRING function
6412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6413#[cfg_attr(feature = "bindings", derive(TS))]
6414pub struct SubstringFunc {
6415    pub this: Expression,
6416    pub start: Expression,
6417    pub length: Option<Expression>,
6418    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6419    #[serde(default)]
6420    pub from_for_syntax: bool,
6421}
6422
6423/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6424#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6425#[cfg_attr(feature = "bindings", derive(TS))]
6426pub struct OverlayFunc {
6427    pub this: Expression,
6428    pub replacement: Expression,
6429    pub from: Expression,
6430    pub length: Option<Expression>,
6431}
6432
6433/// TRIM function
6434#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6435#[cfg_attr(feature = "bindings", derive(TS))]
6436pub struct TrimFunc {
6437    pub this: Expression,
6438    pub characters: Option<Expression>,
6439    pub position: TrimPosition,
6440    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6441    #[serde(default)]
6442    pub sql_standard_syntax: bool,
6443    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6444    #[serde(default)]
6445    pub position_explicit: bool,
6446    /// Inferred data type from type annotation
6447    #[serde(default, skip_serializing_if = "Option::is_none")]
6448    #[ast(skip)]
6449    pub inferred_type: Option<DataType>,
6450}
6451
6452#[derive(
6453    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6454)]
6455#[cfg_attr(feature = "bindings", derive(TS))]
6456pub enum TrimPosition {
6457    Both,
6458    Leading,
6459    Trailing,
6460}
6461
6462/// REPLACE function
6463#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6464#[cfg_attr(feature = "bindings", derive(TS))]
6465pub struct ReplaceFunc {
6466    pub this: Expression,
6467    pub old: Expression,
6468    pub new: Expression,
6469}
6470
6471/// LEFT/RIGHT function
6472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6473#[cfg_attr(feature = "bindings", derive(TS))]
6474pub struct LeftRightFunc {
6475    pub this: Expression,
6476    pub length: Expression,
6477}
6478
6479/// REPEAT function
6480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6481#[cfg_attr(feature = "bindings", derive(TS))]
6482pub struct RepeatFunc {
6483    pub this: Expression,
6484    pub times: Expression,
6485}
6486
6487/// LPAD/RPAD function
6488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6489#[cfg_attr(feature = "bindings", derive(TS))]
6490pub struct PadFunc {
6491    pub this: Expression,
6492    pub length: Expression,
6493    pub fill: Option<Expression>,
6494}
6495
6496/// SPLIT function
6497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6498#[cfg_attr(feature = "bindings", derive(TS))]
6499pub struct SplitFunc {
6500    pub this: Expression,
6501    pub delimiter: Expression,
6502}
6503
6504/// REGEXP_LIKE function
6505#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6506#[cfg_attr(feature = "bindings", derive(TS))]
6507pub struct RegexpFunc {
6508    pub this: Expression,
6509    pub pattern: Expression,
6510    pub flags: Option<Expression>,
6511}
6512
6513/// REGEXP_REPLACE function
6514#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6515#[cfg_attr(feature = "bindings", derive(TS))]
6516pub struct RegexpReplaceFunc {
6517    pub this: Expression,
6518    pub pattern: Expression,
6519    pub replacement: Expression,
6520    pub flags: Option<Expression>,
6521}
6522
6523/// REGEXP_EXTRACT function
6524#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6525#[cfg_attr(feature = "bindings", derive(TS))]
6526pub struct RegexpExtractFunc {
6527    pub this: Expression,
6528    pub pattern: Expression,
6529    pub group: Option<Expression>,
6530}
6531
6532/// ROUND function
6533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6534#[cfg_attr(feature = "bindings", derive(TS))]
6535pub struct RoundFunc {
6536    pub this: Expression,
6537    pub decimals: Option<Expression>,
6538}
6539
6540/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6542#[cfg_attr(feature = "bindings", derive(TS))]
6543pub struct FloorFunc {
6544    pub this: Expression,
6545    pub scale: Option<Expression>,
6546    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6547    #[serde(skip_serializing_if = "Option::is_none", default)]
6548    pub to: Option<Expression>,
6549}
6550
6551/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6553#[cfg_attr(feature = "bindings", derive(TS))]
6554pub struct CeilFunc {
6555    pub this: Expression,
6556    #[serde(skip_serializing_if = "Option::is_none", default)]
6557    pub decimals: Option<Expression>,
6558    /// Time unit for Druid-style CEIL(time TO unit) syntax
6559    #[serde(skip_serializing_if = "Option::is_none", default)]
6560    pub to: Option<Expression>,
6561}
6562
6563/// LOG function
6564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6565#[cfg_attr(feature = "bindings", derive(TS))]
6566pub struct LogFunc {
6567    pub this: Expression,
6568    pub base: Option<Expression>,
6569}
6570
6571/// CURRENT_DATE (no arguments)
6572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6573#[cfg_attr(feature = "bindings", derive(TS))]
6574pub struct CurrentDate;
6575
6576/// CURRENT_TIME
6577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6578#[cfg_attr(feature = "bindings", derive(TS))]
6579pub struct CurrentTime {
6580    pub precision: Option<u32>,
6581}
6582
6583/// CURRENT_TIMESTAMP
6584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6585#[cfg_attr(feature = "bindings", derive(TS))]
6586pub struct CurrentTimestamp {
6587    pub precision: Option<u32>,
6588    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6589    #[serde(default)]
6590    pub sysdate: bool,
6591}
6592
6593/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6594#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6595#[cfg_attr(feature = "bindings", derive(TS))]
6596pub struct CurrentTimestampLTZ {
6597    pub precision: Option<u32>,
6598}
6599
6600/// AT TIME ZONE expression for timezone conversion
6601#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6602#[cfg_attr(feature = "bindings", derive(TS))]
6603pub struct AtTimeZone {
6604    /// The expression to convert
6605    pub this: Expression,
6606    /// The target timezone
6607    pub zone: Expression,
6608}
6609
6610/// DATE_ADD / DATE_SUB function
6611#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6612#[cfg_attr(feature = "bindings", derive(TS))]
6613pub struct DateAddFunc {
6614    pub this: Expression,
6615    pub interval: Expression,
6616    pub unit: IntervalUnit,
6617}
6618
6619/// DATEDIFF function
6620#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6621#[cfg_attr(feature = "bindings", derive(TS))]
6622pub struct DateDiffFunc {
6623    pub this: Expression,
6624    pub expression: Expression,
6625    pub unit: Option<IntervalUnit>,
6626}
6627
6628/// DATE_TRUNC function
6629#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6630#[cfg_attr(feature = "bindings", derive(TS))]
6631pub struct DateTruncFunc {
6632    pub this: Expression,
6633    pub unit: DateTimeField,
6634}
6635
6636/// EXTRACT function
6637#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6638#[cfg_attr(feature = "bindings", derive(TS))]
6639pub struct ExtractFunc {
6640    pub this: Expression,
6641    pub field: DateTimeField,
6642}
6643
6644#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6645#[cfg_attr(feature = "bindings", derive(TS))]
6646pub enum DateTimeField {
6647    Year,
6648    Month,
6649    Day,
6650    Hour,
6651    Minute,
6652    Second,
6653    Millisecond,
6654    Microsecond,
6655    DayOfWeek,
6656    DayOfYear,
6657    Week,
6658    /// Week with a modifier like WEEK(monday), WEEK(sunday)
6659    WeekWithModifier(String),
6660    Quarter,
6661    Epoch,
6662    Timezone,
6663    TimezoneHour,
6664    TimezoneMinute,
6665    Date,
6666    Time,
6667    /// Custom datetime field for dialect-specific or arbitrary fields
6668    Custom(String),
6669}
6670
6671/// TO_DATE function
6672#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6673#[cfg_attr(feature = "bindings", derive(TS))]
6674pub struct ToDateFunc {
6675    pub this: Expression,
6676    pub format: Option<Expression>,
6677}
6678
6679/// TO_TIMESTAMP function
6680#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6681#[cfg_attr(feature = "bindings", derive(TS))]
6682pub struct ToTimestampFunc {
6683    pub this: Expression,
6684    pub format: Option<Expression>,
6685}
6686
6687/// IF function
6688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6689#[cfg_attr(feature = "bindings", derive(TS))]
6690pub struct IfFunc {
6691    pub condition: Expression,
6692    pub true_value: Expression,
6693    pub false_value: Option<Expression>,
6694    /// Original function name (IF, IFF, IIF) for round-trip preservation
6695    #[serde(skip_serializing_if = "Option::is_none", default)]
6696    pub original_name: Option<String>,
6697    /// Inferred data type from type annotation
6698    #[serde(default, skip_serializing_if = "Option::is_none")]
6699    #[ast(skip)]
6700    pub inferred_type: Option<DataType>,
6701}
6702
6703/// NVL2 function
6704#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6705#[cfg_attr(feature = "bindings", derive(TS))]
6706pub struct Nvl2Func {
6707    pub this: Expression,
6708    pub true_value: Expression,
6709    pub false_value: Expression,
6710    /// Inferred data type from type annotation
6711    #[serde(default, skip_serializing_if = "Option::is_none")]
6712    #[ast(skip)]
6713    pub inferred_type: Option<DataType>,
6714}
6715
6716// ============================================================================
6717// Typed Aggregate Function types
6718// ============================================================================
6719
6720/// Generic aggregate function base type
6721#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6722#[cfg_attr(feature = "bindings", derive(TS))]
6723pub struct AggFunc {
6724    pub this: Expression,
6725    pub distinct: bool,
6726    pub filter: Option<Expression>,
6727    pub order_by: Vec<Ordered>,
6728    /// Original function name (case-preserving) when parsed from SQL
6729    #[serde(skip_serializing_if = "Option::is_none", default)]
6730    pub name: Option<String>,
6731    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
6732    #[serde(skip_serializing_if = "Option::is_none", default)]
6733    pub ignore_nulls: Option<bool>,
6734    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
6735    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
6736    #[serde(skip_serializing_if = "Option::is_none", default)]
6737    pub having_max: Option<(Box<Expression>, bool)>,
6738    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
6739    #[serde(skip_serializing_if = "Option::is_none", default)]
6740    pub limit: Option<Box<Expression>>,
6741    /// Inferred data type from type annotation
6742    #[serde(default, skip_serializing_if = "Option::is_none")]
6743    #[ast(skip)]
6744    pub inferred_type: Option<DataType>,
6745}
6746
6747/// COUNT function with optional star
6748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6749#[cfg_attr(feature = "bindings", derive(TS))]
6750pub struct CountFunc {
6751    pub this: Option<Expression>,
6752    pub star: bool,
6753    pub distinct: bool,
6754    pub filter: Option<Expression>,
6755    /// IGNORE NULLS (true) or RESPECT NULLS (false)
6756    #[serde(default, skip_serializing_if = "Option::is_none")]
6757    pub ignore_nulls: Option<bool>,
6758    /// Original function name for case preservation (e.g., "count" or "COUNT")
6759    #[serde(default, skip_serializing_if = "Option::is_none")]
6760    pub original_name: Option<String>,
6761    /// Inferred data type from type annotation
6762    #[serde(default, skip_serializing_if = "Option::is_none")]
6763    #[ast(skip)]
6764    pub inferred_type: Option<DataType>,
6765}
6766
6767/// GROUP_CONCAT function (MySQL style)
6768#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6769#[cfg_attr(feature = "bindings", derive(TS))]
6770pub struct GroupConcatFunc {
6771    pub this: Expression,
6772    pub separator: Option<Expression>,
6773    pub order_by: Option<Vec<Ordered>>,
6774    pub distinct: bool,
6775    pub filter: Option<Expression>,
6776    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
6777    #[serde(default, skip_serializing_if = "Option::is_none")]
6778    pub limit: Option<Box<Expression>>,
6779    /// Inferred data type from type annotation
6780    #[serde(default, skip_serializing_if = "Option::is_none")]
6781    #[ast(skip)]
6782    pub inferred_type: Option<DataType>,
6783}
6784
6785/// STRING_AGG function (PostgreSQL/Standard SQL)
6786#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6787#[cfg_attr(feature = "bindings", derive(TS))]
6788pub struct StringAggFunc {
6789    pub this: Expression,
6790    #[serde(default)]
6791    pub separator: Option<Expression>,
6792    #[serde(default)]
6793    pub order_by: Option<Vec<Ordered>>,
6794    #[serde(default)]
6795    pub distinct: bool,
6796    #[serde(default)]
6797    pub filter: Option<Expression>,
6798    /// BigQuery LIMIT inside STRING_AGG
6799    #[serde(default, skip_serializing_if = "Option::is_none")]
6800    pub limit: Option<Box<Expression>>,
6801    /// Inferred data type from type annotation
6802    #[serde(default, skip_serializing_if = "Option::is_none")]
6803    #[ast(skip)]
6804    pub inferred_type: Option<DataType>,
6805}
6806
6807/// LISTAGG function (Oracle style)
6808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6809#[cfg_attr(feature = "bindings", derive(TS))]
6810pub struct ListAggFunc {
6811    pub this: Expression,
6812    pub separator: Option<Expression>,
6813    pub on_overflow: Option<ListAggOverflow>,
6814    pub order_by: Option<Vec<Ordered>>,
6815    pub distinct: bool,
6816    pub filter: Option<Expression>,
6817    /// Inferred data type from type annotation
6818    #[serde(default, skip_serializing_if = "Option::is_none")]
6819    #[ast(skip)]
6820    pub inferred_type: Option<DataType>,
6821}
6822
6823/// LISTAGG ON OVERFLOW behavior
6824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6825#[cfg_attr(feature = "bindings", derive(TS))]
6826pub enum ListAggOverflow {
6827    Error,
6828    Truncate {
6829        filler: Option<Expression>,
6830        with_count: bool,
6831    },
6832}
6833
6834/// SUM_IF / COUNT_IF function
6835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6836#[cfg_attr(feature = "bindings", derive(TS))]
6837pub struct SumIfFunc {
6838    pub this: Expression,
6839    pub condition: Expression,
6840    pub filter: Option<Expression>,
6841    /// Inferred data type from type annotation
6842    #[serde(default, skip_serializing_if = "Option::is_none")]
6843    #[ast(skip)]
6844    pub inferred_type: Option<DataType>,
6845}
6846
6847/// APPROX_PERCENTILE function
6848#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6849#[cfg_attr(feature = "bindings", derive(TS))]
6850pub struct ApproxPercentileFunc {
6851    pub this: Expression,
6852    pub percentile: Expression,
6853    pub accuracy: Option<Expression>,
6854    pub filter: Option<Expression>,
6855}
6856
6857/// PERCENTILE_CONT / PERCENTILE_DISC function
6858#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6859#[cfg_attr(feature = "bindings", derive(TS))]
6860pub struct PercentileFunc {
6861    pub this: Expression,
6862    pub percentile: Expression,
6863    pub order_by: Option<Vec<Ordered>>,
6864    pub filter: Option<Expression>,
6865}
6866
6867// ============================================================================
6868// Typed Window Function types
6869// ============================================================================
6870
6871/// ROW_NUMBER function (no arguments)
6872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6873#[cfg_attr(feature = "bindings", derive(TS))]
6874pub struct RowNumber;
6875
6876/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6877#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6878#[cfg_attr(feature = "bindings", derive(TS))]
6879pub struct Rank {
6880    /// DuckDB: RANK(ORDER BY col) - order by inside function
6881    #[serde(default, skip_serializing_if = "Option::is_none")]
6882    pub order_by: Option<Vec<Ordered>>,
6883    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6884    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6885    pub args: Vec<Expression>,
6886}
6887
6888/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
6889#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6890#[cfg_attr(feature = "bindings", derive(TS))]
6891pub struct DenseRank {
6892    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6893    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6894    pub args: Vec<Expression>,
6895}
6896
6897/// NTILE function (DuckDB allows ORDER BY inside)
6898#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6899#[cfg_attr(feature = "bindings", derive(TS))]
6900pub struct NTileFunc {
6901    /// num_buckets is optional to support Databricks NTILE() without arguments
6902    #[serde(default, skip_serializing_if = "Option::is_none")]
6903    pub num_buckets: Option<Expression>,
6904    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
6905    #[serde(default, skip_serializing_if = "Option::is_none")]
6906    pub order_by: Option<Vec<Ordered>>,
6907}
6908
6909/// LEAD / LAG function
6910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6911#[cfg_attr(feature = "bindings", derive(TS))]
6912pub struct LeadLagFunc {
6913    pub this: Expression,
6914    pub offset: Option<Expression>,
6915    pub default: Option<Expression>,
6916    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6917    #[serde(default, skip_serializing_if = "Option::is_none")]
6918    pub ignore_nulls: Option<bool>,
6919}
6920
6921/// FIRST_VALUE / LAST_VALUE function
6922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6923#[cfg_attr(feature = "bindings", derive(TS))]
6924pub struct ValueFunc {
6925    pub this: Expression,
6926    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6927    #[serde(default, skip_serializing_if = "Option::is_none")]
6928    pub ignore_nulls: Option<bool>,
6929    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
6930    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6931    pub order_by: Vec<Ordered>,
6932}
6933
6934/// NTH_VALUE function
6935#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6936#[cfg_attr(feature = "bindings", derive(TS))]
6937pub struct NthValueFunc {
6938    pub this: Expression,
6939    pub offset: Expression,
6940    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
6941    #[serde(default, skip_serializing_if = "Option::is_none")]
6942    pub ignore_nulls: Option<bool>,
6943    /// Snowflake FROM FIRST / FROM LAST clause
6944    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
6945    #[serde(default, skip_serializing_if = "Option::is_none")]
6946    pub from_first: Option<bool>,
6947}
6948
6949/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6951#[cfg_attr(feature = "bindings", derive(TS))]
6952pub struct PercentRank {
6953    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
6954    #[serde(default, skip_serializing_if = "Option::is_none")]
6955    pub order_by: Option<Vec<Ordered>>,
6956    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6957    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6958    pub args: Vec<Expression>,
6959}
6960
6961/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
6962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6963#[cfg_attr(feature = "bindings", derive(TS))]
6964pub struct CumeDist {
6965    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
6966    #[serde(default, skip_serializing_if = "Option::is_none")]
6967    pub order_by: Option<Vec<Ordered>>,
6968    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
6969    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6970    pub args: Vec<Expression>,
6971}
6972
6973// ============================================================================
6974// Additional String Function types
6975// ============================================================================
6976
6977/// POSITION/INSTR function
6978#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6979#[cfg_attr(feature = "bindings", derive(TS))]
6980pub struct PositionFunc {
6981    pub substring: Expression,
6982    pub string: Expression,
6983    pub start: Option<Expression>,
6984}
6985
6986// ============================================================================
6987// Additional Math Function types
6988// ============================================================================
6989
6990/// RANDOM function (no arguments)
6991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6992#[cfg_attr(feature = "bindings", derive(TS))]
6993pub struct Random;
6994
6995/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
6996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6997#[cfg_attr(feature = "bindings", derive(TS))]
6998pub struct Rand {
6999    pub seed: Option<Box<Expression>>,
7000    /// Teradata RANDOM lower bound
7001    #[serde(default)]
7002    pub lower: Option<Box<Expression>>,
7003    /// Teradata RANDOM upper bound
7004    #[serde(default)]
7005    pub upper: Option<Box<Expression>>,
7006}
7007
7008/// TRUNCATE / TRUNC function
7009#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7010#[cfg_attr(feature = "bindings", derive(TS))]
7011pub struct TruncateFunc {
7012    pub this: Expression,
7013    pub decimals: Option<Expression>,
7014}
7015
7016/// PI function (no arguments)
7017#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7018#[cfg_attr(feature = "bindings", derive(TS))]
7019pub struct Pi;
7020
7021// ============================================================================
7022// Control Flow Function types
7023// ============================================================================
7024
7025/// DECODE function (Oracle style)
7026#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7027#[cfg_attr(feature = "bindings", derive(TS))]
7028pub struct DecodeFunc {
7029    pub this: Expression,
7030    pub search_results: Vec<(Expression, Expression)>,
7031    pub default: Option<Expression>,
7032}
7033
7034// ============================================================================
7035// Additional Date/Time Function types
7036// ============================================================================
7037
7038/// DATE_FORMAT / FORMAT_DATE function
7039#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7040#[cfg_attr(feature = "bindings", derive(TS))]
7041pub struct DateFormatFunc {
7042    pub this: Expression,
7043    pub format: Expression,
7044}
7045
7046/// FROM_UNIXTIME function
7047#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7048#[cfg_attr(feature = "bindings", derive(TS))]
7049pub struct FromUnixtimeFunc {
7050    pub this: Expression,
7051    pub format: Option<Expression>,
7052}
7053
7054/// UNIX_TIMESTAMP function
7055#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7056#[cfg_attr(feature = "bindings", derive(TS))]
7057pub struct UnixTimestampFunc {
7058    pub this: Option<Expression>,
7059    pub format: Option<Expression>,
7060}
7061
7062/// MAKE_DATE function
7063#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7064#[cfg_attr(feature = "bindings", derive(TS))]
7065pub struct MakeDateFunc {
7066    pub year: Expression,
7067    pub month: Expression,
7068    pub day: Expression,
7069}
7070
7071/// MAKE_TIMESTAMP function
7072#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7073#[cfg_attr(feature = "bindings", derive(TS))]
7074pub struct MakeTimestampFunc {
7075    pub year: Expression,
7076    pub month: Expression,
7077    pub day: Expression,
7078    pub hour: Expression,
7079    pub minute: Expression,
7080    pub second: Expression,
7081    pub timezone: Option<Expression>,
7082}
7083
7084/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
7085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7086#[cfg_attr(feature = "bindings", derive(TS))]
7087pub struct LastDayFunc {
7088    pub this: Expression,
7089    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
7090    #[serde(skip_serializing_if = "Option::is_none", default)]
7091    pub unit: Option<DateTimeField>,
7092}
7093
7094// ============================================================================
7095// Array Function types
7096// ============================================================================
7097
7098/// ARRAY constructor
7099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7100#[cfg_attr(feature = "bindings", derive(TS))]
7101pub struct ArrayConstructor {
7102    pub expressions: Vec<Expression>,
7103    pub bracket_notation: bool,
7104    /// True if LIST keyword was used instead of ARRAY (DuckDB)
7105    pub use_list_keyword: bool,
7106    /// Inferred array data type from type annotation
7107    #[serde(default, skip_serializing_if = "Option::is_none")]
7108    #[ast(skip)]
7109    pub inferred_type: Option<DataType>,
7110}
7111
7112/// ARRAY_SORT function
7113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7114#[cfg_attr(feature = "bindings", derive(TS))]
7115pub struct ArraySortFunc {
7116    pub this: Expression,
7117    pub comparator: Option<Expression>,
7118    pub desc: bool,
7119    pub nulls_first: Option<bool>,
7120}
7121
7122/// ARRAY_JOIN / ARRAY_TO_STRING function
7123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7124#[cfg_attr(feature = "bindings", derive(TS))]
7125pub struct ArrayJoinFunc {
7126    pub this: Expression,
7127    pub separator: Expression,
7128    pub null_replacement: Option<Expression>,
7129}
7130
7131/// UNNEST function
7132#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7133#[cfg_attr(feature = "bindings", derive(TS))]
7134pub struct UnnestFunc {
7135    pub this: Expression,
7136    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
7137    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7138    pub expressions: Vec<Expression>,
7139    pub with_ordinality: bool,
7140    pub alias: Option<Identifier>,
7141    /// BigQuery: offset alias for WITH OFFSET AS <name>
7142    #[serde(default, skip_serializing_if = "Option::is_none")]
7143    pub offset_alias: Option<Identifier>,
7144    /// Inferred type of the first UNNEST output column.
7145    #[serde(default, skip_serializing_if = "Option::is_none")]
7146    #[ast(skip)]
7147    pub inferred_type: Option<DataType>,
7148}
7149
7150/// ARRAY_FILTER function (with lambda)
7151#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7152#[cfg_attr(feature = "bindings", derive(TS))]
7153pub struct ArrayFilterFunc {
7154    pub this: Expression,
7155    pub filter: Expression,
7156}
7157
7158/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
7159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7160#[cfg_attr(feature = "bindings", derive(TS))]
7161pub struct ArrayTransformFunc {
7162    pub this: Expression,
7163    pub transform: Expression,
7164}
7165
7166/// SEQUENCE / GENERATE_SERIES function
7167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7168#[cfg_attr(feature = "bindings", derive(TS))]
7169pub struct SequenceFunc {
7170    pub start: Expression,
7171    pub stop: Expression,
7172    pub step: Option<Expression>,
7173}
7174
7175// ============================================================================
7176// Struct Function types
7177// ============================================================================
7178
7179/// STRUCT constructor
7180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7181#[cfg_attr(feature = "bindings", derive(TS))]
7182pub struct StructConstructor {
7183    pub fields: Vec<(Option<Identifier>, Expression)>,
7184}
7185
7186/// STRUCT_EXTRACT function
7187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7188#[cfg_attr(feature = "bindings", derive(TS))]
7189pub struct StructExtractFunc {
7190    pub this: Expression,
7191    pub field: Identifier,
7192}
7193
7194/// NAMED_STRUCT function
7195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7196#[cfg_attr(feature = "bindings", derive(TS))]
7197pub struct NamedStructFunc {
7198    pub pairs: Vec<(Expression, Expression)>,
7199}
7200
7201// ============================================================================
7202// Map Function types
7203// ============================================================================
7204
7205/// MAP constructor
7206#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7207#[cfg_attr(feature = "bindings", derive(TS))]
7208pub struct MapConstructor {
7209    pub keys: Vec<Expression>,
7210    pub values: Vec<Expression>,
7211    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7212    #[serde(default)]
7213    pub curly_brace_syntax: bool,
7214    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7215    #[serde(default)]
7216    pub with_map_keyword: bool,
7217}
7218
7219/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7220#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7221#[cfg_attr(feature = "bindings", derive(TS))]
7222pub struct TransformFunc {
7223    pub this: Expression,
7224    pub transform: Expression,
7225}
7226
7227/// Function call with EMITS clause (Exasol)
7228/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7229#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7230#[cfg_attr(feature = "bindings", derive(TS))]
7231pub struct FunctionEmits {
7232    /// The function call expression
7233    pub this: Expression,
7234    /// The EMITS schema definition
7235    pub emits: Expression,
7236}
7237
7238// ============================================================================
7239// JSON Function types
7240// ============================================================================
7241
7242/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7243#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7244#[cfg_attr(feature = "bindings", derive(TS))]
7245pub struct JsonExtractFunc {
7246    pub this: Expression,
7247    pub path: Expression,
7248    pub returning: Option<DataType>,
7249    /// True if parsed from -> or ->> operator syntax
7250    #[serde(default)]
7251    pub arrow_syntax: bool,
7252    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7253    #[serde(default)]
7254    pub hash_arrow_syntax: bool,
7255    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7256    #[serde(default)]
7257    pub wrapper_option: Option<String>,
7258    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7259    #[serde(default)]
7260    pub quotes_option: Option<String>,
7261    /// ON SCALAR STRING flag
7262    #[serde(default)]
7263    pub on_scalar_string: bool,
7264    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7265    #[serde(default)]
7266    pub on_error: Option<String>,
7267}
7268
7269/// JSON path extraction
7270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7271#[cfg_attr(feature = "bindings", derive(TS))]
7272pub struct JsonPathFunc {
7273    pub this: Expression,
7274    pub paths: Vec<Expression>,
7275}
7276
7277/// JSON_OBJECT function
7278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7279#[cfg_attr(feature = "bindings", derive(TS))]
7280pub struct JsonObjectFunc {
7281    pub pairs: Vec<(Expression, Expression)>,
7282    pub null_handling: Option<JsonNullHandling>,
7283    #[serde(default)]
7284    pub with_unique_keys: bool,
7285    #[serde(default)]
7286    pub returning_type: Option<DataType>,
7287    #[serde(default)]
7288    pub format_json: bool,
7289    #[serde(default)]
7290    pub encoding: Option<String>,
7291    /// For JSON_OBJECT(*) syntax
7292    #[serde(default)]
7293    pub star: bool,
7294}
7295
7296/// JSON null handling options
7297#[derive(
7298    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7299)]
7300#[cfg_attr(feature = "bindings", derive(TS))]
7301pub enum JsonNullHandling {
7302    NullOnNull,
7303    AbsentOnNull,
7304}
7305
7306/// JSON_SET / JSON_INSERT function
7307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7308#[cfg_attr(feature = "bindings", derive(TS))]
7309pub struct JsonModifyFunc {
7310    pub this: Expression,
7311    pub path_values: Vec<(Expression, Expression)>,
7312}
7313
7314/// JSON_ARRAYAGG function
7315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7316#[cfg_attr(feature = "bindings", derive(TS))]
7317pub struct JsonArrayAggFunc {
7318    pub this: Expression,
7319    pub order_by: Option<Vec<Ordered>>,
7320    pub null_handling: Option<JsonNullHandling>,
7321    pub filter: Option<Expression>,
7322}
7323
7324/// JSON_OBJECTAGG function
7325#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7326#[cfg_attr(feature = "bindings", derive(TS))]
7327pub struct JsonObjectAggFunc {
7328    pub key: Expression,
7329    pub value: Expression,
7330    pub null_handling: Option<JsonNullHandling>,
7331    pub filter: Option<Expression>,
7332}
7333
7334// ============================================================================
7335// Type Casting Function types
7336// ============================================================================
7337
7338/// CONVERT function (SQL Server style)
7339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7340#[cfg_attr(feature = "bindings", derive(TS))]
7341pub struct ConvertFunc {
7342    pub this: Expression,
7343    pub to: DataType,
7344    pub style: Option<Expression>,
7345}
7346
7347// ============================================================================
7348// Additional Expression types
7349// ============================================================================
7350
7351/// Lambda expression
7352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7353#[cfg_attr(feature = "bindings", derive(TS))]
7354pub struct LambdaExpr {
7355    pub parameters: Vec<Identifier>,
7356    pub body: Expression,
7357    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7358    #[serde(default)]
7359    pub colon: bool,
7360    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7361    /// Maps parameter index to data type
7362    #[serde(default)]
7363    pub parameter_types: Vec<Option<DataType>>,
7364}
7365
7366/// Parameter (parameterized queries)
7367#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7368#[cfg_attr(feature = "bindings", derive(TS))]
7369pub struct Parameter {
7370    pub name: Option<String>,
7371    pub index: Option<u32>,
7372    pub style: ParameterStyle,
7373    /// Whether the name was quoted (e.g., @"x" vs @x)
7374    #[serde(default)]
7375    pub quoted: bool,
7376    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7377    #[serde(default)]
7378    pub string_quoted: bool,
7379    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7380    #[serde(default)]
7381    pub expression: Option<String>,
7382}
7383
7384/// Parameter placeholder styles
7385#[derive(
7386    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7387)]
7388#[cfg_attr(feature = "bindings", derive(TS))]
7389pub enum ParameterStyle {
7390    Question,     // ?
7391    Dollar,       // $1, $2
7392    DollarBrace,  // ${name} (Databricks, Hive template variables)
7393    Brace,        // {name} (Spark/Databricks widget/template variables)
7394    Colon,        // :name
7395    At,           // @name
7396    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7397    DoubleDollar, // $$name
7398    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7399}
7400
7401/// Placeholder expression
7402#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7403#[cfg_attr(feature = "bindings", derive(TS))]
7404pub struct Placeholder {
7405    pub index: Option<u32>,
7406}
7407
7408/// Named argument in function call: name => value or name := value
7409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7410#[cfg_attr(feature = "bindings", derive(TS))]
7411pub struct NamedArgument {
7412    pub name: Identifier,
7413    pub value: Expression,
7414    /// The separator used: `=>`, `:=`, or `=`
7415    pub separator: NamedArgSeparator,
7416}
7417
7418/// Separator style for named arguments
7419#[derive(
7420    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7421)]
7422#[cfg_attr(feature = "bindings", derive(TS))]
7423pub enum NamedArgSeparator {
7424    /// `=>` (standard SQL, Snowflake, BigQuery)
7425    DArrow,
7426    /// `:=` (Oracle, MySQL)
7427    ColonEq,
7428    /// `=` (simple equals, some dialects)
7429    Eq,
7430}
7431
7432/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7433/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7434#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7435#[cfg_attr(feature = "bindings", derive(TS))]
7436pub struct TableArgument {
7437    /// The keyword prefix: "TABLE" or "MODEL"
7438    pub prefix: String,
7439    /// The table/model reference expression
7440    pub this: Expression,
7441}
7442
7443/// SQL Comment preservation
7444#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7445#[cfg_attr(feature = "bindings", derive(TS))]
7446pub struct SqlComment {
7447    pub text: String,
7448    pub is_block: bool,
7449}
7450
7451// ============================================================================
7452// Additional Predicate types
7453// ============================================================================
7454
7455/// SIMILAR TO expression
7456#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7457#[cfg_attr(feature = "bindings", derive(TS))]
7458pub struct SimilarToExpr {
7459    pub this: Expression,
7460    pub pattern: Expression,
7461    pub escape: Option<Expression>,
7462    pub not: bool,
7463}
7464
7465/// ANY / ALL quantified expression
7466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7467#[cfg_attr(feature = "bindings", derive(TS))]
7468pub struct QuantifiedExpr {
7469    pub this: Expression,
7470    pub subquery: Expression,
7471    pub op: Option<QuantifiedOp>,
7472}
7473
7474/// Comparison operator for quantified expressions
7475#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7476#[cfg_attr(feature = "bindings", derive(TS))]
7477pub enum QuantifiedOp {
7478    Eq,
7479    Neq,
7480    Lt,
7481    Lte,
7482    Gt,
7483    Gte,
7484}
7485
7486/// OVERLAPS expression
7487/// Supports two forms:
7488/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7489/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7491#[cfg_attr(feature = "bindings", derive(TS))]
7492pub struct OverlapsExpr {
7493    /// Left operand for simple binary form
7494    #[serde(skip_serializing_if = "Option::is_none")]
7495    pub this: Option<Expression>,
7496    /// Right operand for simple binary form
7497    #[serde(skip_serializing_if = "Option::is_none")]
7498    pub expression: Option<Expression>,
7499    /// Left range start for full ANSI form
7500    #[serde(skip_serializing_if = "Option::is_none")]
7501    pub left_start: Option<Expression>,
7502    /// Left range end for full ANSI form
7503    #[serde(skip_serializing_if = "Option::is_none")]
7504    pub left_end: Option<Expression>,
7505    /// Right range start for full ANSI form
7506    #[serde(skip_serializing_if = "Option::is_none")]
7507    pub right_start: Option<Expression>,
7508    /// Right range end for full ANSI form
7509    #[serde(skip_serializing_if = "Option::is_none")]
7510    pub right_end: Option<Expression>,
7511}
7512
7513// ============================================================================
7514// Array/Struct/Map access
7515// ============================================================================
7516
7517/// Subscript access (array[index] or map[key])
7518#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7519#[cfg_attr(feature = "bindings", derive(TS))]
7520pub struct Subscript {
7521    pub this: Expression,
7522    pub index: Expression,
7523}
7524
7525/// Dot access (struct.field)
7526#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7527#[cfg_attr(feature = "bindings", derive(TS))]
7528pub struct DotAccess {
7529    pub this: Expression,
7530    pub field: Identifier,
7531    #[serde(default, skip_serializing_if = "Option::is_none")]
7532    pub inferred_type: Option<DataType>,
7533}
7534
7535/// Method call (expr.method(args))
7536#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7537#[cfg_attr(feature = "bindings", derive(TS))]
7538pub struct MethodCall {
7539    pub this: Expression,
7540    pub method: Identifier,
7541    pub args: Vec<Expression>,
7542}
7543
7544/// Array slice (array[start:end])
7545#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7546#[cfg_attr(feature = "bindings", derive(TS))]
7547pub struct ArraySlice {
7548    pub this: Expression,
7549    pub start: Option<Expression>,
7550    pub end: Option<Expression>,
7551}
7552
7553// ============================================================================
7554// DDL (Data Definition Language) Statements
7555// ============================================================================
7556
7557/// ON COMMIT behavior for temporary tables
7558#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7559#[cfg_attr(feature = "bindings", derive(TS))]
7560pub enum OnCommit {
7561    /// ON COMMIT PRESERVE ROWS
7562    PreserveRows,
7563    /// ON COMMIT DELETE ROWS
7564    DeleteRows,
7565}
7566
7567/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
7568#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7569#[cfg_attr(feature = "bindings", derive(TS))]
7570pub struct TiDBAutoRandom {
7571    #[serde(default, skip_serializing_if = "Option::is_none")]
7572    pub shard_bits: Option<u64>,
7573    #[serde(default, skip_serializing_if = "Option::is_none")]
7574    pub range_bits: Option<u64>,
7575    /// Whether the attribute was wrapped in a TiDB executable comment.
7576    #[serde(default)]
7577    pub executable_comment: bool,
7578}
7579
7580/// A TiDB-specific table option and its source syntax.
7581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7582#[cfg_attr(feature = "bindings", derive(TS))]
7583pub struct TiDBTableOption {
7584    pub kind: TiDBTableOptionKind,
7585    /// Whether the option was wrapped in a TiDB executable comment.
7586    #[serde(default)]
7587    pub executable_comment: bool,
7588}
7589
7590/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
7591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7592#[cfg_attr(feature = "bindings", derive(TS))]
7593#[serde(tag = "type", rename_all = "snake_case")]
7594pub enum TiDBTableOptionKind {
7595    ShardRowIdBits {
7596        bits: u64,
7597    },
7598    PreSplitRegions {
7599        regions: u64,
7600    },
7601    AutoRandomBase {
7602        value: u64,
7603    },
7604    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
7605    PlacementPolicy {
7606        policy: Option<Identifier>,
7607    },
7608    Ttl {
7609        column: Identifier,
7610        interval: Interval,
7611        #[serde(default, skip_serializing_if = "Option::is_none")]
7612        enabled: Option<bool>,
7613    },
7614    TtlEnable {
7615        enabled: bool,
7616    },
7617    TtlJobInterval {
7618        interval: String,
7619    },
7620}
7621
7622/// CREATE TABLE statement
7623#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7624#[cfg_attr(feature = "bindings", derive(TS))]
7625pub struct CreateTable {
7626    pub name: TableRef,
7627    /// ClickHouse: ON CLUSTER clause for distributed DDL
7628    #[serde(default, skip_serializing_if = "Option::is_none")]
7629    pub on_cluster: Option<OnCluster>,
7630    pub columns: Vec<ColumnDef>,
7631    pub constraints: Vec<TableConstraint>,
7632    pub if_not_exists: bool,
7633    pub temporary: bool,
7634    pub or_replace: bool,
7635    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
7636    #[serde(default, skip_serializing_if = "Option::is_none")]
7637    pub table_modifier: Option<String>,
7638    pub as_select: Option<Expression>,
7639    /// Whether the AS SELECT was wrapped in parentheses
7640    #[serde(default)]
7641    pub as_select_parenthesized: bool,
7642    /// ON COMMIT behavior for temporary tables
7643    #[serde(default)]
7644    pub on_commit: Option<OnCommit>,
7645    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
7646    #[serde(default)]
7647    pub clone_source: Option<TableRef>,
7648    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
7649    #[serde(default, skip_serializing_if = "Option::is_none")]
7650    pub clone_at_clause: Option<Expression>,
7651    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
7652    #[serde(default)]
7653    pub is_copy: bool,
7654    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
7655    #[serde(default)]
7656    pub shallow_clone: bool,
7657    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
7658    #[serde(default)]
7659    pub deep_clone: bool,
7660    /// Leading comments before the statement
7661    #[serde(default)]
7662    pub leading_comments: Vec<String>,
7663    /// WITH properties (e.g., WITH (FORMAT='parquet'))
7664    #[serde(default)]
7665    pub with_properties: Vec<(String, String)>,
7666    /// Teradata: table options after name before columns (comma-separated)
7667    #[serde(default)]
7668    pub teradata_post_name_options: Vec<String>,
7669    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
7670    #[serde(default)]
7671    pub with_data: Option<bool>,
7672    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
7673    #[serde(default)]
7674    pub with_statistics: Option<bool>,
7675    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
7676    #[serde(default)]
7677    pub teradata_indexes: Vec<TeradataIndex>,
7678    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
7679    #[serde(default)]
7680    pub with_cte: Option<With>,
7681    /// Table properties like DEFAULT COLLATE (BigQuery)
7682    #[serde(default)]
7683    pub properties: Vec<Expression>,
7684    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
7685    #[serde(default, skip_serializing_if = "Option::is_none")]
7686    pub partition_of: Option<Expression>,
7687    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
7688    #[serde(default)]
7689    pub post_table_properties: Vec<Expression>,
7690    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
7691    #[serde(default)]
7692    pub mysql_table_options: Vec<(String, String)>,
7693    /// TiDB-specific table options after column definitions.
7694    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7695    pub tidb_table_options: Vec<TiDBTableOption>,
7696    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
7697    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7698    pub inherits: Vec<TableRef>,
7699    /// TSQL ON filegroup or ON filegroup (partition_column) clause
7700    #[serde(default, skip_serializing_if = "Option::is_none")]
7701    pub on_property: Option<OnProperty>,
7702    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
7703    #[serde(default)]
7704    pub copy_grants: bool,
7705    /// Snowflake: USING TEMPLATE expression for schema inference
7706    #[serde(default, skip_serializing_if = "Option::is_none")]
7707    pub using_template: Option<Box<Expression>>,
7708    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
7709    #[serde(default, skip_serializing_if = "Option::is_none")]
7710    pub rollup: Option<RollupProperty>,
7711    /// ClickHouse: UUID 'xxx' clause after table name
7712    #[serde(default, skip_serializing_if = "Option::is_none")]
7713    pub uuid: Option<String>,
7714    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
7715    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
7716    /// could appear in other engines.
7717    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7718    pub with_partition_columns: Vec<ColumnDef>,
7719    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
7720    /// for external tables that reference a Cloud Resource connection.
7721    #[serde(default, skip_serializing_if = "Option::is_none")]
7722    pub with_connection: Option<TableRef>,
7723}
7724
7725/// Teradata index specification for CREATE TABLE
7726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7727#[cfg_attr(feature = "bindings", derive(TS))]
7728pub struct TeradataIndex {
7729    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
7730    pub kind: TeradataIndexKind,
7731    /// Optional index name
7732    pub name: Option<String>,
7733    /// Optional column list
7734    pub columns: Vec<String>,
7735}
7736
7737/// Kind of Teradata index
7738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7739#[cfg_attr(feature = "bindings", derive(TS))]
7740pub enum TeradataIndexKind {
7741    /// NO PRIMARY INDEX
7742    NoPrimary,
7743    /// PRIMARY INDEX
7744    Primary,
7745    /// PRIMARY AMP INDEX
7746    PrimaryAmp,
7747    /// UNIQUE INDEX
7748    Unique,
7749    /// UNIQUE PRIMARY INDEX
7750    UniquePrimary,
7751    /// INDEX (secondary, non-primary)
7752    Secondary,
7753}
7754
7755impl CreateTable {
7756    pub fn new(name: impl Into<String>) -> Self {
7757        Self {
7758            name: TableRef::new(name),
7759            on_cluster: None,
7760            columns: Vec::new(),
7761            constraints: Vec::new(),
7762            if_not_exists: false,
7763            temporary: false,
7764            or_replace: false,
7765            table_modifier: None,
7766            as_select: None,
7767            as_select_parenthesized: false,
7768            on_commit: None,
7769            clone_source: None,
7770            clone_at_clause: None,
7771            shallow_clone: false,
7772            deep_clone: false,
7773            is_copy: false,
7774            leading_comments: Vec::new(),
7775            with_properties: Vec::new(),
7776            teradata_post_name_options: Vec::new(),
7777            with_data: None,
7778            with_statistics: None,
7779            teradata_indexes: Vec::new(),
7780            with_cte: None,
7781            properties: Vec::new(),
7782            partition_of: None,
7783            post_table_properties: Vec::new(),
7784            mysql_table_options: Vec::new(),
7785            tidb_table_options: Vec::new(),
7786            inherits: Vec::new(),
7787            on_property: None,
7788            copy_grants: false,
7789            using_template: None,
7790            rollup: None,
7791            uuid: None,
7792            with_partition_columns: Vec::new(),
7793            with_connection: None,
7794        }
7795    }
7796}
7797
7798/// Sort order for PRIMARY KEY ASC/DESC
7799#[derive(
7800    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
7801)]
7802#[cfg_attr(feature = "bindings", derive(TS))]
7803pub enum SortOrder {
7804    Asc,
7805    Desc,
7806}
7807
7808/// Type of column constraint for tracking order
7809#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7810#[cfg_attr(feature = "bindings", derive(TS))]
7811pub enum ConstraintType {
7812    NotNull,
7813    Null,
7814    PrimaryKey,
7815    Unique,
7816    Default,
7817    AutoIncrement,
7818    AutoRandom,
7819    Collate,
7820    Comment,
7821    References,
7822    Check,
7823    GeneratedAsIdentity,
7824    /// Snowflake: TAG (key='value', ...)
7825    Tags,
7826    /// Computed/generated column
7827    ComputedColumn,
7828    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
7829    GeneratedAsRow,
7830    /// MySQL: ON UPDATE expression
7831    OnUpdate,
7832    /// PATH constraint for XMLTABLE/JSON_TABLE columns
7833    Path,
7834    /// Redshift: ENCODE encoding_type
7835    Encode,
7836}
7837
7838/// Column definition in CREATE TABLE
7839#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7840#[cfg_attr(feature = "bindings", derive(TS))]
7841pub struct ColumnDef {
7842    pub name: Identifier,
7843    pub data_type: DataType,
7844    pub nullable: Option<bool>,
7845    pub default: Option<Expression>,
7846    pub primary_key: bool,
7847    /// Sort order for PRIMARY KEY (ASC/DESC)
7848    #[serde(default)]
7849    pub primary_key_order: Option<SortOrder>,
7850    pub unique: bool,
7851    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
7852    #[serde(default)]
7853    pub unique_nulls_not_distinct: bool,
7854    pub auto_increment: bool,
7855    /// TiDB distributed primary-key allocation attribute.
7856    #[serde(default, skip_serializing_if = "Option::is_none")]
7857    pub auto_random: Option<TiDBAutoRandom>,
7858    pub comment: Option<String>,
7859    pub constraints: Vec<ColumnConstraint>,
7860    /// Track original order of constraints for accurate regeneration
7861    #[serde(default)]
7862    pub constraint_order: Vec<ConstraintType>,
7863    /// Teradata: FORMAT 'pattern'
7864    #[serde(default)]
7865    pub format: Option<String>,
7866    /// Teradata: TITLE 'title'
7867    #[serde(default)]
7868    pub title: Option<String>,
7869    /// Teradata: INLINE LENGTH n
7870    #[serde(default)]
7871    pub inline_length: Option<u64>,
7872    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
7873    #[serde(default)]
7874    pub compress: Option<Vec<Expression>>,
7875    /// Teradata: CHARACTER SET name
7876    #[serde(default)]
7877    pub character_set: Option<String>,
7878    /// Teradata: UPPERCASE
7879    #[serde(default)]
7880    pub uppercase: bool,
7881    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
7882    #[serde(default)]
7883    pub casespecific: Option<bool>,
7884    /// Snowflake: AUTOINCREMENT START value
7885    #[serde(default)]
7886    pub auto_increment_start: Option<Box<Expression>>,
7887    /// Snowflake: AUTOINCREMENT INCREMENT value
7888    #[serde(default)]
7889    pub auto_increment_increment: Option<Box<Expression>>,
7890    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
7891    #[serde(default)]
7892    pub auto_increment_order: Option<bool>,
7893    /// MySQL: UNSIGNED modifier
7894    #[serde(default)]
7895    pub unsigned: bool,
7896    /// MySQL: ZEROFILL modifier
7897    #[serde(default)]
7898    pub zerofill: bool,
7899    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
7900    #[serde(default, skip_serializing_if = "Option::is_none")]
7901    pub on_update: Option<Expression>,
7902    /// MySQL: column VISIBLE/INVISIBLE modifier.
7903    #[serde(default, skip_serializing_if = "Option::is_none")]
7904    pub visible: Option<bool>,
7905    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
7906    #[serde(default, skip_serializing_if = "Option::is_none")]
7907    pub unique_constraint_name: Option<String>,
7908    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
7909    #[serde(default, skip_serializing_if = "Option::is_none")]
7910    pub not_null_constraint_name: Option<String>,
7911    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
7912    #[serde(default, skip_serializing_if = "Option::is_none")]
7913    pub primary_key_constraint_name: Option<String>,
7914    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
7915    #[serde(default, skip_serializing_if = "Option::is_none")]
7916    pub check_constraint_name: Option<String>,
7917    /// BigQuery: OPTIONS (key=value, ...) on column
7918    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7919    pub options: Vec<Expression>,
7920    /// SQLite: Column definition without explicit type
7921    #[serde(default)]
7922    pub no_type: bool,
7923    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
7924    #[serde(default, skip_serializing_if = "Option::is_none")]
7925    pub encoding: Option<String>,
7926    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
7927    #[serde(default, skip_serializing_if = "Option::is_none")]
7928    pub codec: Option<String>,
7929    /// ClickHouse: EPHEMERAL [expr] modifier
7930    #[serde(default, skip_serializing_if = "Option::is_none")]
7931    pub ephemeral: Option<Option<Box<Expression>>>,
7932    /// ClickHouse: MATERIALIZED expr modifier
7933    #[serde(default, skip_serializing_if = "Option::is_none")]
7934    pub materialized_expr: Option<Box<Expression>>,
7935    /// ClickHouse: ALIAS expr modifier
7936    #[serde(default, skip_serializing_if = "Option::is_none")]
7937    pub alias_expr: Option<Box<Expression>>,
7938    /// ClickHouse: TTL expr modifier on columns
7939    #[serde(default, skip_serializing_if = "Option::is_none")]
7940    pub ttl_expr: Option<Box<Expression>>,
7941    /// TSQL: NOT FOR REPLICATION
7942    #[serde(default)]
7943    pub not_for_replication: bool,
7944}
7945
7946impl ColumnDef {
7947    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
7948        Self {
7949            name: Identifier::new(name),
7950            data_type,
7951            nullable: None,
7952            default: None,
7953            primary_key: false,
7954            primary_key_order: None,
7955            unique: false,
7956            unique_nulls_not_distinct: false,
7957            auto_increment: false,
7958            auto_random: None,
7959            comment: None,
7960            constraints: Vec::new(),
7961            constraint_order: Vec::new(),
7962            format: None,
7963            title: None,
7964            inline_length: None,
7965            compress: None,
7966            character_set: None,
7967            uppercase: false,
7968            casespecific: None,
7969            auto_increment_start: None,
7970            auto_increment_increment: None,
7971            auto_increment_order: None,
7972            unsigned: false,
7973            zerofill: false,
7974            on_update: None,
7975            visible: None,
7976            unique_constraint_name: None,
7977            not_null_constraint_name: None,
7978            primary_key_constraint_name: None,
7979            check_constraint_name: None,
7980            options: Vec::new(),
7981            no_type: false,
7982            encoding: None,
7983            codec: None,
7984            ephemeral: None,
7985            materialized_expr: None,
7986            alias_expr: None,
7987            ttl_expr: None,
7988            not_for_replication: false,
7989        }
7990    }
7991}
7992
7993/// Column-level constraint
7994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7995#[cfg_attr(feature = "bindings", derive(TS))]
7996pub enum ColumnConstraint {
7997    NotNull,
7998    Null,
7999    Unique,
8000    PrimaryKey,
8001    Default(Expression),
8002    Check(Expression),
8003    References(ForeignKeyRef),
8004    GeneratedAsIdentity(GeneratedAsIdentity),
8005    Collate(Identifier),
8006    Comment(String),
8007    /// Snowflake: TAG (key='value', ...)
8008    Tags(Tags),
8009    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
8010    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
8011    ComputedColumn(ComputedColumn),
8012    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8013    GeneratedAsRow(GeneratedAsRow),
8014    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
8015    Path(Expression),
8016}
8017
8018/// Computed/generated column constraint
8019#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8020#[cfg_attr(feature = "bindings", derive(TS))]
8021pub struct ComputedColumn {
8022    /// The expression that computes the column value
8023    pub expression: Box<Expression>,
8024    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
8025    #[serde(default)]
8026    pub persisted: bool,
8027    /// NOT NULL (TSQL computed columns)
8028    #[serde(default)]
8029    pub not_null: bool,
8030    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
8031    /// When None, defaults to dialect-appropriate output
8032    #[serde(default)]
8033    pub persistence_kind: Option<String>,
8034    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
8035    #[serde(default, skip_serializing_if = "Option::is_none")]
8036    pub data_type: Option<DataType>,
8037}
8038
8039/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8040#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8041#[cfg_attr(feature = "bindings", derive(TS))]
8042pub struct GeneratedAsRow {
8043    /// true = ROW START, false = ROW END
8044    pub start: bool,
8045    /// HIDDEN modifier
8046    #[serde(default)]
8047    pub hidden: bool,
8048}
8049
8050/// Generated identity column constraint
8051#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8052#[cfg_attr(feature = "bindings", derive(TS))]
8053pub struct GeneratedAsIdentity {
8054    /// True for ALWAYS, False for BY DEFAULT
8055    pub always: bool,
8056    /// ON NULL (only valid with BY DEFAULT)
8057    pub on_null: bool,
8058    /// START WITH value
8059    pub start: Option<Box<Expression>>,
8060    /// INCREMENT BY value
8061    pub increment: Option<Box<Expression>>,
8062    /// MINVALUE
8063    pub minvalue: Option<Box<Expression>>,
8064    /// MAXVALUE
8065    pub maxvalue: Option<Box<Expression>>,
8066    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
8067    pub cycle: Option<bool>,
8068}
8069
8070/// Constraint modifiers (shared between table-level constraints)
8071#[derive(
8072    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
8073)]
8074#[cfg_attr(feature = "bindings", derive(TS))]
8075pub struct ConstraintModifiers {
8076    /// ENFORCED / NOT ENFORCED
8077    pub enforced: Option<bool>,
8078    /// DEFERRABLE / NOT DEFERRABLE
8079    pub deferrable: Option<bool>,
8080    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
8081    pub initially_deferred: Option<bool>,
8082    /// NORELY (Oracle)
8083    pub norely: bool,
8084    /// RELY (Oracle)
8085    pub rely: bool,
8086    /// USING index type (MySQL): BTREE or HASH
8087    #[serde(default)]
8088    pub using: Option<String>,
8089    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
8090    #[serde(default)]
8091    pub using_before_columns: bool,
8092    /// MySQL index COMMENT 'text'
8093    #[serde(default, skip_serializing_if = "Option::is_none")]
8094    pub comment: Option<String>,
8095    /// MySQL index VISIBLE/INVISIBLE
8096    #[serde(default, skip_serializing_if = "Option::is_none")]
8097    pub visible: Option<bool>,
8098    /// MySQL ENGINE_ATTRIBUTE = 'value'
8099    #[serde(default, skip_serializing_if = "Option::is_none")]
8100    pub engine_attribute: Option<String>,
8101    /// MySQL WITH PARSER name
8102    #[serde(default, skip_serializing_if = "Option::is_none")]
8103    pub with_parser: Option<String>,
8104    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
8105    #[serde(default)]
8106    pub not_valid: bool,
8107    /// TSQL CLUSTERED/NONCLUSTERED modifier
8108    #[serde(default, skip_serializing_if = "Option::is_none")]
8109    pub clustered: Option<String>,
8110    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
8111    #[serde(default, skip_serializing_if = "Option::is_none")]
8112    pub on_conflict: Option<String>,
8113    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
8114    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8115    pub with_options: Vec<(String, String)>,
8116    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
8117    #[serde(default, skip_serializing_if = "Option::is_none")]
8118    pub on_filegroup: Option<Identifier>,
8119}
8120
8121/// Table-level constraint
8122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8123#[cfg_attr(feature = "bindings", derive(TS))]
8124pub enum TableConstraint {
8125    PrimaryKey {
8126        name: Option<Identifier>,
8127        columns: Vec<Identifier>,
8128        /// Databricks primary-key columns marked with the TIMESERIES attribute.
8129        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8130        timeseries_columns: Vec<Identifier>,
8131        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
8132        #[serde(default)]
8133        include_columns: Vec<Identifier>,
8134        #[serde(default)]
8135        modifiers: ConstraintModifiers,
8136        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
8137        #[serde(default)]
8138        has_constraint_keyword: bool,
8139    },
8140    Unique {
8141        name: Option<Identifier>,
8142        columns: Vec<Identifier>,
8143        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
8144        #[serde(default)]
8145        columns_parenthesized: bool,
8146        #[serde(default)]
8147        modifiers: ConstraintModifiers,
8148        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
8149        #[serde(default)]
8150        has_constraint_keyword: bool,
8151        /// PostgreSQL 15+: NULLS NOT DISTINCT
8152        #[serde(default)]
8153        nulls_not_distinct: bool,
8154    },
8155    ForeignKey {
8156        name: Option<Identifier>,
8157        columns: Vec<Identifier>,
8158        #[serde(default)]
8159        references: Option<ForeignKeyRef>,
8160        /// ON DELETE action when REFERENCES is absent
8161        #[serde(default)]
8162        on_delete: Option<ReferentialAction>,
8163        /// ON UPDATE action when REFERENCES is absent
8164        #[serde(default)]
8165        on_update: Option<ReferentialAction>,
8166        #[serde(default)]
8167        modifiers: ConstraintModifiers,
8168    },
8169    Check {
8170        name: Option<Identifier>,
8171        expression: Expression,
8172        #[serde(default)]
8173        modifiers: ConstraintModifiers,
8174    },
8175    /// ClickHouse ASSUME constraint (query optimization assumption)
8176    Assume {
8177        name: Option<Identifier>,
8178        expression: Expression,
8179    },
8180    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
8181    Default {
8182        name: Option<Identifier>,
8183        expression: Expression,
8184        column: Identifier,
8185    },
8186    /// INDEX / KEY constraint (MySQL)
8187    Index {
8188        name: Option<Identifier>,
8189        columns: Vec<Identifier>,
8190        /// Expression-capable index key parts. This is used when an index contains
8191        /// functional key parts that cannot be represented by `columns`.
8192        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8193        key_parts: Vec<IndexKeyPart>,
8194        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8195        #[serde(default)]
8196        kind: Option<String>,
8197        #[serde(default)]
8198        modifiers: ConstraintModifiers,
8199        /// True if KEY keyword was used instead of INDEX
8200        #[serde(default)]
8201        use_key_keyword: bool,
8202        /// ClickHouse: indexed expression (instead of columns)
8203        #[serde(default, skip_serializing_if = "Option::is_none")]
8204        expression: Option<Box<Expression>>,
8205        /// ClickHouse: TYPE type_func(args)
8206        #[serde(default, skip_serializing_if = "Option::is_none")]
8207        index_type: Option<Box<Expression>>,
8208        /// ClickHouse: GRANULARITY n
8209        #[serde(default, skip_serializing_if = "Option::is_none")]
8210        granularity: Option<Box<Expression>>,
8211    },
8212    /// ClickHouse PROJECTION definition
8213    Projection {
8214        name: Identifier,
8215        expression: Expression,
8216    },
8217    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8218    Like {
8219        source: TableRef,
8220        /// Options as (INCLUDING|EXCLUDING, property) pairs
8221        options: Vec<(LikeOptionAction, String)>,
8222    },
8223    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8224    PeriodForSystemTime {
8225        start_col: Identifier,
8226        end_col: Identifier,
8227    },
8228    /// PostgreSQL EXCLUDE constraint
8229    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8230    Exclude {
8231        name: Option<Identifier>,
8232        /// Index access method (gist, btree, etc.)
8233        #[serde(default)]
8234        using: Option<String>,
8235        /// Elements: (expression, operator) pairs
8236        elements: Vec<ExcludeElement>,
8237        /// INCLUDE columns
8238        #[serde(default)]
8239        include_columns: Vec<Identifier>,
8240        /// WHERE predicate
8241        #[serde(default)]
8242        where_clause: Option<Box<Expression>>,
8243        /// WITH (storage_parameters)
8244        #[serde(default)]
8245        with_params: Vec<(String, String)>,
8246        /// USING INDEX TABLESPACE tablespace_name
8247        #[serde(default)]
8248        using_index_tablespace: Option<String>,
8249        #[serde(default)]
8250        modifiers: ConstraintModifiers,
8251    },
8252    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8253    Tags(Tags),
8254    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8255    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8256    /// for all deferrable constraints in the table
8257    InitiallyDeferred {
8258        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8259        deferred: bool,
8260    },
8261}
8262
8263/// Element in an EXCLUDE constraint: expression WITH operator
8264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8265#[cfg_attr(feature = "bindings", derive(TS))]
8266pub struct ExcludeElement {
8267    /// The column expression (may include operator class, ordering, nulls)
8268    pub expression: String,
8269    /// The operator (e.g., &&, =)
8270    pub operator: String,
8271}
8272
8273/// Action for LIKE clause options
8274#[derive(
8275    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8276)]
8277#[cfg_attr(feature = "bindings", derive(TS))]
8278pub enum LikeOptionAction {
8279    Including,
8280    Excluding,
8281}
8282
8283/// MATCH type for foreign keys
8284#[derive(
8285    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8286)]
8287#[cfg_attr(feature = "bindings", derive(TS))]
8288pub enum MatchType {
8289    Full,
8290    Partial,
8291    Simple,
8292}
8293
8294/// Foreign key reference
8295#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8296#[cfg_attr(feature = "bindings", derive(TS))]
8297pub struct ForeignKeyRef {
8298    pub table: TableRef,
8299    pub columns: Vec<Identifier>,
8300    pub on_delete: Option<ReferentialAction>,
8301    pub on_update: Option<ReferentialAction>,
8302    /// True if ON UPDATE appears before ON DELETE in the original SQL
8303    #[serde(default)]
8304    pub on_update_first: bool,
8305    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8306    #[serde(default)]
8307    pub match_type: Option<MatchType>,
8308    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8309    #[serde(default)]
8310    pub match_after_actions: bool,
8311    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8312    #[serde(default)]
8313    pub constraint_name: Option<String>,
8314    /// DEFERRABLE / NOT DEFERRABLE
8315    #[serde(default)]
8316    pub deferrable: Option<bool>,
8317    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8318    #[serde(default)]
8319    pub has_foreign_key_keywords: bool,
8320}
8321
8322/// Referential action for foreign keys
8323#[derive(
8324    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8325)]
8326#[cfg_attr(feature = "bindings", derive(TS))]
8327pub enum ReferentialAction {
8328    Cascade,
8329    SetNull,
8330    SetDefault,
8331    Restrict,
8332    NoAction,
8333}
8334
8335/// DROP TABLE statement
8336#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8337#[cfg_attr(feature = "bindings", derive(TS))]
8338pub struct DropTable {
8339    pub names: Vec<TableRef>,
8340    pub if_exists: bool,
8341    pub cascade: bool,
8342    /// Oracle: CASCADE CONSTRAINTS
8343    #[serde(default)]
8344    pub cascade_constraints: bool,
8345    /// Oracle: PURGE
8346    #[serde(default)]
8347    pub purge: bool,
8348    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8349    #[serde(default)]
8350    pub leading_comments: Vec<String>,
8351    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8352    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8353    #[serde(default, skip_serializing_if = "Option::is_none")]
8354    pub object_id_args: Option<String>,
8355    /// ClickHouse: SYNC modifier
8356    #[serde(default)]
8357    pub sync: bool,
8358    /// Snowflake: DROP ICEBERG TABLE
8359    #[serde(default)]
8360    pub iceberg: bool,
8361    /// RESTRICT modifier (opposite of CASCADE)
8362    #[serde(default)]
8363    pub restrict: bool,
8364}
8365
8366impl DropTable {
8367    pub fn new(name: impl Into<String>) -> Self {
8368        Self {
8369            names: vec![TableRef::new(name)],
8370            if_exists: false,
8371            cascade: false,
8372            cascade_constraints: false,
8373            purge: false,
8374            leading_comments: Vec::new(),
8375            object_id_args: None,
8376            sync: false,
8377            iceberg: false,
8378            restrict: false,
8379        }
8380    }
8381}
8382
8383/// UNDROP object statement (Snowflake, ClickHouse)
8384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8385#[cfg_attr(feature = "bindings", derive(TS))]
8386pub struct Undrop {
8387    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8388    pub kind: String,
8389    /// The object name
8390    pub name: TableRef,
8391    /// IF EXISTS clause
8392    #[serde(default)]
8393    pub if_exists: bool,
8394    /// Snowflake: optional RENAME TO target
8395    #[serde(default, skip_serializing_if = "Option::is_none")]
8396    pub rename_to: Option<TableRef>,
8397}
8398
8399/// Partition scope for a TiDB `SPLIT TABLE` statement.
8400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8401#[cfg_attr(feature = "bindings", derive(TS))]
8402#[serde(tag = "type", rename_all = "snake_case")]
8403pub enum SplitTablePartitionScope {
8404    Table,
8405    AllPartitions,
8406    Partitions { names: Vec<Identifier> },
8407}
8408
8409/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8410#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8411#[cfg_attr(feature = "bindings", derive(TS))]
8412#[serde(tag = "type", rename_all = "snake_case")]
8413pub enum SplitTableMode {
8414    Between {
8415        lower: Vec<Expression>,
8416        upper: Vec<Expression>,
8417        regions: u64,
8418    },
8419    By {
8420        points: Vec<Vec<Expression>>,
8421    },
8422}
8423
8424/// TiDB `SPLIT [PARTITION] TABLE` statement.
8425#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8426#[cfg_attr(feature = "bindings", derive(TS))]
8427pub struct SplitTable {
8428    pub table: TableRef,
8429    pub partition_scope: SplitTablePartitionScope,
8430    #[serde(default, skip_serializing_if = "Option::is_none")]
8431    pub index: Option<Identifier>,
8432    pub mode: SplitTableMode,
8433}
8434
8435/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
8436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8437#[cfg_attr(feature = "bindings", derive(TS))]
8438pub struct FlashbackTable {
8439    pub table: TableRef,
8440    #[serde(default, skip_serializing_if = "Option::is_none")]
8441    pub rename_to: Option<Identifier>,
8442}
8443
8444/// ALTER TABLE statement
8445#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8446#[cfg_attr(feature = "bindings", derive(TS))]
8447pub struct AlterTable {
8448    pub name: TableRef,
8449    pub actions: Vec<AlterTableAction>,
8450    /// IF EXISTS clause
8451    #[serde(default)]
8452    pub if_exists: bool,
8453    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8454    #[serde(default, skip_serializing_if = "Option::is_none")]
8455    pub algorithm: Option<String>,
8456    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8457    #[serde(default, skip_serializing_if = "Option::is_none")]
8458    pub lock: Option<String>,
8459    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8460    #[serde(default, skip_serializing_if = "Option::is_none")]
8461    pub with_check: Option<String>,
8462    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8463    #[serde(default, skip_serializing_if = "Option::is_none")]
8464    pub partition: Option<Vec<(Identifier, Expression)>>,
8465    /// ClickHouse: ON CLUSTER clause for distributed DDL
8466    #[serde(default, skip_serializing_if = "Option::is_none")]
8467    pub on_cluster: Option<OnCluster>,
8468    /// Snowflake: ALTER ICEBERG TABLE
8469    #[serde(default, skip_serializing_if = "Option::is_none")]
8470    pub table_modifier: Option<String>,
8471}
8472
8473impl AlterTable {
8474    pub fn new(name: impl Into<String>) -> Self {
8475        Self {
8476            name: TableRef::new(name),
8477            actions: Vec::new(),
8478            if_exists: false,
8479            algorithm: None,
8480            lock: None,
8481            with_check: None,
8482            partition: None,
8483            on_cluster: None,
8484            table_modifier: None,
8485        }
8486    }
8487}
8488
8489/// Column position for ADD COLUMN (MySQL/MariaDB)
8490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8491#[cfg_attr(feature = "bindings", derive(TS))]
8492pub enum ColumnPosition {
8493    First,
8494    After(Identifier),
8495}
8496
8497/// Actions for ALTER TABLE
8498#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8499#[cfg_attr(feature = "bindings", derive(TS))]
8500pub enum AlterTableAction {
8501    AddColumn {
8502        column: ColumnDef,
8503        if_not_exists: bool,
8504        position: Option<ColumnPosition>,
8505    },
8506    DropColumn {
8507        name: Identifier,
8508        if_exists: bool,
8509        cascade: bool,
8510    },
8511    RenameColumn {
8512        old_name: Identifier,
8513        new_name: Identifier,
8514        if_exists: bool,
8515    },
8516    AlterColumn {
8517        name: Identifier,
8518        action: AlterColumnAction,
8519        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8520        #[serde(default)]
8521        use_modify_keyword: bool,
8522    },
8523    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
8524    ModifyColumn {
8525        column: ColumnDef,
8526        if_exists: bool,
8527        position: Option<ColumnPosition>,
8528    },
8529    RenameTable(TableRef),
8530    AddConstraint(TableConstraint),
8531    DropConstraint {
8532        name: Identifier,
8533        if_exists: bool,
8534    },
8535    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8536    DropForeignKey {
8537        name: Identifier,
8538    },
8539    /// DROP PARTITION action (Hive/BigQuery)
8540    DropPartition {
8541        /// List of partitions to drop (each partition is a list of key=value pairs)
8542        partitions: Vec<Vec<(Identifier, Expression)>>,
8543        if_exists: bool,
8544    },
8545    /// ADD PARTITION action (Hive/Spark)
8546    AddPartition {
8547        /// The partition expression
8548        partition: Expression,
8549        if_not_exists: bool,
8550        location: Option<Expression>,
8551    },
8552    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8553    Delete {
8554        where_clause: Expression,
8555    },
8556    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8557    SwapWith(TableRef),
8558    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8559    SetProperty {
8560        properties: Vec<(String, Expression)>,
8561    },
8562    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8563    UnsetProperty {
8564        properties: Vec<String>,
8565    },
8566    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8567    ClusterBy {
8568        expressions: Vec<Expression>,
8569    },
8570    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8571    SetTag {
8572        expressions: Vec<(String, Expression)>,
8573    },
8574    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8575    UnsetTag {
8576        names: Vec<String>,
8577    },
8578    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8579    SetOptions {
8580        expressions: Vec<Expression>,
8581    },
8582    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8583    AlterIndex {
8584        name: Identifier,
8585        visible: bool,
8586    },
8587    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8588    SetAttribute {
8589        attribute: String,
8590    },
8591    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8592    SetStageFileFormat {
8593        options: Option<Expression>,
8594    },
8595    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8596    SetStageCopyOptions {
8597        options: Option<Expression>,
8598    },
8599    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8600    AddColumns {
8601        columns: Vec<ColumnDef>,
8602        cascade: bool,
8603    },
8604    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8605    DropColumns {
8606        names: Vec<Identifier>,
8607    },
8608    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8609    /// In SingleStore, data_type can be omitted for simple column renames
8610    ChangeColumn {
8611        old_name: Identifier,
8612        new_name: Identifier,
8613        #[serde(default, skip_serializing_if = "Option::is_none")]
8614        data_type: Option<DataType>,
8615        comment: Option<String>,
8616        #[serde(default)]
8617        cascade: bool,
8618    },
8619    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
8620    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
8621    AlterSortKey {
8622        /// AUTO or NONE keyword
8623        this: Option<String>,
8624        /// Column list for (col1, col2) syntax
8625        expressions: Vec<Expression>,
8626        /// Whether COMPOUND keyword was present
8627        compound: bool,
8628    },
8629    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
8630    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
8631    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
8632    AlterDistStyle {
8633        /// Distribution style: ALL, EVEN, AUTO, or KEY
8634        style: String,
8635        /// DISTKEY column (only when style is KEY)
8636        distkey: Option<Identifier>,
8637    },
8638    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
8639    SetTableProperties {
8640        properties: Vec<(Expression, Expression)>,
8641    },
8642    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
8643    SetLocation {
8644        location: String,
8645    },
8646    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
8647    SetFileFormat {
8648        format: String,
8649    },
8650    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
8651    ReplacePartition {
8652        partition: Expression,
8653        source: Option<Box<Expression>>,
8654    },
8655    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
8656    SetTiDBTableOption {
8657        option: TiDBTableOption,
8658        #[serde(default)]
8659        force: bool,
8660    },
8661    /// TiDB `REMOVE TTL`.
8662    RemoveTiDBTtl {
8663        #[serde(default)]
8664        executable_comment: bool,
8665    },
8666    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
8667    Raw {
8668        sql: String,
8669    },
8670}
8671
8672/// Actions for ALTER COLUMN
8673#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8674#[cfg_attr(feature = "bindings", derive(TS))]
8675pub enum AlterColumnAction {
8676    SetDataType {
8677        data_type: DataType,
8678        /// USING expression for type conversion (PostgreSQL)
8679        using: Option<Expression>,
8680        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
8681        #[serde(default, skip_serializing_if = "Option::is_none")]
8682        collate: Option<String>,
8683    },
8684    SetDefault(Expression),
8685    DropDefault,
8686    SetNotNull,
8687    DropNotNull,
8688    /// Set column comment
8689    Comment(String),
8690    /// MySQL: SET VISIBLE
8691    SetVisible,
8692    /// MySQL: SET INVISIBLE
8693    SetInvisible,
8694}
8695
8696/// CREATE INDEX statement
8697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8698#[cfg_attr(feature = "bindings", derive(TS))]
8699pub struct CreateIndex {
8700    pub name: Identifier,
8701    pub table: TableRef,
8702    pub columns: Vec<IndexColumn>,
8703    /// Expression-capable index key parts. This is used when an index contains
8704    /// functional key parts that cannot be represented by `columns`.
8705    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8706    pub key_parts: Vec<IndexKeyPart>,
8707    pub unique: bool,
8708    pub if_not_exists: bool,
8709    pub using: Option<String>,
8710    /// TSQL CLUSTERED/NONCLUSTERED modifier
8711    #[serde(default)]
8712    pub clustered: Option<String>,
8713    /// PostgreSQL CONCURRENTLY modifier
8714    #[serde(default)]
8715    pub concurrently: bool,
8716    /// PostgreSQL WHERE clause for partial indexes
8717    #[serde(default)]
8718    pub where_clause: Option<Box<Expression>>,
8719    /// PostgreSQL INCLUDE columns
8720    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8721    pub include_columns: Vec<Identifier>,
8722    /// TSQL WITH options (e.g., allow_page_locks=on)
8723    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8724    pub with_options: Vec<(String, String)>,
8725    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
8726    #[serde(default)]
8727    pub on_filegroup: Option<String>,
8728}
8729
8730impl CreateIndex {
8731    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
8732        Self {
8733            name: Identifier::new(name),
8734            table: TableRef::new(table),
8735            columns: Vec::new(),
8736            key_parts: Vec::new(),
8737            unique: false,
8738            if_not_exists: false,
8739            using: None,
8740            clustered: None,
8741            concurrently: false,
8742            where_clause: None,
8743            include_columns: Vec::new(),
8744            with_options: Vec::new(),
8745            on_filegroup: None,
8746        }
8747    }
8748}
8749
8750/// Index column specification
8751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8752#[cfg_attr(feature = "bindings", derive(TS))]
8753pub struct IndexColumn {
8754    pub column: Identifier,
8755    pub desc: bool,
8756    /// Explicit ASC keyword was present
8757    #[serde(default)]
8758    pub asc: bool,
8759    pub nulls_first: Option<bool>,
8760    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
8761    #[serde(default, skip_serializing_if = "Option::is_none")]
8762    pub opclass: Option<String>,
8763}
8764
8765/// An expression-capable index key part.
8766#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8767#[cfg_attr(feature = "bindings", derive(TS))]
8768pub struct IndexKeyPart {
8769    pub expression: Box<Expression>,
8770    /// MySQL column prefix length, for example the `16` in `name(16)`.
8771    #[serde(default, skip_serializing_if = "Option::is_none")]
8772    pub prefix_length: Option<String>,
8773    pub desc: bool,
8774    /// Explicit ASC keyword was present.
8775    #[serde(default)]
8776    pub asc: bool,
8777    pub nulls_first: Option<bool>,
8778    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops).
8779    #[serde(default, skip_serializing_if = "Option::is_none")]
8780    pub opclass: Option<String>,
8781}
8782
8783/// DROP INDEX statement
8784#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8785#[cfg_attr(feature = "bindings", derive(TS))]
8786pub struct DropIndex {
8787    pub name: TableRef,
8788    pub table: Option<TableRef>,
8789    pub if_exists: bool,
8790    /// PostgreSQL CONCURRENTLY modifier
8791    #[serde(default)]
8792    pub concurrently: bool,
8793}
8794
8795impl DropIndex {
8796    pub fn new(name: impl Into<String>) -> Self {
8797        Self {
8798            name: TableRef::new(name),
8799            table: None,
8800            if_exists: false,
8801            concurrently: false,
8802        }
8803    }
8804}
8805
8806/// View column definition with optional COMMENT and OPTIONS (BigQuery)
8807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8808#[cfg_attr(feature = "bindings", derive(TS))]
8809pub struct ViewColumn {
8810    pub name: Identifier,
8811    pub comment: Option<String>,
8812    /// BigQuery: OPTIONS (key=value, ...) on column
8813    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8814    pub options: Vec<Expression>,
8815}
8816
8817impl ViewColumn {
8818    pub fn new(name: impl Into<String>) -> Self {
8819        Self {
8820            name: Identifier::new(name),
8821            comment: None,
8822            options: Vec::new(),
8823        }
8824    }
8825
8826    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
8827        Self {
8828            name: Identifier::new(name),
8829            comment: Some(comment.into()),
8830            options: Vec::new(),
8831        }
8832    }
8833}
8834
8835/// CREATE VIEW statement
8836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8837#[cfg_attr(feature = "bindings", derive(TS))]
8838pub struct CreateView {
8839    pub name: TableRef,
8840    pub columns: Vec<ViewColumn>,
8841    pub query: Expression,
8842    pub or_replace: bool,
8843    /// TSQL: CREATE OR ALTER
8844    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
8845    pub or_alter: bool,
8846    pub if_not_exists: bool,
8847    pub materialized: bool,
8848    pub temporary: bool,
8849    /// Snowflake: SECURE VIEW
8850    #[serde(default)]
8851    pub secure: bool,
8852    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
8853    #[serde(skip_serializing_if = "Option::is_none")]
8854    pub algorithm: Option<String>,
8855    /// MySQL: DEFINER=user@host
8856    #[serde(skip_serializing_if = "Option::is_none")]
8857    pub definer: Option<String>,
8858    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
8859    #[serde(skip_serializing_if = "Option::is_none")]
8860    pub security: Option<FunctionSecurity>,
8861    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
8862    #[serde(default = "default_true")]
8863    pub security_sql_style: bool,
8864    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
8865    #[serde(default)]
8866    pub security_after_name: bool,
8867    /// Whether the query was parenthesized: AS (SELECT ...)
8868    #[serde(default)]
8869    pub query_parenthesized: bool,
8870    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
8871    #[serde(skip_serializing_if = "Option::is_none")]
8872    pub locking_mode: Option<String>,
8873    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
8874    #[serde(skip_serializing_if = "Option::is_none")]
8875    pub locking_access: Option<String>,
8876    /// Snowflake: COPY GRANTS
8877    #[serde(default)]
8878    pub copy_grants: bool,
8879    /// Snowflake: COMMENT = 'text'
8880    #[serde(skip_serializing_if = "Option::is_none", default)]
8881    pub comment: Option<String>,
8882    /// Snowflake: WITH ROW ACCESS POLICY ... clause
8883    #[serde(skip_serializing_if = "Option::is_none", default)]
8884    pub row_access_policy: Option<String>,
8885    /// Snowflake: TAG (name='value', ...)
8886    #[serde(default)]
8887    pub tags: Vec<(String, String)>,
8888    /// BigQuery: OPTIONS (key=value, ...)
8889    #[serde(default)]
8890    pub options: Vec<Expression>,
8891    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
8892    #[serde(skip_serializing_if = "Option::is_none", default)]
8893    pub build: Option<String>,
8894    /// Doris: REFRESH property for materialized views
8895    #[serde(skip_serializing_if = "Option::is_none", default)]
8896    pub refresh: Option<Box<RefreshTriggerProperty>>,
8897    /// Doris: Schema with typed column definitions for materialized views
8898    /// This is used instead of `columns` when the view has typed column definitions
8899    #[serde(skip_serializing_if = "Option::is_none", default)]
8900    pub schema: Option<Box<Schema>>,
8901    /// Doris: KEY (columns) for materialized views
8902    #[serde(skip_serializing_if = "Option::is_none", default)]
8903    pub unique_key: Option<Box<UniqueKeyProperty>>,
8904    /// Redshift: WITH NO SCHEMA BINDING
8905    #[serde(default)]
8906    pub no_schema_binding: bool,
8907    /// Redshift: AUTO REFRESH YES|NO for materialized views
8908    #[serde(skip_serializing_if = "Option::is_none", default)]
8909    pub auto_refresh: Option<bool>,
8910    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
8911    #[serde(skip_serializing_if = "Option::is_none", default)]
8912    pub clickhouse_population: Option<String>,
8913    /// ClickHouse: ON CLUSTER clause
8914    #[serde(default, skip_serializing_if = "Option::is_none")]
8915    pub on_cluster: Option<OnCluster>,
8916    /// ClickHouse: TO destination_table
8917    #[serde(default, skip_serializing_if = "Option::is_none")]
8918    pub to_table: Option<TableRef>,
8919    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
8920    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8921    pub table_properties: Vec<Expression>,
8922}
8923
8924impl CreateView {
8925    pub fn new(name: impl Into<String>, query: Expression) -> Self {
8926        Self {
8927            name: TableRef::new(name),
8928            columns: Vec::new(),
8929            query,
8930            or_replace: false,
8931            or_alter: false,
8932            if_not_exists: false,
8933            materialized: false,
8934            temporary: false,
8935            secure: false,
8936            algorithm: None,
8937            definer: None,
8938            security: None,
8939            security_sql_style: true,
8940            security_after_name: false,
8941            query_parenthesized: false,
8942            locking_mode: None,
8943            locking_access: None,
8944            copy_grants: false,
8945            comment: None,
8946            row_access_policy: None,
8947            tags: Vec::new(),
8948            options: Vec::new(),
8949            build: None,
8950            refresh: None,
8951            schema: None,
8952            unique_key: None,
8953            no_schema_binding: false,
8954            auto_refresh: None,
8955            clickhouse_population: None,
8956            on_cluster: None,
8957            to_table: None,
8958            table_properties: Vec::new(),
8959        }
8960    }
8961}
8962
8963/// DROP VIEW statement
8964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8965#[cfg_attr(feature = "bindings", derive(TS))]
8966pub struct DropView {
8967    pub name: TableRef,
8968    pub if_exists: bool,
8969    pub materialized: bool,
8970}
8971
8972impl DropView {
8973    pub fn new(name: impl Into<String>) -> Self {
8974        Self {
8975            name: TableRef::new(name),
8976            if_exists: false,
8977            materialized: false,
8978        }
8979    }
8980}
8981
8982/// TRUNCATE TABLE statement
8983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8984#[cfg_attr(feature = "bindings", derive(TS))]
8985pub struct Truncate {
8986    /// Target of TRUNCATE (TABLE vs DATABASE)
8987    #[serde(default)]
8988    pub target: TruncateTarget,
8989    /// IF EXISTS clause
8990    #[serde(default)]
8991    pub if_exists: bool,
8992    pub table: TableRef,
8993    /// ClickHouse: ON CLUSTER clause for distributed DDL
8994    #[serde(default, skip_serializing_if = "Option::is_none")]
8995    pub on_cluster: Option<OnCluster>,
8996    pub cascade: bool,
8997    /// Additional tables for multi-table TRUNCATE
8998    #[serde(default)]
8999    pub extra_tables: Vec<TruncateTableEntry>,
9000    /// RESTART IDENTITY or CONTINUE IDENTITY
9001    #[serde(default)]
9002    pub identity: Option<TruncateIdentity>,
9003    /// RESTRICT option (alternative to CASCADE)
9004    #[serde(default)]
9005    pub restrict: bool,
9006    /// Hive PARTITION clause: PARTITION(key=value, ...)
9007    #[serde(default, skip_serializing_if = "Option::is_none")]
9008    pub partition: Option<Box<Expression>>,
9009}
9010
9011/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
9012#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9013#[cfg_attr(feature = "bindings", derive(TS))]
9014pub struct TruncateTableEntry {
9015    pub table: TableRef,
9016    /// Whether the table has a * suffix (inherit children)
9017    #[serde(default)]
9018    pub star: bool,
9019}
9020
9021/// TRUNCATE target type
9022#[derive(
9023    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9024)]
9025#[cfg_attr(feature = "bindings", derive(TS))]
9026pub enum TruncateTarget {
9027    Table,
9028    Database,
9029}
9030
9031impl Default for TruncateTarget {
9032    fn default() -> Self {
9033        TruncateTarget::Table
9034    }
9035}
9036
9037/// TRUNCATE identity option
9038#[derive(
9039    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9040)]
9041#[cfg_attr(feature = "bindings", derive(TS))]
9042pub enum TruncateIdentity {
9043    Restart,
9044    Continue,
9045}
9046
9047impl Truncate {
9048    pub fn new(table: impl Into<String>) -> Self {
9049        Self {
9050            target: TruncateTarget::Table,
9051            if_exists: false,
9052            table: TableRef::new(table),
9053            on_cluster: None,
9054            cascade: false,
9055            extra_tables: Vec::new(),
9056            identity: None,
9057            restrict: false,
9058            partition: None,
9059        }
9060    }
9061}
9062
9063/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
9064#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9065#[cfg_attr(feature = "bindings", derive(TS))]
9066pub struct Use {
9067    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
9068    pub kind: Option<UseKind>,
9069    /// The name of the object
9070    pub this: Identifier,
9071}
9072
9073/// Kind of USE statement
9074#[derive(
9075    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9076)]
9077#[cfg_attr(feature = "bindings", derive(TS))]
9078pub enum UseKind {
9079    Database,
9080    Schema,
9081    Role,
9082    Warehouse,
9083    Catalog,
9084    /// Snowflake: USE SECONDARY ROLES ALL|NONE
9085    SecondaryRoles,
9086}
9087
9088/// SET variable statement
9089#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9090#[cfg_attr(feature = "bindings", derive(TS))]
9091pub struct SetStatement {
9092    /// The items being set
9093    pub items: Vec<SetItem>,
9094}
9095
9096/// A single SET item (variable assignment)
9097#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9098#[cfg_attr(feature = "bindings", derive(TS))]
9099pub struct SetItem {
9100    /// The variable name
9101    pub name: Expression,
9102    /// The value to set
9103    pub value: Expression,
9104    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
9105    pub kind: Option<String>,
9106    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
9107    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9108    pub no_equals: bool,
9109}
9110
9111/// CACHE TABLE statement (Spark)
9112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9113#[cfg_attr(feature = "bindings", derive(TS))]
9114pub struct Cache {
9115    /// The table to cache
9116    pub table: Identifier,
9117    /// LAZY keyword - defer caching until first use
9118    pub lazy: bool,
9119    /// Optional OPTIONS clause (key-value pairs)
9120    pub options: Vec<(Expression, Expression)>,
9121    /// Optional AS clause with query
9122    pub query: Option<Expression>,
9123}
9124
9125/// UNCACHE TABLE statement (Spark)
9126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9127#[cfg_attr(feature = "bindings", derive(TS))]
9128pub struct Uncache {
9129    /// The table to uncache
9130    pub table: Identifier,
9131    /// IF EXISTS clause
9132    pub if_exists: bool,
9133}
9134
9135/// LOAD DATA statement (Hive)
9136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9137#[cfg_attr(feature = "bindings", derive(TS))]
9138pub struct LoadData {
9139    /// LOCAL keyword - load from local filesystem
9140    pub local: bool,
9141    /// The path to load data from (INPATH value)
9142    pub inpath: String,
9143    /// Whether to overwrite existing data
9144    pub overwrite: bool,
9145    /// The target table
9146    pub table: Expression,
9147    /// Optional PARTITION clause with key-value pairs
9148    pub partition: Vec<(Identifier, Expression)>,
9149    /// Optional INPUTFORMAT clause
9150    pub input_format: Option<String>,
9151    /// Optional SERDE clause
9152    pub serde: Option<String>,
9153}
9154
9155/// PRAGMA statement (SQLite)
9156#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9157#[cfg_attr(feature = "bindings", derive(TS))]
9158pub struct Pragma {
9159    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
9160    pub schema: Option<Identifier>,
9161    /// The pragma name
9162    pub name: Identifier,
9163    /// Optional value for assignment (PRAGMA name = value)
9164    pub value: Option<Expression>,
9165    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
9166    pub args: Vec<Expression>,
9167    /// Whether this pragma should be generated using assignment syntax.
9168    #[serde(default)]
9169    pub use_assignment_syntax: bool,
9170}
9171
9172/// A privilege with optional column list for GRANT/REVOKE
9173/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
9174#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9175#[cfg_attr(feature = "bindings", derive(TS))]
9176pub struct Privilege {
9177    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
9178    pub name: String,
9179    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
9180    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9181    pub columns: Vec<String>,
9182}
9183
9184/// Principal in GRANT/REVOKE (user, role, etc.)
9185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9186#[cfg_attr(feature = "bindings", derive(TS))]
9187pub struct GrantPrincipal {
9188    /// The name of the principal
9189    pub name: Identifier,
9190    /// Whether prefixed with ROLE keyword
9191    pub is_role: bool,
9192    /// Whether prefixed with GROUP keyword (Redshift)
9193    #[serde(default)]
9194    pub is_group: bool,
9195    /// Whether prefixed with SHARE keyword (Snowflake)
9196    #[serde(default)]
9197    pub is_share: bool,
9198}
9199
9200/// GRANT statement
9201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9202#[cfg_attr(feature = "bindings", derive(TS))]
9203pub struct Grant {
9204    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
9205    pub privileges: Vec<Privilege>,
9206    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9207    pub kind: Option<String>,
9208    /// The object to grant on
9209    pub securable: Identifier,
9210    /// Function parameter types (for FUNCTION kind)
9211    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9212    pub function_params: Vec<String>,
9213    /// The grantees
9214    pub principals: Vec<GrantPrincipal>,
9215    /// WITH GRANT OPTION
9216    pub grant_option: bool,
9217    /// TSQL: AS principal (the grantor role)
9218    #[serde(default, skip_serializing_if = "Option::is_none")]
9219    pub as_principal: Option<Identifier>,
9220}
9221
9222/// REVOKE statement
9223#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9224#[cfg_attr(feature = "bindings", derive(TS))]
9225pub struct Revoke {
9226    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9227    pub privileges: Vec<Privilege>,
9228    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9229    pub kind: Option<String>,
9230    /// The object to revoke from
9231    pub securable: Identifier,
9232    /// Function parameter types (for FUNCTION kind)
9233    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9234    pub function_params: Vec<String>,
9235    /// The grantees
9236    pub principals: Vec<GrantPrincipal>,
9237    /// GRANT OPTION FOR
9238    pub grant_option: bool,
9239    /// CASCADE
9240    pub cascade: bool,
9241    /// RESTRICT
9242    #[serde(default)]
9243    pub restrict: bool,
9244}
9245
9246/// COMMENT ON statement
9247#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9248#[cfg_attr(feature = "bindings", derive(TS))]
9249pub struct Comment {
9250    /// The object being commented on
9251    pub this: Expression,
9252    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9253    pub kind: String,
9254    /// The comment text expression
9255    pub expression: Expression,
9256    /// IF EXISTS clause
9257    pub exists: bool,
9258    /// MATERIALIZED keyword
9259    pub materialized: bool,
9260}
9261
9262// ============================================================================
9263// Phase 4: Additional DDL Statements
9264// ============================================================================
9265
9266/// ALTER VIEW statement
9267#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9268#[cfg_attr(feature = "bindings", derive(TS))]
9269pub struct AlterView {
9270    pub name: TableRef,
9271    pub actions: Vec<AlterViewAction>,
9272    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9273    #[serde(default, skip_serializing_if = "Option::is_none")]
9274    pub algorithm: Option<String>,
9275    /// MySQL: DEFINER = 'user'@'host'
9276    #[serde(default, skip_serializing_if = "Option::is_none")]
9277    pub definer: Option<String>,
9278    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9279    #[serde(default, skip_serializing_if = "Option::is_none")]
9280    pub sql_security: Option<String>,
9281    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9282    #[serde(default, skip_serializing_if = "Option::is_none")]
9283    pub with_option: Option<String>,
9284    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9285    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9286    pub columns: Vec<ViewColumn>,
9287}
9288
9289/// Actions for ALTER VIEW
9290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9291#[cfg_attr(feature = "bindings", derive(TS))]
9292pub enum AlterViewAction {
9293    /// Rename the view
9294    Rename(TableRef),
9295    /// Change owner
9296    OwnerTo(Identifier),
9297    /// Set schema
9298    SetSchema(Identifier),
9299    /// Set authorization (Trino/Presto)
9300    SetAuthorization(String),
9301    /// Alter column
9302    AlterColumn {
9303        name: Identifier,
9304        action: AlterColumnAction,
9305    },
9306    /// Redefine view as query (SELECT, UNION, etc.)
9307    AsSelect(Box<Expression>),
9308    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9309    SetTblproperties(Vec<(String, String)>),
9310    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9311    UnsetTblproperties(Vec<String>),
9312}
9313
9314impl AlterView {
9315    pub fn new(name: impl Into<String>) -> Self {
9316        Self {
9317            name: TableRef::new(name),
9318            actions: Vec::new(),
9319            algorithm: None,
9320            definer: None,
9321            sql_security: None,
9322            with_option: None,
9323            columns: Vec::new(),
9324        }
9325    }
9326}
9327
9328/// ALTER INDEX statement
9329#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9330#[cfg_attr(feature = "bindings", derive(TS))]
9331pub struct AlterIndex {
9332    pub name: Identifier,
9333    pub table: Option<TableRef>,
9334    pub actions: Vec<AlterIndexAction>,
9335}
9336
9337/// Actions for ALTER INDEX
9338#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9339#[cfg_attr(feature = "bindings", derive(TS))]
9340pub enum AlterIndexAction {
9341    /// Rename the index
9342    Rename(Identifier),
9343    /// Set tablespace
9344    SetTablespace(Identifier),
9345    /// Set visibility (MySQL)
9346    Visible(bool),
9347}
9348
9349impl AlterIndex {
9350    pub fn new(name: impl Into<String>) -> Self {
9351        Self {
9352            name: Identifier::new(name),
9353            table: None,
9354            actions: Vec::new(),
9355        }
9356    }
9357}
9358
9359/// CREATE SCHEMA statement
9360#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9361#[cfg_attr(feature = "bindings", derive(TS))]
9362pub struct CreateSchema {
9363    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9364    pub name: Vec<Identifier>,
9365    pub if_not_exists: bool,
9366    pub authorization: Option<Identifier>,
9367    /// CLONE source parts, possibly dot-qualified
9368    #[serde(default)]
9369    pub clone_from: Option<Vec<Identifier>>,
9370    /// AT/BEFORE clause for time travel (Snowflake)
9371    #[serde(default)]
9372    pub at_clause: Option<Expression>,
9373    /// Schema properties like DEFAULT COLLATE
9374    #[serde(default)]
9375    pub properties: Vec<Expression>,
9376    /// Leading comments before the statement
9377    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9378    pub leading_comments: Vec<String>,
9379}
9380
9381impl CreateSchema {
9382    pub fn new(name: impl Into<String>) -> Self {
9383        Self {
9384            name: vec![Identifier::new(name)],
9385            if_not_exists: false,
9386            authorization: None,
9387            clone_from: None,
9388            at_clause: None,
9389            properties: Vec::new(),
9390            leading_comments: Vec::new(),
9391        }
9392    }
9393}
9394
9395/// DROP SCHEMA statement
9396#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9397#[cfg_attr(feature = "bindings", derive(TS))]
9398pub struct DropSchema {
9399    pub name: Identifier,
9400    pub if_exists: bool,
9401    pub cascade: bool,
9402}
9403
9404impl DropSchema {
9405    pub fn new(name: impl Into<String>) -> Self {
9406        Self {
9407            name: Identifier::new(name),
9408            if_exists: false,
9409            cascade: false,
9410        }
9411    }
9412}
9413
9414/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9415#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9416#[cfg_attr(feature = "bindings", derive(TS))]
9417pub struct DropNamespace {
9418    pub name: Identifier,
9419    pub if_exists: bool,
9420    pub cascade: bool,
9421}
9422
9423impl DropNamespace {
9424    pub fn new(name: impl Into<String>) -> Self {
9425        Self {
9426            name: Identifier::new(name),
9427            if_exists: false,
9428            cascade: false,
9429        }
9430    }
9431}
9432
9433/// CREATE DATABASE statement
9434#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9435#[cfg_attr(feature = "bindings", derive(TS))]
9436pub struct CreateDatabase {
9437    pub name: Identifier,
9438    pub if_not_exists: bool,
9439    pub options: Vec<DatabaseOption>,
9440    /// Snowflake CLONE source
9441    #[serde(default)]
9442    pub clone_from: Option<Identifier>,
9443    /// AT/BEFORE clause for time travel (Snowflake)
9444    #[serde(default)]
9445    pub at_clause: Option<Expression>,
9446}
9447
9448/// Database option
9449#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9450#[cfg_attr(feature = "bindings", derive(TS))]
9451pub enum DatabaseOption {
9452    CharacterSet(String),
9453    Collate(String),
9454    Owner(Identifier),
9455    Template(Identifier),
9456    Encoding(String),
9457    Location(String),
9458}
9459
9460impl CreateDatabase {
9461    pub fn new(name: impl Into<String>) -> Self {
9462        Self {
9463            name: Identifier::new(name),
9464            if_not_exists: false,
9465            options: Vec::new(),
9466            clone_from: None,
9467            at_clause: None,
9468        }
9469    }
9470}
9471
9472/// DROP DATABASE statement
9473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9474#[cfg_attr(feature = "bindings", derive(TS))]
9475pub struct DropDatabase {
9476    pub name: Identifier,
9477    pub if_exists: bool,
9478    /// ClickHouse: SYNC modifier
9479    #[serde(default)]
9480    pub sync: bool,
9481}
9482
9483impl DropDatabase {
9484    pub fn new(name: impl Into<String>) -> Self {
9485        Self {
9486            name: Identifier::new(name),
9487            if_exists: false,
9488            sync: false,
9489        }
9490    }
9491}
9492
9493/// CREATE FUNCTION statement
9494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9495#[cfg_attr(feature = "bindings", derive(TS))]
9496pub struct CreateFunction {
9497    pub name: TableRef,
9498    pub parameters: Vec<FunctionParameter>,
9499    pub return_type: Option<DataType>,
9500    pub body: Option<FunctionBody>,
9501    pub or_replace: bool,
9502    /// TSQL: CREATE OR ALTER
9503    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9504    pub or_alter: bool,
9505    pub if_not_exists: bool,
9506    pub temporary: bool,
9507    pub language: Option<String>,
9508    pub deterministic: Option<bool>,
9509    pub returns_null_on_null_input: Option<bool>,
9510    pub security: Option<FunctionSecurity>,
9511    /// Whether parentheses were present in the original syntax
9512    #[serde(default = "default_true")]
9513    pub has_parens: bool,
9514    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9515    #[serde(default)]
9516    pub sql_data_access: Option<SqlDataAccess>,
9517    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9518    #[serde(default, skip_serializing_if = "Option::is_none")]
9519    pub returns_table_body: Option<String>,
9520    /// True if LANGUAGE clause appears before RETURNS clause
9521    #[serde(default)]
9522    pub language_first: bool,
9523    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9524    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9525    pub set_options: Vec<FunctionSetOption>,
9526    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9527    #[serde(default)]
9528    pub strict: bool,
9529    /// BigQuery: OPTIONS (key=value, ...)
9530    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9531    pub options: Vec<Expression>,
9532    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9533    #[serde(default)]
9534    pub is_table_function: bool,
9535    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9536    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9537    pub property_order: Vec<FunctionPropertyKind>,
9538    /// Hive: USING JAR|FILE|ARCHIVE '...'
9539    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9540    pub using_resources: Vec<FunctionUsingResource>,
9541    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9542    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9543    pub environment: Vec<Expression>,
9544    /// HANDLER 'handler_function' clause (Databricks)
9545    #[serde(default, skip_serializing_if = "Option::is_none")]
9546    pub handler: Option<String>,
9547    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9548    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9549    pub handler_uses_eq: bool,
9550    /// Snowflake: RUNTIME_VERSION='3.11'
9551    #[serde(default, skip_serializing_if = "Option::is_none")]
9552    pub runtime_version: Option<String>,
9553    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9554    #[serde(default, skip_serializing_if = "Option::is_none")]
9555    pub packages: Option<Vec<String>>,
9556    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9557    #[serde(default, skip_serializing_if = "Option::is_none")]
9558    pub parameter_style: Option<String>,
9559}
9560
9561/// A SET option in CREATE FUNCTION (PostgreSQL)
9562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9563#[cfg_attr(feature = "bindings", derive(TS))]
9564pub struct FunctionSetOption {
9565    pub name: String,
9566    pub value: FunctionSetValue,
9567}
9568
9569/// The value of a SET option
9570#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9571#[cfg_attr(feature = "bindings", derive(TS))]
9572pub enum FunctionSetValue {
9573    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9574    Value { value: String, use_to: bool },
9575    /// SET key FROM CURRENT
9576    FromCurrent,
9577}
9578
9579/// SQL data access characteristics for functions
9580#[derive(
9581    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9582)]
9583#[cfg_attr(feature = "bindings", derive(TS))]
9584pub enum SqlDataAccess {
9585    /// NO SQL
9586    NoSql,
9587    /// CONTAINS SQL
9588    ContainsSql,
9589    /// READS SQL DATA
9590    ReadsSqlData,
9591    /// MODIFIES SQL DATA
9592    ModifiesSqlData,
9593}
9594
9595/// Types of properties in CREATE FUNCTION for tracking their original order
9596#[derive(
9597    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9598)]
9599#[cfg_attr(feature = "bindings", derive(TS))]
9600pub enum FunctionPropertyKind {
9601    /// SET option
9602    Set,
9603    /// AS body
9604    As,
9605    /// Hive: USING JAR|FILE|ARCHIVE ...
9606    Using,
9607    /// LANGUAGE clause
9608    Language,
9609    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9610    Determinism,
9611    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
9612    NullInput,
9613    /// SECURITY DEFINER/INVOKER
9614    Security,
9615    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
9616    SqlDataAccess,
9617    /// OPTIONS clause (BigQuery)
9618    Options,
9619    /// ENVIRONMENT clause (Databricks)
9620    Environment,
9621    /// HANDLER clause (Databricks)
9622    Handler,
9623    /// Snowflake: RUNTIME_VERSION='...'
9624    RuntimeVersion,
9625    /// Snowflake: PACKAGES=(...)
9626    Packages,
9627    /// PARAMETER STYLE clause (Databricks)
9628    ParameterStyle,
9629}
9630
9631/// Hive CREATE FUNCTION resource in a USING clause
9632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9633#[cfg_attr(feature = "bindings", derive(TS))]
9634pub struct FunctionUsingResource {
9635    pub kind: String,
9636    pub uri: String,
9637}
9638
9639/// Function parameter
9640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9641#[cfg_attr(feature = "bindings", derive(TS))]
9642pub struct FunctionParameter {
9643    pub name: Option<Identifier>,
9644    pub data_type: DataType,
9645    pub mode: Option<ParameterMode>,
9646    pub default: Option<Expression>,
9647    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
9648    #[serde(default, skip_serializing_if = "Option::is_none")]
9649    pub mode_text: Option<String>,
9650}
9651
9652/// Parameter mode (IN, OUT, INOUT, VARIADIC)
9653#[derive(
9654    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9655)]
9656#[cfg_attr(feature = "bindings", derive(TS))]
9657pub enum ParameterMode {
9658    In,
9659    Out,
9660    InOut,
9661    Variadic,
9662}
9663
9664/// Function body
9665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9666#[cfg_attr(feature = "bindings", derive(TS))]
9667pub enum FunctionBody {
9668    /// AS $$ ... $$ (dollar-quoted)
9669    Block(String),
9670    /// AS 'string' (single-quoted string literal body)
9671    StringLiteral(String),
9672    /// AS 'expression'
9673    Expression(Expression),
9674    /// EXTERNAL NAME 'library'
9675    External(String),
9676    /// RETURN expression
9677    Return(Expression),
9678    /// BEGIN ... END block with parsed statements
9679    Statements(Vec<Expression>),
9680    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
9681    /// Stores (content, optional_tag)
9682    DollarQuoted {
9683        content: String,
9684        tag: Option<String>,
9685    },
9686    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
9687    RawBlock(String),
9688}
9689
9690/// Function security (DEFINER, INVOKER, or NONE)
9691#[derive(
9692    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9693)]
9694#[cfg_attr(feature = "bindings", derive(TS))]
9695pub enum FunctionSecurity {
9696    Definer,
9697    Invoker,
9698    /// StarRocks/MySQL: SECURITY NONE
9699    None,
9700}
9701
9702impl CreateFunction {
9703    pub fn new(name: impl Into<String>) -> Self {
9704        Self {
9705            name: TableRef::new(name),
9706            parameters: Vec::new(),
9707            return_type: None,
9708            body: None,
9709            or_replace: false,
9710            or_alter: false,
9711            if_not_exists: false,
9712            temporary: false,
9713            language: None,
9714            deterministic: None,
9715            returns_null_on_null_input: None,
9716            security: None,
9717            has_parens: true,
9718            sql_data_access: None,
9719            returns_table_body: None,
9720            language_first: false,
9721            set_options: Vec::new(),
9722            strict: false,
9723            options: Vec::new(),
9724            is_table_function: false,
9725            property_order: Vec::new(),
9726            using_resources: Vec::new(),
9727            environment: Vec::new(),
9728            handler: None,
9729            handler_uses_eq: false,
9730            runtime_version: None,
9731            packages: None,
9732            parameter_style: None,
9733        }
9734    }
9735}
9736
9737/// DROP FUNCTION statement
9738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9739#[cfg_attr(feature = "bindings", derive(TS))]
9740pub struct DropFunction {
9741    pub name: TableRef,
9742    pub parameters: Option<Vec<DataType>>,
9743    pub if_exists: bool,
9744    pub cascade: bool,
9745}
9746
9747impl DropFunction {
9748    pub fn new(name: impl Into<String>) -> Self {
9749        Self {
9750            name: TableRef::new(name),
9751            parameters: None,
9752            if_exists: false,
9753            cascade: false,
9754        }
9755    }
9756}
9757
9758/// CREATE PROCEDURE statement
9759#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9760#[cfg_attr(feature = "bindings", derive(TS))]
9761pub struct CreateProcedure {
9762    pub name: TableRef,
9763    pub parameters: Vec<FunctionParameter>,
9764    pub body: Option<FunctionBody>,
9765    pub or_replace: bool,
9766    /// TSQL: CREATE OR ALTER
9767    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9768    pub or_alter: bool,
9769    pub if_not_exists: bool,
9770    pub language: Option<String>,
9771    pub security: Option<FunctionSecurity>,
9772    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
9773    #[serde(default)]
9774    pub return_type: Option<DataType>,
9775    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
9776    #[serde(default)]
9777    pub execute_as: Option<String>,
9778    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
9779    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9780    pub with_options: Vec<String>,
9781    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
9782    #[serde(default = "default_true", skip_serializing_if = "is_true")]
9783    pub has_parens: bool,
9784    /// Whether the short form PROC was used (instead of PROCEDURE)
9785    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9786    pub use_proc_keyword: bool,
9787}
9788
9789impl CreateProcedure {
9790    pub fn new(name: impl Into<String>) -> Self {
9791        Self {
9792            name: TableRef::new(name),
9793            parameters: Vec::new(),
9794            body: None,
9795            or_replace: false,
9796            or_alter: false,
9797            if_not_exists: false,
9798            language: None,
9799            security: None,
9800            return_type: None,
9801            execute_as: None,
9802            with_options: Vec::new(),
9803            has_parens: true,
9804            use_proc_keyword: false,
9805        }
9806    }
9807}
9808
9809/// DROP PROCEDURE statement
9810#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9811#[cfg_attr(feature = "bindings", derive(TS))]
9812pub struct DropProcedure {
9813    pub name: TableRef,
9814    pub parameters: Option<Vec<DataType>>,
9815    pub if_exists: bool,
9816    pub cascade: bool,
9817}
9818
9819impl DropProcedure {
9820    pub fn new(name: impl Into<String>) -> Self {
9821        Self {
9822            name: TableRef::new(name),
9823            parameters: None,
9824            if_exists: false,
9825            cascade: false,
9826        }
9827    }
9828}
9829
9830/// Sequence property tag for ordering
9831#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9832#[cfg_attr(feature = "bindings", derive(TS))]
9833pub enum SeqPropKind {
9834    Start,
9835    Increment,
9836    Minvalue,
9837    Maxvalue,
9838    Cache,
9839    NoCache,
9840    Cycle,
9841    NoCycle,
9842    OwnedBy,
9843    Order,
9844    NoOrder,
9845    Comment,
9846    /// SHARING=<value> (Oracle)
9847    Sharing,
9848    /// KEEP (Oracle)
9849    Keep,
9850    /// NOKEEP (Oracle)
9851    NoKeep,
9852    /// SCALE [EXTEND|NOEXTEND] (Oracle)
9853    Scale,
9854    /// NOSCALE (Oracle)
9855    NoScale,
9856    /// SHARD [EXTEND|NOEXTEND] (Oracle)
9857    Shard,
9858    /// NOSHARD (Oracle)
9859    NoShard,
9860    /// SESSION (Oracle)
9861    Session,
9862    /// GLOBAL (Oracle)
9863    Global,
9864    /// NOCACHE (single word, Oracle)
9865    NoCacheWord,
9866    /// NOCYCLE (single word, Oracle)
9867    NoCycleWord,
9868    /// NOMINVALUE (single word, Oracle)
9869    NoMinvalueWord,
9870    /// NOMAXVALUE (single word, Oracle)
9871    NoMaxvalueWord,
9872}
9873
9874/// CREATE SYNONYM statement (TSQL)
9875#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9876#[cfg_attr(feature = "bindings", derive(TS))]
9877pub struct CreateSynonym {
9878    /// The synonym name (can be qualified: schema.synonym_name)
9879    pub name: TableRef,
9880    /// The target object the synonym refers to
9881    pub target: TableRef,
9882}
9883
9884/// CREATE SEQUENCE statement
9885#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9886#[cfg_attr(feature = "bindings", derive(TS))]
9887pub struct CreateSequence {
9888    pub name: TableRef,
9889    pub if_not_exists: bool,
9890    pub temporary: bool,
9891    #[serde(default)]
9892    pub or_replace: bool,
9893    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
9894    #[serde(default, skip_serializing_if = "Option::is_none")]
9895    pub as_type: Option<DataType>,
9896    pub increment: Option<i64>,
9897    pub minvalue: Option<SequenceBound>,
9898    pub maxvalue: Option<SequenceBound>,
9899    pub start: Option<i64>,
9900    pub cache: Option<i64>,
9901    pub cycle: bool,
9902    pub owned_by: Option<TableRef>,
9903    /// Whether OWNED BY NONE was specified
9904    #[serde(default)]
9905    pub owned_by_none: bool,
9906    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
9907    #[serde(default)]
9908    pub order: Option<bool>,
9909    /// Snowflake: COMMENT = 'value'
9910    #[serde(default)]
9911    pub comment: Option<String>,
9912    /// SHARING=<value> (Oracle)
9913    #[serde(default, skip_serializing_if = "Option::is_none")]
9914    pub sharing: Option<String>,
9915    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
9916    #[serde(default, skip_serializing_if = "Option::is_none")]
9917    pub scale_modifier: Option<String>,
9918    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
9919    #[serde(default, skip_serializing_if = "Option::is_none")]
9920    pub shard_modifier: Option<String>,
9921    /// Tracks the order in which properties appeared in the source
9922    #[serde(default)]
9923    pub property_order: Vec<SeqPropKind>,
9924}
9925
9926/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
9927#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9928#[cfg_attr(feature = "bindings", derive(TS))]
9929pub enum SequenceBound {
9930    Value(i64),
9931    None,
9932}
9933
9934impl CreateSequence {
9935    pub fn new(name: impl Into<String>) -> Self {
9936        Self {
9937            name: TableRef::new(name),
9938            if_not_exists: false,
9939            temporary: false,
9940            or_replace: false,
9941            as_type: None,
9942            increment: None,
9943            minvalue: None,
9944            maxvalue: None,
9945            start: None,
9946            cache: None,
9947            cycle: false,
9948            owned_by: None,
9949            owned_by_none: false,
9950            order: None,
9951            comment: None,
9952            sharing: None,
9953            scale_modifier: None,
9954            shard_modifier: None,
9955            property_order: Vec::new(),
9956        }
9957    }
9958}
9959
9960/// DROP SEQUENCE statement
9961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9962#[cfg_attr(feature = "bindings", derive(TS))]
9963pub struct DropSequence {
9964    pub name: TableRef,
9965    pub if_exists: bool,
9966    pub cascade: bool,
9967}
9968
9969impl DropSequence {
9970    pub fn new(name: impl Into<String>) -> Self {
9971        Self {
9972            name: TableRef::new(name),
9973            if_exists: false,
9974            cascade: false,
9975        }
9976    }
9977}
9978
9979/// ALTER SEQUENCE statement
9980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9981#[cfg_attr(feature = "bindings", derive(TS))]
9982pub struct AlterSequence {
9983    pub name: TableRef,
9984    pub if_exists: bool,
9985    pub increment: Option<i64>,
9986    pub minvalue: Option<SequenceBound>,
9987    pub maxvalue: Option<SequenceBound>,
9988    pub start: Option<i64>,
9989    pub restart: Option<Option<i64>>,
9990    pub cache: Option<i64>,
9991    pub cycle: Option<bool>,
9992    pub owned_by: Option<Option<TableRef>>,
9993}
9994
9995impl AlterSequence {
9996    pub fn new(name: impl Into<String>) -> Self {
9997        Self {
9998            name: TableRef::new(name),
9999            if_exists: false,
10000            increment: None,
10001            minvalue: None,
10002            maxvalue: None,
10003            start: None,
10004            restart: None,
10005            cache: None,
10006            cycle: None,
10007            owned_by: None,
10008        }
10009    }
10010}
10011
10012/// CREATE TRIGGER statement
10013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10014#[cfg_attr(feature = "bindings", derive(TS))]
10015pub struct CreateTrigger {
10016    pub name: Identifier,
10017    pub table: TableRef,
10018    pub timing: TriggerTiming,
10019    pub events: Vec<TriggerEvent>,
10020    #[serde(default, skip_serializing_if = "Option::is_none")]
10021    pub for_each: Option<TriggerForEach>,
10022    pub when: Option<Expression>,
10023    /// Whether the WHEN clause was parenthesized in the original SQL
10024    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10025    pub when_paren: bool,
10026    pub body: TriggerBody,
10027    pub or_replace: bool,
10028    /// TSQL: CREATE OR ALTER
10029    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10030    pub or_alter: bool,
10031    pub constraint: bool,
10032    pub deferrable: Option<bool>,
10033    pub initially_deferred: Option<bool>,
10034    pub referencing: Option<TriggerReferencing>,
10035}
10036
10037/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
10038#[derive(
10039    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10040)]
10041#[cfg_attr(feature = "bindings", derive(TS))]
10042pub enum TriggerTiming {
10043    Before,
10044    After,
10045    InsteadOf,
10046}
10047
10048/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
10049#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10050#[cfg_attr(feature = "bindings", derive(TS))]
10051pub enum TriggerEvent {
10052    Insert,
10053    Update(Option<Vec<Identifier>>),
10054    Delete,
10055    Truncate,
10056}
10057
10058/// Trigger FOR EACH clause
10059#[derive(
10060    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10061)]
10062#[cfg_attr(feature = "bindings", derive(TS))]
10063pub enum TriggerForEach {
10064    Row,
10065    Statement,
10066}
10067
10068/// Trigger body
10069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10070#[cfg_attr(feature = "bindings", derive(TS))]
10071pub enum TriggerBody {
10072    /// EXECUTE FUNCTION/PROCEDURE name(args)
10073    Execute {
10074        function: TableRef,
10075        args: Vec<Expression>,
10076    },
10077    /// BEGIN ... END block
10078    Block(String),
10079}
10080
10081/// Trigger REFERENCING clause
10082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10083#[cfg_attr(feature = "bindings", derive(TS))]
10084pub struct TriggerReferencing {
10085    pub old_table: Option<Identifier>,
10086    pub new_table: Option<Identifier>,
10087    pub old_row: Option<Identifier>,
10088    pub new_row: Option<Identifier>,
10089}
10090
10091impl CreateTrigger {
10092    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
10093        Self {
10094            name: Identifier::new(name),
10095            table: TableRef::new(table),
10096            timing: TriggerTiming::Before,
10097            events: Vec::new(),
10098            for_each: Some(TriggerForEach::Row),
10099            when: None,
10100            when_paren: false,
10101            body: TriggerBody::Execute {
10102                function: TableRef::new(""),
10103                args: Vec::new(),
10104            },
10105            or_replace: false,
10106            or_alter: false,
10107            constraint: false,
10108            deferrable: None,
10109            initially_deferred: None,
10110            referencing: None,
10111        }
10112    }
10113}
10114
10115/// DROP TRIGGER statement
10116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10117#[cfg_attr(feature = "bindings", derive(TS))]
10118pub struct DropTrigger {
10119    pub name: Identifier,
10120    pub table: Option<TableRef>,
10121    pub if_exists: bool,
10122    pub cascade: bool,
10123}
10124
10125impl DropTrigger {
10126    pub fn new(name: impl Into<String>) -> Self {
10127        Self {
10128            name: Identifier::new(name),
10129            table: None,
10130            if_exists: false,
10131            cascade: false,
10132        }
10133    }
10134}
10135
10136/// CREATE TYPE statement
10137#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10138#[cfg_attr(feature = "bindings", derive(TS))]
10139pub struct CreateType {
10140    pub name: TableRef,
10141    pub definition: TypeDefinition,
10142    pub if_not_exists: bool,
10143}
10144
10145/// Type definition
10146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10147#[cfg_attr(feature = "bindings", derive(TS))]
10148pub enum TypeDefinition {
10149    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
10150    Enum(Vec<String>),
10151    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
10152    Composite(Vec<TypeAttribute>),
10153    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
10154    Range {
10155        subtype: DataType,
10156        subtype_diff: Option<String>,
10157        canonical: Option<String>,
10158    },
10159    /// Base type (for advanced usage)
10160    Base {
10161        input: String,
10162        output: String,
10163        internallength: Option<i32>,
10164    },
10165    /// Domain type
10166    Domain {
10167        base_type: DataType,
10168        default: Option<Expression>,
10169        constraints: Vec<DomainConstraint>,
10170    },
10171}
10172
10173/// Type attribute for composite types
10174#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10175#[cfg_attr(feature = "bindings", derive(TS))]
10176pub struct TypeAttribute {
10177    pub name: Identifier,
10178    pub data_type: DataType,
10179    pub collate: Option<Identifier>,
10180}
10181
10182/// Domain constraint
10183#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10184#[cfg_attr(feature = "bindings", derive(TS))]
10185pub struct DomainConstraint {
10186    pub name: Option<Identifier>,
10187    pub check: Expression,
10188}
10189
10190impl CreateType {
10191    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
10192        Self {
10193            name: TableRef::new(name),
10194            definition: TypeDefinition::Enum(values),
10195            if_not_exists: false,
10196        }
10197    }
10198
10199    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
10200        Self {
10201            name: TableRef::new(name),
10202            definition: TypeDefinition::Composite(attributes),
10203            if_not_exists: false,
10204        }
10205    }
10206}
10207
10208/// DROP TYPE statement
10209#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10210#[cfg_attr(feature = "bindings", derive(TS))]
10211pub struct DropType {
10212    pub name: TableRef,
10213    pub if_exists: bool,
10214    pub cascade: bool,
10215}
10216
10217impl DropType {
10218    pub fn new(name: impl Into<String>) -> Self {
10219        Self {
10220            name: TableRef::new(name),
10221            if_exists: false,
10222            cascade: false,
10223        }
10224    }
10225}
10226
10227/// DESCRIBE statement - shows table structure or query plan
10228#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10229#[cfg_attr(feature = "bindings", derive(TS))]
10230pub struct Describe {
10231    /// The target to describe (table name or query)
10232    pub target: Expression,
10233    /// EXTENDED format
10234    pub extended: bool,
10235    /// FORMATTED format
10236    pub formatted: bool,
10237    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10238    #[serde(default)]
10239    pub kind: Option<String>,
10240    /// Properties like type=stage
10241    #[serde(default)]
10242    pub properties: Vec<(String, String)>,
10243    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10244    #[serde(default, skip_serializing_if = "Option::is_none")]
10245    pub style: Option<String>,
10246    /// Partition specification for DESCRIBE PARTITION
10247    #[serde(default)]
10248    pub partition: Option<Box<Expression>>,
10249    /// Leading comments before the statement
10250    #[serde(default)]
10251    pub leading_comments: Vec<String>,
10252    /// AS JSON suffix (Databricks)
10253    #[serde(default)]
10254    pub as_json: bool,
10255    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10256    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10257    pub params: Vec<String>,
10258}
10259
10260impl Describe {
10261    pub fn new(target: Expression) -> Self {
10262        Self {
10263            target,
10264            extended: false,
10265            formatted: false,
10266            kind: None,
10267            properties: Vec::new(),
10268            style: None,
10269            partition: None,
10270            leading_comments: Vec::new(),
10271            as_json: false,
10272            params: Vec::new(),
10273        }
10274    }
10275}
10276
10277/// SHOW statement - displays database objects
10278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10279#[cfg_attr(feature = "bindings", derive(TS))]
10280pub struct Show {
10281    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10282    pub this: String,
10283    /// Whether TERSE was specified
10284    #[serde(default)]
10285    pub terse: bool,
10286    /// Whether HISTORY was specified
10287    #[serde(default)]
10288    pub history: bool,
10289    /// LIKE pattern
10290    pub like: Option<Expression>,
10291    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10292    pub scope_kind: Option<String>,
10293    /// IN scope object
10294    pub scope: Option<Expression>,
10295    /// STARTS WITH pattern
10296    pub starts_with: Option<Expression>,
10297    /// LIMIT clause
10298    pub limit: Option<Box<Limit>>,
10299    /// FROM clause (for specific object)
10300    pub from: Option<Expression>,
10301    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10302    #[serde(default, skip_serializing_if = "Option::is_none")]
10303    pub where_clause: Option<Expression>,
10304    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10305    #[serde(default, skip_serializing_if = "Option::is_none")]
10306    pub for_target: Option<Expression>,
10307    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10308    #[serde(default, skip_serializing_if = "Option::is_none")]
10309    pub db: Option<Expression>,
10310    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10311    #[serde(default, skip_serializing_if = "Option::is_none")]
10312    pub target: Option<Expression>,
10313    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10314    #[serde(default, skip_serializing_if = "Option::is_none")]
10315    pub mutex: Option<bool>,
10316    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10317    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10318    pub privileges: Vec<String>,
10319}
10320
10321impl Show {
10322    pub fn new(this: impl Into<String>) -> Self {
10323        Self {
10324            this: this.into(),
10325            terse: false,
10326            history: false,
10327            like: None,
10328            scope_kind: None,
10329            scope: None,
10330            starts_with: None,
10331            limit: None,
10332            from: None,
10333            where_clause: None,
10334            for_target: None,
10335            db: None,
10336            target: None,
10337            mutex: None,
10338            privileges: Vec::new(),
10339        }
10340    }
10341}
10342
10343/// Represent an explicit parenthesized expression for grouping precedence.
10344///
10345/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10346/// correctly instead of being flattened to `a + b * c`.
10347#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10348#[cfg_attr(feature = "bindings", derive(TS))]
10349pub struct Paren {
10350    /// The inner expression wrapped by parentheses.
10351    pub this: Expression,
10352    #[serde(default)]
10353    pub trailing_comments: Vec<String>,
10354}
10355
10356/// Expression annotated with trailing comments (for round-trip preservation)
10357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10358#[cfg_attr(feature = "bindings", derive(TS))]
10359pub struct Annotated {
10360    pub this: Expression,
10361    pub trailing_comments: Vec<String>,
10362}
10363
10364// === BATCH GENERATED STRUCT DEFINITIONS ===
10365// Generated from Python sqlglot expressions.py
10366
10367/// Refresh
10368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10369#[cfg_attr(feature = "bindings", derive(TS))]
10370pub struct Refresh {
10371    pub this: Box<Expression>,
10372    pub kind: String,
10373}
10374
10375/// LockingStatement
10376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10377#[cfg_attr(feature = "bindings", derive(TS))]
10378pub struct LockingStatement {
10379    pub this: Box<Expression>,
10380    pub expression: Box<Expression>,
10381}
10382
10383/// SequenceProperties
10384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10385#[cfg_attr(feature = "bindings", derive(TS))]
10386pub struct SequenceProperties {
10387    #[serde(default)]
10388    pub increment: Option<Box<Expression>>,
10389    #[serde(default)]
10390    pub minvalue: Option<Box<Expression>>,
10391    #[serde(default)]
10392    pub maxvalue: Option<Box<Expression>>,
10393    #[serde(default)]
10394    pub cache: Option<Box<Expression>>,
10395    #[serde(default)]
10396    pub start: Option<Box<Expression>>,
10397    #[serde(default)]
10398    pub owned: Option<Box<Expression>>,
10399    #[serde(default)]
10400    pub options: Vec<Expression>,
10401}
10402
10403/// TruncateTable
10404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10405#[cfg_attr(feature = "bindings", derive(TS))]
10406pub struct TruncateTable {
10407    #[serde(default)]
10408    pub expressions: Vec<Expression>,
10409    #[serde(default)]
10410    pub is_database: Option<Box<Expression>>,
10411    #[serde(default)]
10412    pub exists: bool,
10413    #[serde(default)]
10414    pub only: Option<Box<Expression>>,
10415    #[serde(default)]
10416    pub cluster: Option<Box<Expression>>,
10417    #[serde(default)]
10418    pub identity: Option<Box<Expression>>,
10419    #[serde(default)]
10420    pub option: Option<Box<Expression>>,
10421    #[serde(default)]
10422    pub partition: Option<Box<Expression>>,
10423}
10424
10425/// Clone
10426#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10427#[cfg_attr(feature = "bindings", derive(TS))]
10428pub struct Clone {
10429    pub this: Box<Expression>,
10430    #[serde(default)]
10431    pub shallow: Option<Box<Expression>>,
10432    #[serde(default)]
10433    pub copy: Option<Box<Expression>>,
10434}
10435
10436/// Attach
10437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10438#[cfg_attr(feature = "bindings", derive(TS))]
10439pub struct Attach {
10440    pub this: Box<Expression>,
10441    #[serde(default)]
10442    pub exists: bool,
10443    #[serde(default)]
10444    pub expressions: Vec<Expression>,
10445}
10446
10447/// Detach
10448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10449#[cfg_attr(feature = "bindings", derive(TS))]
10450pub struct Detach {
10451    pub this: Box<Expression>,
10452    #[serde(default)]
10453    pub exists: bool,
10454}
10455
10456/// Install
10457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10458#[cfg_attr(feature = "bindings", derive(TS))]
10459pub struct Install {
10460    pub this: Box<Expression>,
10461    #[serde(default)]
10462    pub from_: Option<Box<Expression>>,
10463    #[serde(default)]
10464    pub force: Option<Box<Expression>>,
10465}
10466
10467/// Summarize
10468#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10469#[cfg_attr(feature = "bindings", derive(TS))]
10470pub struct Summarize {
10471    pub this: Box<Expression>,
10472    #[serde(default)]
10473    pub table: Option<Box<Expression>>,
10474}
10475
10476/// Declare
10477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10478#[cfg_attr(feature = "bindings", derive(TS))]
10479pub struct Declare {
10480    #[serde(default)]
10481    pub expressions: Vec<Expression>,
10482    #[serde(default)]
10483    pub replace: bool,
10484}
10485
10486/// DeclareItem
10487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10488#[cfg_attr(feature = "bindings", derive(TS))]
10489pub struct DeclareItem {
10490    pub this: Box<Expression>,
10491    #[serde(default)]
10492    pub kind: Option<String>,
10493    #[serde(default)]
10494    pub default: Option<Box<Expression>>,
10495    #[serde(default)]
10496    pub has_as: bool,
10497    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10498    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10499    pub additional_names: Vec<Expression>,
10500}
10501
10502/// Set
10503#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10504#[cfg_attr(feature = "bindings", derive(TS))]
10505pub struct Set {
10506    #[serde(default)]
10507    pub expressions: Vec<Expression>,
10508    #[serde(default)]
10509    pub unset: Option<Box<Expression>>,
10510    #[serde(default)]
10511    pub tag: Option<Box<Expression>>,
10512}
10513
10514/// Heredoc
10515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10516#[cfg_attr(feature = "bindings", derive(TS))]
10517pub struct Heredoc {
10518    pub this: Box<Expression>,
10519    #[serde(default)]
10520    pub tag: Option<Box<Expression>>,
10521}
10522
10523/// QueryBand
10524#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10525#[cfg_attr(feature = "bindings", derive(TS))]
10526pub struct QueryBand {
10527    pub this: Box<Expression>,
10528    #[serde(default)]
10529    pub scope: Option<Box<Expression>>,
10530    #[serde(default)]
10531    pub update: Option<Box<Expression>>,
10532}
10533
10534/// UserDefinedFunction
10535#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10536#[cfg_attr(feature = "bindings", derive(TS))]
10537pub struct UserDefinedFunction {
10538    pub this: Box<Expression>,
10539    #[serde(default)]
10540    pub expressions: Vec<Expression>,
10541    #[serde(default)]
10542    pub wrapped: Option<Box<Expression>>,
10543}
10544
10545/// RecursiveWithSearch
10546#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10547#[cfg_attr(feature = "bindings", derive(TS))]
10548pub struct RecursiveWithSearch {
10549    pub kind: String,
10550    pub this: Box<Expression>,
10551    pub expression: Box<Expression>,
10552    #[serde(default)]
10553    pub using: Option<Box<Expression>>,
10554}
10555
10556/// ProjectionDef
10557#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10558#[cfg_attr(feature = "bindings", derive(TS))]
10559pub struct ProjectionDef {
10560    pub this: Box<Expression>,
10561    pub expression: Box<Expression>,
10562}
10563
10564/// TableAlias
10565#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10566#[cfg_attr(feature = "bindings", derive(TS))]
10567pub struct TableAlias {
10568    #[serde(default)]
10569    pub this: Option<Box<Expression>>,
10570    #[serde(default)]
10571    pub columns: Vec<Expression>,
10572}
10573
10574/// ByteString
10575#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10576#[cfg_attr(feature = "bindings", derive(TS))]
10577pub struct ByteString {
10578    pub this: Box<Expression>,
10579    #[serde(default)]
10580    pub is_bytes: Option<Box<Expression>>,
10581}
10582
10583/// HexStringExpr - Hex string expression (not literal)
10584/// BigQuery: converts to FROM_HEX(this)
10585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10586#[cfg_attr(feature = "bindings", derive(TS))]
10587pub struct HexStringExpr {
10588    pub this: Box<Expression>,
10589    #[serde(default)]
10590    pub is_integer: Option<bool>,
10591}
10592
10593/// UnicodeString
10594#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10595#[cfg_attr(feature = "bindings", derive(TS))]
10596pub struct UnicodeString {
10597    pub this: Box<Expression>,
10598    #[serde(default)]
10599    pub escape: Option<Box<Expression>>,
10600}
10601
10602/// AlterColumn
10603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10604#[cfg_attr(feature = "bindings", derive(TS))]
10605pub struct AlterColumn {
10606    pub this: Box<Expression>,
10607    #[serde(default)]
10608    pub dtype: Option<Box<Expression>>,
10609    #[serde(default)]
10610    pub collate: Option<Box<Expression>>,
10611    #[serde(default)]
10612    pub using: Option<Box<Expression>>,
10613    #[serde(default)]
10614    pub default: Option<Box<Expression>>,
10615    #[serde(default)]
10616    pub drop: Option<Box<Expression>>,
10617    #[serde(default)]
10618    pub comment: Option<Box<Expression>>,
10619    #[serde(default)]
10620    pub allow_null: Option<Box<Expression>>,
10621    #[serde(default)]
10622    pub visible: Option<Box<Expression>>,
10623    #[serde(default)]
10624    pub rename_to: Option<Box<Expression>>,
10625}
10626
10627/// AlterSortKey
10628#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10629#[cfg_attr(feature = "bindings", derive(TS))]
10630pub struct AlterSortKey {
10631    #[serde(default)]
10632    pub this: Option<Box<Expression>>,
10633    #[serde(default)]
10634    pub expressions: Vec<Expression>,
10635    #[serde(default)]
10636    pub compound: Option<Box<Expression>>,
10637}
10638
10639/// AlterSet
10640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10641#[cfg_attr(feature = "bindings", derive(TS))]
10642pub struct AlterSet {
10643    #[serde(default)]
10644    pub expressions: Vec<Expression>,
10645    #[serde(default)]
10646    pub option: Option<Box<Expression>>,
10647    #[serde(default)]
10648    pub tablespace: Option<Box<Expression>>,
10649    #[serde(default)]
10650    pub access_method: Option<Box<Expression>>,
10651    #[serde(default)]
10652    pub file_format: Option<Box<Expression>>,
10653    #[serde(default)]
10654    pub copy_options: Option<Box<Expression>>,
10655    #[serde(default)]
10656    pub tag: Option<Box<Expression>>,
10657    #[serde(default)]
10658    pub location: Option<Box<Expression>>,
10659    #[serde(default)]
10660    pub serde: Option<Box<Expression>>,
10661}
10662
10663/// RenameColumn
10664#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10665#[cfg_attr(feature = "bindings", derive(TS))]
10666pub struct RenameColumn {
10667    pub this: Box<Expression>,
10668    #[serde(default)]
10669    pub to: Option<Box<Expression>>,
10670    #[serde(default)]
10671    pub exists: bool,
10672}
10673
10674/// Comprehension
10675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10676#[cfg_attr(feature = "bindings", derive(TS))]
10677pub struct Comprehension {
10678    pub this: Box<Expression>,
10679    pub expression: Box<Expression>,
10680    #[serde(default)]
10681    pub position: Option<Box<Expression>>,
10682    #[serde(default)]
10683    pub iterator: Option<Box<Expression>>,
10684    #[serde(default)]
10685    pub condition: Option<Box<Expression>>,
10686}
10687
10688/// MergeTreeTTLAction
10689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10690#[cfg_attr(feature = "bindings", derive(TS))]
10691pub struct MergeTreeTTLAction {
10692    pub this: Box<Expression>,
10693    #[serde(default)]
10694    pub delete: Option<Box<Expression>>,
10695    #[serde(default)]
10696    pub recompress: Option<Box<Expression>>,
10697    #[serde(default)]
10698    pub to_disk: Option<Box<Expression>>,
10699    #[serde(default)]
10700    pub to_volume: Option<Box<Expression>>,
10701}
10702
10703/// MergeTreeTTL
10704#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10705#[cfg_attr(feature = "bindings", derive(TS))]
10706pub struct MergeTreeTTL {
10707    #[serde(default)]
10708    pub expressions: Vec<Expression>,
10709    #[serde(default)]
10710    pub where_: Option<Box<Expression>>,
10711    #[serde(default)]
10712    pub group: Option<Box<Expression>>,
10713    #[serde(default)]
10714    pub aggregates: Option<Box<Expression>>,
10715}
10716
10717/// IndexConstraintOption
10718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10719#[cfg_attr(feature = "bindings", derive(TS))]
10720pub struct IndexConstraintOption {
10721    #[serde(default)]
10722    pub key_block_size: Option<Box<Expression>>,
10723    #[serde(default)]
10724    pub using: Option<Box<Expression>>,
10725    #[serde(default)]
10726    pub parser: Option<Box<Expression>>,
10727    #[serde(default)]
10728    pub comment: Option<Box<Expression>>,
10729    #[serde(default)]
10730    pub visible: Option<Box<Expression>>,
10731    #[serde(default)]
10732    pub engine_attr: Option<Box<Expression>>,
10733    #[serde(default)]
10734    pub secondary_engine_attr: Option<Box<Expression>>,
10735}
10736
10737/// PeriodForSystemTimeConstraint
10738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10739#[cfg_attr(feature = "bindings", derive(TS))]
10740pub struct PeriodForSystemTimeConstraint {
10741    pub this: Box<Expression>,
10742    pub expression: Box<Expression>,
10743}
10744
10745/// CaseSpecificColumnConstraint
10746#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10747#[cfg_attr(feature = "bindings", derive(TS))]
10748pub struct CaseSpecificColumnConstraint {
10749    #[serde(default)]
10750    pub not_: Option<Box<Expression>>,
10751}
10752
10753/// CharacterSetColumnConstraint
10754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10755#[cfg_attr(feature = "bindings", derive(TS))]
10756pub struct CharacterSetColumnConstraint {
10757    pub this: Box<Expression>,
10758}
10759
10760/// CheckColumnConstraint
10761#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10762#[cfg_attr(feature = "bindings", derive(TS))]
10763pub struct CheckColumnConstraint {
10764    pub this: Box<Expression>,
10765    #[serde(default)]
10766    pub enforced: Option<Box<Expression>>,
10767}
10768
10769/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
10770#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10771#[cfg_attr(feature = "bindings", derive(TS))]
10772pub struct AssumeColumnConstraint {
10773    pub this: Box<Expression>,
10774}
10775
10776/// CompressColumnConstraint
10777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10778#[cfg_attr(feature = "bindings", derive(TS))]
10779pub struct CompressColumnConstraint {
10780    #[serde(default)]
10781    pub this: Option<Box<Expression>>,
10782}
10783
10784/// DateFormatColumnConstraint
10785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10786#[cfg_attr(feature = "bindings", derive(TS))]
10787pub struct DateFormatColumnConstraint {
10788    pub this: Box<Expression>,
10789}
10790
10791/// EphemeralColumnConstraint
10792#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10793#[cfg_attr(feature = "bindings", derive(TS))]
10794pub struct EphemeralColumnConstraint {
10795    #[serde(default)]
10796    pub this: Option<Box<Expression>>,
10797}
10798
10799/// WithOperator
10800#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10801#[cfg_attr(feature = "bindings", derive(TS))]
10802pub struct WithOperator {
10803    pub this: Box<Expression>,
10804    pub op: String,
10805}
10806
10807/// GeneratedAsIdentityColumnConstraint
10808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10809#[cfg_attr(feature = "bindings", derive(TS))]
10810pub struct GeneratedAsIdentityColumnConstraint {
10811    #[serde(default)]
10812    pub this: Option<Box<Expression>>,
10813    #[serde(default)]
10814    pub expression: Option<Box<Expression>>,
10815    #[serde(default)]
10816    pub on_null: Option<Box<Expression>>,
10817    #[serde(default)]
10818    pub start: Option<Box<Expression>>,
10819    #[serde(default)]
10820    pub increment: Option<Box<Expression>>,
10821    #[serde(default)]
10822    pub minvalue: Option<Box<Expression>>,
10823    #[serde(default)]
10824    pub maxvalue: Option<Box<Expression>>,
10825    #[serde(default)]
10826    pub cycle: Option<Box<Expression>>,
10827    #[serde(default)]
10828    pub order: Option<Box<Expression>>,
10829}
10830
10831/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
10832/// TSQL: outputs "IDENTITY"
10833#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10834#[cfg_attr(feature = "bindings", derive(TS))]
10835pub struct AutoIncrementColumnConstraint;
10836
10837/// CommentColumnConstraint - Column comment marker
10838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10839#[cfg_attr(feature = "bindings", derive(TS))]
10840pub struct CommentColumnConstraint;
10841
10842/// GeneratedAsRowColumnConstraint
10843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10844#[cfg_attr(feature = "bindings", derive(TS))]
10845pub struct GeneratedAsRowColumnConstraint {
10846    #[serde(default)]
10847    pub start: Option<Box<Expression>>,
10848    #[serde(default)]
10849    pub hidden: Option<Box<Expression>>,
10850}
10851
10852/// IndexColumnConstraint
10853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10854#[cfg_attr(feature = "bindings", derive(TS))]
10855pub struct IndexColumnConstraint {
10856    #[serde(default)]
10857    pub this: Option<Box<Expression>>,
10858    #[serde(default)]
10859    pub expressions: Vec<Expression>,
10860    #[serde(default)]
10861    pub kind: Option<String>,
10862    #[serde(default)]
10863    pub index_type: Option<Box<Expression>>,
10864    #[serde(default)]
10865    pub options: Vec<Expression>,
10866    #[serde(default)]
10867    pub expression: Option<Box<Expression>>,
10868    #[serde(default)]
10869    pub granularity: Option<Box<Expression>>,
10870}
10871
10872/// MaskingPolicyColumnConstraint
10873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10874#[cfg_attr(feature = "bindings", derive(TS))]
10875pub struct MaskingPolicyColumnConstraint {
10876    pub this: Box<Expression>,
10877    #[serde(default)]
10878    pub expressions: Vec<Expression>,
10879}
10880
10881/// NotNullColumnConstraint
10882#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10883#[cfg_attr(feature = "bindings", derive(TS))]
10884pub struct NotNullColumnConstraint {
10885    #[serde(default)]
10886    pub allow_null: Option<Box<Expression>>,
10887}
10888
10889/// DefaultColumnConstraint - DEFAULT value for a column
10890#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10891#[cfg_attr(feature = "bindings", derive(TS))]
10892pub struct DefaultColumnConstraint {
10893    pub this: Box<Expression>,
10894    /// TSQL: DEFAULT value FOR column (table-level default constraint)
10895    #[serde(default, skip_serializing_if = "Option::is_none")]
10896    pub for_column: Option<Identifier>,
10897}
10898
10899/// PrimaryKeyColumnConstraint
10900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10901#[cfg_attr(feature = "bindings", derive(TS))]
10902pub struct PrimaryKeyColumnConstraint {
10903    #[serde(default)]
10904    pub desc: Option<Box<Expression>>,
10905    #[serde(default)]
10906    pub options: Vec<Expression>,
10907}
10908
10909/// UniqueColumnConstraint
10910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10911#[cfg_attr(feature = "bindings", derive(TS))]
10912pub struct UniqueColumnConstraint {
10913    #[serde(default)]
10914    pub this: Option<Box<Expression>>,
10915    #[serde(default)]
10916    pub index_type: Option<Box<Expression>>,
10917    #[serde(default)]
10918    pub on_conflict: Option<Box<Expression>>,
10919    #[serde(default)]
10920    pub nulls: Option<Box<Expression>>,
10921    #[serde(default)]
10922    pub options: Vec<Expression>,
10923}
10924
10925/// WatermarkColumnConstraint
10926#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10927#[cfg_attr(feature = "bindings", derive(TS))]
10928pub struct WatermarkColumnConstraint {
10929    pub this: Box<Expression>,
10930    pub expression: Box<Expression>,
10931}
10932
10933/// ComputedColumnConstraint
10934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10935#[cfg_attr(feature = "bindings", derive(TS))]
10936pub struct ComputedColumnConstraint {
10937    pub this: Box<Expression>,
10938    #[serde(default)]
10939    pub persisted: Option<Box<Expression>>,
10940    #[serde(default)]
10941    pub not_null: Option<Box<Expression>>,
10942    #[serde(default)]
10943    pub data_type: Option<Box<Expression>>,
10944}
10945
10946/// InOutColumnConstraint
10947#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10948#[cfg_attr(feature = "bindings", derive(TS))]
10949pub struct InOutColumnConstraint {
10950    #[serde(default)]
10951    pub input_: Option<Box<Expression>>,
10952    #[serde(default)]
10953    pub output: Option<Box<Expression>>,
10954}
10955
10956/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
10957#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10958#[cfg_attr(feature = "bindings", derive(TS))]
10959pub struct PathColumnConstraint {
10960    pub this: Box<Expression>,
10961}
10962
10963/// Constraint
10964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10965#[cfg_attr(feature = "bindings", derive(TS))]
10966pub struct Constraint {
10967    pub this: Box<Expression>,
10968    #[serde(default)]
10969    pub expressions: Vec<Expression>,
10970}
10971
10972/// Export
10973#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10974#[cfg_attr(feature = "bindings", derive(TS))]
10975pub struct Export {
10976    pub this: Box<Expression>,
10977    #[serde(default)]
10978    pub connection: Option<Box<Expression>>,
10979    #[serde(default)]
10980    pub options: Vec<Expression>,
10981}
10982
10983/// Filter
10984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10985#[cfg_attr(feature = "bindings", derive(TS))]
10986pub struct Filter {
10987    pub this: Box<Expression>,
10988    pub expression: Box<Expression>,
10989}
10990
10991/// Changes
10992#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10993#[cfg_attr(feature = "bindings", derive(TS))]
10994pub struct Changes {
10995    #[serde(default)]
10996    pub information: Option<Box<Expression>>,
10997    #[serde(default)]
10998    pub at_before: Option<Box<Expression>>,
10999    #[serde(default)]
11000    pub end: Option<Box<Expression>>,
11001}
11002
11003/// Directory
11004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11005#[cfg_attr(feature = "bindings", derive(TS))]
11006pub struct Directory {
11007    pub this: Box<Expression>,
11008    #[serde(default)]
11009    pub local: Option<Box<Expression>>,
11010    #[serde(default)]
11011    pub row_format: Option<Box<Expression>>,
11012}
11013
11014/// ForeignKey
11015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11016#[cfg_attr(feature = "bindings", derive(TS))]
11017pub struct ForeignKey {
11018    #[serde(default)]
11019    pub expressions: Vec<Expression>,
11020    #[serde(default)]
11021    pub reference: Option<Box<Expression>>,
11022    #[serde(default)]
11023    pub delete: Option<Box<Expression>>,
11024    #[serde(default)]
11025    pub update: Option<Box<Expression>>,
11026    #[serde(default)]
11027    pub options: Vec<Expression>,
11028}
11029
11030/// ColumnPrefix
11031#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11032#[cfg_attr(feature = "bindings", derive(TS))]
11033pub struct ColumnPrefix {
11034    pub this: Box<Expression>,
11035    pub expression: Box<Expression>,
11036}
11037
11038/// PrimaryKey
11039#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11040#[cfg_attr(feature = "bindings", derive(TS))]
11041pub struct PrimaryKey {
11042    #[serde(default)]
11043    pub this: Option<Box<Expression>>,
11044    #[serde(default)]
11045    pub expressions: Vec<Expression>,
11046    #[serde(default)]
11047    pub options: Vec<Expression>,
11048    #[serde(default)]
11049    pub include: Option<Box<Expression>>,
11050}
11051
11052/// Into
11053#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11054#[cfg_attr(feature = "bindings", derive(TS))]
11055pub struct IntoClause {
11056    #[serde(default)]
11057    pub this: Option<Box<Expression>>,
11058    #[serde(default)]
11059    pub temporary: bool,
11060    #[serde(default)]
11061    pub unlogged: Option<Box<Expression>>,
11062    #[serde(default)]
11063    pub bulk_collect: Option<Box<Expression>>,
11064    #[serde(default)]
11065    pub expressions: Vec<Expression>,
11066}
11067
11068/// JoinHint
11069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11070#[cfg_attr(feature = "bindings", derive(TS))]
11071pub struct JoinHint {
11072    pub this: Box<Expression>,
11073    #[serde(default)]
11074    pub expressions: Vec<Expression>,
11075}
11076
11077/// Opclass
11078#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11079#[cfg_attr(feature = "bindings", derive(TS))]
11080pub struct Opclass {
11081    pub this: Box<Expression>,
11082    pub expression: Box<Expression>,
11083}
11084
11085/// Index
11086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11087#[cfg_attr(feature = "bindings", derive(TS))]
11088pub struct Index {
11089    #[serde(default)]
11090    pub this: Option<Box<Expression>>,
11091    #[serde(default)]
11092    pub table: Option<Box<Expression>>,
11093    #[serde(default)]
11094    pub unique: bool,
11095    #[serde(default)]
11096    pub primary: Option<Box<Expression>>,
11097    #[serde(default)]
11098    pub amp: Option<Box<Expression>>,
11099    #[serde(default)]
11100    pub params: Vec<Expression>,
11101}
11102
11103/// IndexParameters
11104#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11105#[cfg_attr(feature = "bindings", derive(TS))]
11106pub struct IndexParameters {
11107    #[serde(default)]
11108    pub using: Option<Box<Expression>>,
11109    #[serde(default)]
11110    pub include: Option<Box<Expression>>,
11111    #[serde(default)]
11112    pub columns: Vec<Expression>,
11113    #[serde(default)]
11114    pub with_storage: Option<Box<Expression>>,
11115    #[serde(default)]
11116    pub partition_by: Option<Box<Expression>>,
11117    #[serde(default)]
11118    pub tablespace: Option<Box<Expression>>,
11119    #[serde(default)]
11120    pub where_: Option<Box<Expression>>,
11121    #[serde(default)]
11122    pub on: Option<Box<Expression>>,
11123}
11124
11125/// ConditionalInsert
11126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11127#[cfg_attr(feature = "bindings", derive(TS))]
11128pub struct ConditionalInsert {
11129    pub this: Box<Expression>,
11130    #[serde(default)]
11131    pub expression: Option<Box<Expression>>,
11132    #[serde(default)]
11133    pub else_: Option<Box<Expression>>,
11134}
11135
11136/// MultitableInserts
11137#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11138#[cfg_attr(feature = "bindings", derive(TS))]
11139pub struct MultitableInserts {
11140    #[serde(default)]
11141    pub expressions: Vec<Expression>,
11142    pub kind: String,
11143    #[serde(default)]
11144    pub source: Option<Box<Expression>>,
11145    /// Leading comments before the statement
11146    #[serde(default)]
11147    pub leading_comments: Vec<String>,
11148    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
11149    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11150    pub overwrite: bool,
11151}
11152
11153/// OnConflict
11154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11155#[cfg_attr(feature = "bindings", derive(TS))]
11156pub struct OnConflict {
11157    #[serde(default)]
11158    pub duplicate: Option<Box<Expression>>,
11159    #[serde(default)]
11160    pub expressions: Vec<Expression>,
11161    #[serde(default)]
11162    pub action: Option<Box<Expression>>,
11163    #[serde(default)]
11164    pub conflict_keys: Option<Box<Expression>>,
11165    #[serde(default)]
11166    pub index_predicate: Option<Box<Expression>>,
11167    #[serde(default)]
11168    pub constraint: Option<Box<Expression>>,
11169    #[serde(default)]
11170    pub where_: Option<Box<Expression>>,
11171}
11172
11173/// OnCondition
11174#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11175#[cfg_attr(feature = "bindings", derive(TS))]
11176pub struct OnCondition {
11177    #[serde(default)]
11178    pub error: Option<Box<Expression>>,
11179    #[serde(default)]
11180    pub empty: Option<Box<Expression>>,
11181    #[serde(default)]
11182    pub null: Option<Box<Expression>>,
11183}
11184
11185/// Returning
11186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11187#[cfg_attr(feature = "bindings", derive(TS))]
11188pub struct Returning {
11189    #[serde(default)]
11190    pub expressions: Vec<Expression>,
11191    #[serde(default)]
11192    pub into: Option<Box<Expression>>,
11193}
11194
11195/// Introducer
11196#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11197#[cfg_attr(feature = "bindings", derive(TS))]
11198pub struct Introducer {
11199    pub this: Box<Expression>,
11200    pub expression: Box<Expression>,
11201}
11202
11203/// PartitionRange
11204#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11205#[cfg_attr(feature = "bindings", derive(TS))]
11206pub struct PartitionRange {
11207    pub this: Box<Expression>,
11208    #[serde(default)]
11209    pub expression: Option<Box<Expression>>,
11210    #[serde(default)]
11211    pub expressions: Vec<Expression>,
11212}
11213
11214/// Group
11215#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11216#[cfg_attr(feature = "bindings", derive(TS))]
11217pub struct Group {
11218    #[serde(default)]
11219    pub expressions: Vec<Expression>,
11220    #[serde(default)]
11221    pub grouping_sets: Option<Box<Expression>>,
11222    #[serde(default)]
11223    pub cube: Option<Box<Expression>>,
11224    #[serde(default)]
11225    pub rollup: Option<Box<Expression>>,
11226    #[serde(default)]
11227    pub totals: Option<Box<Expression>>,
11228    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11229    #[serde(default)]
11230    pub all: Option<bool>,
11231}
11232
11233/// Cube
11234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11235#[cfg_attr(feature = "bindings", derive(TS))]
11236pub struct Cube {
11237    #[serde(default)]
11238    pub expressions: Vec<Expression>,
11239}
11240
11241/// Rollup
11242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11243#[cfg_attr(feature = "bindings", derive(TS))]
11244pub struct Rollup {
11245    #[serde(default)]
11246    pub expressions: Vec<Expression>,
11247}
11248
11249/// GroupingSets
11250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11251#[cfg_attr(feature = "bindings", derive(TS))]
11252pub struct GroupingSets {
11253    #[serde(default)]
11254    pub expressions: Vec<Expression>,
11255}
11256
11257/// LimitOptions
11258#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11259#[cfg_attr(feature = "bindings", derive(TS))]
11260pub struct LimitOptions {
11261    #[serde(default)]
11262    pub percent: Option<Box<Expression>>,
11263    #[serde(default)]
11264    pub rows: Option<Box<Expression>>,
11265    #[serde(default)]
11266    pub with_ties: Option<Box<Expression>>,
11267}
11268
11269/// Lateral
11270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11271#[cfg_attr(feature = "bindings", derive(TS))]
11272pub struct Lateral {
11273    pub this: Box<Expression>,
11274    #[serde(default)]
11275    pub view: Option<Box<Expression>>,
11276    #[serde(default)]
11277    pub outer: Option<Box<Expression>>,
11278    #[serde(default)]
11279    pub alias: Option<String>,
11280    /// Whether the alias was originally quoted (backtick/double-quote)
11281    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11282    pub alias_quoted: bool,
11283    #[serde(default)]
11284    pub cross_apply: Option<Box<Expression>>,
11285    #[serde(default)]
11286    pub ordinality: Option<Box<Expression>>,
11287    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11288    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11289    pub column_aliases: Vec<String>,
11290}
11291
11292/// TableFromRows
11293#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11294#[cfg_attr(feature = "bindings", derive(TS))]
11295pub struct TableFromRows {
11296    pub this: Box<Expression>,
11297    #[serde(default)]
11298    pub alias: Option<String>,
11299    #[serde(default)]
11300    pub joins: Vec<Expression>,
11301    #[serde(default)]
11302    pub pivots: Option<Box<Expression>>,
11303    #[serde(default)]
11304    pub sample: Option<Box<Expression>>,
11305}
11306
11307/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11308/// Used for set-returning functions with typed column definitions
11309#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11310#[cfg_attr(feature = "bindings", derive(TS))]
11311pub struct RowsFrom {
11312    /// List of function expressions, each potentially with an alias and typed columns
11313    pub expressions: Vec<Expression>,
11314    /// WITH ORDINALITY modifier
11315    #[serde(default)]
11316    pub ordinality: bool,
11317    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11318    #[serde(default)]
11319    pub alias: Option<Box<Expression>>,
11320}
11321
11322/// WithFill
11323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11324#[cfg_attr(feature = "bindings", derive(TS))]
11325pub struct WithFill {
11326    #[serde(default)]
11327    pub from_: Option<Box<Expression>>,
11328    #[serde(default)]
11329    pub to: Option<Box<Expression>>,
11330    #[serde(default)]
11331    pub step: Option<Box<Expression>>,
11332    #[serde(default)]
11333    pub staleness: Option<Box<Expression>>,
11334    #[serde(default)]
11335    pub interpolate: Option<Box<Expression>>,
11336}
11337
11338/// Property
11339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11340#[cfg_attr(feature = "bindings", derive(TS))]
11341pub struct Property {
11342    pub this: Box<Expression>,
11343    #[serde(default)]
11344    pub value: Option<Box<Expression>>,
11345}
11346
11347/// GrantPrivilege
11348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11349#[cfg_attr(feature = "bindings", derive(TS))]
11350pub struct GrantPrivilege {
11351    pub this: Box<Expression>,
11352    #[serde(default)]
11353    pub expressions: Vec<Expression>,
11354}
11355
11356/// AllowedValuesProperty
11357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11358#[cfg_attr(feature = "bindings", derive(TS))]
11359pub struct AllowedValuesProperty {
11360    #[serde(default)]
11361    pub expressions: Vec<Expression>,
11362}
11363
11364/// AlgorithmProperty
11365#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11366#[cfg_attr(feature = "bindings", derive(TS))]
11367pub struct AlgorithmProperty {
11368    pub this: Box<Expression>,
11369}
11370
11371/// AutoIncrementProperty
11372#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11373#[cfg_attr(feature = "bindings", derive(TS))]
11374pub struct AutoIncrementProperty {
11375    pub this: Box<Expression>,
11376}
11377
11378/// AutoRefreshProperty
11379#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11380#[cfg_attr(feature = "bindings", derive(TS))]
11381pub struct AutoRefreshProperty {
11382    pub this: Box<Expression>,
11383}
11384
11385/// BackupProperty
11386#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11387#[cfg_attr(feature = "bindings", derive(TS))]
11388pub struct BackupProperty {
11389    pub this: Box<Expression>,
11390}
11391
11392/// BuildProperty
11393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11394#[cfg_attr(feature = "bindings", derive(TS))]
11395pub struct BuildProperty {
11396    pub this: Box<Expression>,
11397}
11398
11399/// BlockCompressionProperty
11400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11401#[cfg_attr(feature = "bindings", derive(TS))]
11402pub struct BlockCompressionProperty {
11403    #[serde(default)]
11404    pub autotemp: Option<Box<Expression>>,
11405    #[serde(default)]
11406    pub always: Option<Box<Expression>>,
11407    #[serde(default)]
11408    pub default: Option<Box<Expression>>,
11409    #[serde(default)]
11410    pub manual: Option<Box<Expression>>,
11411    #[serde(default)]
11412    pub never: Option<Box<Expression>>,
11413}
11414
11415/// CharacterSetProperty
11416#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11417#[cfg_attr(feature = "bindings", derive(TS))]
11418pub struct CharacterSetProperty {
11419    pub this: Box<Expression>,
11420    #[serde(default)]
11421    pub default: Option<Box<Expression>>,
11422}
11423
11424/// ChecksumProperty
11425#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11426#[cfg_attr(feature = "bindings", derive(TS))]
11427pub struct ChecksumProperty {
11428    #[serde(default)]
11429    pub on: Option<Box<Expression>>,
11430    #[serde(default)]
11431    pub default: Option<Box<Expression>>,
11432}
11433
11434/// CollateProperty
11435#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11436#[cfg_attr(feature = "bindings", derive(TS))]
11437pub struct CollateProperty {
11438    pub this: Box<Expression>,
11439    #[serde(default)]
11440    pub default: Option<Box<Expression>>,
11441}
11442
11443/// DataBlocksizeProperty
11444#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11445#[cfg_attr(feature = "bindings", derive(TS))]
11446pub struct DataBlocksizeProperty {
11447    #[serde(default)]
11448    pub size: Option<i64>,
11449    #[serde(default)]
11450    pub units: Option<Box<Expression>>,
11451    #[serde(default)]
11452    pub minimum: Option<Box<Expression>>,
11453    #[serde(default)]
11454    pub maximum: Option<Box<Expression>>,
11455    #[serde(default)]
11456    pub default: Option<Box<Expression>>,
11457}
11458
11459/// DataDeletionProperty
11460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11461#[cfg_attr(feature = "bindings", derive(TS))]
11462pub struct DataDeletionProperty {
11463    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11464    #[ast(skip)]
11465    pub on: Box<Expression>,
11466    #[serde(default)]
11467    pub filter_column: Option<Box<Expression>>,
11468    #[serde(default)]
11469    pub retention_period: Option<Box<Expression>>,
11470}
11471
11472/// DefinerProperty
11473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11474#[cfg_attr(feature = "bindings", derive(TS))]
11475pub struct DefinerProperty {
11476    pub this: Box<Expression>,
11477}
11478
11479/// DistKeyProperty
11480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11481#[cfg_attr(feature = "bindings", derive(TS))]
11482pub struct DistKeyProperty {
11483    pub this: Box<Expression>,
11484}
11485
11486/// DistributedByProperty
11487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11488#[cfg_attr(feature = "bindings", derive(TS))]
11489pub struct DistributedByProperty {
11490    #[serde(default)]
11491    pub expressions: Vec<Expression>,
11492    pub kind: String,
11493    #[serde(default)]
11494    pub buckets: Option<Box<Expression>>,
11495    #[serde(default)]
11496    pub order: Option<Box<Expression>>,
11497}
11498
11499/// DistStyleProperty
11500#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11501#[cfg_attr(feature = "bindings", derive(TS))]
11502pub struct DistStyleProperty {
11503    pub this: Box<Expression>,
11504}
11505
11506/// DuplicateKeyProperty
11507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11508#[cfg_attr(feature = "bindings", derive(TS))]
11509pub struct DuplicateKeyProperty {
11510    #[serde(default)]
11511    pub expressions: Vec<Expression>,
11512}
11513
11514/// EngineProperty
11515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11516#[cfg_attr(feature = "bindings", derive(TS))]
11517pub struct EngineProperty {
11518    pub this: Box<Expression>,
11519}
11520
11521/// ToTableProperty
11522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11523#[cfg_attr(feature = "bindings", derive(TS))]
11524pub struct ToTableProperty {
11525    pub this: Box<Expression>,
11526}
11527
11528/// ExecuteAsProperty
11529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11530#[cfg_attr(feature = "bindings", derive(TS))]
11531pub struct ExecuteAsProperty {
11532    pub this: Box<Expression>,
11533}
11534
11535/// ExternalProperty
11536#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11537#[cfg_attr(feature = "bindings", derive(TS))]
11538pub struct ExternalProperty {
11539    #[serde(default)]
11540    pub this: Option<Box<Expression>>,
11541}
11542
11543/// FallbackProperty
11544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11545#[cfg_attr(feature = "bindings", derive(TS))]
11546pub struct FallbackProperty {
11547    #[serde(default)]
11548    pub no: Option<Box<Expression>>,
11549    #[serde(default)]
11550    pub protection: Option<Box<Expression>>,
11551}
11552
11553/// FileFormatProperty
11554#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11555#[cfg_attr(feature = "bindings", derive(TS))]
11556pub struct FileFormatProperty {
11557    #[serde(default)]
11558    pub this: Option<Box<Expression>>,
11559    #[serde(default)]
11560    pub expressions: Vec<Expression>,
11561    #[serde(default)]
11562    pub hive_format: Option<Box<Expression>>,
11563}
11564
11565/// CredentialsProperty
11566#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11567#[cfg_attr(feature = "bindings", derive(TS))]
11568pub struct CredentialsProperty {
11569    #[serde(default)]
11570    pub expressions: Vec<Expression>,
11571}
11572
11573/// FreespaceProperty
11574#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11575#[cfg_attr(feature = "bindings", derive(TS))]
11576pub struct FreespaceProperty {
11577    pub this: Box<Expression>,
11578    #[serde(default)]
11579    pub percent: Option<Box<Expression>>,
11580}
11581
11582/// InheritsProperty
11583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11584#[cfg_attr(feature = "bindings", derive(TS))]
11585pub struct InheritsProperty {
11586    #[serde(default)]
11587    pub expressions: Vec<Expression>,
11588}
11589
11590/// InputModelProperty
11591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11592#[cfg_attr(feature = "bindings", derive(TS))]
11593pub struct InputModelProperty {
11594    pub this: Box<Expression>,
11595}
11596
11597/// OutputModelProperty
11598#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11599#[cfg_attr(feature = "bindings", derive(TS))]
11600pub struct OutputModelProperty {
11601    pub this: Box<Expression>,
11602}
11603
11604/// IsolatedLoadingProperty
11605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11606#[cfg_attr(feature = "bindings", derive(TS))]
11607pub struct IsolatedLoadingProperty {
11608    #[serde(default)]
11609    pub no: Option<Box<Expression>>,
11610    #[serde(default)]
11611    pub concurrent: Option<Box<Expression>>,
11612    #[serde(default)]
11613    pub target: Option<Box<Expression>>,
11614}
11615
11616/// JournalProperty
11617#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11618#[cfg_attr(feature = "bindings", derive(TS))]
11619pub struct JournalProperty {
11620    #[serde(default)]
11621    pub no: Option<Box<Expression>>,
11622    #[serde(default)]
11623    pub dual: Option<Box<Expression>>,
11624    #[serde(default)]
11625    pub before: Option<Box<Expression>>,
11626    #[serde(default)]
11627    pub local: Option<Box<Expression>>,
11628    #[serde(default)]
11629    pub after: Option<Box<Expression>>,
11630}
11631
11632/// LanguageProperty
11633#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11634#[cfg_attr(feature = "bindings", derive(TS))]
11635pub struct LanguageProperty {
11636    pub this: Box<Expression>,
11637}
11638
11639/// EnviromentProperty
11640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11641#[cfg_attr(feature = "bindings", derive(TS))]
11642pub struct EnviromentProperty {
11643    #[serde(default)]
11644    pub expressions: Vec<Expression>,
11645}
11646
11647/// ClusteredByProperty
11648#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11649#[cfg_attr(feature = "bindings", derive(TS))]
11650pub struct ClusteredByProperty {
11651    #[serde(default)]
11652    pub expressions: Vec<Expression>,
11653    #[serde(default)]
11654    pub sorted_by: Option<Box<Expression>>,
11655    #[serde(default)]
11656    pub buckets: Option<Box<Expression>>,
11657}
11658
11659/// DictProperty
11660#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11661#[cfg_attr(feature = "bindings", derive(TS))]
11662pub struct DictProperty {
11663    pub this: Box<Expression>,
11664    pub kind: String,
11665    #[serde(default)]
11666    pub settings: Option<Box<Expression>>,
11667}
11668
11669/// DictRange
11670#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11671#[cfg_attr(feature = "bindings", derive(TS))]
11672pub struct DictRange {
11673    pub this: Box<Expression>,
11674    #[serde(default)]
11675    pub min: Option<Box<Expression>>,
11676    #[serde(default)]
11677    pub max: Option<Box<Expression>>,
11678}
11679
11680/// OnCluster
11681#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11682#[cfg_attr(feature = "bindings", derive(TS))]
11683pub struct OnCluster {
11684    pub this: Box<Expression>,
11685}
11686
11687/// LikeProperty
11688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11689#[cfg_attr(feature = "bindings", derive(TS))]
11690pub struct LikeProperty {
11691    pub this: Box<Expression>,
11692    #[serde(default)]
11693    pub expressions: Vec<Expression>,
11694}
11695
11696/// LocationProperty
11697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11698#[cfg_attr(feature = "bindings", derive(TS))]
11699pub struct LocationProperty {
11700    pub this: Box<Expression>,
11701}
11702
11703/// LockProperty
11704#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11705#[cfg_attr(feature = "bindings", derive(TS))]
11706pub struct LockProperty {
11707    pub this: Box<Expression>,
11708}
11709
11710/// LockingProperty
11711#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11712#[cfg_attr(feature = "bindings", derive(TS))]
11713pub struct LockingProperty {
11714    #[serde(default)]
11715    pub this: Option<Box<Expression>>,
11716    pub kind: String,
11717    #[serde(default)]
11718    pub for_or_in: Option<Box<Expression>>,
11719    #[serde(default)]
11720    pub lock_type: Option<Box<Expression>>,
11721    #[serde(default)]
11722    pub override_: Option<Box<Expression>>,
11723}
11724
11725/// LogProperty
11726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11727#[cfg_attr(feature = "bindings", derive(TS))]
11728pub struct LogProperty {
11729    #[serde(default)]
11730    pub no: Option<Box<Expression>>,
11731}
11732
11733/// MaterializedProperty
11734#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11735#[cfg_attr(feature = "bindings", derive(TS))]
11736pub struct MaterializedProperty {
11737    #[serde(default)]
11738    pub this: Option<Box<Expression>>,
11739}
11740
11741/// MergeBlockRatioProperty
11742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11743#[cfg_attr(feature = "bindings", derive(TS))]
11744pub struct MergeBlockRatioProperty {
11745    #[serde(default)]
11746    pub this: Option<Box<Expression>>,
11747    #[serde(default)]
11748    pub no: Option<Box<Expression>>,
11749    #[serde(default)]
11750    pub default: Option<Box<Expression>>,
11751    #[serde(default)]
11752    pub percent: Option<Box<Expression>>,
11753}
11754
11755/// OnProperty
11756#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11757#[cfg_attr(feature = "bindings", derive(TS))]
11758pub struct OnProperty {
11759    pub this: Box<Expression>,
11760}
11761
11762/// OnCommitProperty
11763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11764#[cfg_attr(feature = "bindings", derive(TS))]
11765pub struct OnCommitProperty {
11766    #[serde(default)]
11767    pub delete: Option<Box<Expression>>,
11768}
11769
11770/// PartitionedByProperty
11771#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11772#[cfg_attr(feature = "bindings", derive(TS))]
11773pub struct PartitionedByProperty {
11774    pub this: Box<Expression>,
11775}
11776
11777/// BigQuery PARTITION BY property in CREATE TABLE statements.
11778#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11779#[cfg_attr(feature = "bindings", derive(TS))]
11780pub struct PartitionByProperty {
11781    #[serde(default)]
11782    pub expressions: Vec<Expression>,
11783}
11784
11785/// PartitionedByBucket
11786#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11787#[cfg_attr(feature = "bindings", derive(TS))]
11788pub struct PartitionedByBucket {
11789    pub this: Box<Expression>,
11790    pub expression: Box<Expression>,
11791}
11792
11793/// BigQuery CLUSTER BY property in CREATE TABLE statements.
11794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11795#[cfg_attr(feature = "bindings", derive(TS))]
11796pub struct ClusterByColumnsProperty {
11797    #[serde(default)]
11798    pub columns: Vec<Identifier>,
11799}
11800
11801/// PartitionByTruncate
11802#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11803#[cfg_attr(feature = "bindings", derive(TS))]
11804pub struct PartitionByTruncate {
11805    pub this: Box<Expression>,
11806    pub expression: Box<Expression>,
11807}
11808
11809/// PartitionByRangeProperty
11810#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11811#[cfg_attr(feature = "bindings", derive(TS))]
11812pub struct PartitionByRangeProperty {
11813    #[serde(default)]
11814    pub partition_expressions: Option<Box<Expression>>,
11815    #[serde(default)]
11816    pub create_expressions: Option<Box<Expression>>,
11817}
11818
11819/// PartitionByRangePropertyDynamic
11820#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11821#[cfg_attr(feature = "bindings", derive(TS))]
11822pub struct PartitionByRangePropertyDynamic {
11823    #[serde(default)]
11824    pub this: Option<Box<Expression>>,
11825    #[serde(default)]
11826    pub start: Option<Box<Expression>>,
11827    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
11828    #[serde(default)]
11829    pub use_start_end: bool,
11830    #[serde(default)]
11831    pub end: Option<Box<Expression>>,
11832    #[serde(default)]
11833    pub every: Option<Box<Expression>>,
11834}
11835
11836/// PartitionByListProperty
11837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11838#[cfg_attr(feature = "bindings", derive(TS))]
11839pub struct PartitionByListProperty {
11840    #[serde(default)]
11841    pub partition_expressions: Option<Box<Expression>>,
11842    #[serde(default)]
11843    pub create_expressions: Option<Box<Expression>>,
11844}
11845
11846/// PartitionList
11847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11848#[cfg_attr(feature = "bindings", derive(TS))]
11849pub struct PartitionList {
11850    pub this: Box<Expression>,
11851    #[serde(default)]
11852    pub expressions: Vec<Expression>,
11853}
11854
11855/// Partition - represents PARTITION/SUBPARTITION clause
11856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11857#[cfg_attr(feature = "bindings", derive(TS))]
11858pub struct Partition {
11859    pub expressions: Vec<Expression>,
11860    #[serde(default)]
11861    pub subpartition: bool,
11862}
11863
11864/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
11865/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
11866#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11867#[cfg_attr(feature = "bindings", derive(TS))]
11868pub struct RefreshTriggerProperty {
11869    /// Method: COMPLETE or AUTO
11870    pub method: String,
11871    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
11872    #[serde(default)]
11873    pub kind: Option<String>,
11874    /// For SCHEDULE: EVERY n (the number)
11875    #[serde(default)]
11876    pub every: Option<Box<Expression>>,
11877    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
11878    #[serde(default)]
11879    pub unit: Option<String>,
11880    /// For SCHEDULE: STARTS 'datetime'
11881    #[serde(default)]
11882    pub starts: Option<Box<Expression>>,
11883}
11884
11885/// UniqueKeyProperty
11886#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11887#[cfg_attr(feature = "bindings", derive(TS))]
11888pub struct UniqueKeyProperty {
11889    #[serde(default)]
11890    pub expressions: Vec<Expression>,
11891}
11892
11893/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
11894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11895#[cfg_attr(feature = "bindings", derive(TS))]
11896pub struct RollupProperty {
11897    pub expressions: Vec<RollupIndex>,
11898}
11899
11900/// RollupIndex - A single rollup index: name(col1, col2)
11901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11902#[cfg_attr(feature = "bindings", derive(TS))]
11903pub struct RollupIndex {
11904    pub name: Identifier,
11905    pub expressions: Vec<Identifier>,
11906}
11907
11908/// PartitionBoundSpec
11909#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11910#[cfg_attr(feature = "bindings", derive(TS))]
11911pub struct PartitionBoundSpec {
11912    #[serde(default)]
11913    pub this: Option<Box<Expression>>,
11914    #[serde(default)]
11915    pub expression: Option<Box<Expression>>,
11916    #[serde(default)]
11917    pub from_expressions: Option<Box<Expression>>,
11918    #[serde(default)]
11919    pub to_expressions: Option<Box<Expression>>,
11920}
11921
11922/// PartitionedOfProperty
11923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11924#[cfg_attr(feature = "bindings", derive(TS))]
11925pub struct PartitionedOfProperty {
11926    pub this: Box<Expression>,
11927    pub expression: Box<Expression>,
11928}
11929
11930/// RemoteWithConnectionModelProperty
11931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11932#[cfg_attr(feature = "bindings", derive(TS))]
11933pub struct RemoteWithConnectionModelProperty {
11934    pub this: Box<Expression>,
11935}
11936
11937/// ReturnsProperty
11938#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11939#[cfg_attr(feature = "bindings", derive(TS))]
11940pub struct ReturnsProperty {
11941    #[serde(default)]
11942    pub this: Option<Box<Expression>>,
11943    #[serde(default)]
11944    pub is_table: Option<Box<Expression>>,
11945    #[serde(default)]
11946    pub table: Option<Box<Expression>>,
11947    #[serde(default)]
11948    pub null: Option<Box<Expression>>,
11949}
11950
11951/// RowFormatProperty
11952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11953#[cfg_attr(feature = "bindings", derive(TS))]
11954pub struct RowFormatProperty {
11955    pub this: Box<Expression>,
11956}
11957
11958/// RowFormatDelimitedProperty
11959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11960#[cfg_attr(feature = "bindings", derive(TS))]
11961pub struct RowFormatDelimitedProperty {
11962    #[serde(default)]
11963    pub fields: Option<Box<Expression>>,
11964    #[serde(default)]
11965    pub escaped: Option<Box<Expression>>,
11966    #[serde(default)]
11967    pub collection_items: Option<Box<Expression>>,
11968    #[serde(default)]
11969    pub map_keys: Option<Box<Expression>>,
11970    #[serde(default)]
11971    pub lines: Option<Box<Expression>>,
11972    #[serde(default)]
11973    pub null: Option<Box<Expression>>,
11974    #[serde(default)]
11975    pub serde: Option<Box<Expression>>,
11976}
11977
11978/// RowFormatSerdeProperty
11979#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11980#[cfg_attr(feature = "bindings", derive(TS))]
11981pub struct RowFormatSerdeProperty {
11982    pub this: Box<Expression>,
11983    #[serde(default)]
11984    pub serde_properties: Option<Box<Expression>>,
11985}
11986
11987/// QueryTransform
11988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11989#[cfg_attr(feature = "bindings", derive(TS))]
11990pub struct QueryTransform {
11991    #[serde(default)]
11992    pub expressions: Vec<Expression>,
11993    #[serde(default)]
11994    pub command_script: Option<Box<Expression>>,
11995    #[serde(default)]
11996    pub schema: Option<Box<Expression>>,
11997    #[serde(default)]
11998    pub row_format_before: Option<Box<Expression>>,
11999    #[serde(default)]
12000    pub record_writer: Option<Box<Expression>>,
12001    #[serde(default)]
12002    pub row_format_after: Option<Box<Expression>>,
12003    #[serde(default)]
12004    pub record_reader: Option<Box<Expression>>,
12005}
12006
12007/// SampleProperty
12008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12009#[cfg_attr(feature = "bindings", derive(TS))]
12010pub struct SampleProperty {
12011    pub this: Box<Expression>,
12012}
12013
12014/// SecurityProperty
12015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12016#[cfg_attr(feature = "bindings", derive(TS))]
12017pub struct SecurityProperty {
12018    pub this: Box<Expression>,
12019}
12020
12021/// SchemaCommentProperty
12022#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12023#[cfg_attr(feature = "bindings", derive(TS))]
12024pub struct SchemaCommentProperty {
12025    pub this: Box<Expression>,
12026}
12027
12028/// SemanticView
12029#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12030#[cfg_attr(feature = "bindings", derive(TS))]
12031pub struct SemanticView {
12032    pub this: Box<Expression>,
12033    #[serde(default)]
12034    pub metrics: Option<Box<Expression>>,
12035    #[serde(default)]
12036    pub dimensions: Option<Box<Expression>>,
12037    #[serde(default)]
12038    pub facts: Option<Box<Expression>>,
12039    #[serde(default)]
12040    pub where_: Option<Box<Expression>>,
12041}
12042
12043/// SerdeProperties
12044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12045#[cfg_attr(feature = "bindings", derive(TS))]
12046pub struct SerdeProperties {
12047    #[serde(default)]
12048    pub expressions: Vec<Expression>,
12049    #[serde(default)]
12050    pub with_: Option<Box<Expression>>,
12051}
12052
12053/// SetProperty
12054#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12055#[cfg_attr(feature = "bindings", derive(TS))]
12056pub struct SetProperty {
12057    #[serde(default)]
12058    pub multi: Option<Box<Expression>>,
12059}
12060
12061/// SharingProperty
12062#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12063#[cfg_attr(feature = "bindings", derive(TS))]
12064pub struct SharingProperty {
12065    #[serde(default)]
12066    pub this: Option<Box<Expression>>,
12067}
12068
12069/// SetConfigProperty
12070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12071#[cfg_attr(feature = "bindings", derive(TS))]
12072pub struct SetConfigProperty {
12073    pub this: Box<Expression>,
12074}
12075
12076/// SettingsProperty
12077#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12078#[cfg_attr(feature = "bindings", derive(TS))]
12079pub struct SettingsProperty {
12080    #[serde(default)]
12081    pub expressions: Vec<Expression>,
12082}
12083
12084/// SortKeyProperty
12085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12086#[cfg_attr(feature = "bindings", derive(TS))]
12087pub struct SortKeyProperty {
12088    pub this: Box<Expression>,
12089    #[serde(default)]
12090    pub compound: Option<Box<Expression>>,
12091}
12092
12093/// SqlReadWriteProperty
12094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12095#[cfg_attr(feature = "bindings", derive(TS))]
12096pub struct SqlReadWriteProperty {
12097    pub this: Box<Expression>,
12098}
12099
12100/// SqlSecurityProperty
12101#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12102#[cfg_attr(feature = "bindings", derive(TS))]
12103pub struct SqlSecurityProperty {
12104    pub this: Box<Expression>,
12105}
12106
12107/// StabilityProperty
12108#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12109#[cfg_attr(feature = "bindings", derive(TS))]
12110pub struct StabilityProperty {
12111    pub this: Box<Expression>,
12112}
12113
12114/// StorageHandlerProperty
12115#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12116#[cfg_attr(feature = "bindings", derive(TS))]
12117pub struct StorageHandlerProperty {
12118    pub this: Box<Expression>,
12119}
12120
12121/// TemporaryProperty
12122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12123#[cfg_attr(feature = "bindings", derive(TS))]
12124pub struct TemporaryProperty {
12125    #[serde(default)]
12126    pub this: Option<Box<Expression>>,
12127}
12128
12129/// Tags
12130#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12131#[cfg_attr(feature = "bindings", derive(TS))]
12132pub struct Tags {
12133    #[serde(default)]
12134    pub expressions: Vec<Expression>,
12135}
12136
12137/// TransformModelProperty
12138#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12139#[cfg_attr(feature = "bindings", derive(TS))]
12140pub struct TransformModelProperty {
12141    #[serde(default)]
12142    pub expressions: Vec<Expression>,
12143}
12144
12145/// TransientProperty
12146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12147#[cfg_attr(feature = "bindings", derive(TS))]
12148pub struct TransientProperty {
12149    #[serde(default)]
12150    pub this: Option<Box<Expression>>,
12151}
12152
12153/// UsingTemplateProperty
12154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12155#[cfg_attr(feature = "bindings", derive(TS))]
12156pub struct UsingTemplateProperty {
12157    pub this: Box<Expression>,
12158}
12159
12160/// ViewAttributeProperty
12161#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12162#[cfg_attr(feature = "bindings", derive(TS))]
12163pub struct ViewAttributeProperty {
12164    pub this: Box<Expression>,
12165}
12166
12167/// VolatileProperty
12168#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12169#[cfg_attr(feature = "bindings", derive(TS))]
12170pub struct VolatileProperty {
12171    #[serde(default)]
12172    pub this: Option<Box<Expression>>,
12173}
12174
12175/// WithDataProperty
12176#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12177#[cfg_attr(feature = "bindings", derive(TS))]
12178pub struct WithDataProperty {
12179    #[serde(default)]
12180    pub no: Option<Box<Expression>>,
12181    #[serde(default)]
12182    pub statistics: Option<Box<Expression>>,
12183}
12184
12185/// WithJournalTableProperty
12186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12187#[cfg_attr(feature = "bindings", derive(TS))]
12188pub struct WithJournalTableProperty {
12189    pub this: Box<Expression>,
12190}
12191
12192/// WithSchemaBindingProperty
12193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12194#[cfg_attr(feature = "bindings", derive(TS))]
12195pub struct WithSchemaBindingProperty {
12196    pub this: Box<Expression>,
12197}
12198
12199/// WithSystemVersioningProperty
12200#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12201#[cfg_attr(feature = "bindings", derive(TS))]
12202pub struct WithSystemVersioningProperty {
12203    #[serde(default)]
12204    pub on: Option<Box<Expression>>,
12205    #[serde(default)]
12206    pub this: Option<Box<Expression>>,
12207    #[serde(default)]
12208    pub data_consistency: Option<Box<Expression>>,
12209    #[serde(default)]
12210    pub retention_period: Option<Box<Expression>>,
12211    #[serde(default)]
12212    pub with_: Option<Box<Expression>>,
12213}
12214
12215/// WithProcedureOptions
12216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12217#[cfg_attr(feature = "bindings", derive(TS))]
12218pub struct WithProcedureOptions {
12219    #[serde(default)]
12220    pub expressions: Vec<Expression>,
12221}
12222
12223/// EncodeProperty
12224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12225#[cfg_attr(feature = "bindings", derive(TS))]
12226pub struct EncodeProperty {
12227    pub this: Box<Expression>,
12228    #[serde(default)]
12229    pub properties: Vec<Expression>,
12230    #[serde(default)]
12231    pub key: Option<Box<Expression>>,
12232}
12233
12234/// IncludeProperty
12235#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12236#[cfg_attr(feature = "bindings", derive(TS))]
12237pub struct IncludeProperty {
12238    pub this: Box<Expression>,
12239    #[serde(default)]
12240    pub alias: Option<String>,
12241    #[serde(default)]
12242    pub column_def: Option<Box<Expression>>,
12243}
12244
12245/// Properties
12246#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12247#[cfg_attr(feature = "bindings", derive(TS))]
12248pub struct Properties {
12249    #[serde(default)]
12250    pub expressions: Vec<Expression>,
12251}
12252
12253/// Key/value pair in a BigQuery OPTIONS (...) clause.
12254#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12255#[cfg_attr(feature = "bindings", derive(TS))]
12256pub struct OptionEntry {
12257    pub key: Identifier,
12258    pub value: Expression,
12259}
12260
12261/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12262#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12263#[cfg_attr(feature = "bindings", derive(TS))]
12264pub struct OptionsProperty {
12265    #[serde(default)]
12266    pub entries: Vec<OptionEntry>,
12267}
12268
12269/// InputOutputFormat
12270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12271#[cfg_attr(feature = "bindings", derive(TS))]
12272pub struct InputOutputFormat {
12273    #[serde(default)]
12274    pub input_format: Option<Box<Expression>>,
12275    #[serde(default)]
12276    pub output_format: Option<Box<Expression>>,
12277}
12278
12279/// Reference
12280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12281#[cfg_attr(feature = "bindings", derive(TS))]
12282pub struct Reference {
12283    pub this: Box<Expression>,
12284    #[serde(default)]
12285    pub expressions: Vec<Expression>,
12286    #[serde(default)]
12287    pub options: Vec<Expression>,
12288}
12289
12290/// QueryOption
12291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12292#[cfg_attr(feature = "bindings", derive(TS))]
12293pub struct QueryOption {
12294    pub this: Box<Expression>,
12295    #[serde(default)]
12296    pub expression: Option<Box<Expression>>,
12297}
12298
12299/// WithTableHint
12300#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12301#[cfg_attr(feature = "bindings", derive(TS))]
12302pub struct WithTableHint {
12303    #[serde(default)]
12304    pub expressions: Vec<Expression>,
12305}
12306
12307/// IndexTableHint
12308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12309#[cfg_attr(feature = "bindings", derive(TS))]
12310pub struct IndexTableHint {
12311    pub this: Box<Expression>,
12312    #[serde(default)]
12313    pub expressions: Vec<Expression>,
12314    #[serde(default)]
12315    pub target: Option<Box<Expression>>,
12316}
12317
12318/// Get
12319#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12320#[cfg_attr(feature = "bindings", derive(TS))]
12321pub struct Get {
12322    pub this: Box<Expression>,
12323    #[serde(default)]
12324    pub target: Option<Box<Expression>>,
12325    #[serde(default)]
12326    pub properties: Vec<Expression>,
12327}
12328
12329/// SetOperation
12330#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12331#[cfg_attr(feature = "bindings", derive(TS))]
12332pub struct SetOperation {
12333    #[serde(default)]
12334    pub with_: Option<Box<Expression>>,
12335    pub this: Box<Expression>,
12336    pub expression: Box<Expression>,
12337    #[serde(default)]
12338    pub distinct: bool,
12339    #[serde(default)]
12340    pub by_name: Option<Box<Expression>>,
12341    #[serde(default)]
12342    pub side: Option<Box<Expression>>,
12343    #[serde(default)]
12344    pub kind: Option<String>,
12345    #[serde(default)]
12346    pub on: Option<Box<Expression>>,
12347}
12348
12349/// Var - Simple variable reference (for SQL variables, keywords as values)
12350#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12351#[cfg_attr(feature = "bindings", derive(TS))]
12352pub struct Var {
12353    pub this: String,
12354}
12355
12356/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12358#[cfg_attr(feature = "bindings", derive(TS))]
12359pub struct Variadic {
12360    pub this: Box<Expression>,
12361}
12362
12363/// Version
12364#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12365#[cfg_attr(feature = "bindings", derive(TS))]
12366pub struct Version {
12367    pub this: Box<Expression>,
12368    pub kind: String,
12369    #[serde(default)]
12370    pub expression: Option<Box<Expression>>,
12371}
12372
12373/// Schema
12374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12375#[cfg_attr(feature = "bindings", derive(TS))]
12376pub struct Schema {
12377    #[serde(default)]
12378    pub this: Option<Box<Expression>>,
12379    #[serde(default)]
12380    pub expressions: Vec<Expression>,
12381}
12382
12383/// Lock
12384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12385#[cfg_attr(feature = "bindings", derive(TS))]
12386pub struct Lock {
12387    #[serde(default)]
12388    pub update: Option<Box<Expression>>,
12389    #[serde(default)]
12390    pub expressions: Vec<Expression>,
12391    #[serde(default)]
12392    pub wait: Option<Box<Expression>>,
12393    #[serde(default)]
12394    pub key: Option<Box<Expression>>,
12395}
12396
12397/// TableSample - wraps an expression with a TABLESAMPLE clause
12398/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12400#[cfg_attr(feature = "bindings", derive(TS))]
12401pub struct TableSample {
12402    /// The expression being sampled (subquery, function, etc.)
12403    #[serde(default, skip_serializing_if = "Option::is_none")]
12404    pub this: Option<Box<Expression>>,
12405    /// The sample specification
12406    #[serde(default, skip_serializing_if = "Option::is_none")]
12407    pub sample: Option<Box<Sample>>,
12408    #[serde(default)]
12409    pub expressions: Vec<Expression>,
12410    #[serde(default)]
12411    pub method: Option<String>,
12412    #[serde(default)]
12413    pub bucket_numerator: Option<Box<Expression>>,
12414    #[serde(default)]
12415    pub bucket_denominator: Option<Box<Expression>>,
12416    #[serde(default)]
12417    pub bucket_field: Option<Box<Expression>>,
12418    #[serde(default)]
12419    pub percent: Option<Box<Expression>>,
12420    #[serde(default)]
12421    pub rows: Option<Box<Expression>>,
12422    #[serde(default)]
12423    pub size: Option<i64>,
12424    #[serde(default)]
12425    pub seed: Option<Box<Expression>>,
12426}
12427
12428/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12429#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12430#[cfg_attr(feature = "bindings", derive(TS))]
12431pub struct Tag {
12432    #[serde(default)]
12433    pub this: Option<Box<Expression>>,
12434    #[serde(default)]
12435    pub prefix: Option<Box<Expression>>,
12436    #[serde(default)]
12437    pub postfix: Option<Box<Expression>>,
12438}
12439
12440/// UnpivotColumns
12441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12442#[cfg_attr(feature = "bindings", derive(TS))]
12443pub struct UnpivotColumns {
12444    pub this: Box<Expression>,
12445    #[serde(default)]
12446    pub expressions: Vec<Expression>,
12447}
12448
12449/// SessionParameter
12450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12451#[cfg_attr(feature = "bindings", derive(TS))]
12452pub struct SessionParameter {
12453    pub this: Box<Expression>,
12454    #[serde(default)]
12455    pub kind: Option<String>,
12456}
12457
12458/// PseudoType
12459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12460#[cfg_attr(feature = "bindings", derive(TS))]
12461pub struct PseudoType {
12462    pub this: Box<Expression>,
12463}
12464
12465/// ObjectIdentifier
12466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12467#[cfg_attr(feature = "bindings", derive(TS))]
12468pub struct ObjectIdentifier {
12469    pub this: Box<Expression>,
12470}
12471
12472/// Transaction
12473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12474#[cfg_attr(feature = "bindings", derive(TS))]
12475pub struct Transaction {
12476    #[serde(default)]
12477    pub this: Option<Box<Expression>>,
12478    #[serde(default)]
12479    pub modes: Option<Box<Expression>>,
12480    #[serde(default)]
12481    pub mark: Option<Box<Expression>>,
12482}
12483
12484/// Commit
12485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12486#[cfg_attr(feature = "bindings", derive(TS))]
12487pub struct Commit {
12488    #[serde(default)]
12489    pub chain: Option<Box<Expression>>,
12490    #[serde(default)]
12491    pub this: Option<Box<Expression>>,
12492    #[serde(default)]
12493    pub durability: Option<Box<Expression>>,
12494}
12495
12496/// Rollback
12497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12498#[cfg_attr(feature = "bindings", derive(TS))]
12499pub struct Rollback {
12500    #[serde(default)]
12501    pub savepoint: Option<Box<Expression>>,
12502    #[serde(default)]
12503    pub this: Option<Box<Expression>>,
12504}
12505
12506/// AlterSession
12507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12508#[cfg_attr(feature = "bindings", derive(TS))]
12509pub struct AlterSession {
12510    #[serde(default)]
12511    pub expressions: Vec<Expression>,
12512    #[serde(default)]
12513    pub unset: Option<Box<Expression>>,
12514}
12515
12516/// Analyze
12517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12518#[cfg_attr(feature = "bindings", derive(TS))]
12519pub struct Analyze {
12520    #[serde(default)]
12521    pub kind: Option<String>,
12522    #[serde(default)]
12523    pub this: Option<Box<Expression>>,
12524    #[serde(default)]
12525    pub options: Vec<Expression>,
12526    #[serde(default)]
12527    pub mode: Option<Box<Expression>>,
12528    #[serde(default)]
12529    pub partition: Option<Box<Expression>>,
12530    #[serde(default)]
12531    pub expression: Option<Box<Expression>>,
12532    #[serde(default)]
12533    pub properties: Vec<Expression>,
12534    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12535    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12536    pub columns: Vec<String>,
12537}
12538
12539/// AnalyzeStatistics
12540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12541#[cfg_attr(feature = "bindings", derive(TS))]
12542pub struct AnalyzeStatistics {
12543    pub kind: String,
12544    #[serde(default)]
12545    pub option: Option<Box<Expression>>,
12546    #[serde(default)]
12547    pub this: Option<Box<Expression>>,
12548    #[serde(default)]
12549    pub expressions: Vec<Expression>,
12550}
12551
12552/// AnalyzeHistogram
12553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12554#[cfg_attr(feature = "bindings", derive(TS))]
12555pub struct AnalyzeHistogram {
12556    pub this: Box<Expression>,
12557    #[serde(default)]
12558    pub expressions: Vec<Expression>,
12559    #[serde(default)]
12560    pub expression: Option<Box<Expression>>,
12561    #[serde(default)]
12562    pub update_options: Option<Box<Expression>>,
12563}
12564
12565/// AnalyzeSample
12566#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12567#[cfg_attr(feature = "bindings", derive(TS))]
12568pub struct AnalyzeSample {
12569    pub kind: String,
12570    #[serde(default)]
12571    pub sample: Option<Box<Expression>>,
12572}
12573
12574/// AnalyzeListChainedRows
12575#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12576#[cfg_attr(feature = "bindings", derive(TS))]
12577pub struct AnalyzeListChainedRows {
12578    #[serde(default)]
12579    pub expression: Option<Box<Expression>>,
12580}
12581
12582/// AnalyzeDelete
12583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12584#[cfg_attr(feature = "bindings", derive(TS))]
12585pub struct AnalyzeDelete {
12586    #[serde(default)]
12587    pub kind: Option<String>,
12588}
12589
12590/// AnalyzeWith
12591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12592#[cfg_attr(feature = "bindings", derive(TS))]
12593pub struct AnalyzeWith {
12594    #[serde(default)]
12595    pub expressions: Vec<Expression>,
12596}
12597
12598/// AnalyzeValidate
12599#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12600#[cfg_attr(feature = "bindings", derive(TS))]
12601pub struct AnalyzeValidate {
12602    pub kind: String,
12603    #[serde(default)]
12604    pub this: Option<Box<Expression>>,
12605    #[serde(default)]
12606    pub expression: Option<Box<Expression>>,
12607}
12608
12609/// AddPartition
12610#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12611#[cfg_attr(feature = "bindings", derive(TS))]
12612pub struct AddPartition {
12613    pub this: Box<Expression>,
12614    #[serde(default)]
12615    pub exists: bool,
12616    #[serde(default)]
12617    pub location: Option<Box<Expression>>,
12618}
12619
12620/// AttachOption
12621#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12622#[cfg_attr(feature = "bindings", derive(TS))]
12623pub struct AttachOption {
12624    pub this: Box<Expression>,
12625    #[serde(default)]
12626    pub expression: Option<Box<Expression>>,
12627}
12628
12629/// DropPartition
12630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12631#[cfg_attr(feature = "bindings", derive(TS))]
12632pub struct DropPartition {
12633    #[serde(default)]
12634    pub expressions: Vec<Expression>,
12635    #[serde(default)]
12636    pub exists: bool,
12637}
12638
12639/// ReplacePartition
12640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12641#[cfg_attr(feature = "bindings", derive(TS))]
12642pub struct ReplacePartition {
12643    pub expression: Box<Expression>,
12644    #[serde(default)]
12645    pub source: Option<Box<Expression>>,
12646}
12647
12648/// DPipe
12649#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12650#[cfg_attr(feature = "bindings", derive(TS))]
12651pub struct DPipe {
12652    pub this: Box<Expression>,
12653    pub expression: Box<Expression>,
12654    #[serde(default)]
12655    pub safe: Option<Box<Expression>>,
12656}
12657
12658/// Operator
12659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12660#[cfg_attr(feature = "bindings", derive(TS))]
12661pub struct Operator {
12662    pub this: Box<Expression>,
12663    #[serde(default)]
12664    pub operator: Option<Box<Expression>>,
12665    pub expression: Box<Expression>,
12666    /// Comments between OPERATOR() and the RHS expression
12667    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12668    pub comments: Vec<String>,
12669}
12670
12671/// PivotAny
12672#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12673#[cfg_attr(feature = "bindings", derive(TS))]
12674pub struct PivotAny {
12675    #[serde(default)]
12676    pub this: Option<Box<Expression>>,
12677}
12678
12679/// Aliases
12680#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12681#[cfg_attr(feature = "bindings", derive(TS))]
12682pub struct Aliases {
12683    pub this: Box<Expression>,
12684    #[serde(default)]
12685    pub expressions: Vec<Expression>,
12686}
12687
12688/// AtIndex
12689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12690#[cfg_attr(feature = "bindings", derive(TS))]
12691pub struct AtIndex {
12692    pub this: Box<Expression>,
12693    pub expression: Box<Expression>,
12694}
12695
12696/// FromTimeZone
12697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12698#[cfg_attr(feature = "bindings", derive(TS))]
12699pub struct FromTimeZone {
12700    pub this: Box<Expression>,
12701    #[serde(default)]
12702    pub zone: Option<Box<Expression>>,
12703}
12704
12705/// Format override for a column in Teradata
12706#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12707#[cfg_attr(feature = "bindings", derive(TS))]
12708pub struct FormatPhrase {
12709    pub this: Box<Expression>,
12710    pub format: String,
12711}
12712
12713/// ForIn
12714#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12715#[cfg_attr(feature = "bindings", derive(TS))]
12716pub struct ForIn {
12717    pub this: Box<Expression>,
12718    pub expression: Box<Expression>,
12719}
12720
12721/// Automatically converts unit arg into a var.
12722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12723#[cfg_attr(feature = "bindings", derive(TS))]
12724pub struct TimeUnit {
12725    #[serde(default)]
12726    pub unit: Option<String>,
12727}
12728
12729/// IntervalOp
12730#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12731#[cfg_attr(feature = "bindings", derive(TS))]
12732pub struct IntervalOp {
12733    #[serde(default)]
12734    pub unit: Option<String>,
12735    pub expression: Box<Expression>,
12736}
12737
12738/// HavingMax
12739#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12740#[cfg_attr(feature = "bindings", derive(TS))]
12741pub struct HavingMax {
12742    pub this: Box<Expression>,
12743    pub expression: Box<Expression>,
12744    #[serde(default)]
12745    pub max: Option<Box<Expression>>,
12746}
12747
12748/// CosineDistance
12749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12750#[cfg_attr(feature = "bindings", derive(TS))]
12751pub struct CosineDistance {
12752    pub this: Box<Expression>,
12753    pub expression: Box<Expression>,
12754}
12755
12756/// DotProduct
12757#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12758#[cfg_attr(feature = "bindings", derive(TS))]
12759pub struct DotProduct {
12760    pub this: Box<Expression>,
12761    pub expression: Box<Expression>,
12762}
12763
12764/// EuclideanDistance
12765#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12766#[cfg_attr(feature = "bindings", derive(TS))]
12767pub struct EuclideanDistance {
12768    pub this: Box<Expression>,
12769    pub expression: Box<Expression>,
12770}
12771
12772/// ManhattanDistance
12773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12774#[cfg_attr(feature = "bindings", derive(TS))]
12775pub struct ManhattanDistance {
12776    pub this: Box<Expression>,
12777    pub expression: Box<Expression>,
12778}
12779
12780/// JarowinklerSimilarity
12781#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12782#[cfg_attr(feature = "bindings", derive(TS))]
12783pub struct JarowinklerSimilarity {
12784    pub this: Box<Expression>,
12785    pub expression: Box<Expression>,
12786}
12787
12788/// Booland
12789#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12790#[cfg_attr(feature = "bindings", derive(TS))]
12791pub struct Booland {
12792    pub this: Box<Expression>,
12793    pub expression: Box<Expression>,
12794}
12795
12796/// Boolor
12797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12798#[cfg_attr(feature = "bindings", derive(TS))]
12799pub struct Boolor {
12800    pub this: Box<Expression>,
12801    pub expression: Box<Expression>,
12802}
12803
12804/// ParameterizedAgg
12805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12806#[cfg_attr(feature = "bindings", derive(TS))]
12807pub struct ParameterizedAgg {
12808    pub this: Box<Expression>,
12809    #[serde(default)]
12810    pub expressions: Vec<Expression>,
12811    #[serde(default)]
12812    pub params: Vec<Expression>,
12813}
12814
12815/// ArgMax
12816#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12817#[cfg_attr(feature = "bindings", derive(TS))]
12818pub struct ArgMax {
12819    pub this: Box<Expression>,
12820    pub expression: Box<Expression>,
12821    #[serde(default)]
12822    pub count: Option<Box<Expression>>,
12823}
12824
12825/// ArgMin
12826#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12827#[cfg_attr(feature = "bindings", derive(TS))]
12828pub struct ArgMin {
12829    pub this: Box<Expression>,
12830    pub expression: Box<Expression>,
12831    #[serde(default)]
12832    pub count: Option<Box<Expression>>,
12833}
12834
12835/// ApproxTopK
12836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12837#[cfg_attr(feature = "bindings", derive(TS))]
12838pub struct ApproxTopK {
12839    pub this: Box<Expression>,
12840    #[serde(default)]
12841    pub expression: Option<Box<Expression>>,
12842    #[serde(default)]
12843    pub counters: Option<Box<Expression>>,
12844}
12845
12846/// ApproxTopKAccumulate
12847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12848#[cfg_attr(feature = "bindings", derive(TS))]
12849pub struct ApproxTopKAccumulate {
12850    pub this: Box<Expression>,
12851    #[serde(default)]
12852    pub expression: Option<Box<Expression>>,
12853}
12854
12855/// ApproxTopKCombine
12856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12857#[cfg_attr(feature = "bindings", derive(TS))]
12858pub struct ApproxTopKCombine {
12859    pub this: Box<Expression>,
12860    #[serde(default)]
12861    pub expression: Option<Box<Expression>>,
12862}
12863
12864/// ApproxTopKEstimate
12865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12866#[cfg_attr(feature = "bindings", derive(TS))]
12867pub struct ApproxTopKEstimate {
12868    pub this: Box<Expression>,
12869    #[serde(default)]
12870    pub expression: Option<Box<Expression>>,
12871}
12872
12873/// ApproxTopSum
12874#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12875#[cfg_attr(feature = "bindings", derive(TS))]
12876pub struct ApproxTopSum {
12877    pub this: Box<Expression>,
12878    pub expression: Box<Expression>,
12879    #[serde(default)]
12880    pub count: Option<Box<Expression>>,
12881}
12882
12883/// ApproxQuantiles
12884#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12885#[cfg_attr(feature = "bindings", derive(TS))]
12886pub struct ApproxQuantiles {
12887    pub this: Box<Expression>,
12888    #[serde(default)]
12889    pub expression: Option<Box<Expression>>,
12890}
12891
12892/// Minhash
12893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12894#[cfg_attr(feature = "bindings", derive(TS))]
12895pub struct Minhash {
12896    pub this: Box<Expression>,
12897    #[serde(default)]
12898    pub expressions: Vec<Expression>,
12899}
12900
12901/// FarmFingerprint
12902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12903#[cfg_attr(feature = "bindings", derive(TS))]
12904pub struct FarmFingerprint {
12905    #[serde(default)]
12906    pub expressions: Vec<Expression>,
12907}
12908
12909/// Float64
12910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12911#[cfg_attr(feature = "bindings", derive(TS))]
12912pub struct Float64 {
12913    pub this: Box<Expression>,
12914    #[serde(default)]
12915    pub expression: Option<Box<Expression>>,
12916}
12917
12918/// Transform
12919#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12920#[cfg_attr(feature = "bindings", derive(TS))]
12921pub struct Transform {
12922    pub this: Box<Expression>,
12923    pub expression: Box<Expression>,
12924}
12925
12926/// Translate
12927#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12928#[cfg_attr(feature = "bindings", derive(TS))]
12929pub struct Translate {
12930    pub this: Box<Expression>,
12931    #[serde(default)]
12932    pub from_: Option<Box<Expression>>,
12933    #[serde(default)]
12934    pub to: Option<Box<Expression>>,
12935}
12936
12937/// Grouping
12938#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12939#[cfg_attr(feature = "bindings", derive(TS))]
12940pub struct Grouping {
12941    #[serde(default)]
12942    pub expressions: Vec<Expression>,
12943}
12944
12945/// GroupingId
12946#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12947#[cfg_attr(feature = "bindings", derive(TS))]
12948pub struct GroupingId {
12949    #[serde(default)]
12950    pub expressions: Vec<Expression>,
12951}
12952
12953/// Anonymous
12954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12955#[cfg_attr(feature = "bindings", derive(TS))]
12956pub struct Anonymous {
12957    pub this: Box<Expression>,
12958    #[serde(default)]
12959    pub expressions: Vec<Expression>,
12960}
12961
12962/// AnonymousAggFunc
12963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12964#[cfg_attr(feature = "bindings", derive(TS))]
12965pub struct AnonymousAggFunc {
12966    pub this: Box<Expression>,
12967    #[serde(default)]
12968    pub expressions: Vec<Expression>,
12969}
12970
12971/// CombinedAggFunc
12972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12973#[cfg_attr(feature = "bindings", derive(TS))]
12974pub struct CombinedAggFunc {
12975    pub this: Box<Expression>,
12976    #[serde(default)]
12977    pub expressions: Vec<Expression>,
12978}
12979
12980/// CombinedParameterizedAgg
12981#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12982#[cfg_attr(feature = "bindings", derive(TS))]
12983pub struct CombinedParameterizedAgg {
12984    pub this: Box<Expression>,
12985    #[serde(default)]
12986    pub expressions: Vec<Expression>,
12987    #[serde(default)]
12988    pub params: Vec<Expression>,
12989}
12990
12991/// HashAgg
12992#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12993#[cfg_attr(feature = "bindings", derive(TS))]
12994pub struct HashAgg {
12995    pub this: Box<Expression>,
12996    #[serde(default)]
12997    pub expressions: Vec<Expression>,
12998}
12999
13000/// Hll
13001#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13002#[cfg_attr(feature = "bindings", derive(TS))]
13003pub struct Hll {
13004    pub this: Box<Expression>,
13005    #[serde(default)]
13006    pub expressions: Vec<Expression>,
13007}
13008
13009/// Apply
13010#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13011#[cfg_attr(feature = "bindings", derive(TS))]
13012pub struct Apply {
13013    pub this: Box<Expression>,
13014    pub expression: Box<Expression>,
13015}
13016
13017/// ToBoolean
13018#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13019#[cfg_attr(feature = "bindings", derive(TS))]
13020pub struct ToBoolean {
13021    pub this: Box<Expression>,
13022    #[serde(default)]
13023    pub safe: Option<Box<Expression>>,
13024}
13025
13026/// List
13027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13028#[cfg_attr(feature = "bindings", derive(TS))]
13029pub struct List {
13030    #[serde(default)]
13031    pub expressions: Vec<Expression>,
13032}
13033
13034/// ToMap - Materialize-style map constructor
13035/// Can hold either:
13036/// - A SELECT subquery (MAP(SELECT 'a', 1))
13037/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
13038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13039#[cfg_attr(feature = "bindings", derive(TS))]
13040pub struct ToMap {
13041    /// Either a Select subquery or a Struct containing PropertyEQ entries
13042    pub this: Box<Expression>,
13043}
13044
13045/// Pad
13046#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13047#[cfg_attr(feature = "bindings", derive(TS))]
13048pub struct Pad {
13049    pub this: Box<Expression>,
13050    pub expression: Box<Expression>,
13051    #[serde(default)]
13052    pub fill_pattern: Option<Box<Expression>>,
13053    #[serde(default)]
13054    pub is_left: Option<Box<Expression>>,
13055}
13056
13057/// ToChar
13058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13059#[cfg_attr(feature = "bindings", derive(TS))]
13060pub struct ToChar {
13061    pub this: Box<Expression>,
13062    #[serde(default)]
13063    pub format: Option<String>,
13064    #[serde(default)]
13065    pub nlsparam: Option<Box<Expression>>,
13066    #[serde(default)]
13067    pub is_numeric: Option<Box<Expression>>,
13068}
13069
13070/// StringFunc - String type conversion function (BigQuery STRING)
13071#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13072#[cfg_attr(feature = "bindings", derive(TS))]
13073pub struct StringFunc {
13074    pub this: Box<Expression>,
13075    #[serde(default)]
13076    pub zone: Option<Box<Expression>>,
13077}
13078
13079/// ToNumber
13080#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13081#[cfg_attr(feature = "bindings", derive(TS))]
13082pub struct ToNumber {
13083    pub this: Box<Expression>,
13084    #[serde(default)]
13085    pub format: Option<Box<Expression>>,
13086    #[serde(default)]
13087    pub nlsparam: Option<Box<Expression>>,
13088    #[serde(default)]
13089    pub precision: Option<Box<Expression>>,
13090    #[serde(default)]
13091    pub scale: Option<Box<Expression>>,
13092    #[serde(default)]
13093    pub safe: Option<Box<Expression>>,
13094    #[serde(default)]
13095    pub safe_name: Option<Box<Expression>>,
13096}
13097
13098/// ToDouble
13099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13100#[cfg_attr(feature = "bindings", derive(TS))]
13101pub struct ToDouble {
13102    pub this: Box<Expression>,
13103    #[serde(default)]
13104    pub format: Option<String>,
13105    #[serde(default)]
13106    pub safe: Option<Box<Expression>>,
13107}
13108
13109/// ToDecfloat
13110#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13111#[cfg_attr(feature = "bindings", derive(TS))]
13112pub struct ToDecfloat {
13113    pub this: Box<Expression>,
13114    #[serde(default)]
13115    pub format: Option<String>,
13116}
13117
13118/// TryToDecfloat
13119#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13120#[cfg_attr(feature = "bindings", derive(TS))]
13121pub struct TryToDecfloat {
13122    pub this: Box<Expression>,
13123    #[serde(default)]
13124    pub format: Option<String>,
13125}
13126
13127/// ToFile
13128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13129#[cfg_attr(feature = "bindings", derive(TS))]
13130pub struct ToFile {
13131    pub this: Box<Expression>,
13132    #[serde(default)]
13133    pub path: Option<Box<Expression>>,
13134    #[serde(default)]
13135    pub safe: Option<Box<Expression>>,
13136}
13137
13138/// Columns
13139#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13140#[cfg_attr(feature = "bindings", derive(TS))]
13141pub struct Columns {
13142    pub this: Box<Expression>,
13143    #[serde(default)]
13144    pub unpack: Option<Box<Expression>>,
13145}
13146
13147/// ConvertToCharset
13148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13149#[cfg_attr(feature = "bindings", derive(TS))]
13150pub struct ConvertToCharset {
13151    pub this: Box<Expression>,
13152    #[serde(default)]
13153    pub dest: Option<Box<Expression>>,
13154    #[serde(default)]
13155    pub source: Option<Box<Expression>>,
13156}
13157
13158/// ConvertTimezone
13159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13160#[cfg_attr(feature = "bindings", derive(TS))]
13161pub struct ConvertTimezone {
13162    #[serde(default)]
13163    pub source_tz: Option<Box<Expression>>,
13164    #[serde(default)]
13165    pub target_tz: Option<Box<Expression>>,
13166    #[serde(default)]
13167    pub timestamp: Option<Box<Expression>>,
13168    #[serde(default)]
13169    pub options: Vec<Expression>,
13170}
13171
13172/// GenerateSeries
13173#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13174#[cfg_attr(feature = "bindings", derive(TS))]
13175pub struct GenerateSeries {
13176    #[serde(default)]
13177    pub start: Option<Box<Expression>>,
13178    #[serde(default)]
13179    pub end: Option<Box<Expression>>,
13180    #[serde(default)]
13181    pub step: Option<Box<Expression>>,
13182    #[serde(default)]
13183    pub is_end_exclusive: Option<Box<Expression>>,
13184}
13185
13186/// AIAgg
13187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13188#[cfg_attr(feature = "bindings", derive(TS))]
13189pub struct AIAgg {
13190    pub this: Box<Expression>,
13191    pub expression: Box<Expression>,
13192}
13193
13194/// AIClassify
13195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13196#[cfg_attr(feature = "bindings", derive(TS))]
13197pub struct AIClassify {
13198    pub this: Box<Expression>,
13199    #[serde(default)]
13200    pub categories: Option<Box<Expression>>,
13201    #[serde(default)]
13202    pub config: Option<Box<Expression>>,
13203}
13204
13205/// ArrayAll
13206#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13207#[cfg_attr(feature = "bindings", derive(TS))]
13208pub struct ArrayAll {
13209    pub this: Box<Expression>,
13210    pub expression: Box<Expression>,
13211}
13212
13213/// ArrayAny
13214#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13215#[cfg_attr(feature = "bindings", derive(TS))]
13216pub struct ArrayAny {
13217    pub this: Box<Expression>,
13218    pub expression: Box<Expression>,
13219}
13220
13221/// ArrayConstructCompact
13222#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13223#[cfg_attr(feature = "bindings", derive(TS))]
13224pub struct ArrayConstructCompact {
13225    #[serde(default)]
13226    pub expressions: Vec<Expression>,
13227}
13228
13229/// StPoint
13230#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13231#[cfg_attr(feature = "bindings", derive(TS))]
13232pub struct StPoint {
13233    pub this: Box<Expression>,
13234    pub expression: Box<Expression>,
13235    #[serde(default)]
13236    pub null: Option<Box<Expression>>,
13237}
13238
13239/// StDistance
13240#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13241#[cfg_attr(feature = "bindings", derive(TS))]
13242pub struct StDistance {
13243    pub this: Box<Expression>,
13244    pub expression: Box<Expression>,
13245    #[serde(default)]
13246    pub use_spheroid: Option<Box<Expression>>,
13247}
13248
13249/// StringToArray
13250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13251#[cfg_attr(feature = "bindings", derive(TS))]
13252pub struct StringToArray {
13253    pub this: Box<Expression>,
13254    #[serde(default)]
13255    pub expression: Option<Box<Expression>>,
13256    #[serde(default)]
13257    pub null: Option<Box<Expression>>,
13258}
13259
13260/// ArraySum
13261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13262#[cfg_attr(feature = "bindings", derive(TS))]
13263pub struct ArraySum {
13264    pub this: Box<Expression>,
13265    #[serde(default)]
13266    pub expression: Option<Box<Expression>>,
13267}
13268
13269/// ObjectAgg
13270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13271#[cfg_attr(feature = "bindings", derive(TS))]
13272pub struct ObjectAgg {
13273    pub this: Box<Expression>,
13274    pub expression: Box<Expression>,
13275}
13276
13277/// CastToStrType
13278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13279#[cfg_attr(feature = "bindings", derive(TS))]
13280pub struct CastToStrType {
13281    pub this: Box<Expression>,
13282    #[serde(default)]
13283    pub to: Option<Box<Expression>>,
13284}
13285
13286/// CheckJson
13287#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13288#[cfg_attr(feature = "bindings", derive(TS))]
13289pub struct CheckJson {
13290    pub this: Box<Expression>,
13291}
13292
13293/// CheckXml
13294#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13295#[cfg_attr(feature = "bindings", derive(TS))]
13296pub struct CheckXml {
13297    pub this: Box<Expression>,
13298    #[serde(default)]
13299    pub disable_auto_convert: Option<Box<Expression>>,
13300}
13301
13302/// TranslateCharacters
13303#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13304#[cfg_attr(feature = "bindings", derive(TS))]
13305pub struct TranslateCharacters {
13306    pub this: Box<Expression>,
13307    pub expression: Box<Expression>,
13308    #[serde(default)]
13309    pub with_error: Option<Box<Expression>>,
13310}
13311
13312/// CurrentSchemas
13313#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13314#[cfg_attr(feature = "bindings", derive(TS))]
13315pub struct CurrentSchemas {
13316    #[serde(default)]
13317    pub this: Option<Box<Expression>>,
13318}
13319
13320/// CurrentDatetime
13321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13322#[cfg_attr(feature = "bindings", derive(TS))]
13323pub struct CurrentDatetime {
13324    #[serde(default)]
13325    pub this: Option<Box<Expression>>,
13326}
13327
13328/// Localtime
13329#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13330#[cfg_attr(feature = "bindings", derive(TS))]
13331pub struct Localtime {
13332    #[serde(default)]
13333    pub this: Option<Box<Expression>>,
13334}
13335
13336/// Localtimestamp
13337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13338#[cfg_attr(feature = "bindings", derive(TS))]
13339pub struct Localtimestamp {
13340    #[serde(default)]
13341    pub this: Option<Box<Expression>>,
13342}
13343
13344/// Systimestamp
13345#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13346#[cfg_attr(feature = "bindings", derive(TS))]
13347pub struct Systimestamp {
13348    #[serde(default)]
13349    pub this: Option<Box<Expression>>,
13350}
13351
13352/// CurrentSchema
13353#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13354#[cfg_attr(feature = "bindings", derive(TS))]
13355pub struct CurrentSchema {
13356    #[serde(default)]
13357    pub this: Option<Box<Expression>>,
13358}
13359
13360/// CurrentUser
13361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13362#[cfg_attr(feature = "bindings", derive(TS))]
13363pub struct CurrentUser {
13364    #[serde(default)]
13365    pub this: Option<Box<Expression>>,
13366}
13367
13368/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13370#[cfg_attr(feature = "bindings", derive(TS))]
13371pub struct SessionUser;
13372
13373/// JSONPathRoot - Represents $ in JSON path expressions
13374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13375#[cfg_attr(feature = "bindings", derive(TS))]
13376pub struct JSONPathRoot;
13377
13378/// UtcTime
13379#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13380#[cfg_attr(feature = "bindings", derive(TS))]
13381pub struct UtcTime {
13382    #[serde(default)]
13383    pub this: Option<Box<Expression>>,
13384}
13385
13386/// UtcTimestamp
13387#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13388#[cfg_attr(feature = "bindings", derive(TS))]
13389pub struct UtcTimestamp {
13390    #[serde(default)]
13391    pub this: Option<Box<Expression>>,
13392}
13393
13394/// TimestampFunc - TIMESTAMP constructor function
13395#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13396#[cfg_attr(feature = "bindings", derive(TS))]
13397pub struct TimestampFunc {
13398    #[serde(default)]
13399    pub this: Option<Box<Expression>>,
13400    #[serde(default)]
13401    pub zone: Option<Box<Expression>>,
13402    #[serde(default)]
13403    pub with_tz: Option<bool>,
13404    #[serde(default)]
13405    pub safe: Option<bool>,
13406}
13407
13408/// DateBin
13409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13410#[cfg_attr(feature = "bindings", derive(TS))]
13411pub struct DateBin {
13412    pub this: Box<Expression>,
13413    pub expression: Box<Expression>,
13414    #[serde(default)]
13415    pub unit: Option<String>,
13416    #[serde(default)]
13417    pub zone: Option<Box<Expression>>,
13418    #[serde(default)]
13419    pub origin: Option<Box<Expression>>,
13420}
13421
13422/// Datetime
13423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13424#[cfg_attr(feature = "bindings", derive(TS))]
13425pub struct Datetime {
13426    pub this: Box<Expression>,
13427    #[serde(default)]
13428    pub expression: Option<Box<Expression>>,
13429}
13430
13431/// DatetimeAdd
13432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13433#[cfg_attr(feature = "bindings", derive(TS))]
13434pub struct DatetimeAdd {
13435    pub this: Box<Expression>,
13436    pub expression: Box<Expression>,
13437    #[serde(default)]
13438    pub unit: Option<String>,
13439}
13440
13441/// DatetimeSub
13442#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13443#[cfg_attr(feature = "bindings", derive(TS))]
13444pub struct DatetimeSub {
13445    pub this: Box<Expression>,
13446    pub expression: Box<Expression>,
13447    #[serde(default)]
13448    pub unit: Option<String>,
13449}
13450
13451/// DatetimeDiff
13452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13453#[cfg_attr(feature = "bindings", derive(TS))]
13454pub struct DatetimeDiff {
13455    pub this: Box<Expression>,
13456    pub expression: Box<Expression>,
13457    #[serde(default)]
13458    pub unit: Option<String>,
13459}
13460
13461/// DatetimeTrunc
13462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13463#[cfg_attr(feature = "bindings", derive(TS))]
13464pub struct DatetimeTrunc {
13465    pub this: Box<Expression>,
13466    pub unit: String,
13467    #[serde(default)]
13468    pub zone: Option<Box<Expression>>,
13469}
13470
13471/// Dayname
13472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13473#[cfg_attr(feature = "bindings", derive(TS))]
13474pub struct Dayname {
13475    pub this: Box<Expression>,
13476    #[serde(default)]
13477    pub abbreviated: Option<Box<Expression>>,
13478}
13479
13480/// MakeInterval
13481#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13482#[cfg_attr(feature = "bindings", derive(TS))]
13483pub struct MakeInterval {
13484    #[serde(default)]
13485    pub year: Option<Box<Expression>>,
13486    #[serde(default)]
13487    pub month: Option<Box<Expression>>,
13488    #[serde(default)]
13489    pub week: Option<Box<Expression>>,
13490    #[serde(default)]
13491    pub day: Option<Box<Expression>>,
13492    #[serde(default)]
13493    pub hour: Option<Box<Expression>>,
13494    #[serde(default)]
13495    pub minute: Option<Box<Expression>>,
13496    #[serde(default)]
13497    pub second: Option<Box<Expression>>,
13498}
13499
13500/// PreviousDay
13501#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13502#[cfg_attr(feature = "bindings", derive(TS))]
13503pub struct PreviousDay {
13504    pub this: Box<Expression>,
13505    pub expression: Box<Expression>,
13506}
13507
13508/// Elt
13509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13510#[cfg_attr(feature = "bindings", derive(TS))]
13511pub struct Elt {
13512    pub this: Box<Expression>,
13513    #[serde(default)]
13514    pub expressions: Vec<Expression>,
13515}
13516
13517/// TimestampAdd
13518#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13519#[cfg_attr(feature = "bindings", derive(TS))]
13520pub struct TimestampAdd {
13521    pub this: Box<Expression>,
13522    pub expression: Box<Expression>,
13523    #[serde(default)]
13524    pub unit: Option<String>,
13525}
13526
13527/// TimestampSub
13528#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13529#[cfg_attr(feature = "bindings", derive(TS))]
13530pub struct TimestampSub {
13531    pub this: Box<Expression>,
13532    pub expression: Box<Expression>,
13533    #[serde(default)]
13534    pub unit: Option<String>,
13535}
13536
13537/// TimestampDiff
13538#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13539#[cfg_attr(feature = "bindings", derive(TS))]
13540pub struct TimestampDiff {
13541    pub this: Box<Expression>,
13542    pub expression: Box<Expression>,
13543    #[serde(default)]
13544    pub unit: Option<String>,
13545}
13546
13547/// TimeSlice
13548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13549#[cfg_attr(feature = "bindings", derive(TS))]
13550pub struct TimeSlice {
13551    pub this: Box<Expression>,
13552    pub expression: Box<Expression>,
13553    pub unit: String,
13554    #[serde(default)]
13555    pub kind: Option<String>,
13556}
13557
13558/// TimeAdd
13559#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13560#[cfg_attr(feature = "bindings", derive(TS))]
13561pub struct TimeAdd {
13562    pub this: Box<Expression>,
13563    pub expression: Box<Expression>,
13564    #[serde(default)]
13565    pub unit: Option<String>,
13566}
13567
13568/// TimeSub
13569#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13570#[cfg_attr(feature = "bindings", derive(TS))]
13571pub struct TimeSub {
13572    pub this: Box<Expression>,
13573    pub expression: Box<Expression>,
13574    #[serde(default)]
13575    pub unit: Option<String>,
13576}
13577
13578/// TimeDiff
13579#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13580#[cfg_attr(feature = "bindings", derive(TS))]
13581pub struct TimeDiff {
13582    pub this: Box<Expression>,
13583    pub expression: Box<Expression>,
13584    #[serde(default)]
13585    pub unit: Option<String>,
13586}
13587
13588/// TimeTrunc
13589#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13590#[cfg_attr(feature = "bindings", derive(TS))]
13591pub struct TimeTrunc {
13592    pub this: Box<Expression>,
13593    pub unit: String,
13594    #[serde(default)]
13595    pub zone: Option<Box<Expression>>,
13596}
13597
13598/// DateFromParts
13599#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13600#[cfg_attr(feature = "bindings", derive(TS))]
13601pub struct DateFromParts {
13602    #[serde(default)]
13603    pub year: Option<Box<Expression>>,
13604    #[serde(default)]
13605    pub month: Option<Box<Expression>>,
13606    #[serde(default)]
13607    pub day: Option<Box<Expression>>,
13608    #[serde(default)]
13609    pub allow_overflow: Option<Box<Expression>>,
13610}
13611
13612/// TimeFromParts
13613#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13614#[cfg_attr(feature = "bindings", derive(TS))]
13615pub struct TimeFromParts {
13616    #[serde(default)]
13617    pub hour: Option<Box<Expression>>,
13618    #[serde(default)]
13619    pub min: Option<Box<Expression>>,
13620    #[serde(default)]
13621    pub sec: Option<Box<Expression>>,
13622    #[serde(default)]
13623    pub nano: Option<Box<Expression>>,
13624    #[serde(default)]
13625    pub fractions: Option<Box<Expression>>,
13626    #[serde(default)]
13627    pub precision: Option<i64>,
13628}
13629
13630/// DecodeCase
13631#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13632#[cfg_attr(feature = "bindings", derive(TS))]
13633pub struct DecodeCase {
13634    #[serde(default)]
13635    pub expressions: Vec<Expression>,
13636}
13637
13638/// Decrypt
13639#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13640#[cfg_attr(feature = "bindings", derive(TS))]
13641pub struct Decrypt {
13642    pub this: Box<Expression>,
13643    #[serde(default)]
13644    pub passphrase: Option<Box<Expression>>,
13645    #[serde(default)]
13646    pub aad: Option<Box<Expression>>,
13647    #[serde(default)]
13648    pub encryption_method: Option<Box<Expression>>,
13649    #[serde(default)]
13650    pub safe: Option<Box<Expression>>,
13651}
13652
13653/// DecryptRaw
13654#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13655#[cfg_attr(feature = "bindings", derive(TS))]
13656pub struct DecryptRaw {
13657    pub this: Box<Expression>,
13658    #[serde(default)]
13659    pub key: Option<Box<Expression>>,
13660    #[serde(default)]
13661    pub iv: Option<Box<Expression>>,
13662    #[serde(default)]
13663    pub aad: Option<Box<Expression>>,
13664    #[serde(default)]
13665    pub encryption_method: Option<Box<Expression>>,
13666    #[serde(default)]
13667    pub aead: Option<Box<Expression>>,
13668    #[serde(default)]
13669    pub safe: Option<Box<Expression>>,
13670}
13671
13672/// Encode
13673#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13674#[cfg_attr(feature = "bindings", derive(TS))]
13675pub struct Encode {
13676    pub this: Box<Expression>,
13677    #[serde(default)]
13678    pub charset: Option<Box<Expression>>,
13679}
13680
13681/// Encrypt
13682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13683#[cfg_attr(feature = "bindings", derive(TS))]
13684pub struct Encrypt {
13685    pub this: Box<Expression>,
13686    #[serde(default)]
13687    pub passphrase: Option<Box<Expression>>,
13688    #[serde(default)]
13689    pub aad: Option<Box<Expression>>,
13690    #[serde(default)]
13691    pub encryption_method: Option<Box<Expression>>,
13692}
13693
13694/// EncryptRaw
13695#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13696#[cfg_attr(feature = "bindings", derive(TS))]
13697pub struct EncryptRaw {
13698    pub this: Box<Expression>,
13699    #[serde(default)]
13700    pub key: Option<Box<Expression>>,
13701    #[serde(default)]
13702    pub iv: Option<Box<Expression>>,
13703    #[serde(default)]
13704    pub aad: Option<Box<Expression>>,
13705    #[serde(default)]
13706    pub encryption_method: Option<Box<Expression>>,
13707}
13708
13709/// EqualNull
13710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13711#[cfg_attr(feature = "bindings", derive(TS))]
13712pub struct EqualNull {
13713    pub this: Box<Expression>,
13714    pub expression: Box<Expression>,
13715}
13716
13717/// ToBinary
13718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13719#[cfg_attr(feature = "bindings", derive(TS))]
13720pub struct ToBinary {
13721    pub this: Box<Expression>,
13722    #[serde(default)]
13723    pub format: Option<String>,
13724    #[serde(default)]
13725    pub safe: Option<Box<Expression>>,
13726}
13727
13728/// Base64DecodeBinary
13729#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13730#[cfg_attr(feature = "bindings", derive(TS))]
13731pub struct Base64DecodeBinary {
13732    pub this: Box<Expression>,
13733    #[serde(default)]
13734    pub alphabet: Option<Box<Expression>>,
13735}
13736
13737/// Base64DecodeString
13738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13739#[cfg_attr(feature = "bindings", derive(TS))]
13740pub struct Base64DecodeString {
13741    pub this: Box<Expression>,
13742    #[serde(default)]
13743    pub alphabet: Option<Box<Expression>>,
13744}
13745
13746/// Base64Encode
13747#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13748#[cfg_attr(feature = "bindings", derive(TS))]
13749pub struct Base64Encode {
13750    pub this: Box<Expression>,
13751    #[serde(default)]
13752    pub max_line_length: Option<Box<Expression>>,
13753    #[serde(default)]
13754    pub alphabet: Option<Box<Expression>>,
13755}
13756
13757/// TryBase64DecodeBinary
13758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13759#[cfg_attr(feature = "bindings", derive(TS))]
13760pub struct TryBase64DecodeBinary {
13761    pub this: Box<Expression>,
13762    #[serde(default)]
13763    pub alphabet: Option<Box<Expression>>,
13764}
13765
13766/// TryBase64DecodeString
13767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13768#[cfg_attr(feature = "bindings", derive(TS))]
13769pub struct TryBase64DecodeString {
13770    pub this: Box<Expression>,
13771    #[serde(default)]
13772    pub alphabet: Option<Box<Expression>>,
13773}
13774
13775/// GapFill
13776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13777#[cfg_attr(feature = "bindings", derive(TS))]
13778pub struct GapFill {
13779    pub this: Box<Expression>,
13780    #[serde(default)]
13781    pub ts_column: Option<Box<Expression>>,
13782    #[serde(default)]
13783    pub bucket_width: Option<Box<Expression>>,
13784    #[serde(default)]
13785    pub partitioning_columns: Option<Box<Expression>>,
13786    #[serde(default)]
13787    pub value_columns: Option<Box<Expression>>,
13788    #[serde(default)]
13789    pub origin: Option<Box<Expression>>,
13790    #[serde(default)]
13791    pub ignore_nulls: Option<Box<Expression>>,
13792}
13793
13794/// GenerateDateArray
13795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13796#[cfg_attr(feature = "bindings", derive(TS))]
13797pub struct GenerateDateArray {
13798    #[serde(default)]
13799    pub start: Option<Box<Expression>>,
13800    #[serde(default)]
13801    pub end: Option<Box<Expression>>,
13802    #[serde(default)]
13803    pub step: Option<Box<Expression>>,
13804}
13805
13806/// GenerateTimestampArray
13807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13808#[cfg_attr(feature = "bindings", derive(TS))]
13809pub struct GenerateTimestampArray {
13810    #[serde(default)]
13811    pub start: Option<Box<Expression>>,
13812    #[serde(default)]
13813    pub end: Option<Box<Expression>>,
13814    #[serde(default)]
13815    pub step: Option<Box<Expression>>,
13816}
13817
13818/// GetExtract
13819#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13820#[cfg_attr(feature = "bindings", derive(TS))]
13821pub struct GetExtract {
13822    pub this: Box<Expression>,
13823    pub expression: Box<Expression>,
13824}
13825
13826/// Getbit
13827#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13828#[cfg_attr(feature = "bindings", derive(TS))]
13829pub struct Getbit {
13830    pub this: Box<Expression>,
13831    pub expression: Box<Expression>,
13832    #[serde(default)]
13833    pub zero_is_msb: Option<Box<Expression>>,
13834}
13835
13836/// OverflowTruncateBehavior
13837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13838#[cfg_attr(feature = "bindings", derive(TS))]
13839pub struct OverflowTruncateBehavior {
13840    #[serde(default)]
13841    pub this: Option<Box<Expression>>,
13842    #[serde(default)]
13843    pub with_count: Option<Box<Expression>>,
13844}
13845
13846/// HexEncode
13847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13848#[cfg_attr(feature = "bindings", derive(TS))]
13849pub struct HexEncode {
13850    pub this: Box<Expression>,
13851    #[serde(default)]
13852    pub case: Option<Box<Expression>>,
13853}
13854
13855/// Compress
13856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13857#[cfg_attr(feature = "bindings", derive(TS))]
13858pub struct Compress {
13859    pub this: Box<Expression>,
13860    #[serde(default)]
13861    pub method: Option<String>,
13862}
13863
13864/// DecompressBinary
13865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13866#[cfg_attr(feature = "bindings", derive(TS))]
13867pub struct DecompressBinary {
13868    pub this: Box<Expression>,
13869    pub method: String,
13870}
13871
13872/// DecompressString
13873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13874#[cfg_attr(feature = "bindings", derive(TS))]
13875pub struct DecompressString {
13876    pub this: Box<Expression>,
13877    pub method: String,
13878}
13879
13880/// Xor
13881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13882#[cfg_attr(feature = "bindings", derive(TS))]
13883pub struct Xor {
13884    #[serde(default)]
13885    pub this: Option<Box<Expression>>,
13886    #[serde(default)]
13887    pub expression: Option<Box<Expression>>,
13888    #[serde(default)]
13889    pub expressions: Vec<Expression>,
13890}
13891
13892/// Nullif
13893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13894#[cfg_attr(feature = "bindings", derive(TS))]
13895pub struct Nullif {
13896    pub this: Box<Expression>,
13897    pub expression: Box<Expression>,
13898}
13899
13900/// JSON
13901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13902#[cfg_attr(feature = "bindings", derive(TS))]
13903pub struct JSON {
13904    #[serde(default)]
13905    pub this: Option<Box<Expression>>,
13906    #[serde(default)]
13907    pub with_: Option<Box<Expression>>,
13908    #[serde(default)]
13909    pub unique: bool,
13910}
13911
13912/// JSONPath
13913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13914#[cfg_attr(feature = "bindings", derive(TS))]
13915pub struct JSONPath {
13916    #[serde(default)]
13917    pub expressions: Vec<Expression>,
13918    #[serde(default)]
13919    pub escape: Option<Box<Expression>>,
13920}
13921
13922/// JSONPathFilter
13923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13924#[cfg_attr(feature = "bindings", derive(TS))]
13925pub struct JSONPathFilter {
13926    pub this: Box<Expression>,
13927}
13928
13929/// JSONPathKey
13930#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13931#[cfg_attr(feature = "bindings", derive(TS))]
13932pub struct JSONPathKey {
13933    pub this: Box<Expression>,
13934}
13935
13936/// JSONPathRecursive
13937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13938#[cfg_attr(feature = "bindings", derive(TS))]
13939pub struct JSONPathRecursive {
13940    #[serde(default)]
13941    pub this: Option<Box<Expression>>,
13942}
13943
13944/// JSONPathScript
13945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13946#[cfg_attr(feature = "bindings", derive(TS))]
13947pub struct JSONPathScript {
13948    pub this: Box<Expression>,
13949}
13950
13951/// JSONPathSlice
13952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13953#[cfg_attr(feature = "bindings", derive(TS))]
13954pub struct JSONPathSlice {
13955    #[serde(default)]
13956    pub start: Option<Box<Expression>>,
13957    #[serde(default)]
13958    pub end: Option<Box<Expression>>,
13959    #[serde(default)]
13960    pub step: Option<Box<Expression>>,
13961}
13962
13963/// JSONPathSelector
13964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13965#[cfg_attr(feature = "bindings", derive(TS))]
13966pub struct JSONPathSelector {
13967    pub this: Box<Expression>,
13968}
13969
13970/// JSONPathSubscript
13971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13972#[cfg_attr(feature = "bindings", derive(TS))]
13973pub struct JSONPathSubscript {
13974    pub this: Box<Expression>,
13975}
13976
13977/// JSONPathUnion
13978#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13979#[cfg_attr(feature = "bindings", derive(TS))]
13980pub struct JSONPathUnion {
13981    #[serde(default)]
13982    pub expressions: Vec<Expression>,
13983}
13984
13985/// Format
13986#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13987#[cfg_attr(feature = "bindings", derive(TS))]
13988pub struct Format {
13989    pub this: Box<Expression>,
13990    #[serde(default)]
13991    pub expressions: Vec<Expression>,
13992}
13993
13994/// JSONKeys
13995#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13996#[cfg_attr(feature = "bindings", derive(TS))]
13997pub struct JSONKeys {
13998    pub this: Box<Expression>,
13999    #[serde(default)]
14000    pub expression: Option<Box<Expression>>,
14001    #[serde(default)]
14002    pub expressions: Vec<Expression>,
14003}
14004
14005/// JSONKeyValue
14006#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14007#[cfg_attr(feature = "bindings", derive(TS))]
14008pub struct JSONKeyValue {
14009    pub this: Box<Expression>,
14010    pub expression: Box<Expression>,
14011}
14012
14013/// JSONKeysAtDepth
14014#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14015#[cfg_attr(feature = "bindings", derive(TS))]
14016pub struct JSONKeysAtDepth {
14017    pub this: Box<Expression>,
14018    #[serde(default)]
14019    pub expression: Option<Box<Expression>>,
14020    #[serde(default)]
14021    pub mode: Option<Box<Expression>>,
14022}
14023
14024/// JSONObject
14025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14026#[cfg_attr(feature = "bindings", derive(TS))]
14027pub struct JSONObject {
14028    #[serde(default)]
14029    pub expressions: Vec<Expression>,
14030    #[serde(default)]
14031    pub null_handling: Option<Box<Expression>>,
14032    #[serde(default)]
14033    pub unique_keys: Option<Box<Expression>>,
14034    #[serde(default)]
14035    pub return_type: Option<Box<Expression>>,
14036    #[serde(default)]
14037    pub encoding: Option<Box<Expression>>,
14038}
14039
14040/// JSONObjectAgg
14041#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14042#[cfg_attr(feature = "bindings", derive(TS))]
14043pub struct JSONObjectAgg {
14044    #[serde(default)]
14045    pub expressions: Vec<Expression>,
14046    #[serde(default)]
14047    pub null_handling: Option<Box<Expression>>,
14048    #[serde(default)]
14049    pub unique_keys: Option<Box<Expression>>,
14050    #[serde(default)]
14051    pub return_type: Option<Box<Expression>>,
14052    #[serde(default)]
14053    pub encoding: Option<Box<Expression>>,
14054}
14055
14056/// JSONBObjectAgg
14057#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14058#[cfg_attr(feature = "bindings", derive(TS))]
14059pub struct JSONBObjectAgg {
14060    pub this: Box<Expression>,
14061    pub expression: Box<Expression>,
14062}
14063
14064/// JSONArray
14065#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14066#[cfg_attr(feature = "bindings", derive(TS))]
14067pub struct JSONArray {
14068    #[serde(default)]
14069    pub expressions: Vec<Expression>,
14070    #[serde(default)]
14071    pub null_handling: Option<Box<Expression>>,
14072    #[serde(default)]
14073    pub return_type: Option<Box<Expression>>,
14074    #[serde(default)]
14075    pub strict: Option<Box<Expression>>,
14076}
14077
14078/// JSONArrayAgg
14079#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14080#[cfg_attr(feature = "bindings", derive(TS))]
14081pub struct JSONArrayAgg {
14082    pub this: Box<Expression>,
14083    #[serde(default)]
14084    pub order: Option<Box<Expression>>,
14085    #[serde(default)]
14086    pub null_handling: Option<Box<Expression>>,
14087    #[serde(default)]
14088    pub return_type: Option<Box<Expression>>,
14089    #[serde(default)]
14090    pub strict: Option<Box<Expression>>,
14091}
14092
14093/// JSONExists
14094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14095#[cfg_attr(feature = "bindings", derive(TS))]
14096pub struct JSONExists {
14097    pub this: Box<Expression>,
14098    #[serde(default)]
14099    pub path: Option<Box<Expression>>,
14100    #[serde(default)]
14101    pub passing: Option<Box<Expression>>,
14102    #[serde(default)]
14103    pub on_condition: Option<Box<Expression>>,
14104    #[serde(default)]
14105    pub from_dcolonqmark: Option<Box<Expression>>,
14106}
14107
14108/// JSONColumnDef
14109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14110#[cfg_attr(feature = "bindings", derive(TS))]
14111pub struct JSONColumnDef {
14112    #[serde(default)]
14113    pub this: Option<Box<Expression>>,
14114    #[serde(default)]
14115    pub kind: Option<String>,
14116    #[serde(default)]
14117    pub format_json: bool,
14118    #[serde(default)]
14119    pub path: Option<Box<Expression>>,
14120    #[serde(default)]
14121    pub nested_schema: Option<Box<Expression>>,
14122    #[serde(default)]
14123    pub ordinality: Option<Box<Expression>>,
14124}
14125
14126/// JSONSchema
14127#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14128#[cfg_attr(feature = "bindings", derive(TS))]
14129pub struct JSONSchema {
14130    #[serde(default)]
14131    pub expressions: Vec<Expression>,
14132}
14133
14134/// JSONSet
14135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14136#[cfg_attr(feature = "bindings", derive(TS))]
14137pub struct JSONSet {
14138    pub this: Box<Expression>,
14139    #[serde(default)]
14140    pub expressions: Vec<Expression>,
14141}
14142
14143/// JSONStripNulls
14144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14145#[cfg_attr(feature = "bindings", derive(TS))]
14146pub struct JSONStripNulls {
14147    pub this: Box<Expression>,
14148    #[serde(default)]
14149    pub expression: Option<Box<Expression>>,
14150    #[serde(default)]
14151    pub include_arrays: Option<Box<Expression>>,
14152    #[serde(default)]
14153    pub remove_empty: Option<Box<Expression>>,
14154}
14155
14156/// JSONValue
14157#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14158#[cfg_attr(feature = "bindings", derive(TS))]
14159pub struct JSONValue {
14160    pub this: Box<Expression>,
14161    #[serde(default)]
14162    pub path: Option<Box<Expression>>,
14163    #[serde(default)]
14164    pub returning: Option<Box<Expression>>,
14165    #[serde(default)]
14166    pub on_condition: Option<Box<Expression>>,
14167}
14168
14169/// JSONValueArray
14170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14171#[cfg_attr(feature = "bindings", derive(TS))]
14172pub struct JSONValueArray {
14173    pub this: Box<Expression>,
14174    #[serde(default)]
14175    pub expression: Option<Box<Expression>>,
14176}
14177
14178/// JSONRemove
14179#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14180#[cfg_attr(feature = "bindings", derive(TS))]
14181pub struct JSONRemove {
14182    pub this: Box<Expression>,
14183    #[serde(default)]
14184    pub expressions: Vec<Expression>,
14185}
14186
14187/// JSONTable
14188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14189#[cfg_attr(feature = "bindings", derive(TS))]
14190pub struct JSONTable {
14191    pub this: Box<Expression>,
14192    #[serde(default)]
14193    pub schema: Option<Box<Expression>>,
14194    #[serde(default)]
14195    pub path: Option<Box<Expression>>,
14196    #[serde(default)]
14197    pub error_handling: Option<Box<Expression>>,
14198    #[serde(default)]
14199    pub empty_handling: Option<Box<Expression>>,
14200}
14201
14202/// JSONType
14203#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14204#[cfg_attr(feature = "bindings", derive(TS))]
14205pub struct JSONType {
14206    pub this: Box<Expression>,
14207    #[serde(default)]
14208    pub expression: Option<Box<Expression>>,
14209}
14210
14211/// ObjectInsert
14212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14213#[cfg_attr(feature = "bindings", derive(TS))]
14214pub struct ObjectInsert {
14215    pub this: Box<Expression>,
14216    #[serde(default)]
14217    pub key: Option<Box<Expression>>,
14218    #[serde(default)]
14219    pub value: Option<Box<Expression>>,
14220    #[serde(default)]
14221    pub update_flag: Option<Box<Expression>>,
14222}
14223
14224/// OpenJSONColumnDef
14225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14226#[cfg_attr(feature = "bindings", derive(TS))]
14227pub struct OpenJSONColumnDef {
14228    pub this: Box<Expression>,
14229    pub kind: String,
14230    #[serde(default)]
14231    pub path: Option<Box<Expression>>,
14232    #[serde(default)]
14233    pub as_json: Option<Box<Expression>>,
14234    /// The parsed data type for proper generation
14235    #[serde(default, skip_serializing_if = "Option::is_none")]
14236    pub data_type: Option<DataType>,
14237}
14238
14239/// OpenJSON
14240#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14241#[cfg_attr(feature = "bindings", derive(TS))]
14242pub struct OpenJSON {
14243    pub this: Box<Expression>,
14244    #[serde(default)]
14245    pub path: Option<Box<Expression>>,
14246    #[serde(default)]
14247    pub expressions: Vec<Expression>,
14248}
14249
14250/// JSONBExists
14251#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14252#[cfg_attr(feature = "bindings", derive(TS))]
14253pub struct JSONBExists {
14254    pub this: Box<Expression>,
14255    #[serde(default)]
14256    pub path: Option<Box<Expression>>,
14257}
14258
14259/// JSONCast
14260#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14261#[cfg_attr(feature = "bindings", derive(TS))]
14262pub struct JSONCast {
14263    pub this: Box<Expression>,
14264    pub to: DataType,
14265}
14266
14267/// JSONExtract
14268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14269#[cfg_attr(feature = "bindings", derive(TS))]
14270pub struct JSONExtract {
14271    pub this: Box<Expression>,
14272    pub expression: Box<Expression>,
14273    #[serde(default)]
14274    pub only_json_types: Option<Box<Expression>>,
14275    #[serde(default)]
14276    pub expressions: Vec<Expression>,
14277    #[serde(default)]
14278    pub variant_extract: Option<Box<Expression>>,
14279    #[serde(default)]
14280    pub json_query: Option<Box<Expression>>,
14281    #[serde(default)]
14282    pub option: Option<Box<Expression>>,
14283    #[serde(default)]
14284    pub quote: Option<Box<Expression>>,
14285    #[serde(default)]
14286    pub on_condition: Option<Box<Expression>>,
14287    #[serde(default)]
14288    pub requires_json: Option<Box<Expression>>,
14289}
14290
14291/// JSONExtractQuote
14292#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14293#[cfg_attr(feature = "bindings", derive(TS))]
14294pub struct JSONExtractQuote {
14295    #[serde(default)]
14296    pub option: Option<Box<Expression>>,
14297    #[serde(default)]
14298    pub scalar: Option<Box<Expression>>,
14299}
14300
14301/// JSONExtractArray
14302#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14303#[cfg_attr(feature = "bindings", derive(TS))]
14304pub struct JSONExtractArray {
14305    pub this: Box<Expression>,
14306    #[serde(default)]
14307    pub expression: Option<Box<Expression>>,
14308}
14309
14310/// JSONExtractScalar
14311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14312#[cfg_attr(feature = "bindings", derive(TS))]
14313pub struct JSONExtractScalar {
14314    pub this: Box<Expression>,
14315    pub expression: Box<Expression>,
14316    #[serde(default)]
14317    pub only_json_types: Option<Box<Expression>>,
14318    #[serde(default)]
14319    pub expressions: Vec<Expression>,
14320    #[serde(default)]
14321    pub json_type: Option<Box<Expression>>,
14322    #[serde(default)]
14323    pub scalar_only: Option<Box<Expression>>,
14324}
14325
14326/// JSONBExtractScalar
14327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14328#[cfg_attr(feature = "bindings", derive(TS))]
14329pub struct JSONBExtractScalar {
14330    pub this: Box<Expression>,
14331    pub expression: Box<Expression>,
14332    #[serde(default)]
14333    pub json_type: Option<Box<Expression>>,
14334}
14335
14336/// JSONFormat
14337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14338#[cfg_attr(feature = "bindings", derive(TS))]
14339pub struct JSONFormat {
14340    #[serde(default)]
14341    pub this: Option<Box<Expression>>,
14342    #[serde(default)]
14343    pub options: Vec<Expression>,
14344    #[serde(default)]
14345    pub is_json: Option<Box<Expression>>,
14346    #[serde(default)]
14347    pub to_json: Option<Box<Expression>>,
14348}
14349
14350/// JSONArrayAppend
14351#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14352#[cfg_attr(feature = "bindings", derive(TS))]
14353pub struct JSONArrayAppend {
14354    pub this: Box<Expression>,
14355    #[serde(default)]
14356    pub expressions: Vec<Expression>,
14357}
14358
14359/// JSONArrayContains
14360#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14361#[cfg_attr(feature = "bindings", derive(TS))]
14362pub struct JSONArrayContains {
14363    pub this: Box<Expression>,
14364    pub expression: Box<Expression>,
14365    #[serde(default)]
14366    pub json_type: Option<Box<Expression>>,
14367}
14368
14369/// JSONArrayInsert
14370#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14371#[cfg_attr(feature = "bindings", derive(TS))]
14372pub struct JSONArrayInsert {
14373    pub this: Box<Expression>,
14374    #[serde(default)]
14375    pub expressions: Vec<Expression>,
14376}
14377
14378/// ParseJSON
14379#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14380#[cfg_attr(feature = "bindings", derive(TS))]
14381pub struct ParseJSON {
14382    pub this: Box<Expression>,
14383    #[serde(default)]
14384    pub expression: Option<Box<Expression>>,
14385    #[serde(default)]
14386    pub safe: Option<Box<Expression>>,
14387}
14388
14389/// ParseUrl
14390#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14391#[cfg_attr(feature = "bindings", derive(TS))]
14392pub struct ParseUrl {
14393    pub this: Box<Expression>,
14394    #[serde(default)]
14395    pub part_to_extract: Option<Box<Expression>>,
14396    #[serde(default)]
14397    pub key: Option<Box<Expression>>,
14398    #[serde(default)]
14399    pub permissive: Option<Box<Expression>>,
14400}
14401
14402/// ParseIp
14403#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14404#[cfg_attr(feature = "bindings", derive(TS))]
14405pub struct ParseIp {
14406    pub this: Box<Expression>,
14407    #[serde(default)]
14408    pub type_: Option<Box<Expression>>,
14409    #[serde(default)]
14410    pub permissive: Option<Box<Expression>>,
14411}
14412
14413/// ParseTime
14414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14415#[cfg_attr(feature = "bindings", derive(TS))]
14416pub struct ParseTime {
14417    pub this: Box<Expression>,
14418    pub format: String,
14419}
14420
14421/// ParseDatetime
14422#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14423#[cfg_attr(feature = "bindings", derive(TS))]
14424pub struct ParseDatetime {
14425    pub this: Box<Expression>,
14426    #[serde(default)]
14427    pub format: Option<String>,
14428    #[serde(default)]
14429    pub zone: Option<Box<Expression>>,
14430}
14431
14432/// Map
14433#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14434#[cfg_attr(feature = "bindings", derive(TS))]
14435pub struct Map {
14436    #[serde(default)]
14437    pub keys: Vec<Expression>,
14438    #[serde(default)]
14439    pub values: Vec<Expression>,
14440}
14441
14442/// MapCat
14443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14444#[cfg_attr(feature = "bindings", derive(TS))]
14445pub struct MapCat {
14446    pub this: Box<Expression>,
14447    pub expression: Box<Expression>,
14448}
14449
14450/// MapDelete
14451#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14452#[cfg_attr(feature = "bindings", derive(TS))]
14453pub struct MapDelete {
14454    pub this: Box<Expression>,
14455    #[serde(default)]
14456    pub expressions: Vec<Expression>,
14457}
14458
14459/// MapInsert
14460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14461#[cfg_attr(feature = "bindings", derive(TS))]
14462pub struct MapInsert {
14463    pub this: Box<Expression>,
14464    #[serde(default)]
14465    pub key: Option<Box<Expression>>,
14466    #[serde(default)]
14467    pub value: Option<Box<Expression>>,
14468    #[serde(default)]
14469    pub update_flag: Option<Box<Expression>>,
14470}
14471
14472/// MapPick
14473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14474#[cfg_attr(feature = "bindings", derive(TS))]
14475pub struct MapPick {
14476    pub this: Box<Expression>,
14477    #[serde(default)]
14478    pub expressions: Vec<Expression>,
14479}
14480
14481/// ScopeResolution
14482#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14483#[cfg_attr(feature = "bindings", derive(TS))]
14484pub struct ScopeResolution {
14485    #[serde(default)]
14486    pub this: Option<Box<Expression>>,
14487    pub expression: Box<Expression>,
14488}
14489
14490/// Slice
14491#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14492#[cfg_attr(feature = "bindings", derive(TS))]
14493pub struct Slice {
14494    #[serde(default)]
14495    pub this: Option<Box<Expression>>,
14496    #[serde(default)]
14497    pub expression: Option<Box<Expression>>,
14498    #[serde(default)]
14499    pub step: Option<Box<Expression>>,
14500}
14501
14502/// VarMap
14503#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14504#[cfg_attr(feature = "bindings", derive(TS))]
14505pub struct VarMap {
14506    #[serde(default)]
14507    pub keys: Vec<Expression>,
14508    #[serde(default)]
14509    pub values: Vec<Expression>,
14510}
14511
14512/// MatchAgainst
14513#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14514#[cfg_attr(feature = "bindings", derive(TS))]
14515pub struct MatchAgainst {
14516    pub this: Box<Expression>,
14517    #[serde(default)]
14518    pub expressions: Vec<Expression>,
14519    #[serde(default)]
14520    pub modifier: Option<Box<Expression>>,
14521}
14522
14523/// MD5Digest
14524#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14525#[cfg_attr(feature = "bindings", derive(TS))]
14526pub struct MD5Digest {
14527    pub this: Box<Expression>,
14528    #[serde(default)]
14529    pub expressions: Vec<Expression>,
14530}
14531
14532/// Monthname
14533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14534#[cfg_attr(feature = "bindings", derive(TS))]
14535pub struct Monthname {
14536    pub this: Box<Expression>,
14537    #[serde(default)]
14538    pub abbreviated: Option<Box<Expression>>,
14539}
14540
14541/// Ntile
14542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14543#[cfg_attr(feature = "bindings", derive(TS))]
14544pub struct Ntile {
14545    #[serde(default)]
14546    pub this: Option<Box<Expression>>,
14547}
14548
14549/// Normalize
14550#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14551#[cfg_attr(feature = "bindings", derive(TS))]
14552pub struct Normalize {
14553    pub this: Box<Expression>,
14554    #[serde(default)]
14555    pub form: Option<Box<Expression>>,
14556    #[serde(default)]
14557    pub is_casefold: Option<Box<Expression>>,
14558}
14559
14560/// Normal
14561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14562#[cfg_attr(feature = "bindings", derive(TS))]
14563pub struct Normal {
14564    pub this: Box<Expression>,
14565    #[serde(default)]
14566    pub stddev: Option<Box<Expression>>,
14567    #[serde(default)]
14568    pub gen: Option<Box<Expression>>,
14569}
14570
14571/// Predict
14572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14573#[cfg_attr(feature = "bindings", derive(TS))]
14574pub struct Predict {
14575    pub this: Box<Expression>,
14576    pub expression: Box<Expression>,
14577    #[serde(default)]
14578    pub params_struct: Option<Box<Expression>>,
14579}
14580
14581/// MLTranslate
14582#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14583#[cfg_attr(feature = "bindings", derive(TS))]
14584pub struct MLTranslate {
14585    pub this: Box<Expression>,
14586    pub expression: Box<Expression>,
14587    #[serde(default)]
14588    pub params_struct: Option<Box<Expression>>,
14589}
14590
14591/// FeaturesAtTime
14592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14593#[cfg_attr(feature = "bindings", derive(TS))]
14594pub struct FeaturesAtTime {
14595    pub this: Box<Expression>,
14596    #[serde(default)]
14597    pub time: Option<Box<Expression>>,
14598    #[serde(default)]
14599    pub num_rows: Option<Box<Expression>>,
14600    #[serde(default)]
14601    pub ignore_feature_nulls: Option<Box<Expression>>,
14602}
14603
14604/// GenerateEmbedding
14605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14606#[cfg_attr(feature = "bindings", derive(TS))]
14607pub struct GenerateEmbedding {
14608    pub this: Box<Expression>,
14609    pub expression: Box<Expression>,
14610    #[serde(default)]
14611    pub params_struct: Option<Box<Expression>>,
14612    #[serde(default)]
14613    pub is_text: Option<Box<Expression>>,
14614}
14615
14616/// MLForecast
14617#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14618#[cfg_attr(feature = "bindings", derive(TS))]
14619pub struct MLForecast {
14620    pub this: Box<Expression>,
14621    #[serde(default)]
14622    pub expression: Option<Box<Expression>>,
14623    #[serde(default)]
14624    pub params_struct: Option<Box<Expression>>,
14625}
14626
14627/// ModelAttribute
14628#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14629#[cfg_attr(feature = "bindings", derive(TS))]
14630pub struct ModelAttribute {
14631    pub this: Box<Expression>,
14632    pub expression: Box<Expression>,
14633}
14634
14635/// VectorSearch
14636#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14637#[cfg_attr(feature = "bindings", derive(TS))]
14638pub struct VectorSearch {
14639    pub this: Box<Expression>,
14640    #[serde(default)]
14641    pub column_to_search: Option<Box<Expression>>,
14642    #[serde(default)]
14643    pub query_table: Option<Box<Expression>>,
14644    #[serde(default)]
14645    pub query_column_to_search: Option<Box<Expression>>,
14646    #[serde(default)]
14647    pub top_k: Option<Box<Expression>>,
14648    #[serde(default)]
14649    pub distance_type: Option<Box<Expression>>,
14650    #[serde(default)]
14651    pub options: Vec<Expression>,
14652}
14653
14654/// Quantile
14655#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14656#[cfg_attr(feature = "bindings", derive(TS))]
14657pub struct Quantile {
14658    pub this: Box<Expression>,
14659    #[serde(default)]
14660    pub quantile: Option<Box<Expression>>,
14661}
14662
14663/// ApproxQuantile
14664#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14665#[cfg_attr(feature = "bindings", derive(TS))]
14666pub struct ApproxQuantile {
14667    pub this: Box<Expression>,
14668    #[serde(default)]
14669    pub quantile: Option<Box<Expression>>,
14670    #[serde(default)]
14671    pub accuracy: Option<Box<Expression>>,
14672    #[serde(default)]
14673    pub weight: Option<Box<Expression>>,
14674    #[serde(default)]
14675    pub error_tolerance: Option<Box<Expression>>,
14676}
14677
14678/// ApproxPercentileEstimate
14679#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14680#[cfg_attr(feature = "bindings", derive(TS))]
14681pub struct ApproxPercentileEstimate {
14682    pub this: Box<Expression>,
14683    #[serde(default)]
14684    pub percentile: Option<Box<Expression>>,
14685}
14686
14687/// Randn
14688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14689#[cfg_attr(feature = "bindings", derive(TS))]
14690pub struct Randn {
14691    #[serde(default)]
14692    pub this: Option<Box<Expression>>,
14693}
14694
14695/// Randstr
14696#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14697#[cfg_attr(feature = "bindings", derive(TS))]
14698pub struct Randstr {
14699    pub this: Box<Expression>,
14700    #[serde(default)]
14701    pub generator: Option<Box<Expression>>,
14702}
14703
14704/// RangeN
14705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14706#[cfg_attr(feature = "bindings", derive(TS))]
14707pub struct RangeN {
14708    pub this: Box<Expression>,
14709    #[serde(default)]
14710    pub expressions: Vec<Expression>,
14711    #[serde(default)]
14712    pub each: Option<Box<Expression>>,
14713}
14714
14715/// RangeBucket
14716#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14717#[cfg_attr(feature = "bindings", derive(TS))]
14718pub struct RangeBucket {
14719    pub this: Box<Expression>,
14720    pub expression: Box<Expression>,
14721}
14722
14723/// ReadCSV
14724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14725#[cfg_attr(feature = "bindings", derive(TS))]
14726pub struct ReadCSV {
14727    pub this: Box<Expression>,
14728    #[serde(default)]
14729    pub expressions: Vec<Expression>,
14730}
14731
14732/// ReadParquet
14733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14734#[cfg_attr(feature = "bindings", derive(TS))]
14735pub struct ReadParquet {
14736    #[serde(default)]
14737    pub expressions: Vec<Expression>,
14738}
14739
14740/// Reduce
14741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14742#[cfg_attr(feature = "bindings", derive(TS))]
14743pub struct Reduce {
14744    pub this: Box<Expression>,
14745    #[serde(default)]
14746    pub initial: Option<Box<Expression>>,
14747    #[serde(default)]
14748    pub merge: Option<Box<Expression>>,
14749    #[serde(default)]
14750    pub finish: Option<Box<Expression>>,
14751}
14752
14753/// RegexpExtractAll
14754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14755#[cfg_attr(feature = "bindings", derive(TS))]
14756pub struct RegexpExtractAll {
14757    pub this: Box<Expression>,
14758    pub expression: Box<Expression>,
14759    #[serde(default)]
14760    pub group: Option<Box<Expression>>,
14761    #[serde(default)]
14762    pub parameters: Option<Box<Expression>>,
14763    #[serde(default)]
14764    pub position: Option<Box<Expression>>,
14765    #[serde(default)]
14766    pub occurrence: Option<Box<Expression>>,
14767}
14768
14769/// RegexpILike
14770#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14771#[cfg_attr(feature = "bindings", derive(TS))]
14772pub struct RegexpILike {
14773    pub this: Box<Expression>,
14774    pub expression: Box<Expression>,
14775    #[serde(default)]
14776    pub flag: Option<Box<Expression>>,
14777}
14778
14779/// RegexpFullMatch
14780#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14781#[cfg_attr(feature = "bindings", derive(TS))]
14782pub struct RegexpFullMatch {
14783    pub this: Box<Expression>,
14784    pub expression: Box<Expression>,
14785    #[serde(default)]
14786    pub options: Vec<Expression>,
14787}
14788
14789/// RegexpInstr
14790#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14791#[cfg_attr(feature = "bindings", derive(TS))]
14792pub struct RegexpInstr {
14793    pub this: Box<Expression>,
14794    pub expression: Box<Expression>,
14795    #[serde(default)]
14796    pub position: Option<Box<Expression>>,
14797    #[serde(default)]
14798    pub occurrence: Option<Box<Expression>>,
14799    #[serde(default)]
14800    pub option: Option<Box<Expression>>,
14801    #[serde(default)]
14802    pub parameters: Option<Box<Expression>>,
14803    #[serde(default)]
14804    pub group: Option<Box<Expression>>,
14805}
14806
14807/// RegexpSplit
14808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14809#[cfg_attr(feature = "bindings", derive(TS))]
14810pub struct RegexpSplit {
14811    pub this: Box<Expression>,
14812    pub expression: Box<Expression>,
14813    #[serde(default)]
14814    pub limit: Option<Box<Expression>>,
14815}
14816
14817/// RegexpCount
14818#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14819#[cfg_attr(feature = "bindings", derive(TS))]
14820pub struct RegexpCount {
14821    pub this: Box<Expression>,
14822    pub expression: Box<Expression>,
14823    #[serde(default)]
14824    pub position: Option<Box<Expression>>,
14825    #[serde(default)]
14826    pub parameters: Option<Box<Expression>>,
14827}
14828
14829/// RegrValx
14830#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14831#[cfg_attr(feature = "bindings", derive(TS))]
14832pub struct RegrValx {
14833    pub this: Box<Expression>,
14834    pub expression: Box<Expression>,
14835}
14836
14837/// RegrValy
14838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14839#[cfg_attr(feature = "bindings", derive(TS))]
14840pub struct RegrValy {
14841    pub this: Box<Expression>,
14842    pub expression: Box<Expression>,
14843}
14844
14845/// RegrAvgy
14846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14847#[cfg_attr(feature = "bindings", derive(TS))]
14848pub struct RegrAvgy {
14849    pub this: Box<Expression>,
14850    pub expression: Box<Expression>,
14851}
14852
14853/// RegrAvgx
14854#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14855#[cfg_attr(feature = "bindings", derive(TS))]
14856pub struct RegrAvgx {
14857    pub this: Box<Expression>,
14858    pub expression: Box<Expression>,
14859}
14860
14861/// RegrCount
14862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14863#[cfg_attr(feature = "bindings", derive(TS))]
14864pub struct RegrCount {
14865    pub this: Box<Expression>,
14866    pub expression: Box<Expression>,
14867}
14868
14869/// RegrIntercept
14870#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14871#[cfg_attr(feature = "bindings", derive(TS))]
14872pub struct RegrIntercept {
14873    pub this: Box<Expression>,
14874    pub expression: Box<Expression>,
14875}
14876
14877/// RegrR2
14878#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14879#[cfg_attr(feature = "bindings", derive(TS))]
14880pub struct RegrR2 {
14881    pub this: Box<Expression>,
14882    pub expression: Box<Expression>,
14883}
14884
14885/// RegrSxx
14886#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14887#[cfg_attr(feature = "bindings", derive(TS))]
14888pub struct RegrSxx {
14889    pub this: Box<Expression>,
14890    pub expression: Box<Expression>,
14891}
14892
14893/// RegrSxy
14894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14895#[cfg_attr(feature = "bindings", derive(TS))]
14896pub struct RegrSxy {
14897    pub this: Box<Expression>,
14898    pub expression: Box<Expression>,
14899}
14900
14901/// RegrSyy
14902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14903#[cfg_attr(feature = "bindings", derive(TS))]
14904pub struct RegrSyy {
14905    pub this: Box<Expression>,
14906    pub expression: Box<Expression>,
14907}
14908
14909/// RegrSlope
14910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14911#[cfg_attr(feature = "bindings", derive(TS))]
14912pub struct RegrSlope {
14913    pub this: Box<Expression>,
14914    pub expression: Box<Expression>,
14915}
14916
14917/// SafeAdd
14918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14919#[cfg_attr(feature = "bindings", derive(TS))]
14920pub struct SafeAdd {
14921    pub this: Box<Expression>,
14922    pub expression: Box<Expression>,
14923}
14924
14925/// SafeDivide
14926#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14927#[cfg_attr(feature = "bindings", derive(TS))]
14928pub struct SafeDivide {
14929    pub this: Box<Expression>,
14930    pub expression: Box<Expression>,
14931}
14932
14933/// SafeMultiply
14934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14935#[cfg_attr(feature = "bindings", derive(TS))]
14936pub struct SafeMultiply {
14937    pub this: Box<Expression>,
14938    pub expression: Box<Expression>,
14939}
14940
14941/// SafeSubtract
14942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14943#[cfg_attr(feature = "bindings", derive(TS))]
14944pub struct SafeSubtract {
14945    pub this: Box<Expression>,
14946    pub expression: Box<Expression>,
14947}
14948
14949/// SHA2
14950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14951#[cfg_attr(feature = "bindings", derive(TS))]
14952pub struct SHA2 {
14953    pub this: Box<Expression>,
14954    #[serde(default)]
14955    pub length: Option<i64>,
14956}
14957
14958/// SHA2Digest
14959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14960#[cfg_attr(feature = "bindings", derive(TS))]
14961pub struct SHA2Digest {
14962    pub this: Box<Expression>,
14963    #[serde(default)]
14964    pub length: Option<i64>,
14965}
14966
14967/// SortArray
14968#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14969#[cfg_attr(feature = "bindings", derive(TS))]
14970pub struct SortArray {
14971    pub this: Box<Expression>,
14972    #[serde(default)]
14973    pub asc: Option<Box<Expression>>,
14974    #[serde(default)]
14975    pub nulls_first: Option<Box<Expression>>,
14976}
14977
14978/// SplitPart
14979#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14980#[cfg_attr(feature = "bindings", derive(TS))]
14981pub struct SplitPart {
14982    pub this: Box<Expression>,
14983    #[serde(default)]
14984    pub delimiter: Option<Box<Expression>>,
14985    #[serde(default)]
14986    pub part_index: Option<Box<Expression>>,
14987}
14988
14989/// SUBSTRING_INDEX(str, delim, count)
14990#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14991#[cfg_attr(feature = "bindings", derive(TS))]
14992pub struct SubstringIndex {
14993    pub this: Box<Expression>,
14994    #[serde(default)]
14995    pub delimiter: Option<Box<Expression>>,
14996    #[serde(default)]
14997    pub count: Option<Box<Expression>>,
14998}
14999
15000/// StandardHash
15001#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15002#[cfg_attr(feature = "bindings", derive(TS))]
15003pub struct StandardHash {
15004    pub this: Box<Expression>,
15005    #[serde(default)]
15006    pub expression: Option<Box<Expression>>,
15007}
15008
15009/// StrPosition
15010#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15011#[cfg_attr(feature = "bindings", derive(TS))]
15012pub struct StrPosition {
15013    pub this: Box<Expression>,
15014    #[serde(default)]
15015    pub substr: Option<Box<Expression>>,
15016    #[serde(default)]
15017    pub position: Option<Box<Expression>>,
15018    #[serde(default)]
15019    pub occurrence: Option<Box<Expression>>,
15020}
15021
15022/// Search
15023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15024#[cfg_attr(feature = "bindings", derive(TS))]
15025pub struct Search {
15026    pub this: Box<Expression>,
15027    pub expression: Box<Expression>,
15028    #[serde(default)]
15029    pub json_scope: Option<Box<Expression>>,
15030    #[serde(default)]
15031    pub analyzer: Option<Box<Expression>>,
15032    #[serde(default)]
15033    pub analyzer_options: Option<Box<Expression>>,
15034    #[serde(default)]
15035    pub search_mode: Option<Box<Expression>>,
15036}
15037
15038/// SearchIp
15039#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15040#[cfg_attr(feature = "bindings", derive(TS))]
15041pub struct SearchIp {
15042    pub this: Box<Expression>,
15043    pub expression: Box<Expression>,
15044}
15045
15046/// StrToDate
15047#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15048#[cfg_attr(feature = "bindings", derive(TS))]
15049pub struct StrToDate {
15050    pub this: Box<Expression>,
15051    #[serde(default)]
15052    pub format: Option<String>,
15053    #[serde(default)]
15054    pub safe: Option<Box<Expression>>,
15055}
15056
15057/// StrToTime
15058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15059#[cfg_attr(feature = "bindings", derive(TS))]
15060pub struct StrToTime {
15061    pub this: Box<Expression>,
15062    pub format: String,
15063    #[serde(default)]
15064    pub zone: Option<Box<Expression>>,
15065    #[serde(default)]
15066    pub safe: Option<Box<Expression>>,
15067    #[serde(default)]
15068    pub target_type: Option<Box<Expression>>,
15069}
15070
15071/// StrToUnix
15072#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15073#[cfg_attr(feature = "bindings", derive(TS))]
15074pub struct StrToUnix {
15075    #[serde(default)]
15076    pub this: Option<Box<Expression>>,
15077    #[serde(default)]
15078    pub format: Option<String>,
15079}
15080
15081/// StrToMap
15082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15083#[cfg_attr(feature = "bindings", derive(TS))]
15084pub struct StrToMap {
15085    pub this: Box<Expression>,
15086    #[serde(default)]
15087    pub pair_delim: Option<Box<Expression>>,
15088    #[serde(default)]
15089    pub key_value_delim: Option<Box<Expression>>,
15090    #[serde(default)]
15091    pub duplicate_resolution_callback: Option<Box<Expression>>,
15092}
15093
15094/// NumberToStr
15095#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15096#[cfg_attr(feature = "bindings", derive(TS))]
15097pub struct NumberToStr {
15098    pub this: Box<Expression>,
15099    pub format: String,
15100    #[serde(default)]
15101    pub culture: Option<Box<Expression>>,
15102}
15103
15104/// FromBase
15105#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15106#[cfg_attr(feature = "bindings", derive(TS))]
15107pub struct FromBase {
15108    pub this: Box<Expression>,
15109    pub expression: Box<Expression>,
15110}
15111
15112/// Stuff
15113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15114#[cfg_attr(feature = "bindings", derive(TS))]
15115pub struct Stuff {
15116    pub this: Box<Expression>,
15117    #[serde(default)]
15118    pub start: Option<Box<Expression>>,
15119    #[serde(default)]
15120    pub length: Option<i64>,
15121    pub expression: Box<Expression>,
15122}
15123
15124/// TimeToStr
15125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15126#[cfg_attr(feature = "bindings", derive(TS))]
15127pub struct TimeToStr {
15128    pub this: Box<Expression>,
15129    pub format: String,
15130    #[serde(default)]
15131    pub culture: Option<Box<Expression>>,
15132    #[serde(default)]
15133    pub zone: Option<Box<Expression>>,
15134}
15135
15136/// TimeStrToTime
15137#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15138#[cfg_attr(feature = "bindings", derive(TS))]
15139pub struct TimeStrToTime {
15140    pub this: Box<Expression>,
15141    #[serde(default)]
15142    pub zone: Option<Box<Expression>>,
15143}
15144
15145/// TsOrDsAdd
15146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15147#[cfg_attr(feature = "bindings", derive(TS))]
15148pub struct TsOrDsAdd {
15149    pub this: Box<Expression>,
15150    pub expression: Box<Expression>,
15151    #[serde(default)]
15152    pub unit: Option<String>,
15153    #[serde(default)]
15154    pub return_type: Option<Box<Expression>>,
15155}
15156
15157/// TsOrDsDiff
15158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15159#[cfg_attr(feature = "bindings", derive(TS))]
15160pub struct TsOrDsDiff {
15161    pub this: Box<Expression>,
15162    pub expression: Box<Expression>,
15163    #[serde(default)]
15164    pub unit: Option<String>,
15165}
15166
15167/// TsOrDsToDate
15168#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15169#[cfg_attr(feature = "bindings", derive(TS))]
15170pub struct TsOrDsToDate {
15171    pub this: Box<Expression>,
15172    #[serde(default)]
15173    pub format: Option<String>,
15174    #[serde(default)]
15175    pub safe: Option<Box<Expression>>,
15176}
15177
15178/// TsOrDsToTime
15179#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15180#[cfg_attr(feature = "bindings", derive(TS))]
15181pub struct TsOrDsToTime {
15182    pub this: Box<Expression>,
15183    #[serde(default)]
15184    pub format: Option<String>,
15185    #[serde(default)]
15186    pub safe: Option<Box<Expression>>,
15187}
15188
15189/// Unhex
15190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15191#[cfg_attr(feature = "bindings", derive(TS))]
15192pub struct Unhex {
15193    pub this: Box<Expression>,
15194    #[serde(default)]
15195    pub expression: Option<Box<Expression>>,
15196}
15197
15198/// Uniform
15199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15200#[cfg_attr(feature = "bindings", derive(TS))]
15201pub struct Uniform {
15202    pub this: Box<Expression>,
15203    pub expression: Box<Expression>,
15204    #[serde(default)]
15205    pub gen: Option<Box<Expression>>,
15206    #[serde(default)]
15207    pub seed: Option<Box<Expression>>,
15208}
15209
15210/// UnixToStr
15211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15212#[cfg_attr(feature = "bindings", derive(TS))]
15213pub struct UnixToStr {
15214    pub this: Box<Expression>,
15215    #[serde(default)]
15216    pub format: Option<String>,
15217}
15218
15219/// UnixToTime
15220#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15221#[cfg_attr(feature = "bindings", derive(TS))]
15222pub struct UnixToTime {
15223    pub this: Box<Expression>,
15224    #[serde(default)]
15225    pub scale: Option<i64>,
15226    #[serde(default)]
15227    pub zone: Option<Box<Expression>>,
15228    #[serde(default)]
15229    pub hours: Option<Box<Expression>>,
15230    #[serde(default)]
15231    pub minutes: Option<Box<Expression>>,
15232    #[serde(default)]
15233    pub format: Option<String>,
15234    #[serde(default)]
15235    pub target_type: Option<Box<Expression>>,
15236}
15237
15238/// Uuid
15239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15240#[cfg_attr(feature = "bindings", derive(TS))]
15241pub struct Uuid {
15242    #[serde(default)]
15243    pub this: Option<Box<Expression>>,
15244    #[serde(default)]
15245    pub name: Option<String>,
15246    #[serde(default)]
15247    pub is_string: Option<Box<Expression>>,
15248}
15249
15250/// TimestampFromParts
15251#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15252#[cfg_attr(feature = "bindings", derive(TS))]
15253pub struct TimestampFromParts {
15254    #[serde(default)]
15255    pub zone: Option<Box<Expression>>,
15256    #[serde(default)]
15257    pub milli: Option<Box<Expression>>,
15258    #[serde(default)]
15259    pub this: Option<Box<Expression>>,
15260    #[serde(default)]
15261    pub expression: Option<Box<Expression>>,
15262}
15263
15264/// TimestampTzFromParts
15265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15266#[cfg_attr(feature = "bindings", derive(TS))]
15267pub struct TimestampTzFromParts {
15268    #[serde(default)]
15269    pub zone: Option<Box<Expression>>,
15270}
15271
15272/// Corr
15273#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15274#[cfg_attr(feature = "bindings", derive(TS))]
15275pub struct Corr {
15276    pub this: Box<Expression>,
15277    pub expression: Box<Expression>,
15278    #[serde(default)]
15279    pub null_on_zero_variance: Option<Box<Expression>>,
15280}
15281
15282/// WidthBucket
15283#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15284#[cfg_attr(feature = "bindings", derive(TS))]
15285pub struct WidthBucket {
15286    pub this: Box<Expression>,
15287    #[serde(default)]
15288    pub min_value: Option<Box<Expression>>,
15289    #[serde(default)]
15290    pub max_value: Option<Box<Expression>>,
15291    #[serde(default)]
15292    pub num_buckets: Option<Box<Expression>>,
15293    #[serde(default)]
15294    pub threshold: Option<Box<Expression>>,
15295}
15296
15297/// CovarSamp
15298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15299#[cfg_attr(feature = "bindings", derive(TS))]
15300pub struct CovarSamp {
15301    pub this: Box<Expression>,
15302    pub expression: Box<Expression>,
15303}
15304
15305/// CovarPop
15306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15307#[cfg_attr(feature = "bindings", derive(TS))]
15308pub struct CovarPop {
15309    pub this: Box<Expression>,
15310    pub expression: Box<Expression>,
15311}
15312
15313/// Week
15314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15315#[cfg_attr(feature = "bindings", derive(TS))]
15316pub struct Week {
15317    pub this: Box<Expression>,
15318    #[serde(default)]
15319    pub mode: Option<Box<Expression>>,
15320}
15321
15322/// XMLElement
15323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15324#[cfg_attr(feature = "bindings", derive(TS))]
15325pub struct XMLElement {
15326    pub this: Box<Expression>,
15327    #[serde(default)]
15328    pub expressions: Vec<Expression>,
15329    #[serde(default)]
15330    pub evalname: Option<Box<Expression>>,
15331}
15332
15333/// XMLGet
15334#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15335#[cfg_attr(feature = "bindings", derive(TS))]
15336pub struct XMLGet {
15337    pub this: Box<Expression>,
15338    pub expression: Box<Expression>,
15339    #[serde(default)]
15340    pub instance: Option<Box<Expression>>,
15341}
15342
15343/// XMLTable
15344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15345#[cfg_attr(feature = "bindings", derive(TS))]
15346pub struct XMLTable {
15347    pub this: Box<Expression>,
15348    #[serde(default)]
15349    pub namespaces: Option<Box<Expression>>,
15350    #[serde(default)]
15351    pub passing: Option<Box<Expression>>,
15352    #[serde(default)]
15353    pub columns: Vec<Expression>,
15354    #[serde(default)]
15355    pub by_ref: Option<Box<Expression>>,
15356}
15357
15358/// XMLKeyValueOption
15359#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15360#[cfg_attr(feature = "bindings", derive(TS))]
15361pub struct XMLKeyValueOption {
15362    pub this: Box<Expression>,
15363    #[serde(default)]
15364    pub expression: Option<Box<Expression>>,
15365}
15366
15367/// Zipf
15368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15369#[cfg_attr(feature = "bindings", derive(TS))]
15370pub struct Zipf {
15371    pub this: Box<Expression>,
15372    #[serde(default)]
15373    pub elementcount: Option<Box<Expression>>,
15374    #[serde(default)]
15375    pub gen: Option<Box<Expression>>,
15376}
15377
15378/// Merge
15379#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15380#[cfg_attr(feature = "bindings", derive(TS))]
15381pub struct Merge {
15382    pub this: Box<Expression>,
15383    pub using: Box<Expression>,
15384    #[serde(default)]
15385    pub on: Option<Box<Expression>>,
15386    #[serde(default)]
15387    pub using_cond: Option<Box<Expression>>,
15388    #[serde(default)]
15389    pub whens: Option<Box<Expression>>,
15390    #[serde(default)]
15391    pub with_: Option<Box<Expression>>,
15392    #[serde(default)]
15393    pub returning: Option<Box<Expression>>,
15394}
15395
15396/// When
15397#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15398#[cfg_attr(feature = "bindings", derive(TS))]
15399pub struct When {
15400    #[serde(default)]
15401    pub matched: Option<Box<Expression>>,
15402    #[serde(default)]
15403    pub source: Option<Box<Expression>>,
15404    #[serde(default)]
15405    pub condition: Option<Box<Expression>>,
15406    pub then: Box<Expression>,
15407}
15408
15409/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15410#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15411#[cfg_attr(feature = "bindings", derive(TS))]
15412pub struct Whens {
15413    #[serde(default)]
15414    pub expressions: Vec<Expression>,
15415}
15416
15417/// NextValueFor
15418#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15419#[cfg_attr(feature = "bindings", derive(TS))]
15420pub struct NextValueFor {
15421    pub this: Box<Expression>,
15422    #[serde(default)]
15423    pub order: Option<Box<Expression>>,
15424}
15425
15426#[cfg(test)]
15427mod tests {
15428    use super::*;
15429
15430    #[test]
15431    fn test_source_spans_are_metadata_not_expression_identity() {
15432        let plain = Expression::column("customer_id");
15433        let mut positioned = plain.clone();
15434        if let Expression::Column(column) = &mut positioned {
15435            column.span = Some(Span::new(7, 18, 1, 19));
15436            column.name.span = column.span;
15437        }
15438        assert_eq!(plain, positioned);
15439        assert_ne!(
15440            serde_json::to_value(&plain).unwrap(),
15441            serde_json::to_value(&positioned).unwrap()
15442        );
15443        assert_eq!(
15444            Identifier::new("a"),
15445            Identifier::new("a").with_span(Span::new(3, 4, 1, 5))
15446        );
15447        assert_ne!(Identifier::new("a"), Identifier::quoted("a"));
15448        assert_ne!(plain, Expression::column("other"));
15449        let Expression::Column(column) = plain else {
15450            unreachable!()
15451        };
15452        assert!(column.span.is_none() && column.name.span.is_none());
15453    }
15454
15455    #[test]
15456    #[cfg(feature = "bindings")]
15457    fn export_typescript_types() {
15458        // This test exports TypeScript types to the generated directory
15459        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
15460        Expression::export_all(&ts_rs::Config::default())
15461            .expect("Failed to export Expression types");
15462
15463        let mut variant_names = String::from(
15464            "// This file was generated from the Rust Expression enum. Do not edit it manually.\n\n",
15465        );
15466        variant_names.push_str("export const EXPRESSION_VARIANT_NAMES = [\n");
15467        for name in Expression::SERIALIZED_VARIANT_NAMES {
15468            use std::fmt::Write;
15469            writeln!(variant_names, "  {name:?},").expect("writing to a String cannot fail");
15470        }
15471        variant_names.push_str("] as const;\n");
15472
15473        let output_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
15474            .join("bindings/ExpressionVariantNames.ts");
15475        std::fs::write(output_path, variant_names)
15476            .expect("Failed to export serialized Expression variant names");
15477    }
15478
15479    #[test]
15480    fn test_simple_select_builder() {
15481        let select = Select::new()
15482            .column(Expression::star())
15483            .from(Expression::Table(Box::new(TableRef::new("users"))));
15484
15485        assert_eq!(select.expressions.len(), 1);
15486        assert!(select.from.is_some());
15487    }
15488
15489    #[test]
15490    fn test_expression_alias() {
15491        let expr = Expression::column("id").alias("user_id");
15492
15493        match expr {
15494            Expression::Alias(a) => {
15495                assert_eq!(a.alias.name, "user_id");
15496            }
15497            _ => panic!("Expected Alias"),
15498        }
15499    }
15500
15501    #[test]
15502    fn test_literal_creation() {
15503        let num = Expression::number(42);
15504        let str = Expression::string("hello");
15505
15506        match num {
15507            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
15508                let Literal::Number(n) = lit.as_ref() else {
15509                    unreachable!()
15510                };
15511                assert_eq!(n, "42")
15512            }
15513            _ => panic!("Expected Number"),
15514        }
15515
15516        match str {
15517            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
15518                let Literal::String(s) = lit.as_ref() else {
15519                    unreachable!()
15520                };
15521                assert_eq!(s, "hello")
15522            }
15523            _ => panic!("Expected String"),
15524        }
15525    }
15526
15527    #[test]
15528    fn test_expression_sql() {
15529        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
15530        assert_eq!(expr.sql(), "SELECT 1 + 2");
15531    }
15532
15533    #[test]
15534    fn test_expression_sql_for() {
15535        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
15536        let sql = expr.sql_for(crate::DialectType::Generic);
15537        // Generic mode normalizes IF() to CASE WHEN
15538        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
15539    }
15540}