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    /// Structured Vertica syntax whose semantics are not shared by other dialects.
82    Vertica(Box<VerticaExpression>),
83    // Literals
84    Literal(Box<Literal>),
85    Boolean(BooleanLiteral),
86    Null(Null),
87
88    // Identifiers
89    Identifier(Identifier),
90    Column(Box<Column>),
91    Table(Box<TableRef>),
92    Star(Star),
93    /// Snowflake braced wildcard syntax: {*}, {tbl.*}, {* EXCLUDE (...)}, {* ILIKE '...'}
94    BracedWildcard(Box<Expression>),
95
96    // Queries
97    Select(Box<Select>),
98    Union(Box<Union>),
99    Intersect(Box<Intersect>),
100    Except(Box<Except>),
101    Subquery(Box<Subquery>),
102    PipeOperator(Box<PipeOperator>),
103    Pivot(Box<Pivot>),
104    PivotAlias(Box<PivotAlias>),
105    Unpivot(Box<Unpivot>),
106    Values(Box<Values>),
107    PreWhere(Box<PreWhere>),
108    Stream(Box<Stream>),
109    UsingData(Box<UsingData>),
110    XmlNamespace(Box<XmlNamespace>),
111
112    // DML
113    Insert(Box<Insert>),
114    Update(Box<Update>),
115    Delete(Box<Delete>),
116    Copy(Box<CopyStmt>),
117    Put(Box<PutStmt>),
118    StageReference(Box<StageReference>),
119    TryCatch(Box<TryCatch>),
120
121    // Expressions
122    Alias(Box<Alias>),
123    Cast(Box<Cast>),
124    Collation(Box<CollationExpr>),
125    Case(Box<Case>),
126
127    // Binary operations
128    And(Box<BinaryOp>),
129    Or(Box<BinaryOp>),
130    Add(Box<BinaryOp>),
131    Sub(Box<BinaryOp>),
132    Mul(Box<BinaryOp>),
133    Div(Box<BinaryOp>),
134    Mod(Box<BinaryOp>),
135    Eq(Box<BinaryOp>),
136    Neq(Box<BinaryOp>),
137    Lt(Box<BinaryOp>),
138    Lte(Box<BinaryOp>),
139    Gt(Box<BinaryOp>),
140    Gte(Box<BinaryOp>),
141    Like(Box<LikeOp>),
142    ILike(Box<LikeOp>),
143    /// SQLite MATCH operator (FTS)
144    Match(Box<BinaryOp>),
145    BitwiseAnd(Box<BinaryOp>),
146    BitwiseOr(Box<BinaryOp>),
147    BitwiseXor(Box<BinaryOp>),
148    Concat(Box<BinaryOp>),
149    Adjacent(Box<BinaryOp>),   // PostgreSQL range adjacency operator (-|-)
150    TsMatch(Box<BinaryOp>),    // PostgreSQL text search match operator (@@)
151    PropertyEQ(Box<BinaryOp>), // := assignment operator (MySQL @var := val, DuckDB named args)
152
153    // PostgreSQL array/JSONB operators
154    ArrayContainsAll(Box<BinaryOp>), // @> operator (array contains all)
155    ArrayContainedBy(Box<BinaryOp>), // <@ operator (array contained by)
156    ArrayOverlaps(Box<BinaryOp>),    // && operator (array overlaps)
157    JSONBContainsAllTopKeys(Box<BinaryOp>), // ?& operator (JSONB contains all keys)
158    JSONBContainsAnyTopKeys(Box<BinaryOp>), // ?| operator (JSONB contains any key)
159    JSONBDeleteAtPath(Box<BinaryOp>), // #- operator (JSONB delete at path)
160    ExtendsLeft(Box<BinaryOp>),      // &< operator (PostgreSQL range extends left)
161    ExtendsRight(Box<BinaryOp>),     // &> operator (PostgreSQL range extends right)
162
163    // Unary operations
164    Not(Box<UnaryOp>),
165    Neg(Box<UnaryOp>),
166    BitwiseNot(Box<UnaryOp>),
167
168    // Predicates
169    In(Box<In>),
170    Between(Box<Between>),
171    IsNull(Box<IsNull>),
172    IsTrue(Box<IsTrueFalse>),
173    IsFalse(Box<IsTrueFalse>),
174    IsJson(Box<IsJson>),
175    Is(Box<BinaryOp>), // General IS expression (e.g., a IS ?)
176    Exists(Box<Exists>),
177    /// MySQL MEMBER OF operator: expr MEMBER OF(json_array)
178    MemberOf(Box<BinaryOp>),
179
180    // Functions
181    Function(Box<Function>),
182
183    Upsert(Box<Upsert>),
184    StorageProperty(Box<StorageProperty>),
185    Hierarchy(Box<Hierarchy>),
186    ViewParameter(Box<ViewParameter>),
187    Call(Box<Call>),
188
189    AggregateFunction(Box<AggregateFunction>),
190    WindowFunction(Box<WindowFunction>),
191
192    // Clauses
193    From(Box<From>),
194    Join(Box<Join>),
195    JoinedTable(Box<JoinedTable>),
196    Where(Box<Where>),
197    GroupBy(Box<GroupBy>),
198    Having(Box<Having>),
199    OrderBy(Box<OrderBy>),
200    Limit(Box<Limit>),
201    Offset(Box<Offset>),
202    Qualify(Box<Qualify>),
203    With(Box<With>),
204    Cte(Box<Cte>),
205    DistributeBy(Box<DistributeBy>),
206    ClusterBy(Box<ClusterBy>),
207    SortBy(Box<SortBy>),
208    LateralView(Box<LateralView>),
209    Hint(Box<Hint>),
210    Pseudocolumn(Pseudocolumn),
211
212    // Oracle hierarchical queries (CONNECT BY)
213    Connect(Box<Connect>),
214    Prior(Box<Prior>),
215    ConnectByRoot(Box<ConnectByRoot>),
216
217    // Pattern matching (MATCH_RECOGNIZE)
218    MatchRecognize(Box<MatchRecognize>),
219
220    // Order expressions
221    Ordered(Box<Ordered>),
222
223    // Window specifications
224    Window(Box<WindowSpec>),
225    Over(Box<Over>),
226    WithinGroup(Box<WithinGroup>),
227
228    // Data types
229    DataType(DataType),
230
231    // Arrays and structs
232    Array(Box<Array>),
233    Struct(Box<Struct>),
234    Tuple(Box<Tuple>),
235
236    // Interval
237    Interval(Box<Interval>),
238
239    // String functions
240    ConcatWs(Box<ConcatWs>),
241    Substring(Box<SubstringFunc>),
242    Upper(Box<UnaryFunc>),
243    Lower(Box<UnaryFunc>),
244    Length(Box<UnaryFunc>),
245    Trim(Box<TrimFunc>),
246    LTrim(Box<UnaryFunc>),
247    RTrim(Box<UnaryFunc>),
248    Replace(Box<ReplaceFunc>),
249    Reverse(Box<UnaryFunc>),
250    Left(Box<LeftRightFunc>),
251    Right(Box<LeftRightFunc>),
252    Repeat(Box<RepeatFunc>),
253    Lpad(Box<PadFunc>),
254    Rpad(Box<PadFunc>),
255    Split(Box<SplitFunc>),
256    RegexpLike(Box<RegexpFunc>),
257    RegexpReplace(Box<RegexpReplaceFunc>),
258    RegexpExtract(Box<RegexpExtractFunc>),
259    Overlay(Box<OverlayFunc>),
260
261    // Math functions
262    Abs(Box<UnaryFunc>),
263    Round(Box<RoundFunc>),
264    Floor(Box<FloorFunc>),
265    Ceil(Box<CeilFunc>),
266    Power(Box<BinaryFunc>),
267    Sqrt(Box<UnaryFunc>),
268    Cbrt(Box<UnaryFunc>),
269    Ln(Box<UnaryFunc>),
270    Log(Box<LogFunc>),
271    Exp(Box<UnaryFunc>),
272    Sign(Box<UnaryFunc>),
273    Greatest(Box<VarArgFunc>),
274    Least(Box<VarArgFunc>),
275
276    // Date/time functions
277    CurrentDate(CurrentDate),
278    CurrentTime(CurrentTime),
279    CurrentTimestamp(CurrentTimestamp),
280    CurrentTimestampLTZ(CurrentTimestampLTZ),
281    AtTimeZone(Box<AtTimeZone>),
282    DateAdd(Box<DateAddFunc>),
283    DateSub(Box<DateAddFunc>),
284    DateDiff(Box<DateDiffFunc>),
285    DateTrunc(Box<DateTruncFunc>),
286    Extract(Box<ExtractFunc>),
287    ToDate(Box<ToDateFunc>),
288    ToTimestamp(Box<ToTimestampFunc>),
289    Date(Box<UnaryFunc>),
290    Time(Box<UnaryFunc>),
291    DateFromUnixDate(Box<UnaryFunc>),
292    UnixDate(Box<UnaryFunc>),
293    UnixSeconds(Box<UnaryFunc>),
294    UnixMillis(Box<UnaryFunc>),
295    UnixMicros(Box<UnaryFunc>),
296    UnixToTimeStr(Box<BinaryFunc>),
297    TimeStrToDate(Box<UnaryFunc>),
298    DateToDi(Box<UnaryFunc>),
299    DiToDate(Box<UnaryFunc>),
300    TsOrDiToDi(Box<UnaryFunc>),
301    TsOrDsToDatetime(Box<UnaryFunc>),
302    TsOrDsToTimestamp(Box<UnaryFunc>),
303    YearOfWeek(Box<UnaryFunc>),
304    YearOfWeekIso(Box<UnaryFunc>),
305
306    // Control flow functions
307    Coalesce(Box<VarArgFunc>),
308    NullIf(Box<BinaryFunc>),
309    IfFunc(Box<IfFunc>),
310    IfNull(Box<BinaryFunc>),
311    Nvl(Box<BinaryFunc>),
312    Nvl2(Box<Nvl2Func>),
313
314    // Type conversion
315    TryCast(Box<Cast>),
316    SafeCast(Box<Cast>),
317
318    // Typed aggregate functions
319    Count(Box<CountFunc>),
320    Sum(Box<AggFunc>),
321    Avg(Box<AggFunc>),
322    Min(Box<AggFunc>),
323    Max(Box<AggFunc>),
324    GroupConcat(Box<GroupConcatFunc>),
325    StringAgg(Box<StringAggFunc>),
326    ListAgg(Box<ListAggFunc>),
327    ArrayAgg(Box<AggFunc>),
328    CountIf(Box<AggFunc>),
329    SumIf(Box<SumIfFunc>),
330    Stddev(Box<AggFunc>),
331    StddevPop(Box<AggFunc>),
332    StddevSamp(Box<AggFunc>),
333    Variance(Box<AggFunc>),
334    VarPop(Box<AggFunc>),
335    VarSamp(Box<AggFunc>),
336    Median(Box<AggFunc>),
337    Mode(Box<AggFunc>),
338    First(Box<AggFunc>),
339    Last(Box<AggFunc>),
340    AnyValue(Box<AggFunc>),
341    ApproxDistinct(Box<AggFunc>),
342    ApproxCountDistinct(Box<AggFunc>),
343    ApproxPercentile(Box<ApproxPercentileFunc>),
344    Percentile(Box<PercentileFunc>),
345    LogicalAnd(Box<AggFunc>),
346    LogicalOr(Box<AggFunc>),
347    Skewness(Box<AggFunc>),
348    BitwiseCount(Box<UnaryFunc>),
349    ArrayConcatAgg(Box<AggFunc>),
350    ArrayUniqueAgg(Box<AggFunc>),
351    BoolXorAgg(Box<AggFunc>),
352
353    // Typed window functions
354    RowNumber(RowNumber),
355    Rank(Rank),
356    DenseRank(DenseRank),
357    NTile(Box<NTileFunc>),
358    Lead(Box<LeadLagFunc>),
359    Lag(Box<LeadLagFunc>),
360    FirstValue(Box<ValueFunc>),
361    LastValue(Box<ValueFunc>),
362    NthValue(Box<NthValueFunc>),
363    PercentRank(PercentRank),
364    CumeDist(CumeDist),
365    PercentileCont(Box<PercentileFunc>),
366    PercentileDisc(Box<PercentileFunc>),
367
368    // Additional string functions
369    Contains(Box<BinaryFunc>),
370    StartsWith(Box<BinaryFunc>),
371    EndsWith(Box<BinaryFunc>),
372    Position(Box<PositionFunc>),
373    Initcap(Box<UnaryFunc>),
374    Ascii(Box<UnaryFunc>),
375    Chr(Box<UnaryFunc>),
376    /// MySQL CHAR function with multiple args and optional USING charset
377    CharFunc(Box<CharFunc>),
378    Soundex(Box<UnaryFunc>),
379    Levenshtein(Box<BinaryFunc>),
380    ByteLength(Box<UnaryFunc>),
381    Hex(Box<UnaryFunc>),
382    LowerHex(Box<UnaryFunc>),
383    Unicode(Box<UnaryFunc>),
384
385    // Additional math functions
386    ModFunc(Box<BinaryFunc>),
387    Random(Random),
388    Rand(Box<Rand>),
389    TruncFunc(Box<TruncateFunc>),
390    Pi(Pi),
391    Radians(Box<UnaryFunc>),
392    Degrees(Box<UnaryFunc>),
393    Sin(Box<UnaryFunc>),
394    Cos(Box<UnaryFunc>),
395    Tan(Box<UnaryFunc>),
396    Asin(Box<UnaryFunc>),
397    Acos(Box<UnaryFunc>),
398    Atan(Box<UnaryFunc>),
399    Atan2(Box<BinaryFunc>),
400    IsNan(Box<UnaryFunc>),
401    IsInf(Box<UnaryFunc>),
402    IntDiv(Box<BinaryFunc>),
403
404    // Control flow
405    Decode(Box<DecodeFunc>),
406
407    // Additional date/time functions
408    DateFormat(Box<DateFormatFunc>),
409    FormatDate(Box<DateFormatFunc>),
410    Year(Box<UnaryFunc>),
411    Month(Box<UnaryFunc>),
412    Day(Box<UnaryFunc>),
413    Hour(Box<UnaryFunc>),
414    Minute(Box<UnaryFunc>),
415    Second(Box<UnaryFunc>),
416    DayOfWeek(Box<UnaryFunc>),
417    DayOfWeekIso(Box<UnaryFunc>),
418    DayOfMonth(Box<UnaryFunc>),
419    DayOfYear(Box<UnaryFunc>),
420    WeekOfYear(Box<UnaryFunc>),
421    Quarter(Box<UnaryFunc>),
422    AddMonths(Box<BinaryFunc>),
423    MonthsBetween(Box<BinaryFunc>),
424    LastDay(Box<LastDayFunc>),
425    NextDay(Box<BinaryFunc>),
426    Epoch(Box<UnaryFunc>),
427    EpochMs(Box<UnaryFunc>),
428    FromUnixtime(Box<FromUnixtimeFunc>),
429    UnixTimestamp(Box<UnixTimestampFunc>),
430    MakeDate(Box<MakeDateFunc>),
431    MakeTimestamp(Box<MakeTimestampFunc>),
432    TimestampTrunc(Box<DateTruncFunc>),
433    TimeStrToUnix(Box<UnaryFunc>),
434
435    // Session/User functions
436    SessionUser(SessionUser),
437
438    // Hash/Crypto functions
439    SHA(Box<UnaryFunc>),
440    SHA1Digest(Box<UnaryFunc>),
441
442    // Time conversion functions
443    TimeToUnix(Box<UnaryFunc>),
444
445    // Array functions
446    ArrayFunc(Box<ArrayConstructor>),
447    ArrayLength(Box<UnaryFunc>),
448    ArraySize(Box<UnaryFunc>),
449    Cardinality(Box<UnaryFunc>),
450    ArrayContains(Box<BinaryFunc>),
451    ArrayPosition(Box<BinaryFunc>),
452    ArrayAppend(Box<BinaryFunc>),
453    ArrayPrepend(Box<BinaryFunc>),
454    ArrayConcat(Box<VarArgFunc>),
455    ArraySort(Box<ArraySortFunc>),
456    ArrayReverse(Box<UnaryFunc>),
457    ArrayDistinct(Box<UnaryFunc>),
458    ArrayJoin(Box<ArrayJoinFunc>),
459    ArrayToString(Box<ArrayJoinFunc>),
460    Unnest(Box<UnnestFunc>),
461    Explode(Box<UnaryFunc>),
462    ExplodeOuter(Box<UnaryFunc>),
463    ArrayFilter(Box<ArrayFilterFunc>),
464    ArrayTransform(Box<ArrayTransformFunc>),
465    ArrayFlatten(Box<UnaryFunc>),
466    ArrayCompact(Box<UnaryFunc>),
467    ArrayIntersect(Box<VarArgFunc>),
468    ArrayUnion(Box<BinaryFunc>),
469    ArrayExcept(Box<BinaryFunc>),
470    ArrayRemove(Box<BinaryFunc>),
471    ArrayZip(Box<VarArgFunc>),
472    Sequence(Box<SequenceFunc>),
473    Generate(Box<SequenceFunc>),
474    ExplodingGenerateSeries(Box<SequenceFunc>),
475    ToArray(Box<UnaryFunc>),
476    StarMap(Box<BinaryFunc>),
477
478    // Struct functions
479    StructFunc(Box<StructConstructor>),
480    StructExtract(Box<StructExtractFunc>),
481    NamedStruct(Box<NamedStructFunc>),
482
483    // Map functions
484    MapFunc(Box<MapConstructor>),
485    MapFromEntries(Box<UnaryFunc>),
486    MapFromArrays(Box<BinaryFunc>),
487    MapKeys(Box<UnaryFunc>),
488    MapValues(Box<UnaryFunc>),
489    MapContainsKey(Box<BinaryFunc>),
490    MapConcat(Box<VarArgFunc>),
491    ElementAt(Box<BinaryFunc>),
492    TransformKeys(Box<TransformFunc>),
493    TransformValues(Box<TransformFunc>),
494
495    // Exasol: function call with EMITS clause
496    FunctionEmits(Box<FunctionEmits>),
497
498    // JSON functions
499    JsonExtract(Box<JsonExtractFunc>),
500    JsonExtractScalar(Box<JsonExtractFunc>),
501    JsonExtractPath(Box<JsonPathFunc>),
502    JsonArray(Box<VarArgFunc>),
503    JsonObject(Box<JsonObjectFunc>),
504    JsonQuery(Box<JsonExtractFunc>),
505    JsonValue(Box<JsonExtractFunc>),
506    JsonArrayLength(Box<UnaryFunc>),
507    JsonKeys(Box<UnaryFunc>),
508    JsonType(Box<UnaryFunc>),
509    ParseJson(Box<UnaryFunc>),
510    ToJson(Box<UnaryFunc>),
511    JsonSet(Box<JsonModifyFunc>),
512    JsonInsert(Box<JsonModifyFunc>),
513    JsonRemove(Box<JsonPathFunc>),
514    JsonMergePatch(Box<BinaryFunc>),
515    JsonArrayAgg(Box<JsonArrayAggFunc>),
516    JsonObjectAgg(Box<JsonObjectAggFunc>),
517
518    // Type casting/conversion
519    Convert(Box<ConvertFunc>),
520    Typeof(Box<UnaryFunc>),
521
522    // Additional expressions
523    Lambda(Box<LambdaExpr>),
524    Parameter(Box<Parameter>),
525    Placeholder(Placeholder),
526    NamedArgument(Box<NamedArgument>),
527    /// TABLE ref or MODEL ref used as a function argument (BigQuery)
528    /// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
529    TableArgument(Box<TableArgument>),
530    SqlComment(Box<SqlComment>),
531
532    // Additional predicates
533    NullSafeEq(Box<BinaryOp>),
534    NullSafeNeq(Box<BinaryOp>),
535    Glob(Box<BinaryOp>),
536    SimilarTo(Box<SimilarToExpr>),
537    Any(Box<QuantifiedExpr>),
538    All(Box<QuantifiedExpr>),
539    Overlaps(Box<OverlapsExpr>),
540
541    // Bitwise operations
542    BitwiseLeftShift(Box<BinaryOp>),
543    BitwiseRightShift(Box<BinaryOp>),
544    BitwiseAndAgg(Box<AggFunc>),
545    BitwiseOrAgg(Box<AggFunc>),
546    BitwiseXorAgg(Box<AggFunc>),
547
548    // Array/struct/map access
549    Subscript(Box<Subscript>),
550    Dot(Box<DotAccess>),
551    MethodCall(Box<MethodCall>),
552    ArraySlice(Box<ArraySlice>),
553
554    // DDL statements
555    CreateTable(Box<CreateTable>),
556    DropTable(Box<DropTable>),
557    Undrop(Box<Undrop>),
558    AlterTable(Box<AlterTable>),
559    SplitTable(Box<SplitTable>),
560    FlashbackTable(Box<FlashbackTable>),
561    CreateIndex(Box<CreateIndex>),
562    DropIndex(Box<DropIndex>),
563    CreateView(Box<CreateView>),
564    DropView(Box<DropView>),
565    AlterView(Box<AlterView>),
566    AlterIndex(Box<AlterIndex>),
567    Truncate(Box<Truncate>),
568    Use(Box<Use>),
569    Cache(Box<Cache>),
570    Uncache(Box<Uncache>),
571    LoadData(Box<LoadData>),
572    Pragma(Box<Pragma>),
573    Grant(Box<Grant>),
574    Revoke(Box<Revoke>),
575    Comment(Box<Comment>),
576    SetStatement(Box<SetStatement>),
577    // Phase 4: Additional DDL statements
578    CreateSchema(Box<CreateSchema>),
579    DropSchema(Box<DropSchema>),
580    DropNamespace(Box<DropNamespace>),
581    CreateDatabase(Box<CreateDatabase>),
582    DropDatabase(Box<DropDatabase>),
583    CreateFunction(Box<CreateFunction>),
584    DropFunction(Box<DropFunction>),
585    CreateProcedure(Box<CreateProcedure>),
586    DropProcedure(Box<DropProcedure>),
587    CreateSequence(Box<CreateSequence>),
588    CreateSynonym(Box<CreateSynonym>),
589    DropSequence(Box<DropSequence>),
590    AlterSequence(Box<AlterSequence>),
591    CreateTrigger(Box<CreateTrigger>),
592    DropTrigger(Box<DropTrigger>),
593    CreateType(Box<CreateType>),
594    DropType(Box<DropType>),
595    Describe(Box<Describe>),
596    Show(Box<Show>),
597
598    // Transaction and other commands
599    Command(Box<Command>),
600    Kill(Box<Kill>),
601    /// PREPARE statement (PostgreSQL/generic prepared statement definition)
602    Prepare(Box<PrepareStatement>),
603    /// EXEC/EXECUTE statement (TSQL stored procedure call)
604    Execute(Box<ExecuteStatement>),
605
606    /// Snowflake CREATE TASK statement
607    CreateTask(Box<CreateTask>),
608
609    // Placeholder for unparsed/raw SQL
610    Raw(Raw),
611
612    // Paren for grouping
613    Paren(Box<Paren>),
614
615    // Expression with trailing comments (for round-trip preservation)
616    Annotated(Box<Annotated>),
617
618    // === BATCH GENERATED EXPRESSION TYPES ===
619    // Generated from Python sqlglot expressions.py
620    Refresh(Box<Refresh>),
621    LockingStatement(Box<LockingStatement>),
622    SequenceProperties(Box<SequenceProperties>),
623    TruncateTable(Box<TruncateTable>),
624    Clone(Box<Clone>),
625    Attach(Box<Attach>),
626    Detach(Box<Detach>),
627    Install(Box<Install>),
628    Summarize(Box<Summarize>),
629    Declare(Box<Declare>),
630    DeclareItem(Box<DeclareItem>),
631    Set(Box<Set>),
632    Heredoc(Box<Heredoc>),
633    SetItem(Box<SetItem>),
634    QueryBand(Box<QueryBand>),
635    UserDefinedFunction(Box<UserDefinedFunction>),
636    RecursiveWithSearch(Box<RecursiveWithSearch>),
637    ProjectionDef(Box<ProjectionDef>),
638    TableAlias(Box<TableAlias>),
639    ByteString(Box<ByteString>),
640    HexStringExpr(Box<HexStringExpr>),
641    UnicodeString(Box<UnicodeString>),
642    ColumnPosition(Box<ColumnPosition>),
643    ColumnDef(Box<ColumnDef>),
644    AlterColumn(Box<AlterColumn>),
645    AlterSortKey(Box<AlterSortKey>),
646    AlterSet(Box<AlterSet>),
647    RenameColumn(Box<RenameColumn>),
648    Comprehension(Box<Comprehension>),
649    MergeTreeTTLAction(Box<MergeTreeTTLAction>),
650    MergeTreeTTL(Box<MergeTreeTTL>),
651    IndexConstraintOption(Box<IndexConstraintOption>),
652    ColumnConstraint(Box<ColumnConstraint>),
653    PeriodForSystemTimeConstraint(Box<PeriodForSystemTimeConstraint>),
654    CaseSpecificColumnConstraint(Box<CaseSpecificColumnConstraint>),
655    CharacterSetColumnConstraint(Box<CharacterSetColumnConstraint>),
656    CheckColumnConstraint(Box<CheckColumnConstraint>),
657    AssumeColumnConstraint(Box<AssumeColumnConstraint>),
658    CompressColumnConstraint(Box<CompressColumnConstraint>),
659    DateFormatColumnConstraint(Box<DateFormatColumnConstraint>),
660    EphemeralColumnConstraint(Box<EphemeralColumnConstraint>),
661    WithOperator(Box<WithOperator>),
662    GeneratedAsIdentityColumnConstraint(Box<GeneratedAsIdentityColumnConstraint>),
663    AutoIncrementColumnConstraint(AutoIncrementColumnConstraint),
664    CommentColumnConstraint(CommentColumnConstraint),
665    GeneratedAsRowColumnConstraint(Box<GeneratedAsRowColumnConstraint>),
666    IndexColumnConstraint(Box<IndexColumnConstraint>),
667    MaskingPolicyColumnConstraint(Box<MaskingPolicyColumnConstraint>),
668    NotNullColumnConstraint(Box<NotNullColumnConstraint>),
669    PrimaryKeyColumnConstraint(Box<PrimaryKeyColumnConstraint>),
670    UniqueColumnConstraint(Box<UniqueColumnConstraint>),
671    WatermarkColumnConstraint(Box<WatermarkColumnConstraint>),
672    ComputedColumnConstraint(Box<ComputedColumnConstraint>),
673    InOutColumnConstraint(Box<InOutColumnConstraint>),
674    DefaultColumnConstraint(Box<DefaultColumnConstraint>),
675    PathColumnConstraint(Box<PathColumnConstraint>),
676    Constraint(Box<Constraint>),
677    Export(Box<Export>),
678    Filter(Box<Filter>),
679    Changes(Box<Changes>),
680    CopyParameter(Box<CopyParameter>),
681    Credentials(Box<Credentials>),
682    Directory(Box<Directory>),
683    ForeignKey(Box<ForeignKey>),
684    ColumnPrefix(Box<ColumnPrefix>),
685    PrimaryKey(Box<PrimaryKey>),
686    IntoClause(Box<IntoClause>),
687    JoinHint(Box<JoinHint>),
688    Opclass(Box<Opclass>),
689    Index(Box<Index>),
690    IndexParameters(Box<IndexParameters>),
691    ConditionalInsert(Box<ConditionalInsert>),
692    MultitableInserts(Box<MultitableInserts>),
693    OnConflict(Box<OnConflict>),
694    OnCondition(Box<OnCondition>),
695    Returning(Box<Returning>),
696    Introducer(Box<Introducer>),
697    PartitionRange(Box<PartitionRange>),
698    Fetch(Box<Fetch>),
699    Group(Box<Group>),
700    Cube(Box<Cube>),
701    Rollup(Box<Rollup>),
702    GroupingSets(Box<GroupingSets>),
703    LimitOptions(Box<LimitOptions>),
704    Lateral(Box<Lateral>),
705    TableFromRows(Box<TableFromRows>),
706    RowsFrom(Box<RowsFrom>),
707    MatchRecognizeMeasure(Box<MatchRecognizeMeasure>),
708    WithFill(Box<WithFill>),
709    Property(Box<Property>),
710    GrantPrivilege(Box<GrantPrivilege>),
711    GrantPrincipal(Box<GrantPrincipal>),
712    AllowedValuesProperty(Box<AllowedValuesProperty>),
713    AlgorithmProperty(Box<AlgorithmProperty>),
714    AutoIncrementProperty(Box<AutoIncrementProperty>),
715    AutoRefreshProperty(Box<AutoRefreshProperty>),
716    BackupProperty(Box<BackupProperty>),
717    BuildProperty(Box<BuildProperty>),
718    BlockCompressionProperty(Box<BlockCompressionProperty>),
719    CharacterSetProperty(Box<CharacterSetProperty>),
720    ChecksumProperty(Box<ChecksumProperty>),
721    CollateProperty(Box<CollateProperty>),
722    DataBlocksizeProperty(Box<DataBlocksizeProperty>),
723    DataDeletionProperty(Box<DataDeletionProperty>),
724    DefinerProperty(Box<DefinerProperty>),
725    DistKeyProperty(Box<DistKeyProperty>),
726    DistributedByProperty(Box<DistributedByProperty>),
727    DistStyleProperty(Box<DistStyleProperty>),
728    DuplicateKeyProperty(Box<DuplicateKeyProperty>),
729    EngineProperty(Box<EngineProperty>),
730    ToTableProperty(Box<ToTableProperty>),
731    ExecuteAsProperty(Box<ExecuteAsProperty>),
732    ExternalProperty(Box<ExternalProperty>),
733    FallbackProperty(Box<FallbackProperty>),
734    FileFormatProperty(Box<FileFormatProperty>),
735    CredentialsProperty(Box<CredentialsProperty>),
736    FreespaceProperty(Box<FreespaceProperty>),
737    InheritsProperty(Box<InheritsProperty>),
738    InputModelProperty(Box<InputModelProperty>),
739    OutputModelProperty(Box<OutputModelProperty>),
740    IsolatedLoadingProperty(Box<IsolatedLoadingProperty>),
741    JournalProperty(Box<JournalProperty>),
742    LanguageProperty(Box<LanguageProperty>),
743    EnviromentProperty(Box<EnviromentProperty>),
744    ClusteredByProperty(Box<ClusteredByProperty>),
745    DictProperty(Box<DictProperty>),
746    DictRange(Box<DictRange>),
747    OnCluster(Box<OnCluster>),
748    LikeProperty(Box<LikeProperty>),
749    LocationProperty(Box<LocationProperty>),
750    LockProperty(Box<LockProperty>),
751    LockingProperty(Box<LockingProperty>),
752    LogProperty(Box<LogProperty>),
753    MaterializedProperty(Box<MaterializedProperty>),
754    MergeBlockRatioProperty(Box<MergeBlockRatioProperty>),
755    OnProperty(Box<OnProperty>),
756    OnCommitProperty(Box<OnCommitProperty>),
757    PartitionedByProperty(Box<PartitionedByProperty>),
758    PartitionByProperty(Box<PartitionByProperty>),
759    PartitionedByBucket(Box<PartitionedByBucket>),
760    ClusterByColumnsProperty(Box<ClusterByColumnsProperty>),
761    PartitionByTruncate(Box<PartitionByTruncate>),
762    PartitionByRangeProperty(Box<PartitionByRangeProperty>),
763    PartitionByRangePropertyDynamic(Box<PartitionByRangePropertyDynamic>),
764    PartitionByListProperty(Box<PartitionByListProperty>),
765    PartitionList(Box<PartitionList>),
766    Partition(Box<Partition>),
767    RefreshTriggerProperty(Box<RefreshTriggerProperty>),
768    UniqueKeyProperty(Box<UniqueKeyProperty>),
769    RollupProperty(Box<RollupProperty>),
770    PartitionBoundSpec(Box<PartitionBoundSpec>),
771    PartitionedOfProperty(Box<PartitionedOfProperty>),
772    RemoteWithConnectionModelProperty(Box<RemoteWithConnectionModelProperty>),
773    ReturnsProperty(Box<ReturnsProperty>),
774    RowFormatProperty(Box<RowFormatProperty>),
775    RowFormatDelimitedProperty(Box<RowFormatDelimitedProperty>),
776    RowFormatSerdeProperty(Box<RowFormatSerdeProperty>),
777    QueryTransform(Box<QueryTransform>),
778    SampleProperty(Box<SampleProperty>),
779    SecurityProperty(Box<SecurityProperty>),
780    SchemaCommentProperty(Box<SchemaCommentProperty>),
781    SemanticView(Box<SemanticView>),
782    SerdeProperties(Box<SerdeProperties>),
783    SetProperty(Box<SetProperty>),
784    SharingProperty(Box<SharingProperty>),
785    SetConfigProperty(Box<SetConfigProperty>),
786    SettingsProperty(Box<SettingsProperty>),
787    SortKeyProperty(Box<SortKeyProperty>),
788    SqlReadWriteProperty(Box<SqlReadWriteProperty>),
789    SqlSecurityProperty(Box<SqlSecurityProperty>),
790    StabilityProperty(Box<StabilityProperty>),
791    StorageHandlerProperty(Box<StorageHandlerProperty>),
792    TemporaryProperty(Box<TemporaryProperty>),
793    Tags(Box<Tags>),
794    TransformModelProperty(Box<TransformModelProperty>),
795    TransientProperty(Box<TransientProperty>),
796    UsingTemplateProperty(Box<UsingTemplateProperty>),
797    ViewAttributeProperty(Box<ViewAttributeProperty>),
798    VolatileProperty(Box<VolatileProperty>),
799    WithDataProperty(Box<WithDataProperty>),
800    WithJournalTableProperty(Box<WithJournalTableProperty>),
801    WithSchemaBindingProperty(Box<WithSchemaBindingProperty>),
802    WithSystemVersioningProperty(Box<WithSystemVersioningProperty>),
803    WithProcedureOptions(Box<WithProcedureOptions>),
804    EncodeProperty(Box<EncodeProperty>),
805    IncludeProperty(Box<IncludeProperty>),
806    Properties(Box<Properties>),
807    OptionsProperty(Box<OptionsProperty>),
808    InputOutputFormat(Box<InputOutputFormat>),
809    Reference(Box<Reference>),
810    QueryOption(Box<QueryOption>),
811    WithTableHint(Box<WithTableHint>),
812    IndexTableHint(Box<IndexTableHint>),
813    HistoricalData(Box<HistoricalData>),
814    Get(Box<Get>),
815    SetOperation(Box<SetOperation>),
816    Var(Box<Var>),
817    Variadic(Box<Variadic>),
818    Version(Box<Version>),
819    Schema(Box<Schema>),
820    Lock(Box<Lock>),
821    TableSample(Box<TableSample>),
822    Tag(Box<Tag>),
823    UnpivotColumns(Box<UnpivotColumns>),
824    WindowSpec(Box<WindowSpec>),
825    SessionParameter(Box<SessionParameter>),
826    PseudoType(Box<PseudoType>),
827    ObjectIdentifier(Box<ObjectIdentifier>),
828    Transaction(Box<Transaction>),
829    Commit(Box<Commit>),
830    Rollback(Box<Rollback>),
831    AlterSession(Box<AlterSession>),
832    Analyze(Box<Analyze>),
833    AnalyzeStatistics(Box<AnalyzeStatistics>),
834    AnalyzeHistogram(Box<AnalyzeHistogram>),
835    AnalyzeSample(Box<AnalyzeSample>),
836    AnalyzeListChainedRows(Box<AnalyzeListChainedRows>),
837    AnalyzeDelete(Box<AnalyzeDelete>),
838    AnalyzeWith(Box<AnalyzeWith>),
839    AnalyzeValidate(Box<AnalyzeValidate>),
840    AddPartition(Box<AddPartition>),
841    AttachOption(Box<AttachOption>),
842    DropPartition(Box<DropPartition>),
843    ReplacePartition(Box<ReplacePartition>),
844    DPipe(Box<DPipe>),
845    Operator(Box<Operator>),
846    PivotAny(Box<PivotAny>),
847    Aliases(Box<Aliases>),
848    AtIndex(Box<AtIndex>),
849    FromTimeZone(Box<FromTimeZone>),
850    FormatPhrase(Box<FormatPhrase>),
851    ForIn(Box<ForIn>),
852    TimeUnit(Box<TimeUnit>),
853    IntervalOp(Box<IntervalOp>),
854    IntervalSpan(Box<IntervalSpan>),
855    HavingMax(Box<HavingMax>),
856    CosineDistance(Box<CosineDistance>),
857    DotProduct(Box<DotProduct>),
858    EuclideanDistance(Box<EuclideanDistance>),
859    ManhattanDistance(Box<ManhattanDistance>),
860    JarowinklerSimilarity(Box<JarowinklerSimilarity>),
861    Booland(Box<Booland>),
862    Boolor(Box<Boolor>),
863    ParameterizedAgg(Box<ParameterizedAgg>),
864    ArgMax(Box<ArgMax>),
865    ArgMin(Box<ArgMin>),
866    ApproxTopK(Box<ApproxTopK>),
867    ApproxTopKAccumulate(Box<ApproxTopKAccumulate>),
868    ApproxTopKCombine(Box<ApproxTopKCombine>),
869    ApproxTopKEstimate(Box<ApproxTopKEstimate>),
870    ApproxTopSum(Box<ApproxTopSum>),
871    ApproxQuantiles(Box<ApproxQuantiles>),
872    Minhash(Box<Minhash>),
873    FarmFingerprint(Box<FarmFingerprint>),
874    Float64(Box<Float64>),
875    Transform(Box<Transform>),
876    Translate(Box<Translate>),
877    Grouping(Box<Grouping>),
878    GroupingId(Box<GroupingId>),
879    Anonymous(Box<Anonymous>),
880    AnonymousAggFunc(Box<AnonymousAggFunc>),
881    CombinedAggFunc(Box<CombinedAggFunc>),
882    CombinedParameterizedAgg(Box<CombinedParameterizedAgg>),
883    HashAgg(Box<HashAgg>),
884    Hll(Box<Hll>),
885    Apply(Box<Apply>),
886    ToBoolean(Box<ToBoolean>),
887    List(Box<List>),
888    ToMap(Box<ToMap>),
889    Pad(Box<Pad>),
890    ToChar(Box<ToChar>),
891    ToNumber(Box<ToNumber>),
892    ToDouble(Box<ToDouble>),
893    Int64(Box<UnaryFunc>),
894    StringFunc(Box<StringFunc>),
895    ToDecfloat(Box<ToDecfloat>),
896    TryToDecfloat(Box<TryToDecfloat>),
897    ToFile(Box<ToFile>),
898    Columns(Box<Columns>),
899    ConvertToCharset(Box<ConvertToCharset>),
900    ConvertTimezone(Box<ConvertTimezone>),
901    GenerateSeries(Box<GenerateSeries>),
902    AIAgg(Box<AIAgg>),
903    AIClassify(Box<AIClassify>),
904    ArrayAll(Box<ArrayAll>),
905    ArrayAny(Box<ArrayAny>),
906    ArrayConstructCompact(Box<ArrayConstructCompact>),
907    StPoint(Box<StPoint>),
908    StDistance(Box<StDistance>),
909    StringToArray(Box<StringToArray>),
910    ArraySum(Box<ArraySum>),
911    ObjectAgg(Box<ObjectAgg>),
912    CastToStrType(Box<CastToStrType>),
913    CheckJson(Box<CheckJson>),
914    CheckXml(Box<CheckXml>),
915    TranslateCharacters(Box<TranslateCharacters>),
916    CurrentSchemas(Box<CurrentSchemas>),
917    CurrentDatetime(Box<CurrentDatetime>),
918    Localtime(Box<Localtime>),
919    Localtimestamp(Box<Localtimestamp>),
920    Systimestamp(Box<Systimestamp>),
921    CurrentSchema(Box<CurrentSchema>),
922    CurrentUser(Box<CurrentUser>),
923    UtcTime(Box<UtcTime>),
924    UtcTimestamp(Box<UtcTimestamp>),
925    Timestamp(Box<TimestampFunc>),
926    DateBin(Box<DateBin>),
927    Datetime(Box<Datetime>),
928    DatetimeAdd(Box<DatetimeAdd>),
929    DatetimeSub(Box<DatetimeSub>),
930    DatetimeDiff(Box<DatetimeDiff>),
931    DatetimeTrunc(Box<DatetimeTrunc>),
932    Dayname(Box<Dayname>),
933    MakeInterval(Box<MakeInterval>),
934    PreviousDay(Box<PreviousDay>),
935    Elt(Box<Elt>),
936    TimestampAdd(Box<TimestampAdd>),
937    TimestampSub(Box<TimestampSub>),
938    TimestampDiff(Box<TimestampDiff>),
939    TimeSlice(Box<TimeSlice>),
940    TimeAdd(Box<TimeAdd>),
941    TimeSub(Box<TimeSub>),
942    TimeDiff(Box<TimeDiff>),
943    TimeTrunc(Box<TimeTrunc>),
944    DateFromParts(Box<DateFromParts>),
945    TimeFromParts(Box<TimeFromParts>),
946    DecodeCase(Box<DecodeCase>),
947    Decrypt(Box<Decrypt>),
948    DecryptRaw(Box<DecryptRaw>),
949    Encode(Box<Encode>),
950    Encrypt(Box<Encrypt>),
951    EncryptRaw(Box<EncryptRaw>),
952    EqualNull(Box<EqualNull>),
953    ToBinary(Box<ToBinary>),
954    Base64DecodeBinary(Box<Base64DecodeBinary>),
955    Base64DecodeString(Box<Base64DecodeString>),
956    Base64Encode(Box<Base64Encode>),
957    TryBase64DecodeBinary(Box<TryBase64DecodeBinary>),
958    TryBase64DecodeString(Box<TryBase64DecodeString>),
959    GapFill(Box<GapFill>),
960    GenerateDateArray(Box<GenerateDateArray>),
961    GenerateTimestampArray(Box<GenerateTimestampArray>),
962    GetExtract(Box<GetExtract>),
963    Getbit(Box<Getbit>),
964    OverflowTruncateBehavior(Box<OverflowTruncateBehavior>),
965    HexEncode(Box<HexEncode>),
966    Compress(Box<Compress>),
967    DecompressBinary(Box<DecompressBinary>),
968    DecompressString(Box<DecompressString>),
969    Xor(Box<Xor>),
970    Nullif(Box<Nullif>),
971    JSON(Box<JSON>),
972    JSONPath(Box<JSONPath>),
973    JSONPathFilter(Box<JSONPathFilter>),
974    JSONPathKey(Box<JSONPathKey>),
975    JSONPathRecursive(Box<JSONPathRecursive>),
976    JSONPathScript(Box<JSONPathScript>),
977    JSONPathSlice(Box<JSONPathSlice>),
978    JSONPathSelector(Box<JSONPathSelector>),
979    JSONPathSubscript(Box<JSONPathSubscript>),
980    JSONPathUnion(Box<JSONPathUnion>),
981    Format(Box<Format>),
982    JSONKeys(Box<JSONKeys>),
983    JSONKeyValue(Box<JSONKeyValue>),
984    JSONKeysAtDepth(Box<JSONKeysAtDepth>),
985    JSONObject(Box<JSONObject>),
986    JSONObjectAgg(Box<JSONObjectAgg>),
987    JSONBObjectAgg(Box<JSONBObjectAgg>),
988    JSONArray(Box<JSONArray>),
989    JSONArrayAgg(Box<JSONArrayAgg>),
990    JSONExists(Box<JSONExists>),
991    JSONColumnDef(Box<JSONColumnDef>),
992    JSONSchema(Box<JSONSchema>),
993    JSONSet(Box<JSONSet>),
994    JSONStripNulls(Box<JSONStripNulls>),
995    JSONValue(Box<JSONValue>),
996    JSONValueArray(Box<JSONValueArray>),
997    JSONRemove(Box<JSONRemove>),
998    JSONTable(Box<JSONTable>),
999    JSONType(Box<JSONType>),
1000    ObjectInsert(Box<ObjectInsert>),
1001    OpenJSONColumnDef(Box<OpenJSONColumnDef>),
1002    OpenJSON(Box<OpenJSON>),
1003    JSONBExists(Box<JSONBExists>),
1004    JSONBContains(Box<BinaryFunc>),
1005    JSONBExtract(Box<BinaryFunc>),
1006    JSONCast(Box<JSONCast>),
1007    JSONExtract(Box<JSONExtract>),
1008    JSONExtractQuote(Box<JSONExtractQuote>),
1009    JSONExtractArray(Box<JSONExtractArray>),
1010    JSONExtractScalar(Box<JSONExtractScalar>),
1011    JSONBExtractScalar(Box<JSONBExtractScalar>),
1012    JSONFormat(Box<JSONFormat>),
1013    JSONBool(Box<UnaryFunc>),
1014    JSONPathRoot(JSONPathRoot),
1015    JSONArrayAppend(Box<JSONArrayAppend>),
1016    JSONArrayContains(Box<JSONArrayContains>),
1017    JSONArrayInsert(Box<JSONArrayInsert>),
1018    ParseJSON(Box<ParseJSON>),
1019    ParseUrl(Box<ParseUrl>),
1020    ParseIp(Box<ParseIp>),
1021    ParseTime(Box<ParseTime>),
1022    ParseDatetime(Box<ParseDatetime>),
1023    Map(Box<Map>),
1024    MapCat(Box<MapCat>),
1025    MapDelete(Box<MapDelete>),
1026    MapInsert(Box<MapInsert>),
1027    MapPick(Box<MapPick>),
1028    ScopeResolution(Box<ScopeResolution>),
1029    Slice(Box<Slice>),
1030    VarMap(Box<VarMap>),
1031    MatchAgainst(Box<MatchAgainst>),
1032    MD5Digest(Box<MD5Digest>),
1033    MD5NumberLower64(Box<UnaryFunc>),
1034    MD5NumberUpper64(Box<UnaryFunc>),
1035    Monthname(Box<Monthname>),
1036    Ntile(Box<Ntile>),
1037    Normalize(Box<Normalize>),
1038    Normal(Box<Normal>),
1039    Predict(Box<Predict>),
1040    MLTranslate(Box<MLTranslate>),
1041    FeaturesAtTime(Box<FeaturesAtTime>),
1042    GenerateEmbedding(Box<GenerateEmbedding>),
1043    MLForecast(Box<MLForecast>),
1044    ModelAttribute(Box<ModelAttribute>),
1045    VectorSearch(Box<VectorSearch>),
1046    Quantile(Box<Quantile>),
1047    ApproxQuantile(Box<ApproxQuantile>),
1048    ApproxPercentileEstimate(Box<ApproxPercentileEstimate>),
1049    Randn(Box<Randn>),
1050    Randstr(Box<Randstr>),
1051    RangeN(Box<RangeN>),
1052    RangeBucket(Box<RangeBucket>),
1053    ReadCSV(Box<ReadCSV>),
1054    ReadParquet(Box<ReadParquet>),
1055    Reduce(Box<Reduce>),
1056    RegexpExtractAll(Box<RegexpExtractAll>),
1057    RegexpILike(Box<RegexpILike>),
1058    RegexpFullMatch(Box<RegexpFullMatch>),
1059    RegexpInstr(Box<RegexpInstr>),
1060    RegexpSplit(Box<RegexpSplit>),
1061    RegexpCount(Box<RegexpCount>),
1062    RegrValx(Box<RegrValx>),
1063    RegrValy(Box<RegrValy>),
1064    RegrAvgy(Box<RegrAvgy>),
1065    RegrAvgx(Box<RegrAvgx>),
1066    RegrCount(Box<RegrCount>),
1067    RegrIntercept(Box<RegrIntercept>),
1068    RegrR2(Box<RegrR2>),
1069    RegrSxx(Box<RegrSxx>),
1070    RegrSxy(Box<RegrSxy>),
1071    RegrSyy(Box<RegrSyy>),
1072    RegrSlope(Box<RegrSlope>),
1073    SafeAdd(Box<SafeAdd>),
1074    SafeDivide(Box<SafeDivide>),
1075    SafeMultiply(Box<SafeMultiply>),
1076    SafeSubtract(Box<SafeSubtract>),
1077    SHA2(Box<SHA2>),
1078    SHA2Digest(Box<SHA2Digest>),
1079    SortArray(Box<SortArray>),
1080    SplitPart(Box<SplitPart>),
1081    SubstringIndex(Box<SubstringIndex>),
1082    StandardHash(Box<StandardHash>),
1083    StrPosition(Box<StrPosition>),
1084    Search(Box<Search>),
1085    SearchIp(Box<SearchIp>),
1086    StrToDate(Box<StrToDate>),
1087    DateStrToDate(Box<UnaryFunc>),
1088    DateToDateStr(Box<UnaryFunc>),
1089    StrToTime(Box<StrToTime>),
1090    StrToUnix(Box<StrToUnix>),
1091    StrToMap(Box<StrToMap>),
1092    NumberToStr(Box<NumberToStr>),
1093    FromBase(Box<FromBase>),
1094    Stuff(Box<Stuff>),
1095    TimeToStr(Box<TimeToStr>),
1096    TimeStrToTime(Box<TimeStrToTime>),
1097    TsOrDsAdd(Box<TsOrDsAdd>),
1098    TsOrDsDiff(Box<TsOrDsDiff>),
1099    TsOrDsToDate(Box<TsOrDsToDate>),
1100    TsOrDsToTime(Box<TsOrDsToTime>),
1101    Unhex(Box<Unhex>),
1102    Uniform(Box<Uniform>),
1103    UnixToStr(Box<UnixToStr>),
1104    UnixToTime(Box<UnixToTime>),
1105    Uuid(Box<Uuid>),
1106    TimestampFromParts(Box<TimestampFromParts>),
1107    TimestampTzFromParts(Box<TimestampTzFromParts>),
1108    Corr(Box<Corr>),
1109    WidthBucket(Box<WidthBucket>),
1110    CovarSamp(Box<CovarSamp>),
1111    CovarPop(Box<CovarPop>),
1112    Week(Box<Week>),
1113    XMLElement(Box<XMLElement>),
1114    XMLGet(Box<XMLGet>),
1115    XMLTable(Box<XMLTable>),
1116    XMLKeyValueOption(Box<XMLKeyValueOption>),
1117    Zipf(Box<Zipf>),
1118    Merge(Box<Merge>),
1119    When(Box<When>),
1120    Whens(Box<Whens>),
1121    NextValueFor(Box<NextValueFor>),
1122    /// RETURN statement (DuckDB stored procedures)
1123    ReturnStmt(Box<Expression>),
1124}
1125
1126impl Expression {
1127    /// Source semantics that still require dialect-aware lowering. This metadata
1128    /// survives JSON serialization and never changes generic traversal behavior.
1129    pub fn source_dialect(&self) -> Option<crate::dialects::DialectType> {
1130        use crate::dialects::DialectType;
1131        match self {
1132            Self::Function(f) => f.source_dialect,
1133            Self::AggregateFunction(f) => f.source_dialect,
1134            Self::ListAgg(f) => f.source_dialect,
1135            Self::Select(s) => s.source_dialect,
1136            Self::CreateTable(t) => t.source_dialect,
1137            Self::Upsert(u) => u.source_dialect,
1138            Self::Call(c) => c.source_dialect,
1139            Self::Hierarchy(h) => h.source_dialect,
1140            Self::ViewParameter(p) => p.source_dialect,
1141            Self::StorageProperty(p) => p.source_dialect,
1142            Self::Hint(h) => h.source_dialect,
1143            Self::JSONValue(j) => j.source_dialect,
1144            Self::JSONTable(j) => j.source_dialect,
1145            Self::JSONColumnDef(j) => j.source_dialect,
1146            Self::JsonQuery(j) | Self::JsonExtract(j) | Self::JsonExtractScalar(j) => {
1147                j.source_dialect
1148            }
1149            Self::RegexpLike(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1150            Self::RegexpReplace(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1151            Self::RegexpExtract(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1152            Self::RegexpInstr(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1153            Self::RegexpCount(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1154            Self::Cube(g) => g.options.as_ref().and_then(|o| o.source_dialect),
1155            Self::Rollup(g) => g.options.as_ref().and_then(|o| o.source_dialect),
1156            Self::GroupingSets(g) => g.options.as_ref().and_then(|o| o.source_dialect),
1157            Self::PartitionByProperty(p) => p.specification.as_ref().and_then(|s| s.source_dialect),
1158            Self::DataType(DataType::Hana { .. }) => Some(DialectType::HANA),
1159            Self::Cast(c) if matches!(c.to, DataType::Hana { .. }) => Some(DialectType::HANA),
1160            _ => None,
1161        }
1162    }
1163
1164    /// Create a `Column` variant, boxing the value automatically.
1165    #[inline]
1166    pub fn boxed_column(col: Column) -> Self {
1167        Expression::Column(Box::new(col))
1168    }
1169
1170    /// Create a `Table` variant, boxing the value automatically.
1171    #[inline]
1172    pub fn boxed_table(t: TableRef) -> Self {
1173        Expression::Table(Box::new(t))
1174    }
1175
1176    /// Returns `true` if this expression is a valid top-level SQL statement.
1177    ///
1178    /// Bare expressions like identifiers, literals, and function calls are not
1179    /// valid statements. This is used by `validate()` to reject inputs like
1180    /// `SELECT scooby dooby doo` which the parser splits into `SELECT scooby AS dooby`
1181    /// plus the bare identifier `doo`.
1182    pub fn is_statement(&self) -> bool {
1183        match self {
1184            // Queries
1185            Expression::Select(_)
1186            | Expression::Union(_)
1187            | Expression::Intersect(_)
1188            | Expression::Except(_)
1189            | Expression::Subquery(_)
1190            | Expression::Values(_)
1191            | Expression::PipeOperator(_)
1192
1193            // DML
1194            | Expression::Upsert(_)
1195            | Expression::Call(_)
1196            | Expression::Insert(_)
1197            | Expression::Update(_)
1198            | Expression::Delete(_)
1199            | Expression::Copy(_)
1200            | Expression::Put(_)
1201            | Expression::Merge(_)
1202            | Expression::TryCatch(_)
1203
1204            // DDL
1205            | Expression::CreateTable(_)
1206            | Expression::DropTable(_)
1207            | Expression::Undrop(_)
1208            | Expression::AlterTable(_)
1209            | Expression::SplitTable(_)
1210            | Expression::FlashbackTable(_)
1211            | Expression::CreateIndex(_)
1212            | Expression::DropIndex(_)
1213            | Expression::CreateView(_)
1214            | Expression::DropView(_)
1215            | Expression::AlterView(_)
1216            | Expression::AlterIndex(_)
1217            | Expression::Truncate(_)
1218            | Expression::TruncateTable(_)
1219            | Expression::CreateSchema(_)
1220            | Expression::DropSchema(_)
1221            | Expression::DropNamespace(_)
1222            | Expression::CreateDatabase(_)
1223            | Expression::DropDatabase(_)
1224            | Expression::CreateFunction(_)
1225            | Expression::DropFunction(_)
1226            | Expression::CreateProcedure(_)
1227            | Expression::DropProcedure(_)
1228            | Expression::CreateSequence(_)
1229            | Expression::CreateSynonym(_)
1230            | Expression::DropSequence(_)
1231            | Expression::AlterSequence(_)
1232            | Expression::CreateTrigger(_)
1233            | Expression::DropTrigger(_)
1234            | Expression::CreateType(_)
1235            | Expression::DropType(_)
1236            | Expression::Comment(_)
1237
1238            // Session/Transaction/Control
1239            | Expression::Use(_)
1240            | Expression::Set(_)
1241            | Expression::SetStatement(_)
1242            | Expression::Transaction(_)
1243            | Expression::Commit(_)
1244            | Expression::Rollback(_)
1245            | Expression::Grant(_)
1246            | Expression::Revoke(_)
1247            | Expression::Cache(_)
1248            | Expression::Uncache(_)
1249            | Expression::LoadData(_)
1250            | Expression::Pragma(_)
1251            | Expression::Describe(_)
1252            | Expression::Show(_)
1253            | Expression::Kill(_)
1254            | Expression::Prepare(_)
1255            | Expression::Execute(_)
1256            | Expression::Declare(_)
1257            | Expression::Refresh(_)
1258            | Expression::AlterSession(_)
1259            | Expression::LockingStatement(_)
1260
1261            // Analyze
1262            | Expression::Analyze(_)
1263            | Expression::AnalyzeStatistics(_)
1264            | Expression::AnalyzeHistogram(_)
1265            | Expression::AnalyzeSample(_)
1266            | Expression::AnalyzeListChainedRows(_)
1267            | Expression::AnalyzeDelete(_)
1268
1269            // Attach/Detach/Install/Summarize
1270            | Expression::Attach(_)
1271            | Expression::Detach(_)
1272            | Expression::Install(_)
1273            | Expression::Summarize(_)
1274
1275            // Pivot at statement level
1276            | Expression::Pivot(_)
1277            | Expression::Unpivot(_)
1278
1279            // Command (raw/unparsed statements)
1280            | Expression::Command(_)
1281            | Expression::Raw(_)
1282            | Expression::CreateTask(_)
1283
1284            // Return statement
1285            | Expression::ReturnStmt(_) => true,
1286
1287            // Annotated wraps another expression with comments — check inner
1288            Expression::Annotated(a) => a.this.is_statement(),
1289
1290            // Alias at top level can wrap a statement (e.g., parenthesized subquery with alias)
1291            Expression::Alias(a) => a.this.is_statement(),
1292
1293            // Everything else (identifiers, literals, operators, functions, etc.)
1294            _ => false,
1295        }
1296    }
1297
1298    /// Create a literal number expression from an integer.
1299    pub fn number(n: i64) -> Self {
1300        Expression::Literal(Box::new(Literal::Number(n.to_string())))
1301    }
1302
1303    /// Create a single-quoted literal string expression.
1304    pub fn string(s: impl Into<String>) -> Self {
1305        Expression::Literal(Box::new(Literal::String(s.into())))
1306    }
1307
1308    /// Create a literal number expression from a float.
1309    pub fn float(f: f64) -> Self {
1310        Expression::Literal(Box::new(Literal::Number(f.to_string())))
1311    }
1312
1313    /// Get the inferred type annotation, if present.
1314    ///
1315    /// For value-producing expressions with an `inferred_type` field, returns
1316    /// the stored type. For literals and boolean constants, computes the type
1317    /// on the fly from the variant. For DDL/clause expressions, returns `None`.
1318    pub fn inferred_type(&self) -> Option<&DataType> {
1319        match self {
1320            // Structs with inferred_type field
1321            Expression::And(op)
1322            | Expression::Or(op)
1323            | Expression::Add(op)
1324            | Expression::Sub(op)
1325            | Expression::Mul(op)
1326            | Expression::Div(op)
1327            | Expression::Mod(op)
1328            | Expression::Eq(op)
1329            | Expression::Neq(op)
1330            | Expression::Lt(op)
1331            | Expression::Lte(op)
1332            | Expression::Gt(op)
1333            | Expression::Gte(op)
1334            | Expression::Concat(op)
1335            | Expression::BitwiseAnd(op)
1336            | Expression::BitwiseOr(op)
1337            | Expression::BitwiseXor(op)
1338            | Expression::Adjacent(op)
1339            | Expression::TsMatch(op)
1340            | Expression::PropertyEQ(op)
1341            | Expression::ArrayContainsAll(op)
1342            | Expression::ArrayContainedBy(op)
1343            | Expression::ArrayOverlaps(op)
1344            | Expression::JSONBContainsAllTopKeys(op)
1345            | Expression::JSONBContainsAnyTopKeys(op)
1346            | Expression::JSONBDeleteAtPath(op)
1347            | Expression::ExtendsLeft(op)
1348            | Expression::ExtendsRight(op)
1349            | Expression::Is(op)
1350            | Expression::MemberOf(op)
1351            | Expression::Match(op)
1352            | Expression::NullSafeEq(op)
1353            | Expression::NullSafeNeq(op)
1354            | Expression::Glob(op)
1355            | Expression::BitwiseLeftShift(op)
1356            | Expression::BitwiseRightShift(op) => op.inferred_type.as_ref(),
1357
1358            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1359                op.inferred_type.as_ref()
1360            }
1361
1362            Expression::Like(op) | Expression::ILike(op) => op.inferred_type.as_ref(),
1363
1364            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1365                c.inferred_type.as_ref()
1366            }
1367
1368            Expression::Column(c) => c.inferred_type.as_ref(),
1369            Expression::Dot(dot) => dot.inferred_type.as_ref(),
1370            Expression::Function(f) => f.inferred_type.as_ref(),
1371            Expression::AggregateFunction(f) => f.inferred_type.as_ref(),
1372            Expression::WindowFunction(f) => f.inferred_type.as_ref(),
1373            Expression::Case(c) => c.inferred_type.as_ref(),
1374            Expression::Array(a) => a.inferred_type.as_ref(),
1375            Expression::ArrayFunc(a) => a.inferred_type.as_ref(),
1376            Expression::Paren(p) => p.this.inferred_type(),
1377            Expression::Annotated(a) => a.this.inferred_type(),
1378            Expression::Subquery(s) => s.inferred_type.as_ref(),
1379            Expression::Alias(a) => a.inferred_type.as_ref(),
1380            Expression::Unnest(u) => u.inferred_type.as_ref(),
1381            Expression::IfFunc(f) => f.inferred_type.as_ref(),
1382            Expression::Nvl2(f) => f.inferred_type.as_ref(),
1383            Expression::Count(f) => f.inferred_type.as_ref(),
1384            Expression::GroupConcat(f) => f.inferred_type.as_ref(),
1385            Expression::StringAgg(f) => f.inferred_type.as_ref(),
1386            Expression::ListAgg(f) => f.inferred_type.as_ref(),
1387            Expression::SumIf(f) => f.inferred_type.as_ref(),
1388            Expression::Trim(f) => f.inferred_type.as_ref(),
1389
1390            // UnaryFunc variants
1391            Expression::Upper(f)
1392            | Expression::Lower(f)
1393            | Expression::Length(f)
1394            | Expression::LTrim(f)
1395            | Expression::RTrim(f)
1396            | Expression::Reverse(f)
1397            | Expression::Abs(f)
1398            | Expression::Sqrt(f)
1399            | Expression::Cbrt(f)
1400            | Expression::Ln(f)
1401            | Expression::Exp(f)
1402            | Expression::Sign(f)
1403            | Expression::Date(f)
1404            | Expression::Time(f)
1405            | Expression::Initcap(f)
1406            | Expression::Ascii(f)
1407            | Expression::Chr(f)
1408            | Expression::Soundex(f)
1409            | Expression::ByteLength(f)
1410            | Expression::Hex(f)
1411            | Expression::LowerHex(f)
1412            | Expression::Unicode(f)
1413            | Expression::Typeof(f)
1414            | Expression::Explode(f)
1415            | Expression::ExplodeOuter(f)
1416            | Expression::MapFromEntries(f)
1417            | Expression::MapKeys(f)
1418            | Expression::MapValues(f)
1419            | Expression::ArrayLength(f)
1420            | Expression::ArraySize(f)
1421            | Expression::Cardinality(f)
1422            | Expression::ArrayReverse(f)
1423            | Expression::ArrayDistinct(f)
1424            | Expression::ArrayFlatten(f)
1425            | Expression::ArrayCompact(f)
1426            | Expression::ToArray(f)
1427            | Expression::JsonArrayLength(f)
1428            | Expression::JsonKeys(f)
1429            | Expression::JsonType(f)
1430            | Expression::ParseJson(f)
1431            | Expression::ToJson(f)
1432            | Expression::Radians(f)
1433            | Expression::Degrees(f)
1434            | Expression::Sin(f)
1435            | Expression::Cos(f)
1436            | Expression::Tan(f)
1437            | Expression::Asin(f)
1438            | Expression::Acos(f)
1439            | Expression::Atan(f)
1440            | Expression::IsNan(f)
1441            | Expression::IsInf(f)
1442            | Expression::Year(f)
1443            | Expression::Month(f)
1444            | Expression::Day(f)
1445            | Expression::Hour(f)
1446            | Expression::Minute(f)
1447            | Expression::Second(f)
1448            | Expression::DayOfWeek(f)
1449            | Expression::DayOfWeekIso(f)
1450            | Expression::DayOfMonth(f)
1451            | Expression::DayOfYear(f)
1452            | Expression::WeekOfYear(f)
1453            | Expression::Quarter(f)
1454            | Expression::Epoch(f)
1455            | Expression::EpochMs(f)
1456            | Expression::BitwiseCount(f)
1457            | Expression::DateFromUnixDate(f)
1458            | Expression::UnixDate(f)
1459            | Expression::UnixSeconds(f)
1460            | Expression::UnixMillis(f)
1461            | Expression::UnixMicros(f)
1462            | Expression::TimeStrToDate(f)
1463            | Expression::DateToDi(f)
1464            | Expression::DiToDate(f)
1465            | Expression::TsOrDiToDi(f)
1466            | Expression::TsOrDsToDatetime(f)
1467            | Expression::TsOrDsToTimestamp(f)
1468            | Expression::YearOfWeek(f)
1469            | Expression::YearOfWeekIso(f)
1470            | Expression::SHA(f)
1471            | Expression::SHA1Digest(f)
1472            | Expression::TimeToUnix(f)
1473            | Expression::TimeStrToUnix(f) => f.inferred_type.as_ref(),
1474
1475            // BinaryFunc variants
1476            Expression::Power(f)
1477            | Expression::NullIf(f)
1478            | Expression::IfNull(f)
1479            | Expression::Nvl(f)
1480            | Expression::Contains(f)
1481            | Expression::StartsWith(f)
1482            | Expression::EndsWith(f)
1483            | Expression::Levenshtein(f)
1484            | Expression::ModFunc(f)
1485            | Expression::IntDiv(f)
1486            | Expression::Atan2(f)
1487            | Expression::AddMonths(f)
1488            | Expression::MonthsBetween(f)
1489            | Expression::NextDay(f)
1490            | Expression::UnixToTimeStr(f)
1491            | Expression::ArrayContains(f)
1492            | Expression::ArrayPosition(f)
1493            | Expression::ArrayAppend(f)
1494            | Expression::ArrayPrepend(f)
1495            | Expression::ArrayUnion(f)
1496            | Expression::ArrayExcept(f)
1497            | Expression::ArrayRemove(f)
1498            | Expression::StarMap(f)
1499            | Expression::MapFromArrays(f)
1500            | Expression::MapContainsKey(f)
1501            | Expression::ElementAt(f)
1502            | Expression::JsonMergePatch(f) => f.inferred_type.as_ref(),
1503
1504            // VarArgFunc variants
1505            Expression::Coalesce(f)
1506            | Expression::Greatest(f)
1507            | Expression::Least(f)
1508            | Expression::ArrayConcat(f)
1509            | Expression::ArrayIntersect(f)
1510            | Expression::ArrayZip(f)
1511            | Expression::MapConcat(f)
1512            | Expression::JsonArray(f) => f.inferred_type.as_ref(),
1513
1514            // AggFunc variants
1515            Expression::Sum(f)
1516            | Expression::Avg(f)
1517            | Expression::Min(f)
1518            | Expression::Max(f)
1519            | Expression::ArrayAgg(f)
1520            | Expression::CountIf(f)
1521            | Expression::Stddev(f)
1522            | Expression::StddevPop(f)
1523            | Expression::StddevSamp(f)
1524            | Expression::Variance(f)
1525            | Expression::VarPop(f)
1526            | Expression::VarSamp(f)
1527            | Expression::Median(f)
1528            | Expression::Mode(f)
1529            | Expression::First(f)
1530            | Expression::Last(f)
1531            | Expression::AnyValue(f)
1532            | Expression::ApproxDistinct(f)
1533            | Expression::ApproxCountDistinct(f)
1534            | Expression::LogicalAnd(f)
1535            | Expression::LogicalOr(f)
1536            | Expression::Skewness(f)
1537            | Expression::ArrayConcatAgg(f)
1538            | Expression::ArrayUniqueAgg(f)
1539            | Expression::BoolXorAgg(f)
1540            | Expression::BitwiseAndAgg(f)
1541            | Expression::BitwiseOrAgg(f)
1542            | Expression::BitwiseXorAgg(f) => f.inferred_type.as_ref(),
1543
1544            // Everything else: no inferred_type field
1545            _ => None,
1546        }
1547    }
1548
1549    /// Set the inferred type annotation on this expression.
1550    ///
1551    /// Only has an effect on value-producing expressions with an `inferred_type`
1552    /// field. For other expression types, this is a no-op.
1553    pub fn set_inferred_type(&mut self, dt: DataType) {
1554        match self {
1555            Expression::And(op)
1556            | Expression::Or(op)
1557            | Expression::Add(op)
1558            | Expression::Sub(op)
1559            | Expression::Mul(op)
1560            | Expression::Div(op)
1561            | Expression::Mod(op)
1562            | Expression::Eq(op)
1563            | Expression::Neq(op)
1564            | Expression::Lt(op)
1565            | Expression::Lte(op)
1566            | Expression::Gt(op)
1567            | Expression::Gte(op)
1568            | Expression::Concat(op)
1569            | Expression::BitwiseAnd(op)
1570            | Expression::BitwiseOr(op)
1571            | Expression::BitwiseXor(op)
1572            | Expression::Adjacent(op)
1573            | Expression::TsMatch(op)
1574            | Expression::PropertyEQ(op)
1575            | Expression::ArrayContainsAll(op)
1576            | Expression::ArrayContainedBy(op)
1577            | Expression::ArrayOverlaps(op)
1578            | Expression::JSONBContainsAllTopKeys(op)
1579            | Expression::JSONBContainsAnyTopKeys(op)
1580            | Expression::JSONBDeleteAtPath(op)
1581            | Expression::ExtendsLeft(op)
1582            | Expression::ExtendsRight(op)
1583            | Expression::Is(op)
1584            | Expression::MemberOf(op)
1585            | Expression::Match(op)
1586            | Expression::NullSafeEq(op)
1587            | Expression::NullSafeNeq(op)
1588            | Expression::Glob(op)
1589            | Expression::BitwiseLeftShift(op)
1590            | Expression::BitwiseRightShift(op) => op.inferred_type = Some(dt),
1591
1592            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1593                op.inferred_type = Some(dt)
1594            }
1595
1596            Expression::Like(op) | Expression::ILike(op) => op.inferred_type = Some(dt),
1597
1598            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1599                c.inferred_type = Some(dt)
1600            }
1601
1602            Expression::Column(c) => c.inferred_type = Some(dt),
1603            Expression::Dot(dot) => dot.inferred_type = Some(dt),
1604            Expression::Function(f) => f.inferred_type = Some(dt),
1605            Expression::AggregateFunction(f) => f.inferred_type = Some(dt),
1606            Expression::WindowFunction(f) => f.inferred_type = Some(dt),
1607            Expression::Case(c) => c.inferred_type = Some(dt),
1608            Expression::Array(a) => a.inferred_type = Some(dt),
1609            Expression::ArrayFunc(a) => a.inferred_type = Some(dt),
1610            Expression::Paren(p) => p.this.set_inferred_type(dt),
1611            Expression::Annotated(a) => a.this.set_inferred_type(dt),
1612            Expression::Subquery(s) => s.inferred_type = Some(dt),
1613            Expression::Alias(a) => a.inferred_type = Some(dt),
1614            Expression::Unnest(u) => u.inferred_type = Some(dt),
1615            Expression::IfFunc(f) => f.inferred_type = Some(dt),
1616            Expression::Nvl2(f) => f.inferred_type = Some(dt),
1617            Expression::Count(f) => f.inferred_type = Some(dt),
1618            Expression::GroupConcat(f) => f.inferred_type = Some(dt),
1619            Expression::StringAgg(f) => f.inferred_type = Some(dt),
1620            Expression::ListAgg(f) => f.inferred_type = Some(dt),
1621            Expression::SumIf(f) => f.inferred_type = Some(dt),
1622            Expression::Trim(f) => f.inferred_type = Some(dt),
1623
1624            // UnaryFunc variants
1625            Expression::Upper(f)
1626            | Expression::Lower(f)
1627            | Expression::Length(f)
1628            | Expression::LTrim(f)
1629            | Expression::RTrim(f)
1630            | Expression::Reverse(f)
1631            | Expression::Abs(f)
1632            | Expression::Sqrt(f)
1633            | Expression::Cbrt(f)
1634            | Expression::Ln(f)
1635            | Expression::Exp(f)
1636            | Expression::Sign(f)
1637            | Expression::Date(f)
1638            | Expression::Time(f)
1639            | Expression::Initcap(f)
1640            | Expression::Ascii(f)
1641            | Expression::Chr(f)
1642            | Expression::Soundex(f)
1643            | Expression::ByteLength(f)
1644            | Expression::Hex(f)
1645            | Expression::LowerHex(f)
1646            | Expression::Unicode(f)
1647            | Expression::Typeof(f)
1648            | Expression::Explode(f)
1649            | Expression::ExplodeOuter(f)
1650            | Expression::MapFromEntries(f)
1651            | Expression::MapKeys(f)
1652            | Expression::MapValues(f)
1653            | Expression::ArrayLength(f)
1654            | Expression::ArraySize(f)
1655            | Expression::Cardinality(f)
1656            | Expression::ArrayReverse(f)
1657            | Expression::ArrayDistinct(f)
1658            | Expression::ArrayFlatten(f)
1659            | Expression::ArrayCompact(f)
1660            | Expression::ToArray(f)
1661            | Expression::JsonArrayLength(f)
1662            | Expression::JsonKeys(f)
1663            | Expression::JsonType(f)
1664            | Expression::ParseJson(f)
1665            | Expression::ToJson(f)
1666            | Expression::Radians(f)
1667            | Expression::Degrees(f)
1668            | Expression::Sin(f)
1669            | Expression::Cos(f)
1670            | Expression::Tan(f)
1671            | Expression::Asin(f)
1672            | Expression::Acos(f)
1673            | Expression::Atan(f)
1674            | Expression::IsNan(f)
1675            | Expression::IsInf(f)
1676            | Expression::Year(f)
1677            | Expression::Month(f)
1678            | Expression::Day(f)
1679            | Expression::Hour(f)
1680            | Expression::Minute(f)
1681            | Expression::Second(f)
1682            | Expression::DayOfWeek(f)
1683            | Expression::DayOfWeekIso(f)
1684            | Expression::DayOfMonth(f)
1685            | Expression::DayOfYear(f)
1686            | Expression::WeekOfYear(f)
1687            | Expression::Quarter(f)
1688            | Expression::Epoch(f)
1689            | Expression::EpochMs(f)
1690            | Expression::BitwiseCount(f)
1691            | Expression::DateFromUnixDate(f)
1692            | Expression::UnixDate(f)
1693            | Expression::UnixSeconds(f)
1694            | Expression::UnixMillis(f)
1695            | Expression::UnixMicros(f)
1696            | Expression::TimeStrToDate(f)
1697            | Expression::DateToDi(f)
1698            | Expression::DiToDate(f)
1699            | Expression::TsOrDiToDi(f)
1700            | Expression::TsOrDsToDatetime(f)
1701            | Expression::TsOrDsToTimestamp(f)
1702            | Expression::YearOfWeek(f)
1703            | Expression::YearOfWeekIso(f)
1704            | Expression::SHA(f)
1705            | Expression::SHA1Digest(f)
1706            | Expression::TimeToUnix(f)
1707            | Expression::TimeStrToUnix(f) => f.inferred_type = Some(dt),
1708
1709            // BinaryFunc variants
1710            Expression::Power(f)
1711            | Expression::NullIf(f)
1712            | Expression::IfNull(f)
1713            | Expression::Nvl(f)
1714            | Expression::Contains(f)
1715            | Expression::StartsWith(f)
1716            | Expression::EndsWith(f)
1717            | Expression::Levenshtein(f)
1718            | Expression::ModFunc(f)
1719            | Expression::IntDiv(f)
1720            | Expression::Atan2(f)
1721            | Expression::AddMonths(f)
1722            | Expression::MonthsBetween(f)
1723            | Expression::NextDay(f)
1724            | Expression::UnixToTimeStr(f)
1725            | Expression::ArrayContains(f)
1726            | Expression::ArrayPosition(f)
1727            | Expression::ArrayAppend(f)
1728            | Expression::ArrayPrepend(f)
1729            | Expression::ArrayUnion(f)
1730            | Expression::ArrayExcept(f)
1731            | Expression::ArrayRemove(f)
1732            | Expression::StarMap(f)
1733            | Expression::MapFromArrays(f)
1734            | Expression::MapContainsKey(f)
1735            | Expression::ElementAt(f)
1736            | Expression::JsonMergePatch(f) => f.inferred_type = Some(dt),
1737
1738            // VarArgFunc variants
1739            Expression::Coalesce(f)
1740            | Expression::Greatest(f)
1741            | Expression::Least(f)
1742            | Expression::ArrayConcat(f)
1743            | Expression::ArrayIntersect(f)
1744            | Expression::ArrayZip(f)
1745            | Expression::MapConcat(f)
1746            | Expression::JsonArray(f) => f.inferred_type = Some(dt),
1747
1748            // AggFunc variants
1749            Expression::Sum(f)
1750            | Expression::Avg(f)
1751            | Expression::Min(f)
1752            | Expression::Max(f)
1753            | Expression::ArrayAgg(f)
1754            | Expression::CountIf(f)
1755            | Expression::Stddev(f)
1756            | Expression::StddevPop(f)
1757            | Expression::StddevSamp(f)
1758            | Expression::Variance(f)
1759            | Expression::VarPop(f)
1760            | Expression::VarSamp(f)
1761            | Expression::Median(f)
1762            | Expression::Mode(f)
1763            | Expression::First(f)
1764            | Expression::Last(f)
1765            | Expression::AnyValue(f)
1766            | Expression::ApproxDistinct(f)
1767            | Expression::ApproxCountDistinct(f)
1768            | Expression::LogicalAnd(f)
1769            | Expression::LogicalOr(f)
1770            | Expression::Skewness(f)
1771            | Expression::ArrayConcatAgg(f)
1772            | Expression::ArrayUniqueAgg(f)
1773            | Expression::BoolXorAgg(f)
1774            | Expression::BitwiseAndAgg(f)
1775            | Expression::BitwiseOrAgg(f)
1776            | Expression::BitwiseXorAgg(f) => f.inferred_type = Some(dt),
1777
1778            // Expressions without inferred_type field - no-op
1779            _ => {}
1780        }
1781    }
1782
1783    /// Create an unqualified column reference (e.g. `name`).
1784    pub fn column(name: impl Into<String>) -> Self {
1785        Expression::Column(Box::new(Column {
1786            name: Identifier::new(name),
1787            table: None,
1788            join_mark: false,
1789            trailing_comments: Vec::new(),
1790            span: None,
1791            inferred_type: None,
1792        }))
1793    }
1794
1795    /// Create a qualified column reference (`table.column`).
1796    pub fn qualified_column(table: impl Into<String>, column: impl Into<String>) -> Self {
1797        Expression::Column(Box::new(Column {
1798            name: Identifier::new(column),
1799            table: Some(Identifier::new(table)),
1800            join_mark: false,
1801            trailing_comments: Vec::new(),
1802            span: None,
1803            inferred_type: None,
1804        }))
1805    }
1806
1807    /// Create a bare identifier expression (not a column reference).
1808    pub fn identifier(name: impl Into<String>) -> Self {
1809        Expression::Identifier(Identifier::new(name))
1810    }
1811
1812    /// Create a NULL expression
1813    pub fn null() -> Self {
1814        Expression::Null(Null)
1815    }
1816
1817    /// Create a TRUE expression
1818    pub fn true_() -> Self {
1819        Expression::Boolean(BooleanLiteral { value: true })
1820    }
1821
1822    /// Create a FALSE expression
1823    pub fn false_() -> Self {
1824        Expression::Boolean(BooleanLiteral { value: false })
1825    }
1826
1827    /// Create a wildcard star (`*`) expression with no EXCEPT/REPLACE/RENAME modifiers.
1828    pub fn star() -> Self {
1829        Expression::Star(Star {
1830            table: None,
1831            except: None,
1832            replace: None,
1833            rename: None,
1834            trailing_comments: Vec::new(),
1835            span: None,
1836        })
1837    }
1838
1839    /// Wrap this expression in an `AS` alias (e.g. `expr AS name`).
1840    pub fn alias(self, name: impl Into<String>) -> Self {
1841        Expression::Alias(Box::new(Alias::new(self, Identifier::new(name))))
1842    }
1843
1844    /// Check if this is a SELECT expression
1845    pub fn is_select(&self) -> bool {
1846        matches!(self, Expression::Select(_))
1847    }
1848
1849    /// Try to get as a Select
1850    pub fn as_select(&self) -> Option<&Select> {
1851        match self {
1852            Expression::Select(s) => Some(s),
1853            _ => None,
1854        }
1855    }
1856
1857    /// Try to get as a mutable Select
1858    pub fn as_select_mut(&mut self) -> Option<&mut Select> {
1859        match self {
1860            Expression::Select(s) => Some(s),
1861            _ => None,
1862        }
1863    }
1864
1865    /// Generate a SQL string for this expression using the generic (dialect-agnostic) generator.
1866    ///
1867    /// Returns an empty string if generation fails. For dialect-specific output,
1868    /// use [`sql_for()`](Self::sql_for) instead.
1869    #[cfg(feature = "generate")]
1870    pub fn sql(&self) -> String {
1871        crate::generator::Generator::sql(self).unwrap_or_default()
1872    }
1873
1874    /// Generate a SQL string for this expression targeting a specific dialect.
1875    ///
1876    /// Dialect-specific rules (identifier quoting, function names, type mappings,
1877    /// syntax variations) are applied automatically.  Returns an empty string if
1878    /// generation fails.
1879    #[cfg(feature = "generate")]
1880    pub fn sql_for(&self, dialect: crate::dialects::DialectType) -> String {
1881        crate::generate(self, dialect).unwrap_or_default()
1882    }
1883}
1884
1885// === Python API accessor methods ===
1886
1887impl Expression {
1888    /// Returns the serde-compatible snake_case variant name without serialization.
1889    /// This is much faster than serializing to JSON and extracting the key.
1890    pub fn variant_name(&self) -> &'static str {
1891        match self {
1892            Expression::Vertica(_) => "vertica",
1893            Expression::Literal(_) => "literal",
1894            Expression::Boolean(_) => "boolean",
1895            Expression::Null(_) => "null",
1896            Expression::Identifier(_) => "identifier",
1897            Expression::Column(_) => "column",
1898            Expression::Table(_) => "table",
1899            Expression::Star(_) => "star",
1900            Expression::BracedWildcard(_) => "braced_wildcard",
1901            Expression::Select(_) => "select",
1902            Expression::Union(_) => "union",
1903            Expression::Intersect(_) => "intersect",
1904            Expression::Except(_) => "except",
1905            Expression::Subquery(_) => "subquery",
1906            Expression::PipeOperator(_) => "pipe_operator",
1907            Expression::Pivot(_) => "pivot",
1908            Expression::PivotAlias(_) => "pivot_alias",
1909            Expression::Unpivot(_) => "unpivot",
1910            Expression::Values(_) => "values",
1911            Expression::PreWhere(_) => "pre_where",
1912            Expression::Stream(_) => "stream",
1913            Expression::UsingData(_) => "using_data",
1914            Expression::XmlNamespace(_) => "xml_namespace",
1915            Expression::Insert(_) => "insert",
1916            Expression::Update(_) => "update",
1917            Expression::Delete(_) => "delete",
1918            Expression::Copy(_) => "copy",
1919            Expression::Put(_) => "put",
1920            Expression::StageReference(_) => "stage_reference",
1921            Expression::Alias(_) => "alias",
1922            Expression::Cast(_) => "cast",
1923            Expression::Collation(_) => "collation",
1924            Expression::Case(_) => "case",
1925            Expression::And(_) => "and",
1926            Expression::Or(_) => "or",
1927            Expression::Add(_) => "add",
1928            Expression::Sub(_) => "sub",
1929            Expression::Mul(_) => "mul",
1930            Expression::Div(_) => "div",
1931            Expression::Mod(_) => "mod",
1932            Expression::Eq(_) => "eq",
1933            Expression::Neq(_) => "neq",
1934            Expression::Lt(_) => "lt",
1935            Expression::Lte(_) => "lte",
1936            Expression::Gt(_) => "gt",
1937            Expression::Gte(_) => "gte",
1938            Expression::Like(_) => "like",
1939            Expression::ILike(_) => "i_like",
1940            Expression::Match(_) => "match",
1941            Expression::BitwiseAnd(_) => "bitwise_and",
1942            Expression::BitwiseOr(_) => "bitwise_or",
1943            Expression::BitwiseXor(_) => "bitwise_xor",
1944            Expression::Concat(_) => "concat",
1945            Expression::Adjacent(_) => "adjacent",
1946            Expression::TsMatch(_) => "ts_match",
1947            Expression::PropertyEQ(_) => "property_e_q",
1948            Expression::ArrayContainsAll(_) => "array_contains_all",
1949            Expression::ArrayContainedBy(_) => "array_contained_by",
1950            Expression::ArrayOverlaps(_) => "array_overlaps",
1951            Expression::JSONBContainsAllTopKeys(_) => "j_s_o_n_b_contains_all_top_keys",
1952            Expression::JSONBContainsAnyTopKeys(_) => "j_s_o_n_b_contains_any_top_keys",
1953            Expression::JSONBDeleteAtPath(_) => "j_s_o_n_b_delete_at_path",
1954            Expression::ExtendsLeft(_) => "extends_left",
1955            Expression::ExtendsRight(_) => "extends_right",
1956            Expression::Not(_) => "not",
1957            Expression::Neg(_) => "neg",
1958            Expression::BitwiseNot(_) => "bitwise_not",
1959            Expression::In(_) => "in",
1960            Expression::Between(_) => "between",
1961            Expression::IsNull(_) => "is_null",
1962            Expression::IsTrue(_) => "is_true",
1963            Expression::IsFalse(_) => "is_false",
1964            Expression::IsJson(_) => "is_json",
1965            Expression::Is(_) => "is",
1966            Expression::Exists(_) => "exists",
1967            Expression::MemberOf(_) => "member_of",
1968            Expression::Function(_) => "function",
1969            Expression::Upsert(_) => "upsert",
1970            Expression::StorageProperty(_) => "storage_property",
1971            Expression::Hierarchy(_) => "hierarchy",
1972            Expression::ViewParameter(_) => "view_parameter",
1973            Expression::Call(_) => "call",
1974            Expression::AggregateFunction(_) => "aggregate_function",
1975            Expression::WindowFunction(_) => "window_function",
1976            Expression::From(_) => "from",
1977            Expression::Join(_) => "join",
1978            Expression::JoinedTable(_) => "joined_table",
1979            Expression::Where(_) => "where",
1980            Expression::GroupBy(_) => "group_by",
1981            Expression::Having(_) => "having",
1982            Expression::OrderBy(_) => "order_by",
1983            Expression::Limit(_) => "limit",
1984            Expression::Offset(_) => "offset",
1985            Expression::Qualify(_) => "qualify",
1986            Expression::With(_) => "with",
1987            Expression::Cte(_) => "cte",
1988            Expression::DistributeBy(_) => "distribute_by",
1989            Expression::ClusterBy(_) => "cluster_by",
1990            Expression::SortBy(_) => "sort_by",
1991            Expression::LateralView(_) => "lateral_view",
1992            Expression::Hint(_) => "hint",
1993            Expression::Pseudocolumn(_) => "pseudocolumn",
1994            Expression::Connect(_) => "connect",
1995            Expression::Prior(_) => "prior",
1996            Expression::ConnectByRoot(_) => "connect_by_root",
1997            Expression::MatchRecognize(_) => "match_recognize",
1998            Expression::Ordered(_) => "ordered",
1999            Expression::Window(_) => "window",
2000            Expression::Over(_) => "over",
2001            Expression::WithinGroup(_) => "within_group",
2002            Expression::DataType(_) => "data_type",
2003            Expression::Array(_) => "array",
2004            Expression::Struct(_) => "struct",
2005            Expression::Tuple(_) => "tuple",
2006            Expression::Interval(_) => "interval",
2007            Expression::ConcatWs(_) => "concat_ws",
2008            Expression::Substring(_) => "substring",
2009            Expression::Upper(_) => "upper",
2010            Expression::Lower(_) => "lower",
2011            Expression::Length(_) => "length",
2012            Expression::Trim(_) => "trim",
2013            Expression::LTrim(_) => "l_trim",
2014            Expression::RTrim(_) => "r_trim",
2015            Expression::Replace(_) => "replace",
2016            Expression::Reverse(_) => "reverse",
2017            Expression::Left(_) => "left",
2018            Expression::Right(_) => "right",
2019            Expression::Repeat(_) => "repeat",
2020            Expression::Lpad(_) => "lpad",
2021            Expression::Rpad(_) => "rpad",
2022            Expression::Split(_) => "split",
2023            Expression::RegexpLike(_) => "regexp_like",
2024            Expression::RegexpReplace(_) => "regexp_replace",
2025            Expression::RegexpExtract(_) => "regexp_extract",
2026            Expression::Overlay(_) => "overlay",
2027            Expression::Abs(_) => "abs",
2028            Expression::Round(_) => "round",
2029            Expression::Floor(_) => "floor",
2030            Expression::Ceil(_) => "ceil",
2031            Expression::Power(_) => "power",
2032            Expression::Sqrt(_) => "sqrt",
2033            Expression::Cbrt(_) => "cbrt",
2034            Expression::Ln(_) => "ln",
2035            Expression::Log(_) => "log",
2036            Expression::Exp(_) => "exp",
2037            Expression::Sign(_) => "sign",
2038            Expression::Greatest(_) => "greatest",
2039            Expression::Least(_) => "least",
2040            Expression::CurrentDate(_) => "current_date",
2041            Expression::CurrentTime(_) => "current_time",
2042            Expression::CurrentTimestamp(_) => "current_timestamp",
2043            Expression::CurrentTimestampLTZ(_) => "current_timestamp_l_t_z",
2044            Expression::AtTimeZone(_) => "at_time_zone",
2045            Expression::DateAdd(_) => "date_add",
2046            Expression::DateSub(_) => "date_sub",
2047            Expression::DateDiff(_) => "date_diff",
2048            Expression::DateTrunc(_) => "date_trunc",
2049            Expression::Extract(_) => "extract",
2050            Expression::ToDate(_) => "to_date",
2051            Expression::ToTimestamp(_) => "to_timestamp",
2052            Expression::Date(_) => "date",
2053            Expression::Time(_) => "time",
2054            Expression::DateFromUnixDate(_) => "date_from_unix_date",
2055            Expression::UnixDate(_) => "unix_date",
2056            Expression::UnixSeconds(_) => "unix_seconds",
2057            Expression::UnixMillis(_) => "unix_millis",
2058            Expression::UnixMicros(_) => "unix_micros",
2059            Expression::UnixToTimeStr(_) => "unix_to_time_str",
2060            Expression::TimeStrToDate(_) => "time_str_to_date",
2061            Expression::DateToDi(_) => "date_to_di",
2062            Expression::DiToDate(_) => "di_to_date",
2063            Expression::TsOrDiToDi(_) => "ts_or_di_to_di",
2064            Expression::TsOrDsToDatetime(_) => "ts_or_ds_to_datetime",
2065            Expression::TsOrDsToTimestamp(_) => "ts_or_ds_to_timestamp",
2066            Expression::YearOfWeek(_) => "year_of_week",
2067            Expression::YearOfWeekIso(_) => "year_of_week_iso",
2068            Expression::Coalesce(_) => "coalesce",
2069            Expression::NullIf(_) => "null_if",
2070            Expression::IfFunc(_) => "if_func",
2071            Expression::IfNull(_) => "if_null",
2072            Expression::Nvl(_) => "nvl",
2073            Expression::Nvl2(_) => "nvl2",
2074            Expression::TryCast(_) => "try_cast",
2075            Expression::SafeCast(_) => "safe_cast",
2076            Expression::Count(_) => "count",
2077            Expression::Sum(_) => "sum",
2078            Expression::Avg(_) => "avg",
2079            Expression::Min(_) => "min",
2080            Expression::Max(_) => "max",
2081            Expression::GroupConcat(_) => "group_concat",
2082            Expression::StringAgg(_) => "string_agg",
2083            Expression::ListAgg(_) => "list_agg",
2084            Expression::ArrayAgg(_) => "array_agg",
2085            Expression::CountIf(_) => "count_if",
2086            Expression::SumIf(_) => "sum_if",
2087            Expression::Stddev(_) => "stddev",
2088            Expression::StddevPop(_) => "stddev_pop",
2089            Expression::StddevSamp(_) => "stddev_samp",
2090            Expression::Variance(_) => "variance",
2091            Expression::VarPop(_) => "var_pop",
2092            Expression::VarSamp(_) => "var_samp",
2093            Expression::Median(_) => "median",
2094            Expression::Mode(_) => "mode",
2095            Expression::First(_) => "first",
2096            Expression::Last(_) => "last",
2097            Expression::AnyValue(_) => "any_value",
2098            Expression::ApproxDistinct(_) => "approx_distinct",
2099            Expression::ApproxCountDistinct(_) => "approx_count_distinct",
2100            Expression::ApproxPercentile(_) => "approx_percentile",
2101            Expression::Percentile(_) => "percentile",
2102            Expression::LogicalAnd(_) => "logical_and",
2103            Expression::LogicalOr(_) => "logical_or",
2104            Expression::Skewness(_) => "skewness",
2105            Expression::BitwiseCount(_) => "bitwise_count",
2106            Expression::ArrayConcatAgg(_) => "array_concat_agg",
2107            Expression::ArrayUniqueAgg(_) => "array_unique_agg",
2108            Expression::BoolXorAgg(_) => "bool_xor_agg",
2109            Expression::RowNumber(_) => "row_number",
2110            Expression::Rank(_) => "rank",
2111            Expression::DenseRank(_) => "dense_rank",
2112            Expression::NTile(_) => "n_tile",
2113            Expression::Lead(_) => "lead",
2114            Expression::Lag(_) => "lag",
2115            Expression::FirstValue(_) => "first_value",
2116            Expression::LastValue(_) => "last_value",
2117            Expression::NthValue(_) => "nth_value",
2118            Expression::PercentRank(_) => "percent_rank",
2119            Expression::CumeDist(_) => "cume_dist",
2120            Expression::PercentileCont(_) => "percentile_cont",
2121            Expression::PercentileDisc(_) => "percentile_disc",
2122            Expression::Contains(_) => "contains",
2123            Expression::StartsWith(_) => "starts_with",
2124            Expression::EndsWith(_) => "ends_with",
2125            Expression::Position(_) => "position",
2126            Expression::Initcap(_) => "initcap",
2127            Expression::Ascii(_) => "ascii",
2128            Expression::Chr(_) => "chr",
2129            Expression::CharFunc(_) => "char_func",
2130            Expression::Soundex(_) => "soundex",
2131            Expression::Levenshtein(_) => "levenshtein",
2132            Expression::ByteLength(_) => "byte_length",
2133            Expression::Hex(_) => "hex",
2134            Expression::LowerHex(_) => "lower_hex",
2135            Expression::Unicode(_) => "unicode",
2136            Expression::ModFunc(_) => "mod_func",
2137            Expression::Random(_) => "random",
2138            Expression::Rand(_) => "rand",
2139            Expression::TruncFunc(_) => "trunc_func",
2140            Expression::Pi(_) => "pi",
2141            Expression::Radians(_) => "radians",
2142            Expression::Degrees(_) => "degrees",
2143            Expression::Sin(_) => "sin",
2144            Expression::Cos(_) => "cos",
2145            Expression::Tan(_) => "tan",
2146            Expression::Asin(_) => "asin",
2147            Expression::Acos(_) => "acos",
2148            Expression::Atan(_) => "atan",
2149            Expression::Atan2(_) => "atan2",
2150            Expression::IsNan(_) => "is_nan",
2151            Expression::IsInf(_) => "is_inf",
2152            Expression::IntDiv(_) => "int_div",
2153            Expression::Decode(_) => "decode",
2154            Expression::DateFormat(_) => "date_format",
2155            Expression::FormatDate(_) => "format_date",
2156            Expression::Year(_) => "year",
2157            Expression::Month(_) => "month",
2158            Expression::Day(_) => "day",
2159            Expression::Hour(_) => "hour",
2160            Expression::Minute(_) => "minute",
2161            Expression::Second(_) => "second",
2162            Expression::DayOfWeek(_) => "day_of_week",
2163            Expression::DayOfWeekIso(_) => "day_of_week_iso",
2164            Expression::DayOfMonth(_) => "day_of_month",
2165            Expression::DayOfYear(_) => "day_of_year",
2166            Expression::WeekOfYear(_) => "week_of_year",
2167            Expression::Quarter(_) => "quarter",
2168            Expression::AddMonths(_) => "add_months",
2169            Expression::MonthsBetween(_) => "months_between",
2170            Expression::LastDay(_) => "last_day",
2171            Expression::NextDay(_) => "next_day",
2172            Expression::Epoch(_) => "epoch",
2173            Expression::EpochMs(_) => "epoch_ms",
2174            Expression::FromUnixtime(_) => "from_unixtime",
2175            Expression::UnixTimestamp(_) => "unix_timestamp",
2176            Expression::MakeDate(_) => "make_date",
2177            Expression::MakeTimestamp(_) => "make_timestamp",
2178            Expression::TimestampTrunc(_) => "timestamp_trunc",
2179            Expression::TimeStrToUnix(_) => "time_str_to_unix",
2180            Expression::SessionUser(_) => "session_user",
2181            Expression::SHA(_) => "s_h_a",
2182            Expression::SHA1Digest(_) => "s_h_a1_digest",
2183            Expression::TimeToUnix(_) => "time_to_unix",
2184            Expression::ArrayFunc(_) => "array_func",
2185            Expression::ArrayLength(_) => "array_length",
2186            Expression::ArraySize(_) => "array_size",
2187            Expression::Cardinality(_) => "cardinality",
2188            Expression::ArrayContains(_) => "array_contains",
2189            Expression::ArrayPosition(_) => "array_position",
2190            Expression::ArrayAppend(_) => "array_append",
2191            Expression::ArrayPrepend(_) => "array_prepend",
2192            Expression::ArrayConcat(_) => "array_concat",
2193            Expression::ArraySort(_) => "array_sort",
2194            Expression::ArrayReverse(_) => "array_reverse",
2195            Expression::ArrayDistinct(_) => "array_distinct",
2196            Expression::ArrayJoin(_) => "array_join",
2197            Expression::ArrayToString(_) => "array_to_string",
2198            Expression::Unnest(_) => "unnest",
2199            Expression::Explode(_) => "explode",
2200            Expression::ExplodeOuter(_) => "explode_outer",
2201            Expression::ArrayFilter(_) => "array_filter",
2202            Expression::ArrayTransform(_) => "array_transform",
2203            Expression::ArrayFlatten(_) => "array_flatten",
2204            Expression::ArrayCompact(_) => "array_compact",
2205            Expression::ArrayIntersect(_) => "array_intersect",
2206            Expression::ArrayUnion(_) => "array_union",
2207            Expression::ArrayExcept(_) => "array_except",
2208            Expression::ArrayRemove(_) => "array_remove",
2209            Expression::ArrayZip(_) => "array_zip",
2210            Expression::Sequence(_) => "sequence",
2211            Expression::Generate(_) => "generate",
2212            Expression::ExplodingGenerateSeries(_) => "exploding_generate_series",
2213            Expression::ToArray(_) => "to_array",
2214            Expression::StarMap(_) => "star_map",
2215            Expression::StructFunc(_) => "struct_func",
2216            Expression::StructExtract(_) => "struct_extract",
2217            Expression::NamedStruct(_) => "named_struct",
2218            Expression::MapFunc(_) => "map_func",
2219            Expression::MapFromEntries(_) => "map_from_entries",
2220            Expression::MapFromArrays(_) => "map_from_arrays",
2221            Expression::MapKeys(_) => "map_keys",
2222            Expression::MapValues(_) => "map_values",
2223            Expression::MapContainsKey(_) => "map_contains_key",
2224            Expression::MapConcat(_) => "map_concat",
2225            Expression::ElementAt(_) => "element_at",
2226            Expression::TransformKeys(_) => "transform_keys",
2227            Expression::TransformValues(_) => "transform_values",
2228            Expression::FunctionEmits(_) => "function_emits",
2229            Expression::JsonExtract(_) => "json_extract",
2230            Expression::JsonExtractScalar(_) => "json_extract_scalar",
2231            Expression::JsonExtractPath(_) => "json_extract_path",
2232            Expression::JsonArray(_) => "json_array",
2233            Expression::JsonObject(_) => "json_object",
2234            Expression::JsonQuery(_) => "json_query",
2235            Expression::JsonValue(_) => "json_value",
2236            Expression::JsonArrayLength(_) => "json_array_length",
2237            Expression::JsonKeys(_) => "json_keys",
2238            Expression::JsonType(_) => "json_type",
2239            Expression::ParseJson(_) => "parse_json",
2240            Expression::ToJson(_) => "to_json",
2241            Expression::JsonSet(_) => "json_set",
2242            Expression::JsonInsert(_) => "json_insert",
2243            Expression::JsonRemove(_) => "json_remove",
2244            Expression::JsonMergePatch(_) => "json_merge_patch",
2245            Expression::JsonArrayAgg(_) => "json_array_agg",
2246            Expression::JsonObjectAgg(_) => "json_object_agg",
2247            Expression::Convert(_) => "convert",
2248            Expression::Typeof(_) => "typeof",
2249            Expression::Lambda(_) => "lambda",
2250            Expression::Parameter(_) => "parameter",
2251            Expression::Placeholder(_) => "placeholder",
2252            Expression::NamedArgument(_) => "named_argument",
2253            Expression::TableArgument(_) => "table_argument",
2254            Expression::SqlComment(_) => "sql_comment",
2255            Expression::NullSafeEq(_) => "null_safe_eq",
2256            Expression::NullSafeNeq(_) => "null_safe_neq",
2257            Expression::Glob(_) => "glob",
2258            Expression::SimilarTo(_) => "similar_to",
2259            Expression::Any(_) => "any",
2260            Expression::All(_) => "all",
2261            Expression::Overlaps(_) => "overlaps",
2262            Expression::BitwiseLeftShift(_) => "bitwise_left_shift",
2263            Expression::BitwiseRightShift(_) => "bitwise_right_shift",
2264            Expression::BitwiseAndAgg(_) => "bitwise_and_agg",
2265            Expression::BitwiseOrAgg(_) => "bitwise_or_agg",
2266            Expression::BitwiseXorAgg(_) => "bitwise_xor_agg",
2267            Expression::Subscript(_) => "subscript",
2268            Expression::Dot(_) => "dot",
2269            Expression::MethodCall(_) => "method_call",
2270            Expression::ArraySlice(_) => "array_slice",
2271            Expression::CreateTable(_) => "create_table",
2272            Expression::DropTable(_) => "drop_table",
2273            Expression::Undrop(_) => "undrop",
2274            Expression::AlterTable(_) => "alter_table",
2275            Expression::SplitTable(_) => "split_table",
2276            Expression::FlashbackTable(_) => "flashback_table",
2277            Expression::CreateIndex(_) => "create_index",
2278            Expression::DropIndex(_) => "drop_index",
2279            Expression::CreateView(_) => "create_view",
2280            Expression::DropView(_) => "drop_view",
2281            Expression::AlterView(_) => "alter_view",
2282            Expression::AlterIndex(_) => "alter_index",
2283            Expression::Truncate(_) => "truncate",
2284            Expression::Use(_) => "use",
2285            Expression::Cache(_) => "cache",
2286            Expression::Uncache(_) => "uncache",
2287            Expression::LoadData(_) => "load_data",
2288            Expression::Pragma(_) => "pragma",
2289            Expression::Grant(_) => "grant",
2290            Expression::Revoke(_) => "revoke",
2291            Expression::Comment(_) => "comment",
2292            Expression::SetStatement(_) => "set_statement",
2293            Expression::CreateSchema(_) => "create_schema",
2294            Expression::DropSchema(_) => "drop_schema",
2295            Expression::DropNamespace(_) => "drop_namespace",
2296            Expression::CreateDatabase(_) => "create_database",
2297            Expression::DropDatabase(_) => "drop_database",
2298            Expression::CreateFunction(_) => "create_function",
2299            Expression::DropFunction(_) => "drop_function",
2300            Expression::CreateProcedure(_) => "create_procedure",
2301            Expression::DropProcedure(_) => "drop_procedure",
2302            Expression::CreateSequence(_) => "create_sequence",
2303            Expression::CreateSynonym(_) => "create_synonym",
2304            Expression::DropSequence(_) => "drop_sequence",
2305            Expression::AlterSequence(_) => "alter_sequence",
2306            Expression::CreateTrigger(_) => "create_trigger",
2307            Expression::DropTrigger(_) => "drop_trigger",
2308            Expression::CreateType(_) => "create_type",
2309            Expression::DropType(_) => "drop_type",
2310            Expression::Describe(_) => "describe",
2311            Expression::Show(_) => "show",
2312            Expression::Command(_) => "command",
2313            Expression::TryCatch(_) => "try_catch",
2314            Expression::Kill(_) => "kill",
2315            Expression::Prepare(_) => "prepare",
2316            Expression::Execute(_) => "execute",
2317            Expression::Raw(_) => "raw",
2318            Expression::CreateTask(_) => "create_task",
2319            Expression::Paren(_) => "paren",
2320            Expression::Annotated(_) => "annotated",
2321            Expression::Refresh(_) => "refresh",
2322            Expression::LockingStatement(_) => "locking_statement",
2323            Expression::SequenceProperties(_) => "sequence_properties",
2324            Expression::TruncateTable(_) => "truncate_table",
2325            Expression::Clone(_) => "clone",
2326            Expression::Attach(_) => "attach",
2327            Expression::Detach(_) => "detach",
2328            Expression::Install(_) => "install",
2329            Expression::Summarize(_) => "summarize",
2330            Expression::Declare(_) => "declare",
2331            Expression::DeclareItem(_) => "declare_item",
2332            Expression::Set(_) => "set",
2333            Expression::Heredoc(_) => "heredoc",
2334            Expression::SetItem(_) => "set_item",
2335            Expression::QueryBand(_) => "query_band",
2336            Expression::UserDefinedFunction(_) => "user_defined_function",
2337            Expression::RecursiveWithSearch(_) => "recursive_with_search",
2338            Expression::ProjectionDef(_) => "projection_def",
2339            Expression::TableAlias(_) => "table_alias",
2340            Expression::ByteString(_) => "byte_string",
2341            Expression::HexStringExpr(_) => "hex_string_expr",
2342            Expression::UnicodeString(_) => "unicode_string",
2343            Expression::ColumnPosition(_) => "column_position",
2344            Expression::ColumnDef(_) => "column_def",
2345            Expression::AlterColumn(_) => "alter_column",
2346            Expression::AlterSortKey(_) => "alter_sort_key",
2347            Expression::AlterSet(_) => "alter_set",
2348            Expression::RenameColumn(_) => "rename_column",
2349            Expression::Comprehension(_) => "comprehension",
2350            Expression::MergeTreeTTLAction(_) => "merge_tree_t_t_l_action",
2351            Expression::MergeTreeTTL(_) => "merge_tree_t_t_l",
2352            Expression::IndexConstraintOption(_) => "index_constraint_option",
2353            Expression::ColumnConstraint(_) => "column_constraint",
2354            Expression::PeriodForSystemTimeConstraint(_) => "period_for_system_time_constraint",
2355            Expression::CaseSpecificColumnConstraint(_) => "case_specific_column_constraint",
2356            Expression::CharacterSetColumnConstraint(_) => "character_set_column_constraint",
2357            Expression::CheckColumnConstraint(_) => "check_column_constraint",
2358            Expression::AssumeColumnConstraint(_) => "assume_column_constraint",
2359            Expression::CompressColumnConstraint(_) => "compress_column_constraint",
2360            Expression::DateFormatColumnConstraint(_) => "date_format_column_constraint",
2361            Expression::EphemeralColumnConstraint(_) => "ephemeral_column_constraint",
2362            Expression::WithOperator(_) => "with_operator",
2363            Expression::GeneratedAsIdentityColumnConstraint(_) => {
2364                "generated_as_identity_column_constraint"
2365            }
2366            Expression::AutoIncrementColumnConstraint(_) => "auto_increment_column_constraint",
2367            Expression::CommentColumnConstraint(_) => "comment_column_constraint",
2368            Expression::GeneratedAsRowColumnConstraint(_) => "generated_as_row_column_constraint",
2369            Expression::IndexColumnConstraint(_) => "index_column_constraint",
2370            Expression::MaskingPolicyColumnConstraint(_) => "masking_policy_column_constraint",
2371            Expression::NotNullColumnConstraint(_) => "not_null_column_constraint",
2372            Expression::PrimaryKeyColumnConstraint(_) => "primary_key_column_constraint",
2373            Expression::UniqueColumnConstraint(_) => "unique_column_constraint",
2374            Expression::WatermarkColumnConstraint(_) => "watermark_column_constraint",
2375            Expression::ComputedColumnConstraint(_) => "computed_column_constraint",
2376            Expression::InOutColumnConstraint(_) => "in_out_column_constraint",
2377            Expression::DefaultColumnConstraint(_) => "default_column_constraint",
2378            Expression::PathColumnConstraint(_) => "path_column_constraint",
2379            Expression::Constraint(_) => "constraint",
2380            Expression::Export(_) => "export",
2381            Expression::Filter(_) => "filter",
2382            Expression::Changes(_) => "changes",
2383            Expression::CopyParameter(_) => "copy_parameter",
2384            Expression::Credentials(_) => "credentials",
2385            Expression::Directory(_) => "directory",
2386            Expression::ForeignKey(_) => "foreign_key",
2387            Expression::ColumnPrefix(_) => "column_prefix",
2388            Expression::PrimaryKey(_) => "primary_key",
2389            Expression::IntoClause(_) => "into_clause",
2390            Expression::JoinHint(_) => "join_hint",
2391            Expression::Opclass(_) => "opclass",
2392            Expression::Index(_) => "index",
2393            Expression::IndexParameters(_) => "index_parameters",
2394            Expression::ConditionalInsert(_) => "conditional_insert",
2395            Expression::MultitableInserts(_) => "multitable_inserts",
2396            Expression::OnConflict(_) => "on_conflict",
2397            Expression::OnCondition(_) => "on_condition",
2398            Expression::Returning(_) => "returning",
2399            Expression::Introducer(_) => "introducer",
2400            Expression::PartitionRange(_) => "partition_range",
2401            Expression::Fetch(_) => "fetch",
2402            Expression::Group(_) => "group",
2403            Expression::Cube(_) => "cube",
2404            Expression::Rollup(_) => "rollup",
2405            Expression::GroupingSets(_) => "grouping_sets",
2406            Expression::LimitOptions(_) => "limit_options",
2407            Expression::Lateral(_) => "lateral",
2408            Expression::TableFromRows(_) => "table_from_rows",
2409            Expression::RowsFrom(_) => "rows_from",
2410            Expression::MatchRecognizeMeasure(_) => "match_recognize_measure",
2411            Expression::WithFill(_) => "with_fill",
2412            Expression::Property(_) => "property",
2413            Expression::GrantPrivilege(_) => "grant_privilege",
2414            Expression::GrantPrincipal(_) => "grant_principal",
2415            Expression::AllowedValuesProperty(_) => "allowed_values_property",
2416            Expression::AlgorithmProperty(_) => "algorithm_property",
2417            Expression::AutoIncrementProperty(_) => "auto_increment_property",
2418            Expression::AutoRefreshProperty(_) => "auto_refresh_property",
2419            Expression::BackupProperty(_) => "backup_property",
2420            Expression::BuildProperty(_) => "build_property",
2421            Expression::BlockCompressionProperty(_) => "block_compression_property",
2422            Expression::CharacterSetProperty(_) => "character_set_property",
2423            Expression::ChecksumProperty(_) => "checksum_property",
2424            Expression::CollateProperty(_) => "collate_property",
2425            Expression::DataBlocksizeProperty(_) => "data_blocksize_property",
2426            Expression::DataDeletionProperty(_) => "data_deletion_property",
2427            Expression::DefinerProperty(_) => "definer_property",
2428            Expression::DistKeyProperty(_) => "dist_key_property",
2429            Expression::DistributedByProperty(_) => "distributed_by_property",
2430            Expression::DistStyleProperty(_) => "dist_style_property",
2431            Expression::DuplicateKeyProperty(_) => "duplicate_key_property",
2432            Expression::EngineProperty(_) => "engine_property",
2433            Expression::ToTableProperty(_) => "to_table_property",
2434            Expression::ExecuteAsProperty(_) => "execute_as_property",
2435            Expression::ExternalProperty(_) => "external_property",
2436            Expression::FallbackProperty(_) => "fallback_property",
2437            Expression::FileFormatProperty(_) => "file_format_property",
2438            Expression::CredentialsProperty(_) => "credentials_property",
2439            Expression::FreespaceProperty(_) => "freespace_property",
2440            Expression::InheritsProperty(_) => "inherits_property",
2441            Expression::InputModelProperty(_) => "input_model_property",
2442            Expression::OutputModelProperty(_) => "output_model_property",
2443            Expression::IsolatedLoadingProperty(_) => "isolated_loading_property",
2444            Expression::JournalProperty(_) => "journal_property",
2445            Expression::LanguageProperty(_) => "language_property",
2446            Expression::EnviromentProperty(_) => "enviroment_property",
2447            Expression::ClusteredByProperty(_) => "clustered_by_property",
2448            Expression::DictProperty(_) => "dict_property",
2449            Expression::DictRange(_) => "dict_range",
2450            Expression::OnCluster(_) => "on_cluster",
2451            Expression::LikeProperty(_) => "like_property",
2452            Expression::LocationProperty(_) => "location_property",
2453            Expression::LockProperty(_) => "lock_property",
2454            Expression::LockingProperty(_) => "locking_property",
2455            Expression::LogProperty(_) => "log_property",
2456            Expression::MaterializedProperty(_) => "materialized_property",
2457            Expression::MergeBlockRatioProperty(_) => "merge_block_ratio_property",
2458            Expression::OnProperty(_) => "on_property",
2459            Expression::OnCommitProperty(_) => "on_commit_property",
2460            Expression::PartitionedByProperty(_) => "partitioned_by_property",
2461            Expression::PartitionByProperty(_) => "partition_by_property",
2462            Expression::PartitionedByBucket(_) => "partitioned_by_bucket",
2463            Expression::ClusterByColumnsProperty(_) => "cluster_by_columns_property",
2464            Expression::PartitionByTruncate(_) => "partition_by_truncate",
2465            Expression::PartitionByRangeProperty(_) => "partition_by_range_property",
2466            Expression::PartitionByRangePropertyDynamic(_) => "partition_by_range_property_dynamic",
2467            Expression::PartitionByListProperty(_) => "partition_by_list_property",
2468            Expression::PartitionList(_) => "partition_list",
2469            Expression::Partition(_) => "partition",
2470            Expression::RefreshTriggerProperty(_) => "refresh_trigger_property",
2471            Expression::UniqueKeyProperty(_) => "unique_key_property",
2472            Expression::RollupProperty(_) => "rollup_property",
2473            Expression::PartitionBoundSpec(_) => "partition_bound_spec",
2474            Expression::PartitionedOfProperty(_) => "partitioned_of_property",
2475            Expression::RemoteWithConnectionModelProperty(_) => {
2476                "remote_with_connection_model_property"
2477            }
2478            Expression::ReturnsProperty(_) => "returns_property",
2479            Expression::RowFormatProperty(_) => "row_format_property",
2480            Expression::RowFormatDelimitedProperty(_) => "row_format_delimited_property",
2481            Expression::RowFormatSerdeProperty(_) => "row_format_serde_property",
2482            Expression::QueryTransform(_) => "query_transform",
2483            Expression::SampleProperty(_) => "sample_property",
2484            Expression::SecurityProperty(_) => "security_property",
2485            Expression::SchemaCommentProperty(_) => "schema_comment_property",
2486            Expression::SemanticView(_) => "semantic_view",
2487            Expression::SerdeProperties(_) => "serde_properties",
2488            Expression::SetProperty(_) => "set_property",
2489            Expression::SharingProperty(_) => "sharing_property",
2490            Expression::SetConfigProperty(_) => "set_config_property",
2491            Expression::SettingsProperty(_) => "settings_property",
2492            Expression::SortKeyProperty(_) => "sort_key_property",
2493            Expression::SqlReadWriteProperty(_) => "sql_read_write_property",
2494            Expression::SqlSecurityProperty(_) => "sql_security_property",
2495            Expression::StabilityProperty(_) => "stability_property",
2496            Expression::StorageHandlerProperty(_) => "storage_handler_property",
2497            Expression::TemporaryProperty(_) => "temporary_property",
2498            Expression::Tags(_) => "tags",
2499            Expression::TransformModelProperty(_) => "transform_model_property",
2500            Expression::TransientProperty(_) => "transient_property",
2501            Expression::UsingTemplateProperty(_) => "using_template_property",
2502            Expression::ViewAttributeProperty(_) => "view_attribute_property",
2503            Expression::VolatileProperty(_) => "volatile_property",
2504            Expression::WithDataProperty(_) => "with_data_property",
2505            Expression::WithJournalTableProperty(_) => "with_journal_table_property",
2506            Expression::WithSchemaBindingProperty(_) => "with_schema_binding_property",
2507            Expression::WithSystemVersioningProperty(_) => "with_system_versioning_property",
2508            Expression::WithProcedureOptions(_) => "with_procedure_options",
2509            Expression::EncodeProperty(_) => "encode_property",
2510            Expression::IncludeProperty(_) => "include_property",
2511            Expression::Properties(_) => "properties",
2512            Expression::OptionsProperty(_) => "options_property",
2513            Expression::InputOutputFormat(_) => "input_output_format",
2514            Expression::Reference(_) => "reference",
2515            Expression::QueryOption(_) => "query_option",
2516            Expression::WithTableHint(_) => "with_table_hint",
2517            Expression::IndexTableHint(_) => "index_table_hint",
2518            Expression::HistoricalData(_) => "historical_data",
2519            Expression::Get(_) => "get",
2520            Expression::SetOperation(_) => "set_operation",
2521            Expression::Var(_) => "var",
2522            Expression::Variadic(_) => "variadic",
2523            Expression::Version(_) => "version",
2524            Expression::Schema(_) => "schema",
2525            Expression::Lock(_) => "lock",
2526            Expression::TableSample(_) => "table_sample",
2527            Expression::Tag(_) => "tag",
2528            Expression::UnpivotColumns(_) => "unpivot_columns",
2529            Expression::WindowSpec(_) => "window_spec",
2530            Expression::SessionParameter(_) => "session_parameter",
2531            Expression::PseudoType(_) => "pseudo_type",
2532            Expression::ObjectIdentifier(_) => "object_identifier",
2533            Expression::Transaction(_) => "transaction",
2534            Expression::Commit(_) => "commit",
2535            Expression::Rollback(_) => "rollback",
2536            Expression::AlterSession(_) => "alter_session",
2537            Expression::Analyze(_) => "analyze",
2538            Expression::AnalyzeStatistics(_) => "analyze_statistics",
2539            Expression::AnalyzeHistogram(_) => "analyze_histogram",
2540            Expression::AnalyzeSample(_) => "analyze_sample",
2541            Expression::AnalyzeListChainedRows(_) => "analyze_list_chained_rows",
2542            Expression::AnalyzeDelete(_) => "analyze_delete",
2543            Expression::AnalyzeWith(_) => "analyze_with",
2544            Expression::AnalyzeValidate(_) => "analyze_validate",
2545            Expression::AddPartition(_) => "add_partition",
2546            Expression::AttachOption(_) => "attach_option",
2547            Expression::DropPartition(_) => "drop_partition",
2548            Expression::ReplacePartition(_) => "replace_partition",
2549            Expression::DPipe(_) => "d_pipe",
2550            Expression::Operator(_) => "operator",
2551            Expression::PivotAny(_) => "pivot_any",
2552            Expression::Aliases(_) => "aliases",
2553            Expression::AtIndex(_) => "at_index",
2554            Expression::FromTimeZone(_) => "from_time_zone",
2555            Expression::FormatPhrase(_) => "format_phrase",
2556            Expression::ForIn(_) => "for_in",
2557            Expression::TimeUnit(_) => "time_unit",
2558            Expression::IntervalOp(_) => "interval_op",
2559            Expression::IntervalSpan(_) => "interval_span",
2560            Expression::HavingMax(_) => "having_max",
2561            Expression::CosineDistance(_) => "cosine_distance",
2562            Expression::DotProduct(_) => "dot_product",
2563            Expression::EuclideanDistance(_) => "euclidean_distance",
2564            Expression::ManhattanDistance(_) => "manhattan_distance",
2565            Expression::JarowinklerSimilarity(_) => "jarowinkler_similarity",
2566            Expression::Booland(_) => "booland",
2567            Expression::Boolor(_) => "boolor",
2568            Expression::ParameterizedAgg(_) => "parameterized_agg",
2569            Expression::ArgMax(_) => "arg_max",
2570            Expression::ArgMin(_) => "arg_min",
2571            Expression::ApproxTopK(_) => "approx_top_k",
2572            Expression::ApproxTopKAccumulate(_) => "approx_top_k_accumulate",
2573            Expression::ApproxTopKCombine(_) => "approx_top_k_combine",
2574            Expression::ApproxTopKEstimate(_) => "approx_top_k_estimate",
2575            Expression::ApproxTopSum(_) => "approx_top_sum",
2576            Expression::ApproxQuantiles(_) => "approx_quantiles",
2577            Expression::Minhash(_) => "minhash",
2578            Expression::FarmFingerprint(_) => "farm_fingerprint",
2579            Expression::Float64(_) => "float64",
2580            Expression::Transform(_) => "transform",
2581            Expression::Translate(_) => "translate",
2582            Expression::Grouping(_) => "grouping",
2583            Expression::GroupingId(_) => "grouping_id",
2584            Expression::Anonymous(_) => "anonymous",
2585            Expression::AnonymousAggFunc(_) => "anonymous_agg_func",
2586            Expression::CombinedAggFunc(_) => "combined_agg_func",
2587            Expression::CombinedParameterizedAgg(_) => "combined_parameterized_agg",
2588            Expression::HashAgg(_) => "hash_agg",
2589            Expression::Hll(_) => "hll",
2590            Expression::Apply(_) => "apply",
2591            Expression::ToBoolean(_) => "to_boolean",
2592            Expression::List(_) => "list",
2593            Expression::ToMap(_) => "to_map",
2594            Expression::Pad(_) => "pad",
2595            Expression::ToChar(_) => "to_char",
2596            Expression::ToNumber(_) => "to_number",
2597            Expression::ToDouble(_) => "to_double",
2598            Expression::Int64(_) => "int64",
2599            Expression::StringFunc(_) => "string_func",
2600            Expression::ToDecfloat(_) => "to_decfloat",
2601            Expression::TryToDecfloat(_) => "try_to_decfloat",
2602            Expression::ToFile(_) => "to_file",
2603            Expression::Columns(_) => "columns",
2604            Expression::ConvertToCharset(_) => "convert_to_charset",
2605            Expression::ConvertTimezone(_) => "convert_timezone",
2606            Expression::GenerateSeries(_) => "generate_series",
2607            Expression::AIAgg(_) => "a_i_agg",
2608            Expression::AIClassify(_) => "a_i_classify",
2609            Expression::ArrayAll(_) => "array_all",
2610            Expression::ArrayAny(_) => "array_any",
2611            Expression::ArrayConstructCompact(_) => "array_construct_compact",
2612            Expression::StPoint(_) => "st_point",
2613            Expression::StDistance(_) => "st_distance",
2614            Expression::StringToArray(_) => "string_to_array",
2615            Expression::ArraySum(_) => "array_sum",
2616            Expression::ObjectAgg(_) => "object_agg",
2617            Expression::CastToStrType(_) => "cast_to_str_type",
2618            Expression::CheckJson(_) => "check_json",
2619            Expression::CheckXml(_) => "check_xml",
2620            Expression::TranslateCharacters(_) => "translate_characters",
2621            Expression::CurrentSchemas(_) => "current_schemas",
2622            Expression::CurrentDatetime(_) => "current_datetime",
2623            Expression::Localtime(_) => "localtime",
2624            Expression::Localtimestamp(_) => "localtimestamp",
2625            Expression::Systimestamp(_) => "systimestamp",
2626            Expression::CurrentSchema(_) => "current_schema",
2627            Expression::CurrentUser(_) => "current_user",
2628            Expression::UtcTime(_) => "utc_time",
2629            Expression::UtcTimestamp(_) => "utc_timestamp",
2630            Expression::Timestamp(_) => "timestamp",
2631            Expression::DateBin(_) => "date_bin",
2632            Expression::Datetime(_) => "datetime",
2633            Expression::DatetimeAdd(_) => "datetime_add",
2634            Expression::DatetimeSub(_) => "datetime_sub",
2635            Expression::DatetimeDiff(_) => "datetime_diff",
2636            Expression::DatetimeTrunc(_) => "datetime_trunc",
2637            Expression::Dayname(_) => "dayname",
2638            Expression::MakeInterval(_) => "make_interval",
2639            Expression::PreviousDay(_) => "previous_day",
2640            Expression::Elt(_) => "elt",
2641            Expression::TimestampAdd(_) => "timestamp_add",
2642            Expression::TimestampSub(_) => "timestamp_sub",
2643            Expression::TimestampDiff(_) => "timestamp_diff",
2644            Expression::TimeSlice(_) => "time_slice",
2645            Expression::TimeAdd(_) => "time_add",
2646            Expression::TimeSub(_) => "time_sub",
2647            Expression::TimeDiff(_) => "time_diff",
2648            Expression::TimeTrunc(_) => "time_trunc",
2649            Expression::DateFromParts(_) => "date_from_parts",
2650            Expression::TimeFromParts(_) => "time_from_parts",
2651            Expression::DecodeCase(_) => "decode_case",
2652            Expression::Decrypt(_) => "decrypt",
2653            Expression::DecryptRaw(_) => "decrypt_raw",
2654            Expression::Encode(_) => "encode",
2655            Expression::Encrypt(_) => "encrypt",
2656            Expression::EncryptRaw(_) => "encrypt_raw",
2657            Expression::EqualNull(_) => "equal_null",
2658            Expression::ToBinary(_) => "to_binary",
2659            Expression::Base64DecodeBinary(_) => "base64_decode_binary",
2660            Expression::Base64DecodeString(_) => "base64_decode_string",
2661            Expression::Base64Encode(_) => "base64_encode",
2662            Expression::TryBase64DecodeBinary(_) => "try_base64_decode_binary",
2663            Expression::TryBase64DecodeString(_) => "try_base64_decode_string",
2664            Expression::GapFill(_) => "gap_fill",
2665            Expression::GenerateDateArray(_) => "generate_date_array",
2666            Expression::GenerateTimestampArray(_) => "generate_timestamp_array",
2667            Expression::GetExtract(_) => "get_extract",
2668            Expression::Getbit(_) => "getbit",
2669            Expression::OverflowTruncateBehavior(_) => "overflow_truncate_behavior",
2670            Expression::HexEncode(_) => "hex_encode",
2671            Expression::Compress(_) => "compress",
2672            Expression::DecompressBinary(_) => "decompress_binary",
2673            Expression::DecompressString(_) => "decompress_string",
2674            Expression::Xor(_) => "xor",
2675            Expression::Nullif(_) => "nullif",
2676            Expression::JSON(_) => "j_s_o_n",
2677            Expression::JSONPath(_) => "j_s_o_n_path",
2678            Expression::JSONPathFilter(_) => "j_s_o_n_path_filter",
2679            Expression::JSONPathKey(_) => "j_s_o_n_path_key",
2680            Expression::JSONPathRecursive(_) => "j_s_o_n_path_recursive",
2681            Expression::JSONPathScript(_) => "j_s_o_n_path_script",
2682            Expression::JSONPathSlice(_) => "j_s_o_n_path_slice",
2683            Expression::JSONPathSelector(_) => "j_s_o_n_path_selector",
2684            Expression::JSONPathSubscript(_) => "j_s_o_n_path_subscript",
2685            Expression::JSONPathUnion(_) => "j_s_o_n_path_union",
2686            Expression::Format(_) => "format",
2687            Expression::JSONKeys(_) => "j_s_o_n_keys",
2688            Expression::JSONKeyValue(_) => "j_s_o_n_key_value",
2689            Expression::JSONKeysAtDepth(_) => "j_s_o_n_keys_at_depth",
2690            Expression::JSONObject(_) => "j_s_o_n_object",
2691            Expression::JSONObjectAgg(_) => "j_s_o_n_object_agg",
2692            Expression::JSONBObjectAgg(_) => "j_s_o_n_b_object_agg",
2693            Expression::JSONArray(_) => "j_s_o_n_array",
2694            Expression::JSONArrayAgg(_) => "j_s_o_n_array_agg",
2695            Expression::JSONExists(_) => "j_s_o_n_exists",
2696            Expression::JSONColumnDef(_) => "j_s_o_n_column_def",
2697            Expression::JSONSchema(_) => "j_s_o_n_schema",
2698            Expression::JSONSet(_) => "j_s_o_n_set",
2699            Expression::JSONStripNulls(_) => "j_s_o_n_strip_nulls",
2700            Expression::JSONValue(_) => "j_s_o_n_value",
2701            Expression::JSONValueArray(_) => "j_s_o_n_value_array",
2702            Expression::JSONRemove(_) => "j_s_o_n_remove",
2703            Expression::JSONTable(_) => "j_s_o_n_table",
2704            Expression::JSONType(_) => "j_s_o_n_type",
2705            Expression::ObjectInsert(_) => "object_insert",
2706            Expression::OpenJSONColumnDef(_) => "open_j_s_o_n_column_def",
2707            Expression::OpenJSON(_) => "open_j_s_o_n",
2708            Expression::JSONBExists(_) => "j_s_o_n_b_exists",
2709            Expression::JSONBContains(_) => "j_s_o_n_b_contains",
2710            Expression::JSONBExtract(_) => "j_s_o_n_b_extract",
2711            Expression::JSONCast(_) => "j_s_o_n_cast",
2712            Expression::JSONExtract(_) => "j_s_o_n_extract",
2713            Expression::JSONExtractQuote(_) => "j_s_o_n_extract_quote",
2714            Expression::JSONExtractArray(_) => "j_s_o_n_extract_array",
2715            Expression::JSONExtractScalar(_) => "j_s_o_n_extract_scalar",
2716            Expression::JSONBExtractScalar(_) => "j_s_o_n_b_extract_scalar",
2717            Expression::JSONFormat(_) => "j_s_o_n_format",
2718            Expression::JSONBool(_) => "j_s_o_n_bool",
2719            Expression::JSONPathRoot(_) => "j_s_o_n_path_root",
2720            Expression::JSONArrayAppend(_) => "j_s_o_n_array_append",
2721            Expression::JSONArrayContains(_) => "j_s_o_n_array_contains",
2722            Expression::JSONArrayInsert(_) => "j_s_o_n_array_insert",
2723            Expression::ParseJSON(_) => "parse_j_s_o_n",
2724            Expression::ParseUrl(_) => "parse_url",
2725            Expression::ParseIp(_) => "parse_ip",
2726            Expression::ParseTime(_) => "parse_time",
2727            Expression::ParseDatetime(_) => "parse_datetime",
2728            Expression::Map(_) => "map",
2729            Expression::MapCat(_) => "map_cat",
2730            Expression::MapDelete(_) => "map_delete",
2731            Expression::MapInsert(_) => "map_insert",
2732            Expression::MapPick(_) => "map_pick",
2733            Expression::ScopeResolution(_) => "scope_resolution",
2734            Expression::Slice(_) => "slice",
2735            Expression::VarMap(_) => "var_map",
2736            Expression::MatchAgainst(_) => "match_against",
2737            Expression::MD5Digest(_) => "m_d5_digest",
2738            Expression::MD5NumberLower64(_) => "m_d5_number_lower64",
2739            Expression::MD5NumberUpper64(_) => "m_d5_number_upper64",
2740            Expression::Monthname(_) => "monthname",
2741            Expression::Ntile(_) => "ntile",
2742            Expression::Normalize(_) => "normalize",
2743            Expression::Normal(_) => "normal",
2744            Expression::Predict(_) => "predict",
2745            Expression::MLTranslate(_) => "m_l_translate",
2746            Expression::FeaturesAtTime(_) => "features_at_time",
2747            Expression::GenerateEmbedding(_) => "generate_embedding",
2748            Expression::MLForecast(_) => "m_l_forecast",
2749            Expression::ModelAttribute(_) => "model_attribute",
2750            Expression::VectorSearch(_) => "vector_search",
2751            Expression::Quantile(_) => "quantile",
2752            Expression::ApproxQuantile(_) => "approx_quantile",
2753            Expression::ApproxPercentileEstimate(_) => "approx_percentile_estimate",
2754            Expression::Randn(_) => "randn",
2755            Expression::Randstr(_) => "randstr",
2756            Expression::RangeN(_) => "range_n",
2757            Expression::RangeBucket(_) => "range_bucket",
2758            Expression::ReadCSV(_) => "read_c_s_v",
2759            Expression::ReadParquet(_) => "read_parquet",
2760            Expression::Reduce(_) => "reduce",
2761            Expression::RegexpExtractAll(_) => "regexp_extract_all",
2762            Expression::RegexpILike(_) => "regexp_i_like",
2763            Expression::RegexpFullMatch(_) => "regexp_full_match",
2764            Expression::RegexpInstr(_) => "regexp_instr",
2765            Expression::RegexpSplit(_) => "regexp_split",
2766            Expression::RegexpCount(_) => "regexp_count",
2767            Expression::RegrValx(_) => "regr_valx",
2768            Expression::RegrValy(_) => "regr_valy",
2769            Expression::RegrAvgy(_) => "regr_avgy",
2770            Expression::RegrAvgx(_) => "regr_avgx",
2771            Expression::RegrCount(_) => "regr_count",
2772            Expression::RegrIntercept(_) => "regr_intercept",
2773            Expression::RegrR2(_) => "regr_r2",
2774            Expression::RegrSxx(_) => "regr_sxx",
2775            Expression::RegrSxy(_) => "regr_sxy",
2776            Expression::RegrSyy(_) => "regr_syy",
2777            Expression::RegrSlope(_) => "regr_slope",
2778            Expression::SafeAdd(_) => "safe_add",
2779            Expression::SafeDivide(_) => "safe_divide",
2780            Expression::SafeMultiply(_) => "safe_multiply",
2781            Expression::SafeSubtract(_) => "safe_subtract",
2782            Expression::SHA2(_) => "s_h_a2",
2783            Expression::SHA2Digest(_) => "s_h_a2_digest",
2784            Expression::SortArray(_) => "sort_array",
2785            Expression::SplitPart(_) => "split_part",
2786            Expression::SubstringIndex(_) => "substring_index",
2787            Expression::StandardHash(_) => "standard_hash",
2788            Expression::StrPosition(_) => "str_position",
2789            Expression::Search(_) => "search",
2790            Expression::SearchIp(_) => "search_ip",
2791            Expression::StrToDate(_) => "str_to_date",
2792            Expression::DateStrToDate(_) => "date_str_to_date",
2793            Expression::DateToDateStr(_) => "date_to_date_str",
2794            Expression::StrToTime(_) => "str_to_time",
2795            Expression::StrToUnix(_) => "str_to_unix",
2796            Expression::StrToMap(_) => "str_to_map",
2797            Expression::NumberToStr(_) => "number_to_str",
2798            Expression::FromBase(_) => "from_base",
2799            Expression::Stuff(_) => "stuff",
2800            Expression::TimeToStr(_) => "time_to_str",
2801            Expression::TimeStrToTime(_) => "time_str_to_time",
2802            Expression::TsOrDsAdd(_) => "ts_or_ds_add",
2803            Expression::TsOrDsDiff(_) => "ts_or_ds_diff",
2804            Expression::TsOrDsToDate(_) => "ts_or_ds_to_date",
2805            Expression::TsOrDsToTime(_) => "ts_or_ds_to_time",
2806            Expression::Unhex(_) => "unhex",
2807            Expression::Uniform(_) => "uniform",
2808            Expression::UnixToStr(_) => "unix_to_str",
2809            Expression::UnixToTime(_) => "unix_to_time",
2810            Expression::Uuid(_) => "uuid",
2811            Expression::TimestampFromParts(_) => "timestamp_from_parts",
2812            Expression::TimestampTzFromParts(_) => "timestamp_tz_from_parts",
2813            Expression::Corr(_) => "corr",
2814            Expression::WidthBucket(_) => "width_bucket",
2815            Expression::CovarSamp(_) => "covar_samp",
2816            Expression::CovarPop(_) => "covar_pop",
2817            Expression::Week(_) => "week",
2818            Expression::XMLElement(_) => "x_m_l_element",
2819            Expression::XMLGet(_) => "x_m_l_get",
2820            Expression::XMLTable(_) => "x_m_l_table",
2821            Expression::XMLKeyValueOption(_) => "x_m_l_key_value_option",
2822            Expression::Zipf(_) => "zipf",
2823            Expression::Merge(_) => "merge",
2824            Expression::When(_) => "when",
2825            Expression::Whens(_) => "whens",
2826            Expression::NextValueFor(_) => "next_value_for",
2827            Expression::ReturnStmt(_) => "return_stmt",
2828        }
2829    }
2830
2831    /// Returns the primary child expression (".this" in sqlglot).
2832    pub fn get_this(&self) -> Option<&Expression> {
2833        match self {
2834            Expression::JSONValue(j) => Some(&j.this),
2835            Expression::JSONTable(j) => Some(&j.this),
2836            Expression::JSONColumnDef(j) => j.this.as_deref(),
2837            Expression::Hierarchy(hierarchy) => Some(&hierarchy.source),
2838            Expression::Upsert(upsert) => Some(&upsert.source),
2839            // Unary ops
2840            Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this),
2841            // UnaryFunc variants
2842            Expression::Upper(f)
2843            | Expression::Lower(f)
2844            | Expression::Length(f)
2845            | Expression::LTrim(f)
2846            | Expression::RTrim(f)
2847            | Expression::Reverse(f)
2848            | Expression::Abs(f)
2849            | Expression::Sqrt(f)
2850            | Expression::Cbrt(f)
2851            | Expression::Ln(f)
2852            | Expression::Exp(f)
2853            | Expression::Sign(f)
2854            | Expression::Date(f)
2855            | Expression::Time(f)
2856            | Expression::Initcap(f)
2857            | Expression::Ascii(f)
2858            | Expression::Chr(f)
2859            | Expression::Soundex(f)
2860            | Expression::ByteLength(f)
2861            | Expression::Hex(f)
2862            | Expression::LowerHex(f)
2863            | Expression::Unicode(f)
2864            | Expression::Typeof(f)
2865            | Expression::Explode(f)
2866            | Expression::ExplodeOuter(f)
2867            | Expression::MapFromEntries(f)
2868            | Expression::MapKeys(f)
2869            | Expression::MapValues(f)
2870            | Expression::ArrayLength(f)
2871            | Expression::ArraySize(f)
2872            | Expression::Cardinality(f)
2873            | Expression::ArrayReverse(f)
2874            | Expression::ArrayDistinct(f)
2875            | Expression::ArrayFlatten(f)
2876            | Expression::ArrayCompact(f)
2877            | Expression::ToArray(f)
2878            | Expression::JsonArrayLength(f)
2879            | Expression::JsonKeys(f)
2880            | Expression::JsonType(f)
2881            | Expression::ParseJson(f)
2882            | Expression::ToJson(f)
2883            | Expression::Radians(f)
2884            | Expression::Degrees(f)
2885            | Expression::Sin(f)
2886            | Expression::Cos(f)
2887            | Expression::Tan(f)
2888            | Expression::Asin(f)
2889            | Expression::Acos(f)
2890            | Expression::Atan(f)
2891            | Expression::IsNan(f)
2892            | Expression::IsInf(f)
2893            | Expression::Year(f)
2894            | Expression::Month(f)
2895            | Expression::Day(f)
2896            | Expression::Hour(f)
2897            | Expression::Minute(f)
2898            | Expression::Second(f)
2899            | Expression::DayOfWeek(f)
2900            | Expression::DayOfWeekIso(f)
2901            | Expression::DayOfMonth(f)
2902            | Expression::DayOfYear(f)
2903            | Expression::WeekOfYear(f)
2904            | Expression::Quarter(f)
2905            | Expression::Epoch(f)
2906            | Expression::EpochMs(f)
2907            | Expression::BitwiseCount(f)
2908            | Expression::DateFromUnixDate(f)
2909            | Expression::UnixDate(f)
2910            | Expression::UnixSeconds(f)
2911            | Expression::UnixMillis(f)
2912            | Expression::UnixMicros(f)
2913            | Expression::TimeStrToDate(f)
2914            | Expression::DateToDi(f)
2915            | Expression::DiToDate(f)
2916            | Expression::TsOrDiToDi(f)
2917            | Expression::TsOrDsToDatetime(f)
2918            | Expression::TsOrDsToTimestamp(f)
2919            | Expression::YearOfWeek(f)
2920            | Expression::YearOfWeekIso(f)
2921            | Expression::SHA(f)
2922            | Expression::SHA1Digest(f)
2923            | Expression::TimeToUnix(f)
2924            | Expression::TimeStrToUnix(f)
2925            | Expression::Int64(f)
2926            | Expression::JSONBool(f)
2927            | Expression::MD5NumberLower64(f)
2928            | Expression::MD5NumberUpper64(f)
2929            | Expression::DateStrToDate(f)
2930            | Expression::DateToDateStr(f) => Some(&f.this),
2931            // BinaryFunc - this is the primary child
2932            Expression::Power(f)
2933            | Expression::NullIf(f)
2934            | Expression::IfNull(f)
2935            | Expression::Nvl(f)
2936            | Expression::Contains(f)
2937            | Expression::StartsWith(f)
2938            | Expression::EndsWith(f)
2939            | Expression::Levenshtein(f)
2940            | Expression::ModFunc(f)
2941            | Expression::IntDiv(f)
2942            | Expression::Atan2(f)
2943            | Expression::AddMonths(f)
2944            | Expression::MonthsBetween(f)
2945            | Expression::NextDay(f)
2946            | Expression::UnixToTimeStr(f)
2947            | Expression::ArrayContains(f)
2948            | Expression::ArrayPosition(f)
2949            | Expression::ArrayAppend(f)
2950            | Expression::ArrayPrepend(f)
2951            | Expression::ArrayUnion(f)
2952            | Expression::ArrayExcept(f)
2953            | Expression::ArrayRemove(f)
2954            | Expression::StarMap(f)
2955            | Expression::MapFromArrays(f)
2956            | Expression::MapContainsKey(f)
2957            | Expression::ElementAt(f)
2958            | Expression::JsonMergePatch(f)
2959            | Expression::JSONBContains(f)
2960            | Expression::JSONBExtract(f) => Some(&f.this),
2961            // AggFunc - this is the primary child
2962            Expression::Sum(af)
2963            | Expression::Avg(af)
2964            | Expression::Min(af)
2965            | Expression::Max(af)
2966            | Expression::ArrayAgg(af)
2967            | Expression::CountIf(af)
2968            | Expression::Stddev(af)
2969            | Expression::StddevPop(af)
2970            | Expression::StddevSamp(af)
2971            | Expression::Variance(af)
2972            | Expression::VarPop(af)
2973            | Expression::VarSamp(af)
2974            | Expression::Median(af)
2975            | Expression::Mode(af)
2976            | Expression::First(af)
2977            | Expression::Last(af)
2978            | Expression::AnyValue(af)
2979            | Expression::ApproxDistinct(af)
2980            | Expression::ApproxCountDistinct(af)
2981            | Expression::LogicalAnd(af)
2982            | Expression::LogicalOr(af)
2983            | Expression::Skewness(af)
2984            | Expression::ArrayConcatAgg(af)
2985            | Expression::ArrayUniqueAgg(af)
2986            | Expression::BoolXorAgg(af)
2987            | Expression::BitwiseAndAgg(af)
2988            | Expression::BitwiseOrAgg(af)
2989            | Expression::BitwiseXorAgg(af) => Some(&af.this),
2990            // Binary operations - left is "this" in sqlglot
2991            Expression::And(op)
2992            | Expression::Or(op)
2993            | Expression::Add(op)
2994            | Expression::Sub(op)
2995            | Expression::Mul(op)
2996            | Expression::Div(op)
2997            | Expression::Mod(op)
2998            | Expression::Eq(op)
2999            | Expression::Neq(op)
3000            | Expression::Lt(op)
3001            | Expression::Lte(op)
3002            | Expression::Gt(op)
3003            | Expression::Gte(op)
3004            | Expression::BitwiseAnd(op)
3005            | Expression::BitwiseOr(op)
3006            | Expression::BitwiseXor(op)
3007            | Expression::Concat(op)
3008            | Expression::Adjacent(op)
3009            | Expression::TsMatch(op)
3010            | Expression::PropertyEQ(op)
3011            | Expression::ArrayContainsAll(op)
3012            | Expression::ArrayContainedBy(op)
3013            | Expression::ArrayOverlaps(op)
3014            | Expression::JSONBContainsAllTopKeys(op)
3015            | Expression::JSONBContainsAnyTopKeys(op)
3016            | Expression::JSONBDeleteAtPath(op)
3017            | Expression::ExtendsLeft(op)
3018            | Expression::ExtendsRight(op)
3019            | Expression::Is(op)
3020            | Expression::MemberOf(op)
3021            | Expression::Match(op)
3022            | Expression::NullSafeEq(op)
3023            | Expression::NullSafeNeq(op)
3024            | Expression::Glob(op)
3025            | Expression::BitwiseLeftShift(op)
3026            | Expression::BitwiseRightShift(op) => Some(&op.left),
3027            // Like operations - left is "this"
3028            Expression::Like(op) | Expression::ILike(op) => Some(&op.left),
3029            // Structural types with .this
3030            Expression::Alias(a) => Some(&a.this),
3031            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => Some(&c.this),
3032            Expression::Paren(p) => Some(&p.this),
3033            Expression::Annotated(a) => Some(&a.this),
3034            Expression::Subquery(s) => Some(&s.this),
3035            Expression::Where(w) => Some(&w.this),
3036            Expression::Having(h) => Some(&h.this),
3037            Expression::Qualify(q) => Some(&q.this),
3038            Expression::IsNull(i) => Some(&i.this),
3039            Expression::Exists(e) => Some(&e.this),
3040            Expression::Ordered(o) => Some(&o.this),
3041            Expression::WindowFunction(wf) => Some(&wf.this),
3042            Expression::Cte(cte) => Some(&cte.this),
3043            Expression::Between(b) => Some(&b.this),
3044            Expression::In(i) => Some(&i.this),
3045            Expression::ReturnStmt(e) => Some(e),
3046            _ => None,
3047        }
3048    }
3049
3050    /// Returns the secondary child expression (".expression" in sqlglot).
3051    pub fn get_expression(&self) -> Option<&Expression> {
3052        match self {
3053            // Binary operations - right is "expression"
3054            Expression::And(op)
3055            | Expression::Or(op)
3056            | Expression::Add(op)
3057            | Expression::Sub(op)
3058            | Expression::Mul(op)
3059            | Expression::Div(op)
3060            | Expression::Mod(op)
3061            | Expression::Eq(op)
3062            | Expression::Neq(op)
3063            | Expression::Lt(op)
3064            | Expression::Lte(op)
3065            | Expression::Gt(op)
3066            | Expression::Gte(op)
3067            | Expression::BitwiseAnd(op)
3068            | Expression::BitwiseOr(op)
3069            | Expression::BitwiseXor(op)
3070            | Expression::Concat(op)
3071            | Expression::Adjacent(op)
3072            | Expression::TsMatch(op)
3073            | Expression::PropertyEQ(op)
3074            | Expression::ArrayContainsAll(op)
3075            | Expression::ArrayContainedBy(op)
3076            | Expression::ArrayOverlaps(op)
3077            | Expression::JSONBContainsAllTopKeys(op)
3078            | Expression::JSONBContainsAnyTopKeys(op)
3079            | Expression::JSONBDeleteAtPath(op)
3080            | Expression::ExtendsLeft(op)
3081            | Expression::ExtendsRight(op)
3082            | Expression::Is(op)
3083            | Expression::MemberOf(op)
3084            | Expression::Match(op)
3085            | Expression::NullSafeEq(op)
3086            | Expression::NullSafeNeq(op)
3087            | Expression::Glob(op)
3088            | Expression::BitwiseLeftShift(op)
3089            | Expression::BitwiseRightShift(op) => Some(&op.right),
3090            // Like operations - right is "expression"
3091            Expression::Like(op) | Expression::ILike(op) => Some(&op.right),
3092            // BinaryFunc - expression is the secondary
3093            Expression::Power(f)
3094            | Expression::NullIf(f)
3095            | Expression::IfNull(f)
3096            | Expression::Nvl(f)
3097            | Expression::Contains(f)
3098            | Expression::StartsWith(f)
3099            | Expression::EndsWith(f)
3100            | Expression::Levenshtein(f)
3101            | Expression::ModFunc(f)
3102            | Expression::IntDiv(f)
3103            | Expression::Atan2(f)
3104            | Expression::AddMonths(f)
3105            | Expression::MonthsBetween(f)
3106            | Expression::NextDay(f)
3107            | Expression::UnixToTimeStr(f)
3108            | Expression::ArrayContains(f)
3109            | Expression::ArrayPosition(f)
3110            | Expression::ArrayAppend(f)
3111            | Expression::ArrayPrepend(f)
3112            | Expression::ArrayUnion(f)
3113            | Expression::ArrayExcept(f)
3114            | Expression::ArrayRemove(f)
3115            | Expression::StarMap(f)
3116            | Expression::MapFromArrays(f)
3117            | Expression::MapContainsKey(f)
3118            | Expression::ElementAt(f)
3119            | Expression::JsonMergePatch(f)
3120            | Expression::JSONBContains(f)
3121            | Expression::JSONBExtract(f) => Some(&f.expression),
3122            _ => None,
3123        }
3124    }
3125
3126    /// Returns the list of child expressions (".expressions" in sqlglot).
3127    pub fn get_expressions(&self) -> &[Expression] {
3128        match self {
3129            Expression::Select(s) => &s.expressions,
3130            Expression::Function(f) => &f.args,
3131            Expression::AggregateFunction(f) => &f.args,
3132            Expression::Call(f) => &f.arguments,
3133            Expression::From(f) => &f.expressions,
3134            Expression::GroupBy(g) => &g.expressions,
3135            Expression::In(i) => &i.expressions,
3136            Expression::Array(a) => &a.expressions,
3137            Expression::ArrayFunc(a) => &a.expressions,
3138            Expression::Tuple(t) => &t.expressions,
3139            Expression::Coalesce(f)
3140            | Expression::Greatest(f)
3141            | Expression::Least(f)
3142            | Expression::ArrayConcat(f)
3143            | Expression::ArrayIntersect(f)
3144            | Expression::ArrayZip(f)
3145            | Expression::MapConcat(f)
3146            | Expression::JsonArray(f) => &f.expressions,
3147            _ => &[],
3148        }
3149    }
3150
3151    /// Returns the name of this expression as a string slice.
3152    pub fn get_name(&self) -> &str {
3153        match self {
3154            Expression::JSONValue(_) => "JSON_VALUE",
3155            Expression::JSONTable(_) => "JSON_TABLE",
3156            Expression::JsonQuery(_) => "JSON_QUERY",
3157            Expression::Identifier(id) => &id.name,
3158            Expression::Column(col) => &col.name.name,
3159            Expression::Table(t) => &t.name.name,
3160            Expression::Literal(lit) => lit.value_str(),
3161            Expression::Star(_) => "*",
3162            Expression::Function(f) => &f.name,
3163            Expression::AggregateFunction(f) => &f.name,
3164            Expression::Hierarchy(h) => &h.name,
3165            Expression::Alias(a) => a.this.get_name(),
3166            Expression::Boolean(b) => {
3167                if b.value {
3168                    "TRUE"
3169                } else {
3170                    "FALSE"
3171                }
3172            }
3173            Expression::Null(_) => "NULL",
3174            _ => "",
3175        }
3176    }
3177
3178    /// Returns the alias name if this expression has one.
3179    pub fn get_alias(&self) -> &str {
3180        match self {
3181            Expression::Alias(a) => &a.alias.name,
3182            Expression::Table(t) => t.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3183            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3184            _ => "",
3185        }
3186    }
3187
3188    /// Returns the output name of this expression (what it shows up as in a SELECT).
3189    pub fn get_output_name(&self) -> &str {
3190        match self {
3191            Expression::Alias(a) => &a.alias.name,
3192            Expression::Column(c) => &c.name.name,
3193            Expression::Identifier(id) => &id.name,
3194            Expression::Literal(lit) => lit.value_str(),
3195            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3196            Expression::Star(_) => "*",
3197            _ => "",
3198        }
3199    }
3200
3201    /// Returns comments attached to this expression.
3202    pub fn get_comments(&self) -> Vec<&str> {
3203        match self {
3204            Expression::Identifier(id) => id.trailing_comments.iter().map(|s| s.as_str()).collect(),
3205            Expression::Column(c) => c.trailing_comments.iter().map(|s| s.as_str()).collect(),
3206            Expression::Star(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3207            Expression::Paren(p) => p.trailing_comments.iter().map(|s| s.as_str()).collect(),
3208            Expression::Annotated(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3209            Expression::Alias(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3210            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
3211                c.trailing_comments.iter().map(|s| s.as_str()).collect()
3212            }
3213            Expression::And(op)
3214            | Expression::Or(op)
3215            | Expression::Add(op)
3216            | Expression::Sub(op)
3217            | Expression::Mul(op)
3218            | Expression::Div(op)
3219            | Expression::Mod(op)
3220            | Expression::Eq(op)
3221            | Expression::Neq(op)
3222            | Expression::Lt(op)
3223            | Expression::Lte(op)
3224            | Expression::Gt(op)
3225            | Expression::Gte(op)
3226            | Expression::Concat(op)
3227            | Expression::BitwiseAnd(op)
3228            | Expression::BitwiseOr(op)
3229            | Expression::BitwiseXor(op) => {
3230                op.trailing_comments.iter().map(|s| s.as_str()).collect()
3231            }
3232            Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(),
3233            Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3234            _ => Vec::new(),
3235        }
3236    }
3237}
3238
3239impl fmt::Display for Expression {
3240    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3241        // Basic display - full SQL generation is in generator module
3242        match self {
3243            Expression::Literal(lit) => write!(f, "{}", lit),
3244            Expression::Identifier(id) => write!(f, "{}", id),
3245            Expression::Column(col) => write!(f, "{}", col),
3246            Expression::Star(_) => write!(f, "*"),
3247            Expression::Null(_) => write!(f, "NULL"),
3248            Expression::Boolean(b) => write!(f, "{}", if b.value { "TRUE" } else { "FALSE" }),
3249            Expression::Select(_) => write!(f, "SELECT ..."),
3250            _ => write!(f, "{:?}", self),
3251        }
3252    }
3253}
3254
3255/// Represent a SQL literal value.
3256///
3257/// Numeric values are stored as their original text representation (not parsed
3258/// to `i64`/`f64`) so that precision, trailing zeros, and hex notation are
3259/// preserved across round-trips.
3260///
3261/// Dialect-specific literal forms (triple-quoted strings, dollar-quoted
3262/// strings, raw strings, etc.) each have a dedicated variant so that the
3263/// generator can emit them with the correct syntax.
3264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3265#[cfg_attr(feature = "bindings", derive(TS))]
3266#[serde(tag = "literal_type", content = "value", rename_all = "snake_case")]
3267pub enum Literal {
3268    /// Single-quoted string literal: `'hello'`
3269    String(String),
3270    /// Numeric literal, stored as the original text: `42`, `3.14`, `1e10`
3271    Number(String),
3272    /// Hex string literal: `X'FF'`
3273    HexString(String),
3274    /// Hex number: 0xA, 0xFF (BigQuery, SQLite style) - represents an integer in hex notation
3275    HexNumber(String),
3276    BitString(String),
3277    /// Byte string: b"..." (BigQuery style)
3278    ByteString(String),
3279    /// National string: N'abc'
3280    NationalString(String),
3281    /// DATE literal: DATE '2024-01-15'
3282    Date(String),
3283    /// TIME literal: TIME '10:30:00'
3284    Time(String),
3285    /// TIMESTAMP literal: TIMESTAMP '2024-01-15 10:30:00'
3286    Timestamp(String),
3287    /// DATETIME literal: DATETIME '2024-01-15 10:30:00' (BigQuery)
3288    Datetime(String),
3289    /// Triple-quoted string: """...""" or '''...'''
3290    /// Contains (content, quote_char) where quote_char is '"' or '\''
3291    TripleQuotedString(String, char),
3292    /// Escape string: E'...' (PostgreSQL)
3293    EscapeString(String),
3294    /// Dollar-quoted string: $$...$$  (PostgreSQL)
3295    DollarString(String),
3296    /// Raw string: r"..." or r'...' (BigQuery, Spark, Databricks)
3297    /// In raw strings, backslashes are literal and not escape characters.
3298    /// When converting to a regular string, backslashes must be doubled.
3299    RawString(String),
3300}
3301
3302impl Literal {
3303    /// Returns the inner value as a string slice, regardless of literal type.
3304    pub fn value_str(&self) -> &str {
3305        match self {
3306            Literal::String(s)
3307            | Literal::Number(s)
3308            | Literal::HexString(s)
3309            | Literal::HexNumber(s)
3310            | Literal::BitString(s)
3311            | Literal::ByteString(s)
3312            | Literal::NationalString(s)
3313            | Literal::Date(s)
3314            | Literal::Time(s)
3315            | Literal::Timestamp(s)
3316            | Literal::Datetime(s)
3317            | Literal::EscapeString(s)
3318            | Literal::DollarString(s)
3319            | Literal::RawString(s) => s.as_str(),
3320            Literal::TripleQuotedString(s, _) => s.as_str(),
3321        }
3322    }
3323
3324    /// Returns `true` if this is a string-type literal.
3325    pub fn is_string(&self) -> bool {
3326        matches!(
3327            self,
3328            Literal::String(_)
3329                | Literal::NationalString(_)
3330                | Literal::EscapeString(_)
3331                | Literal::DollarString(_)
3332                | Literal::RawString(_)
3333                | Literal::TripleQuotedString(_, _)
3334        )
3335    }
3336
3337    /// Returns `true` if this is a numeric literal.
3338    pub fn is_number(&self) -> bool {
3339        matches!(self, Literal::Number(_) | Literal::HexNumber(_))
3340    }
3341}
3342
3343impl fmt::Display for Literal {
3344    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3345        match self {
3346            Literal::String(s) => write!(f, "'{}'", s),
3347            Literal::Number(n) => write!(f, "{}", n),
3348            Literal::HexString(h) => write!(f, "X'{}'", h),
3349            Literal::HexNumber(h) => write!(f, "0x{}", h),
3350            Literal::BitString(b) => write!(f, "B'{}'", b),
3351            Literal::ByteString(b) => write!(f, "b'{}'", b),
3352            Literal::NationalString(s) => write!(f, "N'{}'", s),
3353            Literal::Date(d) => write!(f, "DATE '{}'", d),
3354            Literal::Time(t) => write!(f, "TIME '{}'", t),
3355            Literal::Timestamp(ts) => write!(f, "TIMESTAMP '{}'", ts),
3356            Literal::Datetime(dt) => write!(f, "DATETIME '{}'", dt),
3357            Literal::TripleQuotedString(s, q) => {
3358                write!(f, "{0}{0}{0}{1}{0}{0}{0}", q, s)
3359            }
3360            Literal::EscapeString(s) => write!(f, "E'{}'", s),
3361            Literal::DollarString(s) => write!(f, "$${}$$", s),
3362            Literal::RawString(s) => write!(f, "r'{}'", s),
3363        }
3364    }
3365}
3366
3367/// Boolean literal
3368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3369#[cfg_attr(feature = "bindings", derive(TS))]
3370pub struct BooleanLiteral {
3371    pub value: bool,
3372}
3373
3374/// NULL literal
3375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3376#[cfg_attr(feature = "bindings", derive(TS))]
3377pub struct Null;
3378
3379/// Represent a SQL identifier (table name, column name, alias, keyword-as-name, etc.).
3380///
3381/// The `quoted` flag indicates whether the identifier was originally delimited
3382/// (double-quoted, backtick-quoted, or bracket-quoted depending on the
3383/// dialect). The generator uses this flag to decide whether to emit quoting
3384/// characters.
3385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, Serialize, Deserialize)]
3386#[cfg_attr(feature = "bindings", derive(TS))]
3387pub struct Identifier {
3388    /// The raw text of the identifier, without any quoting characters.
3389    pub name: String,
3390    /// Whether the identifier was quoted in the source SQL.
3391    pub quoted: bool,
3392    #[serde(default)]
3393    pub trailing_comments: Vec<String>,
3394    /// Original source range, including quoting delimiters. Absent for synthetic
3395    /// or programmatically constructed identifiers. Not part of structural equality.
3396    #[serde(default, skip_serializing_if = "Option::is_none")]
3397    pub span: Option<Span>,
3398}
3399
3400impl PartialEq for Identifier {
3401    fn eq(&self, other: &Self) -> bool {
3402        self.name == other.name
3403            && self.quoted == other.quoted
3404            && self.trailing_comments == other.trailing_comments
3405    }
3406}
3407
3408impl Identifier {
3409    pub fn new(name: impl Into<String>) -> Self {
3410        Self {
3411            name: name.into(),
3412            quoted: false,
3413            trailing_comments: Vec::new(),
3414            span: None,
3415        }
3416    }
3417
3418    pub fn quoted(name: impl Into<String>) -> Self {
3419        Self {
3420            name: name.into(),
3421            quoted: true,
3422            trailing_comments: Vec::new(),
3423            span: None,
3424        }
3425    }
3426
3427    pub fn empty() -> Self {
3428        Self {
3429            name: String::new(),
3430            quoted: false,
3431            trailing_comments: Vec::new(),
3432            span: None,
3433        }
3434    }
3435
3436    pub fn is_empty(&self) -> bool {
3437        self.name.is_empty()
3438    }
3439
3440    /// Preserve quoting in the legacy string representation of named type fields.
3441    /// Always use SQL-standard delimiters internally, independent of the source dialect.
3442    pub(crate) fn to_type_field_name(&self) -> String {
3443        if self.quoted {
3444            format!("\"{}\"", self.name.replace('"', "\"\""))
3445        } else {
3446            self.name.clone()
3447        }
3448    }
3449
3450    /// Set the source span on this identifier
3451    pub fn with_span(mut self, span: Span) -> Self {
3452        self.span = Some(span);
3453        self
3454    }
3455}
3456
3457impl fmt::Display for Identifier {
3458    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3459        if self.quoted {
3460            write!(f, "\"{}\"", self.name)
3461        } else {
3462            write!(f, "{}", self.name)
3463        }
3464    }
3465}
3466
3467/// Represent a column reference, optionally qualified by a table name.
3468///
3469/// Renders as `name` when unqualified, or `table.name` when qualified.
3470/// Use [`Expression::column()`] or [`Expression::qualified_column()`] for
3471/// convenient construction.
3472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, Serialize, Deserialize)]
3473#[cfg_attr(feature = "bindings", derive(TS))]
3474pub struct Column {
3475    /// The column name.
3476    pub name: Identifier,
3477    /// Optional table qualifier (e.g. `t` in `t.col`).
3478    pub table: Option<Identifier>,
3479    /// Oracle-style join marker (+) for outer joins
3480    #[serde(default)]
3481    pub join_mark: bool,
3482    /// Trailing comments that appeared after this column reference
3483    #[serde(default)]
3484    pub trailing_comments: Vec<String>,
3485    /// Original column-reference range, including its qualifier when present.
3486    /// Absent for synthetic references. Not part of structural equality.
3487    #[serde(default, skip_serializing_if = "Option::is_none")]
3488    pub span: Option<Span>,
3489    /// Inferred data type from type annotation
3490    #[serde(default, skip_serializing_if = "Option::is_none")]
3491    #[ast(skip)]
3492    pub inferred_type: Option<DataType>,
3493}
3494
3495impl PartialEq for Column {
3496    fn eq(&self, other: &Self) -> bool {
3497        self.name == other.name
3498            && self.table == other.table
3499            && self.join_mark == other.join_mark
3500            && self.trailing_comments == other.trailing_comments
3501            && self.inferred_type == other.inferred_type
3502    }
3503}
3504
3505impl fmt::Display for Column {
3506    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3507        if let Some(table) = &self.table {
3508            write!(f, "{}.{}", table, self.name)
3509        } else {
3510            write!(f, "{}", self.name)
3511        }
3512    }
3513}
3514
3515/// Represent a table reference with optional schema and catalog qualifiers.
3516///
3517/// Renders as `name`, `schema.name`, or `catalog.schema.name` depending on
3518/// which qualifiers are present. Supports aliases, column alias lists,
3519/// time-travel clauses (Snowflake, BigQuery), table hints (TSQL), and
3520/// several other dialect-specific extensions.
3521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3522#[cfg_attr(feature = "bindings", derive(TS))]
3523pub struct TableRef {
3524    /// The unqualified table name.
3525    pub name: Identifier,
3526    /// Optional schema qualifier (e.g. `public` in `public.users`).
3527    pub schema: Option<Identifier>,
3528    /// Optional catalog qualifier (e.g. `mydb` in `mydb.public.users`).
3529    pub catalog: Option<Identifier>,
3530    /// Optional table alias (e.g. `t` in `FROM users AS t`).
3531    pub alias: Option<Identifier>,
3532    /// Whether AS keyword was explicitly used for the alias
3533    #[serde(default)]
3534    pub alias_explicit_as: bool,
3535    /// Column aliases for table alias: AS t(c1, c2)
3536    #[serde(default)]
3537    pub column_aliases: Vec<Identifier>,
3538    /// Leading comments that appeared before this table reference in a FROM clause
3539    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3540    pub leading_comments: Vec<String>,
3541    /// Trailing comments that appeared after this table reference
3542    #[serde(default)]
3543    pub trailing_comments: Vec<String>,
3544    /// Snowflake time travel: BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
3545    #[serde(default)]
3546    pub when: Option<Box<HistoricalData>>,
3547    /// PostgreSQL ONLY modifier: prevents scanning child tables in inheritance hierarchy
3548    #[serde(default)]
3549    pub only: bool,
3550    /// ClickHouse FINAL modifier: forces final aggregation for MergeTree tables
3551    #[serde(default)]
3552    pub final_: bool,
3553    /// TABLESAMPLE clause attached to this table reference (DuckDB, BigQuery)
3554    #[serde(default, skip_serializing_if = "Option::is_none")]
3555    pub table_sample: Option<Box<Sample>>,
3556    /// TSQL table hints: WITH (TABLOCK, INDEX(myindex), ...)
3557    #[serde(default)]
3558    pub hints: Vec<Expression>,
3559    /// TSQL: FOR SYSTEM_TIME temporal clause
3560    /// Contains the full clause text, e.g., "FOR SYSTEM_TIME BETWEEN c AND d"
3561    #[serde(default, skip_serializing_if = "Option::is_none")]
3562    pub system_time: Option<String>,
3563    /// MySQL: PARTITION(p0, p1, ...) hint for reading from specific partitions
3564    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3565    pub partitions: Vec<Identifier>,
3566    /// Snowflake IDENTIFIER() function: dynamic table name from string/variable
3567    /// When set, this is used instead of the name field
3568    #[serde(default, skip_serializing_if = "Option::is_none")]
3569    pub identifier_func: Option<Box<Expression>>,
3570    /// Snowflake CHANGES clause: CHANGES (INFORMATION => ...) AT (...) END (...)
3571    #[serde(default, skip_serializing_if = "Option::is_none")]
3572    pub changes: Option<Box<Changes>>,
3573    /// Time travel version clause: FOR VERSION AS OF / FOR TIMESTAMP AS OF (Presto/Trino, BigQuery, Databricks)
3574    #[serde(default, skip_serializing_if = "Option::is_none")]
3575    pub version: Option<Box<Version>>,
3576    /// Source position span
3577    #[serde(default, skip_serializing_if = "Option::is_none")]
3578    pub span: Option<Span>,
3579}
3580
3581impl TableRef {
3582    pub fn new(name: impl Into<String>) -> Self {
3583        Self {
3584            name: Identifier::new(name),
3585            schema: None,
3586            catalog: None,
3587            alias: None,
3588            alias_explicit_as: false,
3589            column_aliases: Vec::new(),
3590            leading_comments: Vec::new(),
3591            trailing_comments: Vec::new(),
3592            when: None,
3593            only: false,
3594            final_: false,
3595            table_sample: None,
3596            hints: Vec::new(),
3597            system_time: None,
3598            partitions: Vec::new(),
3599            identifier_func: None,
3600            changes: None,
3601            version: None,
3602            span: None,
3603        }
3604    }
3605
3606    /// Create with a schema qualifier.
3607    pub fn new_with_schema(name: impl Into<String>, schema: impl Into<String>) -> Self {
3608        let mut t = Self::new(name);
3609        t.schema = Some(Identifier::new(schema));
3610        t
3611    }
3612
3613    /// Create with catalog and schema qualifiers.
3614    pub fn new_with_catalog(
3615        name: impl Into<String>,
3616        schema: impl Into<String>,
3617        catalog: impl Into<String>,
3618    ) -> Self {
3619        let mut t = Self::new(name);
3620        t.schema = Some(Identifier::new(schema));
3621        t.catalog = Some(Identifier::new(catalog));
3622        t
3623    }
3624
3625    /// Create from an Identifier, preserving the quoted flag
3626    pub fn from_identifier(name: Identifier) -> Self {
3627        Self {
3628            name,
3629            schema: None,
3630            catalog: None,
3631            alias: None,
3632            alias_explicit_as: false,
3633            column_aliases: Vec::new(),
3634            leading_comments: Vec::new(),
3635            trailing_comments: Vec::new(),
3636            when: None,
3637            only: false,
3638            final_: false,
3639            table_sample: None,
3640            hints: Vec::new(),
3641            system_time: None,
3642            partitions: Vec::new(),
3643            identifier_func: None,
3644            changes: None,
3645            version: None,
3646            span: None,
3647        }
3648    }
3649
3650    pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
3651        self.alias = Some(Identifier::new(alias));
3652        self
3653    }
3654
3655    pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
3656        self.schema = Some(Identifier::new(schema));
3657        self
3658    }
3659}
3660
3661/// Represent a wildcard star expression (`*`, `table.*`).
3662///
3663/// Supports the EXCEPT/EXCLUDE, REPLACE, and RENAME modifiers found in
3664/// DuckDB, BigQuery, and Snowflake (e.g. `SELECT * EXCEPT (id) FROM t`).
3665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3666#[cfg_attr(feature = "bindings", derive(TS))]
3667pub struct Star {
3668    /// Optional table qualifier (e.g. `t` in `t.*`).
3669    pub table: Option<Identifier>,
3670    /// EXCLUDE / EXCEPT columns (DuckDB, BigQuery, Snowflake)
3671    pub except: Option<Vec<Identifier>>,
3672    /// REPLACE expressions (BigQuery, Snowflake)
3673    pub replace: Option<Vec<Alias>>,
3674    /// RENAME columns (Snowflake)
3675    pub rename: Option<Vec<(Identifier, Identifier)>>,
3676    /// Trailing comments that appeared after the star
3677    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3678    pub trailing_comments: Vec<String>,
3679    /// Source position span
3680    #[serde(default, skip_serializing_if = "Option::is_none")]
3681    pub span: Option<Span>,
3682}
3683
3684/// Represent a complete SELECT statement.
3685///
3686/// This is the most feature-rich AST node, covering the full surface area of
3687/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3688/// `Vec` are omitted from the generated SQL when absent.
3689///
3690/// # Key Fields
3691///
3692/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3693/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3694/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3695/// - `where_clause` -- the WHERE predicate.
3696/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3697/// - `having` -- HAVING predicate.
3698/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3699/// - `limit` / `offset` / `fetch` -- result set limiting.
3700/// - `with` -- Common Table Expressions (CTEs).
3701/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3702/// - `windows` -- named window definitions (WINDOW w AS ...).
3703///
3704/// Dialect-specific extensions are supported via fields like `prewhere`
3705/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3706/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3707#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3708#[cfg_attr(feature = "bindings", derive(TS))]
3709pub struct Select {
3710    #[serde(default, skip_serializing_if = "Option::is_none")]
3711    pub vertica: Option<Box<VerticaSelectExtensions>>,
3712    /// The select-list: columns, expressions, aliases, and wildcards.
3713    pub expressions: Vec<Expression>,
3714    /// The FROM clause, containing one or more table sources.
3715    pub from: Option<From>,
3716    /// JOIN clauses applied after the FROM source.
3717    pub joins: Vec<Join>,
3718    pub lateral_views: Vec<LateralView>,
3719    /// ClickHouse PREWHERE clause
3720    #[serde(default, skip_serializing_if = "Option::is_none")]
3721    pub prewhere: Option<Expression>,
3722    pub where_clause: Option<Where>,
3723    pub group_by: Option<GroupBy>,
3724    pub having: Option<Having>,
3725    pub qualify: Option<Qualify>,
3726    pub order_by: Option<OrderBy>,
3727    pub distribute_by: Option<DistributeBy>,
3728    pub cluster_by: Option<ClusterBy>,
3729    pub sort_by: Option<SortBy>,
3730    pub limit: Option<Limit>,
3731    pub offset: Option<Offset>,
3732    /// ClickHouse LIMIT BY clause expressions
3733    #[serde(default, skip_serializing_if = "Option::is_none")]
3734    pub limit_by: Option<Vec<Expression>>,
3735    pub fetch: Option<Fetch>,
3736    pub distinct: bool,
3737    pub distinct_on: Option<Vec<Expression>>,
3738    pub top: Option<Top>,
3739    pub with: Option<With>,
3740    pub sample: Option<Sample>,
3741    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3742    #[serde(default, skip_serializing_if = "Option::is_none")]
3743    pub settings: Option<Vec<Expression>>,
3744    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3745    #[serde(default, skip_serializing_if = "Option::is_none")]
3746    pub format: Option<Expression>,
3747    pub windows: Option<Vec<NamedWindow>>,
3748    pub hint: Option<Hint>,
3749    /// Oracle CONNECT BY clause for hierarchical queries
3750    pub connect: Option<Connect>,
3751    /// SELECT ... INTO table_name for creating tables
3752    pub into: Option<SelectInto>,
3753    /// FOR UPDATE/SHARE locking clauses
3754    #[serde(default)]
3755    pub locks: Vec<Lock>,
3756    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3757    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3758    pub for_xml: Vec<Expression>,
3759    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3760    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3761    pub for_json: Vec<Expression>,
3762    /// Structured result serialization, including a bare FOR JSON/XML clause.
3763    #[serde(default, skip_serializing_if = "Option::is_none")]
3764    pub result_serialization: Option<ResultSerialization>,
3765    #[serde(default, skip_serializing_if = "Option::is_none")]
3766    pub query_collation: Option<Identifier>,
3767    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3768    pub query_hints: Vec<Expression>,
3769    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3770    pub total_rowcount: bool,
3771    #[serde(default, skip_serializing_if = "Option::is_none")]
3772    #[ast(skip)]
3773    pub source_dialect: Option<crate::dialects::DialectType>,
3774    /// Leading comments before the statement
3775    #[serde(default)]
3776    pub leading_comments: Vec<String>,
3777    /// Comments that appear after SELECT keyword (before expressions)
3778    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3779    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3780    pub post_select_comments: Vec<String>,
3781    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3782    #[serde(default, skip_serializing_if = "Option::is_none")]
3783    pub kind: Option<String>,
3784    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3785    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3786    pub operation_modifiers: Vec<String>,
3787    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3788    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3789    pub qualify_after_window: bool,
3790    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3791    #[serde(default, skip_serializing_if = "Option::is_none")]
3792    pub option: Option<String>,
3793    /// Redshift-style EXCLUDE clause at the end of the projection list
3794    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3795    #[serde(default, skip_serializing_if = "Option::is_none")]
3796    pub exclude: Option<Vec<Expression>>,
3797}
3798
3799impl Select {
3800    pub fn new() -> Self {
3801        Self {
3802            vertica: None,
3803            expressions: Vec::new(),
3804            from: None,
3805            joins: Vec::new(),
3806            lateral_views: Vec::new(),
3807            prewhere: None,
3808            where_clause: None,
3809            group_by: None,
3810            having: None,
3811            qualify: None,
3812            order_by: None,
3813            distribute_by: None,
3814            cluster_by: None,
3815            sort_by: None,
3816            limit: None,
3817            offset: None,
3818            limit_by: None,
3819            fetch: None,
3820            distinct: false,
3821            distinct_on: None,
3822            top: None,
3823            with: None,
3824            sample: None,
3825            settings: None,
3826            format: None,
3827            windows: None,
3828            hint: None,
3829            connect: None,
3830            into: None,
3831            locks: Vec::new(),
3832            for_xml: Vec::new(),
3833            for_json: Vec::new(),
3834            result_serialization: None,
3835            query_collation: None,
3836            query_hints: Vec::new(),
3837            total_rowcount: false,
3838            source_dialect: None,
3839            leading_comments: Vec::new(),
3840            post_select_comments: Vec::new(),
3841            kind: None,
3842            operation_modifiers: Vec::new(),
3843            qualify_after_window: false,
3844            option: None,
3845            exclude: None,
3846        }
3847    }
3848
3849    /// Add a column to select
3850    pub fn column(mut self, expr: Expression) -> Self {
3851        self.expressions.push(expr);
3852        self
3853    }
3854
3855    /// Set the FROM clause
3856    pub fn from(mut self, table: Expression) -> Self {
3857        self.from = Some(From {
3858            expressions: vec![table],
3859        });
3860        self
3861    }
3862
3863    /// Add a WHERE clause
3864    pub fn where_(mut self, condition: Expression) -> Self {
3865        self.where_clause = Some(Where { this: condition });
3866        self
3867    }
3868
3869    /// Set DISTINCT
3870    pub fn distinct(mut self) -> Self {
3871        self.distinct = true;
3872        self
3873    }
3874
3875    /// Add a JOIN
3876    pub fn join(mut self, join: Join) -> Self {
3877        self.joins.push(join);
3878        self
3879    }
3880
3881    /// Set ORDER BY
3882    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
3883        self.order_by = Some(OrderBy {
3884            expressions,
3885            siblings: false,
3886            comments: Vec::new(),
3887        });
3888        self
3889    }
3890
3891    /// Set LIMIT
3892    pub fn limit(mut self, n: Expression) -> Self {
3893        self.limit = Some(Limit {
3894            this: n,
3895            percent: false,
3896            comments: Vec::new(),
3897        });
3898        self
3899    }
3900
3901    /// Set OFFSET
3902    pub fn offset(mut self, n: Expression) -> Self {
3903        self.offset = Some(Offset {
3904            this: n,
3905            rows: None,
3906        });
3907        self
3908    }
3909}
3910
3911impl Default for Select {
3912    fn default() -> Self {
3913        Self::new()
3914    }
3915}
3916
3917/// Represent a UNION set operation between two query expressions.
3918///
3919/// When `all` is true, duplicate rows are preserved (UNION ALL).
3920/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
3921/// Supports DuckDB/Snowflake BY NAME and BigQuery BY NAME/CORRESPONDING modifiers.
3922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3923#[cfg_attr(feature = "bindings", derive(TS))]
3924pub struct Union {
3925    /// The left-hand query operand.
3926    pub left: Expression,
3927    /// The right-hand query operand.
3928    pub right: Expression,
3929    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
3930    pub all: bool,
3931    /// Whether DISTINCT was explicitly specified
3932    #[serde(default)]
3933    pub distinct: bool,
3934    /// Optional WITH clause
3935    pub with: Option<With>,
3936    /// ORDER BY applied to entire UNION result
3937    pub order_by: Option<OrderBy>,
3938    /// Row limit applied to the entire UNION result: a legacy count expression,
3939    /// or a complete `Expression::Limit` / `Expression::Fetch` with clause options.
3940    pub limit: Option<Box<Expression>>,
3941    /// OFFSET applied to entire UNION result
3942    pub offset: Option<Box<Expression>>,
3943    /// DISTRIBUTE BY clause (Hive/Spark)
3944    #[serde(default, skip_serializing_if = "Option::is_none")]
3945    pub distribute_by: Option<DistributeBy>,
3946    /// SORT BY clause (Hive/Spark)
3947    #[serde(default, skip_serializing_if = "Option::is_none")]
3948    pub sort_by: Option<SortBy>,
3949    /// CLUSTER BY clause (Hive/Spark)
3950    #[serde(default, skip_serializing_if = "Option::is_none")]
3951    pub cluster_by: Option<ClusterBy>,
3952    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3953    #[serde(default)]
3954    pub by_name: bool,
3955    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3956    #[serde(default, skip_serializing_if = "Option::is_none")]
3957    pub side: Option<String>,
3958    /// BigQuery: Set operation kind (INNER)
3959    #[serde(default, skip_serializing_if = "Option::is_none")]
3960    pub kind: Option<String>,
3961    /// BigQuery: CORRESPONDING modifier
3962    #[serde(default)]
3963    pub corresponding: bool,
3964    /// BigQuery: STRICT modifier (before CORRESPONDING)
3965    #[serde(default)]
3966    pub strict: bool,
3967    /// BigQuery: BY (columns) after CORRESPONDING
3968    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3969    pub on_columns: Vec<Expression>,
3970}
3971
3972/// Iteratively flatten the left-recursive chain to prevent stack overflow
3973/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3974impl Drop for Union {
3975    fn drop(&mut self) {
3976        loop {
3977            if let Expression::Union(ref mut inner) = self.left {
3978                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3979                let old_left = std::mem::replace(&mut self.left, next_left);
3980                drop(old_left);
3981            } else {
3982                break;
3983            }
3984        }
3985    }
3986}
3987
3988/// Represent an INTERSECT set operation between two query expressions.
3989///
3990/// Returns only rows that appear in both operands. When `all` is true,
3991/// duplicates are preserved according to their multiplicity.
3992#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3993#[cfg_attr(feature = "bindings", derive(TS))]
3994pub struct Intersect {
3995    /// The left-hand query operand.
3996    pub left: Expression,
3997    /// The right-hand query operand.
3998    pub right: Expression,
3999    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
4000    pub all: bool,
4001    /// Whether DISTINCT was explicitly specified
4002    #[serde(default)]
4003    pub distinct: bool,
4004    /// Optional WITH clause
4005    pub with: Option<With>,
4006    /// ORDER BY applied to entire INTERSECT result
4007    pub order_by: Option<OrderBy>,
4008    /// Row limit applied to the entire INTERSECT result: a legacy count expression,
4009    /// or a complete `Expression::Limit` / `Expression::Fetch` with clause options.
4010    pub limit: Option<Box<Expression>>,
4011    /// OFFSET applied to entire INTERSECT result
4012    pub offset: Option<Box<Expression>>,
4013    /// DISTRIBUTE BY clause (Hive/Spark)
4014    #[serde(default, skip_serializing_if = "Option::is_none")]
4015    pub distribute_by: Option<DistributeBy>,
4016    /// SORT BY clause (Hive/Spark)
4017    #[serde(default, skip_serializing_if = "Option::is_none")]
4018    pub sort_by: Option<SortBy>,
4019    /// CLUSTER BY clause (Hive/Spark)
4020    #[serde(default, skip_serializing_if = "Option::is_none")]
4021    pub cluster_by: Option<ClusterBy>,
4022    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4023    #[serde(default)]
4024    pub by_name: bool,
4025    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4026    #[serde(default, skip_serializing_if = "Option::is_none")]
4027    pub side: Option<String>,
4028    /// BigQuery: Set operation kind (INNER)
4029    #[serde(default, skip_serializing_if = "Option::is_none")]
4030    pub kind: Option<String>,
4031    /// BigQuery: CORRESPONDING modifier
4032    #[serde(default)]
4033    pub corresponding: bool,
4034    /// BigQuery: STRICT modifier (before CORRESPONDING)
4035    #[serde(default)]
4036    pub strict: bool,
4037    /// BigQuery: BY (columns) after CORRESPONDING
4038    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4039    pub on_columns: Vec<Expression>,
4040}
4041
4042impl Drop for Intersect {
4043    fn drop(&mut self) {
4044        loop {
4045            if let Expression::Intersect(ref mut inner) = self.left {
4046                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4047                let old_left = std::mem::replace(&mut self.left, next_left);
4048                drop(old_left);
4049            } else {
4050                break;
4051            }
4052        }
4053    }
4054}
4055
4056/// Represent an EXCEPT (MINUS) set operation between two query expressions.
4057///
4058/// Returns rows from the left operand that do not appear in the right operand.
4059/// When `all` is true, duplicates are subtracted according to their multiplicity.
4060#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4061#[cfg_attr(feature = "bindings", derive(TS))]
4062pub struct Except {
4063    /// The left-hand query operand.
4064    pub left: Expression,
4065    /// The right-hand query operand (rows to subtract).
4066    pub right: Expression,
4067    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
4068    pub all: bool,
4069    /// Whether DISTINCT was explicitly specified
4070    #[serde(default)]
4071    pub distinct: bool,
4072    /// Optional WITH clause
4073    pub with: Option<With>,
4074    /// ORDER BY applied to entire EXCEPT result
4075    pub order_by: Option<OrderBy>,
4076    /// Row limit applied to the entire EXCEPT result: a legacy count expression,
4077    /// or a complete `Expression::Limit` / `Expression::Fetch` with clause options.
4078    pub limit: Option<Box<Expression>>,
4079    /// OFFSET applied to entire EXCEPT result
4080    pub offset: Option<Box<Expression>>,
4081    /// DISTRIBUTE BY clause (Hive/Spark)
4082    #[serde(default, skip_serializing_if = "Option::is_none")]
4083    pub distribute_by: Option<DistributeBy>,
4084    /// SORT BY clause (Hive/Spark)
4085    #[serde(default, skip_serializing_if = "Option::is_none")]
4086    pub sort_by: Option<SortBy>,
4087    /// CLUSTER BY clause (Hive/Spark)
4088    #[serde(default, skip_serializing_if = "Option::is_none")]
4089    pub cluster_by: Option<ClusterBy>,
4090    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4091    #[serde(default)]
4092    pub by_name: bool,
4093    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4094    #[serde(default, skip_serializing_if = "Option::is_none")]
4095    pub side: Option<String>,
4096    /// BigQuery: Set operation kind (INNER)
4097    #[serde(default, skip_serializing_if = "Option::is_none")]
4098    pub kind: Option<String>,
4099    /// BigQuery: CORRESPONDING modifier
4100    #[serde(default)]
4101    pub corresponding: bool,
4102    /// BigQuery: STRICT modifier (before CORRESPONDING)
4103    #[serde(default)]
4104    pub strict: bool,
4105    /// BigQuery: BY (columns) after CORRESPONDING
4106    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4107    pub on_columns: Vec<Expression>,
4108}
4109
4110impl Drop for Except {
4111    fn drop(&mut self) {
4112        loop {
4113            if let Expression::Except(ref mut inner) = self.left {
4114                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4115                let old_left = std::mem::replace(&mut self.left, next_left);
4116                drop(old_left);
4117            } else {
4118                break;
4119            }
4120        }
4121    }
4122}
4123
4124/// INTO clause for SELECT INTO statements
4125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4126#[cfg_attr(feature = "bindings", derive(TS))]
4127pub struct SelectInto {
4128    /// Target table or variable (used when single target)
4129    pub this: Expression,
4130    /// Whether TEMPORARY keyword was used
4131    #[serde(default)]
4132    pub temporary: bool,
4133    /// Whether UNLOGGED keyword was used (PostgreSQL)
4134    #[serde(default)]
4135    pub unlogged: bool,
4136    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4137    #[serde(default)]
4138    pub bulk_collect: bool,
4139    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4140    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4141    pub expressions: Vec<Expression>,
4142}
4143
4144/// Represent a parenthesized subquery expression.
4145///
4146/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4147/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4148/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4149/// modifiers are rendered inside or outside the parentheses.
4150///
4151/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4152/// scalar subqueries in select-lists, and derived tables.
4153#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4154#[cfg_attr(feature = "bindings", derive(TS))]
4155pub struct Subquery {
4156    /// The inner query expression.
4157    pub this: Expression,
4158    /// Optional alias for the derived table.
4159    pub alias: Option<Identifier>,
4160    /// Optional column aliases: AS t(c1, c2)
4161    pub column_aliases: Vec<Identifier>,
4162    /// Whether AS keyword was explicitly used for the alias.
4163    #[serde(default)]
4164    pub alias_explicit_as: bool,
4165    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4166    #[serde(skip_serializing_if = "Option::is_none", default)]
4167    pub alias_keyword: Option<String>,
4168    /// ORDER BY clause (for parenthesized queries)
4169    pub order_by: Option<OrderBy>,
4170    /// LIMIT clause
4171    pub limit: Option<Limit>,
4172    /// OFFSET clause
4173    pub offset: Option<Offset>,
4174    /// DISTRIBUTE BY clause (Hive/Spark)
4175    #[serde(default, skip_serializing_if = "Option::is_none")]
4176    pub distribute_by: Option<DistributeBy>,
4177    /// SORT BY clause (Hive/Spark)
4178    #[serde(default, skip_serializing_if = "Option::is_none")]
4179    pub sort_by: Option<SortBy>,
4180    /// CLUSTER BY clause (Hive/Spark)
4181    #[serde(default, skip_serializing_if = "Option::is_none")]
4182    pub cluster_by: Option<ClusterBy>,
4183    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4184    #[serde(default)]
4185    pub lateral: bool,
4186    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4187    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4188    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4189    #[serde(default)]
4190    pub modifiers_inside: bool,
4191    /// Trailing comments after the closing paren
4192    #[serde(default)]
4193    pub trailing_comments: Vec<String>,
4194    /// Inferred data type from type annotation
4195    #[serde(default, skip_serializing_if = "Option::is_none")]
4196    #[ast(skip)]
4197    pub inferred_type: Option<DataType>,
4198}
4199
4200/// Pipe operator expression: query |> transform
4201///
4202/// Used in DataFusion and BigQuery pipe syntax:
4203///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4204#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4205#[cfg_attr(feature = "bindings", derive(TS))]
4206pub struct PipeOperator {
4207    /// The input query/expression (left side of |>)
4208    pub this: Expression,
4209    /// The piped operation (right side of |>)
4210    pub expression: Expression,
4211}
4212
4213/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4214#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4215#[cfg_attr(feature = "bindings", derive(TS))]
4216pub struct Values {
4217    /// The rows of values
4218    pub expressions: Vec<Tuple>,
4219    /// Optional alias for the table
4220    pub alias: Option<Identifier>,
4221    /// Optional column aliases: AS t(c1, c2)
4222    pub column_aliases: Vec<Identifier>,
4223}
4224
4225/// PIVOT operation - supports both standard and DuckDB simplified syntax
4226///
4227/// Standard syntax (in FROM clause):
4228///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4229///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4230///
4231/// DuckDB simplified syntax (statement-level):
4232///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4233///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4235#[cfg_attr(feature = "bindings", derive(TS))]
4236pub struct Pivot {
4237    /// Source table/expression
4238    pub this: Expression,
4239    /// For standard PIVOT: the aggregation function(s) (first is primary)
4240    /// For DuckDB simplified: unused (use `using` instead)
4241    #[serde(default)]
4242    pub expressions: Vec<Expression>,
4243    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4244    #[serde(default)]
4245    pub fields: Vec<Expression>,
4246    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4247    #[serde(default)]
4248    pub using: Vec<Expression>,
4249    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4250    #[serde(default)]
4251    pub group: Option<Box<Expression>>,
4252    /// Whether this is an UNPIVOT (vs PIVOT)
4253    #[serde(default)]
4254    pub unpivot: bool,
4255    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4256    #[serde(default)]
4257    pub into: Option<Box<Expression>>,
4258    /// Optional alias
4259    #[serde(default)]
4260    pub alias: Option<Identifier>,
4261    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4262    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4263    pub alias_columns: Vec<Identifier>,
4264    /// Include/exclude nulls (for UNPIVOT)
4265    #[serde(default)]
4266    pub include_nulls: Option<bool>,
4267    /// Default on null value (Snowflake)
4268    #[serde(default)]
4269    pub default_on_null: Option<Box<Expression>>,
4270    /// WITH clause (CTEs)
4271    #[serde(default, skip_serializing_if = "Option::is_none")]
4272    pub with: Option<With>,
4273}
4274
4275/// UNPIVOT operation
4276#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4277#[cfg_attr(feature = "bindings", derive(TS))]
4278pub struct Unpivot {
4279    pub this: Expression,
4280    pub value_column: Identifier,
4281    pub name_column: Identifier,
4282    pub columns: Vec<Expression>,
4283    pub alias: Option<Identifier>,
4284    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4285    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4286    pub alias_columns: Vec<Identifier>,
4287    /// Whether the value_column was parenthesized in the original SQL
4288    #[serde(default)]
4289    pub value_column_parenthesized: bool,
4290    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4291    #[serde(default)]
4292    pub include_nulls: Option<bool>,
4293    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4294    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4295    pub extra_value_columns: Vec<Identifier>,
4296}
4297
4298/// PIVOT alias for aliasing pivot expressions
4299/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4300#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4301#[cfg_attr(feature = "bindings", derive(TS))]
4302pub struct PivotAlias {
4303    pub this: Expression,
4304    pub alias: Expression,
4305}
4306
4307/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4309#[cfg_attr(feature = "bindings", derive(TS))]
4310pub struct PreWhere {
4311    pub this: Expression,
4312}
4313
4314/// STREAM definition (Snowflake) - for change data capture
4315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4316#[cfg_attr(feature = "bindings", derive(TS))]
4317pub struct Stream {
4318    pub this: Expression,
4319    #[serde(skip_serializing_if = "Option::is_none")]
4320    pub on: Option<Expression>,
4321    #[serde(skip_serializing_if = "Option::is_none")]
4322    pub show_initial_rows: Option<bool>,
4323}
4324
4325/// USING DATA clause for data import statements
4326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4327#[cfg_attr(feature = "bindings", derive(TS))]
4328pub struct UsingData {
4329    pub this: Expression,
4330}
4331
4332/// XML Namespace declaration
4333#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4334#[cfg_attr(feature = "bindings", derive(TS))]
4335pub struct XmlNamespace {
4336    pub this: Expression,
4337    #[serde(skip_serializing_if = "Option::is_none")]
4338    pub alias: Option<Identifier>,
4339}
4340
4341/// ROW FORMAT clause for Hive/Spark
4342#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4343#[cfg_attr(feature = "bindings", derive(TS))]
4344pub struct RowFormat {
4345    pub delimited: bool,
4346    pub fields_terminated_by: Option<String>,
4347    pub collection_items_terminated_by: Option<String>,
4348    pub map_keys_terminated_by: Option<String>,
4349    pub lines_terminated_by: Option<String>,
4350    pub null_defined_as: Option<String>,
4351}
4352
4353/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4354#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4355#[cfg_attr(feature = "bindings", derive(TS))]
4356pub struct DirectoryInsert {
4357    pub local: bool,
4358    pub path: String,
4359    pub row_format: Option<RowFormat>,
4360    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4361    #[serde(default)]
4362    pub stored_as: Option<String>,
4363}
4364
4365/// INSERT statement
4366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4367#[cfg_attr(feature = "bindings", derive(TS))]
4368pub struct Insert {
4369    pub table: TableRef,
4370    pub columns: Vec<Identifier>,
4371    pub values: Vec<Vec<Expression>>,
4372    pub query: Option<Expression>,
4373    /// INSERT OVERWRITE for Hive/Spark
4374    pub overwrite: bool,
4375    /// PARTITION clause for Hive/Spark
4376    pub partition: Vec<(Identifier, Option<Expression>)>,
4377    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4378    #[serde(default)]
4379    pub directory: Option<DirectoryInsert>,
4380    /// RETURNING clause (PostgreSQL, SQLite)
4381    #[serde(default)]
4382    pub returning: Vec<Expression>,
4383    /// OUTPUT clause (TSQL)
4384    #[serde(default)]
4385    pub output: Option<OutputClause>,
4386    /// ON CONFLICT clause (PostgreSQL, SQLite)
4387    #[serde(default)]
4388    pub on_conflict: Option<Box<Expression>>,
4389    /// Leading comments before the statement
4390    #[serde(default)]
4391    pub leading_comments: Vec<String>,
4392    /// IF EXISTS clause (Hive)
4393    #[serde(default)]
4394    pub if_exists: bool,
4395    /// WITH clause (CTEs)
4396    #[serde(default)]
4397    pub with: Option<With>,
4398    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4399    #[serde(default)]
4400    pub ignore: bool,
4401    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4402    #[serde(default)]
4403    pub source_alias: Option<Identifier>,
4404    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4405    #[serde(default)]
4406    pub alias: Option<Identifier>,
4407    /// Whether the alias uses explicit AS keyword
4408    #[serde(default)]
4409    pub alias_explicit_as: bool,
4410    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4411    #[serde(default)]
4412    pub default_values: bool,
4413    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4414    #[serde(default)]
4415    pub by_name: bool,
4416    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4417    #[serde(default, skip_serializing_if = "Option::is_none")]
4418    pub conflict_action: Option<String>,
4419    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4420    #[serde(default)]
4421    pub is_replace: bool,
4422    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4423    #[serde(default, skip_serializing_if = "Option::is_none")]
4424    pub hint: Option<Hint>,
4425    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4426    #[serde(default)]
4427    pub replace_where: Option<Box<Expression>>,
4428    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4429    #[serde(default)]
4430    pub source: Option<Box<Expression>>,
4431    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4432    #[serde(default, skip_serializing_if = "Option::is_none")]
4433    pub function_target: Option<Box<Expression>>,
4434    /// ClickHouse: PARTITION BY expr
4435    #[serde(default, skip_serializing_if = "Option::is_none")]
4436    pub partition_by: Option<Box<Expression>>,
4437    /// ClickHouse: SETTINGS key = val, ...
4438    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4439    pub settings: Vec<Expression>,
4440}
4441
4442/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4444#[cfg_attr(feature = "bindings", derive(TS))]
4445pub struct OutputClause {
4446    /// Columns/expressions to output
4447    pub columns: Vec<Expression>,
4448    /// Optional INTO target table or table variable
4449    #[serde(default)]
4450    pub into_table: Option<Expression>,
4451}
4452
4453/// UPDATE statement
4454#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4455#[cfg_attr(feature = "bindings", derive(TS))]
4456pub struct Update {
4457    pub table: TableRef,
4458    #[serde(default)]
4459    pub hint: Option<Hint>,
4460    /// Additional tables for multi-table UPDATE (MySQL syntax)
4461    #[serde(default)]
4462    pub extra_tables: Vec<TableRef>,
4463    /// JOINs attached to the table list (MySQL multi-table syntax)
4464    #[serde(default)]
4465    pub table_joins: Vec<Join>,
4466    pub set: Vec<(Identifier, Expression)>,
4467    pub from_clause: Option<From>,
4468    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4469    #[serde(default)]
4470    pub from_joins: Vec<Join>,
4471    pub where_clause: Option<Where>,
4472    /// RETURNING clause (PostgreSQL, SQLite)
4473    #[serde(default)]
4474    pub returning: Vec<Expression>,
4475    /// OUTPUT clause (TSQL)
4476    #[serde(default)]
4477    pub output: Option<OutputClause>,
4478    /// WITH clause (CTEs)
4479    #[serde(default)]
4480    pub with: Option<With>,
4481    /// Leading comments before the statement
4482    #[serde(default)]
4483    pub leading_comments: Vec<String>,
4484    /// LIMIT clause (MySQL)
4485    #[serde(default)]
4486    pub limit: Option<Expression>,
4487    /// ORDER BY clause (MySQL)
4488    #[serde(default)]
4489    pub order_by: Option<OrderBy>,
4490    /// Whether FROM clause appears before SET (Snowflake syntax)
4491    #[serde(default)]
4492    pub from_before_set: bool,
4493}
4494
4495/// DELETE statement
4496#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4497#[cfg_attr(feature = "bindings", derive(TS))]
4498pub struct Delete {
4499    pub table: TableRef,
4500    #[serde(default)]
4501    pub hint: Option<Hint>,
4502    /// ClickHouse: ON CLUSTER clause for distributed DDL
4503    #[serde(default, skip_serializing_if = "Option::is_none")]
4504    pub on_cluster: Option<OnCluster>,
4505    /// Optional alias for the table
4506    pub alias: Option<Identifier>,
4507    /// Whether the alias was declared with explicit AS keyword
4508    #[serde(default)]
4509    pub alias_explicit_as: bool,
4510    /// PostgreSQL/DuckDB USING clause - additional tables to join
4511    pub using: Vec<TableRef>,
4512    pub where_clause: Option<Where>,
4513    /// OUTPUT clause (TSQL)
4514    #[serde(default)]
4515    pub output: Option<OutputClause>,
4516    /// Leading comments before the statement
4517    #[serde(default)]
4518    pub leading_comments: Vec<String>,
4519    /// WITH clause (CTEs)
4520    #[serde(default)]
4521    pub with: Option<With>,
4522    /// LIMIT clause (MySQL)
4523    #[serde(default)]
4524    pub limit: Option<Expression>,
4525    /// ORDER BY clause (MySQL)
4526    #[serde(default)]
4527    pub order_by: Option<OrderBy>,
4528    /// RETURNING clause (PostgreSQL)
4529    #[serde(default)]
4530    pub returning: Vec<Expression>,
4531    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4532    /// These are the target tables to delete from
4533    #[serde(default)]
4534    pub tables: Vec<TableRef>,
4535    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4536    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4537    #[serde(default)]
4538    pub tables_from_using: bool,
4539    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4540    #[serde(default)]
4541    pub joins: Vec<Join>,
4542    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4543    #[serde(default)]
4544    pub force_index: Option<String>,
4545    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4546    #[serde(default)]
4547    pub no_from: bool,
4548}
4549
4550/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4552#[cfg_attr(feature = "bindings", derive(TS))]
4553pub struct CopyStmt {
4554    /// Target table or query
4555    pub this: Expression,
4556    /// True for FROM (loading into table), false for TO (exporting)
4557    pub kind: bool,
4558    /// Source/destination file(s) or stage
4559    pub files: Vec<Expression>,
4560    /// Copy parameters
4561    #[serde(default)]
4562    pub params: Vec<CopyParameter>,
4563    /// Credentials for external access
4564    #[serde(default)]
4565    pub credentials: Option<Box<Credentials>>,
4566    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4567    #[serde(default)]
4568    pub is_into: bool,
4569    /// Whether parameters are wrapped in WITH (...) syntax
4570    #[serde(default)]
4571    pub with_wrapped: bool,
4572}
4573
4574/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4575#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4576#[cfg_attr(feature = "bindings", derive(TS))]
4577pub struct CopyParameter {
4578    pub name: String,
4579    pub value: Option<Expression>,
4580    pub values: Vec<Expression>,
4581    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4582    #[serde(default)]
4583    pub eq: bool,
4584}
4585
4586/// Credentials for external access (S3, Azure, etc.)
4587#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4588#[cfg_attr(feature = "bindings", derive(TS))]
4589pub struct Credentials {
4590    pub credentials: Vec<(String, String)>,
4591    pub encryption: Option<String>,
4592    pub storage: Option<String>,
4593}
4594
4595/// PUT statement (Snowflake)
4596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4597#[cfg_attr(feature = "bindings", derive(TS))]
4598pub struct PutStmt {
4599    /// Source file path
4600    pub source: String,
4601    /// Whether source was quoted in the original SQL
4602    #[serde(default)]
4603    pub source_quoted: bool,
4604    /// Target stage
4605    pub target: Expression,
4606    /// PUT parameters
4607    #[serde(default)]
4608    pub params: Vec<CopyParameter>,
4609}
4610
4611/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4613#[cfg_attr(feature = "bindings", derive(TS))]
4614pub struct StageReference {
4615    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4616    pub name: String,
4617    /// Optional path within the stage (e.g., "/path/to/file.csv")
4618    #[serde(default)]
4619    pub path: Option<String>,
4620    /// Optional FILE_FORMAT parameter
4621    #[serde(default)]
4622    pub file_format: Option<Expression>,
4623    /// Optional PATTERN parameter
4624    #[serde(default)]
4625    pub pattern: Option<String>,
4626    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4627    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4628    pub quoted: bool,
4629}
4630
4631/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4633#[cfg_attr(feature = "bindings", derive(TS))]
4634pub struct HistoricalData {
4635    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4636    pub this: Box<Expression>,
4637    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4638    pub kind: String,
4639    /// The expression value (e.g., the statement ID or timestamp)
4640    pub expression: Box<Expression>,
4641}
4642
4643/// Represent an aliased expression (`expr AS name`).
4644///
4645/// Used for column aliases in select-lists, table aliases on subqueries,
4646/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4647#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4648#[cfg_attr(feature = "bindings", derive(TS))]
4649pub struct Alias {
4650    /// The expression being aliased.
4651    pub this: Expression,
4652    /// The alias name (required for simple aliases, optional when only column aliases provided)
4653    pub alias: Identifier,
4654    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4655    #[serde(default)]
4656    pub column_aliases: Vec<Identifier>,
4657    /// Whether AS keyword was explicitly used for the alias.
4658    #[serde(default)]
4659    pub alias_explicit_as: bool,
4660    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4661    #[serde(skip_serializing_if = "Option::is_none", default)]
4662    pub alias_keyword: Option<String>,
4663    /// Comments that appeared between the expression and AS keyword
4664    #[serde(default)]
4665    pub pre_alias_comments: Vec<String>,
4666    /// Trailing comments that appeared after the alias
4667    #[serde(default)]
4668    pub trailing_comments: Vec<String>,
4669    /// Inferred data type from type annotation
4670    #[serde(default, skip_serializing_if = "Option::is_none")]
4671    #[ast(skip)]
4672    pub inferred_type: Option<DataType>,
4673}
4674
4675impl Alias {
4676    /// Create a simple alias
4677    pub fn new(this: Expression, alias: Identifier) -> Self {
4678        Self {
4679            this,
4680            alias,
4681            column_aliases: Vec::new(),
4682            alias_explicit_as: false,
4683            alias_keyword: None,
4684            pre_alias_comments: Vec::new(),
4685            trailing_comments: Vec::new(),
4686            inferred_type: None,
4687        }
4688    }
4689
4690    /// Create an alias with column aliases only (no table alias name)
4691    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4692        Self {
4693            this,
4694            alias: Identifier::empty(),
4695            column_aliases,
4696            alias_explicit_as: false,
4697            alias_keyword: None,
4698            pre_alias_comments: Vec::new(),
4699            trailing_comments: Vec::new(),
4700            inferred_type: None,
4701        }
4702    }
4703}
4704
4705/// Represent a type cast expression.
4706///
4707/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4708/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4709/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4710/// CONVERSION ERROR (Oracle) clauses.
4711#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4712#[cfg_attr(feature = "bindings", derive(TS))]
4713pub struct Cast {
4714    /// The expression being cast.
4715    pub this: Expression,
4716    /// The target data type.
4717    pub to: DataType,
4718    #[serde(default)]
4719    pub trailing_comments: Vec<String>,
4720    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4721    #[serde(default)]
4722    pub double_colon_syntax: bool,
4723    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4724    #[serde(skip_serializing_if = "Option::is_none", default)]
4725    pub format: Option<Box<Expression>>,
4726    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4727    #[serde(skip_serializing_if = "Option::is_none", default)]
4728    pub default: Option<Box<Expression>>,
4729    /// Inferred data type from type annotation
4730    #[serde(default, skip_serializing_if = "Option::is_none")]
4731    #[ast(skip)]
4732    pub inferred_type: Option<DataType>,
4733}
4734
4735///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4736#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4737#[cfg_attr(feature = "bindings", derive(TS))]
4738pub struct CollationExpr {
4739    pub this: Expression,
4740    pub collation: String,
4741    /// True if the collation was single-quoted in the original SQL (string literal)
4742    #[serde(default)]
4743    pub quoted: bool,
4744    /// True if the collation was double-quoted in the original SQL (identifier)
4745    #[serde(default)]
4746    pub double_quoted: bool,
4747}
4748
4749/// Represent a CASE expression (both simple and searched forms).
4750///
4751/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4752/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4753/// Each entry in `whens` is a `(condition, result)` pair.
4754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4755#[cfg_attr(feature = "bindings", derive(TS))]
4756pub struct Case {
4757    /// The operand for simple CASE, or `None` for searched CASE.
4758    pub operand: Option<Expression>,
4759    /// Pairs of (WHEN condition, THEN result).
4760    pub whens: Vec<(Expression, Expression)>,
4761    /// Optional ELSE result.
4762    pub else_: Option<Expression>,
4763    /// Comments from the CASE keyword (emitted after END)
4764    #[serde(default)]
4765    #[serde(skip_serializing_if = "Vec::is_empty")]
4766    pub comments: Vec<String>,
4767    /// Inferred data type from type annotation
4768    #[serde(default, skip_serializing_if = "Option::is_none")]
4769    #[ast(skip)]
4770    pub inferred_type: Option<DataType>,
4771}
4772
4773/// Represent a binary operation (two operands separated by an operator).
4774///
4775/// This is the shared payload struct for all binary operator variants in the
4776/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4777/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4778/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4779/// preservation of inline comments around operators.
4780#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4781#[cfg_attr(feature = "bindings", derive(TS))]
4782pub struct BinaryOp {
4783    pub left: Expression,
4784    pub right: Expression,
4785    /// Comments after the left operand (before the operator)
4786    #[serde(default)]
4787    pub left_comments: Vec<String>,
4788    /// Comments after the operator (before the right operand)
4789    #[serde(default)]
4790    pub operator_comments: Vec<String>,
4791    /// Comments after the right operand
4792    #[serde(default)]
4793    pub trailing_comments: Vec<String>,
4794    /// Inferred data type from type annotation
4795    #[serde(default, skip_serializing_if = "Option::is_none")]
4796    #[ast(skip)]
4797    pub inferred_type: Option<DataType>,
4798}
4799
4800impl BinaryOp {
4801    pub fn new(left: Expression, right: Expression) -> Self {
4802        Self {
4803            left,
4804            right,
4805            left_comments: Vec::new(),
4806            operator_comments: Vec::new(),
4807            trailing_comments: Vec::new(),
4808            inferred_type: None,
4809        }
4810    }
4811}
4812
4813/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4815#[cfg_attr(feature = "bindings", derive(TS))]
4816pub struct LikeOp {
4817    pub left: Expression,
4818    pub right: Expression,
4819    /// ESCAPE character/expression
4820    #[serde(default)]
4821    pub escape: Option<Expression>,
4822    /// Quantifier: ANY, ALL, or SOME
4823    #[serde(default)]
4824    pub quantifier: Option<String>,
4825    /// Inferred data type from type annotation
4826    #[serde(default, skip_serializing_if = "Option::is_none")]
4827    #[ast(skip)]
4828    pub inferred_type: Option<DataType>,
4829}
4830
4831impl LikeOp {
4832    pub fn new(left: Expression, right: Expression) -> Self {
4833        Self {
4834            left,
4835            right,
4836            escape: None,
4837            quantifier: None,
4838            inferred_type: None,
4839        }
4840    }
4841
4842    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4843        Self {
4844            left,
4845            right,
4846            escape: Some(escape),
4847            quantifier: None,
4848            inferred_type: None,
4849        }
4850    }
4851}
4852
4853/// Represent a unary operation (single operand with a prefix operator).
4854///
4855/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4857#[cfg_attr(feature = "bindings", derive(TS))]
4858pub struct UnaryOp {
4859    /// The operand expression.
4860    pub this: Expression,
4861    /// Inferred data type from type annotation
4862    #[serde(default, skip_serializing_if = "Option::is_none")]
4863    #[ast(skip)]
4864    pub inferred_type: Option<DataType>,
4865}
4866
4867impl UnaryOp {
4868    pub fn new(this: Expression) -> Self {
4869        Self {
4870            this,
4871            inferred_type: None,
4872        }
4873    }
4874}
4875
4876/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4877///
4878/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4879/// but not both. When `not` is true, the predicate is `NOT IN`.
4880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4881#[cfg_attr(feature = "bindings", derive(TS))]
4882pub struct In {
4883    /// The expression being tested.
4884    pub this: Expression,
4885    /// The value list (mutually exclusive with `query`).
4886    pub expressions: Vec<Expression>,
4887    /// A subquery (mutually exclusive with `expressions`).
4888    pub query: Option<Expression>,
4889    /// Whether this is NOT IN.
4890    pub not: bool,
4891    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4892    pub global: bool,
4893    /// BigQuery: IN UNNEST(expr)
4894    #[serde(default, skip_serializing_if = "Option::is_none")]
4895    pub unnest: Option<Box<Expression>>,
4896    /// Whether the right side is a bare field reference (no parentheses).
4897    /// Matches Python sqlglot's `field` attribute on `In` expression.
4898    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4899    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4900    pub is_field: bool,
4901}
4902
4903/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4904#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4905#[cfg_attr(feature = "bindings", derive(TS))]
4906pub struct Between {
4907    /// The expression being tested.
4908    pub this: Expression,
4909    /// The lower bound.
4910    pub low: Expression,
4911    /// The upper bound.
4912    pub high: Expression,
4913    /// Whether this is NOT BETWEEN.
4914    pub not: bool,
4915    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4916    #[serde(default)]
4917    pub symmetric: Option<bool>,
4918}
4919
4920/// IS NULL predicate
4921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4922#[cfg_attr(feature = "bindings", derive(TS))]
4923pub struct IsNull {
4924    pub this: Expression,
4925    pub not: bool,
4926    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4927    #[serde(default)]
4928    pub postfix_form: bool,
4929}
4930
4931/// IS TRUE / IS FALSE predicate
4932#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4933#[cfg_attr(feature = "bindings", derive(TS))]
4934pub struct IsTrueFalse {
4935    pub this: Expression,
4936    pub not: bool,
4937}
4938
4939/// IS JSON predicate (SQL standard)
4940/// Checks if a value is valid JSON
4941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4942#[cfg_attr(feature = "bindings", derive(TS))]
4943pub struct IsJson {
4944    pub this: Expression,
4945    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4946    pub json_type: Option<String>,
4947    /// Key uniqueness constraint
4948    pub unique_keys: Option<JsonUniqueKeys>,
4949    /// Whether IS NOT JSON
4950    pub negated: bool,
4951}
4952
4953/// JSON unique keys constraint variants
4954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4955#[cfg_attr(feature = "bindings", derive(TS))]
4956pub enum JsonUniqueKeys {
4957    /// WITH UNIQUE KEYS
4958    With,
4959    /// WITHOUT UNIQUE KEYS
4960    Without,
4961    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4962    Shorthand,
4963}
4964
4965/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4967#[cfg_attr(feature = "bindings", derive(TS))]
4968pub struct Exists {
4969    /// The subquery expression.
4970    pub this: Expression,
4971    /// Whether this is NOT EXISTS.
4972    pub not: bool,
4973}
4974
4975#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4976#[cfg_attr(feature = "bindings", derive(TS))]
4977pub struct Upsert {
4978    /// Retained source semantics; serialized independently of generator configuration.
4979    #[serde(default, skip_serializing_if = "Option::is_none")]
4980    #[ast(skip)]
4981    pub source_dialect: Option<crate::dialects::DialectType>,
4982
4983    pub table: TableRef,
4984    pub partition: Option<Expression>,
4985    pub columns: Vec<Identifier>,
4986    pub source: Expression,
4987    pub condition: Option<Expression>,
4988    pub primary_key: bool,
4989}
4990
4991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4992#[cfg_attr(feature = "bindings", derive(TS))]
4993pub struct PartitionSpec {
4994    /// Retained source semantics; serialized independently of generator configuration.
4995    #[serde(default, skip_serializing_if = "Option::is_none")]
4996    #[ast(skip)]
4997    pub source_dialect: Option<crate::dialects::DialectType>,
4998
4999    pub method: String,
5000    pub columns: Vec<Expression>,
5001    pub partitions: Option<Expression>,
5002    pub ranges: Vec<PartitionRangeSpec>,
5003    pub primary_key_check: Option<bool>,
5004    pub properties: Vec<Expression>,
5005    pub subpartition: Option<Box<PartitionSpec>>,
5006}
5007
5008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5009#[cfg_attr(feature = "bindings", derive(TS))]
5010pub struct PartitionRangeSpec {
5011    pub name: Option<Identifier>,
5012    pub kind: String,
5013    pub values: Vec<Expression>,
5014    pub dynamic: bool,
5015    pub direction: Option<String>,
5016    pub threshold: Option<Expression>,
5017    pub interval: Option<(Expression, Option<String>)>,
5018    pub properties: Vec<Expression>,
5019}
5020
5021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5022#[cfg_attr(feature = "bindings", derive(TS))]
5023pub struct StorageProperty {
5024    /// Retained source semantics; serialized independently of generator configuration.
5025    #[serde(default, skip_serializing_if = "Option::is_none")]
5026    #[ast(skip)]
5027    pub source_dialect: Option<crate::dialects::DialectType>,
5028
5029    pub name: String,
5030    pub values: Vec<Expression>,
5031}
5032
5033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5034#[cfg_attr(feature = "bindings", derive(TS))]
5035pub struct Hierarchy {
5036    /// Retained source semantics; serialized independently of generator configuration.
5037    #[serde(default, skip_serializing_if = "Option::is_none")]
5038    #[ast(skip)]
5039    pub source_dialect: Option<crate::dialects::DialectType>,
5040
5041    pub name: String,
5042    pub source: Expression,
5043    pub start: Option<Expression>,
5044    pub siblings: Vec<Ordered>,
5045    pub depth: Option<Expression>,
5046    pub multiparent: Option<String>,
5047    pub orphan: Option<String>,
5048    pub cycle: Option<String>,
5049    pub cache: Option<String>,
5050}
5051
5052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5053#[cfg_attr(feature = "bindings", derive(TS))]
5054pub struct ViewParameter {
5055    /// Retained source semantics; serialized independently of generator configuration.
5056    #[serde(default, skip_serializing_if = "Option::is_none")]
5057    #[ast(skip)]
5058    pub source_dialect: Option<crate::dialects::DialectType>,
5059
5060    pub name: Identifier,
5061    pub value: Expression,
5062}
5063
5064#[derive(
5065    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
5066)]
5067#[cfg_attr(feature = "bindings", derive(TS))]
5068pub struct JsonOptions {
5069    pub wrapper: Option<String>,
5070    pub on_empty: Option<SqlBehavior>,
5071    pub on_error: Option<SqlBehavior>,
5072}
5073
5074#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5075#[cfg_attr(feature = "bindings", derive(TS))]
5076pub struct SqlBehavior {
5077    /// ERROR, NULL, DEFAULT, EMPTY ARRAY, or EMPTY OBJECT.
5078    pub kind: String,
5079    pub value: Option<Expression>,
5080}
5081
5082/// Procedure invocation, including library member calls and asynchronous execution.
5083#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5084#[cfg_attr(feature = "bindings", derive(TS))]
5085pub struct Call {
5086    /// Retained source semantics; serialized independently of generator configuration.
5087    #[serde(default, skip_serializing_if = "Option::is_none")]
5088    #[ast(skip)]
5089    pub source_dialect: Option<crate::dialects::DialectType>,
5090
5091    pub name: Vec<Identifier>,
5092    pub member: Option<Identifier>,
5093    pub arguments: Vec<Expression>,
5094    pub asynchronous: bool,
5095    pub hints: Vec<Expression>,
5096}
5097
5098/// Regex search options shared by predicates, extraction, replacement, and position calls.
5099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5100#[cfg_attr(feature = "bindings", derive(TS))]
5101pub struct RegexOptions {
5102    #[serde(default, skip_serializing_if = "Option::is_none")]
5103    #[ast(skip)]
5104    pub source_dialect: Option<crate::dialects::DialectType>,
5105    /// Original spelling when a dialect has more than one native alias.
5106    pub source_name: String,
5107    #[serde(default)]
5108    pub negated: bool,
5109    pub start: Option<Expression>,
5110    pub occurrence: Option<Expression>,
5111    pub flags: Option<Expression>,
5112    pub position_after: Option<bool>,
5113}
5114
5115/// Grouping-set selection and result-delivery options.
5116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5117#[cfg_attr(feature = "bindings", derive(TS))]
5118pub struct GroupingOptions {
5119    #[serde(default, skip_serializing_if = "Option::is_none")]
5120    #[ast(skip)]
5121    pub source_dialect: Option<crate::dialects::DialectType>,
5122    pub best: Option<Expression>,
5123    pub limit: Option<Expression>,
5124    pub offset: Option<Expression>,
5125    pub subtotal: bool,
5126    pub balance: bool,
5127    pub total: bool,
5128    pub structured: bool,
5129    pub overview: bool,
5130    pub prefix: Option<Expression>,
5131    pub multiple_resultsets: bool,
5132}
5133
5134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5135#[cfg_attr(feature = "bindings", derive(TS))]
5136pub struct ResultSerialization {
5137    /// JSON or XML, validated by the HANA parser.
5138    pub format: String,
5139    pub options: Vec<(String, String)>,
5140    #[serde(default, skip_serializing_if = "Option::is_none")]
5141    pub returning: Option<DataType>,
5142}
5143
5144/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
5145///
5146/// This is the generic function node. Well-known aggregates, window functions,
5147/// and built-in functions each have their own dedicated `Expression` variants
5148/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
5149/// not recognize as built-ins are represented with this struct.
5150#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5151#[cfg_attr(feature = "bindings", derive(TS))]
5152pub struct Function {
5153    /// Qualified name components preserve quoting without changing the node kind.
5154    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5155    pub qualified_name: Vec<Identifier>,
5156    /// Optional DEFAULT/NULL/ERROR behavior after the arguments.
5157    #[serde(default, skip_serializing_if = "Option::is_none")]
5158    pub on_error: Option<Box<SqlBehavior>>,
5159    /// Dialect whose call semantics must be retained through independent generation.
5160    #[serde(default, skip_serializing_if = "Option::is_none")]
5161    #[ast(skip)]
5162    pub source_dialect: Option<crate::dialects::DialectType>,
5163
5164    /// The function name, as originally written (may be schema-qualified).
5165    pub name: String,
5166    /// Positional arguments to the function.
5167    pub args: Vec<Expression>,
5168    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
5169    pub distinct: bool,
5170    #[serde(default)]
5171    pub trailing_comments: Vec<String>,
5172    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
5173    #[serde(default)]
5174    pub use_bracket_syntax: bool,
5175    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
5176    #[serde(default)]
5177    pub no_parens: bool,
5178    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
5179    #[serde(default)]
5180    pub quoted: bool,
5181    /// Source position span
5182    #[serde(default, skip_serializing_if = "Option::is_none")]
5183    pub span: Option<Span>,
5184    /// Inferred data type from type annotation
5185    #[serde(default, skip_serializing_if = "Option::is_none")]
5186    #[ast(skip)]
5187    pub inferred_type: Option<DataType>,
5188}
5189
5190impl Default for Function {
5191    fn default() -> Self {
5192        Self {
5193            source_dialect: None,
5194            qualified_name: Vec::new(),
5195            on_error: None,
5196            name: String::new(),
5197            args: Vec::new(),
5198            distinct: false,
5199            trailing_comments: Vec::new(),
5200            use_bracket_syntax: false,
5201            no_parens: false,
5202            quoted: false,
5203            span: None,
5204            inferred_type: None,
5205        }
5206    }
5207}
5208
5209impl Function {
5210    /// Construct a call with individually quoted qualified name components.
5211    pub fn qualified(name: Vec<Identifier>, args: Vec<Expression>) -> Self {
5212        Self {
5213            name: name
5214                .iter()
5215                .map(|part| part.name.as_str())
5216                .collect::<Vec<_>>()
5217                .join("."),
5218            qualified_name: name,
5219            args,
5220            ..Default::default()
5221        }
5222    }
5223    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
5224        Self {
5225            source_dialect: None,
5226            qualified_name: Vec::new(),
5227            on_error: None,
5228            name: name.into(),
5229            args,
5230            distinct: false,
5231            trailing_comments: Vec::new(),
5232            use_bracket_syntax: false,
5233            no_parens: false,
5234            quoted: false,
5235            span: None,
5236            inferred_type: None,
5237        }
5238    }
5239}
5240
5241/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
5242///
5243/// This struct is used for aggregate function calls that are not covered by
5244/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
5245/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
5246/// IGNORE NULLS / RESPECT NULLS modifiers.
5247#[derive(
5248    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
5249)]
5250#[cfg_attr(feature = "bindings", derive(TS))]
5251pub struct AggregateFunction {
5252    /// Dialect whose call semantics must be retained through independent generation.
5253    #[serde(default, skip_serializing_if = "Option::is_none")]
5254    #[ast(skip)]
5255    pub source_dialect: Option<crate::dialects::DialectType>,
5256
5257    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
5258    pub name: String,
5259    /// Positional arguments.
5260    pub args: Vec<Expression>,
5261    /// Whether DISTINCT was specified.
5262    pub distinct: bool,
5263    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
5264    pub filter: Option<Expression>,
5265    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
5266    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5267    pub order_by: Vec<Ordered>,
5268    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
5269    #[serde(default, skip_serializing_if = "Option::is_none")]
5270    pub limit: Option<Box<Expression>>,
5271    /// IGNORE NULLS / RESPECT NULLS
5272    #[serde(default, skip_serializing_if = "Option::is_none")]
5273    pub ignore_nulls: Option<bool>,
5274    /// Inferred data type from type annotation
5275    #[serde(default, skip_serializing_if = "Option::is_none")]
5276    #[ast(skip)]
5277    pub inferred_type: Option<DataType>,
5278}
5279
5280/// Represent a window function call with its OVER clause.
5281///
5282/// The inner `this` expression is typically a window-specific expression
5283/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
5284/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
5285/// frame specification.
5286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5287#[cfg_attr(feature = "bindings", derive(TS))]
5288pub struct WindowFunction {
5289    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
5290    pub this: Expression,
5291    /// The OVER clause defining the window partitioning, ordering, and frame.
5292    pub over: Over,
5293    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
5294    #[serde(default, skip_serializing_if = "Option::is_none")]
5295    pub keep: Option<Keep>,
5296    /// Inferred data type from type annotation
5297    #[serde(default, skip_serializing_if = "Option::is_none")]
5298    #[ast(skip)]
5299    pub inferred_type: Option<DataType>,
5300}
5301
5302/// Oracle KEEP clause for aggregate functions
5303/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
5304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5305#[cfg_attr(feature = "bindings", derive(TS))]
5306pub struct Keep {
5307    /// true = FIRST, false = LAST
5308    pub first: bool,
5309    /// ORDER BY clause inside KEEP
5310    pub order_by: Vec<Ordered>,
5311}
5312
5313/// WITHIN GROUP clause (for ordered-set aggregate functions)
5314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5315#[cfg_attr(feature = "bindings", derive(TS))]
5316pub struct WithinGroup {
5317    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
5318    pub this: Expression,
5319    /// The ORDER BY clause within the group
5320    pub order_by: Vec<Ordered>,
5321}
5322
5323/// Represent the FROM clause of a SELECT statement.
5324///
5325/// Contains one or more table sources (tables, subqueries, table-valued
5326/// functions, etc.). Multiple entries represent comma-separated implicit joins.
5327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5328#[cfg_attr(feature = "bindings", derive(TS))]
5329pub struct From {
5330    /// The table source expressions.
5331    pub expressions: Vec<Expression>,
5332}
5333
5334/// Represent a JOIN clause between two table sources.
5335///
5336/// The join condition can be specified via `on` (ON predicate) or `using`
5337/// (USING column list), but not both. The `kind` field determines the join
5338/// type (INNER, LEFT, CROSS, etc.).
5339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5340#[cfg_attr(feature = "bindings", derive(TS))]
5341pub struct Join {
5342    /// The right-hand table expression being joined.
5343    pub this: Expression,
5344    /// The ON condition (mutually exclusive with `using`).
5345    pub on: Option<Expression>,
5346    /// The USING column list (mutually exclusive with `on`).
5347    pub using: Vec<Identifier>,
5348    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5349    pub kind: JoinKind,
5350    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5351    pub use_inner_keyword: bool,
5352    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5353    pub use_outer_keyword: bool,
5354    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5355    pub deferred_condition: bool,
5356    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5357    #[serde(default, skip_serializing_if = "Option::is_none")]
5358    pub join_hint: Option<String>,
5359    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5360    #[serde(default, skip_serializing_if = "Option::is_none")]
5361    pub match_condition: Option<Expression>,
5362    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5363    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5364    pub pivots: Vec<Expression>,
5365    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5366    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5367    pub comments: Vec<String>,
5368    /// Nesting group identifier for nested join pretty-printing.
5369    /// Joins in the same group were parsed together; group boundaries come from
5370    /// deferred condition resolution phases.
5371    #[serde(default)]
5372    pub nesting_group: usize,
5373    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5374    #[serde(default)]
5375    pub directed: bool,
5376}
5377
5378/// Enumerate all supported SQL join types.
5379///
5380/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5381/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5382/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5383/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5384#[derive(
5385    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5386)]
5387#[cfg_attr(feature = "bindings", derive(TS))]
5388pub enum JoinKind {
5389    Inner,
5390    Left,
5391    Right,
5392    Full,
5393    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5394    Cross,
5395    Natural,
5396    NaturalLeft,
5397    NaturalRight,
5398    NaturalFull,
5399    Semi,
5400    Anti,
5401    // Directional SEMI/ANTI joins
5402    LeftSemi,
5403    LeftAnti,
5404    RightSemi,
5405    RightAnti,
5406    // SQL Server specific
5407    CrossApply,
5408    OuterApply,
5409    // Time-series specific
5410    AsOf,
5411    AsOfLeft,
5412    AsOfRight,
5413    // Lateral join
5414    Lateral,
5415    LeftLateral,
5416    // MySQL specific
5417    Straight,
5418    // Implicit join (comma-separated tables: FROM a, b)
5419    Implicit,
5420    // ClickHouse ARRAY JOIN
5421    Array,
5422    LeftArray,
5423    // ClickHouse PASTE JOIN (positional join)
5424    Paste,
5425    // DuckDB POSITIONAL JOIN
5426    Positional,
5427}
5428
5429impl Default for JoinKind {
5430    fn default() -> Self {
5431        JoinKind::Inner
5432    }
5433}
5434
5435/// Parenthesized table expression with joins
5436/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5438#[cfg_attr(feature = "bindings", derive(TS))]
5439pub struct JoinedTable {
5440    /// The left-hand side table expression
5441    pub left: Expression,
5442    /// The joins applied to the left table
5443    pub joins: Vec<Join>,
5444    /// LATERAL VIEW clauses (Hive/Spark)
5445    pub lateral_views: Vec<LateralView>,
5446    /// Optional alias for the joined table expression
5447    pub alias: Option<Identifier>,
5448}
5449
5450/// Represent a WHERE clause containing a boolean filter predicate.
5451#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5452#[cfg_attr(feature = "bindings", derive(TS))]
5453pub struct Where {
5454    /// The filter predicate expression.
5455    pub this: Expression,
5456}
5457
5458/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5459///
5460/// The `expressions` list may contain plain columns, ordinal positions,
5461/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5463#[cfg_attr(feature = "bindings", derive(TS))]
5464pub struct GroupBy {
5465    /// The grouping expressions.
5466    pub expressions: Vec<Expression>,
5467    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5468    #[serde(default)]
5469    pub all: Option<bool>,
5470    /// ClickHouse: WITH TOTALS modifier
5471    #[serde(default)]
5472    pub totals: bool,
5473    /// Leading comments that appeared before the GROUP BY keyword
5474    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5475    pub comments: Vec<String>,
5476}
5477
5478/// Represent a HAVING clause containing a predicate over aggregate results.
5479#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5480#[cfg_attr(feature = "bindings", derive(TS))]
5481pub struct Having {
5482    /// The filter predicate, typically involving aggregate functions.
5483    pub this: Expression,
5484    /// Leading comments that appeared before the HAVING keyword
5485    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5486    pub comments: Vec<String>,
5487}
5488
5489/// Represent an ORDER BY clause containing one or more sort specifications.
5490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5491#[cfg_attr(feature = "bindings", derive(TS))]
5492pub struct OrderBy {
5493    /// The sort specifications, each with direction and null ordering.
5494    pub expressions: Vec<Ordered>,
5495    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5496    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5497    pub siblings: bool,
5498    /// Leading comments that appeared before the ORDER BY keyword
5499    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5500    pub comments: Vec<String>,
5501}
5502
5503/// Represent an expression with sort direction and null ordering.
5504///
5505/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5506/// When `desc` is false the sort is ascending. The `nulls_first` field
5507/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5508/// (database default).
5509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5510#[cfg_attr(feature = "bindings", derive(TS))]
5511pub struct Ordered {
5512    /// Vertica lets the engine select null placement for aggregate/window ordering.
5513    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5514    pub nulls_auto: bool,
5515    /// The expression to sort by.
5516    pub this: Expression,
5517    /// Whether the sort direction is descending (true) or ascending (false).
5518    pub desc: bool,
5519    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5520    pub nulls_first: Option<bool>,
5521    /// Whether ASC was explicitly written (not just implied)
5522    #[serde(default)]
5523    pub explicit_asc: bool,
5524    /// ClickHouse WITH FILL clause
5525    #[serde(default, skip_serializing_if = "Option::is_none")]
5526    pub with_fill: Option<Box<WithFill>>,
5527}
5528
5529impl Ordered {
5530    pub fn asc(expr: Expression) -> Self {
5531        Self {
5532            nulls_auto: false,
5533            this: expr,
5534            desc: false,
5535            nulls_first: None,
5536            explicit_asc: false,
5537            with_fill: None,
5538        }
5539    }
5540
5541    pub fn desc(expr: Expression) -> Self {
5542        Self {
5543            nulls_auto: false,
5544            this: expr,
5545            desc: true,
5546            nulls_first: None,
5547            explicit_asc: false,
5548            with_fill: None,
5549        }
5550    }
5551}
5552
5553/// DISTRIBUTE BY clause (Hive/Spark)
5554/// Controls how rows are distributed across reducers
5555#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5556#[cfg_attr(feature = "bindings", derive(TS))]
5557#[cfg_attr(feature = "bindings", ts(export))]
5558pub struct DistributeBy {
5559    pub expressions: Vec<Expression>,
5560}
5561
5562/// CLUSTER BY clause (Hive/Spark)
5563/// Combines DISTRIBUTE BY and SORT BY on the same columns
5564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5565#[cfg_attr(feature = "bindings", derive(TS))]
5566#[cfg_attr(feature = "bindings", ts(export))]
5567pub struct ClusterBy {
5568    pub expressions: Vec<Ordered>,
5569}
5570
5571/// SORT BY clause (Hive/Spark)
5572/// Sorts data within each reducer (local sort, not global)
5573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5574#[cfg_attr(feature = "bindings", derive(TS))]
5575#[cfg_attr(feature = "bindings", ts(export))]
5576pub struct SortBy {
5577    pub expressions: Vec<Ordered>,
5578}
5579
5580/// LATERAL VIEW clause (Hive/Spark)
5581/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5582#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5583#[cfg_attr(feature = "bindings", derive(TS))]
5584#[cfg_attr(feature = "bindings", ts(export))]
5585pub struct LateralView {
5586    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5587    pub this: Expression,
5588    /// Table alias for the generated table
5589    pub table_alias: Option<Identifier>,
5590    /// Column aliases for the generated columns
5591    pub column_aliases: Vec<Identifier>,
5592    /// OUTER keyword - preserve nulls when input is empty/null
5593    pub outer: bool,
5594}
5595
5596/// Query hint
5597#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5598#[cfg_attr(feature = "bindings", derive(TS))]
5599#[cfg_attr(feature = "bindings", ts(export))]
5600pub struct Hint {
5601    #[serde(default, skip_serializing_if = "Option::is_none")]
5602    #[ast(skip)]
5603    pub source_dialect: Option<crate::dialects::DialectType>,
5604    pub expressions: Vec<HintExpression>,
5605}
5606
5607/// Individual hint expression
5608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5609#[cfg_attr(feature = "bindings", derive(TS))]
5610#[cfg_attr(feature = "bindings", ts(export))]
5611pub enum HintExpression {
5612    /// A structured hint directive with optional execution scope modifiers.
5613    Directive {
5614        name: Identifier,
5615        arguments: Option<Vec<Expression>>,
5616        remote: bool,
5617        cascade: bool,
5618    },
5619    /// Function-style hint: USE_HASH(table)
5620    Function { name: String, args: Vec<Expression> },
5621    /// Simple identifier hint: PARALLEL
5622    Identifier(String),
5623    /// Raw hint text (unparsed)
5624    Raw(String),
5625}
5626
5627/// Pseudocolumn type
5628#[derive(
5629    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5630)]
5631#[cfg_attr(feature = "bindings", derive(TS))]
5632#[cfg_attr(feature = "bindings", ts(export))]
5633pub enum PseudocolumnType {
5634    Rownum,      // Oracle ROWNUM
5635    Rowid,       // Oracle ROWID
5636    Level,       // Oracle LEVEL (for CONNECT BY)
5637    Sysdate,     // Oracle SYSDATE
5638    ObjectId,    // Oracle OBJECT_ID
5639    ObjectValue, // Oracle OBJECT_VALUE
5640}
5641
5642impl PseudocolumnType {
5643    pub fn as_str(&self) -> &'static str {
5644        match self {
5645            PseudocolumnType::Rownum => "ROWNUM",
5646            PseudocolumnType::Rowid => "ROWID",
5647            PseudocolumnType::Level => "LEVEL",
5648            PseudocolumnType::Sysdate => "SYSDATE",
5649            PseudocolumnType::ObjectId => "OBJECT_ID",
5650            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5651        }
5652    }
5653
5654    pub fn from_str(s: &str) -> Option<Self> {
5655        match s.to_uppercase().as_str() {
5656            "ROWNUM" => Some(PseudocolumnType::Rownum),
5657            "ROWID" => Some(PseudocolumnType::Rowid),
5658            "LEVEL" => Some(PseudocolumnType::Level),
5659            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5660            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5661            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5662            _ => None,
5663        }
5664    }
5665}
5666
5667/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5668/// These are special identifiers that should not be quoted
5669#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5670#[cfg_attr(feature = "bindings", derive(TS))]
5671#[cfg_attr(feature = "bindings", ts(export))]
5672pub struct Pseudocolumn {
5673    pub kind: PseudocolumnType,
5674}
5675
5676impl Pseudocolumn {
5677    pub fn rownum() -> Self {
5678        Self {
5679            kind: PseudocolumnType::Rownum,
5680        }
5681    }
5682
5683    pub fn rowid() -> Self {
5684        Self {
5685            kind: PseudocolumnType::Rowid,
5686        }
5687    }
5688
5689    pub fn level() -> Self {
5690        Self {
5691            kind: PseudocolumnType::Level,
5692        }
5693    }
5694}
5695
5696/// Oracle CONNECT BY clause for hierarchical queries
5697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5698#[cfg_attr(feature = "bindings", derive(TS))]
5699#[cfg_attr(feature = "bindings", ts(export))]
5700pub struct Connect {
5701    /// START WITH condition (optional, can come before or after CONNECT BY)
5702    pub start: Option<Expression>,
5703    /// CONNECT BY condition (required, contains PRIOR references)
5704    pub connect: Expression,
5705    /// NOCYCLE keyword to prevent infinite loops
5706    pub nocycle: bool,
5707}
5708
5709/// Oracle PRIOR expression - references parent row's value in CONNECT BY
5710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5711#[cfg_attr(feature = "bindings", derive(TS))]
5712#[cfg_attr(feature = "bindings", ts(export))]
5713pub struct Prior {
5714    pub this: Expression,
5715}
5716
5717/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5719#[cfg_attr(feature = "bindings", derive(TS))]
5720#[cfg_attr(feature = "bindings", ts(export))]
5721pub struct ConnectByRoot {
5722    pub this: Expression,
5723}
5724
5725/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5727#[cfg_attr(feature = "bindings", derive(TS))]
5728#[cfg_attr(feature = "bindings", ts(export))]
5729pub struct MatchRecognize {
5730    /// Source table/expression
5731    pub this: Option<Box<Expression>>,
5732    /// PARTITION BY expressions
5733    pub partition_by: Option<Vec<Expression>>,
5734    /// ORDER BY expressions
5735    pub order_by: Option<Vec<Ordered>>,
5736    /// MEASURES definitions
5737    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5738    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5739    pub rows: Option<MatchRecognizeRows>,
5740    /// AFTER MATCH SKIP behavior
5741    pub after: Option<MatchRecognizeAfter>,
5742    /// PATTERN definition (stored as raw string for complex regex patterns)
5743    pub pattern: Option<String>,
5744    /// DEFINE clauses (pattern variable definitions)
5745    pub define: Option<Vec<(Identifier, Expression)>>,
5746    /// Optional alias for the result
5747    pub alias: Option<Identifier>,
5748    /// Whether AS keyword was explicitly present before alias
5749    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5750    pub alias_explicit_as: bool,
5751}
5752
5753/// MEASURES expression with optional RUNNING/FINAL semantics
5754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5755#[cfg_attr(feature = "bindings", derive(TS))]
5756#[cfg_attr(feature = "bindings", ts(export))]
5757pub struct MatchRecognizeMeasure {
5758    /// The measure expression
5759    pub this: Expression,
5760    /// RUNNING or FINAL semantics (Snowflake-specific)
5761    pub window_frame: Option<MatchRecognizeSemantics>,
5762}
5763
5764/// Semantics for MEASURES in MATCH_RECOGNIZE
5765#[derive(
5766    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5767)]
5768#[cfg_attr(feature = "bindings", derive(TS))]
5769#[cfg_attr(feature = "bindings", ts(export))]
5770pub enum MatchRecognizeSemantics {
5771    Running,
5772    Final,
5773}
5774
5775/// Row output semantics for MATCH_RECOGNIZE
5776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5777#[cfg_attr(feature = "bindings", derive(TS))]
5778#[cfg_attr(feature = "bindings", ts(export))]
5779pub enum MatchRecognizeRows {
5780    OneRowPerMatch,
5781    AllRowsPerMatch,
5782    AllRowsPerMatchShowEmptyMatches,
5783    AllRowsPerMatchOmitEmptyMatches,
5784    AllRowsPerMatchWithUnmatchedRows,
5785}
5786
5787/// AFTER MATCH SKIP behavior
5788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5789#[cfg_attr(feature = "bindings", derive(TS))]
5790#[cfg_attr(feature = "bindings", ts(export))]
5791pub enum MatchRecognizeAfter {
5792    PastLastRow,
5793    ToNextRow,
5794    ToFirst(Identifier),
5795    ToLast(Identifier),
5796}
5797
5798/// Represent a LIMIT clause that restricts the number of returned rows.
5799#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5800#[cfg_attr(feature = "bindings", derive(TS))]
5801pub struct Limit {
5802    /// The limit count expression.
5803    pub this: Expression,
5804    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5805    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5806    pub percent: bool,
5807    /// Comments from before the LIMIT keyword (emitted after the limit value)
5808    #[serde(default)]
5809    #[serde(skip_serializing_if = "Vec::is_empty")]
5810    pub comments: Vec<String>,
5811}
5812
5813impl Limit {
5814    /// Preserve the legacy count-only set-operation AST when no metadata is needed.
5815    pub(crate) fn into_set_limit(self) -> Box<Expression> {
5816        if self.percent || !self.comments.is_empty() {
5817            Box::new(Expression::Limit(Box::new(self)))
5818        } else {
5819            Box::new(self.this)
5820        }
5821    }
5822}
5823
5824/// Move a compound query's row limit onto a SELECT without losing clause options.
5825/// Bare expressions remain supported for existing builders and serialized ASTs.
5826pub(crate) fn split_set_limit(limit: Option<Box<Expression>>) -> (Option<Limit>, Option<Fetch>) {
5827    match limit.map(|limit| *limit) {
5828        Some(Expression::Limit(limit)) => (Some(*limit), None),
5829        Some(Expression::Fetch(fetch)) => (None, Some(*fetch)),
5830        Some(this) => (
5831            Some(Limit {
5832                this,
5833                percent: false,
5834                comments: Vec::new(),
5835            }),
5836            None,
5837        ),
5838        None => (None, None),
5839    }
5840}
5841
5842/// OFFSET clause
5843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5844#[cfg_attr(feature = "bindings", derive(TS))]
5845pub struct Offset {
5846    pub this: Expression,
5847    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5848    #[serde(skip_serializing_if = "Option::is_none", default)]
5849    pub rows: Option<bool>,
5850}
5851
5852/// TOP clause (SQL Server)
5853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5854#[cfg_attr(feature = "bindings", derive(TS))]
5855pub struct Top {
5856    pub this: Expression,
5857    pub percent: bool,
5858    pub with_ties: bool,
5859    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5860    #[serde(default)]
5861    pub parenthesized: bool,
5862}
5863
5864/// FETCH FIRST/NEXT clause (SQL standard)
5865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5866#[cfg_attr(feature = "bindings", derive(TS))]
5867pub struct Fetch {
5868    /// FIRST or NEXT
5869    pub direction: String,
5870    /// Count expression (optional)
5871    pub count: Option<Expression>,
5872    /// PERCENT modifier
5873    pub percent: bool,
5874    /// ROWS or ROW keyword present
5875    pub rows: bool,
5876    /// WITH TIES modifier
5877    pub with_ties: bool,
5878}
5879
5880/// Represent a QUALIFY clause for filtering on window function results.
5881///
5882/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5883/// typically references a window function (e.g.
5884/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5885#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5886#[cfg_attr(feature = "bindings", derive(TS))]
5887pub struct Qualify {
5888    /// The filter predicate over window function results.
5889    pub this: Expression,
5890}
5891
5892/// SAMPLE / TABLESAMPLE clause
5893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5894#[cfg_attr(feature = "bindings", derive(TS))]
5895pub struct Sample {
5896    pub method: SampleMethod,
5897    pub size: Expression,
5898    pub seed: Option<Expression>,
5899    /// ClickHouse OFFSET expression after SAMPLE size
5900    #[serde(default)]
5901    pub offset: Option<Expression>,
5902    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5903    pub unit_after_size: bool,
5904    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5905    #[serde(default)]
5906    pub use_sample_keyword: bool,
5907    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5908    #[serde(default)]
5909    pub explicit_method: bool,
5910    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5911    #[serde(default)]
5912    pub method_before_size: bool,
5913    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5914    #[serde(default)]
5915    pub use_seed_keyword: bool,
5916    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5917    pub bucket_numerator: Option<Box<Expression>>,
5918    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5919    pub bucket_denominator: Option<Box<Expression>>,
5920    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5921    pub bucket_field: Option<Box<Expression>>,
5922    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5923    #[serde(default)]
5924    pub is_using_sample: bool,
5925    /// Whether the unit was explicitly PERCENT (vs ROWS)
5926    #[serde(default)]
5927    pub is_percent: bool,
5928    /// Whether to suppress method output (for cross-dialect transpilation)
5929    #[serde(default)]
5930    pub suppress_method_output: bool,
5931}
5932
5933/// Sample method
5934#[derive(
5935    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5936)]
5937#[cfg_attr(feature = "bindings", derive(TS))]
5938pub enum SampleMethod {
5939    Bernoulli,
5940    System,
5941    Block,
5942    Row,
5943    Percent,
5944    /// Hive bucket sampling
5945    Bucket,
5946    /// DuckDB reservoir sampling
5947    Reservoir,
5948}
5949
5950/// Named window definition (WINDOW w AS (...))
5951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5952#[cfg_attr(feature = "bindings", derive(TS))]
5953pub struct NamedWindow {
5954    pub name: Identifier,
5955    pub spec: Over,
5956}
5957
5958/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5959///
5960/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5961/// that reference themselves. Each CTE is defined in the `ctes` vector and
5962/// can be referenced by name in subsequent CTEs and in the main query body.
5963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5964#[cfg_attr(feature = "bindings", derive(TS))]
5965pub struct With {
5966    /// The list of CTE definitions, in order.
5967    pub ctes: Vec<Cte>,
5968    /// Whether the WITH RECURSIVE keyword was used.
5969    pub recursive: bool,
5970    /// Leading comments before the statement
5971    #[serde(default)]
5972    pub leading_comments: Vec<String>,
5973    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5974    #[serde(default, skip_serializing_if = "Option::is_none")]
5975    pub search: Option<Box<Expression>>,
5976}
5977
5978/// Represent a single Common Table Expression definition.
5979///
5980/// A CTE has a name (`alias`), an optional column list, and a body query.
5981/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5982/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5983/// the expression comes before the alias (`alias_first`).
5984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5985#[cfg_attr(feature = "bindings", derive(TS))]
5986pub struct Cte {
5987    /// The CTE name.
5988    pub alias: Identifier,
5989    /// The CTE body (typically a SELECT, UNION, etc.).
5990    pub this: Expression,
5991    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5992    pub columns: Vec<Identifier>,
5993    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5994    pub materialized: Option<bool>,
5995    /// USING KEY (columns) for DuckDB recursive CTEs
5996    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5997    pub key_expressions: Vec<Identifier>,
5998    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5999    #[serde(default)]
6000    pub alias_first: bool,
6001    /// Comments associated with this CTE (placed after alias name, before AS)
6002    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6003    pub comments: Vec<String>,
6004}
6005
6006/// Window specification
6007#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6008#[cfg_attr(feature = "bindings", derive(TS))]
6009pub struct WindowSpec {
6010    pub partition_by: Vec<Expression>,
6011    pub order_by: Vec<Ordered>,
6012    pub frame: Option<WindowFrame>,
6013}
6014
6015/// OVER clause
6016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6017#[cfg_attr(feature = "bindings", derive(TS))]
6018pub struct Over {
6019    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
6020    pub window_name: Option<Identifier>,
6021    pub partition_by: Vec<Expression>,
6022    pub order_by: Vec<Ordered>,
6023    pub frame: Option<WindowFrame>,
6024    pub alias: Option<Identifier>,
6025}
6026
6027/// Window frame
6028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6029#[cfg_attr(feature = "bindings", derive(TS))]
6030pub struct WindowFrame {
6031    pub kind: WindowFrameKind,
6032    pub start: WindowFrameBound,
6033    pub end: Option<WindowFrameBound>,
6034    pub exclude: Option<WindowFrameExclude>,
6035    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
6036    #[serde(default, skip_serializing_if = "Option::is_none")]
6037    pub kind_text: Option<String>,
6038    /// Original text of the start bound side keyword (e.g. "preceding")
6039    #[serde(default, skip_serializing_if = "Option::is_none")]
6040    pub start_side_text: Option<String>,
6041    /// Original text of the end bound side keyword
6042    #[serde(default, skip_serializing_if = "Option::is_none")]
6043    pub end_side_text: Option<String>,
6044}
6045
6046#[derive(
6047    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6048)]
6049#[cfg_attr(feature = "bindings", derive(TS))]
6050pub enum WindowFrameKind {
6051    Rows,
6052    Range,
6053    Groups,
6054}
6055
6056/// EXCLUDE clause for window frames
6057#[derive(
6058    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6059)]
6060#[cfg_attr(feature = "bindings", derive(TS))]
6061pub enum WindowFrameExclude {
6062    CurrentRow,
6063    Group,
6064    Ties,
6065    NoOthers,
6066}
6067
6068#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6069#[cfg_attr(feature = "bindings", derive(TS))]
6070pub enum WindowFrameBound {
6071    CurrentRow,
6072    UnboundedPreceding,
6073    UnboundedFollowing,
6074    Preceding(Box<Expression>),
6075    Following(Box<Expression>),
6076    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
6077    BarePreceding,
6078    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
6079    BareFollowing,
6080    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
6081    Value(Box<Expression>),
6082}
6083
6084/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
6085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6086#[cfg_attr(feature = "bindings", derive(TS))]
6087pub struct StructField {
6088    /// A raw field name, or a delimited identifier for compatibility with parsed ASTs.
6089    /// Parsed quoted names use double quotes with doubled internal quotes. An empty
6090    /// string denotes an anonymous field. Generation selects the target dialect's quotes.
6091    pub name: String,
6092    pub data_type: DataType,
6093    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6094    pub options: Vec<Expression>,
6095    #[serde(default, skip_serializing_if = "Option::is_none")]
6096    pub comment: Option<String>,
6097}
6098
6099impl StructField {
6100    /// Create a new struct field without options
6101    pub fn new(name: String, data_type: DataType) -> Self {
6102        Self {
6103            name,
6104            data_type,
6105            options: Vec::new(),
6106            comment: None,
6107        }
6108    }
6109
6110    /// Create a new struct field with options
6111    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
6112        Self {
6113            name,
6114            data_type,
6115            options,
6116            comment: None,
6117        }
6118    }
6119
6120    /// Create a new struct field with options and comment
6121    pub fn with_options_and_comment(
6122        name: String,
6123        data_type: DataType,
6124        options: Vec<Expression>,
6125        comment: Option<String>,
6126    ) -> Self {
6127        Self {
6128            name,
6129            data_type,
6130            options,
6131            comment,
6132        }
6133    }
6134}
6135
6136/// Oracle-specific data types whose semantics cannot be represented losslessly by the
6137/// generic [`DataType`] variants.
6138///
6139/// Keeping these types structured allows the Oracle parser to retain details such as a
6140/// negative `NUMBER` scale, `BYTE`/`CHAR` length semantics, interval precisions, and
6141/// `TIMESTAMP WITH LOCAL TIME ZONE` until the target dialect is known.
6142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6143#[cfg_attr(feature = "bindings", derive(TS))]
6144#[serde(tag = "oracle_data_type", rename_all = "snake_case")]
6145pub enum OracleDataType {
6146    Number {
6147        precision: Option<u32>,
6148        scale: Option<i32>,
6149    },
6150    BinaryFloat,
6151    BinaryDouble,
6152    Float {
6153        precision: Option<u32>,
6154    },
6155    Character {
6156        kind: OracleCharacterKind,
6157        length: Option<u32>,
6158        semantics: Option<OracleCharacterLengthSemantics>,
6159    },
6160    Date,
6161    Timestamp {
6162        precision: Option<u32>,
6163        timezone: OracleTimestampTimeZone,
6164    },
6165    IntervalYearToMonth {
6166        year_precision: Option<u32>,
6167    },
6168    IntervalDayToSecond {
6169        day_precision: Option<u32>,
6170        fractional_seconds_precision: Option<u32>,
6171    },
6172    Clob {
6173        national: bool,
6174    },
6175    Blob,
6176    Raw {
6177        length: Option<u32>,
6178    },
6179    Long {
6180        raw: bool,
6181    },
6182    RowId,
6183}
6184
6185#[derive(
6186    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6187)]
6188#[cfg_attr(feature = "bindings", derive(TS))]
6189#[serde(rename_all = "snake_case")]
6190pub enum OracleCharacterKind {
6191    Char,
6192    VarChar,
6193    NChar,
6194    NVarChar,
6195}
6196
6197#[derive(
6198    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6199)]
6200#[cfg_attr(feature = "bindings", derive(TS))]
6201#[serde(rename_all = "snake_case")]
6202pub enum OracleCharacterLengthSemantics {
6203    Byte,
6204    Char,
6205}
6206
6207#[derive(
6208    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6209)]
6210#[cfg_attr(feature = "bindings", derive(TS))]
6211#[serde(rename_all = "snake_case")]
6212pub enum OracleTimestampTimeZone {
6213    None,
6214    WithTimeZone,
6215    WithLocalTimeZone,
6216}
6217
6218/// Enumerate all SQL data types recognized by the parser.
6219///
6220/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
6221/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
6222/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
6223///
6224/// This enum is used in CAST expressions, column definitions, function return
6225/// types, and anywhere a data type specification appears in SQL.
6226///
6227/// Types that do not match any known variant fall through to `Custom { name }`,
6228/// preserving the original type name for round-trip fidelity.
6229#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6230#[cfg_attr(feature = "bindings", derive(TS))]
6231#[serde(tag = "data_type", rename_all = "snake_case")]
6232pub enum DataType {
6233    Vertica {
6234        vertica_type: Box<VerticaDataType>,
6235    },
6236    // Numeric
6237    Boolean,
6238    TinyInt {
6239        length: Option<u32>,
6240    },
6241    SmallInt {
6242        length: Option<u32>,
6243    },
6244    /// Int type with optional length. `integer_spelling` indicates whether the original
6245    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
6246    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
6247    Int {
6248        length: Option<u32>,
6249        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6250        integer_spelling: bool,
6251    },
6252    BigInt {
6253        length: Option<u32>,
6254    },
6255    /// Signed 128-bit integer (DuckDB HUGEINT, ClickHouse Int128, StarRocks LARGEINT).
6256    Int128,
6257    /// Unsigned 8-bit integer (DuckDB UTINYINT, ClickHouse UInt8).
6258    #[serde(rename = "uint8")]
6259    UInt8,
6260    /// Unsigned 16-bit integer (DuckDB USMALLINT, ClickHouse UInt16).
6261    #[serde(rename = "uint16")]
6262    UInt16,
6263    /// Unsigned 32-bit integer (DuckDB UINTEGER, ClickHouse UInt32).
6264    #[serde(rename = "uint32")]
6265    UInt32,
6266    /// Unsigned 64-bit integer (DuckDB UBIGINT, ClickHouse UInt64).
6267    #[serde(rename = "uint64")]
6268    UInt64,
6269    /// Unsigned 128-bit integer (DuckDB UHUGEINT, ClickHouse UInt128).
6270    #[serde(rename = "uint128")]
6271    UInt128,
6272    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
6273    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
6274    /// preserve the original spelling.
6275    Float {
6276        precision: Option<u32>,
6277        scale: Option<u32>,
6278        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6279        real_spelling: bool,
6280    },
6281    Double {
6282        precision: Option<u32>,
6283        scale: Option<u32>,
6284    },
6285    Decimal {
6286        precision: Option<u32>,
6287        scale: Option<u32>,
6288    },
6289    /// Structured Oracle data type retained until the target dialect is known.
6290    Oracle {
6291        oracle_type: OracleDataType,
6292    },
6293
6294    /// A HANA type whose domain or syntax is not represented by a common type.
6295    Hana {
6296        hana_type: HanaDataType,
6297    },
6298
6299    // String
6300    Char {
6301        length: Option<u32>,
6302    },
6303    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
6304    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
6305    VarChar {
6306        length: Option<u32>,
6307        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6308        parenthesized_length: bool,
6309    },
6310    /// String type with optional max length (BigQuery STRING(n))
6311    String {
6312        length: Option<u32>,
6313    },
6314    Text,
6315    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
6316    TextWithLength {
6317        length: u32,
6318    },
6319
6320    // Binary
6321    Binary {
6322        length: Option<u32>,
6323    },
6324    VarBinary {
6325        length: Option<u32>,
6326    },
6327    Blob,
6328
6329    // Bit
6330    Bit {
6331        length: Option<u32>,
6332    },
6333    VarBit {
6334        length: Option<u32>,
6335    },
6336
6337    // Date/Time
6338    Date,
6339    Time {
6340        precision: Option<u32>,
6341        #[serde(default)]
6342        timezone: bool,
6343    },
6344    Timestamp {
6345        precision: Option<u32>,
6346        timezone: bool,
6347    },
6348    Interval {
6349        unit: Option<String>,
6350        /// For range intervals like INTERVAL DAY TO HOUR
6351        #[serde(default, skip_serializing_if = "Option::is_none")]
6352        to: Option<String>,
6353    },
6354
6355    // JSON
6356    Json,
6357    JsonB,
6358
6359    // UUID
6360    Uuid,
6361
6362    // Array
6363    Array {
6364        element_type: Box<DataType>,
6365        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
6366        #[serde(default, skip_serializing_if = "Option::is_none")]
6367        dimension: Option<u32>,
6368    },
6369
6370    /// List type (Materialize): INT LIST, TEXT LIST LIST
6371    /// Uses postfix LIST syntax instead of ARRAY<T>
6372    List {
6373        element_type: Box<DataType>,
6374    },
6375
6376    // Struct/Map
6377    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
6378    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
6379    Struct {
6380        fields: Vec<StructField>,
6381        nested: bool,
6382    },
6383    Map {
6384        key_type: Box<DataType>,
6385        value_type: Box<DataType>,
6386    },
6387
6388    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
6389    Enum {
6390        values: Vec<String>,
6391        #[serde(default, skip_serializing_if = "Vec::is_empty")]
6392        assignments: Vec<Option<String>>,
6393    },
6394
6395    // Set type (MySQL): SET('a', 'b', 'c')
6396    Set {
6397        values: Vec<String>,
6398    },
6399
6400    // Union type (DuckDB): UNION(num INT, str TEXT)
6401    Union {
6402        fields: Vec<(String, DataType)>,
6403    },
6404
6405    // Vector (Snowflake / SingleStore)
6406    Vector {
6407        #[serde(default)]
6408        element_type: Option<Box<DataType>>,
6409        dimension: Option<u32>,
6410    },
6411
6412    // Object (Snowflake structured type)
6413    // fields: Vec of (field_name, field_type, not_null)
6414    Object {
6415        fields: Vec<(String, DataType, bool)>,
6416        modifier: Option<String>,
6417    },
6418
6419    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
6420    Nullable {
6421        inner: Box<DataType>,
6422    },
6423
6424    // Custom/User-defined
6425    Custom {
6426        name: String,
6427    },
6428
6429    // Spatial types
6430    Geometry {
6431        subtype: Option<String>,
6432        srid: Option<u32>,
6433    },
6434    Geography {
6435        subtype: Option<String>,
6436        srid: Option<u32>,
6437    },
6438
6439    // Character Set (for CONVERT USING in MySQL)
6440    // Renders as CHAR CHARACTER SET {name} in cast target
6441    CharacterSet {
6442        name: String,
6443    },
6444
6445    // Unknown
6446    Unknown,
6447}
6448
6449/// Source-specific HANA type, retained until a target is selected.
6450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6451#[cfg_attr(feature = "bindings", derive(TS))]
6452pub struct HanaDataType {
6453    pub name: String,
6454    pub parameters: Vec<u32>,
6455}
6456
6457impl DataType {
6458    /// Canonical unsigned names and their bit-width aliases. Parser entry points
6459    /// and legacy Custom-type normalization share this mapping.
6460    pub(crate) fn from_unsigned_name(name: &str) -> Option<Self> {
6461        match name.to_ascii_uppercase().as_str() {
6462            "UTINYINT" | "UINT8" => Some(Self::UInt8),
6463            "USMALLINT" | "UINT16" => Some(Self::UInt16),
6464            "UINTEGER" | "UINT32" => Some(Self::UInt32),
6465            "UBIGINT" | "UINT64" => Some(Self::UInt64),
6466            "UHUGEINT" | "UINT128" => Some(Self::UInt128),
6467            _ => None,
6468        }
6469    }
6470}
6471
6472/// Array expression
6473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6474#[cfg_attr(feature = "bindings", derive(TS))]
6475#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
6476pub struct Array {
6477    pub expressions: Vec<Expression>,
6478    /// Inferred array data type from type annotation
6479    #[serde(default, skip_serializing_if = "Option::is_none")]
6480    #[ast(skip)]
6481    pub inferred_type: Option<DataType>,
6482}
6483
6484/// Struct expression
6485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6486#[cfg_attr(feature = "bindings", derive(TS))]
6487pub struct Struct {
6488    pub fields: Vec<(Option<String>, Expression)>,
6489}
6490
6491/// Tuple expression
6492#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6493#[cfg_attr(feature = "bindings", derive(TS))]
6494pub struct Tuple {
6495    pub expressions: Vec<Expression>,
6496}
6497
6498/// Interval expression
6499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6500#[cfg_attr(feature = "bindings", derive(TS))]
6501pub struct Interval {
6502    /// The value expression (e.g., '1', 5, column_ref)
6503    pub this: Option<Expression>,
6504    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
6505    pub unit: Option<IntervalUnitSpec>,
6506}
6507
6508/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
6509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6510#[cfg_attr(feature = "bindings", derive(TS))]
6511#[serde(tag = "type", rename_all = "snake_case")]
6512pub enum IntervalUnitSpec {
6513    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
6514    Simple {
6515        unit: IntervalUnit,
6516        /// Whether to use plural form (e.g., DAYS vs DAY)
6517        use_plural: bool,
6518    },
6519    /// Interval span (e.g., HOUR TO SECOND)
6520    Span(IntervalSpan),
6521    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6522    /// The start and end can be expressions like function calls with precision
6523    ExprSpan(IntervalSpanExpr),
6524    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6525    Expr(Box<Expression>),
6526}
6527
6528/// Interval span for ranges like HOUR TO SECOND
6529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6530#[cfg_attr(feature = "bindings", derive(TS))]
6531pub struct IntervalSpan {
6532    /// Start unit (e.g., HOUR)
6533    pub this: IntervalUnit,
6534    /// End unit (e.g., SECOND)
6535    pub expression: IntervalUnit,
6536}
6537
6538/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6539/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6541#[cfg_attr(feature = "bindings", derive(TS))]
6542pub struct IntervalSpanExpr {
6543    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6544    pub this: Box<Expression>,
6545    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6546    pub expression: Box<Expression>,
6547}
6548
6549#[derive(
6550    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6551)]
6552#[cfg_attr(feature = "bindings", derive(TS))]
6553pub enum IntervalUnit {
6554    Year,
6555    Quarter,
6556    Month,
6557    Week,
6558    Day,
6559    Hour,
6560    Minute,
6561    Second,
6562    Millisecond,
6563    Microsecond,
6564    Nanosecond,
6565}
6566
6567/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6568#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6569#[cfg_attr(feature = "bindings", derive(TS))]
6570pub struct Command {
6571    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6572    pub this: String,
6573}
6574
6575/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6576/// Syntax: PREPARE name [(type, ...)] AS statement
6577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6578#[cfg_attr(feature = "bindings", derive(TS))]
6579pub struct PrepareStatement {
6580    /// The prepared statement name.
6581    pub name: Identifier,
6582    /// Optional PostgreSQL parameter type list.
6583    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6584    pub parameter_types: Vec<DataType>,
6585    /// The statement to execute when the prepared statement is invoked.
6586    pub statement: Expression,
6587}
6588
6589/// T-SQL TRY/CATCH block.
6590#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6591#[cfg_attr(feature = "bindings", derive(TS))]
6592pub struct TryCatch {
6593    /// Statements inside BEGIN TRY ... END TRY.
6594    #[serde(default)]
6595    pub try_body: Vec<Expression>,
6596    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6597    #[serde(default, skip_serializing_if = "Option::is_none")]
6598    pub catch_body: Option<Vec<Expression>>,
6599}
6600
6601/// EXEC/EXECUTE statement (TSQL stored procedure call)
6602/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6604#[cfg_attr(feature = "bindings", derive(TS))]
6605pub struct ExecuteStatement {
6606    /// The procedure name (can be qualified: schema.proc_name)
6607    pub this: Expression,
6608    /// Optional T-SQL return-status variable (`EXECUTE @status = procedure`).
6609    #[serde(default, skip_serializing_if = "Option::is_none")]
6610    pub return_status: Option<String>,
6611    /// Named parameters: @param=value pairs
6612    #[serde(default)]
6613    pub parameters: Vec<ExecuteParameter>,
6614    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6615    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6616    pub arguments: Vec<Expression>,
6617    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6618    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6619    pub prepared: bool,
6620    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6621    #[serde(default, skip_serializing_if = "Option::is_none")]
6622    pub suffix: Option<String>,
6623}
6624
6625/// Named parameter in EXEC statement: @name=value
6626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6627#[cfg_attr(feature = "bindings", derive(TS))]
6628pub struct ExecuteParameter {
6629    /// Parameter name (including @)
6630    pub name: String,
6631    /// Parameter value
6632    pub value: Expression,
6633    /// Whether this is a positional parameter (no = sign)
6634    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6635    pub positional: bool,
6636    /// TSQL OUTPUT modifier on parameter
6637    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6638    pub output: bool,
6639}
6640
6641/// KILL statement (MySQL/MariaDB)
6642/// KILL [CONNECTION | QUERY] <id>
6643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6644#[cfg_attr(feature = "bindings", derive(TS))]
6645pub struct Kill {
6646    /// The target (process ID or connection ID)
6647    pub this: Expression,
6648    /// Optional kind: "CONNECTION" or "QUERY"
6649    pub kind: Option<String>,
6650}
6651
6652/// Snowflake CREATE TASK statement
6653#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6654#[cfg_attr(feature = "bindings", derive(TS))]
6655pub struct CreateTask {
6656    pub or_replace: bool,
6657    pub if_not_exists: bool,
6658    /// Task name (possibly qualified: db.schema.task)
6659    pub name: String,
6660    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6661    pub properties: String,
6662    /// The SQL statement body after AS
6663    pub body: Expression,
6664}
6665
6666/// Raw/unparsed SQL
6667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6668#[cfg_attr(feature = "bindings", derive(TS))]
6669pub struct Raw {
6670    pub sql: String,
6671}
6672
6673// ============================================================================
6674// Function expression types
6675// ============================================================================
6676
6677/// Generic unary function (takes a single argument)
6678#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6679#[cfg_attr(feature = "bindings", derive(TS))]
6680pub struct UnaryFunc {
6681    pub this: Expression,
6682    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6683    #[serde(skip_serializing_if = "Option::is_none", default)]
6684    pub original_name: Option<String>,
6685    /// Inferred data type from type annotation
6686    #[serde(default, skip_serializing_if = "Option::is_none")]
6687    #[ast(skip)]
6688    pub inferred_type: Option<DataType>,
6689}
6690
6691impl UnaryFunc {
6692    /// Create a new UnaryFunc with no original_name
6693    pub fn new(this: Expression) -> Self {
6694        Self {
6695            this,
6696            original_name: None,
6697            inferred_type: None,
6698        }
6699    }
6700
6701    /// Create a new UnaryFunc with an original name for round-trip preservation
6702    pub fn with_name(this: Expression, name: String) -> Self {
6703        Self {
6704            this,
6705            original_name: Some(name),
6706            inferred_type: None,
6707        }
6708    }
6709}
6710
6711/// CHAR/CHR function with multiple args and optional USING charset
6712/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6713/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6714#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6715#[cfg_attr(feature = "bindings", derive(TS))]
6716pub struct CharFunc {
6717    pub args: Vec<Expression>,
6718    #[serde(skip_serializing_if = "Option::is_none", default)]
6719    pub charset: Option<String>,
6720    /// Original function name (CHAR or CHR), defaults to CHAR
6721    #[serde(skip_serializing_if = "Option::is_none", default)]
6722    pub name: Option<String>,
6723}
6724
6725/// Generic binary function (takes two arguments)
6726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6727#[cfg_attr(feature = "bindings", derive(TS))]
6728pub struct BinaryFunc {
6729    pub this: Expression,
6730    pub expression: Expression,
6731    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6732    #[serde(skip_serializing_if = "Option::is_none", default)]
6733    pub original_name: Option<String>,
6734    /// Inferred data type from type annotation
6735    #[serde(default, skip_serializing_if = "Option::is_none")]
6736    #[ast(skip)]
6737    pub inferred_type: Option<DataType>,
6738}
6739
6740/// Variable argument function
6741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6742#[cfg_attr(feature = "bindings", derive(TS))]
6743pub struct VarArgFunc {
6744    pub expressions: Vec<Expression>,
6745    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6746    #[serde(skip_serializing_if = "Option::is_none", default)]
6747    pub original_name: Option<String>,
6748    /// Inferred data type from type annotation
6749    #[serde(default, skip_serializing_if = "Option::is_none")]
6750    #[ast(skip)]
6751    pub inferred_type: Option<DataType>,
6752}
6753
6754/// CONCAT_WS function
6755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6756#[cfg_attr(feature = "bindings", derive(TS))]
6757pub struct ConcatWs {
6758    pub separator: Expression,
6759    pub expressions: Vec<Expression>,
6760}
6761
6762/// SUBSTRING function
6763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6764#[cfg_attr(feature = "bindings", derive(TS))]
6765pub struct SubstringFunc {
6766    pub this: Expression,
6767    pub start: Expression,
6768    pub length: Option<Expression>,
6769    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6770    #[serde(default)]
6771    pub from_for_syntax: bool,
6772}
6773
6774/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6775#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6776#[cfg_attr(feature = "bindings", derive(TS))]
6777pub struct OverlayFunc {
6778    pub this: Expression,
6779    pub replacement: Expression,
6780    pub from: Expression,
6781    pub length: Option<Expression>,
6782}
6783
6784/// TRIM function
6785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6786#[cfg_attr(feature = "bindings", derive(TS))]
6787pub struct TrimFunc {
6788    pub this: Expression,
6789    pub characters: Option<Expression>,
6790    pub position: TrimPosition,
6791    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6792    #[serde(default)]
6793    pub sql_standard_syntax: bool,
6794    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6795    #[serde(default)]
6796    pub position_explicit: bool,
6797    /// Inferred data type from type annotation
6798    #[serde(default, skip_serializing_if = "Option::is_none")]
6799    #[ast(skip)]
6800    pub inferred_type: Option<DataType>,
6801}
6802
6803#[derive(
6804    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6805)]
6806#[cfg_attr(feature = "bindings", derive(TS))]
6807pub enum TrimPosition {
6808    Both,
6809    Leading,
6810    Trailing,
6811}
6812
6813/// REPLACE function
6814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6815#[cfg_attr(feature = "bindings", derive(TS))]
6816pub struct ReplaceFunc {
6817    pub this: Expression,
6818    pub old: Expression,
6819    pub new: Expression,
6820}
6821
6822/// LEFT/RIGHT function
6823#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6824#[cfg_attr(feature = "bindings", derive(TS))]
6825pub struct LeftRightFunc {
6826    pub this: Expression,
6827    pub length: Expression,
6828}
6829
6830/// REPEAT function
6831#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6832#[cfg_attr(feature = "bindings", derive(TS))]
6833pub struct RepeatFunc {
6834    pub this: Expression,
6835    pub times: Expression,
6836}
6837
6838/// LPAD/RPAD function
6839#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6840#[cfg_attr(feature = "bindings", derive(TS))]
6841pub struct PadFunc {
6842    pub this: Expression,
6843    pub length: Expression,
6844    pub fill: Option<Expression>,
6845}
6846
6847/// SPLIT function
6848#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6849#[cfg_attr(feature = "bindings", derive(TS))]
6850pub struct SplitFunc {
6851    pub this: Expression,
6852    pub delimiter: Expression,
6853}
6854
6855/// REGEXP_LIKE function
6856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6857#[cfg_attr(feature = "bindings", derive(TS))]
6858pub struct RegexpFunc {
6859    /// Additional search boundaries and retained source semantics.
6860    #[serde(default, skip_serializing_if = "Option::is_none")]
6861    pub options: Option<RegexOptions>,
6862    pub this: Expression,
6863    pub pattern: Expression,
6864    pub flags: Option<Expression>,
6865}
6866
6867/// REGEXP_REPLACE function
6868#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6869#[cfg_attr(feature = "bindings", derive(TS))]
6870pub struct RegexpReplaceFunc {
6871    /// Additional search boundaries and retained source semantics.
6872    #[serde(default, skip_serializing_if = "Option::is_none")]
6873    pub options: Option<RegexOptions>,
6874    pub this: Expression,
6875    pub pattern: Expression,
6876    pub replacement: Expression,
6877    pub flags: Option<Expression>,
6878}
6879
6880/// REGEXP_EXTRACT function
6881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6882#[cfg_attr(feature = "bindings", derive(TS))]
6883pub struct RegexpExtractFunc {
6884    /// Additional search boundaries and retained source semantics.
6885    #[serde(default, skip_serializing_if = "Option::is_none")]
6886    pub options: Option<RegexOptions>,
6887    pub this: Expression,
6888    pub pattern: Expression,
6889    pub group: Option<Expression>,
6890}
6891
6892/// ROUND function
6893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6894#[cfg_attr(feature = "bindings", derive(TS))]
6895pub struct RoundFunc {
6896    pub this: Expression,
6897    pub decimals: Option<Expression>,
6898}
6899
6900/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6902#[cfg_attr(feature = "bindings", derive(TS))]
6903pub struct FloorFunc {
6904    pub this: Expression,
6905    pub scale: Option<Expression>,
6906    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6907    #[serde(skip_serializing_if = "Option::is_none", default)]
6908    pub to: Option<Expression>,
6909}
6910
6911/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6913#[cfg_attr(feature = "bindings", derive(TS))]
6914pub struct CeilFunc {
6915    pub this: Expression,
6916    #[serde(skip_serializing_if = "Option::is_none", default)]
6917    pub decimals: Option<Expression>,
6918    /// Time unit for Druid-style CEIL(time TO unit) syntax
6919    #[serde(skip_serializing_if = "Option::is_none", default)]
6920    pub to: Option<Expression>,
6921}
6922
6923/// LOG function
6924#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6925#[cfg_attr(feature = "bindings", derive(TS))]
6926pub struct LogFunc {
6927    pub this: Expression,
6928    pub base: Option<Expression>,
6929}
6930
6931/// CURRENT_DATE (no arguments)
6932#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6933#[cfg_attr(feature = "bindings", derive(TS))]
6934pub struct CurrentDate;
6935
6936/// CURRENT_TIME
6937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6938#[cfg_attr(feature = "bindings", derive(TS))]
6939pub struct CurrentTime {
6940    pub precision: Option<u32>,
6941}
6942
6943/// CURRENT_TIMESTAMP
6944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6945#[cfg_attr(feature = "bindings", derive(TS))]
6946pub struct CurrentTimestamp {
6947    pub precision: Option<u32>,
6948    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6949    #[serde(default)]
6950    pub sysdate: bool,
6951}
6952
6953/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6955#[cfg_attr(feature = "bindings", derive(TS))]
6956pub struct CurrentTimestampLTZ {
6957    pub precision: Option<u32>,
6958}
6959
6960/// AT TIME ZONE expression for timezone conversion
6961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6962#[cfg_attr(feature = "bindings", derive(TS))]
6963pub struct AtTimeZone {
6964    /// The expression to convert
6965    pub this: Expression,
6966    /// The target timezone
6967    pub zone: Expression,
6968}
6969
6970/// DATE_ADD / DATE_SUB function
6971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6972#[cfg_attr(feature = "bindings", derive(TS))]
6973pub struct DateAddFunc {
6974    pub this: Expression,
6975    pub interval: Expression,
6976    pub unit: IntervalUnit,
6977}
6978
6979/// DATEDIFF function
6980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6981#[cfg_attr(feature = "bindings", derive(TS))]
6982pub struct DateDiffFunc {
6983    pub this: Expression,
6984    pub expression: Expression,
6985    pub unit: Option<IntervalUnit>,
6986}
6987
6988/// DATE_TRUNC function
6989#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6990#[cfg_attr(feature = "bindings", derive(TS))]
6991pub struct DateTruncFunc {
6992    pub this: Expression,
6993    pub unit: DateTimeField,
6994}
6995
6996/// EXTRACT function
6997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6998#[cfg_attr(feature = "bindings", derive(TS))]
6999pub struct ExtractFunc {
7000    pub this: Expression,
7001    pub field: DateTimeField,
7002}
7003
7004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7005#[cfg_attr(feature = "bindings", derive(TS))]
7006pub enum DateTimeField {
7007    Year,
7008    Month,
7009    Day,
7010    Hour,
7011    Minute,
7012    Second,
7013    Millisecond,
7014    Microsecond,
7015    DayOfWeek,
7016    DayOfYear,
7017    Week,
7018    /// Week with a modifier like WEEK(monday), WEEK(sunday)
7019    WeekWithModifier(String),
7020    Quarter,
7021    Epoch,
7022    Timezone,
7023    TimezoneHour,
7024    TimezoneMinute,
7025    Date,
7026    Time,
7027    /// Custom datetime field for dialect-specific or arbitrary fields
7028    Custom(String),
7029}
7030
7031/// TO_DATE function
7032#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7033#[cfg_attr(feature = "bindings", derive(TS))]
7034pub struct ToDateFunc {
7035    pub this: Expression,
7036    pub format: Option<Expression>,
7037}
7038
7039/// TO_TIMESTAMP function
7040#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7041#[cfg_attr(feature = "bindings", derive(TS))]
7042pub struct ToTimestampFunc {
7043    pub this: Expression,
7044    pub format: Option<Expression>,
7045}
7046
7047/// IF function
7048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7049#[cfg_attr(feature = "bindings", derive(TS))]
7050pub struct IfFunc {
7051    pub condition: Expression,
7052    pub true_value: Expression,
7053    pub false_value: Option<Expression>,
7054    /// Original function name (IF, IFF, IIF) for round-trip preservation
7055    #[serde(skip_serializing_if = "Option::is_none", default)]
7056    pub original_name: Option<String>,
7057    /// Inferred data type from type annotation
7058    #[serde(default, skip_serializing_if = "Option::is_none")]
7059    #[ast(skip)]
7060    pub inferred_type: Option<DataType>,
7061}
7062
7063/// NVL2 function
7064#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7065#[cfg_attr(feature = "bindings", derive(TS))]
7066pub struct Nvl2Func {
7067    pub this: Expression,
7068    pub true_value: Expression,
7069    pub false_value: Expression,
7070    /// Inferred data type from type annotation
7071    #[serde(default, skip_serializing_if = "Option::is_none")]
7072    #[ast(skip)]
7073    pub inferred_type: Option<DataType>,
7074}
7075
7076// ============================================================================
7077// Typed Aggregate Function types
7078// ============================================================================
7079
7080/// Generic aggregate function base type
7081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7082#[cfg_attr(feature = "bindings", derive(TS))]
7083pub struct AggFunc {
7084    pub this: Expression,
7085    pub distinct: bool,
7086    pub filter: Option<Expression>,
7087    pub order_by: Vec<Ordered>,
7088    /// Original function name (case-preserving) when parsed from SQL
7089    #[serde(skip_serializing_if = "Option::is_none", default)]
7090    pub name: Option<String>,
7091    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
7092    #[serde(skip_serializing_if = "Option::is_none", default)]
7093    pub ignore_nulls: Option<bool>,
7094    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
7095    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
7096    #[serde(skip_serializing_if = "Option::is_none", default)]
7097    pub having_max: Option<(Box<Expression>, bool)>,
7098    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
7099    #[serde(skip_serializing_if = "Option::is_none", default)]
7100    pub limit: Option<Box<Expression>>,
7101    /// Inferred data type from type annotation
7102    #[serde(default, skip_serializing_if = "Option::is_none")]
7103    #[ast(skip)]
7104    pub inferred_type: Option<DataType>,
7105}
7106
7107/// COUNT function with optional star
7108#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7109#[cfg_attr(feature = "bindings", derive(TS))]
7110pub struct CountFunc {
7111    pub this: Option<Expression>,
7112    pub star: bool,
7113    pub distinct: bool,
7114    pub filter: Option<Expression>,
7115    /// IGNORE NULLS (true) or RESPECT NULLS (false)
7116    #[serde(default, skip_serializing_if = "Option::is_none")]
7117    pub ignore_nulls: Option<bool>,
7118    /// Original function name for case preservation (e.g., "count" or "COUNT")
7119    #[serde(default, skip_serializing_if = "Option::is_none")]
7120    pub original_name: Option<String>,
7121    /// Inferred data type from type annotation
7122    #[serde(default, skip_serializing_if = "Option::is_none")]
7123    #[ast(skip)]
7124    pub inferred_type: Option<DataType>,
7125}
7126
7127/// GROUP_CONCAT function (MySQL style)
7128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7129#[cfg_attr(feature = "bindings", derive(TS))]
7130pub struct GroupConcatFunc {
7131    pub this: Expression,
7132    pub separator: Option<Expression>,
7133    pub order_by: Option<Vec<Ordered>>,
7134    pub distinct: bool,
7135    pub filter: Option<Expression>,
7136    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
7137    #[serde(default, skip_serializing_if = "Option::is_none")]
7138    pub limit: Option<Box<Expression>>,
7139    /// Inferred data type from type annotation
7140    #[serde(default, skip_serializing_if = "Option::is_none")]
7141    #[ast(skip)]
7142    pub inferred_type: Option<DataType>,
7143}
7144
7145/// STRING_AGG function (PostgreSQL/Standard SQL)
7146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7147#[cfg_attr(feature = "bindings", derive(TS))]
7148pub struct StringAggFunc {
7149    pub this: Expression,
7150    #[serde(default)]
7151    pub separator: Option<Expression>,
7152    #[serde(default)]
7153    pub order_by: Option<Vec<Ordered>>,
7154    #[serde(default)]
7155    pub distinct: bool,
7156    #[serde(default)]
7157    pub filter: Option<Expression>,
7158    /// BigQuery LIMIT inside STRING_AGG
7159    #[serde(default, skip_serializing_if = "Option::is_none")]
7160    pub limit: Option<Box<Expression>>,
7161    /// Inferred data type from type annotation
7162    #[serde(default, skip_serializing_if = "Option::is_none")]
7163    #[ast(skip)]
7164    pub inferred_type: Option<DataType>,
7165}
7166
7167/// LISTAGG function (Oracle style)
7168#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7169#[cfg_attr(feature = "bindings", derive(TS))]
7170pub struct ListAggFunc {
7171    /// Retain source byte-limit and overflow semantics through AST generation.
7172    #[serde(default, skip_serializing_if = "Option::is_none")]
7173    #[ast(skip)]
7174    pub source_dialect: Option<crate::dialects::DialectType>,
7175    pub this: Expression,
7176    pub separator: Option<Expression>,
7177    pub on_overflow: Option<ListAggOverflow>,
7178    /// Vertica `USING PARAMETERS max_length = n`
7179    #[serde(default, skip_serializing_if = "Option::is_none")]
7180    pub max_length: Option<Box<Expression>>,
7181    pub order_by: Option<Vec<Ordered>>,
7182    pub distinct: bool,
7183    pub filter: Option<Expression>,
7184    /// Inferred data type from type annotation
7185    #[serde(default, skip_serializing_if = "Option::is_none")]
7186    #[ast(skip)]
7187    pub inferred_type: Option<DataType>,
7188}
7189
7190/// LISTAGG ON OVERFLOW behavior
7191#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7192#[cfg_attr(feature = "bindings", derive(TS))]
7193pub enum ListAggOverflow {
7194    Error,
7195    Truncate {
7196        filler: Option<Expression>,
7197        with_count: bool,
7198    },
7199}
7200
7201/// SUM_IF / COUNT_IF function
7202#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7203#[cfg_attr(feature = "bindings", derive(TS))]
7204pub struct SumIfFunc {
7205    pub this: Expression,
7206    pub condition: Expression,
7207    pub filter: Option<Expression>,
7208    /// Inferred data type from type annotation
7209    #[serde(default, skip_serializing_if = "Option::is_none")]
7210    #[ast(skip)]
7211    pub inferred_type: Option<DataType>,
7212}
7213
7214/// APPROX_PERCENTILE function
7215#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7216#[cfg_attr(feature = "bindings", derive(TS))]
7217pub struct ApproxPercentileFunc {
7218    pub this: Expression,
7219    pub percentile: Expression,
7220    pub accuracy: Option<Expression>,
7221    pub filter: Option<Expression>,
7222}
7223
7224/// PERCENTILE_CONT / PERCENTILE_DISC function
7225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7226#[cfg_attr(feature = "bindings", derive(TS))]
7227pub struct PercentileFunc {
7228    pub this: Expression,
7229    pub percentile: Expression,
7230    pub order_by: Option<Vec<Ordered>>,
7231    pub filter: Option<Expression>,
7232}
7233
7234// ============================================================================
7235// Typed Window Function types
7236// ============================================================================
7237
7238/// ROW_NUMBER function (no arguments)
7239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7240#[cfg_attr(feature = "bindings", derive(TS))]
7241pub struct RowNumber;
7242
7243/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7244#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7245#[cfg_attr(feature = "bindings", derive(TS))]
7246pub struct Rank {
7247    /// DuckDB: RANK(ORDER BY col) - order by inside function
7248    #[serde(default, skip_serializing_if = "Option::is_none")]
7249    pub order_by: Option<Vec<Ordered>>,
7250    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7251    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7252    pub args: Vec<Expression>,
7253}
7254
7255/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
7256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7257#[cfg_attr(feature = "bindings", derive(TS))]
7258pub struct DenseRank {
7259    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7260    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7261    pub args: Vec<Expression>,
7262}
7263
7264/// NTILE function (DuckDB allows ORDER BY inside)
7265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7266#[cfg_attr(feature = "bindings", derive(TS))]
7267pub struct NTileFunc {
7268    /// num_buckets is optional to support Databricks NTILE() without arguments
7269    #[serde(default, skip_serializing_if = "Option::is_none")]
7270    pub num_buckets: Option<Expression>,
7271    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
7272    #[serde(default, skip_serializing_if = "Option::is_none")]
7273    pub order_by: Option<Vec<Ordered>>,
7274}
7275
7276/// LEAD / LAG function
7277#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7278#[cfg_attr(feature = "bindings", derive(TS))]
7279pub struct LeadLagFunc {
7280    pub this: Expression,
7281    pub offset: Option<Expression>,
7282    pub default: Option<Expression>,
7283    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7284    #[serde(default, skip_serializing_if = "Option::is_none")]
7285    pub ignore_nulls: Option<bool>,
7286}
7287
7288/// FIRST_VALUE / LAST_VALUE function
7289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7290#[cfg_attr(feature = "bindings", derive(TS))]
7291pub struct ValueFunc {
7292    pub this: Expression,
7293    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7294    #[serde(default, skip_serializing_if = "Option::is_none")]
7295    pub ignore_nulls: Option<bool>,
7296    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
7297    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7298    pub order_by: Vec<Ordered>,
7299}
7300
7301/// NTH_VALUE function
7302#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7303#[cfg_attr(feature = "bindings", derive(TS))]
7304pub struct NthValueFunc {
7305    pub this: Expression,
7306    pub offset: Expression,
7307    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7308    #[serde(default, skip_serializing_if = "Option::is_none")]
7309    pub ignore_nulls: Option<bool>,
7310    /// Snowflake FROM FIRST / FROM LAST clause
7311    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
7312    #[serde(default, skip_serializing_if = "Option::is_none")]
7313    pub from_first: Option<bool>,
7314}
7315
7316/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7317#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7318#[cfg_attr(feature = "bindings", derive(TS))]
7319pub struct PercentRank {
7320    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
7321    #[serde(default, skip_serializing_if = "Option::is_none")]
7322    pub order_by: Option<Vec<Ordered>>,
7323    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7324    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7325    pub args: Vec<Expression>,
7326}
7327
7328/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7329#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7330#[cfg_attr(feature = "bindings", derive(TS))]
7331pub struct CumeDist {
7332    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
7333    #[serde(default, skip_serializing_if = "Option::is_none")]
7334    pub order_by: Option<Vec<Ordered>>,
7335    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7336    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7337    pub args: Vec<Expression>,
7338}
7339
7340// ============================================================================
7341// Additional String Function types
7342// ============================================================================
7343
7344/// POSITION/INSTR function
7345#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7346#[cfg_attr(feature = "bindings", derive(TS))]
7347pub struct PositionFunc {
7348    pub substring: Expression,
7349    pub string: Expression,
7350    pub start: Option<Expression>,
7351}
7352
7353// ============================================================================
7354// Additional Math Function types
7355// ============================================================================
7356
7357/// RANDOM function (no arguments)
7358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7359#[cfg_attr(feature = "bindings", derive(TS))]
7360pub struct Random;
7361
7362/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
7363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7364#[cfg_attr(feature = "bindings", derive(TS))]
7365pub struct Rand {
7366    pub seed: Option<Box<Expression>>,
7367    /// Teradata RANDOM lower bound
7368    #[serde(default)]
7369    pub lower: Option<Box<Expression>>,
7370    /// Teradata RANDOM upper bound
7371    #[serde(default)]
7372    pub upper: Option<Box<Expression>>,
7373}
7374
7375/// TRUNCATE / TRUNC function
7376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7377#[cfg_attr(feature = "bindings", derive(TS))]
7378pub struct TruncateFunc {
7379    pub this: Expression,
7380    pub decimals: Option<Expression>,
7381}
7382
7383/// PI function (no arguments)
7384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7385#[cfg_attr(feature = "bindings", derive(TS))]
7386pub struct Pi;
7387
7388// ============================================================================
7389// Control Flow Function types
7390// ============================================================================
7391
7392/// DECODE function (Oracle style)
7393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7394#[cfg_attr(feature = "bindings", derive(TS))]
7395pub struct DecodeFunc {
7396    pub this: Expression,
7397    pub search_results: Vec<(Expression, Expression)>,
7398    pub default: Option<Expression>,
7399}
7400
7401// ============================================================================
7402// Additional Date/Time Function types
7403// ============================================================================
7404
7405/// DATE_FORMAT / FORMAT_DATE function
7406#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7407#[cfg_attr(feature = "bindings", derive(TS))]
7408pub struct DateFormatFunc {
7409    pub this: Expression,
7410    pub format: Expression,
7411}
7412
7413/// FROM_UNIXTIME function
7414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7415#[cfg_attr(feature = "bindings", derive(TS))]
7416pub struct FromUnixtimeFunc {
7417    pub this: Expression,
7418    pub format: Option<Expression>,
7419}
7420
7421/// UNIX_TIMESTAMP function
7422#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7423#[cfg_attr(feature = "bindings", derive(TS))]
7424pub struct UnixTimestampFunc {
7425    pub this: Option<Expression>,
7426    pub format: Option<Expression>,
7427}
7428
7429/// MAKE_DATE function
7430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7431#[cfg_attr(feature = "bindings", derive(TS))]
7432pub struct MakeDateFunc {
7433    pub year: Expression,
7434    pub month: Expression,
7435    pub day: Expression,
7436}
7437
7438/// MAKE_TIMESTAMP function
7439#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7440#[cfg_attr(feature = "bindings", derive(TS))]
7441pub struct MakeTimestampFunc {
7442    pub year: Expression,
7443    pub month: Expression,
7444    pub day: Expression,
7445    pub hour: Expression,
7446    pub minute: Expression,
7447    pub second: Expression,
7448    pub timezone: Option<Expression>,
7449}
7450
7451/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
7452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7453#[cfg_attr(feature = "bindings", derive(TS))]
7454pub struct LastDayFunc {
7455    pub this: Expression,
7456    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
7457    #[serde(skip_serializing_if = "Option::is_none", default)]
7458    pub unit: Option<DateTimeField>,
7459}
7460
7461// ============================================================================
7462// Array Function types
7463// ============================================================================
7464
7465/// ARRAY constructor
7466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7467#[cfg_attr(feature = "bindings", derive(TS))]
7468pub struct ArrayConstructor {
7469    pub expressions: Vec<Expression>,
7470    pub bracket_notation: bool,
7471    /// True if LIST keyword was used instead of ARRAY (DuckDB)
7472    pub use_list_keyword: bool,
7473    /// Inferred array data type from type annotation
7474    #[serde(default, skip_serializing_if = "Option::is_none")]
7475    #[ast(skip)]
7476    pub inferred_type: Option<DataType>,
7477}
7478
7479/// ARRAY_SORT function
7480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7481#[cfg_attr(feature = "bindings", derive(TS))]
7482pub struct ArraySortFunc {
7483    pub this: Expression,
7484    pub comparator: Option<Expression>,
7485    pub desc: bool,
7486    pub nulls_first: Option<bool>,
7487}
7488
7489/// ARRAY_JOIN / ARRAY_TO_STRING function
7490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7491#[cfg_attr(feature = "bindings", derive(TS))]
7492pub struct ArrayJoinFunc {
7493    pub this: Expression,
7494    pub separator: Expression,
7495    pub null_replacement: Option<Expression>,
7496}
7497
7498/// UNNEST function
7499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7500#[cfg_attr(feature = "bindings", derive(TS))]
7501pub struct UnnestFunc {
7502    pub this: Expression,
7503    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
7504    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7505    pub expressions: Vec<Expression>,
7506    pub with_ordinality: bool,
7507    pub alias: Option<Identifier>,
7508    /// BigQuery: offset alias for WITH OFFSET AS <name>
7509    #[serde(default, skip_serializing_if = "Option::is_none")]
7510    pub offset_alias: Option<Identifier>,
7511    /// Inferred type of the first UNNEST output column.
7512    #[serde(default, skip_serializing_if = "Option::is_none")]
7513    #[ast(skip)]
7514    pub inferred_type: Option<DataType>,
7515}
7516
7517/// ARRAY_FILTER function (with lambda)
7518#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7519#[cfg_attr(feature = "bindings", derive(TS))]
7520pub struct ArrayFilterFunc {
7521    pub this: Expression,
7522    pub filter: Expression,
7523}
7524
7525/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
7526#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7527#[cfg_attr(feature = "bindings", derive(TS))]
7528pub struct ArrayTransformFunc {
7529    pub this: Expression,
7530    pub transform: Expression,
7531}
7532
7533/// SEQUENCE / GENERATE_SERIES function
7534#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7535#[cfg_attr(feature = "bindings", derive(TS))]
7536pub struct SequenceFunc {
7537    pub start: Expression,
7538    pub stop: Expression,
7539    pub step: Option<Expression>,
7540}
7541
7542// ============================================================================
7543// Struct Function types
7544// ============================================================================
7545
7546/// STRUCT constructor
7547#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7548#[cfg_attr(feature = "bindings", derive(TS))]
7549pub struct StructConstructor {
7550    pub fields: Vec<(Option<Identifier>, Expression)>,
7551}
7552
7553/// STRUCT_EXTRACT function
7554#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7555#[cfg_attr(feature = "bindings", derive(TS))]
7556pub struct StructExtractFunc {
7557    pub this: Expression,
7558    pub field: Identifier,
7559}
7560
7561/// NAMED_STRUCT function
7562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7563#[cfg_attr(feature = "bindings", derive(TS))]
7564pub struct NamedStructFunc {
7565    pub pairs: Vec<(Expression, Expression)>,
7566}
7567
7568// ============================================================================
7569// Map Function types
7570// ============================================================================
7571
7572/// MAP constructor
7573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7574#[cfg_attr(feature = "bindings", derive(TS))]
7575pub struct MapConstructor {
7576    pub keys: Vec<Expression>,
7577    pub values: Vec<Expression>,
7578    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7579    #[serde(default)]
7580    pub curly_brace_syntax: bool,
7581    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7582    #[serde(default)]
7583    pub with_map_keyword: bool,
7584}
7585
7586/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7587#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7588#[cfg_attr(feature = "bindings", derive(TS))]
7589pub struct TransformFunc {
7590    pub this: Expression,
7591    pub transform: Expression,
7592}
7593
7594/// Function call with EMITS clause (Exasol)
7595/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7597#[cfg_attr(feature = "bindings", derive(TS))]
7598pub struct FunctionEmits {
7599    /// The function call expression
7600    pub this: Expression,
7601    /// The EMITS schema definition
7602    pub emits: Expression,
7603}
7604
7605// ============================================================================
7606// JSON Function types
7607// ============================================================================
7608
7609/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7610#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7611#[cfg_attr(feature = "bindings", derive(TS))]
7612pub struct JsonExtractFunc {
7613    #[serde(default, skip_serializing_if = "Option::is_none")]
7614    #[ast(skip)]
7615    pub source_dialect: Option<crate::dialects::DialectType>,
7616    /// Structured SQL/JSON wrapper and error/empty behavior.
7617    #[serde(default, skip_serializing_if = "Option::is_none")]
7618    pub options: Option<JsonOptions>,
7619
7620    pub this: Expression,
7621    pub path: Expression,
7622    pub returning: Option<DataType>,
7623    /// True if parsed from -> or ->> operator syntax
7624    #[serde(default)]
7625    pub arrow_syntax: bool,
7626    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7627    #[serde(default)]
7628    pub hash_arrow_syntax: bool,
7629    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7630    #[serde(default)]
7631    pub wrapper_option: Option<String>,
7632    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7633    #[serde(default)]
7634    pub quotes_option: Option<String>,
7635    /// ON SCALAR STRING flag
7636    #[serde(default)]
7637    pub on_scalar_string: bool,
7638    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7639    #[serde(default)]
7640    pub on_error: Option<String>,
7641}
7642
7643/// JSON path extraction
7644#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7645#[cfg_attr(feature = "bindings", derive(TS))]
7646pub struct JsonPathFunc {
7647    pub this: Expression,
7648    pub paths: Vec<Expression>,
7649}
7650
7651/// JSON_OBJECT function
7652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7653#[cfg_attr(feature = "bindings", derive(TS))]
7654pub struct JsonObjectFunc {
7655    pub pairs: Vec<(Expression, Expression)>,
7656    pub null_handling: Option<JsonNullHandling>,
7657    #[serde(default)]
7658    pub with_unique_keys: bool,
7659    #[serde(default)]
7660    pub returning_type: Option<DataType>,
7661    #[serde(default)]
7662    pub format_json: bool,
7663    #[serde(default)]
7664    pub encoding: Option<String>,
7665    /// For JSON_OBJECT(*) syntax
7666    #[serde(default)]
7667    pub star: bool,
7668}
7669
7670/// JSON null handling options
7671#[derive(
7672    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7673)]
7674#[cfg_attr(feature = "bindings", derive(TS))]
7675pub enum JsonNullHandling {
7676    NullOnNull,
7677    AbsentOnNull,
7678}
7679
7680/// JSON_SET / JSON_INSERT function
7681#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7682#[cfg_attr(feature = "bindings", derive(TS))]
7683pub struct JsonModifyFunc {
7684    pub this: Expression,
7685    pub path_values: Vec<(Expression, Expression)>,
7686}
7687
7688/// JSON_ARRAYAGG function
7689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7690#[cfg_attr(feature = "bindings", derive(TS))]
7691pub struct JsonArrayAggFunc {
7692    pub this: Expression,
7693    pub order_by: Option<Vec<Ordered>>,
7694    pub null_handling: Option<JsonNullHandling>,
7695    pub filter: Option<Expression>,
7696}
7697
7698/// JSON_OBJECTAGG function
7699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7700#[cfg_attr(feature = "bindings", derive(TS))]
7701pub struct JsonObjectAggFunc {
7702    pub key: Expression,
7703    pub value: Expression,
7704    pub null_handling: Option<JsonNullHandling>,
7705    pub filter: Option<Expression>,
7706}
7707
7708// ============================================================================
7709// Type Casting Function types
7710// ============================================================================
7711
7712/// CONVERT function (SQL Server style)
7713#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7714#[cfg_attr(feature = "bindings", derive(TS))]
7715pub struct ConvertFunc {
7716    pub this: Expression,
7717    pub to: DataType,
7718    pub style: Option<Expression>,
7719}
7720
7721// ============================================================================
7722// Additional Expression types
7723// ============================================================================
7724
7725/// Lambda expression
7726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7727#[cfg_attr(feature = "bindings", derive(TS))]
7728pub struct LambdaExpr {
7729    pub parameters: Vec<Identifier>,
7730    pub body: Expression,
7731    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7732    #[serde(default)]
7733    pub colon: bool,
7734    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7735    /// Maps parameter index to data type
7736    #[serde(default)]
7737    pub parameter_types: Vec<Option<DataType>>,
7738}
7739
7740/// Parameter (parameterized queries)
7741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7742#[cfg_attr(feature = "bindings", derive(TS))]
7743pub struct Parameter {
7744    pub name: Option<String>,
7745    pub index: Option<u32>,
7746    pub style: ParameterStyle,
7747    /// Whether the name was quoted (e.g., @"x" vs @x)
7748    #[serde(default)]
7749    pub quoted: bool,
7750    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7751    #[serde(default)]
7752    pub string_quoted: bool,
7753    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7754    #[serde(default)]
7755    pub expression: Option<String>,
7756}
7757
7758/// Parameter placeholder styles
7759#[derive(
7760    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7761)]
7762#[cfg_attr(feature = "bindings", derive(TS))]
7763pub enum ParameterStyle {
7764    Question,     // ?
7765    Dollar,       // $1, $2
7766    DollarBrace,  // ${name} (Databricks, Hive template variables)
7767    Brace,        // {name} (Spark/Databricks widget/template variables)
7768    Colon,        // :name
7769    At,           // @name
7770    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7771    DoubleDollar, // $$name
7772    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7773}
7774
7775/// Placeholder expression
7776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7777#[cfg_attr(feature = "bindings", derive(TS))]
7778pub struct Placeholder {
7779    pub index: Option<u32>,
7780}
7781
7782/// Named argument in function call: name => value or name := value
7783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7784#[cfg_attr(feature = "bindings", derive(TS))]
7785pub struct NamedArgument {
7786    pub name: Identifier,
7787    pub value: Expression,
7788    /// The separator used: `=>`, `:=`, or `=`
7789    pub separator: NamedArgSeparator,
7790}
7791
7792/// Separator style for named arguments
7793#[derive(
7794    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7795)]
7796#[cfg_attr(feature = "bindings", derive(TS))]
7797pub enum NamedArgSeparator {
7798    /// `=>` (standard SQL, Snowflake, BigQuery)
7799    DArrow,
7800    /// `:=` (Oracle, MySQL)
7801    ColonEq,
7802    /// `=` (simple equals, some dialects)
7803    Eq,
7804}
7805
7806/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7807/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7809#[cfg_attr(feature = "bindings", derive(TS))]
7810pub struct TableArgument {
7811    /// The keyword prefix: "TABLE" or "MODEL"
7812    pub prefix: String,
7813    /// The table/model reference expression
7814    pub this: Expression,
7815}
7816
7817/// SQL Comment preservation
7818#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7819#[cfg_attr(feature = "bindings", derive(TS))]
7820pub struct SqlComment {
7821    pub text: String,
7822    pub is_block: bool,
7823}
7824
7825// ============================================================================
7826// Additional Predicate types
7827// ============================================================================
7828
7829/// SIMILAR TO expression
7830#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7831#[cfg_attr(feature = "bindings", derive(TS))]
7832pub struct SimilarToExpr {
7833    pub this: Expression,
7834    pub pattern: Expression,
7835    pub escape: Option<Expression>,
7836    pub not: bool,
7837}
7838
7839/// ANY / ALL quantified expression
7840#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7841#[cfg_attr(feature = "bindings", derive(TS))]
7842pub struct QuantifiedExpr {
7843    pub this: Expression,
7844    pub subquery: Expression,
7845    pub op: Option<QuantifiedOp>,
7846}
7847
7848/// Comparison operator for quantified expressions
7849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7850#[cfg_attr(feature = "bindings", derive(TS))]
7851pub enum QuantifiedOp {
7852    Eq,
7853    Neq,
7854    Lt,
7855    Lte,
7856    Gt,
7857    Gte,
7858}
7859
7860/// OVERLAPS expression
7861/// Supports two forms:
7862/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7863/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7865#[cfg_attr(feature = "bindings", derive(TS))]
7866pub struct OverlapsExpr {
7867    /// Left operand for simple binary form
7868    #[serde(skip_serializing_if = "Option::is_none")]
7869    pub this: Option<Expression>,
7870    /// Right operand for simple binary form
7871    #[serde(skip_serializing_if = "Option::is_none")]
7872    pub expression: Option<Expression>,
7873    /// Left range start for full ANSI form
7874    #[serde(skip_serializing_if = "Option::is_none")]
7875    pub left_start: Option<Expression>,
7876    /// Left range end for full ANSI form
7877    #[serde(skip_serializing_if = "Option::is_none")]
7878    pub left_end: Option<Expression>,
7879    /// Right range start for full ANSI form
7880    #[serde(skip_serializing_if = "Option::is_none")]
7881    pub right_start: Option<Expression>,
7882    /// Right range end for full ANSI form
7883    #[serde(skip_serializing_if = "Option::is_none")]
7884    pub right_end: Option<Expression>,
7885}
7886
7887// ============================================================================
7888// Array/Struct/Map access
7889// ============================================================================
7890
7891/// Subscript access (array[index] or map[key])
7892#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7893#[cfg_attr(feature = "bindings", derive(TS))]
7894pub struct Subscript {
7895    pub this: Expression,
7896    pub index: Expression,
7897}
7898
7899/// Dot access (struct.field)
7900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7901#[cfg_attr(feature = "bindings", derive(TS))]
7902pub struct DotAccess {
7903    pub this: Expression,
7904    pub field: Identifier,
7905    #[serde(default, skip_serializing_if = "Option::is_none")]
7906    pub inferred_type: Option<DataType>,
7907}
7908
7909/// Method call (expr.method(args))
7910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7911#[cfg_attr(feature = "bindings", derive(TS))]
7912pub struct MethodCall {
7913    pub this: Expression,
7914    pub method: Identifier,
7915    pub args: Vec<Expression>,
7916}
7917
7918/// Array slice (array[start:end])
7919#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7920#[cfg_attr(feature = "bindings", derive(TS))]
7921pub struct ArraySlice {
7922    pub this: Expression,
7923    pub start: Option<Expression>,
7924    pub end: Option<Expression>,
7925}
7926
7927// ============================================================================
7928// DDL (Data Definition Language) Statements
7929// ============================================================================
7930
7931/// ON COMMIT behavior for temporary tables
7932#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7933#[cfg_attr(feature = "bindings", derive(TS))]
7934pub enum OnCommit {
7935    /// ON COMMIT PRESERVE ROWS
7936    PreserveRows,
7937    /// ON COMMIT DELETE ROWS
7938    DeleteRows,
7939}
7940
7941/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
7942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7943#[cfg_attr(feature = "bindings", derive(TS))]
7944pub struct TiDBAutoRandom {
7945    #[serde(default, skip_serializing_if = "Option::is_none")]
7946    pub shard_bits: Option<u64>,
7947    #[serde(default, skip_serializing_if = "Option::is_none")]
7948    pub range_bits: Option<u64>,
7949    /// Whether the attribute was wrapped in a TiDB executable comment.
7950    #[serde(default)]
7951    pub executable_comment: bool,
7952}
7953
7954/// A TiDB-specific table option and its source syntax.
7955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7956#[cfg_attr(feature = "bindings", derive(TS))]
7957pub struct TiDBTableOption {
7958    pub kind: TiDBTableOptionKind,
7959    /// Whether the option was wrapped in a TiDB executable comment.
7960    #[serde(default)]
7961    pub executable_comment: bool,
7962}
7963
7964/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
7965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7966#[cfg_attr(feature = "bindings", derive(TS))]
7967#[serde(tag = "type", rename_all = "snake_case")]
7968pub enum TiDBTableOptionKind {
7969    ShardRowIdBits {
7970        bits: u64,
7971    },
7972    PreSplitRegions {
7973        regions: u64,
7974    },
7975    AutoRandomBase {
7976        value: u64,
7977    },
7978    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
7979    PlacementPolicy {
7980        policy: Option<Identifier>,
7981    },
7982    Ttl {
7983        column: Identifier,
7984        interval: Interval,
7985        #[serde(default, skip_serializing_if = "Option::is_none")]
7986        enabled: Option<bool>,
7987    },
7988    TtlEnable {
7989        enabled: bool,
7990    },
7991    TtlJobInterval {
7992        interval: String,
7993    },
7994}
7995
7996/// CREATE TABLE statement
7997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7998#[cfg_attr(feature = "bindings", derive(TS))]
7999pub struct CreateTable {
8000    pub name: TableRef,
8001    /// ClickHouse: ON CLUSTER clause for distributed DDL
8002    #[serde(default, skip_serializing_if = "Option::is_none")]
8003    pub on_cluster: Option<OnCluster>,
8004    pub columns: Vec<ColumnDef>,
8005    pub constraints: Vec<TableConstraint>,
8006    pub if_not_exists: bool,
8007    pub temporary: bool,
8008    pub or_replace: bool,
8009    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
8010    #[serde(default, skip_serializing_if = "Option::is_none")]
8011    pub table_modifier: Option<String>,
8012    /// Dialect whose call semantics must be retained through independent generation.
8013    #[serde(default, skip_serializing_if = "Option::is_none")]
8014    #[ast(skip)]
8015    pub source_dialect: Option<crate::dialects::DialectType>,
8016
8017    pub as_select: Option<Expression>,
8018    /// Whether the AS SELECT was wrapped in parentheses
8019    #[serde(default)]
8020    pub as_select_parenthesized: bool,
8021    /// ON COMMIT behavior for temporary tables
8022    #[serde(default)]
8023    pub on_commit: Option<OnCommit>,
8024    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
8025    #[serde(default)]
8026    pub clone_source: Option<TableRef>,
8027    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
8028    #[serde(default, skip_serializing_if = "Option::is_none")]
8029    pub clone_at_clause: Option<Expression>,
8030    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
8031    #[serde(default)]
8032    pub is_copy: bool,
8033    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
8034    #[serde(default)]
8035    pub shallow_clone: bool,
8036    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
8037    #[serde(default)]
8038    pub deep_clone: bool,
8039    /// Leading comments before the statement
8040    #[serde(default)]
8041    pub leading_comments: Vec<String>,
8042    /// WITH properties (e.g., WITH (FORMAT='parquet'))
8043    #[serde(default)]
8044    pub with_properties: Vec<(String, String)>,
8045    /// Teradata: table options after name before columns (comma-separated)
8046    #[serde(default)]
8047    pub teradata_post_name_options: Vec<String>,
8048    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
8049    #[serde(default)]
8050    pub with_data: Option<bool>,
8051    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
8052    #[serde(default)]
8053    pub with_statistics: Option<bool>,
8054    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
8055    #[serde(default)]
8056    pub teradata_indexes: Vec<TeradataIndex>,
8057    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
8058    #[serde(default)]
8059    pub with_cte: Option<With>,
8060    /// Table properties like DEFAULT COLLATE (BigQuery)
8061    #[serde(default)]
8062    pub properties: Vec<Expression>,
8063    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
8064    #[serde(default, skip_serializing_if = "Option::is_none")]
8065    pub partition_of: Option<Expression>,
8066    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
8067    #[serde(default)]
8068    pub post_table_properties: Vec<Expression>,
8069    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
8070    #[serde(default)]
8071    pub mysql_table_options: Vec<(String, String)>,
8072    /// TiDB-specific table options after column definitions.
8073    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8074    pub tidb_table_options: Vec<TiDBTableOption>,
8075    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
8076    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8077    pub inherits: Vec<TableRef>,
8078    /// TSQL ON filegroup or ON filegroup (partition_column) clause
8079    #[serde(default, skip_serializing_if = "Option::is_none")]
8080    pub on_property: Option<OnProperty>,
8081    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
8082    #[serde(default)]
8083    pub copy_grants: bool,
8084    /// Snowflake: USING TEMPLATE expression for schema inference
8085    #[serde(default, skip_serializing_if = "Option::is_none")]
8086    pub using_template: Option<Box<Expression>>,
8087    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
8088    #[serde(default, skip_serializing_if = "Option::is_none")]
8089    pub rollup: Option<RollupProperty>,
8090    /// ClickHouse: UUID 'xxx' clause after table name
8091    #[serde(default, skip_serializing_if = "Option::is_none")]
8092    pub uuid: Option<String>,
8093    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
8094    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
8095    /// could appear in other engines.
8096    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8097    pub with_partition_columns: Vec<ColumnDef>,
8098    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
8099    /// for external tables that reference a Cloud Resource connection.
8100    #[serde(default, skip_serializing_if = "Option::is_none")]
8101    pub with_connection: Option<TableRef>,
8102}
8103
8104/// Teradata index specification for CREATE TABLE
8105#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8106#[cfg_attr(feature = "bindings", derive(TS))]
8107pub struct TeradataIndex {
8108    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
8109    pub kind: TeradataIndexKind,
8110    /// Optional index name
8111    pub name: Option<String>,
8112    /// Optional column list
8113    pub columns: Vec<String>,
8114}
8115
8116/// Kind of Teradata index
8117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8118#[cfg_attr(feature = "bindings", derive(TS))]
8119pub enum TeradataIndexKind {
8120    /// NO PRIMARY INDEX
8121    NoPrimary,
8122    /// PRIMARY INDEX
8123    Primary,
8124    /// PRIMARY AMP INDEX
8125    PrimaryAmp,
8126    /// UNIQUE INDEX
8127    Unique,
8128    /// UNIQUE PRIMARY INDEX
8129    UniquePrimary,
8130    /// INDEX (secondary, non-primary)
8131    Secondary,
8132}
8133
8134impl CreateTable {
8135    pub fn new(name: impl Into<String>) -> Self {
8136        Self {
8137            name: TableRef::new(name),
8138            on_cluster: None,
8139            columns: Vec::new(),
8140            constraints: Vec::new(),
8141            if_not_exists: false,
8142            temporary: false,
8143            or_replace: false,
8144            table_modifier: None,
8145            source_dialect: None,
8146            as_select: None,
8147            as_select_parenthesized: false,
8148            on_commit: None,
8149            clone_source: None,
8150            clone_at_clause: None,
8151            shallow_clone: false,
8152            deep_clone: false,
8153            is_copy: false,
8154            leading_comments: Vec::new(),
8155            with_properties: Vec::new(),
8156            teradata_post_name_options: Vec::new(),
8157            with_data: None,
8158            with_statistics: None,
8159            teradata_indexes: Vec::new(),
8160            with_cte: None,
8161            properties: Vec::new(),
8162            partition_of: None,
8163            post_table_properties: Vec::new(),
8164            mysql_table_options: Vec::new(),
8165            tidb_table_options: Vec::new(),
8166            inherits: Vec::new(),
8167            on_property: None,
8168            copy_grants: false,
8169            using_template: None,
8170            rollup: None,
8171            uuid: None,
8172            with_partition_columns: Vec::new(),
8173            with_connection: None,
8174        }
8175    }
8176}
8177
8178/// Sort order for PRIMARY KEY ASC/DESC
8179#[derive(
8180    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
8181)]
8182#[cfg_attr(feature = "bindings", derive(TS))]
8183pub enum SortOrder {
8184    Asc,
8185    Desc,
8186}
8187
8188/// Type of column constraint for tracking order
8189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8190#[cfg_attr(feature = "bindings", derive(TS))]
8191pub enum ConstraintType {
8192    NotNull,
8193    Null,
8194    PrimaryKey,
8195    Unique,
8196    Default,
8197    AutoIncrement,
8198    AutoRandom,
8199    Collate,
8200    Comment,
8201    References,
8202    Check,
8203    GeneratedAsIdentity,
8204    /// Snowflake: TAG (key='value', ...)
8205    Tags,
8206    /// Computed/generated column
8207    ComputedColumn,
8208    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
8209    GeneratedAsRow,
8210    /// MySQL: ON UPDATE expression
8211    OnUpdate,
8212    /// PATH constraint for XMLTABLE/JSON_TABLE columns
8213    Path,
8214    /// Redshift: ENCODE encoding_type
8215    Encode,
8216}
8217
8218/// Column definition in CREATE TABLE
8219#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8220#[cfg_attr(feature = "bindings", derive(TS))]
8221pub struct ColumnDef {
8222    pub name: Identifier,
8223    pub data_type: DataType,
8224    pub nullable: Option<bool>,
8225    pub default: Option<Expression>,
8226    pub primary_key: bool,
8227    /// Sort order for PRIMARY KEY (ASC/DESC)
8228    #[serde(default)]
8229    pub primary_key_order: Option<SortOrder>,
8230    pub unique: bool,
8231    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
8232    #[serde(default)]
8233    pub unique_nulls_not_distinct: bool,
8234    pub auto_increment: bool,
8235    /// TiDB distributed primary-key allocation attribute.
8236    #[serde(default, skip_serializing_if = "Option::is_none")]
8237    pub auto_random: Option<TiDBAutoRandom>,
8238    pub comment: Option<String>,
8239    pub constraints: Vec<ColumnConstraint>,
8240    /// Track original order of constraints for accurate regeneration
8241    #[serde(default)]
8242    pub constraint_order: Vec<ConstraintType>,
8243    /// Teradata: FORMAT 'pattern'
8244    #[serde(default)]
8245    pub format: Option<String>,
8246    /// Teradata: TITLE 'title'
8247    #[serde(default)]
8248    pub title: Option<String>,
8249    /// Teradata: INLINE LENGTH n
8250    #[serde(default)]
8251    pub inline_length: Option<u64>,
8252    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
8253    #[serde(default)]
8254    pub compress: Option<Vec<Expression>>,
8255    /// Teradata: CHARACTER SET name
8256    #[serde(default)]
8257    pub character_set: Option<String>,
8258    /// Teradata: UPPERCASE
8259    #[serde(default)]
8260    pub uppercase: bool,
8261    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
8262    #[serde(default)]
8263    pub casespecific: Option<bool>,
8264    /// Snowflake: AUTOINCREMENT START value
8265    #[serde(default)]
8266    pub auto_increment_start: Option<Box<Expression>>,
8267    /// Snowflake: AUTOINCREMENT INCREMENT value
8268    #[serde(default)]
8269    pub auto_increment_increment: Option<Box<Expression>>,
8270    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
8271    #[serde(default)]
8272    pub auto_increment_order: Option<bool>,
8273    /// MySQL: UNSIGNED modifier
8274    #[serde(default)]
8275    pub unsigned: bool,
8276    /// MySQL: ZEROFILL modifier
8277    #[serde(default)]
8278    pub zerofill: bool,
8279    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
8280    #[serde(default, skip_serializing_if = "Option::is_none")]
8281    pub on_update: Option<Expression>,
8282    /// MySQL: column VISIBLE/INVISIBLE modifier.
8283    #[serde(default, skip_serializing_if = "Option::is_none")]
8284    pub visible: Option<bool>,
8285    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
8286    #[serde(default, skip_serializing_if = "Option::is_none")]
8287    pub unique_constraint_name: Option<String>,
8288    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
8289    #[serde(default, skip_serializing_if = "Option::is_none")]
8290    pub not_null_constraint_name: Option<String>,
8291    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
8292    #[serde(default, skip_serializing_if = "Option::is_none")]
8293    pub primary_key_constraint_name: Option<String>,
8294    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
8295    #[serde(default, skip_serializing_if = "Option::is_none")]
8296    pub check_constraint_name: Option<String>,
8297    /// BigQuery: OPTIONS (key=value, ...) on column
8298    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8299    pub options: Vec<Expression>,
8300    /// SQLite: Column definition without explicit type
8301    #[serde(default)]
8302    pub no_type: bool,
8303    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
8304    #[serde(default, skip_serializing_if = "Option::is_none")]
8305    pub encoding: Option<String>,
8306    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
8307    #[serde(default, skip_serializing_if = "Option::is_none")]
8308    pub codec: Option<String>,
8309    /// ClickHouse: EPHEMERAL [expr] modifier
8310    #[serde(default, skip_serializing_if = "Option::is_none")]
8311    pub ephemeral: Option<Option<Box<Expression>>>,
8312    /// ClickHouse: MATERIALIZED expr modifier
8313    #[serde(default, skip_serializing_if = "Option::is_none")]
8314    pub materialized_expr: Option<Box<Expression>>,
8315    /// ClickHouse: ALIAS expr modifier
8316    #[serde(default, skip_serializing_if = "Option::is_none")]
8317    pub alias_expr: Option<Box<Expression>>,
8318    /// ClickHouse: TTL expr modifier on columns
8319    #[serde(default, skip_serializing_if = "Option::is_none")]
8320    pub ttl_expr: Option<Box<Expression>>,
8321    /// TSQL: NOT FOR REPLICATION
8322    #[serde(default)]
8323    pub not_for_replication: bool,
8324}
8325
8326impl ColumnDef {
8327    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
8328        Self {
8329            name: Identifier::new(name),
8330            data_type,
8331            nullable: None,
8332            default: None,
8333            primary_key: false,
8334            primary_key_order: None,
8335            unique: false,
8336            unique_nulls_not_distinct: false,
8337            auto_increment: false,
8338            auto_random: None,
8339            comment: None,
8340            constraints: Vec::new(),
8341            constraint_order: Vec::new(),
8342            format: None,
8343            title: None,
8344            inline_length: None,
8345            compress: None,
8346            character_set: None,
8347            uppercase: false,
8348            casespecific: None,
8349            auto_increment_start: None,
8350            auto_increment_increment: None,
8351            auto_increment_order: None,
8352            unsigned: false,
8353            zerofill: false,
8354            on_update: None,
8355            visible: None,
8356            unique_constraint_name: None,
8357            not_null_constraint_name: None,
8358            primary_key_constraint_name: None,
8359            check_constraint_name: None,
8360            options: Vec::new(),
8361            no_type: false,
8362            encoding: None,
8363            codec: None,
8364            ephemeral: None,
8365            materialized_expr: None,
8366            alias_expr: None,
8367            ttl_expr: None,
8368            not_for_replication: false,
8369        }
8370    }
8371}
8372
8373/// Column-level constraint
8374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8375#[cfg_attr(feature = "bindings", derive(TS))]
8376pub enum ColumnConstraint {
8377    NotNull,
8378    Null,
8379    Unique,
8380    PrimaryKey,
8381    Default(Expression),
8382    Check(Expression),
8383    References(ForeignKeyRef),
8384    GeneratedAsIdentity(GeneratedAsIdentity),
8385    Collate(Identifier),
8386    Comment(String),
8387    /// Snowflake: TAG (key='value', ...)
8388    Tags(Tags),
8389    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
8390    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
8391    ComputedColumn(ComputedColumn),
8392    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8393    GeneratedAsRow(GeneratedAsRow),
8394    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
8395    Path(Expression),
8396}
8397
8398/// Computed/generated column constraint
8399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8400#[cfg_attr(feature = "bindings", derive(TS))]
8401pub struct ComputedColumn {
8402    /// The expression that computes the column value
8403    pub expression: Box<Expression>,
8404    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
8405    #[serde(default)]
8406    pub persisted: bool,
8407    /// NOT NULL (TSQL computed columns)
8408    #[serde(default)]
8409    pub not_null: bool,
8410    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
8411    /// When None, defaults to dialect-appropriate output
8412    #[serde(default)]
8413    pub persistence_kind: Option<String>,
8414    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
8415    #[serde(default, skip_serializing_if = "Option::is_none")]
8416    pub data_type: Option<DataType>,
8417}
8418
8419/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8420#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8421#[cfg_attr(feature = "bindings", derive(TS))]
8422pub struct GeneratedAsRow {
8423    /// true = ROW START, false = ROW END
8424    pub start: bool,
8425    /// HIDDEN modifier
8426    #[serde(default)]
8427    pub hidden: bool,
8428}
8429
8430/// Generated identity column constraint
8431#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8432#[cfg_attr(feature = "bindings", derive(TS))]
8433pub struct GeneratedAsIdentity {
8434    /// True for ALWAYS, False for BY DEFAULT
8435    pub always: bool,
8436    /// ON NULL (only valid with BY DEFAULT)
8437    pub on_null: bool,
8438    /// START WITH value
8439    pub start: Option<Box<Expression>>,
8440    /// INCREMENT BY value
8441    pub increment: Option<Box<Expression>>,
8442    /// MINVALUE
8443    pub minvalue: Option<Box<Expression>>,
8444    /// MAXVALUE
8445    pub maxvalue: Option<Box<Expression>>,
8446    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
8447    pub cycle: Option<bool>,
8448}
8449
8450/// Constraint modifiers (shared between table-level constraints)
8451#[derive(
8452    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
8453)]
8454#[cfg_attr(feature = "bindings", derive(TS))]
8455pub struct ConstraintModifiers {
8456    /// ENFORCED / NOT ENFORCED
8457    pub enforced: Option<bool>,
8458    /// DEFERRABLE / NOT DEFERRABLE
8459    pub deferrable: Option<bool>,
8460    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
8461    pub initially_deferred: Option<bool>,
8462    /// NORELY (Oracle)
8463    pub norely: bool,
8464    /// RELY (Oracle)
8465    pub rely: bool,
8466    /// USING index type (MySQL): BTREE or HASH
8467    #[serde(default)]
8468    pub using: Option<String>,
8469    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
8470    #[serde(default)]
8471    pub using_before_columns: bool,
8472    /// MySQL index COMMENT 'text'
8473    #[serde(default, skip_serializing_if = "Option::is_none")]
8474    pub comment: Option<String>,
8475    /// MySQL index VISIBLE/INVISIBLE
8476    #[serde(default, skip_serializing_if = "Option::is_none")]
8477    pub visible: Option<bool>,
8478    /// MySQL ENGINE_ATTRIBUTE = 'value'
8479    #[serde(default, skip_serializing_if = "Option::is_none")]
8480    pub engine_attribute: Option<String>,
8481    /// MySQL WITH PARSER name
8482    #[serde(default, skip_serializing_if = "Option::is_none")]
8483    pub with_parser: Option<String>,
8484    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
8485    #[serde(default)]
8486    pub not_valid: bool,
8487    /// TSQL CLUSTERED/NONCLUSTERED modifier
8488    #[serde(default, skip_serializing_if = "Option::is_none")]
8489    pub clustered: Option<String>,
8490    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
8491    #[serde(default, skip_serializing_if = "Option::is_none")]
8492    pub on_conflict: Option<String>,
8493    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
8494    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8495    pub with_options: Vec<(String, String)>,
8496    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
8497    #[serde(default, skip_serializing_if = "Option::is_none")]
8498    pub on_filegroup: Option<Identifier>,
8499}
8500
8501/// Table-level constraint
8502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8503#[cfg_attr(feature = "bindings", derive(TS))]
8504pub enum TableConstraint {
8505    PrimaryKey {
8506        name: Option<Identifier>,
8507        columns: Vec<Identifier>,
8508        /// Databricks primary-key columns marked with the TIMESERIES attribute.
8509        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8510        timeseries_columns: Vec<Identifier>,
8511        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
8512        #[serde(default)]
8513        include_columns: Vec<Identifier>,
8514        #[serde(default)]
8515        modifiers: ConstraintModifiers,
8516        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
8517        #[serde(default)]
8518        has_constraint_keyword: bool,
8519    },
8520    Unique {
8521        name: Option<Identifier>,
8522        columns: Vec<Identifier>,
8523        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
8524        #[serde(default)]
8525        columns_parenthesized: bool,
8526        #[serde(default)]
8527        modifiers: ConstraintModifiers,
8528        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
8529        #[serde(default)]
8530        has_constraint_keyword: bool,
8531        /// PostgreSQL 15+: NULLS NOT DISTINCT
8532        #[serde(default)]
8533        nulls_not_distinct: bool,
8534    },
8535    ForeignKey {
8536        name: Option<Identifier>,
8537        columns: Vec<Identifier>,
8538        #[serde(default)]
8539        references: Option<ForeignKeyRef>,
8540        /// ON DELETE action when REFERENCES is absent
8541        #[serde(default)]
8542        on_delete: Option<ReferentialAction>,
8543        /// ON UPDATE action when REFERENCES is absent
8544        #[serde(default)]
8545        on_update: Option<ReferentialAction>,
8546        #[serde(default)]
8547        modifiers: ConstraintModifiers,
8548    },
8549    Check {
8550        name: Option<Identifier>,
8551        expression: Expression,
8552        #[serde(default)]
8553        modifiers: ConstraintModifiers,
8554    },
8555    /// ClickHouse ASSUME constraint (query optimization assumption)
8556    Assume {
8557        name: Option<Identifier>,
8558        expression: Expression,
8559    },
8560    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
8561    Default {
8562        name: Option<Identifier>,
8563        expression: Expression,
8564        column: Identifier,
8565    },
8566    /// INDEX / KEY constraint (MySQL)
8567    Index {
8568        name: Option<Identifier>,
8569        columns: Vec<Identifier>,
8570        /// Expression-capable index key parts. This is used when an index contains
8571        /// functional key parts that cannot be represented by `columns`.
8572        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8573        key_parts: Vec<IndexKeyPart>,
8574        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8575        #[serde(default)]
8576        kind: Option<String>,
8577        #[serde(default)]
8578        modifiers: ConstraintModifiers,
8579        /// True if KEY keyword was used instead of INDEX
8580        #[serde(default)]
8581        use_key_keyword: bool,
8582        /// ClickHouse: indexed expression (instead of columns)
8583        #[serde(default, skip_serializing_if = "Option::is_none")]
8584        expression: Option<Box<Expression>>,
8585        /// ClickHouse: TYPE type_func(args)
8586        #[serde(default, skip_serializing_if = "Option::is_none")]
8587        index_type: Option<Box<Expression>>,
8588        /// ClickHouse: GRANULARITY n
8589        #[serde(default, skip_serializing_if = "Option::is_none")]
8590        granularity: Option<Box<Expression>>,
8591    },
8592    /// ClickHouse PROJECTION definition
8593    Projection {
8594        name: Identifier,
8595        expression: Expression,
8596    },
8597    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8598    Like {
8599        source: TableRef,
8600        /// Options as (INCLUDING|EXCLUDING, property) pairs
8601        options: Vec<(LikeOptionAction, String)>,
8602    },
8603    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8604    PeriodForSystemTime {
8605        start_col: Identifier,
8606        end_col: Identifier,
8607    },
8608    /// PostgreSQL EXCLUDE constraint
8609    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8610    Exclude {
8611        name: Option<Identifier>,
8612        /// Index access method (gist, btree, etc.)
8613        #[serde(default)]
8614        using: Option<String>,
8615        /// Elements: (expression, operator) pairs
8616        elements: Vec<ExcludeElement>,
8617        /// INCLUDE columns
8618        #[serde(default)]
8619        include_columns: Vec<Identifier>,
8620        /// WHERE predicate
8621        #[serde(default)]
8622        where_clause: Option<Box<Expression>>,
8623        /// WITH (storage_parameters)
8624        #[serde(default)]
8625        with_params: Vec<(String, String)>,
8626        /// USING INDEX TABLESPACE tablespace_name
8627        #[serde(default)]
8628        using_index_tablespace: Option<String>,
8629        #[serde(default)]
8630        modifiers: ConstraintModifiers,
8631    },
8632    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8633    Tags(Tags),
8634    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8635    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8636    /// for all deferrable constraints in the table
8637    InitiallyDeferred {
8638        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8639        deferred: bool,
8640    },
8641}
8642
8643/// Element in an EXCLUDE constraint: expression WITH operator
8644#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8645#[cfg_attr(feature = "bindings", derive(TS))]
8646pub struct ExcludeElement {
8647    /// The column expression (may include operator class, ordering, nulls)
8648    pub expression: String,
8649    /// The operator (e.g., &&, =)
8650    pub operator: String,
8651}
8652
8653/// Action for LIKE clause options
8654#[derive(
8655    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8656)]
8657#[cfg_attr(feature = "bindings", derive(TS))]
8658pub enum LikeOptionAction {
8659    Including,
8660    Excluding,
8661}
8662
8663/// MATCH type for foreign keys
8664#[derive(
8665    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8666)]
8667#[cfg_attr(feature = "bindings", derive(TS))]
8668pub enum MatchType {
8669    Full,
8670    Partial,
8671    Simple,
8672}
8673
8674/// Foreign key reference
8675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8676#[cfg_attr(feature = "bindings", derive(TS))]
8677pub struct ForeignKeyRef {
8678    pub table: TableRef,
8679    pub columns: Vec<Identifier>,
8680    pub on_delete: Option<ReferentialAction>,
8681    pub on_update: Option<ReferentialAction>,
8682    /// True if ON UPDATE appears before ON DELETE in the original SQL
8683    #[serde(default)]
8684    pub on_update_first: bool,
8685    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8686    #[serde(default)]
8687    pub match_type: Option<MatchType>,
8688    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8689    #[serde(default)]
8690    pub match_after_actions: bool,
8691    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8692    #[serde(default)]
8693    pub constraint_name: Option<String>,
8694    /// DEFERRABLE / NOT DEFERRABLE
8695    #[serde(default)]
8696    pub deferrable: Option<bool>,
8697    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8698    #[serde(default)]
8699    pub has_foreign_key_keywords: bool,
8700}
8701
8702/// Referential action for foreign keys
8703#[derive(
8704    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8705)]
8706#[cfg_attr(feature = "bindings", derive(TS))]
8707pub enum ReferentialAction {
8708    Cascade,
8709    SetNull,
8710    SetDefault,
8711    Restrict,
8712    NoAction,
8713}
8714
8715/// DROP TABLE statement
8716#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8717#[cfg_attr(feature = "bindings", derive(TS))]
8718pub struct DropTable {
8719    pub names: Vec<TableRef>,
8720    pub if_exists: bool,
8721    pub cascade: bool,
8722    /// Oracle: CASCADE CONSTRAINTS
8723    #[serde(default)]
8724    pub cascade_constraints: bool,
8725    /// Oracle: PURGE
8726    #[serde(default)]
8727    pub purge: bool,
8728    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8729    #[serde(default)]
8730    pub leading_comments: Vec<String>,
8731    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8732    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8733    #[serde(default, skip_serializing_if = "Option::is_none")]
8734    pub object_id_args: Option<String>,
8735    /// ClickHouse: SYNC modifier
8736    #[serde(default)]
8737    pub sync: bool,
8738    /// Snowflake: DROP ICEBERG TABLE
8739    #[serde(default)]
8740    pub iceberg: bool,
8741    /// RESTRICT modifier (opposite of CASCADE)
8742    #[serde(default)]
8743    pub restrict: bool,
8744}
8745
8746impl DropTable {
8747    pub fn new(name: impl Into<String>) -> Self {
8748        Self {
8749            names: vec![TableRef::new(name)],
8750            if_exists: false,
8751            cascade: false,
8752            cascade_constraints: false,
8753            purge: false,
8754            leading_comments: Vec::new(),
8755            object_id_args: None,
8756            sync: false,
8757            iceberg: false,
8758            restrict: false,
8759        }
8760    }
8761}
8762
8763/// UNDROP object statement (Snowflake, ClickHouse)
8764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8765#[cfg_attr(feature = "bindings", derive(TS))]
8766pub struct Undrop {
8767    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8768    pub kind: String,
8769    /// The object name
8770    pub name: TableRef,
8771    /// IF EXISTS clause
8772    #[serde(default)]
8773    pub if_exists: bool,
8774    /// Snowflake: optional RENAME TO target
8775    #[serde(default, skip_serializing_if = "Option::is_none")]
8776    pub rename_to: Option<TableRef>,
8777}
8778
8779/// Partition scope for a TiDB `SPLIT TABLE` statement.
8780#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8781#[cfg_attr(feature = "bindings", derive(TS))]
8782#[serde(tag = "type", rename_all = "snake_case")]
8783pub enum SplitTablePartitionScope {
8784    Table,
8785    AllPartitions,
8786    Partitions { names: Vec<Identifier> },
8787}
8788
8789/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8790#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8791#[cfg_attr(feature = "bindings", derive(TS))]
8792#[serde(tag = "type", rename_all = "snake_case")]
8793pub enum SplitTableMode {
8794    Between {
8795        lower: Vec<Expression>,
8796        upper: Vec<Expression>,
8797        regions: u64,
8798    },
8799    By {
8800        points: Vec<Vec<Expression>>,
8801    },
8802}
8803
8804/// TiDB `SPLIT [PARTITION] TABLE` statement.
8805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8806#[cfg_attr(feature = "bindings", derive(TS))]
8807pub struct SplitTable {
8808    pub table: TableRef,
8809    pub partition_scope: SplitTablePartitionScope,
8810    #[serde(default, skip_serializing_if = "Option::is_none")]
8811    pub index: Option<Identifier>,
8812    pub mode: SplitTableMode,
8813}
8814
8815/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
8816#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8817#[cfg_attr(feature = "bindings", derive(TS))]
8818pub struct FlashbackTable {
8819    pub table: TableRef,
8820    #[serde(default, skip_serializing_if = "Option::is_none")]
8821    pub rename_to: Option<Identifier>,
8822}
8823
8824/// ALTER TABLE statement
8825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8826#[cfg_attr(feature = "bindings", derive(TS))]
8827pub struct AlterTable {
8828    pub name: TableRef,
8829    pub actions: Vec<AlterTableAction>,
8830    /// IF EXISTS clause
8831    #[serde(default)]
8832    pub if_exists: bool,
8833    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8834    #[serde(default, skip_serializing_if = "Option::is_none")]
8835    pub algorithm: Option<String>,
8836    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8837    #[serde(default, skip_serializing_if = "Option::is_none")]
8838    pub lock: Option<String>,
8839    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8840    #[serde(default, skip_serializing_if = "Option::is_none")]
8841    pub with_check: Option<String>,
8842    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8843    #[serde(default, skip_serializing_if = "Option::is_none")]
8844    pub partition: Option<Vec<(Identifier, Expression)>>,
8845    /// ClickHouse: ON CLUSTER clause for distributed DDL
8846    #[serde(default, skip_serializing_if = "Option::is_none")]
8847    pub on_cluster: Option<OnCluster>,
8848    /// Snowflake: ALTER ICEBERG TABLE
8849    #[serde(default, skip_serializing_if = "Option::is_none")]
8850    pub table_modifier: Option<String>,
8851}
8852
8853impl AlterTable {
8854    pub fn new(name: impl Into<String>) -> Self {
8855        Self {
8856            name: TableRef::new(name),
8857            actions: Vec::new(),
8858            if_exists: false,
8859            algorithm: None,
8860            lock: None,
8861            with_check: None,
8862            partition: None,
8863            on_cluster: None,
8864            table_modifier: None,
8865        }
8866    }
8867}
8868
8869/// Column position for ADD COLUMN (MySQL/MariaDB)
8870#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8871#[cfg_attr(feature = "bindings", derive(TS))]
8872pub enum ColumnPosition {
8873    First,
8874    After(Identifier),
8875}
8876
8877/// Actions for ALTER TABLE
8878#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8879#[cfg_attr(feature = "bindings", derive(TS))]
8880pub enum AlterTableAction {
8881    AddColumn {
8882        column: ColumnDef,
8883        if_not_exists: bool,
8884        position: Option<ColumnPosition>,
8885    },
8886    DropColumn {
8887        name: Identifier,
8888        if_exists: bool,
8889        cascade: bool,
8890    },
8891    RenameColumn {
8892        old_name: Identifier,
8893        new_name: Identifier,
8894        if_exists: bool,
8895    },
8896    AlterColumn {
8897        name: Identifier,
8898        action: AlterColumnAction,
8899        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8900        #[serde(default)]
8901        use_modify_keyword: bool,
8902    },
8903    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
8904    ModifyColumn {
8905        column: ColumnDef,
8906        if_exists: bool,
8907        position: Option<ColumnPosition>,
8908    },
8909    RenameTable(TableRef),
8910    AddConstraint(TableConstraint),
8911    DropConstraint {
8912        name: Identifier,
8913        if_exists: bool,
8914    },
8915    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8916    DropForeignKey {
8917        name: Identifier,
8918    },
8919    /// DROP PARTITION action (Hive/BigQuery)
8920    DropPartition {
8921        /// List of partitions to drop (each partition is a list of key=value pairs)
8922        partitions: Vec<Vec<(Identifier, Expression)>>,
8923        if_exists: bool,
8924    },
8925    /// ADD PARTITION action (Hive/Spark)
8926    AddPartition {
8927        /// The partition expression
8928        partition: Expression,
8929        if_not_exists: bool,
8930        location: Option<Expression>,
8931    },
8932    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8933    Delete {
8934        where_clause: Expression,
8935    },
8936    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8937    SwapWith(TableRef),
8938    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8939    SetProperty {
8940        properties: Vec<(String, Expression)>,
8941    },
8942    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8943    UnsetProperty {
8944        properties: Vec<String>,
8945    },
8946    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8947    ClusterBy {
8948        expressions: Vec<Expression>,
8949    },
8950    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8951    SetTag {
8952        expressions: Vec<(String, Expression)>,
8953    },
8954    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8955    UnsetTag {
8956        names: Vec<String>,
8957    },
8958    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8959    SetOptions {
8960        expressions: Vec<Expression>,
8961    },
8962    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8963    AlterIndex {
8964        name: Identifier,
8965        visible: bool,
8966    },
8967    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8968    SetAttribute {
8969        attribute: String,
8970    },
8971    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8972    SetStageFileFormat {
8973        options: Option<Expression>,
8974    },
8975    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8976    SetStageCopyOptions {
8977        options: Option<Expression>,
8978    },
8979    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8980    AddColumns {
8981        columns: Vec<ColumnDef>,
8982        cascade: bool,
8983    },
8984    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8985    DropColumns {
8986        names: Vec<Identifier>,
8987    },
8988    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8989    /// In SingleStore, data_type can be omitted for simple column renames
8990    ChangeColumn {
8991        old_name: Identifier,
8992        new_name: Identifier,
8993        #[serde(default, skip_serializing_if = "Option::is_none")]
8994        data_type: Option<DataType>,
8995        comment: Option<String>,
8996        #[serde(default)]
8997        cascade: bool,
8998    },
8999    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
9000    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
9001    AlterSortKey {
9002        /// AUTO or NONE keyword
9003        this: Option<String>,
9004        /// Column list for (col1, col2) syntax
9005        expressions: Vec<Expression>,
9006        /// Whether COMPOUND keyword was present
9007        compound: bool,
9008    },
9009    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
9010    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
9011    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
9012    AlterDistStyle {
9013        /// Distribution style: ALL, EVEN, AUTO, or KEY
9014        style: String,
9015        /// DISTKEY column (only when style is KEY)
9016        distkey: Option<Identifier>,
9017    },
9018    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
9019    SetTableProperties {
9020        properties: Vec<(Expression, Expression)>,
9021    },
9022    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
9023    SetLocation {
9024        location: String,
9025    },
9026    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
9027    SetFileFormat {
9028        format: String,
9029    },
9030    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
9031    ReplacePartition {
9032        partition: Expression,
9033        source: Option<Box<Expression>>,
9034    },
9035    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
9036    SetTiDBTableOption {
9037        option: TiDBTableOption,
9038        #[serde(default)]
9039        force: bool,
9040    },
9041    /// TiDB `REMOVE TTL`.
9042    RemoveTiDBTtl {
9043        #[serde(default)]
9044        executable_comment: bool,
9045    },
9046    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
9047    Raw {
9048        sql: String,
9049    },
9050}
9051
9052/// Actions for ALTER COLUMN
9053#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9054#[cfg_attr(feature = "bindings", derive(TS))]
9055pub enum AlterColumnAction {
9056    SetDataType {
9057        data_type: DataType,
9058        /// USING expression for type conversion (PostgreSQL)
9059        using: Option<Expression>,
9060        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
9061        #[serde(default, skip_serializing_if = "Option::is_none")]
9062        collate: Option<String>,
9063    },
9064    SetDefault(Expression),
9065    DropDefault,
9066    SetNotNull,
9067    DropNotNull,
9068    /// Set column comment
9069    Comment(String),
9070    /// MySQL: SET VISIBLE
9071    SetVisible,
9072    /// MySQL: SET INVISIBLE
9073    SetInvisible,
9074}
9075
9076/// CREATE INDEX statement
9077#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9078#[cfg_attr(feature = "bindings", derive(TS))]
9079pub struct CreateIndex {
9080    pub name: Identifier,
9081    pub table: TableRef,
9082    pub columns: Vec<IndexColumn>,
9083    /// Expression-capable index key parts. This is used when an index contains
9084    /// functional key parts that cannot be represented by `columns`.
9085    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9086    pub key_parts: Vec<IndexKeyPart>,
9087    pub unique: bool,
9088    pub if_not_exists: bool,
9089    pub using: Option<String>,
9090    /// TSQL CLUSTERED/NONCLUSTERED modifier
9091    #[serde(default)]
9092    pub clustered: Option<String>,
9093    /// PostgreSQL CONCURRENTLY modifier
9094    #[serde(default)]
9095    pub concurrently: bool,
9096    /// PostgreSQL WHERE clause for partial indexes
9097    #[serde(default)]
9098    pub where_clause: Option<Box<Expression>>,
9099    /// PostgreSQL INCLUDE columns
9100    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9101    pub include_columns: Vec<Identifier>,
9102    /// TSQL WITH options (e.g., allow_page_locks=on)
9103    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9104    pub with_options: Vec<(String, String)>,
9105    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
9106    #[serde(default)]
9107    pub on_filegroup: Option<String>,
9108}
9109
9110impl CreateIndex {
9111    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
9112        Self {
9113            name: Identifier::new(name),
9114            table: TableRef::new(table),
9115            columns: Vec::new(),
9116            key_parts: Vec::new(),
9117            unique: false,
9118            if_not_exists: false,
9119            using: None,
9120            clustered: None,
9121            concurrently: false,
9122            where_clause: None,
9123            include_columns: Vec::new(),
9124            with_options: Vec::new(),
9125            on_filegroup: None,
9126        }
9127    }
9128}
9129
9130/// Index column specification
9131#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9132#[cfg_attr(feature = "bindings", derive(TS))]
9133pub struct IndexColumn {
9134    pub column: Identifier,
9135    pub desc: bool,
9136    /// Explicit ASC keyword was present
9137    #[serde(default)]
9138    pub asc: bool,
9139    pub nulls_first: Option<bool>,
9140    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
9141    #[serde(default, skip_serializing_if = "Option::is_none")]
9142    pub opclass: Option<String>,
9143}
9144
9145/// An expression-capable index key part.
9146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9147#[cfg_attr(feature = "bindings", derive(TS))]
9148pub struct IndexKeyPart {
9149    pub expression: Box<Expression>,
9150    /// MySQL column prefix length, for example the `16` in `name(16)`.
9151    #[serde(default, skip_serializing_if = "Option::is_none")]
9152    pub prefix_length: Option<String>,
9153    pub desc: bool,
9154    /// Explicit ASC keyword was present.
9155    #[serde(default)]
9156    pub asc: bool,
9157    pub nulls_first: Option<bool>,
9158    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops).
9159    #[serde(default, skip_serializing_if = "Option::is_none")]
9160    pub opclass: Option<String>,
9161}
9162
9163/// DROP INDEX statement
9164#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9165#[cfg_attr(feature = "bindings", derive(TS))]
9166pub struct DropIndex {
9167    pub name: TableRef,
9168    pub table: Option<TableRef>,
9169    pub if_exists: bool,
9170    /// PostgreSQL CONCURRENTLY modifier
9171    #[serde(default)]
9172    pub concurrently: bool,
9173}
9174
9175impl DropIndex {
9176    pub fn new(name: impl Into<String>) -> Self {
9177        Self {
9178            name: TableRef::new(name),
9179            table: None,
9180            if_exists: false,
9181            concurrently: false,
9182        }
9183    }
9184}
9185
9186/// View column definition with optional COMMENT and OPTIONS (BigQuery)
9187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9188#[cfg_attr(feature = "bindings", derive(TS))]
9189pub struct ViewColumn {
9190    pub name: Identifier,
9191    pub comment: Option<String>,
9192    /// BigQuery: OPTIONS (key=value, ...) on column
9193    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9194    pub options: Vec<Expression>,
9195}
9196
9197impl ViewColumn {
9198    pub fn new(name: impl Into<String>) -> Self {
9199        Self {
9200            name: Identifier::new(name),
9201            comment: None,
9202            options: Vec::new(),
9203        }
9204    }
9205
9206    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
9207        Self {
9208            name: Identifier::new(name),
9209            comment: Some(comment.into()),
9210            options: Vec::new(),
9211        }
9212    }
9213}
9214
9215/// CREATE VIEW statement
9216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9217#[cfg_attr(feature = "bindings", derive(TS))]
9218pub struct CreateView {
9219    pub name: TableRef,
9220    pub columns: Vec<ViewColumn>,
9221    pub query: Expression,
9222    pub or_replace: bool,
9223    /// TSQL: CREATE OR ALTER
9224    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9225    pub or_alter: bool,
9226    pub if_not_exists: bool,
9227    pub materialized: bool,
9228    pub temporary: bool,
9229    /// Snowflake: SECURE VIEW
9230    #[serde(default)]
9231    pub secure: bool,
9232    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
9233    #[serde(skip_serializing_if = "Option::is_none")]
9234    pub algorithm: Option<String>,
9235    /// MySQL: DEFINER=user@host
9236    #[serde(skip_serializing_if = "Option::is_none")]
9237    pub definer: Option<String>,
9238    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
9239    #[serde(skip_serializing_if = "Option::is_none")]
9240    pub security: Option<FunctionSecurity>,
9241    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
9242    #[serde(default = "default_true")]
9243    pub security_sql_style: bool,
9244    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
9245    #[serde(default)]
9246    pub security_after_name: bool,
9247    /// Whether the query was parenthesized: AS (SELECT ...)
9248    #[serde(default)]
9249    pub query_parenthesized: bool,
9250    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
9251    #[serde(skip_serializing_if = "Option::is_none")]
9252    pub locking_mode: Option<String>,
9253    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
9254    #[serde(skip_serializing_if = "Option::is_none")]
9255    pub locking_access: Option<String>,
9256    /// Snowflake: COPY GRANTS
9257    #[serde(default)]
9258    pub copy_grants: bool,
9259    /// Snowflake: COMMENT = 'text'
9260    #[serde(skip_serializing_if = "Option::is_none", default)]
9261    pub comment: Option<String>,
9262    /// Snowflake: WITH ROW ACCESS POLICY ... clause
9263    #[serde(skip_serializing_if = "Option::is_none", default)]
9264    pub row_access_policy: Option<String>,
9265    /// Snowflake: TAG (name='value', ...)
9266    #[serde(default)]
9267    pub tags: Vec<(String, String)>,
9268    /// BigQuery: OPTIONS (key=value, ...)
9269    #[serde(default)]
9270    pub options: Vec<Expression>,
9271    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
9272    #[serde(skip_serializing_if = "Option::is_none", default)]
9273    pub build: Option<String>,
9274    /// Doris: REFRESH property for materialized views
9275    #[serde(skip_serializing_if = "Option::is_none", default)]
9276    pub refresh: Option<Box<RefreshTriggerProperty>>,
9277    /// Doris: Schema with typed column definitions for materialized views
9278    /// This is used instead of `columns` when the view has typed column definitions
9279    #[serde(skip_serializing_if = "Option::is_none", default)]
9280    pub schema: Option<Box<Schema>>,
9281    /// Doris: KEY (columns) for materialized views
9282    #[serde(skip_serializing_if = "Option::is_none", default)]
9283    pub unique_key: Option<Box<UniqueKeyProperty>>,
9284    /// Redshift: WITH NO SCHEMA BINDING
9285    #[serde(default)]
9286    pub no_schema_binding: bool,
9287    /// Redshift: AUTO REFRESH YES|NO for materialized views
9288    #[serde(skip_serializing_if = "Option::is_none", default)]
9289    pub auto_refresh: Option<bool>,
9290    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
9291    #[serde(skip_serializing_if = "Option::is_none", default)]
9292    pub clickhouse_population: Option<String>,
9293    /// ClickHouse: ON CLUSTER clause
9294    #[serde(default, skip_serializing_if = "Option::is_none")]
9295    pub on_cluster: Option<OnCluster>,
9296    /// ClickHouse: TO destination_table
9297    #[serde(default, skip_serializing_if = "Option::is_none")]
9298    pub to_table: Option<TableRef>,
9299    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
9300    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9301    pub table_properties: Vec<Expression>,
9302}
9303
9304impl CreateView {
9305    pub fn new(name: impl Into<String>, query: Expression) -> Self {
9306        Self {
9307            name: TableRef::new(name),
9308            columns: Vec::new(),
9309            query,
9310            or_replace: false,
9311            or_alter: false,
9312            if_not_exists: false,
9313            materialized: false,
9314            temporary: false,
9315            secure: false,
9316            algorithm: None,
9317            definer: None,
9318            security: None,
9319            security_sql_style: true,
9320            security_after_name: false,
9321            query_parenthesized: false,
9322            locking_mode: None,
9323            locking_access: None,
9324            copy_grants: false,
9325            comment: None,
9326            row_access_policy: None,
9327            tags: Vec::new(),
9328            options: Vec::new(),
9329            build: None,
9330            refresh: None,
9331            schema: None,
9332            unique_key: None,
9333            no_schema_binding: false,
9334            auto_refresh: None,
9335            clickhouse_population: None,
9336            on_cluster: None,
9337            to_table: None,
9338            table_properties: Vec::new(),
9339        }
9340    }
9341}
9342
9343/// DROP VIEW statement
9344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9345#[cfg_attr(feature = "bindings", derive(TS))]
9346pub struct DropView {
9347    pub name: TableRef,
9348    pub if_exists: bool,
9349    pub materialized: bool,
9350}
9351
9352impl DropView {
9353    pub fn new(name: impl Into<String>) -> Self {
9354        Self {
9355            name: TableRef::new(name),
9356            if_exists: false,
9357            materialized: false,
9358        }
9359    }
9360}
9361
9362/// TRUNCATE TABLE statement
9363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9364#[cfg_attr(feature = "bindings", derive(TS))]
9365pub struct Truncate {
9366    /// Target of TRUNCATE (TABLE vs DATABASE)
9367    #[serde(default)]
9368    pub target: TruncateTarget,
9369    /// IF EXISTS clause
9370    #[serde(default)]
9371    pub if_exists: bool,
9372    pub table: TableRef,
9373    /// ClickHouse: ON CLUSTER clause for distributed DDL
9374    #[serde(default, skip_serializing_if = "Option::is_none")]
9375    pub on_cluster: Option<OnCluster>,
9376    pub cascade: bool,
9377    /// Additional tables for multi-table TRUNCATE
9378    #[serde(default)]
9379    pub extra_tables: Vec<TruncateTableEntry>,
9380    /// RESTART IDENTITY or CONTINUE IDENTITY
9381    #[serde(default)]
9382    pub identity: Option<TruncateIdentity>,
9383    /// RESTRICT option (alternative to CASCADE)
9384    #[serde(default)]
9385    pub restrict: bool,
9386    /// Hive PARTITION clause: PARTITION(key=value, ...)
9387    #[serde(default, skip_serializing_if = "Option::is_none")]
9388    pub partition: Option<Box<Expression>>,
9389}
9390
9391/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
9392#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9393#[cfg_attr(feature = "bindings", derive(TS))]
9394pub struct TruncateTableEntry {
9395    pub table: TableRef,
9396    /// Whether the table has a * suffix (inherit children)
9397    #[serde(default)]
9398    pub star: bool,
9399}
9400
9401/// TRUNCATE target type
9402#[derive(
9403    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9404)]
9405#[cfg_attr(feature = "bindings", derive(TS))]
9406pub enum TruncateTarget {
9407    Table,
9408    Database,
9409}
9410
9411impl Default for TruncateTarget {
9412    fn default() -> Self {
9413        TruncateTarget::Table
9414    }
9415}
9416
9417/// TRUNCATE identity option
9418#[derive(
9419    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9420)]
9421#[cfg_attr(feature = "bindings", derive(TS))]
9422pub enum TruncateIdentity {
9423    Restart,
9424    Continue,
9425}
9426
9427impl Truncate {
9428    pub fn new(table: impl Into<String>) -> Self {
9429        Self {
9430            target: TruncateTarget::Table,
9431            if_exists: false,
9432            table: TableRef::new(table),
9433            on_cluster: None,
9434            cascade: false,
9435            extra_tables: Vec::new(),
9436            identity: None,
9437            restrict: false,
9438            partition: None,
9439        }
9440    }
9441}
9442
9443/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
9444#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9445#[cfg_attr(feature = "bindings", derive(TS))]
9446pub struct Use {
9447    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
9448    pub kind: Option<UseKind>,
9449    /// The name of the object
9450    pub this: Identifier,
9451}
9452
9453/// Kind of USE statement
9454#[derive(
9455    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9456)]
9457#[cfg_attr(feature = "bindings", derive(TS))]
9458pub enum UseKind {
9459    Database,
9460    Schema,
9461    Role,
9462    Warehouse,
9463    Catalog,
9464    /// Snowflake: USE SECONDARY ROLES ALL|NONE
9465    SecondaryRoles,
9466}
9467
9468/// SET variable statement
9469#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9470#[cfg_attr(feature = "bindings", derive(TS))]
9471pub struct SetStatement {
9472    /// The items being set
9473    pub items: Vec<SetItem>,
9474}
9475
9476/// A single SET item (variable assignment)
9477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9478#[cfg_attr(feature = "bindings", derive(TS))]
9479pub struct SetItem {
9480    /// The variable name
9481    pub name: Expression,
9482    /// The value to set
9483    pub value: Expression,
9484    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
9485    pub kind: Option<String>,
9486    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
9487    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9488    pub no_equals: bool,
9489}
9490
9491/// CACHE TABLE statement (Spark)
9492#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9493#[cfg_attr(feature = "bindings", derive(TS))]
9494pub struct Cache {
9495    /// The table to cache
9496    pub table: Identifier,
9497    /// LAZY keyword - defer caching until first use
9498    pub lazy: bool,
9499    /// Optional OPTIONS clause (key-value pairs)
9500    pub options: Vec<(Expression, Expression)>,
9501    /// Optional AS clause with query
9502    pub query: Option<Expression>,
9503}
9504
9505/// UNCACHE TABLE statement (Spark)
9506#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9507#[cfg_attr(feature = "bindings", derive(TS))]
9508pub struct Uncache {
9509    /// The table to uncache
9510    pub table: Identifier,
9511    /// IF EXISTS clause
9512    pub if_exists: bool,
9513}
9514
9515/// LOAD DATA statement (Hive)
9516#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9517#[cfg_attr(feature = "bindings", derive(TS))]
9518pub struct LoadData {
9519    /// LOCAL keyword - load from local filesystem
9520    pub local: bool,
9521    /// The path to load data from (INPATH value)
9522    pub inpath: String,
9523    /// Whether to overwrite existing data
9524    pub overwrite: bool,
9525    /// The target table
9526    pub table: Expression,
9527    /// Optional PARTITION clause with key-value pairs
9528    pub partition: Vec<(Identifier, Expression)>,
9529    /// Optional INPUTFORMAT clause
9530    pub input_format: Option<String>,
9531    /// Optional SERDE clause
9532    pub serde: Option<String>,
9533}
9534
9535/// PRAGMA statement (SQLite)
9536#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9537#[cfg_attr(feature = "bindings", derive(TS))]
9538pub struct Pragma {
9539    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
9540    pub schema: Option<Identifier>,
9541    /// The pragma name
9542    pub name: Identifier,
9543    /// Optional value for assignment (PRAGMA name = value)
9544    pub value: Option<Expression>,
9545    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
9546    pub args: Vec<Expression>,
9547    /// Whether this pragma should be generated using assignment syntax.
9548    #[serde(default)]
9549    pub use_assignment_syntax: bool,
9550}
9551
9552/// A privilege with optional column list for GRANT/REVOKE
9553/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
9554#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9555#[cfg_attr(feature = "bindings", derive(TS))]
9556pub struct Privilege {
9557    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
9558    pub name: String,
9559    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
9560    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9561    pub columns: Vec<String>,
9562}
9563
9564/// Principal in GRANT/REVOKE (user, role, etc.)
9565#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9566#[cfg_attr(feature = "bindings", derive(TS))]
9567pub struct GrantPrincipal {
9568    /// The name of the principal
9569    pub name: Identifier,
9570    /// Whether prefixed with ROLE keyword
9571    pub is_role: bool,
9572    /// Whether prefixed with GROUP keyword (Redshift)
9573    #[serde(default)]
9574    pub is_group: bool,
9575    /// Whether prefixed with SHARE keyword (Snowflake)
9576    #[serde(default)]
9577    pub is_share: bool,
9578}
9579
9580/// GRANT statement
9581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9582#[cfg_attr(feature = "bindings", derive(TS))]
9583pub struct Grant {
9584    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
9585    pub privileges: Vec<Privilege>,
9586    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9587    pub kind: Option<String>,
9588    /// The object to grant on
9589    pub securable: Identifier,
9590    /// Function parameter types (for FUNCTION kind)
9591    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9592    pub function_params: Vec<String>,
9593    /// The grantees
9594    pub principals: Vec<GrantPrincipal>,
9595    /// WITH GRANT OPTION
9596    pub grant_option: bool,
9597    /// TSQL: AS principal (the grantor role)
9598    #[serde(default, skip_serializing_if = "Option::is_none")]
9599    pub as_principal: Option<Identifier>,
9600}
9601
9602/// REVOKE statement
9603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9604#[cfg_attr(feature = "bindings", derive(TS))]
9605pub struct Revoke {
9606    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9607    pub privileges: Vec<Privilege>,
9608    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9609    pub kind: Option<String>,
9610    /// The object to revoke from
9611    pub securable: Identifier,
9612    /// Function parameter types (for FUNCTION kind)
9613    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9614    pub function_params: Vec<String>,
9615    /// The grantees
9616    pub principals: Vec<GrantPrincipal>,
9617    /// GRANT OPTION FOR
9618    pub grant_option: bool,
9619    /// CASCADE
9620    pub cascade: bool,
9621    /// RESTRICT
9622    #[serde(default)]
9623    pub restrict: bool,
9624}
9625
9626/// COMMENT ON statement
9627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9628#[cfg_attr(feature = "bindings", derive(TS))]
9629pub struct Comment {
9630    /// The object being commented on
9631    pub this: Expression,
9632    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9633    pub kind: String,
9634    /// The comment text expression
9635    pub expression: Expression,
9636    /// IF EXISTS clause
9637    pub exists: bool,
9638    /// MATERIALIZED keyword
9639    pub materialized: bool,
9640}
9641
9642// ============================================================================
9643// Phase 4: Additional DDL Statements
9644// ============================================================================
9645
9646/// ALTER VIEW statement
9647#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9648#[cfg_attr(feature = "bindings", derive(TS))]
9649pub struct AlterView {
9650    pub name: TableRef,
9651    pub actions: Vec<AlterViewAction>,
9652    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9653    #[serde(default, skip_serializing_if = "Option::is_none")]
9654    pub algorithm: Option<String>,
9655    /// MySQL: DEFINER = 'user'@'host'
9656    #[serde(default, skip_serializing_if = "Option::is_none")]
9657    pub definer: Option<String>,
9658    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9659    #[serde(default, skip_serializing_if = "Option::is_none")]
9660    pub sql_security: Option<String>,
9661    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9662    #[serde(default, skip_serializing_if = "Option::is_none")]
9663    pub with_option: Option<String>,
9664    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9665    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9666    pub columns: Vec<ViewColumn>,
9667}
9668
9669/// Actions for ALTER VIEW
9670#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9671#[cfg_attr(feature = "bindings", derive(TS))]
9672pub enum AlterViewAction {
9673    /// Rename the view
9674    Rename(TableRef),
9675    /// Change owner
9676    OwnerTo(Identifier),
9677    /// Set schema
9678    SetSchema(Identifier),
9679    /// Set authorization (Trino/Presto)
9680    SetAuthorization(String),
9681    /// Alter column
9682    AlterColumn {
9683        name: Identifier,
9684        action: AlterColumnAction,
9685    },
9686    /// Redefine view as query (SELECT, UNION, etc.)
9687    AsSelect(Box<Expression>),
9688    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9689    SetTblproperties(Vec<(String, String)>),
9690    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9691    UnsetTblproperties(Vec<String>),
9692}
9693
9694impl AlterView {
9695    pub fn new(name: impl Into<String>) -> Self {
9696        Self {
9697            name: TableRef::new(name),
9698            actions: Vec::new(),
9699            algorithm: None,
9700            definer: None,
9701            sql_security: None,
9702            with_option: None,
9703            columns: Vec::new(),
9704        }
9705    }
9706}
9707
9708/// ALTER INDEX statement
9709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9710#[cfg_attr(feature = "bindings", derive(TS))]
9711pub struct AlterIndex {
9712    pub name: Identifier,
9713    pub table: Option<TableRef>,
9714    pub actions: Vec<AlterIndexAction>,
9715}
9716
9717/// Actions for ALTER INDEX
9718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9719#[cfg_attr(feature = "bindings", derive(TS))]
9720pub enum AlterIndexAction {
9721    /// Rename the index
9722    Rename(Identifier),
9723    /// Set tablespace
9724    SetTablespace(Identifier),
9725    /// Set visibility (MySQL)
9726    Visible(bool),
9727}
9728
9729impl AlterIndex {
9730    pub fn new(name: impl Into<String>) -> Self {
9731        Self {
9732            name: Identifier::new(name),
9733            table: None,
9734            actions: Vec::new(),
9735        }
9736    }
9737}
9738
9739/// CREATE SCHEMA statement
9740#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9741#[cfg_attr(feature = "bindings", derive(TS))]
9742pub struct CreateSchema {
9743    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9744    pub name: Vec<Identifier>,
9745    pub if_not_exists: bool,
9746    pub authorization: Option<Identifier>,
9747    /// CLONE source parts, possibly dot-qualified
9748    #[serde(default)]
9749    pub clone_from: Option<Vec<Identifier>>,
9750    /// AT/BEFORE clause for time travel (Snowflake)
9751    #[serde(default)]
9752    pub at_clause: Option<Expression>,
9753    /// Schema properties like DEFAULT COLLATE
9754    #[serde(default)]
9755    pub properties: Vec<Expression>,
9756    /// Leading comments before the statement
9757    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9758    pub leading_comments: Vec<String>,
9759}
9760
9761impl CreateSchema {
9762    pub fn new(name: impl Into<String>) -> Self {
9763        Self {
9764            name: vec![Identifier::new(name)],
9765            if_not_exists: false,
9766            authorization: None,
9767            clone_from: None,
9768            at_clause: None,
9769            properties: Vec::new(),
9770            leading_comments: Vec::new(),
9771        }
9772    }
9773}
9774
9775/// DROP SCHEMA statement
9776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9777#[cfg_attr(feature = "bindings", derive(TS))]
9778pub struct DropSchema {
9779    pub name: Identifier,
9780    pub if_exists: bool,
9781    pub cascade: bool,
9782}
9783
9784impl DropSchema {
9785    pub fn new(name: impl Into<String>) -> Self {
9786        Self {
9787            name: Identifier::new(name),
9788            if_exists: false,
9789            cascade: false,
9790        }
9791    }
9792}
9793
9794/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9795#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9796#[cfg_attr(feature = "bindings", derive(TS))]
9797pub struct DropNamespace {
9798    pub name: Identifier,
9799    pub if_exists: bool,
9800    pub cascade: bool,
9801}
9802
9803impl DropNamespace {
9804    pub fn new(name: impl Into<String>) -> Self {
9805        Self {
9806            name: Identifier::new(name),
9807            if_exists: false,
9808            cascade: false,
9809        }
9810    }
9811}
9812
9813/// CREATE DATABASE statement
9814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9815#[cfg_attr(feature = "bindings", derive(TS))]
9816pub struct CreateDatabase {
9817    pub name: Identifier,
9818    pub if_not_exists: bool,
9819    pub options: Vec<DatabaseOption>,
9820    /// Snowflake CLONE source
9821    #[serde(default)]
9822    pub clone_from: Option<Identifier>,
9823    /// AT/BEFORE clause for time travel (Snowflake)
9824    #[serde(default)]
9825    pub at_clause: Option<Expression>,
9826}
9827
9828/// Database option
9829#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9830#[cfg_attr(feature = "bindings", derive(TS))]
9831pub enum DatabaseOption {
9832    CharacterSet(String),
9833    Collate(String),
9834    Owner(Identifier),
9835    Template(Identifier),
9836    Encoding(String),
9837    Location(String),
9838}
9839
9840impl CreateDatabase {
9841    pub fn new(name: impl Into<String>) -> Self {
9842        Self {
9843            name: Identifier::new(name),
9844            if_not_exists: false,
9845            options: Vec::new(),
9846            clone_from: None,
9847            at_clause: None,
9848        }
9849    }
9850}
9851
9852/// DROP DATABASE statement
9853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9854#[cfg_attr(feature = "bindings", derive(TS))]
9855pub struct DropDatabase {
9856    pub name: Identifier,
9857    pub if_exists: bool,
9858    /// ClickHouse: SYNC modifier
9859    #[serde(default)]
9860    pub sync: bool,
9861}
9862
9863impl DropDatabase {
9864    pub fn new(name: impl Into<String>) -> Self {
9865        Self {
9866            name: Identifier::new(name),
9867            if_exists: false,
9868            sync: false,
9869        }
9870    }
9871}
9872
9873/// CREATE FUNCTION statement
9874#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9875#[cfg_attr(feature = "bindings", derive(TS))]
9876pub struct CreateFunction {
9877    pub name: TableRef,
9878    pub parameters: Vec<FunctionParameter>,
9879    pub return_type: Option<DataType>,
9880    pub body: Option<FunctionBody>,
9881    pub or_replace: bool,
9882    /// TSQL: CREATE OR ALTER
9883    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9884    pub or_alter: bool,
9885    pub if_not_exists: bool,
9886    pub temporary: bool,
9887    pub language: Option<String>,
9888    pub deterministic: Option<bool>,
9889    pub returns_null_on_null_input: Option<bool>,
9890    pub security: Option<FunctionSecurity>,
9891    /// Whether parentheses were present in the original syntax
9892    #[serde(default = "default_true")]
9893    pub has_parens: bool,
9894    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9895    #[serde(default)]
9896    pub sql_data_access: Option<SqlDataAccess>,
9897    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9898    #[serde(default, skip_serializing_if = "Option::is_none")]
9899    pub returns_table_body: Option<String>,
9900    /// True if LANGUAGE clause appears before RETURNS clause
9901    #[serde(default)]
9902    pub language_first: bool,
9903    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9904    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9905    pub set_options: Vec<FunctionSetOption>,
9906    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9907    #[serde(default)]
9908    pub strict: bool,
9909    /// BigQuery: OPTIONS (key=value, ...)
9910    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9911    pub options: Vec<Expression>,
9912    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9913    #[serde(default)]
9914    pub is_table_function: bool,
9915    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9916    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9917    pub property_order: Vec<FunctionPropertyKind>,
9918    /// Hive: USING JAR|FILE|ARCHIVE '...'
9919    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9920    pub using_resources: Vec<FunctionUsingResource>,
9921    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9922    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9923    pub environment: Vec<Expression>,
9924    /// HANDLER 'handler_function' clause (Databricks)
9925    #[serde(default, skip_serializing_if = "Option::is_none")]
9926    pub handler: Option<String>,
9927    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9928    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9929    pub handler_uses_eq: bool,
9930    /// Snowflake: RUNTIME_VERSION='3.11'
9931    #[serde(default, skip_serializing_if = "Option::is_none")]
9932    pub runtime_version: Option<String>,
9933    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9934    #[serde(default, skip_serializing_if = "Option::is_none")]
9935    pub packages: Option<Vec<String>>,
9936    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9937    #[serde(default, skip_serializing_if = "Option::is_none")]
9938    pub parameter_style: Option<String>,
9939}
9940
9941/// A SET option in CREATE FUNCTION (PostgreSQL)
9942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9943#[cfg_attr(feature = "bindings", derive(TS))]
9944pub struct FunctionSetOption {
9945    pub name: String,
9946    pub value: FunctionSetValue,
9947}
9948
9949/// The value of a SET option
9950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9951#[cfg_attr(feature = "bindings", derive(TS))]
9952pub enum FunctionSetValue {
9953    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9954    Value { value: String, use_to: bool },
9955    /// SET key FROM CURRENT
9956    FromCurrent,
9957}
9958
9959/// SQL data access characteristics for functions
9960#[derive(
9961    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9962)]
9963#[cfg_attr(feature = "bindings", derive(TS))]
9964pub enum SqlDataAccess {
9965    /// NO SQL
9966    NoSql,
9967    /// CONTAINS SQL
9968    ContainsSql,
9969    /// READS SQL DATA
9970    ReadsSqlData,
9971    /// MODIFIES SQL DATA
9972    ModifiesSqlData,
9973}
9974
9975/// Types of properties in CREATE FUNCTION for tracking their original order
9976#[derive(
9977    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9978)]
9979#[cfg_attr(feature = "bindings", derive(TS))]
9980pub enum FunctionPropertyKind {
9981    /// SET option
9982    Set,
9983    /// AS body
9984    As,
9985    /// Hive: USING JAR|FILE|ARCHIVE ...
9986    Using,
9987    /// LANGUAGE clause
9988    Language,
9989    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9990    Determinism,
9991    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
9992    NullInput,
9993    /// SECURITY DEFINER/INVOKER
9994    Security,
9995    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
9996    SqlDataAccess,
9997    /// OPTIONS clause (BigQuery)
9998    Options,
9999    /// ENVIRONMENT clause (Databricks)
10000    Environment,
10001    /// HANDLER clause (Databricks)
10002    Handler,
10003    /// Snowflake: RUNTIME_VERSION='...'
10004    RuntimeVersion,
10005    /// Snowflake: PACKAGES=(...)
10006    Packages,
10007    /// PARAMETER STYLE clause (Databricks)
10008    ParameterStyle,
10009}
10010
10011/// Hive CREATE FUNCTION resource in a USING clause
10012#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10013#[cfg_attr(feature = "bindings", derive(TS))]
10014pub struct FunctionUsingResource {
10015    pub kind: String,
10016    pub uri: String,
10017}
10018
10019/// Function parameter
10020#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10021#[cfg_attr(feature = "bindings", derive(TS))]
10022pub struct FunctionParameter {
10023    pub name: Option<Identifier>,
10024    pub data_type: DataType,
10025    pub mode: Option<ParameterMode>,
10026    pub default: Option<Expression>,
10027    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
10028    #[serde(default, skip_serializing_if = "Option::is_none")]
10029    pub mode_text: Option<String>,
10030}
10031
10032/// Parameter mode (IN, OUT, INOUT, VARIADIC)
10033#[derive(
10034    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10035)]
10036#[cfg_attr(feature = "bindings", derive(TS))]
10037pub enum ParameterMode {
10038    In,
10039    Out,
10040    InOut,
10041    Variadic,
10042}
10043
10044/// Function body
10045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10046#[cfg_attr(feature = "bindings", derive(TS))]
10047pub enum FunctionBody {
10048    /// AS $$ ... $$ (dollar-quoted)
10049    Block(String),
10050    /// AS 'string' (single-quoted string literal body)
10051    StringLiteral(String),
10052    /// AS 'expression'
10053    Expression(Expression),
10054    /// EXTERNAL NAME 'library'
10055    External(String),
10056    /// RETURN expression
10057    Return(Expression),
10058    /// BEGIN ... END block with parsed statements
10059    Statements(Vec<Expression>),
10060    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
10061    /// Stores (content, optional_tag)
10062    DollarQuoted {
10063        content: String,
10064        tag: Option<String>,
10065    },
10066    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
10067    RawBlock(String),
10068}
10069
10070/// Function security (DEFINER, INVOKER, or NONE)
10071#[derive(
10072    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10073)]
10074#[cfg_attr(feature = "bindings", derive(TS))]
10075pub enum FunctionSecurity {
10076    Definer,
10077    Invoker,
10078    /// StarRocks/MySQL: SECURITY NONE
10079    None,
10080}
10081
10082impl CreateFunction {
10083    pub fn new(name: impl Into<String>) -> Self {
10084        Self {
10085            name: TableRef::new(name),
10086            parameters: Vec::new(),
10087            return_type: None,
10088            body: None,
10089            or_replace: false,
10090            or_alter: false,
10091            if_not_exists: false,
10092            temporary: false,
10093            language: None,
10094            deterministic: None,
10095            returns_null_on_null_input: None,
10096            security: None,
10097            has_parens: true,
10098            sql_data_access: None,
10099            returns_table_body: None,
10100            language_first: false,
10101            set_options: Vec::new(),
10102            strict: false,
10103            options: Vec::new(),
10104            is_table_function: false,
10105            property_order: Vec::new(),
10106            using_resources: Vec::new(),
10107            environment: Vec::new(),
10108            handler: None,
10109            handler_uses_eq: false,
10110            runtime_version: None,
10111            packages: None,
10112            parameter_style: None,
10113        }
10114    }
10115}
10116
10117/// DROP FUNCTION statement
10118#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10119#[cfg_attr(feature = "bindings", derive(TS))]
10120pub struct DropFunction {
10121    pub name: TableRef,
10122    pub parameters: Option<Vec<DataType>>,
10123    pub if_exists: bool,
10124    pub cascade: bool,
10125}
10126
10127impl DropFunction {
10128    pub fn new(name: impl Into<String>) -> Self {
10129        Self {
10130            name: TableRef::new(name),
10131            parameters: None,
10132            if_exists: false,
10133            cascade: false,
10134        }
10135    }
10136}
10137
10138/// CREATE PROCEDURE statement
10139#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10140#[cfg_attr(feature = "bindings", derive(TS))]
10141pub struct CreateProcedure {
10142    pub name: TableRef,
10143    pub parameters: Vec<FunctionParameter>,
10144    pub body: Option<FunctionBody>,
10145    pub or_replace: bool,
10146    /// TSQL: CREATE OR ALTER
10147    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10148    pub or_alter: bool,
10149    pub if_not_exists: bool,
10150    pub language: Option<String>,
10151    pub security: Option<FunctionSecurity>,
10152    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
10153    #[serde(default)]
10154    pub return_type: Option<DataType>,
10155    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
10156    #[serde(default)]
10157    pub execute_as: Option<String>,
10158    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
10159    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10160    pub with_options: Vec<String>,
10161    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
10162    #[serde(default = "default_true", skip_serializing_if = "is_true")]
10163    pub has_parens: bool,
10164    /// Whether the short form PROC was used (instead of PROCEDURE)
10165    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10166    pub use_proc_keyword: bool,
10167}
10168
10169impl CreateProcedure {
10170    pub fn new(name: impl Into<String>) -> Self {
10171        Self {
10172            name: TableRef::new(name),
10173            parameters: Vec::new(),
10174            body: None,
10175            or_replace: false,
10176            or_alter: false,
10177            if_not_exists: false,
10178            language: None,
10179            security: None,
10180            return_type: None,
10181            execute_as: None,
10182            with_options: Vec::new(),
10183            has_parens: true,
10184            use_proc_keyword: false,
10185        }
10186    }
10187}
10188
10189/// DROP PROCEDURE statement
10190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10191#[cfg_attr(feature = "bindings", derive(TS))]
10192pub struct DropProcedure {
10193    pub name: TableRef,
10194    pub parameters: Option<Vec<DataType>>,
10195    pub if_exists: bool,
10196    pub cascade: bool,
10197}
10198
10199impl DropProcedure {
10200    pub fn new(name: impl Into<String>) -> Self {
10201        Self {
10202            name: TableRef::new(name),
10203            parameters: None,
10204            if_exists: false,
10205            cascade: false,
10206        }
10207    }
10208}
10209
10210/// Sequence property tag for ordering
10211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10212#[cfg_attr(feature = "bindings", derive(TS))]
10213pub enum SeqPropKind {
10214    Start,
10215    Increment,
10216    Minvalue,
10217    Maxvalue,
10218    Cache,
10219    NoCache,
10220    Cycle,
10221    NoCycle,
10222    OwnedBy,
10223    Order,
10224    NoOrder,
10225    Comment,
10226    /// SHARING=<value> (Oracle)
10227    Sharing,
10228    /// KEEP (Oracle)
10229    Keep,
10230    /// NOKEEP (Oracle)
10231    NoKeep,
10232    /// SCALE [EXTEND|NOEXTEND] (Oracle)
10233    Scale,
10234    /// NOSCALE (Oracle)
10235    NoScale,
10236    /// SHARD [EXTEND|NOEXTEND] (Oracle)
10237    Shard,
10238    /// NOSHARD (Oracle)
10239    NoShard,
10240    /// SESSION (Oracle)
10241    Session,
10242    /// GLOBAL (Oracle)
10243    Global,
10244    /// NOCACHE (single word, Oracle)
10245    NoCacheWord,
10246    /// NOCYCLE (single word, Oracle)
10247    NoCycleWord,
10248    /// NOMINVALUE (single word, Oracle)
10249    NoMinvalueWord,
10250    /// NOMAXVALUE (single word, Oracle)
10251    NoMaxvalueWord,
10252}
10253
10254/// CREATE SYNONYM statement (TSQL)
10255#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10256#[cfg_attr(feature = "bindings", derive(TS))]
10257pub struct CreateSynonym {
10258    /// The synonym name (can be qualified: schema.synonym_name)
10259    pub name: TableRef,
10260    /// The target object the synonym refers to
10261    pub target: TableRef,
10262}
10263
10264/// CREATE SEQUENCE statement
10265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10266#[cfg_attr(feature = "bindings", derive(TS))]
10267pub struct CreateSequence {
10268    pub name: TableRef,
10269    pub if_not_exists: bool,
10270    pub temporary: bool,
10271    #[serde(default)]
10272    pub or_replace: bool,
10273    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
10274    #[serde(default, skip_serializing_if = "Option::is_none")]
10275    pub as_type: Option<DataType>,
10276    pub increment: Option<i64>,
10277    pub minvalue: Option<SequenceBound>,
10278    pub maxvalue: Option<SequenceBound>,
10279    pub start: Option<i64>,
10280    pub cache: Option<i64>,
10281    pub cycle: bool,
10282    pub owned_by: Option<TableRef>,
10283    /// Whether OWNED BY NONE was specified
10284    #[serde(default)]
10285    pub owned_by_none: bool,
10286    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
10287    #[serde(default)]
10288    pub order: Option<bool>,
10289    /// Snowflake: COMMENT = 'value'
10290    #[serde(default)]
10291    pub comment: Option<String>,
10292    /// SHARING=<value> (Oracle)
10293    #[serde(default, skip_serializing_if = "Option::is_none")]
10294    pub sharing: Option<String>,
10295    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
10296    #[serde(default, skip_serializing_if = "Option::is_none")]
10297    pub scale_modifier: Option<String>,
10298    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
10299    #[serde(default, skip_serializing_if = "Option::is_none")]
10300    pub shard_modifier: Option<String>,
10301    /// Tracks the order in which properties appeared in the source
10302    #[serde(default)]
10303    pub property_order: Vec<SeqPropKind>,
10304}
10305
10306/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
10307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10308#[cfg_attr(feature = "bindings", derive(TS))]
10309pub enum SequenceBound {
10310    Value(i64),
10311    None,
10312}
10313
10314impl CreateSequence {
10315    pub fn new(name: impl Into<String>) -> Self {
10316        Self {
10317            name: TableRef::new(name),
10318            if_not_exists: false,
10319            temporary: false,
10320            or_replace: false,
10321            as_type: None,
10322            increment: None,
10323            minvalue: None,
10324            maxvalue: None,
10325            start: None,
10326            cache: None,
10327            cycle: false,
10328            owned_by: None,
10329            owned_by_none: false,
10330            order: None,
10331            comment: None,
10332            sharing: None,
10333            scale_modifier: None,
10334            shard_modifier: None,
10335            property_order: Vec::new(),
10336        }
10337    }
10338}
10339
10340/// DROP SEQUENCE statement
10341#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10342#[cfg_attr(feature = "bindings", derive(TS))]
10343pub struct DropSequence {
10344    pub name: TableRef,
10345    pub if_exists: bool,
10346    pub cascade: bool,
10347}
10348
10349impl DropSequence {
10350    pub fn new(name: impl Into<String>) -> Self {
10351        Self {
10352            name: TableRef::new(name),
10353            if_exists: false,
10354            cascade: false,
10355        }
10356    }
10357}
10358
10359/// ALTER SEQUENCE statement
10360#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10361#[cfg_attr(feature = "bindings", derive(TS))]
10362pub struct AlterSequence {
10363    pub name: TableRef,
10364    pub if_exists: bool,
10365    pub increment: Option<i64>,
10366    pub minvalue: Option<SequenceBound>,
10367    pub maxvalue: Option<SequenceBound>,
10368    pub start: Option<i64>,
10369    pub restart: Option<Option<i64>>,
10370    pub cache: Option<i64>,
10371    pub cycle: Option<bool>,
10372    pub owned_by: Option<Option<TableRef>>,
10373}
10374
10375impl AlterSequence {
10376    pub fn new(name: impl Into<String>) -> Self {
10377        Self {
10378            name: TableRef::new(name),
10379            if_exists: false,
10380            increment: None,
10381            minvalue: None,
10382            maxvalue: None,
10383            start: None,
10384            restart: None,
10385            cache: None,
10386            cycle: None,
10387            owned_by: None,
10388        }
10389    }
10390}
10391
10392/// CREATE TRIGGER statement
10393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10394#[cfg_attr(feature = "bindings", derive(TS))]
10395pub struct CreateTrigger {
10396    pub name: Identifier,
10397    pub table: TableRef,
10398    pub timing: TriggerTiming,
10399    pub events: Vec<TriggerEvent>,
10400    #[serde(default, skip_serializing_if = "Option::is_none")]
10401    pub for_each: Option<TriggerForEach>,
10402    pub when: Option<Expression>,
10403    /// Whether the WHEN clause was parenthesized in the original SQL
10404    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10405    pub when_paren: bool,
10406    pub body: TriggerBody,
10407    pub or_replace: bool,
10408    /// TSQL: CREATE OR ALTER
10409    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10410    pub or_alter: bool,
10411    pub constraint: bool,
10412    pub deferrable: Option<bool>,
10413    pub initially_deferred: Option<bool>,
10414    pub referencing: Option<TriggerReferencing>,
10415}
10416
10417/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
10418#[derive(
10419    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10420)]
10421#[cfg_attr(feature = "bindings", derive(TS))]
10422pub enum TriggerTiming {
10423    Before,
10424    After,
10425    InsteadOf,
10426}
10427
10428/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
10429#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10430#[cfg_attr(feature = "bindings", derive(TS))]
10431pub enum TriggerEvent {
10432    Insert,
10433    Update(Option<Vec<Identifier>>),
10434    Delete,
10435    Truncate,
10436}
10437
10438/// Trigger FOR EACH clause
10439#[derive(
10440    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10441)]
10442#[cfg_attr(feature = "bindings", derive(TS))]
10443pub enum TriggerForEach {
10444    Row,
10445    Statement,
10446}
10447
10448/// Trigger body
10449#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10450#[cfg_attr(feature = "bindings", derive(TS))]
10451pub enum TriggerBody {
10452    /// EXECUTE FUNCTION/PROCEDURE name(args)
10453    Execute {
10454        function: TableRef,
10455        args: Vec<Expression>,
10456    },
10457    /// BEGIN ... END block
10458    Block(String),
10459}
10460
10461/// Trigger REFERENCING clause
10462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10463#[cfg_attr(feature = "bindings", derive(TS))]
10464pub struct TriggerReferencing {
10465    pub old_table: Option<Identifier>,
10466    pub new_table: Option<Identifier>,
10467    pub old_row: Option<Identifier>,
10468    pub new_row: Option<Identifier>,
10469}
10470
10471impl CreateTrigger {
10472    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
10473        Self {
10474            name: Identifier::new(name),
10475            table: TableRef::new(table),
10476            timing: TriggerTiming::Before,
10477            events: Vec::new(),
10478            for_each: Some(TriggerForEach::Row),
10479            when: None,
10480            when_paren: false,
10481            body: TriggerBody::Execute {
10482                function: TableRef::new(""),
10483                args: Vec::new(),
10484            },
10485            or_replace: false,
10486            or_alter: false,
10487            constraint: false,
10488            deferrable: None,
10489            initially_deferred: None,
10490            referencing: None,
10491        }
10492    }
10493}
10494
10495/// DROP TRIGGER statement
10496#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10497#[cfg_attr(feature = "bindings", derive(TS))]
10498pub struct DropTrigger {
10499    pub name: Identifier,
10500    pub table: Option<TableRef>,
10501    pub if_exists: bool,
10502    pub cascade: bool,
10503}
10504
10505impl DropTrigger {
10506    pub fn new(name: impl Into<String>) -> Self {
10507        Self {
10508            name: Identifier::new(name),
10509            table: None,
10510            if_exists: false,
10511            cascade: false,
10512        }
10513    }
10514}
10515
10516/// CREATE TYPE statement
10517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10518#[cfg_attr(feature = "bindings", derive(TS))]
10519pub struct CreateType {
10520    pub name: TableRef,
10521    pub definition: TypeDefinition,
10522    pub if_not_exists: bool,
10523}
10524
10525/// Type definition
10526#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10527#[cfg_attr(feature = "bindings", derive(TS))]
10528pub enum TypeDefinition {
10529    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
10530    Enum(Vec<String>),
10531    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
10532    Composite(Vec<TypeAttribute>),
10533    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
10534    Range {
10535        subtype: DataType,
10536        subtype_diff: Option<String>,
10537        canonical: Option<String>,
10538    },
10539    /// Base type (for advanced usage)
10540    Base {
10541        input: String,
10542        output: String,
10543        internallength: Option<i32>,
10544    },
10545    /// Domain type
10546    Domain {
10547        base_type: DataType,
10548        default: Option<Expression>,
10549        constraints: Vec<DomainConstraint>,
10550    },
10551}
10552
10553/// Type attribute for composite types
10554#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10555#[cfg_attr(feature = "bindings", derive(TS))]
10556pub struct TypeAttribute {
10557    pub name: Identifier,
10558    pub data_type: DataType,
10559    pub collate: Option<Identifier>,
10560}
10561
10562/// Domain constraint
10563#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10564#[cfg_attr(feature = "bindings", derive(TS))]
10565pub struct DomainConstraint {
10566    pub name: Option<Identifier>,
10567    pub check: Expression,
10568}
10569
10570impl CreateType {
10571    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
10572        Self {
10573            name: TableRef::new(name),
10574            definition: TypeDefinition::Enum(values),
10575            if_not_exists: false,
10576        }
10577    }
10578
10579    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
10580        Self {
10581            name: TableRef::new(name),
10582            definition: TypeDefinition::Composite(attributes),
10583            if_not_exists: false,
10584        }
10585    }
10586}
10587
10588/// DROP TYPE statement
10589#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10590#[cfg_attr(feature = "bindings", derive(TS))]
10591pub struct DropType {
10592    pub name: TableRef,
10593    pub if_exists: bool,
10594    pub cascade: bool,
10595}
10596
10597impl DropType {
10598    pub fn new(name: impl Into<String>) -> Self {
10599        Self {
10600            name: TableRef::new(name),
10601            if_exists: false,
10602            cascade: false,
10603        }
10604    }
10605}
10606
10607/// DESCRIBE statement - shows table structure or query plan
10608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10609#[cfg_attr(feature = "bindings", derive(TS))]
10610pub struct Describe {
10611    /// The target to describe (table name or query)
10612    pub target: Expression,
10613    /// EXTENDED format
10614    pub extended: bool,
10615    /// FORMATTED format
10616    pub formatted: bool,
10617    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10618    #[serde(default)]
10619    pub kind: Option<String>,
10620    /// Properties like type=stage
10621    #[serde(default)]
10622    pub properties: Vec<(String, String)>,
10623    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10624    #[serde(default, skip_serializing_if = "Option::is_none")]
10625    pub style: Option<String>,
10626    /// Partition specification for DESCRIBE PARTITION
10627    #[serde(default)]
10628    pub partition: Option<Box<Expression>>,
10629    /// Leading comments before the statement
10630    #[serde(default)]
10631    pub leading_comments: Vec<String>,
10632    /// AS JSON suffix (Databricks)
10633    #[serde(default)]
10634    pub as_json: bool,
10635    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10636    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10637    pub params: Vec<String>,
10638}
10639
10640impl Describe {
10641    pub fn new(target: Expression) -> Self {
10642        Self {
10643            target,
10644            extended: false,
10645            formatted: false,
10646            kind: None,
10647            properties: Vec::new(),
10648            style: None,
10649            partition: None,
10650            leading_comments: Vec::new(),
10651            as_json: false,
10652            params: Vec::new(),
10653        }
10654    }
10655}
10656
10657/// SHOW statement - displays database objects
10658#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10659#[cfg_attr(feature = "bindings", derive(TS))]
10660pub struct Show {
10661    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10662    pub this: String,
10663    /// Whether TERSE was specified
10664    #[serde(default)]
10665    pub terse: bool,
10666    /// Whether HISTORY was specified
10667    #[serde(default)]
10668    pub history: bool,
10669    /// LIKE pattern
10670    pub like: Option<Expression>,
10671    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10672    pub scope_kind: Option<String>,
10673    /// IN scope object
10674    pub scope: Option<Expression>,
10675    /// STARTS WITH pattern
10676    pub starts_with: Option<Expression>,
10677    /// LIMIT clause
10678    pub limit: Option<Box<Limit>>,
10679    /// FROM clause (for specific object)
10680    pub from: Option<Expression>,
10681    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10682    #[serde(default, skip_serializing_if = "Option::is_none")]
10683    pub where_clause: Option<Expression>,
10684    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10685    #[serde(default, skip_serializing_if = "Option::is_none")]
10686    pub for_target: Option<Expression>,
10687    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10688    #[serde(default, skip_serializing_if = "Option::is_none")]
10689    pub db: Option<Expression>,
10690    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10691    #[serde(default, skip_serializing_if = "Option::is_none")]
10692    pub target: Option<Expression>,
10693    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10694    #[serde(default, skip_serializing_if = "Option::is_none")]
10695    pub mutex: Option<bool>,
10696    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10697    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10698    pub privileges: Vec<String>,
10699}
10700
10701impl Show {
10702    pub fn new(this: impl Into<String>) -> Self {
10703        Self {
10704            this: this.into(),
10705            terse: false,
10706            history: false,
10707            like: None,
10708            scope_kind: None,
10709            scope: None,
10710            starts_with: None,
10711            limit: None,
10712            from: None,
10713            where_clause: None,
10714            for_target: None,
10715            db: None,
10716            target: None,
10717            mutex: None,
10718            privileges: Vec::new(),
10719        }
10720    }
10721}
10722
10723/// Represent an explicit parenthesized expression for grouping precedence.
10724///
10725/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10726/// correctly instead of being flattened to `a + b * c`.
10727#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10728#[cfg_attr(feature = "bindings", derive(TS))]
10729pub struct Paren {
10730    /// The inner expression wrapped by parentheses.
10731    pub this: Expression,
10732    #[serde(default)]
10733    pub trailing_comments: Vec<String>,
10734}
10735
10736/// Expression annotated with trailing comments (for round-trip preservation)
10737#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10738#[cfg_attr(feature = "bindings", derive(TS))]
10739pub struct Annotated {
10740    pub this: Expression,
10741    pub trailing_comments: Vec<String>,
10742}
10743
10744// === BATCH GENERATED STRUCT DEFINITIONS ===
10745// Generated from Python sqlglot expressions.py
10746
10747/// Refresh
10748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10749#[cfg_attr(feature = "bindings", derive(TS))]
10750pub struct Refresh {
10751    pub this: Box<Expression>,
10752    pub kind: String,
10753}
10754
10755/// LockingStatement
10756#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10757#[cfg_attr(feature = "bindings", derive(TS))]
10758pub struct LockingStatement {
10759    pub this: Box<Expression>,
10760    pub expression: Box<Expression>,
10761}
10762
10763/// SequenceProperties
10764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10765#[cfg_attr(feature = "bindings", derive(TS))]
10766pub struct SequenceProperties {
10767    #[serde(default)]
10768    pub increment: Option<Box<Expression>>,
10769    #[serde(default)]
10770    pub minvalue: Option<Box<Expression>>,
10771    #[serde(default)]
10772    pub maxvalue: Option<Box<Expression>>,
10773    #[serde(default)]
10774    pub cache: Option<Box<Expression>>,
10775    #[serde(default)]
10776    pub start: Option<Box<Expression>>,
10777    #[serde(default)]
10778    pub owned: Option<Box<Expression>>,
10779    #[serde(default)]
10780    pub options: Vec<Expression>,
10781}
10782
10783/// TruncateTable
10784#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10785#[cfg_attr(feature = "bindings", derive(TS))]
10786pub struct TruncateTable {
10787    #[serde(default)]
10788    pub expressions: Vec<Expression>,
10789    #[serde(default)]
10790    pub is_database: Option<Box<Expression>>,
10791    #[serde(default)]
10792    pub exists: bool,
10793    #[serde(default)]
10794    pub only: Option<Box<Expression>>,
10795    #[serde(default)]
10796    pub cluster: Option<Box<Expression>>,
10797    #[serde(default)]
10798    pub identity: Option<Box<Expression>>,
10799    #[serde(default)]
10800    pub option: Option<Box<Expression>>,
10801    #[serde(default)]
10802    pub partition: Option<Box<Expression>>,
10803}
10804
10805/// Clone
10806#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10807#[cfg_attr(feature = "bindings", derive(TS))]
10808pub struct Clone {
10809    pub this: Box<Expression>,
10810    #[serde(default)]
10811    pub shallow: Option<Box<Expression>>,
10812    #[serde(default)]
10813    pub copy: Option<Box<Expression>>,
10814}
10815
10816/// Attach
10817#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10818#[cfg_attr(feature = "bindings", derive(TS))]
10819pub struct Attach {
10820    pub this: Box<Expression>,
10821    #[serde(default)]
10822    pub exists: bool,
10823    #[serde(default)]
10824    pub expressions: Vec<Expression>,
10825}
10826
10827/// Detach
10828#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10829#[cfg_attr(feature = "bindings", derive(TS))]
10830pub struct Detach {
10831    pub this: Box<Expression>,
10832    #[serde(default)]
10833    pub exists: bool,
10834}
10835
10836/// Install
10837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10838#[cfg_attr(feature = "bindings", derive(TS))]
10839pub struct Install {
10840    pub this: Box<Expression>,
10841    #[serde(default)]
10842    pub from_: Option<Box<Expression>>,
10843    #[serde(default)]
10844    pub force: Option<Box<Expression>>,
10845}
10846
10847/// Summarize
10848#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10849#[cfg_attr(feature = "bindings", derive(TS))]
10850pub struct Summarize {
10851    pub this: Box<Expression>,
10852    #[serde(default)]
10853    pub table: Option<Box<Expression>>,
10854}
10855
10856/// Declare
10857#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10858#[cfg_attr(feature = "bindings", derive(TS))]
10859pub struct Declare {
10860    #[serde(default)]
10861    pub expressions: Vec<Expression>,
10862    #[serde(default)]
10863    pub replace: bool,
10864}
10865
10866/// DeclareItem
10867#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10868#[cfg_attr(feature = "bindings", derive(TS))]
10869pub struct DeclareItem {
10870    pub this: Box<Expression>,
10871    #[serde(default)]
10872    pub kind: Option<String>,
10873    #[serde(default)]
10874    pub default: Option<Box<Expression>>,
10875    #[serde(default)]
10876    pub has_as: bool,
10877    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10878    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10879    pub additional_names: Vec<Expression>,
10880}
10881
10882/// Set
10883#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10884#[cfg_attr(feature = "bindings", derive(TS))]
10885pub struct Set {
10886    #[serde(default)]
10887    pub expressions: Vec<Expression>,
10888    #[serde(default)]
10889    pub unset: Option<Box<Expression>>,
10890    #[serde(default)]
10891    pub tag: Option<Box<Expression>>,
10892}
10893
10894/// Heredoc
10895#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10896#[cfg_attr(feature = "bindings", derive(TS))]
10897pub struct Heredoc {
10898    pub this: Box<Expression>,
10899    #[serde(default)]
10900    pub tag: Option<Box<Expression>>,
10901}
10902
10903/// QueryBand
10904#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10905#[cfg_attr(feature = "bindings", derive(TS))]
10906pub struct QueryBand {
10907    pub this: Box<Expression>,
10908    #[serde(default)]
10909    pub scope: Option<Box<Expression>>,
10910    #[serde(default)]
10911    pub update: Option<Box<Expression>>,
10912}
10913
10914/// UserDefinedFunction
10915#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10916#[cfg_attr(feature = "bindings", derive(TS))]
10917pub struct UserDefinedFunction {
10918    pub this: Box<Expression>,
10919    #[serde(default)]
10920    pub expressions: Vec<Expression>,
10921    #[serde(default)]
10922    pub wrapped: Option<Box<Expression>>,
10923}
10924
10925/// RecursiveWithSearch
10926#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10927#[cfg_attr(feature = "bindings", derive(TS))]
10928pub struct RecursiveWithSearch {
10929    pub kind: String,
10930    pub this: Box<Expression>,
10931    pub expression: Box<Expression>,
10932    #[serde(default)]
10933    pub using: Option<Box<Expression>>,
10934}
10935
10936/// ProjectionDef
10937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10938#[cfg_attr(feature = "bindings", derive(TS))]
10939pub struct ProjectionDef {
10940    pub this: Box<Expression>,
10941    pub expression: Box<Expression>,
10942}
10943
10944/// TableAlias
10945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10946#[cfg_attr(feature = "bindings", derive(TS))]
10947pub struct TableAlias {
10948    #[serde(default)]
10949    pub this: Option<Box<Expression>>,
10950    #[serde(default)]
10951    pub columns: Vec<Expression>,
10952}
10953
10954/// ByteString
10955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10956#[cfg_attr(feature = "bindings", derive(TS))]
10957pub struct ByteString {
10958    pub this: Box<Expression>,
10959    #[serde(default)]
10960    pub is_bytes: Option<Box<Expression>>,
10961}
10962
10963/// HexStringExpr - Hex string expression (not literal)
10964/// BigQuery: converts to FROM_HEX(this)
10965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10966#[cfg_attr(feature = "bindings", derive(TS))]
10967pub struct HexStringExpr {
10968    pub this: Box<Expression>,
10969    #[serde(default)]
10970    pub is_integer: Option<bool>,
10971}
10972
10973/// UnicodeString
10974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10975#[cfg_attr(feature = "bindings", derive(TS))]
10976pub struct UnicodeString {
10977    pub this: Box<Expression>,
10978    #[serde(default)]
10979    pub escape: Option<Box<Expression>>,
10980}
10981
10982/// AlterColumn
10983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10984#[cfg_attr(feature = "bindings", derive(TS))]
10985pub struct AlterColumn {
10986    pub this: Box<Expression>,
10987    #[serde(default)]
10988    pub dtype: Option<Box<Expression>>,
10989    #[serde(default)]
10990    pub collate: Option<Box<Expression>>,
10991    #[serde(default)]
10992    pub using: Option<Box<Expression>>,
10993    #[serde(default)]
10994    pub default: Option<Box<Expression>>,
10995    #[serde(default)]
10996    pub drop: Option<Box<Expression>>,
10997    #[serde(default)]
10998    pub comment: Option<Box<Expression>>,
10999    #[serde(default)]
11000    pub allow_null: Option<Box<Expression>>,
11001    #[serde(default)]
11002    pub visible: Option<Box<Expression>>,
11003    #[serde(default)]
11004    pub rename_to: Option<Box<Expression>>,
11005}
11006
11007/// AlterSortKey
11008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11009#[cfg_attr(feature = "bindings", derive(TS))]
11010pub struct AlterSortKey {
11011    #[serde(default)]
11012    pub this: Option<Box<Expression>>,
11013    #[serde(default)]
11014    pub expressions: Vec<Expression>,
11015    #[serde(default)]
11016    pub compound: Option<Box<Expression>>,
11017}
11018
11019/// AlterSet
11020#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11021#[cfg_attr(feature = "bindings", derive(TS))]
11022pub struct AlterSet {
11023    #[serde(default)]
11024    pub expressions: Vec<Expression>,
11025    #[serde(default)]
11026    pub option: Option<Box<Expression>>,
11027    #[serde(default)]
11028    pub tablespace: Option<Box<Expression>>,
11029    #[serde(default)]
11030    pub access_method: Option<Box<Expression>>,
11031    #[serde(default)]
11032    pub file_format: Option<Box<Expression>>,
11033    #[serde(default)]
11034    pub copy_options: Option<Box<Expression>>,
11035    #[serde(default)]
11036    pub tag: Option<Box<Expression>>,
11037    #[serde(default)]
11038    pub location: Option<Box<Expression>>,
11039    #[serde(default)]
11040    pub serde: Option<Box<Expression>>,
11041}
11042
11043/// RenameColumn
11044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11045#[cfg_attr(feature = "bindings", derive(TS))]
11046pub struct RenameColumn {
11047    pub this: Box<Expression>,
11048    #[serde(default)]
11049    pub to: Option<Box<Expression>>,
11050    #[serde(default)]
11051    pub exists: bool,
11052}
11053
11054/// Comprehension
11055#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11056#[cfg_attr(feature = "bindings", derive(TS))]
11057pub struct Comprehension {
11058    pub this: Box<Expression>,
11059    pub expression: Box<Expression>,
11060    #[serde(default)]
11061    pub position: Option<Box<Expression>>,
11062    #[serde(default)]
11063    pub iterator: Option<Box<Expression>>,
11064    #[serde(default)]
11065    pub condition: Option<Box<Expression>>,
11066}
11067
11068/// MergeTreeTTLAction
11069#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11070#[cfg_attr(feature = "bindings", derive(TS))]
11071pub struct MergeTreeTTLAction {
11072    pub this: Box<Expression>,
11073    #[serde(default)]
11074    pub delete: Option<Box<Expression>>,
11075    #[serde(default)]
11076    pub recompress: Option<Box<Expression>>,
11077    #[serde(default)]
11078    pub to_disk: Option<Box<Expression>>,
11079    #[serde(default)]
11080    pub to_volume: Option<Box<Expression>>,
11081}
11082
11083/// MergeTreeTTL
11084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11085#[cfg_attr(feature = "bindings", derive(TS))]
11086pub struct MergeTreeTTL {
11087    #[serde(default)]
11088    pub expressions: Vec<Expression>,
11089    #[serde(default)]
11090    pub where_: Option<Box<Expression>>,
11091    #[serde(default)]
11092    pub group: Option<Box<Expression>>,
11093    #[serde(default)]
11094    pub aggregates: Option<Box<Expression>>,
11095}
11096
11097/// IndexConstraintOption
11098#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11099#[cfg_attr(feature = "bindings", derive(TS))]
11100pub struct IndexConstraintOption {
11101    #[serde(default)]
11102    pub key_block_size: Option<Box<Expression>>,
11103    #[serde(default)]
11104    pub using: Option<Box<Expression>>,
11105    #[serde(default)]
11106    pub parser: Option<Box<Expression>>,
11107    #[serde(default)]
11108    pub comment: Option<Box<Expression>>,
11109    #[serde(default)]
11110    pub visible: Option<Box<Expression>>,
11111    #[serde(default)]
11112    pub engine_attr: Option<Box<Expression>>,
11113    #[serde(default)]
11114    pub secondary_engine_attr: Option<Box<Expression>>,
11115}
11116
11117/// PeriodForSystemTimeConstraint
11118#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11119#[cfg_attr(feature = "bindings", derive(TS))]
11120pub struct PeriodForSystemTimeConstraint {
11121    pub this: Box<Expression>,
11122    pub expression: Box<Expression>,
11123}
11124
11125/// CaseSpecificColumnConstraint
11126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11127#[cfg_attr(feature = "bindings", derive(TS))]
11128pub struct CaseSpecificColumnConstraint {
11129    #[serde(default)]
11130    pub not_: Option<Box<Expression>>,
11131}
11132
11133/// CharacterSetColumnConstraint
11134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11135#[cfg_attr(feature = "bindings", derive(TS))]
11136pub struct CharacterSetColumnConstraint {
11137    pub this: Box<Expression>,
11138}
11139
11140/// CheckColumnConstraint
11141#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11142#[cfg_attr(feature = "bindings", derive(TS))]
11143pub struct CheckColumnConstraint {
11144    pub this: Box<Expression>,
11145    #[serde(default)]
11146    pub enforced: Option<Box<Expression>>,
11147}
11148
11149/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
11150#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11151#[cfg_attr(feature = "bindings", derive(TS))]
11152pub struct AssumeColumnConstraint {
11153    pub this: Box<Expression>,
11154}
11155
11156/// CompressColumnConstraint
11157#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11158#[cfg_attr(feature = "bindings", derive(TS))]
11159pub struct CompressColumnConstraint {
11160    #[serde(default)]
11161    pub this: Option<Box<Expression>>,
11162}
11163
11164/// DateFormatColumnConstraint
11165#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11166#[cfg_attr(feature = "bindings", derive(TS))]
11167pub struct DateFormatColumnConstraint {
11168    pub this: Box<Expression>,
11169}
11170
11171/// EphemeralColumnConstraint
11172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11173#[cfg_attr(feature = "bindings", derive(TS))]
11174pub struct EphemeralColumnConstraint {
11175    #[serde(default)]
11176    pub this: Option<Box<Expression>>,
11177}
11178
11179/// WithOperator
11180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11181#[cfg_attr(feature = "bindings", derive(TS))]
11182pub struct WithOperator {
11183    pub this: Box<Expression>,
11184    pub op: String,
11185}
11186
11187/// GeneratedAsIdentityColumnConstraint
11188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11189#[cfg_attr(feature = "bindings", derive(TS))]
11190pub struct GeneratedAsIdentityColumnConstraint {
11191    #[serde(default)]
11192    pub this: Option<Box<Expression>>,
11193    #[serde(default)]
11194    pub expression: Option<Box<Expression>>,
11195    #[serde(default)]
11196    pub on_null: Option<Box<Expression>>,
11197    #[serde(default)]
11198    pub start: Option<Box<Expression>>,
11199    #[serde(default)]
11200    pub increment: Option<Box<Expression>>,
11201    #[serde(default)]
11202    pub minvalue: Option<Box<Expression>>,
11203    #[serde(default)]
11204    pub maxvalue: Option<Box<Expression>>,
11205    #[serde(default)]
11206    pub cycle: Option<Box<Expression>>,
11207    #[serde(default)]
11208    pub order: Option<Box<Expression>>,
11209}
11210
11211/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
11212/// TSQL: outputs "IDENTITY"
11213#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11214#[cfg_attr(feature = "bindings", derive(TS))]
11215pub struct AutoIncrementColumnConstraint;
11216
11217/// CommentColumnConstraint - Column comment marker
11218#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11219#[cfg_attr(feature = "bindings", derive(TS))]
11220pub struct CommentColumnConstraint;
11221
11222/// GeneratedAsRowColumnConstraint
11223#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11224#[cfg_attr(feature = "bindings", derive(TS))]
11225pub struct GeneratedAsRowColumnConstraint {
11226    #[serde(default)]
11227    pub start: Option<Box<Expression>>,
11228    #[serde(default)]
11229    pub hidden: Option<Box<Expression>>,
11230}
11231
11232/// IndexColumnConstraint
11233#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11234#[cfg_attr(feature = "bindings", derive(TS))]
11235pub struct IndexColumnConstraint {
11236    #[serde(default)]
11237    pub this: Option<Box<Expression>>,
11238    #[serde(default)]
11239    pub expressions: Vec<Expression>,
11240    #[serde(default)]
11241    pub kind: Option<String>,
11242    #[serde(default)]
11243    pub index_type: Option<Box<Expression>>,
11244    #[serde(default)]
11245    pub options: Vec<Expression>,
11246    #[serde(default)]
11247    pub expression: Option<Box<Expression>>,
11248    #[serde(default)]
11249    pub granularity: Option<Box<Expression>>,
11250}
11251
11252/// MaskingPolicyColumnConstraint
11253#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11254#[cfg_attr(feature = "bindings", derive(TS))]
11255pub struct MaskingPolicyColumnConstraint {
11256    pub this: Box<Expression>,
11257    #[serde(default)]
11258    pub expressions: Vec<Expression>,
11259}
11260
11261/// NotNullColumnConstraint
11262#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11263#[cfg_attr(feature = "bindings", derive(TS))]
11264pub struct NotNullColumnConstraint {
11265    #[serde(default)]
11266    pub allow_null: Option<Box<Expression>>,
11267}
11268
11269/// DefaultColumnConstraint - DEFAULT value for a column
11270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11271#[cfg_attr(feature = "bindings", derive(TS))]
11272pub struct DefaultColumnConstraint {
11273    pub this: Box<Expression>,
11274    /// TSQL: DEFAULT value FOR column (table-level default constraint)
11275    #[serde(default, skip_serializing_if = "Option::is_none")]
11276    pub for_column: Option<Identifier>,
11277}
11278
11279/// PrimaryKeyColumnConstraint
11280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11281#[cfg_attr(feature = "bindings", derive(TS))]
11282pub struct PrimaryKeyColumnConstraint {
11283    #[serde(default)]
11284    pub desc: Option<Box<Expression>>,
11285    #[serde(default)]
11286    pub options: Vec<Expression>,
11287}
11288
11289/// UniqueColumnConstraint
11290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11291#[cfg_attr(feature = "bindings", derive(TS))]
11292pub struct UniqueColumnConstraint {
11293    #[serde(default)]
11294    pub this: Option<Box<Expression>>,
11295    #[serde(default)]
11296    pub index_type: Option<Box<Expression>>,
11297    #[serde(default)]
11298    pub on_conflict: Option<Box<Expression>>,
11299    #[serde(default)]
11300    pub nulls: Option<Box<Expression>>,
11301    #[serde(default)]
11302    pub options: Vec<Expression>,
11303}
11304
11305/// WatermarkColumnConstraint
11306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11307#[cfg_attr(feature = "bindings", derive(TS))]
11308pub struct WatermarkColumnConstraint {
11309    pub this: Box<Expression>,
11310    pub expression: Box<Expression>,
11311}
11312
11313/// ComputedColumnConstraint
11314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11315#[cfg_attr(feature = "bindings", derive(TS))]
11316pub struct ComputedColumnConstraint {
11317    pub this: Box<Expression>,
11318    #[serde(default)]
11319    pub persisted: Option<Box<Expression>>,
11320    #[serde(default)]
11321    pub not_null: Option<Box<Expression>>,
11322    #[serde(default)]
11323    pub data_type: Option<Box<Expression>>,
11324}
11325
11326/// InOutColumnConstraint
11327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11328#[cfg_attr(feature = "bindings", derive(TS))]
11329pub struct InOutColumnConstraint {
11330    #[serde(default)]
11331    pub input_: Option<Box<Expression>>,
11332    #[serde(default)]
11333    pub output: Option<Box<Expression>>,
11334}
11335
11336/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
11337#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11338#[cfg_attr(feature = "bindings", derive(TS))]
11339pub struct PathColumnConstraint {
11340    pub this: Box<Expression>,
11341}
11342
11343/// Constraint
11344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11345#[cfg_attr(feature = "bindings", derive(TS))]
11346pub struct Constraint {
11347    pub this: Box<Expression>,
11348    #[serde(default)]
11349    pub expressions: Vec<Expression>,
11350}
11351
11352/// Export
11353#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11354#[cfg_attr(feature = "bindings", derive(TS))]
11355pub struct Export {
11356    pub this: Box<Expression>,
11357    #[serde(default)]
11358    pub connection: Option<Box<Expression>>,
11359    #[serde(default)]
11360    pub options: Vec<Expression>,
11361}
11362
11363/// Filter
11364#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11365#[cfg_attr(feature = "bindings", derive(TS))]
11366pub struct Filter {
11367    pub this: Box<Expression>,
11368    pub expression: Box<Expression>,
11369}
11370
11371/// Changes
11372#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11373#[cfg_attr(feature = "bindings", derive(TS))]
11374pub struct Changes {
11375    #[serde(default)]
11376    pub information: Option<Box<Expression>>,
11377    #[serde(default)]
11378    pub at_before: Option<Box<Expression>>,
11379    #[serde(default)]
11380    pub end: Option<Box<Expression>>,
11381}
11382
11383/// Directory
11384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11385#[cfg_attr(feature = "bindings", derive(TS))]
11386pub struct Directory {
11387    pub this: Box<Expression>,
11388    #[serde(default)]
11389    pub local: Option<Box<Expression>>,
11390    #[serde(default)]
11391    pub row_format: Option<Box<Expression>>,
11392}
11393
11394/// ForeignKey
11395#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11396#[cfg_attr(feature = "bindings", derive(TS))]
11397pub struct ForeignKey {
11398    #[serde(default)]
11399    pub expressions: Vec<Expression>,
11400    #[serde(default)]
11401    pub reference: Option<Box<Expression>>,
11402    #[serde(default)]
11403    pub delete: Option<Box<Expression>>,
11404    #[serde(default)]
11405    pub update: Option<Box<Expression>>,
11406    #[serde(default)]
11407    pub options: Vec<Expression>,
11408}
11409
11410/// ColumnPrefix
11411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11412#[cfg_attr(feature = "bindings", derive(TS))]
11413pub struct ColumnPrefix {
11414    pub this: Box<Expression>,
11415    pub expression: Box<Expression>,
11416}
11417
11418/// PrimaryKey
11419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11420#[cfg_attr(feature = "bindings", derive(TS))]
11421pub struct PrimaryKey {
11422    #[serde(default)]
11423    pub this: Option<Box<Expression>>,
11424    #[serde(default)]
11425    pub expressions: Vec<Expression>,
11426    #[serde(default)]
11427    pub options: Vec<Expression>,
11428    #[serde(default)]
11429    pub include: Option<Box<Expression>>,
11430}
11431
11432/// Into
11433#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11434#[cfg_attr(feature = "bindings", derive(TS))]
11435pub struct IntoClause {
11436    #[serde(default)]
11437    pub this: Option<Box<Expression>>,
11438    #[serde(default)]
11439    pub temporary: bool,
11440    #[serde(default)]
11441    pub unlogged: Option<Box<Expression>>,
11442    #[serde(default)]
11443    pub bulk_collect: Option<Box<Expression>>,
11444    #[serde(default)]
11445    pub expressions: Vec<Expression>,
11446}
11447
11448/// JoinHint
11449#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11450#[cfg_attr(feature = "bindings", derive(TS))]
11451pub struct JoinHint {
11452    pub this: Box<Expression>,
11453    #[serde(default)]
11454    pub expressions: Vec<Expression>,
11455}
11456
11457/// Opclass
11458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11459#[cfg_attr(feature = "bindings", derive(TS))]
11460pub struct Opclass {
11461    pub this: Box<Expression>,
11462    pub expression: Box<Expression>,
11463}
11464
11465/// Index
11466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11467#[cfg_attr(feature = "bindings", derive(TS))]
11468pub struct Index {
11469    #[serde(default)]
11470    pub this: Option<Box<Expression>>,
11471    #[serde(default)]
11472    pub table: Option<Box<Expression>>,
11473    #[serde(default)]
11474    pub unique: bool,
11475    #[serde(default)]
11476    pub primary: Option<Box<Expression>>,
11477    #[serde(default)]
11478    pub amp: Option<Box<Expression>>,
11479    #[serde(default)]
11480    pub params: Vec<Expression>,
11481}
11482
11483/// IndexParameters
11484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11485#[cfg_attr(feature = "bindings", derive(TS))]
11486pub struct IndexParameters {
11487    #[serde(default)]
11488    pub using: Option<Box<Expression>>,
11489    #[serde(default)]
11490    pub include: Option<Box<Expression>>,
11491    #[serde(default)]
11492    pub columns: Vec<Expression>,
11493    #[serde(default)]
11494    pub with_storage: Option<Box<Expression>>,
11495    #[serde(default)]
11496    pub partition_by: Option<Box<Expression>>,
11497    #[serde(default)]
11498    pub tablespace: Option<Box<Expression>>,
11499    #[serde(default)]
11500    pub where_: Option<Box<Expression>>,
11501    #[serde(default)]
11502    pub on: Option<Box<Expression>>,
11503}
11504
11505/// ConditionalInsert
11506#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11507#[cfg_attr(feature = "bindings", derive(TS))]
11508pub struct ConditionalInsert {
11509    pub this: Box<Expression>,
11510    #[serde(default)]
11511    pub expression: Option<Box<Expression>>,
11512    #[serde(default)]
11513    pub else_: Option<Box<Expression>>,
11514}
11515
11516/// MultitableInserts
11517#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11518#[cfg_attr(feature = "bindings", derive(TS))]
11519pub struct MultitableInserts {
11520    #[serde(default)]
11521    pub expressions: Vec<Expression>,
11522    pub kind: String,
11523    #[serde(default)]
11524    pub source: Option<Box<Expression>>,
11525    /// Leading comments before the statement
11526    #[serde(default)]
11527    pub leading_comments: Vec<String>,
11528    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
11529    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11530    pub overwrite: bool,
11531}
11532
11533/// OnConflict
11534#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11535#[cfg_attr(feature = "bindings", derive(TS))]
11536pub struct OnConflict {
11537    #[serde(default)]
11538    pub duplicate: Option<Box<Expression>>,
11539    #[serde(default)]
11540    pub expressions: Vec<Expression>,
11541    #[serde(default)]
11542    pub action: Option<Box<Expression>>,
11543    #[serde(default)]
11544    pub conflict_keys: Option<Box<Expression>>,
11545    #[serde(default)]
11546    pub index_predicate: Option<Box<Expression>>,
11547    #[serde(default)]
11548    pub constraint: Option<Box<Expression>>,
11549    #[serde(default)]
11550    pub where_: Option<Box<Expression>>,
11551}
11552
11553/// OnCondition
11554#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11555#[cfg_attr(feature = "bindings", derive(TS))]
11556pub struct OnCondition {
11557    #[serde(default)]
11558    pub error: Option<Box<Expression>>,
11559    #[serde(default)]
11560    pub empty: Option<Box<Expression>>,
11561    #[serde(default)]
11562    pub null: Option<Box<Expression>>,
11563}
11564
11565/// Returning
11566#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11567#[cfg_attr(feature = "bindings", derive(TS))]
11568pub struct Returning {
11569    #[serde(default)]
11570    pub expressions: Vec<Expression>,
11571    #[serde(default)]
11572    pub into: Option<Box<Expression>>,
11573}
11574
11575/// Introducer
11576#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11577#[cfg_attr(feature = "bindings", derive(TS))]
11578pub struct Introducer {
11579    pub this: Box<Expression>,
11580    pub expression: Box<Expression>,
11581}
11582
11583/// PartitionRange
11584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11585#[cfg_attr(feature = "bindings", derive(TS))]
11586pub struct PartitionRange {
11587    pub this: Box<Expression>,
11588    #[serde(default)]
11589    pub expression: Option<Box<Expression>>,
11590    #[serde(default)]
11591    pub expressions: Vec<Expression>,
11592}
11593
11594/// Group
11595#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11596#[cfg_attr(feature = "bindings", derive(TS))]
11597pub struct Group {
11598    #[serde(default)]
11599    pub expressions: Vec<Expression>,
11600    #[serde(default)]
11601    pub grouping_sets: Option<Box<Expression>>,
11602    #[serde(default)]
11603    pub cube: Option<Box<Expression>>,
11604    #[serde(default)]
11605    pub rollup: Option<Box<Expression>>,
11606    #[serde(default)]
11607    pub totals: Option<Box<Expression>>,
11608    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11609    #[serde(default)]
11610    pub all: Option<bool>,
11611}
11612
11613/// Cube
11614#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11615#[cfg_attr(feature = "bindings", derive(TS))]
11616pub struct Cube {
11617    /// Selection, subtotal, and result-delivery options for this grouping operation.
11618    #[serde(default, skip_serializing_if = "Option::is_none")]
11619    pub options: Option<GroupingOptions>,
11620    #[serde(default)]
11621    pub expressions: Vec<Expression>,
11622}
11623
11624/// Rollup
11625#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11626#[cfg_attr(feature = "bindings", derive(TS))]
11627pub struct Rollup {
11628    /// Selection, subtotal, and result-delivery options for this grouping operation.
11629    #[serde(default, skip_serializing_if = "Option::is_none")]
11630    pub options: Option<GroupingOptions>,
11631    #[serde(default)]
11632    pub expressions: Vec<Expression>,
11633}
11634
11635/// GroupingSets
11636#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11637#[cfg_attr(feature = "bindings", derive(TS))]
11638pub struct GroupingSets {
11639    /// Selection, subtotal, and result-delivery options for this grouping operation.
11640    #[serde(default, skip_serializing_if = "Option::is_none")]
11641    pub options: Option<GroupingOptions>,
11642    #[serde(default)]
11643    pub expressions: Vec<Expression>,
11644}
11645
11646/// LimitOptions
11647#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11648#[cfg_attr(feature = "bindings", derive(TS))]
11649pub struct LimitOptions {
11650    #[serde(default)]
11651    pub percent: Option<Box<Expression>>,
11652    #[serde(default)]
11653    pub rows: Option<Box<Expression>>,
11654    #[serde(default)]
11655    pub with_ties: Option<Box<Expression>>,
11656}
11657
11658/// Lateral
11659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11660#[cfg_attr(feature = "bindings", derive(TS))]
11661pub struct Lateral {
11662    pub this: Box<Expression>,
11663    #[serde(default)]
11664    pub view: Option<Box<Expression>>,
11665    #[serde(default)]
11666    pub outer: Option<Box<Expression>>,
11667    #[serde(default)]
11668    pub alias: Option<String>,
11669    /// Whether the alias was originally quoted (backtick/double-quote)
11670    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11671    pub alias_quoted: bool,
11672    #[serde(default)]
11673    pub cross_apply: Option<Box<Expression>>,
11674    #[serde(default)]
11675    pub ordinality: Option<Box<Expression>>,
11676    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11677    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11678    pub column_aliases: Vec<String>,
11679}
11680
11681/// TableFromRows
11682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11683#[cfg_attr(feature = "bindings", derive(TS))]
11684pub struct TableFromRows {
11685    pub this: Box<Expression>,
11686    #[serde(default)]
11687    pub alias: Option<String>,
11688    #[serde(default)]
11689    pub joins: Vec<Expression>,
11690    #[serde(default)]
11691    pub pivots: Option<Box<Expression>>,
11692    #[serde(default)]
11693    pub sample: Option<Box<Expression>>,
11694}
11695
11696/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11697/// Used for set-returning functions with typed column definitions
11698#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11699#[cfg_attr(feature = "bindings", derive(TS))]
11700pub struct RowsFrom {
11701    /// List of function expressions, each potentially with an alias and typed columns
11702    pub expressions: Vec<Expression>,
11703    /// WITH ORDINALITY modifier
11704    #[serde(default)]
11705    pub ordinality: bool,
11706    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11707    #[serde(default)]
11708    pub alias: Option<Box<Expression>>,
11709}
11710
11711/// WithFill
11712#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11713#[cfg_attr(feature = "bindings", derive(TS))]
11714pub struct WithFill {
11715    #[serde(default)]
11716    pub from_: Option<Box<Expression>>,
11717    #[serde(default)]
11718    pub to: Option<Box<Expression>>,
11719    #[serde(default)]
11720    pub step: Option<Box<Expression>>,
11721    #[serde(default)]
11722    pub staleness: Option<Box<Expression>>,
11723    #[serde(default)]
11724    pub interpolate: Option<Box<Expression>>,
11725}
11726
11727/// Property
11728#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11729#[cfg_attr(feature = "bindings", derive(TS))]
11730pub struct Property {
11731    pub this: Box<Expression>,
11732    #[serde(default)]
11733    pub value: Option<Box<Expression>>,
11734}
11735
11736/// GrantPrivilege
11737#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11738#[cfg_attr(feature = "bindings", derive(TS))]
11739pub struct GrantPrivilege {
11740    pub this: Box<Expression>,
11741    #[serde(default)]
11742    pub expressions: Vec<Expression>,
11743}
11744
11745/// AllowedValuesProperty
11746#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11747#[cfg_attr(feature = "bindings", derive(TS))]
11748pub struct AllowedValuesProperty {
11749    #[serde(default)]
11750    pub expressions: Vec<Expression>,
11751}
11752
11753/// AlgorithmProperty
11754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11755#[cfg_attr(feature = "bindings", derive(TS))]
11756pub struct AlgorithmProperty {
11757    pub this: Box<Expression>,
11758}
11759
11760/// AutoIncrementProperty
11761#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11762#[cfg_attr(feature = "bindings", derive(TS))]
11763pub struct AutoIncrementProperty {
11764    pub this: Box<Expression>,
11765}
11766
11767/// AutoRefreshProperty
11768#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11769#[cfg_attr(feature = "bindings", derive(TS))]
11770pub struct AutoRefreshProperty {
11771    pub this: Box<Expression>,
11772}
11773
11774/// BackupProperty
11775#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11776#[cfg_attr(feature = "bindings", derive(TS))]
11777pub struct BackupProperty {
11778    pub this: Box<Expression>,
11779}
11780
11781/// BuildProperty
11782#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11783#[cfg_attr(feature = "bindings", derive(TS))]
11784pub struct BuildProperty {
11785    pub this: Box<Expression>,
11786}
11787
11788/// BlockCompressionProperty
11789#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11790#[cfg_attr(feature = "bindings", derive(TS))]
11791pub struct BlockCompressionProperty {
11792    #[serde(default)]
11793    pub autotemp: Option<Box<Expression>>,
11794    #[serde(default)]
11795    pub always: Option<Box<Expression>>,
11796    #[serde(default)]
11797    pub default: Option<Box<Expression>>,
11798    #[serde(default)]
11799    pub manual: Option<Box<Expression>>,
11800    #[serde(default)]
11801    pub never: Option<Box<Expression>>,
11802}
11803
11804/// CharacterSetProperty
11805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11806#[cfg_attr(feature = "bindings", derive(TS))]
11807pub struct CharacterSetProperty {
11808    pub this: Box<Expression>,
11809    #[serde(default)]
11810    pub default: Option<Box<Expression>>,
11811}
11812
11813/// ChecksumProperty
11814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11815#[cfg_attr(feature = "bindings", derive(TS))]
11816pub struct ChecksumProperty {
11817    #[serde(default)]
11818    pub on: Option<Box<Expression>>,
11819    #[serde(default)]
11820    pub default: Option<Box<Expression>>,
11821}
11822
11823/// CollateProperty
11824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11825#[cfg_attr(feature = "bindings", derive(TS))]
11826pub struct CollateProperty {
11827    pub this: Box<Expression>,
11828    #[serde(default)]
11829    pub default: Option<Box<Expression>>,
11830}
11831
11832/// DataBlocksizeProperty
11833#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11834#[cfg_attr(feature = "bindings", derive(TS))]
11835pub struct DataBlocksizeProperty {
11836    #[serde(default)]
11837    pub size: Option<i64>,
11838    #[serde(default)]
11839    pub units: Option<Box<Expression>>,
11840    #[serde(default)]
11841    pub minimum: Option<Box<Expression>>,
11842    #[serde(default)]
11843    pub maximum: Option<Box<Expression>>,
11844    #[serde(default)]
11845    pub default: Option<Box<Expression>>,
11846}
11847
11848/// DataDeletionProperty
11849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11850#[cfg_attr(feature = "bindings", derive(TS))]
11851pub struct DataDeletionProperty {
11852    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11853    #[ast(skip)]
11854    pub on: Box<Expression>,
11855    #[serde(default)]
11856    pub filter_column: Option<Box<Expression>>,
11857    #[serde(default)]
11858    pub retention_period: Option<Box<Expression>>,
11859}
11860
11861/// DefinerProperty
11862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11863#[cfg_attr(feature = "bindings", derive(TS))]
11864pub struct DefinerProperty {
11865    pub this: Box<Expression>,
11866}
11867
11868/// DistKeyProperty
11869#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11870#[cfg_attr(feature = "bindings", derive(TS))]
11871pub struct DistKeyProperty {
11872    pub this: Box<Expression>,
11873}
11874
11875/// DistributedByProperty
11876#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11877#[cfg_attr(feature = "bindings", derive(TS))]
11878pub struct DistributedByProperty {
11879    #[serde(default)]
11880    pub expressions: Vec<Expression>,
11881    pub kind: String,
11882    #[serde(default)]
11883    pub buckets: Option<Box<Expression>>,
11884    #[serde(default)]
11885    pub order: Option<Box<Expression>>,
11886}
11887
11888/// DistStyleProperty
11889#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11890#[cfg_attr(feature = "bindings", derive(TS))]
11891pub struct DistStyleProperty {
11892    pub this: Box<Expression>,
11893}
11894
11895/// DuplicateKeyProperty
11896#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11897#[cfg_attr(feature = "bindings", derive(TS))]
11898pub struct DuplicateKeyProperty {
11899    #[serde(default)]
11900    pub expressions: Vec<Expression>,
11901}
11902
11903/// EngineProperty
11904#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11905#[cfg_attr(feature = "bindings", derive(TS))]
11906pub struct EngineProperty {
11907    pub this: Box<Expression>,
11908}
11909
11910/// ToTableProperty
11911#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11912#[cfg_attr(feature = "bindings", derive(TS))]
11913pub struct ToTableProperty {
11914    pub this: Box<Expression>,
11915}
11916
11917/// ExecuteAsProperty
11918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11919#[cfg_attr(feature = "bindings", derive(TS))]
11920pub struct ExecuteAsProperty {
11921    pub this: Box<Expression>,
11922}
11923
11924/// ExternalProperty
11925#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11926#[cfg_attr(feature = "bindings", derive(TS))]
11927pub struct ExternalProperty {
11928    #[serde(default)]
11929    pub this: Option<Box<Expression>>,
11930}
11931
11932/// FallbackProperty
11933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11934#[cfg_attr(feature = "bindings", derive(TS))]
11935pub struct FallbackProperty {
11936    #[serde(default)]
11937    pub no: Option<Box<Expression>>,
11938    #[serde(default)]
11939    pub protection: Option<Box<Expression>>,
11940}
11941
11942/// FileFormatProperty
11943#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11944#[cfg_attr(feature = "bindings", derive(TS))]
11945pub struct FileFormatProperty {
11946    #[serde(default)]
11947    pub this: Option<Box<Expression>>,
11948    #[serde(default)]
11949    pub expressions: Vec<Expression>,
11950    #[serde(default)]
11951    pub hive_format: Option<Box<Expression>>,
11952}
11953
11954/// CredentialsProperty
11955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11956#[cfg_attr(feature = "bindings", derive(TS))]
11957pub struct CredentialsProperty {
11958    #[serde(default)]
11959    pub expressions: Vec<Expression>,
11960}
11961
11962/// FreespaceProperty
11963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11964#[cfg_attr(feature = "bindings", derive(TS))]
11965pub struct FreespaceProperty {
11966    pub this: Box<Expression>,
11967    #[serde(default)]
11968    pub percent: Option<Box<Expression>>,
11969}
11970
11971/// InheritsProperty
11972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11973#[cfg_attr(feature = "bindings", derive(TS))]
11974pub struct InheritsProperty {
11975    #[serde(default)]
11976    pub expressions: Vec<Expression>,
11977}
11978
11979/// InputModelProperty
11980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11981#[cfg_attr(feature = "bindings", derive(TS))]
11982pub struct InputModelProperty {
11983    pub this: Box<Expression>,
11984}
11985
11986/// OutputModelProperty
11987#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11988#[cfg_attr(feature = "bindings", derive(TS))]
11989pub struct OutputModelProperty {
11990    pub this: Box<Expression>,
11991}
11992
11993/// IsolatedLoadingProperty
11994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11995#[cfg_attr(feature = "bindings", derive(TS))]
11996pub struct IsolatedLoadingProperty {
11997    #[serde(default)]
11998    pub no: Option<Box<Expression>>,
11999    #[serde(default)]
12000    pub concurrent: Option<Box<Expression>>,
12001    #[serde(default)]
12002    pub target: Option<Box<Expression>>,
12003}
12004
12005/// JournalProperty
12006#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12007#[cfg_attr(feature = "bindings", derive(TS))]
12008pub struct JournalProperty {
12009    #[serde(default)]
12010    pub no: Option<Box<Expression>>,
12011    #[serde(default)]
12012    pub dual: Option<Box<Expression>>,
12013    #[serde(default)]
12014    pub before: Option<Box<Expression>>,
12015    #[serde(default)]
12016    pub local: Option<Box<Expression>>,
12017    #[serde(default)]
12018    pub after: Option<Box<Expression>>,
12019}
12020
12021/// LanguageProperty
12022#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12023#[cfg_attr(feature = "bindings", derive(TS))]
12024pub struct LanguageProperty {
12025    pub this: Box<Expression>,
12026}
12027
12028/// EnviromentProperty
12029#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12030#[cfg_attr(feature = "bindings", derive(TS))]
12031pub struct EnviromentProperty {
12032    #[serde(default)]
12033    pub expressions: Vec<Expression>,
12034}
12035
12036/// ClusteredByProperty
12037#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12038#[cfg_attr(feature = "bindings", derive(TS))]
12039pub struct ClusteredByProperty {
12040    #[serde(default)]
12041    pub expressions: Vec<Expression>,
12042    #[serde(default)]
12043    pub sorted_by: Option<Box<Expression>>,
12044    #[serde(default)]
12045    pub buckets: Option<Box<Expression>>,
12046}
12047
12048/// DictProperty
12049#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12050#[cfg_attr(feature = "bindings", derive(TS))]
12051pub struct DictProperty {
12052    pub this: Box<Expression>,
12053    pub kind: String,
12054    #[serde(default)]
12055    pub settings: Option<Box<Expression>>,
12056}
12057
12058/// DictRange
12059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12060#[cfg_attr(feature = "bindings", derive(TS))]
12061pub struct DictRange {
12062    pub this: Box<Expression>,
12063    #[serde(default)]
12064    pub min: Option<Box<Expression>>,
12065    #[serde(default)]
12066    pub max: Option<Box<Expression>>,
12067}
12068
12069/// OnCluster
12070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12071#[cfg_attr(feature = "bindings", derive(TS))]
12072pub struct OnCluster {
12073    pub this: Box<Expression>,
12074}
12075
12076/// LikeProperty
12077#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12078#[cfg_attr(feature = "bindings", derive(TS))]
12079pub struct LikeProperty {
12080    pub this: Box<Expression>,
12081    #[serde(default)]
12082    pub expressions: Vec<Expression>,
12083}
12084
12085/// LocationProperty
12086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12087#[cfg_attr(feature = "bindings", derive(TS))]
12088pub struct LocationProperty {
12089    pub this: Box<Expression>,
12090}
12091
12092/// LockProperty
12093#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12094#[cfg_attr(feature = "bindings", derive(TS))]
12095pub struct LockProperty {
12096    pub this: Box<Expression>,
12097}
12098
12099/// LockingProperty
12100#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12101#[cfg_attr(feature = "bindings", derive(TS))]
12102pub struct LockingProperty {
12103    #[serde(default)]
12104    pub this: Option<Box<Expression>>,
12105    pub kind: String,
12106    #[serde(default)]
12107    pub for_or_in: Option<Box<Expression>>,
12108    #[serde(default)]
12109    pub lock_type: Option<Box<Expression>>,
12110    #[serde(default)]
12111    pub override_: Option<Box<Expression>>,
12112}
12113
12114/// LogProperty
12115#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12116#[cfg_attr(feature = "bindings", derive(TS))]
12117pub struct LogProperty {
12118    #[serde(default)]
12119    pub no: Option<Box<Expression>>,
12120}
12121
12122/// MaterializedProperty
12123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12124#[cfg_attr(feature = "bindings", derive(TS))]
12125pub struct MaterializedProperty {
12126    #[serde(default)]
12127    pub this: Option<Box<Expression>>,
12128}
12129
12130/// MergeBlockRatioProperty
12131#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12132#[cfg_attr(feature = "bindings", derive(TS))]
12133pub struct MergeBlockRatioProperty {
12134    #[serde(default)]
12135    pub this: Option<Box<Expression>>,
12136    #[serde(default)]
12137    pub no: Option<Box<Expression>>,
12138    #[serde(default)]
12139    pub default: Option<Box<Expression>>,
12140    #[serde(default)]
12141    pub percent: Option<Box<Expression>>,
12142}
12143
12144/// OnProperty
12145#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12146#[cfg_attr(feature = "bindings", derive(TS))]
12147pub struct OnProperty {
12148    pub this: Box<Expression>,
12149}
12150
12151/// OnCommitProperty
12152#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12153#[cfg_attr(feature = "bindings", derive(TS))]
12154pub struct OnCommitProperty {
12155    #[serde(default)]
12156    pub delete: Option<Box<Expression>>,
12157}
12158
12159/// PartitionedByProperty
12160#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12161#[cfg_attr(feature = "bindings", derive(TS))]
12162pub struct PartitionedByProperty {
12163    pub this: Box<Expression>,
12164}
12165
12166/// BigQuery PARTITION BY property in CREATE TABLE statements.
12167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12168#[cfg_attr(feature = "bindings", derive(TS))]
12169pub struct PartitionByProperty {
12170    /// Structured partition scheme when the dialect supports methods and ranges.
12171    #[serde(default, skip_serializing_if = "Option::is_none")]
12172    pub specification: Option<PartitionSpec>,
12173    #[serde(default)]
12174    pub expressions: Vec<Expression>,
12175}
12176
12177/// PartitionedByBucket
12178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12179#[cfg_attr(feature = "bindings", derive(TS))]
12180pub struct PartitionedByBucket {
12181    pub this: Box<Expression>,
12182    pub expression: Box<Expression>,
12183}
12184
12185/// BigQuery CLUSTER BY property in CREATE TABLE statements.
12186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12187#[cfg_attr(feature = "bindings", derive(TS))]
12188pub struct ClusterByColumnsProperty {
12189    #[serde(default)]
12190    pub columns: Vec<Identifier>,
12191}
12192
12193/// PartitionByTruncate
12194#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12195#[cfg_attr(feature = "bindings", derive(TS))]
12196pub struct PartitionByTruncate {
12197    pub this: Box<Expression>,
12198    pub expression: Box<Expression>,
12199}
12200
12201/// PartitionByRangeProperty
12202#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12203#[cfg_attr(feature = "bindings", derive(TS))]
12204pub struct PartitionByRangeProperty {
12205    #[serde(default)]
12206    pub partition_expressions: Option<Box<Expression>>,
12207    #[serde(default)]
12208    pub create_expressions: Option<Box<Expression>>,
12209}
12210
12211/// PartitionByRangePropertyDynamic
12212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12213#[cfg_attr(feature = "bindings", derive(TS))]
12214pub struct PartitionByRangePropertyDynamic {
12215    #[serde(default)]
12216    pub this: Option<Box<Expression>>,
12217    #[serde(default)]
12218    pub start: Option<Box<Expression>>,
12219    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
12220    #[serde(default)]
12221    pub use_start_end: bool,
12222    #[serde(default)]
12223    pub end: Option<Box<Expression>>,
12224    #[serde(default)]
12225    pub every: Option<Box<Expression>>,
12226}
12227
12228/// PartitionByListProperty
12229#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12230#[cfg_attr(feature = "bindings", derive(TS))]
12231pub struct PartitionByListProperty {
12232    #[serde(default)]
12233    pub partition_expressions: Option<Box<Expression>>,
12234    #[serde(default)]
12235    pub create_expressions: Option<Box<Expression>>,
12236}
12237
12238/// PartitionList
12239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12240#[cfg_attr(feature = "bindings", derive(TS))]
12241pub struct PartitionList {
12242    pub this: Box<Expression>,
12243    #[serde(default)]
12244    pub expressions: Vec<Expression>,
12245}
12246
12247/// Partition - represents PARTITION/SUBPARTITION clause
12248#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12249#[cfg_attr(feature = "bindings", derive(TS))]
12250pub struct Partition {
12251    pub expressions: Vec<Expression>,
12252    #[serde(default)]
12253    pub subpartition: bool,
12254}
12255
12256/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
12257/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
12258#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12259#[cfg_attr(feature = "bindings", derive(TS))]
12260pub struct RefreshTriggerProperty {
12261    /// Method: COMPLETE or AUTO
12262    pub method: String,
12263    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
12264    #[serde(default)]
12265    pub kind: Option<String>,
12266    /// For SCHEDULE: EVERY n (the number)
12267    #[serde(default)]
12268    pub every: Option<Box<Expression>>,
12269    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
12270    #[serde(default)]
12271    pub unit: Option<String>,
12272    /// For SCHEDULE: STARTS 'datetime'
12273    #[serde(default)]
12274    pub starts: Option<Box<Expression>>,
12275}
12276
12277/// UniqueKeyProperty
12278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12279#[cfg_attr(feature = "bindings", derive(TS))]
12280pub struct UniqueKeyProperty {
12281    #[serde(default)]
12282    pub expressions: Vec<Expression>,
12283}
12284
12285/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
12286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12287#[cfg_attr(feature = "bindings", derive(TS))]
12288pub struct RollupProperty {
12289    pub expressions: Vec<RollupIndex>,
12290}
12291
12292/// RollupIndex - A single rollup index: name(col1, col2)
12293#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12294#[cfg_attr(feature = "bindings", derive(TS))]
12295pub struct RollupIndex {
12296    pub name: Identifier,
12297    pub expressions: Vec<Identifier>,
12298}
12299
12300/// PartitionBoundSpec
12301#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12302#[cfg_attr(feature = "bindings", derive(TS))]
12303pub struct PartitionBoundSpec {
12304    #[serde(default)]
12305    pub this: Option<Box<Expression>>,
12306    #[serde(default)]
12307    pub expression: Option<Box<Expression>>,
12308    #[serde(default)]
12309    pub from_expressions: Option<Box<Expression>>,
12310    #[serde(default)]
12311    pub to_expressions: Option<Box<Expression>>,
12312}
12313
12314/// PartitionedOfProperty
12315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12316#[cfg_attr(feature = "bindings", derive(TS))]
12317pub struct PartitionedOfProperty {
12318    pub this: Box<Expression>,
12319    pub expression: Box<Expression>,
12320}
12321
12322/// RemoteWithConnectionModelProperty
12323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12324#[cfg_attr(feature = "bindings", derive(TS))]
12325pub struct RemoteWithConnectionModelProperty {
12326    pub this: Box<Expression>,
12327}
12328
12329/// ReturnsProperty
12330#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12331#[cfg_attr(feature = "bindings", derive(TS))]
12332pub struct ReturnsProperty {
12333    #[serde(default)]
12334    pub this: Option<Box<Expression>>,
12335    #[serde(default)]
12336    pub is_table: Option<Box<Expression>>,
12337    #[serde(default)]
12338    pub table: Option<Box<Expression>>,
12339    #[serde(default)]
12340    pub null: Option<Box<Expression>>,
12341}
12342
12343/// RowFormatProperty
12344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12345#[cfg_attr(feature = "bindings", derive(TS))]
12346pub struct RowFormatProperty {
12347    pub this: Box<Expression>,
12348}
12349
12350/// RowFormatDelimitedProperty
12351#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12352#[cfg_attr(feature = "bindings", derive(TS))]
12353pub struct RowFormatDelimitedProperty {
12354    #[serde(default)]
12355    pub fields: Option<Box<Expression>>,
12356    #[serde(default)]
12357    pub escaped: Option<Box<Expression>>,
12358    #[serde(default)]
12359    pub collection_items: Option<Box<Expression>>,
12360    #[serde(default)]
12361    pub map_keys: Option<Box<Expression>>,
12362    #[serde(default)]
12363    pub lines: Option<Box<Expression>>,
12364    #[serde(default)]
12365    pub null: Option<Box<Expression>>,
12366    #[serde(default)]
12367    pub serde: Option<Box<Expression>>,
12368}
12369
12370/// RowFormatSerdeProperty
12371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12372#[cfg_attr(feature = "bindings", derive(TS))]
12373pub struct RowFormatSerdeProperty {
12374    pub this: Box<Expression>,
12375    #[serde(default)]
12376    pub serde_properties: Option<Box<Expression>>,
12377}
12378
12379/// QueryTransform
12380#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12381#[cfg_attr(feature = "bindings", derive(TS))]
12382pub struct QueryTransform {
12383    #[serde(default)]
12384    pub expressions: Vec<Expression>,
12385    #[serde(default)]
12386    pub command_script: Option<Box<Expression>>,
12387    #[serde(default)]
12388    pub schema: Option<Box<Expression>>,
12389    #[serde(default)]
12390    pub row_format_before: Option<Box<Expression>>,
12391    #[serde(default)]
12392    pub record_writer: Option<Box<Expression>>,
12393    #[serde(default)]
12394    pub row_format_after: Option<Box<Expression>>,
12395    #[serde(default)]
12396    pub record_reader: Option<Box<Expression>>,
12397}
12398
12399/// SampleProperty
12400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12401#[cfg_attr(feature = "bindings", derive(TS))]
12402pub struct SampleProperty {
12403    pub this: Box<Expression>,
12404}
12405
12406/// SecurityProperty
12407#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12408#[cfg_attr(feature = "bindings", derive(TS))]
12409pub struct SecurityProperty {
12410    pub this: Box<Expression>,
12411}
12412
12413/// SchemaCommentProperty
12414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12415#[cfg_attr(feature = "bindings", derive(TS))]
12416pub struct SchemaCommentProperty {
12417    pub this: Box<Expression>,
12418}
12419
12420/// SemanticView
12421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12422#[cfg_attr(feature = "bindings", derive(TS))]
12423pub struct SemanticView {
12424    pub this: Box<Expression>,
12425    #[serde(default)]
12426    pub metrics: Option<Box<Expression>>,
12427    #[serde(default)]
12428    pub dimensions: Option<Box<Expression>>,
12429    #[serde(default)]
12430    pub facts: Option<Box<Expression>>,
12431    #[serde(default)]
12432    pub where_: Option<Box<Expression>>,
12433}
12434
12435/// SerdeProperties
12436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12437#[cfg_attr(feature = "bindings", derive(TS))]
12438pub struct SerdeProperties {
12439    #[serde(default)]
12440    pub expressions: Vec<Expression>,
12441    #[serde(default)]
12442    pub with_: Option<Box<Expression>>,
12443}
12444
12445/// SetProperty
12446#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12447#[cfg_attr(feature = "bindings", derive(TS))]
12448pub struct SetProperty {
12449    #[serde(default)]
12450    pub multi: Option<Box<Expression>>,
12451}
12452
12453/// SharingProperty
12454#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12455#[cfg_attr(feature = "bindings", derive(TS))]
12456pub struct SharingProperty {
12457    #[serde(default)]
12458    pub this: Option<Box<Expression>>,
12459}
12460
12461/// SetConfigProperty
12462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12463#[cfg_attr(feature = "bindings", derive(TS))]
12464pub struct SetConfigProperty {
12465    pub this: Box<Expression>,
12466}
12467
12468/// SettingsProperty
12469#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12470#[cfg_attr(feature = "bindings", derive(TS))]
12471pub struct SettingsProperty {
12472    #[serde(default)]
12473    pub expressions: Vec<Expression>,
12474}
12475
12476/// SortKeyProperty
12477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12478#[cfg_attr(feature = "bindings", derive(TS))]
12479pub struct SortKeyProperty {
12480    pub this: Box<Expression>,
12481    #[serde(default)]
12482    pub compound: Option<Box<Expression>>,
12483}
12484
12485/// SqlReadWriteProperty
12486#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12487#[cfg_attr(feature = "bindings", derive(TS))]
12488pub struct SqlReadWriteProperty {
12489    pub this: Box<Expression>,
12490}
12491
12492/// SqlSecurityProperty
12493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12494#[cfg_attr(feature = "bindings", derive(TS))]
12495pub struct SqlSecurityProperty {
12496    pub this: Box<Expression>,
12497}
12498
12499/// StabilityProperty
12500#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12501#[cfg_attr(feature = "bindings", derive(TS))]
12502pub struct StabilityProperty {
12503    pub this: Box<Expression>,
12504}
12505
12506/// StorageHandlerProperty
12507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12508#[cfg_attr(feature = "bindings", derive(TS))]
12509pub struct StorageHandlerProperty {
12510    pub this: Box<Expression>,
12511}
12512
12513/// TemporaryProperty
12514#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12515#[cfg_attr(feature = "bindings", derive(TS))]
12516pub struct TemporaryProperty {
12517    #[serde(default)]
12518    pub this: Option<Box<Expression>>,
12519}
12520
12521/// Tags
12522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12523#[cfg_attr(feature = "bindings", derive(TS))]
12524pub struct Tags {
12525    #[serde(default)]
12526    pub expressions: Vec<Expression>,
12527}
12528
12529/// TransformModelProperty
12530#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12531#[cfg_attr(feature = "bindings", derive(TS))]
12532pub struct TransformModelProperty {
12533    #[serde(default)]
12534    pub expressions: Vec<Expression>,
12535}
12536
12537/// TransientProperty
12538#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12539#[cfg_attr(feature = "bindings", derive(TS))]
12540pub struct TransientProperty {
12541    #[serde(default)]
12542    pub this: Option<Box<Expression>>,
12543}
12544
12545/// UsingTemplateProperty
12546#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12547#[cfg_attr(feature = "bindings", derive(TS))]
12548pub struct UsingTemplateProperty {
12549    pub this: Box<Expression>,
12550}
12551
12552/// ViewAttributeProperty
12553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12554#[cfg_attr(feature = "bindings", derive(TS))]
12555pub struct ViewAttributeProperty {
12556    pub this: Box<Expression>,
12557}
12558
12559/// VolatileProperty
12560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12561#[cfg_attr(feature = "bindings", derive(TS))]
12562pub struct VolatileProperty {
12563    #[serde(default)]
12564    pub this: Option<Box<Expression>>,
12565}
12566
12567/// WithDataProperty
12568#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12569#[cfg_attr(feature = "bindings", derive(TS))]
12570pub struct WithDataProperty {
12571    #[serde(default)]
12572    pub no: Option<Box<Expression>>,
12573    #[serde(default)]
12574    pub statistics: Option<Box<Expression>>,
12575}
12576
12577/// WithJournalTableProperty
12578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12579#[cfg_attr(feature = "bindings", derive(TS))]
12580pub struct WithJournalTableProperty {
12581    pub this: Box<Expression>,
12582}
12583
12584/// WithSchemaBindingProperty
12585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12586#[cfg_attr(feature = "bindings", derive(TS))]
12587pub struct WithSchemaBindingProperty {
12588    pub this: Box<Expression>,
12589}
12590
12591/// WithSystemVersioningProperty
12592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12593#[cfg_attr(feature = "bindings", derive(TS))]
12594pub struct WithSystemVersioningProperty {
12595    #[serde(default)]
12596    pub on: Option<Box<Expression>>,
12597    #[serde(default)]
12598    pub this: Option<Box<Expression>>,
12599    #[serde(default)]
12600    pub data_consistency: Option<Box<Expression>>,
12601    #[serde(default)]
12602    pub retention_period: Option<Box<Expression>>,
12603    #[serde(default)]
12604    pub with_: Option<Box<Expression>>,
12605}
12606
12607/// WithProcedureOptions
12608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12609#[cfg_attr(feature = "bindings", derive(TS))]
12610pub struct WithProcedureOptions {
12611    #[serde(default)]
12612    pub expressions: Vec<Expression>,
12613}
12614
12615/// EncodeProperty
12616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12617#[cfg_attr(feature = "bindings", derive(TS))]
12618pub struct EncodeProperty {
12619    pub this: Box<Expression>,
12620    #[serde(default)]
12621    pub properties: Vec<Expression>,
12622    #[serde(default)]
12623    pub key: Option<Box<Expression>>,
12624}
12625
12626/// IncludeProperty
12627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12628#[cfg_attr(feature = "bindings", derive(TS))]
12629pub struct IncludeProperty {
12630    pub this: Box<Expression>,
12631    #[serde(default)]
12632    pub alias: Option<String>,
12633    #[serde(default)]
12634    pub column_def: Option<Box<Expression>>,
12635}
12636
12637/// Properties
12638#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12639#[cfg_attr(feature = "bindings", derive(TS))]
12640pub struct Properties {
12641    #[serde(default)]
12642    pub expressions: Vec<Expression>,
12643}
12644
12645/// Key/value pair in a BigQuery OPTIONS (...) clause.
12646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12647#[cfg_attr(feature = "bindings", derive(TS))]
12648pub struct OptionEntry {
12649    pub key: Identifier,
12650    pub value: Expression,
12651}
12652
12653/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12654#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12655#[cfg_attr(feature = "bindings", derive(TS))]
12656pub struct OptionsProperty {
12657    #[serde(default)]
12658    pub entries: Vec<OptionEntry>,
12659}
12660
12661/// InputOutputFormat
12662#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12663#[cfg_attr(feature = "bindings", derive(TS))]
12664pub struct InputOutputFormat {
12665    #[serde(default)]
12666    pub input_format: Option<Box<Expression>>,
12667    #[serde(default)]
12668    pub output_format: Option<Box<Expression>>,
12669}
12670
12671/// Reference
12672#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12673#[cfg_attr(feature = "bindings", derive(TS))]
12674pub struct Reference {
12675    pub this: Box<Expression>,
12676    #[serde(default)]
12677    pub expressions: Vec<Expression>,
12678    #[serde(default)]
12679    pub options: Vec<Expression>,
12680}
12681
12682/// QueryOption
12683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12684#[cfg_attr(feature = "bindings", derive(TS))]
12685pub struct QueryOption {
12686    pub this: Box<Expression>,
12687    #[serde(default)]
12688    pub expression: Option<Box<Expression>>,
12689}
12690
12691/// WithTableHint
12692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12693#[cfg_attr(feature = "bindings", derive(TS))]
12694pub struct WithTableHint {
12695    #[serde(default)]
12696    pub expressions: Vec<Expression>,
12697}
12698
12699/// IndexTableHint
12700#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12701#[cfg_attr(feature = "bindings", derive(TS))]
12702pub struct IndexTableHint {
12703    pub this: Box<Expression>,
12704    #[serde(default)]
12705    pub expressions: Vec<Expression>,
12706    #[serde(default)]
12707    pub target: Option<Box<Expression>>,
12708}
12709
12710/// Get
12711#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12712#[cfg_attr(feature = "bindings", derive(TS))]
12713pub struct Get {
12714    pub this: Box<Expression>,
12715    #[serde(default)]
12716    pub target: Option<Box<Expression>>,
12717    #[serde(default)]
12718    pub properties: Vec<Expression>,
12719}
12720
12721/// SetOperation
12722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12723#[cfg_attr(feature = "bindings", derive(TS))]
12724pub struct SetOperation {
12725    #[serde(default)]
12726    pub with_: Option<Box<Expression>>,
12727    pub this: Box<Expression>,
12728    pub expression: Box<Expression>,
12729    #[serde(default)]
12730    pub distinct: bool,
12731    #[serde(default)]
12732    pub by_name: Option<Box<Expression>>,
12733    #[serde(default)]
12734    pub side: Option<Box<Expression>>,
12735    #[serde(default)]
12736    pub kind: Option<String>,
12737    #[serde(default)]
12738    pub on: Option<Box<Expression>>,
12739}
12740
12741/// Var - Simple variable reference (for SQL variables, keywords as values)
12742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12743#[cfg_attr(feature = "bindings", derive(TS))]
12744pub struct Var {
12745    pub this: String,
12746}
12747
12748/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12750#[cfg_attr(feature = "bindings", derive(TS))]
12751pub struct Variadic {
12752    pub this: Box<Expression>,
12753}
12754
12755/// Version
12756#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12757#[cfg_attr(feature = "bindings", derive(TS))]
12758pub struct Version {
12759    pub this: Box<Expression>,
12760    pub kind: String,
12761    #[serde(default)]
12762    pub expression: Option<Box<Expression>>,
12763}
12764
12765/// Schema
12766#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12767#[cfg_attr(feature = "bindings", derive(TS))]
12768pub struct Schema {
12769    #[serde(default)]
12770    pub this: Option<Box<Expression>>,
12771    #[serde(default)]
12772    pub expressions: Vec<Expression>,
12773}
12774
12775/// Lock
12776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12777#[cfg_attr(feature = "bindings", derive(TS))]
12778pub struct Lock {
12779    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
12780    pub ignore_locked: bool,
12781    #[serde(default)]
12782    pub update: Option<Box<Expression>>,
12783    #[serde(default)]
12784    pub expressions: Vec<Expression>,
12785    #[serde(default)]
12786    pub wait: Option<Box<Expression>>,
12787    #[serde(default)]
12788    pub key: Option<Box<Expression>>,
12789}
12790
12791/// TableSample - wraps an expression with a TABLESAMPLE clause
12792/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12794#[cfg_attr(feature = "bindings", derive(TS))]
12795pub struct TableSample {
12796    /// The expression being sampled (subquery, function, etc.)
12797    #[serde(default, skip_serializing_if = "Option::is_none")]
12798    pub this: Option<Box<Expression>>,
12799    /// The sample specification
12800    #[serde(default, skip_serializing_if = "Option::is_none")]
12801    pub sample: Option<Box<Sample>>,
12802    #[serde(default)]
12803    pub expressions: Vec<Expression>,
12804    #[serde(default)]
12805    pub method: Option<String>,
12806    #[serde(default)]
12807    pub bucket_numerator: Option<Box<Expression>>,
12808    #[serde(default)]
12809    pub bucket_denominator: Option<Box<Expression>>,
12810    #[serde(default)]
12811    pub bucket_field: Option<Box<Expression>>,
12812    #[serde(default)]
12813    pub percent: Option<Box<Expression>>,
12814    #[serde(default)]
12815    pub rows: Option<Box<Expression>>,
12816    #[serde(default)]
12817    pub size: Option<i64>,
12818    #[serde(default)]
12819    pub seed: Option<Box<Expression>>,
12820}
12821
12822/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12823#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12824#[cfg_attr(feature = "bindings", derive(TS))]
12825pub struct Tag {
12826    #[serde(default)]
12827    pub this: Option<Box<Expression>>,
12828    #[serde(default)]
12829    pub prefix: Option<Box<Expression>>,
12830    #[serde(default)]
12831    pub postfix: Option<Box<Expression>>,
12832}
12833
12834/// UnpivotColumns
12835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12836#[cfg_attr(feature = "bindings", derive(TS))]
12837pub struct UnpivotColumns {
12838    pub this: Box<Expression>,
12839    #[serde(default)]
12840    pub expressions: Vec<Expression>,
12841}
12842
12843/// SessionParameter
12844#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12845#[cfg_attr(feature = "bindings", derive(TS))]
12846pub struct SessionParameter {
12847    pub this: Box<Expression>,
12848    #[serde(default)]
12849    pub kind: Option<String>,
12850}
12851
12852/// PseudoType
12853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12854#[cfg_attr(feature = "bindings", derive(TS))]
12855pub struct PseudoType {
12856    pub this: Box<Expression>,
12857}
12858
12859/// ObjectIdentifier
12860#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12861#[cfg_attr(feature = "bindings", derive(TS))]
12862pub struct ObjectIdentifier {
12863    pub this: Box<Expression>,
12864}
12865
12866/// Transaction
12867#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12868#[cfg_attr(feature = "bindings", derive(TS))]
12869pub struct Transaction {
12870    #[serde(default)]
12871    pub this: Option<Box<Expression>>,
12872    #[serde(default)]
12873    pub modes: Option<Box<Expression>>,
12874    #[serde(default)]
12875    pub mark: Option<Box<Expression>>,
12876}
12877
12878/// Commit
12879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12880#[cfg_attr(feature = "bindings", derive(TS))]
12881pub struct Commit {
12882    #[serde(default)]
12883    pub chain: Option<Box<Expression>>,
12884    #[serde(default)]
12885    pub this: Option<Box<Expression>>,
12886    #[serde(default)]
12887    pub durability: Option<Box<Expression>>,
12888}
12889
12890/// Rollback
12891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12892#[cfg_attr(feature = "bindings", derive(TS))]
12893pub struct Rollback {
12894    #[serde(default)]
12895    pub savepoint: Option<Box<Expression>>,
12896    #[serde(default)]
12897    pub this: Option<Box<Expression>>,
12898}
12899
12900/// AlterSession
12901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12902#[cfg_attr(feature = "bindings", derive(TS))]
12903pub struct AlterSession {
12904    #[serde(default)]
12905    pub expressions: Vec<Expression>,
12906    #[serde(default)]
12907    pub unset: Option<Box<Expression>>,
12908}
12909
12910/// Analyze
12911#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12912#[cfg_attr(feature = "bindings", derive(TS))]
12913pub struct Analyze {
12914    #[serde(default)]
12915    pub kind: Option<String>,
12916    #[serde(default)]
12917    pub this: Option<Box<Expression>>,
12918    #[serde(default)]
12919    pub options: Vec<Expression>,
12920    #[serde(default)]
12921    pub mode: Option<Box<Expression>>,
12922    #[serde(default)]
12923    pub partition: Option<Box<Expression>>,
12924    #[serde(default)]
12925    pub expression: Option<Box<Expression>>,
12926    #[serde(default)]
12927    pub properties: Vec<Expression>,
12928    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12929    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12930    pub columns: Vec<String>,
12931}
12932
12933/// AnalyzeStatistics
12934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12935#[cfg_attr(feature = "bindings", derive(TS))]
12936pub struct AnalyzeStatistics {
12937    pub kind: String,
12938    #[serde(default)]
12939    pub option: Option<Box<Expression>>,
12940    #[serde(default)]
12941    pub this: Option<Box<Expression>>,
12942    #[serde(default)]
12943    pub expressions: Vec<Expression>,
12944}
12945
12946/// AnalyzeHistogram
12947#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12948#[cfg_attr(feature = "bindings", derive(TS))]
12949pub struct AnalyzeHistogram {
12950    pub this: Box<Expression>,
12951    #[serde(default)]
12952    pub expressions: Vec<Expression>,
12953    #[serde(default)]
12954    pub expression: Option<Box<Expression>>,
12955    #[serde(default)]
12956    pub update_options: Option<Box<Expression>>,
12957}
12958
12959/// AnalyzeSample
12960#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12961#[cfg_attr(feature = "bindings", derive(TS))]
12962pub struct AnalyzeSample {
12963    pub kind: String,
12964    #[serde(default)]
12965    pub sample: Option<Box<Expression>>,
12966}
12967
12968/// AnalyzeListChainedRows
12969#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12970#[cfg_attr(feature = "bindings", derive(TS))]
12971pub struct AnalyzeListChainedRows {
12972    #[serde(default)]
12973    pub expression: Option<Box<Expression>>,
12974}
12975
12976/// AnalyzeDelete
12977#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12978#[cfg_attr(feature = "bindings", derive(TS))]
12979pub struct AnalyzeDelete {
12980    #[serde(default)]
12981    pub kind: Option<String>,
12982}
12983
12984/// AnalyzeWith
12985#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12986#[cfg_attr(feature = "bindings", derive(TS))]
12987pub struct AnalyzeWith {
12988    #[serde(default)]
12989    pub expressions: Vec<Expression>,
12990}
12991
12992/// AnalyzeValidate
12993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12994#[cfg_attr(feature = "bindings", derive(TS))]
12995pub struct AnalyzeValidate {
12996    pub kind: String,
12997    #[serde(default)]
12998    pub this: Option<Box<Expression>>,
12999    #[serde(default)]
13000    pub expression: Option<Box<Expression>>,
13001}
13002
13003/// AddPartition
13004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13005#[cfg_attr(feature = "bindings", derive(TS))]
13006pub struct AddPartition {
13007    pub this: Box<Expression>,
13008    #[serde(default)]
13009    pub exists: bool,
13010    #[serde(default)]
13011    pub location: Option<Box<Expression>>,
13012}
13013
13014/// AttachOption
13015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13016#[cfg_attr(feature = "bindings", derive(TS))]
13017pub struct AttachOption {
13018    pub this: Box<Expression>,
13019    #[serde(default)]
13020    pub expression: Option<Box<Expression>>,
13021}
13022
13023/// DropPartition
13024#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13025#[cfg_attr(feature = "bindings", derive(TS))]
13026pub struct DropPartition {
13027    #[serde(default)]
13028    pub expressions: Vec<Expression>,
13029    #[serde(default)]
13030    pub exists: bool,
13031}
13032
13033/// ReplacePartition
13034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13035#[cfg_attr(feature = "bindings", derive(TS))]
13036pub struct ReplacePartition {
13037    pub expression: Box<Expression>,
13038    #[serde(default)]
13039    pub source: Option<Box<Expression>>,
13040}
13041
13042/// DPipe
13043#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13044#[cfg_attr(feature = "bindings", derive(TS))]
13045pub struct DPipe {
13046    pub this: Box<Expression>,
13047    pub expression: Box<Expression>,
13048    #[serde(default)]
13049    pub safe: Option<Box<Expression>>,
13050}
13051
13052/// Operator
13053#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13054#[cfg_attr(feature = "bindings", derive(TS))]
13055pub struct Operator {
13056    pub this: Box<Expression>,
13057    #[serde(default)]
13058    pub operator: Option<Box<Expression>>,
13059    pub expression: Box<Expression>,
13060    /// Comments between OPERATOR() and the RHS expression
13061    #[serde(default, skip_serializing_if = "Vec::is_empty")]
13062    pub comments: Vec<String>,
13063}
13064
13065/// PivotAny
13066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13067#[cfg_attr(feature = "bindings", derive(TS))]
13068pub struct PivotAny {
13069    #[serde(default)]
13070    pub this: Option<Box<Expression>>,
13071}
13072
13073/// Aliases
13074#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13075#[cfg_attr(feature = "bindings", derive(TS))]
13076pub struct Aliases {
13077    pub this: Box<Expression>,
13078    #[serde(default)]
13079    pub expressions: Vec<Expression>,
13080}
13081
13082/// AtIndex
13083#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13084#[cfg_attr(feature = "bindings", derive(TS))]
13085pub struct AtIndex {
13086    pub this: Box<Expression>,
13087    pub expression: Box<Expression>,
13088}
13089
13090/// FromTimeZone
13091#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13092#[cfg_attr(feature = "bindings", derive(TS))]
13093pub struct FromTimeZone {
13094    pub this: Box<Expression>,
13095    #[serde(default)]
13096    pub zone: Option<Box<Expression>>,
13097}
13098
13099/// Format override for a column in Teradata
13100#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13101#[cfg_attr(feature = "bindings", derive(TS))]
13102pub struct FormatPhrase {
13103    pub this: Box<Expression>,
13104    pub format: String,
13105}
13106
13107/// ForIn
13108#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13109#[cfg_attr(feature = "bindings", derive(TS))]
13110pub struct ForIn {
13111    pub this: Box<Expression>,
13112    pub expression: Box<Expression>,
13113}
13114
13115/// Automatically converts unit arg into a var.
13116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13117#[cfg_attr(feature = "bindings", derive(TS))]
13118pub struct TimeUnit {
13119    #[serde(default)]
13120    pub unit: Option<String>,
13121}
13122
13123/// IntervalOp
13124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13125#[cfg_attr(feature = "bindings", derive(TS))]
13126pub struct IntervalOp {
13127    #[serde(default)]
13128    pub unit: Option<String>,
13129    pub expression: Box<Expression>,
13130}
13131
13132/// HavingMax
13133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13134#[cfg_attr(feature = "bindings", derive(TS))]
13135pub struct HavingMax {
13136    pub this: Box<Expression>,
13137    pub expression: Box<Expression>,
13138    #[serde(default)]
13139    pub max: Option<Box<Expression>>,
13140}
13141
13142/// CosineDistance
13143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13144#[cfg_attr(feature = "bindings", derive(TS))]
13145pub struct CosineDistance {
13146    pub this: Box<Expression>,
13147    pub expression: Box<Expression>,
13148}
13149
13150/// DotProduct
13151#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13152#[cfg_attr(feature = "bindings", derive(TS))]
13153pub struct DotProduct {
13154    pub this: Box<Expression>,
13155    pub expression: Box<Expression>,
13156}
13157
13158/// EuclideanDistance
13159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13160#[cfg_attr(feature = "bindings", derive(TS))]
13161pub struct EuclideanDistance {
13162    pub this: Box<Expression>,
13163    pub expression: Box<Expression>,
13164}
13165
13166/// ManhattanDistance
13167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13168#[cfg_attr(feature = "bindings", derive(TS))]
13169pub struct ManhattanDistance {
13170    pub this: Box<Expression>,
13171    pub expression: Box<Expression>,
13172}
13173
13174/// JarowinklerSimilarity
13175#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13176#[cfg_attr(feature = "bindings", derive(TS))]
13177pub struct JarowinklerSimilarity {
13178    pub this: Box<Expression>,
13179    pub expression: Box<Expression>,
13180}
13181
13182/// Booland
13183#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13184#[cfg_attr(feature = "bindings", derive(TS))]
13185pub struct Booland {
13186    pub this: Box<Expression>,
13187    pub expression: Box<Expression>,
13188}
13189
13190/// Boolor
13191#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13192#[cfg_attr(feature = "bindings", derive(TS))]
13193pub struct Boolor {
13194    pub this: Box<Expression>,
13195    pub expression: Box<Expression>,
13196}
13197
13198/// ParameterizedAgg
13199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13200#[cfg_attr(feature = "bindings", derive(TS))]
13201pub struct ParameterizedAgg {
13202    pub this: Box<Expression>,
13203    #[serde(default)]
13204    pub expressions: Vec<Expression>,
13205    #[serde(default)]
13206    pub params: Vec<Expression>,
13207}
13208
13209/// ArgMax
13210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13211#[cfg_attr(feature = "bindings", derive(TS))]
13212pub struct ArgMax {
13213    pub this: Box<Expression>,
13214    pub expression: Box<Expression>,
13215    #[serde(default)]
13216    pub count: Option<Box<Expression>>,
13217}
13218
13219/// ArgMin
13220#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13221#[cfg_attr(feature = "bindings", derive(TS))]
13222pub struct ArgMin {
13223    pub this: Box<Expression>,
13224    pub expression: Box<Expression>,
13225    #[serde(default)]
13226    pub count: Option<Box<Expression>>,
13227}
13228
13229/// ApproxTopK
13230#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13231#[cfg_attr(feature = "bindings", derive(TS))]
13232pub struct ApproxTopK {
13233    pub this: Box<Expression>,
13234    #[serde(default)]
13235    pub expression: Option<Box<Expression>>,
13236    #[serde(default)]
13237    pub counters: Option<Box<Expression>>,
13238}
13239
13240/// ApproxTopKAccumulate
13241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13242#[cfg_attr(feature = "bindings", derive(TS))]
13243pub struct ApproxTopKAccumulate {
13244    pub this: Box<Expression>,
13245    #[serde(default)]
13246    pub expression: Option<Box<Expression>>,
13247}
13248
13249/// ApproxTopKCombine
13250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13251#[cfg_attr(feature = "bindings", derive(TS))]
13252pub struct ApproxTopKCombine {
13253    pub this: Box<Expression>,
13254    #[serde(default)]
13255    pub expression: Option<Box<Expression>>,
13256}
13257
13258/// ApproxTopKEstimate
13259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13260#[cfg_attr(feature = "bindings", derive(TS))]
13261pub struct ApproxTopKEstimate {
13262    pub this: Box<Expression>,
13263    #[serde(default)]
13264    pub expression: Option<Box<Expression>>,
13265}
13266
13267/// ApproxTopSum
13268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13269#[cfg_attr(feature = "bindings", derive(TS))]
13270pub struct ApproxTopSum {
13271    pub this: Box<Expression>,
13272    pub expression: Box<Expression>,
13273    #[serde(default)]
13274    pub count: Option<Box<Expression>>,
13275}
13276
13277/// ApproxQuantiles
13278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13279#[cfg_attr(feature = "bindings", derive(TS))]
13280pub struct ApproxQuantiles {
13281    pub this: Box<Expression>,
13282    #[serde(default)]
13283    pub expression: Option<Box<Expression>>,
13284}
13285
13286/// Minhash
13287#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13288#[cfg_attr(feature = "bindings", derive(TS))]
13289pub struct Minhash {
13290    pub this: Box<Expression>,
13291    #[serde(default)]
13292    pub expressions: Vec<Expression>,
13293}
13294
13295/// FarmFingerprint
13296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13297#[cfg_attr(feature = "bindings", derive(TS))]
13298pub struct FarmFingerprint {
13299    #[serde(default)]
13300    pub expressions: Vec<Expression>,
13301}
13302
13303/// Float64
13304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13305#[cfg_attr(feature = "bindings", derive(TS))]
13306pub struct Float64 {
13307    pub this: Box<Expression>,
13308    #[serde(default)]
13309    pub expression: Option<Box<Expression>>,
13310}
13311
13312/// Transform
13313#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13314#[cfg_attr(feature = "bindings", derive(TS))]
13315pub struct Transform {
13316    pub this: Box<Expression>,
13317    pub expression: Box<Expression>,
13318}
13319
13320/// Translate
13321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13322#[cfg_attr(feature = "bindings", derive(TS))]
13323pub struct Translate {
13324    pub this: Box<Expression>,
13325    #[serde(default)]
13326    pub from_: Option<Box<Expression>>,
13327    #[serde(default)]
13328    pub to: Option<Box<Expression>>,
13329}
13330
13331/// Grouping
13332#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13333#[cfg_attr(feature = "bindings", derive(TS))]
13334pub struct Grouping {
13335    #[serde(default)]
13336    pub expressions: Vec<Expression>,
13337}
13338
13339/// GroupingId
13340#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13341#[cfg_attr(feature = "bindings", derive(TS))]
13342pub struct GroupingId {
13343    #[serde(default)]
13344    pub expressions: Vec<Expression>,
13345}
13346
13347/// Anonymous
13348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13349#[cfg_attr(feature = "bindings", derive(TS))]
13350pub struct Anonymous {
13351    pub this: Box<Expression>,
13352    #[serde(default)]
13353    pub expressions: Vec<Expression>,
13354}
13355
13356/// AnonymousAggFunc
13357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13358#[cfg_attr(feature = "bindings", derive(TS))]
13359pub struct AnonymousAggFunc {
13360    pub this: Box<Expression>,
13361    #[serde(default)]
13362    pub expressions: Vec<Expression>,
13363}
13364
13365/// CombinedAggFunc
13366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13367#[cfg_attr(feature = "bindings", derive(TS))]
13368pub struct CombinedAggFunc {
13369    pub this: Box<Expression>,
13370    #[serde(default)]
13371    pub expressions: Vec<Expression>,
13372}
13373
13374/// CombinedParameterizedAgg
13375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13376#[cfg_attr(feature = "bindings", derive(TS))]
13377pub struct CombinedParameterizedAgg {
13378    pub this: Box<Expression>,
13379    #[serde(default)]
13380    pub expressions: Vec<Expression>,
13381    #[serde(default)]
13382    pub params: Vec<Expression>,
13383}
13384
13385/// HashAgg
13386#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13387#[cfg_attr(feature = "bindings", derive(TS))]
13388pub struct HashAgg {
13389    pub this: Box<Expression>,
13390    #[serde(default)]
13391    pub expressions: Vec<Expression>,
13392}
13393
13394/// Hll
13395#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13396#[cfg_attr(feature = "bindings", derive(TS))]
13397pub struct Hll {
13398    pub this: Box<Expression>,
13399    #[serde(default)]
13400    pub expressions: Vec<Expression>,
13401}
13402
13403/// Apply
13404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13405#[cfg_attr(feature = "bindings", derive(TS))]
13406pub struct Apply {
13407    pub this: Box<Expression>,
13408    pub expression: Box<Expression>,
13409}
13410
13411/// ToBoolean
13412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13413#[cfg_attr(feature = "bindings", derive(TS))]
13414pub struct ToBoolean {
13415    pub this: Box<Expression>,
13416    #[serde(default)]
13417    pub safe: Option<Box<Expression>>,
13418}
13419
13420/// List
13421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13422#[cfg_attr(feature = "bindings", derive(TS))]
13423pub struct List {
13424    #[serde(default)]
13425    pub expressions: Vec<Expression>,
13426}
13427
13428/// ToMap - Materialize-style map constructor
13429/// Can hold either:
13430/// - A SELECT subquery (MAP(SELECT 'a', 1))
13431/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
13432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13433#[cfg_attr(feature = "bindings", derive(TS))]
13434pub struct ToMap {
13435    /// Either a Select subquery or a Struct containing PropertyEQ entries
13436    pub this: Box<Expression>,
13437}
13438
13439/// Pad
13440#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13441#[cfg_attr(feature = "bindings", derive(TS))]
13442pub struct Pad {
13443    pub this: Box<Expression>,
13444    pub expression: Box<Expression>,
13445    #[serde(default)]
13446    pub fill_pattern: Option<Box<Expression>>,
13447    #[serde(default)]
13448    pub is_left: Option<Box<Expression>>,
13449}
13450
13451/// ToChar
13452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13453#[cfg_attr(feature = "bindings", derive(TS))]
13454pub struct ToChar {
13455    pub this: Box<Expression>,
13456    #[serde(default)]
13457    pub format: Option<String>,
13458    #[serde(default)]
13459    pub nlsparam: Option<Box<Expression>>,
13460    #[serde(default)]
13461    pub is_numeric: Option<Box<Expression>>,
13462}
13463
13464/// StringFunc - String type conversion function (BigQuery STRING)
13465#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13466#[cfg_attr(feature = "bindings", derive(TS))]
13467pub struct StringFunc {
13468    pub this: Box<Expression>,
13469    #[serde(default)]
13470    pub zone: Option<Box<Expression>>,
13471}
13472
13473/// ToNumber
13474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13475#[cfg_attr(feature = "bindings", derive(TS))]
13476pub struct ToNumber {
13477    pub this: Box<Expression>,
13478    #[serde(default)]
13479    pub format: Option<Box<Expression>>,
13480    #[serde(default)]
13481    pub nlsparam: Option<Box<Expression>>,
13482    #[serde(default)]
13483    pub precision: Option<Box<Expression>>,
13484    #[serde(default)]
13485    pub scale: Option<Box<Expression>>,
13486    #[serde(default)]
13487    pub safe: Option<Box<Expression>>,
13488    #[serde(default)]
13489    pub safe_name: Option<Box<Expression>>,
13490}
13491
13492/// ToDouble
13493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13494#[cfg_attr(feature = "bindings", derive(TS))]
13495pub struct ToDouble {
13496    pub this: Box<Expression>,
13497    #[serde(default)]
13498    pub format: Option<String>,
13499    #[serde(default)]
13500    pub safe: Option<Box<Expression>>,
13501}
13502
13503/// ToDecfloat
13504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13505#[cfg_attr(feature = "bindings", derive(TS))]
13506pub struct ToDecfloat {
13507    pub this: Box<Expression>,
13508    #[serde(default)]
13509    pub format: Option<String>,
13510}
13511
13512/// TryToDecfloat
13513#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13514#[cfg_attr(feature = "bindings", derive(TS))]
13515pub struct TryToDecfloat {
13516    pub this: Box<Expression>,
13517    #[serde(default)]
13518    pub format: Option<String>,
13519}
13520
13521/// ToFile
13522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13523#[cfg_attr(feature = "bindings", derive(TS))]
13524pub struct ToFile {
13525    pub this: Box<Expression>,
13526    #[serde(default)]
13527    pub path: Option<Box<Expression>>,
13528    #[serde(default)]
13529    pub safe: Option<Box<Expression>>,
13530}
13531
13532/// Columns
13533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13534#[cfg_attr(feature = "bindings", derive(TS))]
13535pub struct Columns {
13536    pub this: Box<Expression>,
13537    #[serde(default)]
13538    pub unpack: Option<Box<Expression>>,
13539}
13540
13541/// ConvertToCharset
13542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13543#[cfg_attr(feature = "bindings", derive(TS))]
13544pub struct ConvertToCharset {
13545    pub this: Box<Expression>,
13546    #[serde(default)]
13547    pub dest: Option<Box<Expression>>,
13548    #[serde(default)]
13549    pub source: Option<Box<Expression>>,
13550}
13551
13552/// ConvertTimezone
13553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13554#[cfg_attr(feature = "bindings", derive(TS))]
13555pub struct ConvertTimezone {
13556    #[serde(default)]
13557    pub source_tz: Option<Box<Expression>>,
13558    #[serde(default)]
13559    pub target_tz: Option<Box<Expression>>,
13560    #[serde(default)]
13561    pub timestamp: Option<Box<Expression>>,
13562    #[serde(default)]
13563    pub options: Vec<Expression>,
13564}
13565
13566/// GenerateSeries
13567#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13568#[cfg_attr(feature = "bindings", derive(TS))]
13569pub struct GenerateSeries {
13570    #[serde(default)]
13571    pub start: Option<Box<Expression>>,
13572    #[serde(default)]
13573    pub end: Option<Box<Expression>>,
13574    #[serde(default)]
13575    pub step: Option<Box<Expression>>,
13576    #[serde(default)]
13577    pub is_end_exclusive: Option<Box<Expression>>,
13578}
13579
13580/// AIAgg
13581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13582#[cfg_attr(feature = "bindings", derive(TS))]
13583pub struct AIAgg {
13584    pub this: Box<Expression>,
13585    pub expression: Box<Expression>,
13586}
13587
13588/// AIClassify
13589#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13590#[cfg_attr(feature = "bindings", derive(TS))]
13591pub struct AIClassify {
13592    pub this: Box<Expression>,
13593    #[serde(default)]
13594    pub categories: Option<Box<Expression>>,
13595    #[serde(default)]
13596    pub config: Option<Box<Expression>>,
13597}
13598
13599/// ArrayAll
13600#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13601#[cfg_attr(feature = "bindings", derive(TS))]
13602pub struct ArrayAll {
13603    pub this: Box<Expression>,
13604    pub expression: Box<Expression>,
13605}
13606
13607/// ArrayAny
13608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13609#[cfg_attr(feature = "bindings", derive(TS))]
13610pub struct ArrayAny {
13611    pub this: Box<Expression>,
13612    pub expression: Box<Expression>,
13613}
13614
13615/// ArrayConstructCompact
13616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13617#[cfg_attr(feature = "bindings", derive(TS))]
13618pub struct ArrayConstructCompact {
13619    #[serde(default)]
13620    pub expressions: Vec<Expression>,
13621}
13622
13623/// StPoint
13624#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13625#[cfg_attr(feature = "bindings", derive(TS))]
13626pub struct StPoint {
13627    pub this: Box<Expression>,
13628    pub expression: Box<Expression>,
13629    #[serde(default)]
13630    pub null: Option<Box<Expression>>,
13631}
13632
13633/// StDistance
13634#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13635#[cfg_attr(feature = "bindings", derive(TS))]
13636pub struct StDistance {
13637    pub this: Box<Expression>,
13638    pub expression: Box<Expression>,
13639    #[serde(default)]
13640    pub use_spheroid: Option<Box<Expression>>,
13641}
13642
13643/// StringToArray
13644#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13645#[cfg_attr(feature = "bindings", derive(TS))]
13646pub struct StringToArray {
13647    pub this: Box<Expression>,
13648    #[serde(default)]
13649    pub expression: Option<Box<Expression>>,
13650    #[serde(default)]
13651    pub null: Option<Box<Expression>>,
13652}
13653
13654/// ArraySum
13655#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13656#[cfg_attr(feature = "bindings", derive(TS))]
13657pub struct ArraySum {
13658    pub this: Box<Expression>,
13659    #[serde(default)]
13660    pub expression: Option<Box<Expression>>,
13661}
13662
13663/// ObjectAgg
13664#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13665#[cfg_attr(feature = "bindings", derive(TS))]
13666pub struct ObjectAgg {
13667    pub this: Box<Expression>,
13668    pub expression: Box<Expression>,
13669}
13670
13671/// CastToStrType
13672#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13673#[cfg_attr(feature = "bindings", derive(TS))]
13674pub struct CastToStrType {
13675    pub this: Box<Expression>,
13676    #[serde(default)]
13677    pub to: Option<Box<Expression>>,
13678}
13679
13680/// CheckJson
13681#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13682#[cfg_attr(feature = "bindings", derive(TS))]
13683pub struct CheckJson {
13684    pub this: Box<Expression>,
13685}
13686
13687/// CheckXml
13688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13689#[cfg_attr(feature = "bindings", derive(TS))]
13690pub struct CheckXml {
13691    pub this: Box<Expression>,
13692    #[serde(default)]
13693    pub disable_auto_convert: Option<Box<Expression>>,
13694}
13695
13696/// TranslateCharacters
13697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13698#[cfg_attr(feature = "bindings", derive(TS))]
13699pub struct TranslateCharacters {
13700    pub this: Box<Expression>,
13701    pub expression: Box<Expression>,
13702    #[serde(default)]
13703    pub with_error: Option<Box<Expression>>,
13704}
13705
13706/// CurrentSchemas
13707#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13708#[cfg_attr(feature = "bindings", derive(TS))]
13709pub struct CurrentSchemas {
13710    #[serde(default)]
13711    pub this: Option<Box<Expression>>,
13712}
13713
13714/// CurrentDatetime
13715#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13716#[cfg_attr(feature = "bindings", derive(TS))]
13717pub struct CurrentDatetime {
13718    #[serde(default)]
13719    pub this: Option<Box<Expression>>,
13720}
13721
13722/// Localtime
13723#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13724#[cfg_attr(feature = "bindings", derive(TS))]
13725pub struct Localtime {
13726    #[serde(default)]
13727    pub this: Option<Box<Expression>>,
13728}
13729
13730/// Localtimestamp
13731#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13732#[cfg_attr(feature = "bindings", derive(TS))]
13733pub struct Localtimestamp {
13734    #[serde(default)]
13735    pub this: Option<Box<Expression>>,
13736}
13737
13738/// Systimestamp
13739#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13740#[cfg_attr(feature = "bindings", derive(TS))]
13741pub struct Systimestamp {
13742    #[serde(default)]
13743    pub this: Option<Box<Expression>>,
13744}
13745
13746/// CurrentSchema
13747#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13748#[cfg_attr(feature = "bindings", derive(TS))]
13749pub struct CurrentSchema {
13750    #[serde(default)]
13751    pub this: Option<Box<Expression>>,
13752}
13753
13754/// CurrentUser
13755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13756#[cfg_attr(feature = "bindings", derive(TS))]
13757pub struct CurrentUser {
13758    #[serde(default)]
13759    pub this: Option<Box<Expression>>,
13760}
13761
13762/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13764#[cfg_attr(feature = "bindings", derive(TS))]
13765pub struct SessionUser;
13766
13767/// JSONPathRoot - Represents $ in JSON path expressions
13768#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13769#[cfg_attr(feature = "bindings", derive(TS))]
13770pub struct JSONPathRoot;
13771
13772/// UtcTime
13773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13774#[cfg_attr(feature = "bindings", derive(TS))]
13775pub struct UtcTime {
13776    #[serde(default)]
13777    pub this: Option<Box<Expression>>,
13778}
13779
13780/// UtcTimestamp
13781#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13782#[cfg_attr(feature = "bindings", derive(TS))]
13783pub struct UtcTimestamp {
13784    #[serde(default)]
13785    pub this: Option<Box<Expression>>,
13786}
13787
13788/// TimestampFunc - TIMESTAMP constructor function
13789#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13790#[cfg_attr(feature = "bindings", derive(TS))]
13791pub struct TimestampFunc {
13792    #[serde(default)]
13793    pub this: Option<Box<Expression>>,
13794    #[serde(default)]
13795    pub zone: Option<Box<Expression>>,
13796    #[serde(default)]
13797    pub with_tz: Option<bool>,
13798    #[serde(default)]
13799    pub safe: Option<bool>,
13800}
13801
13802/// DateBin
13803#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13804#[cfg_attr(feature = "bindings", derive(TS))]
13805pub struct DateBin {
13806    pub this: Box<Expression>,
13807    pub expression: Box<Expression>,
13808    #[serde(default)]
13809    pub unit: Option<String>,
13810    #[serde(default)]
13811    pub zone: Option<Box<Expression>>,
13812    #[serde(default)]
13813    pub origin: Option<Box<Expression>>,
13814}
13815
13816/// Datetime
13817#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13818#[cfg_attr(feature = "bindings", derive(TS))]
13819pub struct Datetime {
13820    pub this: Box<Expression>,
13821    #[serde(default)]
13822    pub expression: Option<Box<Expression>>,
13823}
13824
13825/// DatetimeAdd
13826#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13827#[cfg_attr(feature = "bindings", derive(TS))]
13828pub struct DatetimeAdd {
13829    pub this: Box<Expression>,
13830    pub expression: Box<Expression>,
13831    #[serde(default)]
13832    pub unit: Option<String>,
13833}
13834
13835/// DatetimeSub
13836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13837#[cfg_attr(feature = "bindings", derive(TS))]
13838pub struct DatetimeSub {
13839    pub this: Box<Expression>,
13840    pub expression: Box<Expression>,
13841    #[serde(default)]
13842    pub unit: Option<String>,
13843}
13844
13845/// DatetimeDiff
13846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13847#[cfg_attr(feature = "bindings", derive(TS))]
13848pub struct DatetimeDiff {
13849    pub this: Box<Expression>,
13850    pub expression: Box<Expression>,
13851    #[serde(default)]
13852    pub unit: Option<String>,
13853}
13854
13855/// DatetimeTrunc
13856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13857#[cfg_attr(feature = "bindings", derive(TS))]
13858pub struct DatetimeTrunc {
13859    pub this: Box<Expression>,
13860    pub unit: String,
13861    #[serde(default)]
13862    pub zone: Option<Box<Expression>>,
13863}
13864
13865/// Dayname
13866#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13867#[cfg_attr(feature = "bindings", derive(TS))]
13868pub struct Dayname {
13869    pub this: Box<Expression>,
13870    #[serde(default)]
13871    pub abbreviated: Option<Box<Expression>>,
13872}
13873
13874/// MakeInterval
13875#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13876#[cfg_attr(feature = "bindings", derive(TS))]
13877pub struct MakeInterval {
13878    #[serde(default)]
13879    pub year: Option<Box<Expression>>,
13880    #[serde(default)]
13881    pub month: Option<Box<Expression>>,
13882    #[serde(default)]
13883    pub week: Option<Box<Expression>>,
13884    #[serde(default)]
13885    pub day: Option<Box<Expression>>,
13886    #[serde(default)]
13887    pub hour: Option<Box<Expression>>,
13888    #[serde(default)]
13889    pub minute: Option<Box<Expression>>,
13890    #[serde(default)]
13891    pub second: Option<Box<Expression>>,
13892}
13893
13894/// PreviousDay
13895#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13896#[cfg_attr(feature = "bindings", derive(TS))]
13897pub struct PreviousDay {
13898    pub this: Box<Expression>,
13899    pub expression: Box<Expression>,
13900}
13901
13902/// Elt
13903#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13904#[cfg_attr(feature = "bindings", derive(TS))]
13905pub struct Elt {
13906    pub this: Box<Expression>,
13907    #[serde(default)]
13908    pub expressions: Vec<Expression>,
13909}
13910
13911/// TimestampAdd
13912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13913#[cfg_attr(feature = "bindings", derive(TS))]
13914pub struct TimestampAdd {
13915    pub this: Box<Expression>,
13916    pub expression: Box<Expression>,
13917    #[serde(default)]
13918    pub unit: Option<String>,
13919}
13920
13921/// TimestampSub
13922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13923#[cfg_attr(feature = "bindings", derive(TS))]
13924pub struct TimestampSub {
13925    pub this: Box<Expression>,
13926    pub expression: Box<Expression>,
13927    #[serde(default)]
13928    pub unit: Option<String>,
13929}
13930
13931/// TimestampDiff
13932#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13933#[cfg_attr(feature = "bindings", derive(TS))]
13934pub struct TimestampDiff {
13935    pub this: Box<Expression>,
13936    pub expression: Box<Expression>,
13937    #[serde(default)]
13938    pub unit: Option<String>,
13939}
13940
13941/// TimeSlice
13942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13943#[cfg_attr(feature = "bindings", derive(TS))]
13944pub struct TimeSlice {
13945    pub this: Box<Expression>,
13946    pub expression: Box<Expression>,
13947    pub unit: String,
13948    #[serde(default)]
13949    pub kind: Option<String>,
13950}
13951
13952/// TimeAdd
13953#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13954#[cfg_attr(feature = "bindings", derive(TS))]
13955pub struct TimeAdd {
13956    pub this: Box<Expression>,
13957    pub expression: Box<Expression>,
13958    #[serde(default)]
13959    pub unit: Option<String>,
13960}
13961
13962/// TimeSub
13963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13964#[cfg_attr(feature = "bindings", derive(TS))]
13965pub struct TimeSub {
13966    pub this: Box<Expression>,
13967    pub expression: Box<Expression>,
13968    #[serde(default)]
13969    pub unit: Option<String>,
13970}
13971
13972/// TimeDiff
13973#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13974#[cfg_attr(feature = "bindings", derive(TS))]
13975pub struct TimeDiff {
13976    pub this: Box<Expression>,
13977    pub expression: Box<Expression>,
13978    #[serde(default)]
13979    pub unit: Option<String>,
13980}
13981
13982/// TimeTrunc
13983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13984#[cfg_attr(feature = "bindings", derive(TS))]
13985pub struct TimeTrunc {
13986    pub this: Box<Expression>,
13987    pub unit: String,
13988    #[serde(default)]
13989    pub zone: Option<Box<Expression>>,
13990}
13991
13992/// DateFromParts
13993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13994#[cfg_attr(feature = "bindings", derive(TS))]
13995pub struct DateFromParts {
13996    #[serde(default)]
13997    pub year: Option<Box<Expression>>,
13998    #[serde(default)]
13999    pub month: Option<Box<Expression>>,
14000    #[serde(default)]
14001    pub day: Option<Box<Expression>>,
14002    #[serde(default)]
14003    pub allow_overflow: Option<Box<Expression>>,
14004}
14005
14006/// TimeFromParts
14007#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14008#[cfg_attr(feature = "bindings", derive(TS))]
14009pub struct TimeFromParts {
14010    #[serde(default)]
14011    pub hour: Option<Box<Expression>>,
14012    #[serde(default)]
14013    pub min: Option<Box<Expression>>,
14014    #[serde(default)]
14015    pub sec: Option<Box<Expression>>,
14016    #[serde(default)]
14017    pub nano: Option<Box<Expression>>,
14018    #[serde(default)]
14019    pub fractions: Option<Box<Expression>>,
14020    #[serde(default)]
14021    pub precision: Option<i64>,
14022}
14023
14024/// DecodeCase
14025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14026#[cfg_attr(feature = "bindings", derive(TS))]
14027pub struct DecodeCase {
14028    #[serde(default)]
14029    pub expressions: Vec<Expression>,
14030}
14031
14032/// Decrypt
14033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14034#[cfg_attr(feature = "bindings", derive(TS))]
14035pub struct Decrypt {
14036    pub this: Box<Expression>,
14037    #[serde(default)]
14038    pub passphrase: Option<Box<Expression>>,
14039    #[serde(default)]
14040    pub aad: Option<Box<Expression>>,
14041    #[serde(default)]
14042    pub encryption_method: Option<Box<Expression>>,
14043    #[serde(default)]
14044    pub safe: Option<Box<Expression>>,
14045}
14046
14047/// DecryptRaw
14048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14049#[cfg_attr(feature = "bindings", derive(TS))]
14050pub struct DecryptRaw {
14051    pub this: Box<Expression>,
14052    #[serde(default)]
14053    pub key: Option<Box<Expression>>,
14054    #[serde(default)]
14055    pub iv: Option<Box<Expression>>,
14056    #[serde(default)]
14057    pub aad: Option<Box<Expression>>,
14058    #[serde(default)]
14059    pub encryption_method: Option<Box<Expression>>,
14060    #[serde(default)]
14061    pub aead: Option<Box<Expression>>,
14062    #[serde(default)]
14063    pub safe: Option<Box<Expression>>,
14064}
14065
14066/// Encode
14067#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14068#[cfg_attr(feature = "bindings", derive(TS))]
14069pub struct Encode {
14070    pub this: Box<Expression>,
14071    #[serde(default)]
14072    pub charset: Option<Box<Expression>>,
14073}
14074
14075/// Encrypt
14076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14077#[cfg_attr(feature = "bindings", derive(TS))]
14078pub struct Encrypt {
14079    pub this: Box<Expression>,
14080    #[serde(default)]
14081    pub passphrase: Option<Box<Expression>>,
14082    #[serde(default)]
14083    pub aad: Option<Box<Expression>>,
14084    #[serde(default)]
14085    pub encryption_method: Option<Box<Expression>>,
14086}
14087
14088/// EncryptRaw
14089#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14090#[cfg_attr(feature = "bindings", derive(TS))]
14091pub struct EncryptRaw {
14092    pub this: Box<Expression>,
14093    #[serde(default)]
14094    pub key: Option<Box<Expression>>,
14095    #[serde(default)]
14096    pub iv: Option<Box<Expression>>,
14097    #[serde(default)]
14098    pub aad: Option<Box<Expression>>,
14099    #[serde(default)]
14100    pub encryption_method: Option<Box<Expression>>,
14101}
14102
14103/// EqualNull
14104#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14105#[cfg_attr(feature = "bindings", derive(TS))]
14106pub struct EqualNull {
14107    pub this: Box<Expression>,
14108    pub expression: Box<Expression>,
14109}
14110
14111/// ToBinary
14112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14113#[cfg_attr(feature = "bindings", derive(TS))]
14114pub struct ToBinary {
14115    pub this: Box<Expression>,
14116    #[serde(default)]
14117    pub format: Option<String>,
14118    #[serde(default)]
14119    pub safe: Option<Box<Expression>>,
14120}
14121
14122/// Base64DecodeBinary
14123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14124#[cfg_attr(feature = "bindings", derive(TS))]
14125pub struct Base64DecodeBinary {
14126    pub this: Box<Expression>,
14127    #[serde(default)]
14128    pub alphabet: Option<Box<Expression>>,
14129}
14130
14131/// Base64DecodeString
14132#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14133#[cfg_attr(feature = "bindings", derive(TS))]
14134pub struct Base64DecodeString {
14135    pub this: Box<Expression>,
14136    #[serde(default)]
14137    pub alphabet: Option<Box<Expression>>,
14138}
14139
14140/// Base64Encode
14141#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14142#[cfg_attr(feature = "bindings", derive(TS))]
14143pub struct Base64Encode {
14144    pub this: Box<Expression>,
14145    #[serde(default)]
14146    pub max_line_length: Option<Box<Expression>>,
14147    #[serde(default)]
14148    pub alphabet: Option<Box<Expression>>,
14149}
14150
14151/// TryBase64DecodeBinary
14152#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14153#[cfg_attr(feature = "bindings", derive(TS))]
14154pub struct TryBase64DecodeBinary {
14155    pub this: Box<Expression>,
14156    #[serde(default)]
14157    pub alphabet: Option<Box<Expression>>,
14158}
14159
14160/// TryBase64DecodeString
14161#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14162#[cfg_attr(feature = "bindings", derive(TS))]
14163pub struct TryBase64DecodeString {
14164    pub this: Box<Expression>,
14165    #[serde(default)]
14166    pub alphabet: Option<Box<Expression>>,
14167}
14168
14169/// GapFill
14170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14171#[cfg_attr(feature = "bindings", derive(TS))]
14172pub struct GapFill {
14173    pub this: Box<Expression>,
14174    #[serde(default)]
14175    pub ts_column: Option<Box<Expression>>,
14176    #[serde(default)]
14177    pub bucket_width: Option<Box<Expression>>,
14178    #[serde(default)]
14179    pub partitioning_columns: Option<Box<Expression>>,
14180    #[serde(default)]
14181    pub value_columns: Option<Box<Expression>>,
14182    #[serde(default)]
14183    pub origin: Option<Box<Expression>>,
14184    #[serde(default)]
14185    pub ignore_nulls: Option<Box<Expression>>,
14186}
14187
14188/// GenerateDateArray
14189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14190#[cfg_attr(feature = "bindings", derive(TS))]
14191pub struct GenerateDateArray {
14192    #[serde(default)]
14193    pub start: Option<Box<Expression>>,
14194    #[serde(default)]
14195    pub end: Option<Box<Expression>>,
14196    #[serde(default)]
14197    pub step: Option<Box<Expression>>,
14198}
14199
14200/// GenerateTimestampArray
14201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14202#[cfg_attr(feature = "bindings", derive(TS))]
14203pub struct GenerateTimestampArray {
14204    #[serde(default)]
14205    pub start: Option<Box<Expression>>,
14206    #[serde(default)]
14207    pub end: Option<Box<Expression>>,
14208    #[serde(default)]
14209    pub step: Option<Box<Expression>>,
14210}
14211
14212/// GetExtract
14213#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14214#[cfg_attr(feature = "bindings", derive(TS))]
14215pub struct GetExtract {
14216    pub this: Box<Expression>,
14217    pub expression: Box<Expression>,
14218}
14219
14220/// Getbit
14221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14222#[cfg_attr(feature = "bindings", derive(TS))]
14223pub struct Getbit {
14224    pub this: Box<Expression>,
14225    pub expression: Box<Expression>,
14226    #[serde(default)]
14227    pub zero_is_msb: Option<Box<Expression>>,
14228}
14229
14230/// OverflowTruncateBehavior
14231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14232#[cfg_attr(feature = "bindings", derive(TS))]
14233pub struct OverflowTruncateBehavior {
14234    #[serde(default)]
14235    pub this: Option<Box<Expression>>,
14236    #[serde(default)]
14237    pub with_count: Option<Box<Expression>>,
14238}
14239
14240/// HexEncode
14241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14242#[cfg_attr(feature = "bindings", derive(TS))]
14243pub struct HexEncode {
14244    pub this: Box<Expression>,
14245    #[serde(default)]
14246    pub case: Option<Box<Expression>>,
14247}
14248
14249/// Compress
14250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14251#[cfg_attr(feature = "bindings", derive(TS))]
14252pub struct Compress {
14253    pub this: Box<Expression>,
14254    #[serde(default)]
14255    pub method: Option<String>,
14256}
14257
14258/// DecompressBinary
14259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14260#[cfg_attr(feature = "bindings", derive(TS))]
14261pub struct DecompressBinary {
14262    pub this: Box<Expression>,
14263    pub method: String,
14264}
14265
14266/// DecompressString
14267#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14268#[cfg_attr(feature = "bindings", derive(TS))]
14269pub struct DecompressString {
14270    pub this: Box<Expression>,
14271    pub method: String,
14272}
14273
14274/// Xor
14275#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14276#[cfg_attr(feature = "bindings", derive(TS))]
14277pub struct Xor {
14278    #[serde(default)]
14279    pub this: Option<Box<Expression>>,
14280    #[serde(default)]
14281    pub expression: Option<Box<Expression>>,
14282    #[serde(default)]
14283    pub expressions: Vec<Expression>,
14284}
14285
14286/// Nullif
14287#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14288#[cfg_attr(feature = "bindings", derive(TS))]
14289pub struct Nullif {
14290    pub this: Box<Expression>,
14291    pub expression: Box<Expression>,
14292}
14293
14294/// JSON
14295#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14296#[cfg_attr(feature = "bindings", derive(TS))]
14297pub struct JSON {
14298    #[serde(default)]
14299    pub this: Option<Box<Expression>>,
14300    #[serde(default)]
14301    pub with_: Option<Box<Expression>>,
14302    #[serde(default)]
14303    pub unique: bool,
14304}
14305
14306/// JSONPath
14307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14308#[cfg_attr(feature = "bindings", derive(TS))]
14309pub struct JSONPath {
14310    #[serde(default)]
14311    pub expressions: Vec<Expression>,
14312    #[serde(default)]
14313    pub escape: Option<Box<Expression>>,
14314}
14315
14316/// JSONPathFilter
14317#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14318#[cfg_attr(feature = "bindings", derive(TS))]
14319pub struct JSONPathFilter {
14320    pub this: Box<Expression>,
14321}
14322
14323/// JSONPathKey
14324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14325#[cfg_attr(feature = "bindings", derive(TS))]
14326pub struct JSONPathKey {
14327    pub this: Box<Expression>,
14328}
14329
14330/// JSONPathRecursive
14331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14332#[cfg_attr(feature = "bindings", derive(TS))]
14333pub struct JSONPathRecursive {
14334    #[serde(default)]
14335    pub this: Option<Box<Expression>>,
14336}
14337
14338/// JSONPathScript
14339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14340#[cfg_attr(feature = "bindings", derive(TS))]
14341pub struct JSONPathScript {
14342    pub this: Box<Expression>,
14343}
14344
14345/// JSONPathSlice
14346#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14347#[cfg_attr(feature = "bindings", derive(TS))]
14348pub struct JSONPathSlice {
14349    #[serde(default)]
14350    pub start: Option<Box<Expression>>,
14351    #[serde(default)]
14352    pub end: Option<Box<Expression>>,
14353    #[serde(default)]
14354    pub step: Option<Box<Expression>>,
14355}
14356
14357/// JSONPathSelector
14358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14359#[cfg_attr(feature = "bindings", derive(TS))]
14360pub struct JSONPathSelector {
14361    pub this: Box<Expression>,
14362}
14363
14364/// JSONPathSubscript
14365#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14366#[cfg_attr(feature = "bindings", derive(TS))]
14367pub struct JSONPathSubscript {
14368    pub this: Box<Expression>,
14369}
14370
14371/// JSONPathUnion
14372#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14373#[cfg_attr(feature = "bindings", derive(TS))]
14374pub struct JSONPathUnion {
14375    #[serde(default)]
14376    pub expressions: Vec<Expression>,
14377}
14378
14379/// Format
14380#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14381#[cfg_attr(feature = "bindings", derive(TS))]
14382pub struct Format {
14383    pub this: Box<Expression>,
14384    #[serde(default)]
14385    pub expressions: Vec<Expression>,
14386}
14387
14388/// JSONKeys
14389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14390#[cfg_attr(feature = "bindings", derive(TS))]
14391pub struct JSONKeys {
14392    pub this: Box<Expression>,
14393    #[serde(default)]
14394    pub expression: Option<Box<Expression>>,
14395    #[serde(default)]
14396    pub expressions: Vec<Expression>,
14397}
14398
14399/// JSONKeyValue
14400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14401#[cfg_attr(feature = "bindings", derive(TS))]
14402pub struct JSONKeyValue {
14403    pub this: Box<Expression>,
14404    pub expression: Box<Expression>,
14405}
14406
14407/// JSONKeysAtDepth
14408#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14409#[cfg_attr(feature = "bindings", derive(TS))]
14410pub struct JSONKeysAtDepth {
14411    pub this: Box<Expression>,
14412    #[serde(default)]
14413    pub expression: Option<Box<Expression>>,
14414    #[serde(default)]
14415    pub mode: Option<Box<Expression>>,
14416}
14417
14418/// JSONObject
14419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14420#[cfg_attr(feature = "bindings", derive(TS))]
14421pub struct JSONObject {
14422    #[serde(default)]
14423    pub expressions: Vec<Expression>,
14424    #[serde(default)]
14425    pub null_handling: Option<Box<Expression>>,
14426    #[serde(default)]
14427    pub unique_keys: Option<Box<Expression>>,
14428    #[serde(default)]
14429    pub return_type: Option<Box<Expression>>,
14430    #[serde(default)]
14431    pub encoding: Option<Box<Expression>>,
14432}
14433
14434/// JSONObjectAgg
14435#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14436#[cfg_attr(feature = "bindings", derive(TS))]
14437pub struct JSONObjectAgg {
14438    #[serde(default)]
14439    pub expressions: Vec<Expression>,
14440    #[serde(default)]
14441    pub null_handling: Option<Box<Expression>>,
14442    #[serde(default)]
14443    pub unique_keys: Option<Box<Expression>>,
14444    #[serde(default)]
14445    pub return_type: Option<Box<Expression>>,
14446    #[serde(default)]
14447    pub encoding: Option<Box<Expression>>,
14448}
14449
14450/// JSONBObjectAgg
14451#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14452#[cfg_attr(feature = "bindings", derive(TS))]
14453pub struct JSONBObjectAgg {
14454    pub this: Box<Expression>,
14455    pub expression: Box<Expression>,
14456}
14457
14458/// JSONArray
14459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14460#[cfg_attr(feature = "bindings", derive(TS))]
14461pub struct JSONArray {
14462    #[serde(default)]
14463    pub expressions: Vec<Expression>,
14464    #[serde(default)]
14465    pub null_handling: Option<Box<Expression>>,
14466    #[serde(default)]
14467    pub return_type: Option<Box<Expression>>,
14468    #[serde(default)]
14469    pub strict: Option<Box<Expression>>,
14470}
14471
14472/// JSONArrayAgg
14473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14474#[cfg_attr(feature = "bindings", derive(TS))]
14475pub struct JSONArrayAgg {
14476    pub this: Box<Expression>,
14477    #[serde(default)]
14478    pub order: Option<Box<Expression>>,
14479    #[serde(default)]
14480    pub null_handling: Option<Box<Expression>>,
14481    #[serde(default)]
14482    pub return_type: Option<Box<Expression>>,
14483    #[serde(default)]
14484    pub strict: Option<Box<Expression>>,
14485}
14486
14487/// JSONExists
14488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14489#[cfg_attr(feature = "bindings", derive(TS))]
14490pub struct JSONExists {
14491    pub this: Box<Expression>,
14492    #[serde(default)]
14493    pub path: Option<Box<Expression>>,
14494    #[serde(default)]
14495    pub passing: Option<Box<Expression>>,
14496    #[serde(default)]
14497    pub on_condition: Option<Box<Expression>>,
14498    #[serde(default)]
14499    pub from_dcolonqmark: Option<Box<Expression>>,
14500}
14501
14502/// JSONColumnDef
14503#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14504#[cfg_attr(feature = "bindings", derive(TS))]
14505pub struct JSONColumnDef {
14506    /// Typed column definition; legacy dialects may use the textual kind field.
14507    #[serde(default, skip_serializing_if = "Option::is_none")]
14508    pub data_type: Option<DataType>,
14509    #[serde(default, skip_serializing_if = "Option::is_none")]
14510    pub encoding: Option<String>,
14511    #[serde(default, skip_serializing_if = "Option::is_none")]
14512    #[ast(skip)]
14513    pub source_dialect: Option<crate::dialects::DialectType>,
14514    /// Structured SQL/JSON wrapper and error/empty behavior.
14515    #[serde(default, skip_serializing_if = "Option::is_none")]
14516    pub options: Option<JsonOptions>,
14517
14518    #[serde(default)]
14519    pub this: Option<Box<Expression>>,
14520    #[serde(default)]
14521    pub kind: Option<String>,
14522    #[serde(default)]
14523    pub format_json: bool,
14524    #[serde(default)]
14525    pub path: Option<Box<Expression>>,
14526    #[serde(default)]
14527    pub nested_schema: Option<Box<Expression>>,
14528    #[serde(default)]
14529    pub ordinality: Option<Box<Expression>>,
14530}
14531
14532/// JSONSchema
14533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14534#[cfg_attr(feature = "bindings", derive(TS))]
14535pub struct JSONSchema {
14536    #[serde(default)]
14537    pub expressions: Vec<Expression>,
14538}
14539
14540/// JSONSet
14541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14542#[cfg_attr(feature = "bindings", derive(TS))]
14543pub struct JSONSet {
14544    pub this: Box<Expression>,
14545    #[serde(default)]
14546    pub expressions: Vec<Expression>,
14547}
14548
14549/// JSONStripNulls
14550#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14551#[cfg_attr(feature = "bindings", derive(TS))]
14552pub struct JSONStripNulls {
14553    pub this: Box<Expression>,
14554    #[serde(default)]
14555    pub expression: Option<Box<Expression>>,
14556    #[serde(default)]
14557    pub include_arrays: Option<Box<Expression>>,
14558    #[serde(default)]
14559    pub remove_empty: Option<Box<Expression>>,
14560}
14561
14562/// JSONValue
14563#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14564#[cfg_attr(feature = "bindings", derive(TS))]
14565pub struct JSONValue {
14566    #[serde(default, skip_serializing_if = "Option::is_none")]
14567    #[ast(skip)]
14568    pub source_dialect: Option<crate::dialects::DialectType>,
14569    /// Structured SQL/JSON wrapper and error/empty behavior.
14570    #[serde(default, skip_serializing_if = "Option::is_none")]
14571    pub options: Option<JsonOptions>,
14572
14573    pub this: Box<Expression>,
14574    #[serde(default)]
14575    pub path: Option<Box<Expression>>,
14576    #[serde(default)]
14577    pub returning: Option<Box<Expression>>,
14578    #[serde(default)]
14579    pub on_condition: Option<Box<Expression>>,
14580}
14581
14582/// JSONValueArray
14583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14584#[cfg_attr(feature = "bindings", derive(TS))]
14585pub struct JSONValueArray {
14586    pub this: Box<Expression>,
14587    #[serde(default)]
14588    pub expression: Option<Box<Expression>>,
14589}
14590
14591/// JSONRemove
14592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14593#[cfg_attr(feature = "bindings", derive(TS))]
14594pub struct JSONRemove {
14595    pub this: Box<Expression>,
14596    #[serde(default)]
14597    pub expressions: Vec<Expression>,
14598}
14599
14600/// JSONTable
14601#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14602#[cfg_attr(feature = "bindings", derive(TS))]
14603pub struct JSONTable {
14604    #[serde(default, skip_serializing_if = "Option::is_none")]
14605    #[ast(skip)]
14606    pub source_dialect: Option<crate::dialects::DialectType>,
14607    /// Structured SQL/JSON wrapper and error/empty behavior.
14608    #[serde(default, skip_serializing_if = "Option::is_none")]
14609    pub options: Option<JsonOptions>,
14610
14611    pub this: Box<Expression>,
14612    #[serde(default)]
14613    pub schema: Option<Box<Expression>>,
14614    #[serde(default)]
14615    pub path: Option<Box<Expression>>,
14616    #[serde(default)]
14617    pub error_handling: Option<Box<Expression>>,
14618    #[serde(default)]
14619    pub empty_handling: Option<Box<Expression>>,
14620}
14621
14622/// JSONType
14623#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14624#[cfg_attr(feature = "bindings", derive(TS))]
14625pub struct JSONType {
14626    pub this: Box<Expression>,
14627    #[serde(default)]
14628    pub expression: Option<Box<Expression>>,
14629}
14630
14631/// ObjectInsert
14632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14633#[cfg_attr(feature = "bindings", derive(TS))]
14634pub struct ObjectInsert {
14635    pub this: Box<Expression>,
14636    #[serde(default)]
14637    pub key: Option<Box<Expression>>,
14638    #[serde(default)]
14639    pub value: Option<Box<Expression>>,
14640    #[serde(default)]
14641    pub update_flag: Option<Box<Expression>>,
14642}
14643
14644/// OpenJSONColumnDef
14645#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14646#[cfg_attr(feature = "bindings", derive(TS))]
14647pub struct OpenJSONColumnDef {
14648    pub this: Box<Expression>,
14649    pub kind: String,
14650    #[serde(default)]
14651    pub path: Option<Box<Expression>>,
14652    #[serde(default)]
14653    pub as_json: Option<Box<Expression>>,
14654    /// The parsed data type for proper generation
14655    #[serde(default, skip_serializing_if = "Option::is_none")]
14656    pub data_type: Option<DataType>,
14657}
14658
14659/// OpenJSON
14660#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14661#[cfg_attr(feature = "bindings", derive(TS))]
14662pub struct OpenJSON {
14663    pub this: Box<Expression>,
14664    #[serde(default)]
14665    pub path: Option<Box<Expression>>,
14666    #[serde(default)]
14667    pub expressions: Vec<Expression>,
14668}
14669
14670/// JSONBExists
14671#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14672#[cfg_attr(feature = "bindings", derive(TS))]
14673pub struct JSONBExists {
14674    pub this: Box<Expression>,
14675    #[serde(default)]
14676    pub path: Option<Box<Expression>>,
14677}
14678
14679/// JSONCast
14680#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14681#[cfg_attr(feature = "bindings", derive(TS))]
14682pub struct JSONCast {
14683    pub this: Box<Expression>,
14684    pub to: DataType,
14685}
14686
14687/// JSONExtract
14688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14689#[cfg_attr(feature = "bindings", derive(TS))]
14690pub struct JSONExtract {
14691    pub this: Box<Expression>,
14692    pub expression: Box<Expression>,
14693    #[serde(default)]
14694    pub only_json_types: Option<Box<Expression>>,
14695    #[serde(default)]
14696    pub expressions: Vec<Expression>,
14697    #[serde(default)]
14698    pub variant_extract: Option<Box<Expression>>,
14699    #[serde(default)]
14700    pub json_query: Option<Box<Expression>>,
14701    #[serde(default)]
14702    pub option: Option<Box<Expression>>,
14703    #[serde(default)]
14704    pub quote: Option<Box<Expression>>,
14705    #[serde(default)]
14706    pub on_condition: Option<Box<Expression>>,
14707    #[serde(default)]
14708    pub requires_json: Option<Box<Expression>>,
14709}
14710
14711/// JSONExtractQuote
14712#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14713#[cfg_attr(feature = "bindings", derive(TS))]
14714pub struct JSONExtractQuote {
14715    #[serde(default)]
14716    pub option: Option<Box<Expression>>,
14717    #[serde(default)]
14718    pub scalar: Option<Box<Expression>>,
14719}
14720
14721/// JSONExtractArray
14722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14723#[cfg_attr(feature = "bindings", derive(TS))]
14724pub struct JSONExtractArray {
14725    pub this: Box<Expression>,
14726    #[serde(default)]
14727    pub expression: Option<Box<Expression>>,
14728}
14729
14730/// JSONExtractScalar
14731#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14732#[cfg_attr(feature = "bindings", derive(TS))]
14733pub struct JSONExtractScalar {
14734    pub this: Box<Expression>,
14735    pub expression: Box<Expression>,
14736    #[serde(default)]
14737    pub only_json_types: Option<Box<Expression>>,
14738    #[serde(default)]
14739    pub expressions: Vec<Expression>,
14740    #[serde(default)]
14741    pub json_type: Option<Box<Expression>>,
14742    #[serde(default)]
14743    pub scalar_only: Option<Box<Expression>>,
14744}
14745
14746/// JSONBExtractScalar
14747#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14748#[cfg_attr(feature = "bindings", derive(TS))]
14749pub struct JSONBExtractScalar {
14750    pub this: Box<Expression>,
14751    pub expression: Box<Expression>,
14752    #[serde(default)]
14753    pub json_type: Option<Box<Expression>>,
14754}
14755
14756/// JSONFormat
14757#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14758#[cfg_attr(feature = "bindings", derive(TS))]
14759pub struct JSONFormat {
14760    #[serde(default)]
14761    pub this: Option<Box<Expression>>,
14762    #[serde(default)]
14763    pub options: Vec<Expression>,
14764    #[serde(default)]
14765    pub is_json: Option<Box<Expression>>,
14766    #[serde(default)]
14767    pub to_json: Option<Box<Expression>>,
14768}
14769
14770/// JSONArrayAppend
14771#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14772#[cfg_attr(feature = "bindings", derive(TS))]
14773pub struct JSONArrayAppend {
14774    pub this: Box<Expression>,
14775    #[serde(default)]
14776    pub expressions: Vec<Expression>,
14777}
14778
14779/// JSONArrayContains
14780#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14781#[cfg_attr(feature = "bindings", derive(TS))]
14782pub struct JSONArrayContains {
14783    pub this: Box<Expression>,
14784    pub expression: Box<Expression>,
14785    #[serde(default)]
14786    pub json_type: Option<Box<Expression>>,
14787}
14788
14789/// JSONArrayInsert
14790#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14791#[cfg_attr(feature = "bindings", derive(TS))]
14792pub struct JSONArrayInsert {
14793    pub this: Box<Expression>,
14794    #[serde(default)]
14795    pub expressions: Vec<Expression>,
14796}
14797
14798/// ParseJSON
14799#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14800#[cfg_attr(feature = "bindings", derive(TS))]
14801pub struct ParseJSON {
14802    pub this: Box<Expression>,
14803    #[serde(default)]
14804    pub expression: Option<Box<Expression>>,
14805    #[serde(default)]
14806    pub safe: Option<Box<Expression>>,
14807}
14808
14809/// ParseUrl
14810#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14811#[cfg_attr(feature = "bindings", derive(TS))]
14812pub struct ParseUrl {
14813    pub this: Box<Expression>,
14814    #[serde(default)]
14815    pub part_to_extract: Option<Box<Expression>>,
14816    #[serde(default)]
14817    pub key: Option<Box<Expression>>,
14818    #[serde(default)]
14819    pub permissive: Option<Box<Expression>>,
14820}
14821
14822/// ParseIp
14823#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14824#[cfg_attr(feature = "bindings", derive(TS))]
14825pub struct ParseIp {
14826    pub this: Box<Expression>,
14827    #[serde(default)]
14828    pub type_: Option<Box<Expression>>,
14829    #[serde(default)]
14830    pub permissive: Option<Box<Expression>>,
14831}
14832
14833/// ParseTime
14834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14835#[cfg_attr(feature = "bindings", derive(TS))]
14836pub struct ParseTime {
14837    pub this: Box<Expression>,
14838    pub format: String,
14839}
14840
14841/// ParseDatetime
14842#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14843#[cfg_attr(feature = "bindings", derive(TS))]
14844pub struct ParseDatetime {
14845    pub this: Box<Expression>,
14846    #[serde(default)]
14847    pub format: Option<String>,
14848    #[serde(default)]
14849    pub zone: Option<Box<Expression>>,
14850}
14851
14852/// Map
14853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14854#[cfg_attr(feature = "bindings", derive(TS))]
14855pub struct Map {
14856    #[serde(default)]
14857    pub keys: Vec<Expression>,
14858    #[serde(default)]
14859    pub values: Vec<Expression>,
14860}
14861
14862/// MapCat
14863#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14864#[cfg_attr(feature = "bindings", derive(TS))]
14865pub struct MapCat {
14866    pub this: Box<Expression>,
14867    pub expression: Box<Expression>,
14868}
14869
14870/// MapDelete
14871#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14872#[cfg_attr(feature = "bindings", derive(TS))]
14873pub struct MapDelete {
14874    pub this: Box<Expression>,
14875    #[serde(default)]
14876    pub expressions: Vec<Expression>,
14877}
14878
14879/// MapInsert
14880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14881#[cfg_attr(feature = "bindings", derive(TS))]
14882pub struct MapInsert {
14883    pub this: Box<Expression>,
14884    #[serde(default)]
14885    pub key: Option<Box<Expression>>,
14886    #[serde(default)]
14887    pub value: Option<Box<Expression>>,
14888    #[serde(default)]
14889    pub update_flag: Option<Box<Expression>>,
14890}
14891
14892/// MapPick
14893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14894#[cfg_attr(feature = "bindings", derive(TS))]
14895pub struct MapPick {
14896    pub this: Box<Expression>,
14897    #[serde(default)]
14898    pub expressions: Vec<Expression>,
14899}
14900
14901/// ScopeResolution
14902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14903#[cfg_attr(feature = "bindings", derive(TS))]
14904pub struct ScopeResolution {
14905    #[serde(default)]
14906    pub this: Option<Box<Expression>>,
14907    pub expression: Box<Expression>,
14908}
14909
14910/// Slice
14911#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14912#[cfg_attr(feature = "bindings", derive(TS))]
14913pub struct Slice {
14914    #[serde(default)]
14915    pub this: Option<Box<Expression>>,
14916    #[serde(default)]
14917    pub expression: Option<Box<Expression>>,
14918    #[serde(default)]
14919    pub step: Option<Box<Expression>>,
14920}
14921
14922/// VarMap
14923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14924#[cfg_attr(feature = "bindings", derive(TS))]
14925pub struct VarMap {
14926    #[serde(default)]
14927    pub keys: Vec<Expression>,
14928    #[serde(default)]
14929    pub values: Vec<Expression>,
14930}
14931
14932/// MatchAgainst
14933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14934#[cfg_attr(feature = "bindings", derive(TS))]
14935pub struct MatchAgainst {
14936    pub this: Box<Expression>,
14937    #[serde(default)]
14938    pub expressions: Vec<Expression>,
14939    #[serde(default)]
14940    pub modifier: Option<Box<Expression>>,
14941}
14942
14943/// MD5Digest
14944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14945#[cfg_attr(feature = "bindings", derive(TS))]
14946pub struct MD5Digest {
14947    pub this: Box<Expression>,
14948    #[serde(default)]
14949    pub expressions: Vec<Expression>,
14950}
14951
14952/// Monthname
14953#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14954#[cfg_attr(feature = "bindings", derive(TS))]
14955pub struct Monthname {
14956    pub this: Box<Expression>,
14957    #[serde(default)]
14958    pub abbreviated: Option<Box<Expression>>,
14959}
14960
14961/// Ntile
14962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14963#[cfg_attr(feature = "bindings", derive(TS))]
14964pub struct Ntile {
14965    #[serde(default)]
14966    pub this: Option<Box<Expression>>,
14967}
14968
14969/// Normalize
14970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14971#[cfg_attr(feature = "bindings", derive(TS))]
14972pub struct Normalize {
14973    pub this: Box<Expression>,
14974    #[serde(default)]
14975    pub form: Option<Box<Expression>>,
14976    #[serde(default)]
14977    pub is_casefold: Option<Box<Expression>>,
14978}
14979
14980/// Normal
14981#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14982#[cfg_attr(feature = "bindings", derive(TS))]
14983pub struct Normal {
14984    pub this: Box<Expression>,
14985    #[serde(default)]
14986    pub stddev: Option<Box<Expression>>,
14987    #[serde(default)]
14988    pub gen: Option<Box<Expression>>,
14989}
14990
14991/// Predict
14992#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14993#[cfg_attr(feature = "bindings", derive(TS))]
14994pub struct Predict {
14995    pub this: Box<Expression>,
14996    pub expression: Box<Expression>,
14997    #[serde(default)]
14998    pub params_struct: Option<Box<Expression>>,
14999}
15000
15001/// MLTranslate
15002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15003#[cfg_attr(feature = "bindings", derive(TS))]
15004pub struct MLTranslate {
15005    pub this: Box<Expression>,
15006    pub expression: Box<Expression>,
15007    #[serde(default)]
15008    pub params_struct: Option<Box<Expression>>,
15009}
15010
15011/// FeaturesAtTime
15012#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15013#[cfg_attr(feature = "bindings", derive(TS))]
15014pub struct FeaturesAtTime {
15015    pub this: Box<Expression>,
15016    #[serde(default)]
15017    pub time: Option<Box<Expression>>,
15018    #[serde(default)]
15019    pub num_rows: Option<Box<Expression>>,
15020    #[serde(default)]
15021    pub ignore_feature_nulls: Option<Box<Expression>>,
15022}
15023
15024/// GenerateEmbedding
15025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15026#[cfg_attr(feature = "bindings", derive(TS))]
15027pub struct GenerateEmbedding {
15028    pub this: Box<Expression>,
15029    pub expression: Box<Expression>,
15030    #[serde(default)]
15031    pub params_struct: Option<Box<Expression>>,
15032    #[serde(default)]
15033    pub is_text: Option<Box<Expression>>,
15034}
15035
15036/// MLForecast
15037#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15038#[cfg_attr(feature = "bindings", derive(TS))]
15039pub struct MLForecast {
15040    pub this: Box<Expression>,
15041    #[serde(default)]
15042    pub expression: Option<Box<Expression>>,
15043    #[serde(default)]
15044    pub params_struct: Option<Box<Expression>>,
15045}
15046
15047/// ModelAttribute
15048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15049#[cfg_attr(feature = "bindings", derive(TS))]
15050pub struct ModelAttribute {
15051    pub this: Box<Expression>,
15052    pub expression: Box<Expression>,
15053}
15054
15055/// VectorSearch
15056#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15057#[cfg_attr(feature = "bindings", derive(TS))]
15058pub struct VectorSearch {
15059    pub this: Box<Expression>,
15060    #[serde(default)]
15061    pub column_to_search: Option<Box<Expression>>,
15062    #[serde(default)]
15063    pub query_table: Option<Box<Expression>>,
15064    #[serde(default)]
15065    pub query_column_to_search: Option<Box<Expression>>,
15066    #[serde(default)]
15067    pub top_k: Option<Box<Expression>>,
15068    #[serde(default)]
15069    pub distance_type: Option<Box<Expression>>,
15070    #[serde(default)]
15071    pub options: Vec<Expression>,
15072}
15073
15074/// Quantile
15075#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15076#[cfg_attr(feature = "bindings", derive(TS))]
15077pub struct Quantile {
15078    pub this: Box<Expression>,
15079    #[serde(default)]
15080    pub quantile: Option<Box<Expression>>,
15081}
15082
15083/// ApproxQuantile
15084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15085#[cfg_attr(feature = "bindings", derive(TS))]
15086pub struct ApproxQuantile {
15087    pub this: Box<Expression>,
15088    #[serde(default)]
15089    pub quantile: Option<Box<Expression>>,
15090    #[serde(default)]
15091    pub accuracy: Option<Box<Expression>>,
15092    #[serde(default)]
15093    pub weight: Option<Box<Expression>>,
15094    #[serde(default)]
15095    pub error_tolerance: Option<Box<Expression>>,
15096}
15097
15098/// ApproxPercentileEstimate
15099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15100#[cfg_attr(feature = "bindings", derive(TS))]
15101pub struct ApproxPercentileEstimate {
15102    pub this: Box<Expression>,
15103    #[serde(default)]
15104    pub percentile: Option<Box<Expression>>,
15105}
15106
15107/// Randn
15108#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15109#[cfg_attr(feature = "bindings", derive(TS))]
15110pub struct Randn {
15111    #[serde(default)]
15112    pub this: Option<Box<Expression>>,
15113}
15114
15115/// Randstr
15116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15117#[cfg_attr(feature = "bindings", derive(TS))]
15118pub struct Randstr {
15119    pub this: Box<Expression>,
15120    #[serde(default)]
15121    pub generator: Option<Box<Expression>>,
15122}
15123
15124/// RangeN
15125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15126#[cfg_attr(feature = "bindings", derive(TS))]
15127pub struct RangeN {
15128    pub this: Box<Expression>,
15129    #[serde(default)]
15130    pub expressions: Vec<Expression>,
15131    #[serde(default)]
15132    pub each: Option<Box<Expression>>,
15133}
15134
15135/// RangeBucket
15136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15137#[cfg_attr(feature = "bindings", derive(TS))]
15138pub struct RangeBucket {
15139    pub this: Box<Expression>,
15140    pub expression: Box<Expression>,
15141}
15142
15143/// ReadCSV
15144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15145#[cfg_attr(feature = "bindings", derive(TS))]
15146pub struct ReadCSV {
15147    pub this: Box<Expression>,
15148    #[serde(default)]
15149    pub expressions: Vec<Expression>,
15150}
15151
15152/// ReadParquet
15153#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15154#[cfg_attr(feature = "bindings", derive(TS))]
15155pub struct ReadParquet {
15156    #[serde(default)]
15157    pub expressions: Vec<Expression>,
15158}
15159
15160/// Reduce
15161#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15162#[cfg_attr(feature = "bindings", derive(TS))]
15163pub struct Reduce {
15164    pub this: Box<Expression>,
15165    #[serde(default)]
15166    pub initial: Option<Box<Expression>>,
15167    #[serde(default)]
15168    pub merge: Option<Box<Expression>>,
15169    #[serde(default)]
15170    pub finish: Option<Box<Expression>>,
15171}
15172
15173/// RegexpExtractAll
15174#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15175#[cfg_attr(feature = "bindings", derive(TS))]
15176pub struct RegexpExtractAll {
15177    pub this: Box<Expression>,
15178    pub expression: Box<Expression>,
15179    #[serde(default)]
15180    pub group: Option<Box<Expression>>,
15181    #[serde(default)]
15182    pub parameters: Option<Box<Expression>>,
15183    #[serde(default)]
15184    pub position: Option<Box<Expression>>,
15185    #[serde(default)]
15186    pub occurrence: Option<Box<Expression>>,
15187}
15188
15189/// RegexpILike
15190#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15191#[cfg_attr(feature = "bindings", derive(TS))]
15192pub struct RegexpILike {
15193    pub this: Box<Expression>,
15194    pub expression: Box<Expression>,
15195    #[serde(default)]
15196    pub flag: Option<Box<Expression>>,
15197}
15198
15199/// RegexpFullMatch
15200#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15201#[cfg_attr(feature = "bindings", derive(TS))]
15202pub struct RegexpFullMatch {
15203    pub this: Box<Expression>,
15204    pub expression: Box<Expression>,
15205    #[serde(default)]
15206    pub options: Vec<Expression>,
15207}
15208
15209/// RegexpInstr
15210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15211#[cfg_attr(feature = "bindings", derive(TS))]
15212pub struct RegexpInstr {
15213    /// Additional search boundaries and retained source semantics.
15214    #[serde(default, skip_serializing_if = "Option::is_none")]
15215    pub options: Option<RegexOptions>,
15216    pub this: Box<Expression>,
15217    pub expression: Box<Expression>,
15218    #[serde(default)]
15219    pub position: Option<Box<Expression>>,
15220    #[serde(default)]
15221    pub occurrence: Option<Box<Expression>>,
15222    #[serde(default)]
15223    pub option: Option<Box<Expression>>,
15224    #[serde(default)]
15225    pub parameters: Option<Box<Expression>>,
15226    #[serde(default)]
15227    pub group: Option<Box<Expression>>,
15228}
15229
15230/// RegexpSplit
15231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15232#[cfg_attr(feature = "bindings", derive(TS))]
15233pub struct RegexpSplit {
15234    pub this: Box<Expression>,
15235    pub expression: Box<Expression>,
15236    #[serde(default)]
15237    pub limit: Option<Box<Expression>>,
15238}
15239
15240/// RegexpCount
15241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15242#[cfg_attr(feature = "bindings", derive(TS))]
15243pub struct RegexpCount {
15244    /// Additional search boundaries and retained source semantics.
15245    #[serde(default, skip_serializing_if = "Option::is_none")]
15246    pub options: Option<RegexOptions>,
15247    pub this: Box<Expression>,
15248    pub expression: Box<Expression>,
15249    #[serde(default)]
15250    pub position: Option<Box<Expression>>,
15251    #[serde(default)]
15252    pub parameters: Option<Box<Expression>>,
15253}
15254
15255/// RegrValx
15256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15257#[cfg_attr(feature = "bindings", derive(TS))]
15258pub struct RegrValx {
15259    pub this: Box<Expression>,
15260    pub expression: Box<Expression>,
15261}
15262
15263/// RegrValy
15264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15265#[cfg_attr(feature = "bindings", derive(TS))]
15266pub struct RegrValy {
15267    pub this: Box<Expression>,
15268    pub expression: Box<Expression>,
15269}
15270
15271/// RegrAvgy
15272#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15273#[cfg_attr(feature = "bindings", derive(TS))]
15274pub struct RegrAvgy {
15275    pub this: Box<Expression>,
15276    pub expression: Box<Expression>,
15277}
15278
15279/// RegrAvgx
15280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15281#[cfg_attr(feature = "bindings", derive(TS))]
15282pub struct RegrAvgx {
15283    pub this: Box<Expression>,
15284    pub expression: Box<Expression>,
15285}
15286
15287/// RegrCount
15288#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15289#[cfg_attr(feature = "bindings", derive(TS))]
15290pub struct RegrCount {
15291    pub this: Box<Expression>,
15292    pub expression: Box<Expression>,
15293}
15294
15295/// RegrIntercept
15296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15297#[cfg_attr(feature = "bindings", derive(TS))]
15298pub struct RegrIntercept {
15299    pub this: Box<Expression>,
15300    pub expression: Box<Expression>,
15301}
15302
15303/// RegrR2
15304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15305#[cfg_attr(feature = "bindings", derive(TS))]
15306pub struct RegrR2 {
15307    pub this: Box<Expression>,
15308    pub expression: Box<Expression>,
15309}
15310
15311/// RegrSxx
15312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15313#[cfg_attr(feature = "bindings", derive(TS))]
15314pub struct RegrSxx {
15315    pub this: Box<Expression>,
15316    pub expression: Box<Expression>,
15317}
15318
15319/// RegrSxy
15320#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15321#[cfg_attr(feature = "bindings", derive(TS))]
15322pub struct RegrSxy {
15323    pub this: Box<Expression>,
15324    pub expression: Box<Expression>,
15325}
15326
15327/// RegrSyy
15328#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15329#[cfg_attr(feature = "bindings", derive(TS))]
15330pub struct RegrSyy {
15331    pub this: Box<Expression>,
15332    pub expression: Box<Expression>,
15333}
15334
15335/// RegrSlope
15336#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15337#[cfg_attr(feature = "bindings", derive(TS))]
15338pub struct RegrSlope {
15339    pub this: Box<Expression>,
15340    pub expression: Box<Expression>,
15341}
15342
15343/// SafeAdd
15344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15345#[cfg_attr(feature = "bindings", derive(TS))]
15346pub struct SafeAdd {
15347    pub this: Box<Expression>,
15348    pub expression: Box<Expression>,
15349}
15350
15351/// SafeDivide
15352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15353#[cfg_attr(feature = "bindings", derive(TS))]
15354pub struct SafeDivide {
15355    pub this: Box<Expression>,
15356    pub expression: Box<Expression>,
15357}
15358
15359/// SafeMultiply
15360#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15361#[cfg_attr(feature = "bindings", derive(TS))]
15362pub struct SafeMultiply {
15363    pub this: Box<Expression>,
15364    pub expression: Box<Expression>,
15365}
15366
15367/// SafeSubtract
15368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15369#[cfg_attr(feature = "bindings", derive(TS))]
15370pub struct SafeSubtract {
15371    pub this: Box<Expression>,
15372    pub expression: Box<Expression>,
15373}
15374
15375/// SHA2
15376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15377#[cfg_attr(feature = "bindings", derive(TS))]
15378pub struct SHA2 {
15379    pub this: Box<Expression>,
15380    #[serde(default)]
15381    pub length: Option<i64>,
15382}
15383
15384/// SHA2Digest
15385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15386#[cfg_attr(feature = "bindings", derive(TS))]
15387pub struct SHA2Digest {
15388    pub this: Box<Expression>,
15389    #[serde(default)]
15390    pub length: Option<i64>,
15391}
15392
15393/// SortArray
15394#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15395#[cfg_attr(feature = "bindings", derive(TS))]
15396pub struct SortArray {
15397    pub this: Box<Expression>,
15398    #[serde(default)]
15399    pub asc: Option<Box<Expression>>,
15400    #[serde(default)]
15401    pub nulls_first: Option<Box<Expression>>,
15402}
15403
15404/// SplitPart
15405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15406#[cfg_attr(feature = "bindings", derive(TS))]
15407pub struct SplitPart {
15408    pub this: Box<Expression>,
15409    #[serde(default)]
15410    pub delimiter: Option<Box<Expression>>,
15411    #[serde(default)]
15412    pub part_index: Option<Box<Expression>>,
15413}
15414
15415/// SUBSTRING_INDEX(str, delim, count)
15416#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15417#[cfg_attr(feature = "bindings", derive(TS))]
15418pub struct SubstringIndex {
15419    pub this: Box<Expression>,
15420    #[serde(default)]
15421    pub delimiter: Option<Box<Expression>>,
15422    #[serde(default)]
15423    pub count: Option<Box<Expression>>,
15424}
15425
15426/// StandardHash
15427#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15428#[cfg_attr(feature = "bindings", derive(TS))]
15429pub struct StandardHash {
15430    pub this: Box<Expression>,
15431    #[serde(default)]
15432    pub expression: Option<Box<Expression>>,
15433}
15434
15435/// StrPosition
15436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15437#[cfg_attr(feature = "bindings", derive(TS))]
15438pub struct StrPosition {
15439    pub this: Box<Expression>,
15440    #[serde(default)]
15441    pub substr: Option<Box<Expression>>,
15442    #[serde(default)]
15443    pub position: Option<Box<Expression>>,
15444    #[serde(default)]
15445    pub occurrence: Option<Box<Expression>>,
15446}
15447
15448/// Search
15449#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15450#[cfg_attr(feature = "bindings", derive(TS))]
15451pub struct Search {
15452    pub this: Box<Expression>,
15453    pub expression: Box<Expression>,
15454    #[serde(default)]
15455    pub json_scope: Option<Box<Expression>>,
15456    #[serde(default)]
15457    pub analyzer: Option<Box<Expression>>,
15458    #[serde(default)]
15459    pub analyzer_options: Option<Box<Expression>>,
15460    #[serde(default)]
15461    pub search_mode: Option<Box<Expression>>,
15462}
15463
15464/// SearchIp
15465#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15466#[cfg_attr(feature = "bindings", derive(TS))]
15467pub struct SearchIp {
15468    pub this: Box<Expression>,
15469    pub expression: Box<Expression>,
15470}
15471
15472/// StrToDate
15473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15474#[cfg_attr(feature = "bindings", derive(TS))]
15475pub struct StrToDate {
15476    pub this: Box<Expression>,
15477    #[serde(default)]
15478    pub format: Option<String>,
15479    #[serde(default)]
15480    pub safe: Option<Box<Expression>>,
15481}
15482
15483/// StrToTime
15484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15485#[cfg_attr(feature = "bindings", derive(TS))]
15486pub struct StrToTime {
15487    pub this: Box<Expression>,
15488    pub format: String,
15489    #[serde(default)]
15490    pub zone: Option<Box<Expression>>,
15491    #[serde(default)]
15492    pub safe: Option<Box<Expression>>,
15493    #[serde(default)]
15494    pub target_type: Option<Box<Expression>>,
15495}
15496
15497/// StrToUnix
15498#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15499#[cfg_attr(feature = "bindings", derive(TS))]
15500pub struct StrToUnix {
15501    #[serde(default)]
15502    pub this: Option<Box<Expression>>,
15503    #[serde(default)]
15504    pub format: Option<String>,
15505}
15506
15507/// StrToMap
15508#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15509#[cfg_attr(feature = "bindings", derive(TS))]
15510pub struct StrToMap {
15511    pub this: Box<Expression>,
15512    #[serde(default)]
15513    pub pair_delim: Option<Box<Expression>>,
15514    #[serde(default)]
15515    pub key_value_delim: Option<Box<Expression>>,
15516    #[serde(default)]
15517    pub duplicate_resolution_callback: Option<Box<Expression>>,
15518}
15519
15520/// NumberToStr
15521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15522#[cfg_attr(feature = "bindings", derive(TS))]
15523pub struct NumberToStr {
15524    pub this: Box<Expression>,
15525    pub format: String,
15526    #[serde(default)]
15527    pub culture: Option<Box<Expression>>,
15528}
15529
15530/// FromBase
15531#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15532#[cfg_attr(feature = "bindings", derive(TS))]
15533pub struct FromBase {
15534    pub this: Box<Expression>,
15535    pub expression: Box<Expression>,
15536}
15537
15538/// Stuff
15539#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15540#[cfg_attr(feature = "bindings", derive(TS))]
15541pub struct Stuff {
15542    pub this: Box<Expression>,
15543    #[serde(default)]
15544    pub start: Option<Box<Expression>>,
15545    #[serde(default)]
15546    pub length: Option<i64>,
15547    pub expression: Box<Expression>,
15548}
15549
15550/// TimeToStr
15551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15552#[cfg_attr(feature = "bindings", derive(TS))]
15553pub struct TimeToStr {
15554    pub this: Box<Expression>,
15555    pub format: String,
15556    #[serde(default)]
15557    pub culture: Option<Box<Expression>>,
15558    #[serde(default)]
15559    pub zone: Option<Box<Expression>>,
15560}
15561
15562/// TimeStrToTime
15563#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15564#[cfg_attr(feature = "bindings", derive(TS))]
15565pub struct TimeStrToTime {
15566    pub this: Box<Expression>,
15567    #[serde(default)]
15568    pub zone: Option<Box<Expression>>,
15569}
15570
15571/// TsOrDsAdd
15572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15573#[cfg_attr(feature = "bindings", derive(TS))]
15574pub struct TsOrDsAdd {
15575    pub this: Box<Expression>,
15576    pub expression: Box<Expression>,
15577    #[serde(default)]
15578    pub unit: Option<String>,
15579    #[serde(default)]
15580    pub return_type: Option<Box<Expression>>,
15581}
15582
15583/// TsOrDsDiff
15584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15585#[cfg_attr(feature = "bindings", derive(TS))]
15586pub struct TsOrDsDiff {
15587    pub this: Box<Expression>,
15588    pub expression: Box<Expression>,
15589    #[serde(default)]
15590    pub unit: Option<String>,
15591}
15592
15593/// TsOrDsToDate
15594#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15595#[cfg_attr(feature = "bindings", derive(TS))]
15596pub struct TsOrDsToDate {
15597    pub this: Box<Expression>,
15598    #[serde(default)]
15599    pub format: Option<String>,
15600    #[serde(default)]
15601    pub safe: Option<Box<Expression>>,
15602}
15603
15604/// TsOrDsToTime
15605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15606#[cfg_attr(feature = "bindings", derive(TS))]
15607pub struct TsOrDsToTime {
15608    pub this: Box<Expression>,
15609    #[serde(default)]
15610    pub format: Option<String>,
15611    #[serde(default)]
15612    pub safe: Option<Box<Expression>>,
15613}
15614
15615/// Unhex
15616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15617#[cfg_attr(feature = "bindings", derive(TS))]
15618pub struct Unhex {
15619    pub this: Box<Expression>,
15620    #[serde(default)]
15621    pub expression: Option<Box<Expression>>,
15622}
15623
15624/// Uniform
15625#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15626#[cfg_attr(feature = "bindings", derive(TS))]
15627pub struct Uniform {
15628    pub this: Box<Expression>,
15629    pub expression: Box<Expression>,
15630    #[serde(default)]
15631    pub gen: Option<Box<Expression>>,
15632    #[serde(default)]
15633    pub seed: Option<Box<Expression>>,
15634}
15635
15636/// UnixToStr
15637#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15638#[cfg_attr(feature = "bindings", derive(TS))]
15639pub struct UnixToStr {
15640    pub this: Box<Expression>,
15641    #[serde(default)]
15642    pub format: Option<String>,
15643}
15644
15645/// UnixToTime
15646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15647#[cfg_attr(feature = "bindings", derive(TS))]
15648pub struct UnixToTime {
15649    pub this: Box<Expression>,
15650    #[serde(default)]
15651    pub scale: Option<i64>,
15652    #[serde(default)]
15653    pub zone: Option<Box<Expression>>,
15654    #[serde(default)]
15655    pub hours: Option<Box<Expression>>,
15656    #[serde(default)]
15657    pub minutes: Option<Box<Expression>>,
15658    #[serde(default)]
15659    pub format: Option<String>,
15660    #[serde(default)]
15661    pub target_type: Option<Box<Expression>>,
15662}
15663
15664/// Uuid
15665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15666#[cfg_attr(feature = "bindings", derive(TS))]
15667pub struct Uuid {
15668    #[serde(default)]
15669    pub this: Option<Box<Expression>>,
15670    #[serde(default)]
15671    pub name: Option<String>,
15672    #[serde(default)]
15673    pub is_string: Option<Box<Expression>>,
15674}
15675
15676/// TimestampFromParts
15677#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15678#[cfg_attr(feature = "bindings", derive(TS))]
15679pub struct TimestampFromParts {
15680    #[serde(default)]
15681    pub zone: Option<Box<Expression>>,
15682    #[serde(default)]
15683    pub milli: Option<Box<Expression>>,
15684    #[serde(default)]
15685    pub this: Option<Box<Expression>>,
15686    #[serde(default)]
15687    pub expression: Option<Box<Expression>>,
15688}
15689
15690/// TimestampTzFromParts
15691#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15692#[cfg_attr(feature = "bindings", derive(TS))]
15693pub struct TimestampTzFromParts {
15694    #[serde(default)]
15695    pub zone: Option<Box<Expression>>,
15696}
15697
15698/// Corr
15699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15700#[cfg_attr(feature = "bindings", derive(TS))]
15701pub struct Corr {
15702    pub this: Box<Expression>,
15703    pub expression: Box<Expression>,
15704    #[serde(default)]
15705    pub null_on_zero_variance: Option<Box<Expression>>,
15706}
15707
15708/// WidthBucket
15709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15710#[cfg_attr(feature = "bindings", derive(TS))]
15711pub struct WidthBucket {
15712    pub this: Box<Expression>,
15713    #[serde(default)]
15714    pub min_value: Option<Box<Expression>>,
15715    #[serde(default)]
15716    pub max_value: Option<Box<Expression>>,
15717    #[serde(default)]
15718    pub num_buckets: Option<Box<Expression>>,
15719    #[serde(default)]
15720    pub threshold: Option<Box<Expression>>,
15721}
15722
15723/// CovarSamp
15724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15725#[cfg_attr(feature = "bindings", derive(TS))]
15726pub struct CovarSamp {
15727    pub this: Box<Expression>,
15728    pub expression: Box<Expression>,
15729}
15730
15731/// CovarPop
15732#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15733#[cfg_attr(feature = "bindings", derive(TS))]
15734pub struct CovarPop {
15735    pub this: Box<Expression>,
15736    pub expression: Box<Expression>,
15737}
15738
15739/// Week
15740#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15741#[cfg_attr(feature = "bindings", derive(TS))]
15742pub struct Week {
15743    pub this: Box<Expression>,
15744    #[serde(default)]
15745    pub mode: Option<Box<Expression>>,
15746}
15747
15748/// XMLElement
15749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15750#[cfg_attr(feature = "bindings", derive(TS))]
15751pub struct XMLElement {
15752    pub this: Box<Expression>,
15753    #[serde(default)]
15754    pub expressions: Vec<Expression>,
15755    #[serde(default)]
15756    pub evalname: Option<Box<Expression>>,
15757}
15758
15759/// XMLGet
15760#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15761#[cfg_attr(feature = "bindings", derive(TS))]
15762pub struct XMLGet {
15763    pub this: Box<Expression>,
15764    pub expression: Box<Expression>,
15765    #[serde(default)]
15766    pub instance: Option<Box<Expression>>,
15767}
15768
15769/// XMLTable
15770#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15771#[cfg_attr(feature = "bindings", derive(TS))]
15772pub struct XMLTable {
15773    pub this: Box<Expression>,
15774    #[serde(default)]
15775    pub namespaces: Option<Box<Expression>>,
15776    #[serde(default)]
15777    pub passing: Option<Box<Expression>>,
15778    #[serde(default)]
15779    pub columns: Vec<Expression>,
15780    #[serde(default)]
15781    pub by_ref: Option<Box<Expression>>,
15782}
15783
15784/// XMLKeyValueOption
15785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15786#[cfg_attr(feature = "bindings", derive(TS))]
15787pub struct XMLKeyValueOption {
15788    pub this: Box<Expression>,
15789    #[serde(default)]
15790    pub expression: Option<Box<Expression>>,
15791}
15792
15793/// Zipf
15794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15795#[cfg_attr(feature = "bindings", derive(TS))]
15796pub struct Zipf {
15797    pub this: Box<Expression>,
15798    #[serde(default)]
15799    pub elementcount: Option<Box<Expression>>,
15800    #[serde(default)]
15801    pub gen: Option<Box<Expression>>,
15802}
15803
15804/// Merge
15805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15806#[cfg_attr(feature = "bindings", derive(TS))]
15807pub struct Merge {
15808    pub this: Box<Expression>,
15809    pub using: Box<Expression>,
15810    #[serde(default)]
15811    pub on: Option<Box<Expression>>,
15812    #[serde(default)]
15813    pub using_cond: Option<Box<Expression>>,
15814    #[serde(default)]
15815    pub whens: Option<Box<Expression>>,
15816    #[serde(default)]
15817    pub with_: Option<Box<Expression>>,
15818    #[serde(default)]
15819    pub returning: Option<Box<Expression>>,
15820}
15821
15822/// When
15823#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15824#[cfg_attr(feature = "bindings", derive(TS))]
15825pub struct When {
15826    #[serde(default)]
15827    pub matched: Option<Box<Expression>>,
15828    #[serde(default)]
15829    pub source: Option<Box<Expression>>,
15830    #[serde(default)]
15831    pub condition: Option<Box<Expression>>,
15832    pub then: Box<Expression>,
15833}
15834
15835/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15837#[cfg_attr(feature = "bindings", derive(TS))]
15838pub struct Whens {
15839    #[serde(default)]
15840    pub expressions: Vec<Expression>,
15841}
15842
15843/// NextValueFor
15844#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15845#[cfg_attr(feature = "bindings", derive(TS))]
15846pub struct NextValueFor {
15847    pub this: Box<Expression>,
15848    #[serde(default)]
15849    pub order: Option<Box<Expression>>,
15850}
15851
15852// Vertica dialect support.
15853/// Native Vertica syntax, retaining semantics through serialization and traversal.
15854#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15855#[cfg_attr(feature = "bindings", derive(TS))]
15856#[serde(tag = "kind", rename_all = "snake_case")]
15857pub enum VerticaExpression {
15858    PhysicalTable {
15859        this: Expression,
15860        physical: VerticaPhysical,
15861    },
15862    FlexTable {
15863        this: Expression,
15864        physical: VerticaPhysical,
15865    },
15866    Projection {
15867        name: TableRef,
15868        columns: Vec<VerticaProjectionColumn>,
15869        query: Expression,
15870        physical: VerticaPhysical,
15871    },
15872    Copy {
15873        table: TableRef,
15874        columns: Vec<Identifier>,
15875        local: bool,
15876        sources: Vec<Expression>,
15877        parser: Option<VerticaParserCall>,
15878        options: Vec<VerticaParameter>,
15879    },
15880    ExportParquet {
15881        options: Vec<VerticaParameter>,
15882        over: Option<Over>,
15883        query: Expression,
15884    },
15885    Interpolate {
15886        left: Expression,
15887        right: Expression,
15888        previous: bool,
15889    },
15890    /// Zero-based array access retains source bounds semantics from parsing.
15891    ArrayAccess {
15892        this: Expression,
15893        indices: Vec<Expression>,
15894    },
15895    ArraySlice {
15896        this: Expression,
15897        start: Option<Expression>,
15898        end: Option<Expression>,
15899    },
15900    BoundaryDateDiff {
15901        start: Expression,
15902        end: Expression,
15903        unit: IntervalUnit,
15904    },
15905    UsingParameters {
15906        this: Expression,
15907        parameters: Vec<VerticaParameter>,
15908    },
15909    SafeCast {
15910        this: Expression,
15911        to: DataType,
15912    },
15913    Set {
15914        values: Vec<Expression>,
15915    },
15916    Interval {
15917        value: Expression,
15918        precision: Option<u32>,
15919        year_month: bool,
15920        unit: Option<String>,
15921        end_unit: Option<String>,
15922    },
15923    /// Hexadecimal byte value, distinct from PostgreSQL's bit strings.
15924    Binary {
15925        hex: String,
15926    },
15927    Historical {
15928        query: Expression,
15929        point: VerticaHistoricalPoint,
15930    },
15931    PartitionBest,
15932}
15933
15934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15935#[cfg_attr(feature = "bindings", derive(TS))]
15936pub struct VerticaParameter {
15937    pub name: Identifier,
15938    pub value: Expression,
15939}
15940
15941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15942#[cfg_attr(feature = "bindings", derive(TS))]
15943#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
15944pub enum VerticaHistoricalPoint {
15945    Latest,
15946    Epoch(Expression),
15947    Time(Expression),
15948}
15949
15950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15951#[cfg_attr(feature = "bindings", derive(TS))]
15952#[serde(tag = "kind", rename_all = "snake_case")]
15953pub enum VerticaDataType {
15954    Array {
15955        element_type: DataType,
15956        bound: Option<VerticaCollectionBound>,
15957    },
15958    Set {
15959        element_type: DataType,
15960        bound: Option<VerticaCollectionBound>,
15961    },
15962    Row {
15963        fields: Vec<StructField>,
15964    },
15965    LongVarBinary {
15966        length: Option<u32>,
15967    },
15968    Interval {
15969        precision: Option<u32>,
15970        year_month: bool,
15971        unit: Option<String>,
15972        end_unit: Option<String>,
15973    },
15974}
15975
15976#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15977#[cfg_attr(feature = "bindings", derive(TS))]
15978#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
15979pub enum VerticaCollectionBound {
15980    Elements(u32),
15981    Bytes(u32),
15982}
15983
15984#[derive(
15985    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
15986)]
15987#[cfg_attr(feature = "bindings", derive(TS))]
15988pub struct VerticaSelectExtensions {
15989    pub timeseries: Option<VerticaTimeseries>,
15990    pub match_clause: Option<VerticaMatch>,
15991    pub limit_over: Option<Over>,
15992}
15993
15994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15995#[cfg_attr(feature = "bindings", derive(TS))]
15996pub struct VerticaTimeseries {
15997    pub alias: Identifier,
15998    pub interval: Expression,
15999    pub over: Over,
16000}
16001
16002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16003#[cfg_attr(feature = "bindings", derive(TS))]
16004pub struct VerticaMatch {
16005    pub partition_by: Vec<Expression>,
16006    pub order_by: Vec<Ordered>,
16007    pub definitions: Vec<VerticaParameter>,
16008    pub name: Identifier,
16009    pub pattern: VerticaPattern,
16010    /// None = default; true = FIRST EVENT; false = ALL EVENTS.
16011    pub first_event: Option<bool>,
16012}
16013
16014#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16015#[cfg_attr(feature = "bindings", derive(TS))]
16016#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
16017pub enum VerticaPattern {
16018    Event(Identifier),
16019    Sequence(Vec<VerticaPattern>),
16020    Alternative(Vec<VerticaPattern>),
16021    Group(Box<VerticaPattern>),
16022    Repeat {
16023        pattern: Box<VerticaPattern>,
16024        quantifier: String,
16025    },
16026}
16027
16028#[derive(
16029    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
16030)]
16031#[cfg_attr(feature = "bindings", derive(TS))]
16032pub struct VerticaPhysical {
16033    pub order_by: Vec<Ordered>,
16034    pub segmentation: Option<VerticaSegmentation>,
16035    pub ksafe: Option<VerticaKsafe>,
16036}
16037
16038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16039#[cfg_attr(feature = "bindings", derive(TS))]
16040#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
16041pub enum VerticaKsafe {
16042    Default,
16043    Level(u32),
16044}
16045
16046#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16047#[cfg_attr(feature = "bindings", derive(TS))]
16048#[serde(tag = "kind", rename_all = "snake_case")]
16049pub enum VerticaSegmentation {
16050    Segmented {
16051        expression: Expression,
16052        offset: Option<u32>,
16053    },
16054    Unsegmented {
16055        node: Option<Identifier>,
16056    },
16057}
16058
16059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16060#[cfg_attr(feature = "bindings", derive(TS))]
16061pub struct VerticaProjectionColumn {
16062    pub name: Identifier,
16063    pub encoding: Option<Identifier>,
16064}
16065
16066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16067#[cfg_attr(feature = "bindings", derive(TS))]
16068pub struct VerticaParserCall {
16069    pub name: TableRef,
16070    pub parameters: Vec<VerticaParameter>,
16071}
16072
16073#[cfg(test)]
16074mod tests {
16075    use super::*;
16076
16077    #[test]
16078    fn test_source_spans_are_metadata_not_expression_identity() {
16079        let plain = Expression::column("customer_id");
16080        let mut positioned = plain.clone();
16081        if let Expression::Column(column) = &mut positioned {
16082            column.span = Some(Span::new(7, 18, 1, 19));
16083            column.name.span = column.span;
16084        }
16085        assert_eq!(plain, positioned);
16086        assert_ne!(
16087            serde_json::to_value(&plain).unwrap(),
16088            serde_json::to_value(&positioned).unwrap()
16089        );
16090        assert_eq!(
16091            Identifier::new("a"),
16092            Identifier::new("a").with_span(Span::new(3, 4, 1, 5))
16093        );
16094        assert_ne!(Identifier::new("a"), Identifier::quoted("a"));
16095        assert_ne!(plain, Expression::column("other"));
16096        let Expression::Column(column) = plain else {
16097            unreachable!()
16098        };
16099        assert!(column.span.is_none() && column.name.span.is_none());
16100    }
16101
16102    #[test]
16103    #[cfg(feature = "bindings")]
16104    fn export_typescript_types() {
16105        // This test exports TypeScript types to the generated directory
16106        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
16107        Expression::export_all(&ts_rs::Config::default())
16108            .expect("Failed to export Expression types");
16109
16110        let mut variant_names = String::from(
16111            "// This file was generated from the Rust Expression enum. Do not edit it manually.\n\n",
16112        );
16113        variant_names.push_str("export const EXPRESSION_VARIANT_NAMES = [\n");
16114        for name in Expression::SERIALIZED_VARIANT_NAMES {
16115            use std::fmt::Write;
16116            writeln!(variant_names, "  {name:?},").expect("writing to a String cannot fail");
16117        }
16118        variant_names.push_str("] as const;\n");
16119
16120        let output_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
16121            .join("bindings/ExpressionVariantNames.ts");
16122        std::fs::write(output_path, variant_names)
16123            .expect("Failed to export serialized Expression variant names");
16124    }
16125
16126    #[test]
16127    fn test_simple_select_builder() {
16128        let select = Select::new()
16129            .column(Expression::star())
16130            .from(Expression::Table(Box::new(TableRef::new("users"))));
16131
16132        assert_eq!(select.expressions.len(), 1);
16133        assert!(select.from.is_some());
16134    }
16135
16136    #[test]
16137    fn test_expression_alias() {
16138        let expr = Expression::column("id").alias("user_id");
16139
16140        match expr {
16141            Expression::Alias(a) => {
16142                assert_eq!(a.alias.name, "user_id");
16143            }
16144            _ => panic!("Expected Alias"),
16145        }
16146    }
16147
16148    #[test]
16149    fn test_literal_creation() {
16150        let num = Expression::number(42);
16151        let str = Expression::string("hello");
16152
16153        match num {
16154            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
16155                let Literal::Number(n) = lit.as_ref() else {
16156                    unreachable!()
16157                };
16158                assert_eq!(n, "42")
16159            }
16160            _ => panic!("Expected Number"),
16161        }
16162
16163        match str {
16164            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
16165                let Literal::String(s) = lit.as_ref() else {
16166                    unreachable!()
16167                };
16168                assert_eq!(s, "hello")
16169            }
16170            _ => panic!("Expected String"),
16171        }
16172    }
16173
16174    #[test]
16175    fn test_expression_sql() {
16176        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
16177        assert_eq!(expr.sql(), "SELECT 1 + 2");
16178    }
16179
16180    #[test]
16181    fn test_expression_sql_for() {
16182        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
16183        let sql = expr.sql_for(crate::DialectType::Generic);
16184        // Generic mode normalizes IF() to CASE WHEN
16185        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
16186    }
16187}