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
3684impl Star {
3685    /// Apply EXCEPT, REPLACE, and RENAME to the expanded `column` named `name`.
3686    /// Returns `None` when EXCEPT removes the column.
3687    #[cfg(feature = "semantic")]
3688    pub(crate) fn expand_column(
3689        &self,
3690        name: &str,
3691        column: Expression,
3692        dialect: Option<crate::dialects::DialectType>,
3693    ) -> Option<Expression> {
3694        if self.excludes(name, dialect) {
3695            return None;
3696        }
3697        let renamed = self.renamed(name, dialect);
3698        if let Some(replacement) = self.replacement(name, dialect) {
3699            let mut replacement = replacement.clone();
3700            if let Some(alias) = renamed {
3701                replacement.alias = alias;
3702            }
3703            return Some(Expression::Alias(Box::new(replacement)));
3704        }
3705        Some(match renamed {
3706            Some(alias) => Expression::Alias(Box::new(Alias::new(column, alias))),
3707            None => column,
3708        })
3709    }
3710
3711    /// Whether EXCEPT holds a ClickHouse pattern string (`EXCEPT ('re')`).
3712    /// The columns it removes are not known, so the star stays unexpanded.
3713    #[cfg(any(feature = "semantic", test))]
3714    pub(crate) fn has_except_pattern(&self) -> bool {
3715        self.except.iter().flatten().any(is_except_pattern)
3716    }
3717
3718    /// Whether EXCEPT / EXCLUDE removes the column `name`.
3719    #[cfg(feature = "semantic")]
3720    pub(crate) fn excludes(
3721        &self,
3722        name: &str,
3723        dialect: Option<crate::dialects::DialectType>,
3724    ) -> bool {
3725        self.except
3726            .iter()
3727            .flatten()
3728            .any(|column| star_modifier_matches(column, name, dialect))
3729    }
3730
3731    /// The new name RENAME gives to the column `name`. With a known dialect,
3732    /// the name gets the identifier normalization that schema columns get.
3733    #[cfg(feature = "semantic")]
3734    pub(crate) fn renamed(
3735        &self,
3736        name: &str,
3737        dialect: Option<crate::dialects::DialectType>,
3738    ) -> Option<Identifier> {
3739        let (_, new) = self
3740            .rename
3741            .iter()
3742            .flatten()
3743            .find(|(old, _)| star_modifier_matches(old, name, dialect))?;
3744        Some(match dialect {
3745            Some(_) => crate::optimizer::normalize_identifiers::normalize_identifier(
3746                new.clone(),
3747                crate::optimizer::normalize_identifiers::get_normalization_strategy(dialect),
3748            ),
3749            None => new.clone(),
3750        })
3751    }
3752
3753    /// The REPLACE expression for the column `name`.
3754    #[cfg(feature = "semantic")]
3755    pub(crate) fn replacement(
3756        &self,
3757        name: &str,
3758        dialect: Option<crate::dialects::DialectType>,
3759    ) -> Option<&Alias> {
3760        self.replace
3761            .iter()
3762            .flatten()
3763            .find(|replacement| star_modifier_matches(&replacement.alias, name, dialect))
3764    }
3765
3766    /// The source column that the star outputs as `output`, after RENAME and
3767    /// EXCEPT. Returns `None` when the star does not output `output`.
3768    #[cfg(feature = "semantic")]
3769    pub(crate) fn source_column(
3770        &self,
3771        output: &str,
3772        dialect: Option<crate::dialects::DialectType>,
3773    ) -> Option<String> {
3774        let renames = self.rename.iter().flatten();
3775        let column = match renames
3776            .clone()
3777            .find(|(_, new)| star_modifier_matches(new, output, dialect))
3778        {
3779            Some((old, _)) => old.name.clone(),
3780            None if renames
3781                .clone()
3782                .any(|(old, _)| star_modifier_matches(old, output, dialect)) =>
3783            {
3784                return None
3785            }
3786            None => output.to_string(),
3787        };
3788        (!self.excludes(&column, dialect)).then_some(column)
3789    }
3790}
3791
3792/// A pattern string keeps its quotes in the name (see `parse_star_except_name`).
3793#[cfg(any(feature = "semantic", test))]
3794fn is_except_pattern(identifier: &Identifier) -> bool {
3795    !identifier.quoted && identifier.name.starts_with('\'')
3796}
3797
3798/// Match a modifier name to the column `name`. A quoted name matches with
3799/// its case, unless the dialect ignores case. An unquoted name ignores case,
3800/// unless the dialect is case sensitive. A qualified name such as `t.col`
3801/// matches on its column part, as in sqlglot. A pattern string never matches.
3802#[cfg(feature = "semantic")]
3803fn star_modifier_matches(
3804    identifier: &Identifier,
3805    name: &str,
3806    dialect: Option<crate::dialects::DialectType>,
3807) -> bool {
3808    use crate::optimizer::normalize_identifiers::{
3809        get_normalization_strategy, NormalizationStrategy,
3810    };
3811    use std::borrow::Cow;
3812    if is_except_pattern(identifier) {
3813        return false;
3814    }
3815    let text = identifier.name.as_str();
3816    let (column, quoted) = if identifier.quoted {
3817        (Cow::Borrowed(text), true)
3818    } else if let Some(quote) = text.chars().last().filter(|c| matches!(c, '"' | '`')) {
3819        // A qualified name keeps the quotes of its parts: `t."col"`.
3820        let body = &text[..text.len() - 1];
3821        let mut chars = body.char_indices().rev().peekable();
3822        let mut opening = None;
3823        while let Some((index, ch)) = chars.next() {
3824            if ch == quote {
3825                if chars.peek().is_some_and(|(_, next)| *next == quote) {
3826                    chars.next(); // Skip an escaped quote inside the identifier.
3827                } else {
3828                    opening = Some(index);
3829                    break;
3830                }
3831            }
3832        }
3833        match opening {
3834            Some(open) => (
3835                Cow::Owned(
3836                    body[open + 1..].replace(&format!("{quote}{quote}"), &quote.to_string()),
3837                ),
3838                true,
3839            ),
3840            None => (Cow::Borrowed(text), false),
3841        }
3842    } else {
3843        (
3844            Cow::Borrowed(text.rsplit_once('.').map_or(text, |(_, column)| column)),
3845            false,
3846        )
3847    };
3848    let strategy = dialect.map(|dialect| get_normalization_strategy(Some(dialect)));
3849    let exact = match strategy {
3850        Some(NormalizationStrategy::CaseSensitive) => true,
3851        Some(
3852            NormalizationStrategy::CaseInsensitive
3853            | NormalizationStrategy::CaseInsensitiveUppercase,
3854        ) => false,
3855        _ => quoted,
3856    };
3857    if exact {
3858        column == name
3859    } else {
3860        column.eq_ignore_ascii_case(name)
3861    }
3862}
3863
3864/// Represent a complete SELECT statement.
3865///
3866/// This is the most feature-rich AST node, covering the full surface area of
3867/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3868/// `Vec` are omitted from the generated SQL when absent.
3869///
3870/// # Key Fields
3871///
3872/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3873/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3874/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3875/// - `where_clause` -- the WHERE predicate.
3876/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3877/// - `having` -- HAVING predicate.
3878/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3879/// - `limit` / `offset` / `fetch` -- result set limiting.
3880/// - `with` -- Common Table Expressions (CTEs).
3881/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3882/// - `windows` -- named window definitions (WINDOW w AS ...).
3883///
3884/// Dialect-specific extensions are supported via fields like `prewhere`
3885/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3886/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3887#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3888#[cfg_attr(feature = "bindings", derive(TS))]
3889pub struct Select {
3890    #[serde(default, skip_serializing_if = "Option::is_none")]
3891    pub vertica: Option<Box<VerticaSelectExtensions>>,
3892    /// The select-list: columns, expressions, aliases, and wildcards.
3893    pub expressions: Vec<Expression>,
3894    /// The FROM clause, containing one or more table sources.
3895    pub from: Option<From>,
3896    /// JOIN clauses applied after the FROM source.
3897    pub joins: Vec<Join>,
3898    pub lateral_views: Vec<LateralView>,
3899    /// ClickHouse PREWHERE clause
3900    #[serde(default, skip_serializing_if = "Option::is_none")]
3901    pub prewhere: Option<Expression>,
3902    pub where_clause: Option<Where>,
3903    pub group_by: Option<GroupBy>,
3904    pub having: Option<Having>,
3905    pub qualify: Option<Qualify>,
3906    pub order_by: Option<OrderBy>,
3907    pub distribute_by: Option<DistributeBy>,
3908    pub cluster_by: Option<ClusterBy>,
3909    pub sort_by: Option<SortBy>,
3910    pub limit: Option<Limit>,
3911    pub offset: Option<Offset>,
3912    /// ClickHouse LIMIT BY clause expressions
3913    #[serde(default, skip_serializing_if = "Option::is_none")]
3914    pub limit_by: Option<Vec<Expression>>,
3915    pub fetch: Option<Fetch>,
3916    pub distinct: bool,
3917    pub distinct_on: Option<Vec<Expression>>,
3918    pub top: Option<Top>,
3919    pub with: Option<With>,
3920    pub sample: Option<Sample>,
3921    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3922    #[serde(default, skip_serializing_if = "Option::is_none")]
3923    pub settings: Option<Vec<Expression>>,
3924    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3925    #[serde(default, skip_serializing_if = "Option::is_none")]
3926    pub format: Option<Expression>,
3927    pub windows: Option<Vec<NamedWindow>>,
3928    pub hint: Option<Hint>,
3929    /// Oracle CONNECT BY clause for hierarchical queries
3930    pub connect: Option<Connect>,
3931    /// SELECT ... INTO table_name for creating tables
3932    pub into: Option<SelectInto>,
3933    /// FOR UPDATE/SHARE locking clauses
3934    #[serde(default)]
3935    pub locks: Vec<Lock>,
3936    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3937    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3938    pub for_xml: Vec<Expression>,
3939    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3940    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3941    pub for_json: Vec<Expression>,
3942    /// Structured result serialization, including a bare FOR JSON/XML clause.
3943    #[serde(default, skip_serializing_if = "Option::is_none")]
3944    pub result_serialization: Option<ResultSerialization>,
3945    #[serde(default, skip_serializing_if = "Option::is_none")]
3946    pub query_collation: Option<Identifier>,
3947    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3948    pub query_hints: Vec<Expression>,
3949    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3950    pub total_rowcount: bool,
3951    #[serde(default, skip_serializing_if = "Option::is_none")]
3952    #[ast(skip)]
3953    pub source_dialect: Option<crate::dialects::DialectType>,
3954    /// Leading comments before the statement
3955    #[serde(default)]
3956    pub leading_comments: Vec<String>,
3957    /// Comments that appear after SELECT keyword (before expressions)
3958    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3959    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3960    pub post_select_comments: Vec<String>,
3961    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3962    #[serde(default, skip_serializing_if = "Option::is_none")]
3963    pub kind: Option<String>,
3964    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3965    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3966    pub operation_modifiers: Vec<String>,
3967    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3968    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3969    pub qualify_after_window: bool,
3970    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3971    #[serde(default, skip_serializing_if = "Option::is_none")]
3972    pub option: Option<String>,
3973    /// Redshift-style EXCLUDE clause at the end of the projection list
3974    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3975    #[serde(default, skip_serializing_if = "Option::is_none")]
3976    pub exclude: Option<Vec<Expression>>,
3977}
3978
3979impl Select {
3980    pub fn new() -> Self {
3981        Self {
3982            vertica: None,
3983            expressions: Vec::new(),
3984            from: None,
3985            joins: Vec::new(),
3986            lateral_views: Vec::new(),
3987            prewhere: None,
3988            where_clause: None,
3989            group_by: None,
3990            having: None,
3991            qualify: None,
3992            order_by: None,
3993            distribute_by: None,
3994            cluster_by: None,
3995            sort_by: None,
3996            limit: None,
3997            offset: None,
3998            limit_by: None,
3999            fetch: None,
4000            distinct: false,
4001            distinct_on: None,
4002            top: None,
4003            with: None,
4004            sample: None,
4005            settings: None,
4006            format: None,
4007            windows: None,
4008            hint: None,
4009            connect: None,
4010            into: None,
4011            locks: Vec::new(),
4012            for_xml: Vec::new(),
4013            for_json: Vec::new(),
4014            result_serialization: None,
4015            query_collation: None,
4016            query_hints: Vec::new(),
4017            total_rowcount: false,
4018            source_dialect: None,
4019            leading_comments: Vec::new(),
4020            post_select_comments: Vec::new(),
4021            kind: None,
4022            operation_modifiers: Vec::new(),
4023            qualify_after_window: false,
4024            option: None,
4025            exclude: None,
4026        }
4027    }
4028
4029    /// Add a column to select
4030    pub fn column(mut self, expr: Expression) -> Self {
4031        self.expressions.push(expr);
4032        self
4033    }
4034
4035    /// Set the FROM clause
4036    pub fn from(mut self, table: Expression) -> Self {
4037        self.from = Some(From {
4038            expressions: vec![table],
4039        });
4040        self
4041    }
4042
4043    /// Add a WHERE clause
4044    pub fn where_(mut self, condition: Expression) -> Self {
4045        self.where_clause = Some(Where { this: condition });
4046        self
4047    }
4048
4049    /// Set DISTINCT
4050    pub fn distinct(mut self) -> Self {
4051        self.distinct = true;
4052        self
4053    }
4054
4055    /// Add a JOIN
4056    pub fn join(mut self, join: Join) -> Self {
4057        self.joins.push(join);
4058        self
4059    }
4060
4061    /// Set ORDER BY
4062    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
4063        self.order_by = Some(OrderBy {
4064            expressions,
4065            siblings: false,
4066            comments: Vec::new(),
4067        });
4068        self
4069    }
4070
4071    /// Set LIMIT
4072    pub fn limit(mut self, n: Expression) -> Self {
4073        self.limit = Some(Limit {
4074            this: n,
4075            percent: false,
4076            comments: Vec::new(),
4077        });
4078        self
4079    }
4080
4081    /// Set OFFSET
4082    pub fn offset(mut self, n: Expression) -> Self {
4083        self.offset = Some(Offset {
4084            this: n,
4085            rows: None,
4086        });
4087        self
4088    }
4089}
4090
4091impl Default for Select {
4092    fn default() -> Self {
4093        Self::new()
4094    }
4095}
4096
4097/// Represent a UNION set operation between two query expressions.
4098///
4099/// When `all` is true, duplicate rows are preserved (UNION ALL).
4100/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
4101/// Supports DuckDB/Snowflake BY NAME and BigQuery BY NAME/CORRESPONDING modifiers.
4102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4103#[cfg_attr(feature = "bindings", derive(TS))]
4104pub struct Union {
4105    /// The left-hand query operand.
4106    pub left: Expression,
4107    /// The right-hand query operand.
4108    pub right: Expression,
4109    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
4110    pub all: bool,
4111    /// Whether DISTINCT was explicitly specified
4112    #[serde(default)]
4113    pub distinct: bool,
4114    /// Optional WITH clause
4115    pub with: Option<With>,
4116    /// ORDER BY applied to entire UNION result
4117    pub order_by: Option<OrderBy>,
4118    /// Row limit applied to the entire UNION result: a legacy count expression,
4119    /// or a complete `Expression::Limit` / `Expression::Fetch` with clause options.
4120    pub limit: Option<Box<Expression>>,
4121    /// OFFSET applied to entire UNION result
4122    pub offset: Option<Box<Expression>>,
4123    /// DISTRIBUTE BY clause (Hive/Spark)
4124    #[serde(default, skip_serializing_if = "Option::is_none")]
4125    pub distribute_by: Option<DistributeBy>,
4126    /// SORT BY clause (Hive/Spark)
4127    #[serde(default, skip_serializing_if = "Option::is_none")]
4128    pub sort_by: Option<SortBy>,
4129    /// CLUSTER BY clause (Hive/Spark)
4130    #[serde(default, skip_serializing_if = "Option::is_none")]
4131    pub cluster_by: Option<ClusterBy>,
4132    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4133    #[serde(default)]
4134    pub by_name: bool,
4135    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4136    #[serde(default, skip_serializing_if = "Option::is_none")]
4137    pub side: Option<String>,
4138    /// BigQuery: Set operation kind (INNER)
4139    #[serde(default, skip_serializing_if = "Option::is_none")]
4140    pub kind: Option<String>,
4141    /// BigQuery: CORRESPONDING modifier
4142    #[serde(default)]
4143    pub corresponding: bool,
4144    /// BigQuery: STRICT modifier (before CORRESPONDING)
4145    #[serde(default)]
4146    pub strict: bool,
4147    /// BigQuery: BY (columns) after CORRESPONDING
4148    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4149    pub on_columns: Vec<Expression>,
4150}
4151
4152/// Iteratively flatten the left-recursive chain to prevent stack overflow
4153/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
4154impl Drop for Union {
4155    fn drop(&mut self) {
4156        loop {
4157            if let Expression::Union(ref mut inner) = self.left {
4158                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4159                let old_left = std::mem::replace(&mut self.left, next_left);
4160                drop(old_left);
4161            } else {
4162                break;
4163            }
4164        }
4165    }
4166}
4167
4168/// Represent an INTERSECT set operation between two query expressions.
4169///
4170/// Returns only rows that appear in both operands. When `all` is true,
4171/// duplicates are preserved according to their multiplicity.
4172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4173#[cfg_attr(feature = "bindings", derive(TS))]
4174pub struct Intersect {
4175    /// The left-hand query operand.
4176    pub left: Expression,
4177    /// The right-hand query operand.
4178    pub right: Expression,
4179    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
4180    pub all: bool,
4181    /// Whether DISTINCT was explicitly specified
4182    #[serde(default)]
4183    pub distinct: bool,
4184    /// Optional WITH clause
4185    pub with: Option<With>,
4186    /// ORDER BY applied to entire INTERSECT result
4187    pub order_by: Option<OrderBy>,
4188    /// Row limit applied to the entire INTERSECT result: a legacy count expression,
4189    /// or a complete `Expression::Limit` / `Expression::Fetch` with clause options.
4190    pub limit: Option<Box<Expression>>,
4191    /// OFFSET applied to entire INTERSECT result
4192    pub offset: Option<Box<Expression>>,
4193    /// DISTRIBUTE BY clause (Hive/Spark)
4194    #[serde(default, skip_serializing_if = "Option::is_none")]
4195    pub distribute_by: Option<DistributeBy>,
4196    /// SORT BY clause (Hive/Spark)
4197    #[serde(default, skip_serializing_if = "Option::is_none")]
4198    pub sort_by: Option<SortBy>,
4199    /// CLUSTER BY clause (Hive/Spark)
4200    #[serde(default, skip_serializing_if = "Option::is_none")]
4201    pub cluster_by: Option<ClusterBy>,
4202    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4203    #[serde(default)]
4204    pub by_name: bool,
4205    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4206    #[serde(default, skip_serializing_if = "Option::is_none")]
4207    pub side: Option<String>,
4208    /// BigQuery: Set operation kind (INNER)
4209    #[serde(default, skip_serializing_if = "Option::is_none")]
4210    pub kind: Option<String>,
4211    /// BigQuery: CORRESPONDING modifier
4212    #[serde(default)]
4213    pub corresponding: bool,
4214    /// BigQuery: STRICT modifier (before CORRESPONDING)
4215    #[serde(default)]
4216    pub strict: bool,
4217    /// BigQuery: BY (columns) after CORRESPONDING
4218    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4219    pub on_columns: Vec<Expression>,
4220}
4221
4222impl Drop for Intersect {
4223    fn drop(&mut self) {
4224        loop {
4225            if let Expression::Intersect(ref mut inner) = self.left {
4226                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4227                let old_left = std::mem::replace(&mut self.left, next_left);
4228                drop(old_left);
4229            } else {
4230                break;
4231            }
4232        }
4233    }
4234}
4235
4236/// Represent an EXCEPT (MINUS) set operation between two query expressions.
4237///
4238/// Returns rows from the left operand that do not appear in the right operand.
4239/// When `all` is true, duplicates are subtracted according to their multiplicity.
4240#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4241#[cfg_attr(feature = "bindings", derive(TS))]
4242pub struct Except {
4243    /// The left-hand query operand.
4244    pub left: Expression,
4245    /// The right-hand query operand (rows to subtract).
4246    pub right: Expression,
4247    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
4248    pub all: bool,
4249    /// Whether DISTINCT was explicitly specified
4250    #[serde(default)]
4251    pub distinct: bool,
4252    /// Optional WITH clause
4253    pub with: Option<With>,
4254    /// ORDER BY applied to entire EXCEPT result
4255    pub order_by: Option<OrderBy>,
4256    /// Row limit applied to the entire EXCEPT result: a legacy count expression,
4257    /// or a complete `Expression::Limit` / `Expression::Fetch` with clause options.
4258    pub limit: Option<Box<Expression>>,
4259    /// OFFSET applied to entire EXCEPT result
4260    pub offset: Option<Box<Expression>>,
4261    /// DISTRIBUTE BY clause (Hive/Spark)
4262    #[serde(default, skip_serializing_if = "Option::is_none")]
4263    pub distribute_by: Option<DistributeBy>,
4264    /// SORT BY clause (Hive/Spark)
4265    #[serde(default, skip_serializing_if = "Option::is_none")]
4266    pub sort_by: Option<SortBy>,
4267    /// CLUSTER BY clause (Hive/Spark)
4268    #[serde(default, skip_serializing_if = "Option::is_none")]
4269    pub cluster_by: Option<ClusterBy>,
4270    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4271    #[serde(default)]
4272    pub by_name: bool,
4273    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4274    #[serde(default, skip_serializing_if = "Option::is_none")]
4275    pub side: Option<String>,
4276    /// BigQuery: Set operation kind (INNER)
4277    #[serde(default, skip_serializing_if = "Option::is_none")]
4278    pub kind: Option<String>,
4279    /// BigQuery: CORRESPONDING modifier
4280    #[serde(default)]
4281    pub corresponding: bool,
4282    /// BigQuery: STRICT modifier (before CORRESPONDING)
4283    #[serde(default)]
4284    pub strict: bool,
4285    /// BigQuery: BY (columns) after CORRESPONDING
4286    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4287    pub on_columns: Vec<Expression>,
4288}
4289
4290impl Drop for Except {
4291    fn drop(&mut self) {
4292        loop {
4293            if let Expression::Except(ref mut inner) = self.left {
4294                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4295                let old_left = std::mem::replace(&mut self.left, next_left);
4296                drop(old_left);
4297            } else {
4298                break;
4299            }
4300        }
4301    }
4302}
4303
4304/// INTO clause for SELECT INTO statements
4305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4306#[cfg_attr(feature = "bindings", derive(TS))]
4307pub struct SelectInto {
4308    /// Target table or variable (used when single target)
4309    pub this: Expression,
4310    /// Whether TEMPORARY keyword was used
4311    #[serde(default)]
4312    pub temporary: bool,
4313    /// Whether UNLOGGED keyword was used (PostgreSQL)
4314    #[serde(default)]
4315    pub unlogged: bool,
4316    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4317    #[serde(default)]
4318    pub bulk_collect: bool,
4319    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4320    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4321    pub expressions: Vec<Expression>,
4322}
4323
4324/// Represent a parenthesized subquery expression.
4325///
4326/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4327/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4328/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4329/// modifiers are rendered inside or outside the parentheses.
4330///
4331/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4332/// scalar subqueries in select-lists, and derived tables.
4333#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4334#[cfg_attr(feature = "bindings", derive(TS))]
4335pub struct Subquery {
4336    /// The inner query expression.
4337    pub this: Expression,
4338    /// Optional alias for the derived table.
4339    pub alias: Option<Identifier>,
4340    /// Optional column aliases: AS t(c1, c2)
4341    pub column_aliases: Vec<Identifier>,
4342    /// Whether AS keyword was explicitly used for the alias.
4343    #[serde(default)]
4344    pub alias_explicit_as: bool,
4345    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4346    #[serde(skip_serializing_if = "Option::is_none", default)]
4347    pub alias_keyword: Option<String>,
4348    /// ORDER BY clause (for parenthesized queries)
4349    pub order_by: Option<OrderBy>,
4350    /// LIMIT clause
4351    pub limit: Option<Limit>,
4352    /// OFFSET clause
4353    pub offset: Option<Offset>,
4354    /// DISTRIBUTE BY clause (Hive/Spark)
4355    #[serde(default, skip_serializing_if = "Option::is_none")]
4356    pub distribute_by: Option<DistributeBy>,
4357    /// SORT BY clause (Hive/Spark)
4358    #[serde(default, skip_serializing_if = "Option::is_none")]
4359    pub sort_by: Option<SortBy>,
4360    /// CLUSTER BY clause (Hive/Spark)
4361    #[serde(default, skip_serializing_if = "Option::is_none")]
4362    pub cluster_by: Option<ClusterBy>,
4363    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4364    #[serde(default)]
4365    pub lateral: bool,
4366    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4367    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4368    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4369    #[serde(default)]
4370    pub modifiers_inside: bool,
4371    /// Trailing comments after the closing paren
4372    #[serde(default)]
4373    pub trailing_comments: Vec<String>,
4374    /// Inferred data type from type annotation
4375    #[serde(default, skip_serializing_if = "Option::is_none")]
4376    #[ast(skip)]
4377    pub inferred_type: Option<DataType>,
4378}
4379
4380/// Pipe operator expression: query |> transform
4381///
4382/// Used in DataFusion and BigQuery pipe syntax:
4383///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4385#[cfg_attr(feature = "bindings", derive(TS))]
4386pub struct PipeOperator {
4387    /// The input query/expression (left side of |>)
4388    pub this: Expression,
4389    /// The piped operation (right side of |>)
4390    pub expression: Expression,
4391}
4392
4393/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4394#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4395#[cfg_attr(feature = "bindings", derive(TS))]
4396pub struct Values {
4397    /// The rows of values
4398    pub expressions: Vec<Tuple>,
4399    /// Optional alias for the table
4400    pub alias: Option<Identifier>,
4401    /// Optional column aliases: AS t(c1, c2)
4402    pub column_aliases: Vec<Identifier>,
4403}
4404
4405/// PIVOT operation - supports both standard and DuckDB simplified syntax
4406///
4407/// Standard syntax (in FROM clause):
4408///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4409///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4410///
4411/// DuckDB simplified syntax (statement-level):
4412///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4413///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4415#[cfg_attr(feature = "bindings", derive(TS))]
4416pub struct Pivot {
4417    /// Source table/expression
4418    pub this: Expression,
4419    /// For standard PIVOT: the aggregation function(s) (first is primary)
4420    /// For DuckDB simplified: unused (use `using` instead)
4421    #[serde(default)]
4422    pub expressions: Vec<Expression>,
4423    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4424    #[serde(default)]
4425    pub fields: Vec<Expression>,
4426    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4427    #[serde(default)]
4428    pub using: Vec<Expression>,
4429    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4430    #[serde(default)]
4431    pub group: Option<Box<Expression>>,
4432    /// Whether this is an UNPIVOT (vs PIVOT)
4433    #[serde(default)]
4434    pub unpivot: bool,
4435    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4436    #[serde(default)]
4437    pub into: Option<Box<Expression>>,
4438    /// Optional alias
4439    #[serde(default)]
4440    pub alias: Option<Identifier>,
4441    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4442    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4443    pub alias_columns: Vec<Identifier>,
4444    /// Include/exclude nulls (for UNPIVOT)
4445    #[serde(default)]
4446    pub include_nulls: Option<bool>,
4447    /// Default on null value (Snowflake)
4448    #[serde(default)]
4449    pub default_on_null: Option<Box<Expression>>,
4450    /// WITH clause (CTEs)
4451    #[serde(default, skip_serializing_if = "Option::is_none")]
4452    pub with: Option<With>,
4453}
4454
4455/// UNPIVOT operation
4456#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4457#[cfg_attr(feature = "bindings", derive(TS))]
4458pub struct Unpivot {
4459    pub this: Expression,
4460    pub value_column: Identifier,
4461    pub name_column: Identifier,
4462    pub columns: Vec<Expression>,
4463    pub alias: Option<Identifier>,
4464    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4465    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4466    pub alias_columns: Vec<Identifier>,
4467    /// Whether the value_column was parenthesized in the original SQL
4468    #[serde(default)]
4469    pub value_column_parenthesized: bool,
4470    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4471    #[serde(default)]
4472    pub include_nulls: Option<bool>,
4473    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4474    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4475    pub extra_value_columns: Vec<Identifier>,
4476}
4477
4478/// PIVOT alias for aliasing pivot expressions
4479/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4481#[cfg_attr(feature = "bindings", derive(TS))]
4482pub struct PivotAlias {
4483    pub this: Expression,
4484    pub alias: Expression,
4485}
4486
4487/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4489#[cfg_attr(feature = "bindings", derive(TS))]
4490pub struct PreWhere {
4491    pub this: Expression,
4492}
4493
4494/// STREAM definition (Snowflake) - for change data capture
4495#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4496#[cfg_attr(feature = "bindings", derive(TS))]
4497pub struct Stream {
4498    pub this: Expression,
4499    #[serde(skip_serializing_if = "Option::is_none")]
4500    pub on: Option<Expression>,
4501    #[serde(skip_serializing_if = "Option::is_none")]
4502    pub show_initial_rows: Option<bool>,
4503}
4504
4505/// USING DATA clause for data import statements
4506#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4507#[cfg_attr(feature = "bindings", derive(TS))]
4508pub struct UsingData {
4509    pub this: Expression,
4510}
4511
4512/// XML Namespace declaration
4513#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4514#[cfg_attr(feature = "bindings", derive(TS))]
4515pub struct XmlNamespace {
4516    pub this: Expression,
4517    #[serde(skip_serializing_if = "Option::is_none")]
4518    pub alias: Option<Identifier>,
4519}
4520
4521/// ROW FORMAT clause for Hive/Spark
4522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4523#[cfg_attr(feature = "bindings", derive(TS))]
4524pub struct RowFormat {
4525    pub delimited: bool,
4526    pub fields_terminated_by: Option<String>,
4527    pub collection_items_terminated_by: Option<String>,
4528    pub map_keys_terminated_by: Option<String>,
4529    pub lines_terminated_by: Option<String>,
4530    pub null_defined_as: Option<String>,
4531}
4532
4533/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4534#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4535#[cfg_attr(feature = "bindings", derive(TS))]
4536pub struct DirectoryInsert {
4537    pub local: bool,
4538    pub path: String,
4539    pub row_format: Option<RowFormat>,
4540    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4541    #[serde(default)]
4542    pub stored_as: Option<String>,
4543}
4544
4545/// INSERT statement
4546#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4547#[cfg_attr(feature = "bindings", derive(TS))]
4548pub struct Insert {
4549    pub table: TableRef,
4550    pub columns: Vec<Identifier>,
4551    pub values: Vec<Vec<Expression>>,
4552    pub query: Option<Expression>,
4553    /// INSERT OVERWRITE for Hive/Spark
4554    pub overwrite: bool,
4555    /// PARTITION clause for Hive/Spark
4556    pub partition: Vec<(Identifier, Option<Expression>)>,
4557    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4558    #[serde(default)]
4559    pub directory: Option<DirectoryInsert>,
4560    /// RETURNING clause (PostgreSQL, SQLite)
4561    #[serde(default)]
4562    pub returning: Vec<Expression>,
4563    /// OUTPUT clause (TSQL)
4564    #[serde(default)]
4565    pub output: Option<OutputClause>,
4566    /// ON CONFLICT clause (PostgreSQL, SQLite)
4567    #[serde(default)]
4568    pub on_conflict: Option<Box<Expression>>,
4569    /// Leading comments before the statement
4570    #[serde(default)]
4571    pub leading_comments: Vec<String>,
4572    /// IF EXISTS clause (Hive)
4573    #[serde(default)]
4574    pub if_exists: bool,
4575    /// WITH clause (CTEs)
4576    #[serde(default)]
4577    pub with: Option<With>,
4578    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4579    #[serde(default)]
4580    pub ignore: bool,
4581    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4582    #[serde(default)]
4583    pub source_alias: Option<Identifier>,
4584    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4585    #[serde(default)]
4586    pub alias: Option<Identifier>,
4587    /// Whether the alias uses explicit AS keyword
4588    #[serde(default)]
4589    pub alias_explicit_as: bool,
4590    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4591    #[serde(default)]
4592    pub default_values: bool,
4593    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4594    #[serde(default)]
4595    pub by_name: bool,
4596    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4597    #[serde(default, skip_serializing_if = "Option::is_none")]
4598    pub conflict_action: Option<String>,
4599    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4600    #[serde(default)]
4601    pub is_replace: bool,
4602    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4603    #[serde(default, skip_serializing_if = "Option::is_none")]
4604    pub hint: Option<Hint>,
4605    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4606    #[serde(default)]
4607    pub replace_where: Option<Box<Expression>>,
4608    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4609    #[serde(default)]
4610    pub source: Option<Box<Expression>>,
4611    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4612    #[serde(default, skip_serializing_if = "Option::is_none")]
4613    pub function_target: Option<Box<Expression>>,
4614    /// ClickHouse: PARTITION BY expr
4615    #[serde(default, skip_serializing_if = "Option::is_none")]
4616    pub partition_by: Option<Box<Expression>>,
4617    /// ClickHouse: SETTINGS key = val, ...
4618    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4619    pub settings: Vec<Expression>,
4620}
4621
4622/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4623#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4624#[cfg_attr(feature = "bindings", derive(TS))]
4625pub struct OutputClause {
4626    /// Columns/expressions to output
4627    pub columns: Vec<Expression>,
4628    /// Optional INTO target table or table variable
4629    #[serde(default)]
4630    pub into_table: Option<Expression>,
4631}
4632
4633/// UPDATE statement
4634#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4635#[cfg_attr(feature = "bindings", derive(TS))]
4636pub struct Update {
4637    pub table: TableRef,
4638    #[serde(default)]
4639    pub hint: Option<Hint>,
4640    /// Additional tables for multi-table UPDATE (MySQL syntax)
4641    #[serde(default)]
4642    pub extra_tables: Vec<TableRef>,
4643    /// JOINs attached to the table list (MySQL multi-table syntax)
4644    #[serde(default)]
4645    pub table_joins: Vec<Join>,
4646    pub set: Vec<(Identifier, Expression)>,
4647    pub from_clause: Option<From>,
4648    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4649    #[serde(default)]
4650    pub from_joins: Vec<Join>,
4651    pub where_clause: Option<Where>,
4652    /// RETURNING clause (PostgreSQL, SQLite)
4653    #[serde(default)]
4654    pub returning: Vec<Expression>,
4655    /// OUTPUT clause (TSQL)
4656    #[serde(default)]
4657    pub output: Option<OutputClause>,
4658    /// WITH clause (CTEs)
4659    #[serde(default)]
4660    pub with: Option<With>,
4661    /// Leading comments before the statement
4662    #[serde(default)]
4663    pub leading_comments: Vec<String>,
4664    /// LIMIT clause (MySQL)
4665    #[serde(default)]
4666    pub limit: Option<Expression>,
4667    /// ORDER BY clause (MySQL)
4668    #[serde(default)]
4669    pub order_by: Option<OrderBy>,
4670    /// Whether FROM clause appears before SET (Snowflake syntax)
4671    #[serde(default)]
4672    pub from_before_set: bool,
4673}
4674
4675/// DELETE statement
4676#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4677#[cfg_attr(feature = "bindings", derive(TS))]
4678pub struct Delete {
4679    pub table: TableRef,
4680    #[serde(default)]
4681    pub hint: Option<Hint>,
4682    /// ClickHouse: ON CLUSTER clause for distributed DDL
4683    #[serde(default, skip_serializing_if = "Option::is_none")]
4684    pub on_cluster: Option<OnCluster>,
4685    /// Optional alias for the table
4686    pub alias: Option<Identifier>,
4687    /// Whether the alias was declared with explicit AS keyword
4688    #[serde(default)]
4689    pub alias_explicit_as: bool,
4690    /// PostgreSQL/DuckDB USING clause - additional tables to join
4691    pub using: Vec<TableRef>,
4692    pub where_clause: Option<Where>,
4693    /// OUTPUT clause (TSQL)
4694    #[serde(default)]
4695    pub output: Option<OutputClause>,
4696    /// Leading comments before the statement
4697    #[serde(default)]
4698    pub leading_comments: Vec<String>,
4699    /// WITH clause (CTEs)
4700    #[serde(default)]
4701    pub with: Option<With>,
4702    /// LIMIT clause (MySQL)
4703    #[serde(default)]
4704    pub limit: Option<Expression>,
4705    /// ORDER BY clause (MySQL)
4706    #[serde(default)]
4707    pub order_by: Option<OrderBy>,
4708    /// RETURNING clause (PostgreSQL)
4709    #[serde(default)]
4710    pub returning: Vec<Expression>,
4711    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4712    /// These are the target tables to delete from
4713    #[serde(default)]
4714    pub tables: Vec<TableRef>,
4715    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4716    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4717    #[serde(default)]
4718    pub tables_from_using: bool,
4719    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4720    #[serde(default)]
4721    pub joins: Vec<Join>,
4722    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4723    #[serde(default)]
4724    pub force_index: Option<String>,
4725    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4726    #[serde(default)]
4727    pub no_from: bool,
4728}
4729
4730/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4731#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4732#[cfg_attr(feature = "bindings", derive(TS))]
4733pub struct CopyStmt {
4734    /// Target table or query
4735    pub this: Expression,
4736    /// True for FROM (loading into table), false for TO (exporting)
4737    pub kind: bool,
4738    /// Source/destination file(s) or stage
4739    pub files: Vec<Expression>,
4740    /// Copy parameters
4741    #[serde(default)]
4742    pub params: Vec<CopyParameter>,
4743    /// Credentials for external access
4744    #[serde(default)]
4745    pub credentials: Option<Box<Credentials>>,
4746    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4747    #[serde(default)]
4748    pub is_into: bool,
4749    /// Whether parameters are wrapped in WITH (...) syntax
4750    #[serde(default)]
4751    pub with_wrapped: bool,
4752}
4753
4754/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4756#[cfg_attr(feature = "bindings", derive(TS))]
4757pub struct CopyParameter {
4758    pub name: String,
4759    pub value: Option<Expression>,
4760    pub values: Vec<Expression>,
4761    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4762    #[serde(default)]
4763    pub eq: bool,
4764}
4765
4766/// Credentials for external access (S3, Azure, etc.)
4767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4768#[cfg_attr(feature = "bindings", derive(TS))]
4769pub struct Credentials {
4770    pub credentials: Vec<(String, String)>,
4771    pub encryption: Option<String>,
4772    pub storage: Option<String>,
4773}
4774
4775/// PUT statement (Snowflake)
4776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4777#[cfg_attr(feature = "bindings", derive(TS))]
4778pub struct PutStmt {
4779    /// Source file path
4780    pub source: String,
4781    /// Whether source was quoted in the original SQL
4782    #[serde(default)]
4783    pub source_quoted: bool,
4784    /// Target stage
4785    pub target: Expression,
4786    /// PUT parameters
4787    #[serde(default)]
4788    pub params: Vec<CopyParameter>,
4789}
4790
4791/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4792#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4793#[cfg_attr(feature = "bindings", derive(TS))]
4794pub struct StageReference {
4795    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4796    pub name: String,
4797    /// Optional path within the stage (e.g., "/path/to/file.csv")
4798    #[serde(default)]
4799    pub path: Option<String>,
4800    /// Optional FILE_FORMAT parameter
4801    #[serde(default)]
4802    pub file_format: Option<Expression>,
4803    /// Optional PATTERN parameter
4804    #[serde(default)]
4805    pub pattern: Option<String>,
4806    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4807    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4808    pub quoted: bool,
4809}
4810
4811/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4813#[cfg_attr(feature = "bindings", derive(TS))]
4814pub struct HistoricalData {
4815    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4816    pub this: Box<Expression>,
4817    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4818    pub kind: String,
4819    /// The expression value (e.g., the statement ID or timestamp)
4820    pub expression: Box<Expression>,
4821}
4822
4823/// Represent an aliased expression (`expr AS name`).
4824///
4825/// Used for column aliases in select-lists, table aliases on subqueries,
4826/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4827#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4828#[cfg_attr(feature = "bindings", derive(TS))]
4829pub struct Alias {
4830    /// The expression being aliased.
4831    pub this: Expression,
4832    /// The alias name (required for simple aliases, optional when only column aliases provided)
4833    pub alias: Identifier,
4834    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4835    #[serde(default)]
4836    pub column_aliases: Vec<Identifier>,
4837    /// Whether AS keyword was explicitly used for the alias.
4838    #[serde(default)]
4839    pub alias_explicit_as: bool,
4840    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4841    #[serde(skip_serializing_if = "Option::is_none", default)]
4842    pub alias_keyword: Option<String>,
4843    /// Comments that appeared between the expression and AS keyword
4844    #[serde(default)]
4845    pub pre_alias_comments: Vec<String>,
4846    /// Trailing comments that appeared after the alias
4847    #[serde(default)]
4848    pub trailing_comments: Vec<String>,
4849    /// Inferred data type from type annotation
4850    #[serde(default, skip_serializing_if = "Option::is_none")]
4851    #[ast(skip)]
4852    pub inferred_type: Option<DataType>,
4853}
4854
4855impl Alias {
4856    /// Create a simple alias
4857    pub fn new(this: Expression, alias: Identifier) -> Self {
4858        Self {
4859            this,
4860            alias,
4861            column_aliases: Vec::new(),
4862            alias_explicit_as: false,
4863            alias_keyword: None,
4864            pre_alias_comments: Vec::new(),
4865            trailing_comments: Vec::new(),
4866            inferred_type: None,
4867        }
4868    }
4869
4870    /// Create an alias with column aliases only (no table alias name)
4871    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4872        Self {
4873            this,
4874            alias: Identifier::empty(),
4875            column_aliases,
4876            alias_explicit_as: false,
4877            alias_keyword: None,
4878            pre_alias_comments: Vec::new(),
4879            trailing_comments: Vec::new(),
4880            inferred_type: None,
4881        }
4882    }
4883}
4884
4885/// Represent a type cast expression.
4886///
4887/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4888/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4889/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4890/// CONVERSION ERROR (Oracle) clauses.
4891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4892#[cfg_attr(feature = "bindings", derive(TS))]
4893pub struct Cast {
4894    /// The expression being cast.
4895    pub this: Expression,
4896    /// The target data type.
4897    pub to: DataType,
4898    #[serde(default)]
4899    pub trailing_comments: Vec<String>,
4900    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4901    #[serde(default)]
4902    pub double_colon_syntax: bool,
4903    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4904    #[serde(skip_serializing_if = "Option::is_none", default)]
4905    pub format: Option<Box<Expression>>,
4906    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4907    #[serde(skip_serializing_if = "Option::is_none", default)]
4908    pub default: Option<Box<Expression>>,
4909    /// Inferred data type from type annotation
4910    #[serde(default, skip_serializing_if = "Option::is_none")]
4911    #[ast(skip)]
4912    pub inferred_type: Option<DataType>,
4913}
4914
4915///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4916#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4917#[cfg_attr(feature = "bindings", derive(TS))]
4918pub struct CollationExpr {
4919    pub this: Expression,
4920    pub collation: String,
4921    /// True if the collation was single-quoted in the original SQL (string literal)
4922    #[serde(default)]
4923    pub quoted: bool,
4924    /// True if the collation was double-quoted in the original SQL (identifier)
4925    #[serde(default)]
4926    pub double_quoted: bool,
4927}
4928
4929/// Represent a CASE expression (both simple and searched forms).
4930///
4931/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4932/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4933/// Each entry in `whens` is a `(condition, result)` pair.
4934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4935#[cfg_attr(feature = "bindings", derive(TS))]
4936pub struct Case {
4937    /// The operand for simple CASE, or `None` for searched CASE.
4938    pub operand: Option<Expression>,
4939    /// Pairs of (WHEN condition, THEN result).
4940    pub whens: Vec<(Expression, Expression)>,
4941    /// Optional ELSE result.
4942    pub else_: Option<Expression>,
4943    /// Comments from the CASE keyword (emitted after END)
4944    #[serde(default)]
4945    #[serde(skip_serializing_if = "Vec::is_empty")]
4946    pub comments: Vec<String>,
4947    /// Inferred data type from type annotation
4948    #[serde(default, skip_serializing_if = "Option::is_none")]
4949    #[ast(skip)]
4950    pub inferred_type: Option<DataType>,
4951}
4952
4953/// Represent a binary operation (two operands separated by an operator).
4954///
4955/// This is the shared payload struct for all binary operator variants in the
4956/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4957/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4958/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4959/// preservation of inline comments around operators.
4960#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4961#[cfg_attr(feature = "bindings", derive(TS))]
4962pub struct BinaryOp {
4963    pub left: Expression,
4964    pub right: Expression,
4965    /// Comments after the left operand (before the operator)
4966    #[serde(default)]
4967    pub left_comments: Vec<String>,
4968    /// Comments after the operator (before the right operand)
4969    #[serde(default)]
4970    pub operator_comments: Vec<String>,
4971    /// Comments after the right operand
4972    #[serde(default)]
4973    pub trailing_comments: Vec<String>,
4974    /// Inferred data type from type annotation
4975    #[serde(default, skip_serializing_if = "Option::is_none")]
4976    #[ast(skip)]
4977    pub inferred_type: Option<DataType>,
4978}
4979
4980impl BinaryOp {
4981    pub fn new(left: Expression, right: Expression) -> Self {
4982        Self {
4983            left,
4984            right,
4985            left_comments: Vec::new(),
4986            operator_comments: Vec::new(),
4987            trailing_comments: Vec::new(),
4988            inferred_type: None,
4989        }
4990    }
4991}
4992
4993/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4995#[cfg_attr(feature = "bindings", derive(TS))]
4996pub struct LikeOp {
4997    pub left: Expression,
4998    pub right: Expression,
4999    /// ESCAPE character/expression
5000    #[serde(default)]
5001    pub escape: Option<Expression>,
5002    /// Quantifier: ANY, ALL, or SOME
5003    #[serde(default)]
5004    pub quantifier: Option<String>,
5005    /// Inferred data type from type annotation
5006    #[serde(default, skip_serializing_if = "Option::is_none")]
5007    #[ast(skip)]
5008    pub inferred_type: Option<DataType>,
5009}
5010
5011impl LikeOp {
5012    pub fn new(left: Expression, right: Expression) -> Self {
5013        Self {
5014            left,
5015            right,
5016            escape: None,
5017            quantifier: None,
5018            inferred_type: None,
5019        }
5020    }
5021
5022    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
5023        Self {
5024            left,
5025            right,
5026            escape: Some(escape),
5027            quantifier: None,
5028            inferred_type: None,
5029        }
5030    }
5031}
5032
5033/// Represent a unary operation (single operand with a prefix operator).
5034///
5035/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
5036#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5037#[cfg_attr(feature = "bindings", derive(TS))]
5038pub struct UnaryOp {
5039    /// The operand expression.
5040    pub this: Expression,
5041    /// Inferred data type from type annotation
5042    #[serde(default, skip_serializing_if = "Option::is_none")]
5043    #[ast(skip)]
5044    pub inferred_type: Option<DataType>,
5045}
5046
5047impl UnaryOp {
5048    pub fn new(this: Expression) -> Self {
5049        Self {
5050            this,
5051            inferred_type: None,
5052        }
5053    }
5054}
5055
5056/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
5057///
5058/// Either `expressions` (a value list) or `query` (a subquery) is populated,
5059/// but not both. When `not` is true, the predicate is `NOT IN`.
5060#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5061#[cfg_attr(feature = "bindings", derive(TS))]
5062pub struct In {
5063    /// The expression being tested.
5064    pub this: Expression,
5065    /// The value list (mutually exclusive with `query`).
5066    pub expressions: Vec<Expression>,
5067    /// A subquery (mutually exclusive with `expressions`).
5068    pub query: Option<Expression>,
5069    /// Whether this is NOT IN.
5070    pub not: bool,
5071    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5072    pub global: bool,
5073    /// BigQuery: IN UNNEST(expr)
5074    #[serde(default, skip_serializing_if = "Option::is_none")]
5075    pub unnest: Option<Box<Expression>>,
5076    /// Whether the right side is a bare field reference (no parentheses).
5077    /// Matches Python sqlglot's `field` attribute on `In` expression.
5078    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
5079    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5080    pub is_field: bool,
5081}
5082
5083/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
5084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5085#[cfg_attr(feature = "bindings", derive(TS))]
5086pub struct Between {
5087    /// The expression being tested.
5088    pub this: Expression,
5089    /// The lower bound.
5090    pub low: Expression,
5091    /// The upper bound.
5092    pub high: Expression,
5093    /// Whether this is NOT BETWEEN.
5094    pub not: bool,
5095    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
5096    #[serde(default)]
5097    pub symmetric: Option<bool>,
5098}
5099
5100/// IS NULL predicate
5101#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5102#[cfg_attr(feature = "bindings", derive(TS))]
5103pub struct IsNull {
5104    pub this: Expression,
5105    pub not: bool,
5106    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
5107    #[serde(default)]
5108    pub postfix_form: bool,
5109}
5110
5111/// IS TRUE / IS FALSE predicate
5112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5113#[cfg_attr(feature = "bindings", derive(TS))]
5114pub struct IsTrueFalse {
5115    pub this: Expression,
5116    pub not: bool,
5117}
5118
5119/// IS JSON predicate (SQL standard)
5120/// Checks if a value is valid JSON
5121#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5122#[cfg_attr(feature = "bindings", derive(TS))]
5123pub struct IsJson {
5124    pub this: Expression,
5125    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
5126    pub json_type: Option<String>,
5127    /// Key uniqueness constraint
5128    pub unique_keys: Option<JsonUniqueKeys>,
5129    /// Whether IS NOT JSON
5130    pub negated: bool,
5131}
5132
5133/// JSON unique keys constraint variants
5134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5135#[cfg_attr(feature = "bindings", derive(TS))]
5136pub enum JsonUniqueKeys {
5137    /// WITH UNIQUE KEYS
5138    With,
5139    /// WITHOUT UNIQUE KEYS
5140    Without,
5141    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
5142    Shorthand,
5143}
5144
5145/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
5146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5147#[cfg_attr(feature = "bindings", derive(TS))]
5148pub struct Exists {
5149    /// The subquery expression.
5150    pub this: Expression,
5151    /// Whether this is NOT EXISTS.
5152    pub not: bool,
5153}
5154
5155#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5156#[cfg_attr(feature = "bindings", derive(TS))]
5157pub struct Upsert {
5158    /// Retained source semantics; serialized independently of generator configuration.
5159    #[serde(default, skip_serializing_if = "Option::is_none")]
5160    #[ast(skip)]
5161    pub source_dialect: Option<crate::dialects::DialectType>,
5162
5163    pub table: TableRef,
5164    pub partition: Option<Expression>,
5165    pub columns: Vec<Identifier>,
5166    pub source: Expression,
5167    pub condition: Option<Expression>,
5168    pub primary_key: bool,
5169}
5170
5171#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5172#[cfg_attr(feature = "bindings", derive(TS))]
5173pub struct PartitionSpec {
5174    /// Retained source semantics; serialized independently of generator configuration.
5175    #[serde(default, skip_serializing_if = "Option::is_none")]
5176    #[ast(skip)]
5177    pub source_dialect: Option<crate::dialects::DialectType>,
5178
5179    pub method: String,
5180    pub columns: Vec<Expression>,
5181    pub partitions: Option<Expression>,
5182    pub ranges: Vec<PartitionRangeSpec>,
5183    pub primary_key_check: Option<bool>,
5184    pub properties: Vec<Expression>,
5185    pub subpartition: Option<Box<PartitionSpec>>,
5186}
5187
5188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5189#[cfg_attr(feature = "bindings", derive(TS))]
5190pub struct PartitionRangeSpec {
5191    pub name: Option<Identifier>,
5192    pub kind: String,
5193    pub values: Vec<Expression>,
5194    pub dynamic: bool,
5195    pub direction: Option<String>,
5196    pub threshold: Option<Expression>,
5197    pub interval: Option<(Expression, Option<String>)>,
5198    pub properties: Vec<Expression>,
5199}
5200
5201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5202#[cfg_attr(feature = "bindings", derive(TS))]
5203pub struct StorageProperty {
5204    /// Retained source semantics; serialized independently of generator configuration.
5205    #[serde(default, skip_serializing_if = "Option::is_none")]
5206    #[ast(skip)]
5207    pub source_dialect: Option<crate::dialects::DialectType>,
5208
5209    pub name: String,
5210    pub values: Vec<Expression>,
5211}
5212
5213#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5214#[cfg_attr(feature = "bindings", derive(TS))]
5215pub struct Hierarchy {
5216    /// Retained source semantics; serialized independently of generator configuration.
5217    #[serde(default, skip_serializing_if = "Option::is_none")]
5218    #[ast(skip)]
5219    pub source_dialect: Option<crate::dialects::DialectType>,
5220
5221    pub name: String,
5222    pub source: Expression,
5223    pub start: Option<Expression>,
5224    pub siblings: Vec<Ordered>,
5225    pub depth: Option<Expression>,
5226    pub multiparent: Option<String>,
5227    pub orphan: Option<String>,
5228    pub cycle: Option<String>,
5229    pub cache: Option<String>,
5230}
5231
5232#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5233#[cfg_attr(feature = "bindings", derive(TS))]
5234pub struct ViewParameter {
5235    /// Retained source semantics; serialized independently of generator configuration.
5236    #[serde(default, skip_serializing_if = "Option::is_none")]
5237    #[ast(skip)]
5238    pub source_dialect: Option<crate::dialects::DialectType>,
5239
5240    pub name: Identifier,
5241    pub value: Expression,
5242}
5243
5244#[derive(
5245    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
5246)]
5247#[cfg_attr(feature = "bindings", derive(TS))]
5248pub struct JsonOptions {
5249    pub wrapper: Option<String>,
5250    pub on_empty: Option<SqlBehavior>,
5251    pub on_error: Option<SqlBehavior>,
5252}
5253
5254#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5255#[cfg_attr(feature = "bindings", derive(TS))]
5256pub struct SqlBehavior {
5257    /// ERROR, NULL, DEFAULT, EMPTY ARRAY, or EMPTY OBJECT.
5258    pub kind: String,
5259    pub value: Option<Expression>,
5260}
5261
5262/// Procedure invocation, including library member calls and asynchronous execution.
5263#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5264#[cfg_attr(feature = "bindings", derive(TS))]
5265pub struct Call {
5266    /// Retained source semantics; serialized independently of generator configuration.
5267    #[serde(default, skip_serializing_if = "Option::is_none")]
5268    #[ast(skip)]
5269    pub source_dialect: Option<crate::dialects::DialectType>,
5270
5271    pub name: Vec<Identifier>,
5272    pub member: Option<Identifier>,
5273    pub arguments: Vec<Expression>,
5274    pub asynchronous: bool,
5275    pub hints: Vec<Expression>,
5276}
5277
5278/// Regex search options shared by predicates, extraction, replacement, and position calls.
5279#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5280#[cfg_attr(feature = "bindings", derive(TS))]
5281pub struct RegexOptions {
5282    #[serde(default, skip_serializing_if = "Option::is_none")]
5283    #[ast(skip)]
5284    pub source_dialect: Option<crate::dialects::DialectType>,
5285    /// Original spelling when a dialect has more than one native alias.
5286    pub source_name: String,
5287    #[serde(default)]
5288    pub negated: bool,
5289    pub start: Option<Expression>,
5290    pub occurrence: Option<Expression>,
5291    pub flags: Option<Expression>,
5292    pub position_after: Option<bool>,
5293}
5294
5295/// Grouping-set selection and result-delivery options.
5296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5297#[cfg_attr(feature = "bindings", derive(TS))]
5298pub struct GroupingOptions {
5299    #[serde(default, skip_serializing_if = "Option::is_none")]
5300    #[ast(skip)]
5301    pub source_dialect: Option<crate::dialects::DialectType>,
5302    pub best: Option<Expression>,
5303    pub limit: Option<Expression>,
5304    pub offset: Option<Expression>,
5305    pub subtotal: bool,
5306    pub balance: bool,
5307    pub total: bool,
5308    pub structured: bool,
5309    pub overview: bool,
5310    pub prefix: Option<Expression>,
5311    pub multiple_resultsets: bool,
5312}
5313
5314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5315#[cfg_attr(feature = "bindings", derive(TS))]
5316pub struct ResultSerialization {
5317    /// JSON or XML, validated by the HANA parser.
5318    pub format: String,
5319    pub options: Vec<(String, String)>,
5320    #[serde(default, skip_serializing_if = "Option::is_none")]
5321    pub returning: Option<DataType>,
5322}
5323
5324/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
5325///
5326/// This is the generic function node. Well-known aggregates, window functions,
5327/// and built-in functions each have their own dedicated `Expression` variants
5328/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
5329/// not recognize as built-ins are represented with this struct.
5330#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5331#[cfg_attr(feature = "bindings", derive(TS))]
5332pub struct Function {
5333    /// Qualified name components preserve quoting without changing the node kind.
5334    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5335    pub qualified_name: Vec<Identifier>,
5336    /// Optional DEFAULT/NULL/ERROR behavior after the arguments.
5337    #[serde(default, skip_serializing_if = "Option::is_none")]
5338    pub on_error: Option<Box<SqlBehavior>>,
5339    /// Dialect whose call semantics must be retained through independent generation.
5340    #[serde(default, skip_serializing_if = "Option::is_none")]
5341    #[ast(skip)]
5342    pub source_dialect: Option<crate::dialects::DialectType>,
5343
5344    /// The function name, as originally written (may be schema-qualified).
5345    pub name: String,
5346    /// Positional arguments to the function.
5347    pub args: Vec<Expression>,
5348    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
5349    pub distinct: bool,
5350    #[serde(default)]
5351    pub trailing_comments: Vec<String>,
5352    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
5353    #[serde(default)]
5354    pub use_bracket_syntax: bool,
5355    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
5356    #[serde(default)]
5357    pub no_parens: bool,
5358    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
5359    #[serde(default)]
5360    pub quoted: bool,
5361    /// Source position span
5362    #[serde(default, skip_serializing_if = "Option::is_none")]
5363    pub span: Option<Span>,
5364    /// Inferred data type from type annotation
5365    #[serde(default, skip_serializing_if = "Option::is_none")]
5366    #[ast(skip)]
5367    pub inferred_type: Option<DataType>,
5368}
5369
5370impl Default for Function {
5371    fn default() -> Self {
5372        Self {
5373            source_dialect: None,
5374            qualified_name: Vec::new(),
5375            on_error: None,
5376            name: String::new(),
5377            args: Vec::new(),
5378            distinct: false,
5379            trailing_comments: Vec::new(),
5380            use_bracket_syntax: false,
5381            no_parens: false,
5382            quoted: false,
5383            span: None,
5384            inferred_type: None,
5385        }
5386    }
5387}
5388
5389impl Function {
5390    /// Construct a call with individually quoted qualified name components.
5391    pub fn qualified(name: Vec<Identifier>, args: Vec<Expression>) -> Self {
5392        Self {
5393            name: name
5394                .iter()
5395                .map(|part| part.name.as_str())
5396                .collect::<Vec<_>>()
5397                .join("."),
5398            qualified_name: name,
5399            args,
5400            ..Default::default()
5401        }
5402    }
5403    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
5404        Self {
5405            source_dialect: None,
5406            qualified_name: Vec::new(),
5407            on_error: None,
5408            name: name.into(),
5409            args,
5410            distinct: false,
5411            trailing_comments: Vec::new(),
5412            use_bracket_syntax: false,
5413            no_parens: false,
5414            quoted: false,
5415            span: None,
5416            inferred_type: None,
5417        }
5418    }
5419}
5420
5421/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
5422///
5423/// This struct is used for aggregate function calls that are not covered by
5424/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
5425/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
5426/// IGNORE NULLS / RESPECT NULLS modifiers.
5427#[derive(
5428    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
5429)]
5430#[cfg_attr(feature = "bindings", derive(TS))]
5431pub struct AggregateFunction {
5432    /// Dialect whose call semantics must be retained through independent generation.
5433    #[serde(default, skip_serializing_if = "Option::is_none")]
5434    #[ast(skip)]
5435    pub source_dialect: Option<crate::dialects::DialectType>,
5436
5437    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
5438    pub name: String,
5439    /// Positional arguments.
5440    pub args: Vec<Expression>,
5441    /// Whether DISTINCT was specified.
5442    pub distinct: bool,
5443    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
5444    pub filter: Option<Expression>,
5445    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
5446    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5447    pub order_by: Vec<Ordered>,
5448    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
5449    #[serde(default, skip_serializing_if = "Option::is_none")]
5450    pub limit: Option<Box<Expression>>,
5451    /// IGNORE NULLS / RESPECT NULLS
5452    #[serde(default, skip_serializing_if = "Option::is_none")]
5453    pub ignore_nulls: Option<bool>,
5454    /// Inferred data type from type annotation
5455    #[serde(default, skip_serializing_if = "Option::is_none")]
5456    #[ast(skip)]
5457    pub inferred_type: Option<DataType>,
5458}
5459
5460/// Represent a window function call with its OVER clause.
5461///
5462/// The inner `this` expression is typically a window-specific expression
5463/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
5464/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
5465/// frame specification.
5466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5467#[cfg_attr(feature = "bindings", derive(TS))]
5468pub struct WindowFunction {
5469    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
5470    pub this: Expression,
5471    /// The OVER clause defining the window partitioning, ordering, and frame.
5472    pub over: Over,
5473    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
5474    #[serde(default, skip_serializing_if = "Option::is_none")]
5475    pub keep: Option<Keep>,
5476    /// Inferred data type from type annotation
5477    #[serde(default, skip_serializing_if = "Option::is_none")]
5478    #[ast(skip)]
5479    pub inferred_type: Option<DataType>,
5480}
5481
5482/// Oracle KEEP clause for aggregate functions
5483/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
5484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5485#[cfg_attr(feature = "bindings", derive(TS))]
5486pub struct Keep {
5487    /// true = FIRST, false = LAST
5488    pub first: bool,
5489    /// ORDER BY clause inside KEEP
5490    pub order_by: Vec<Ordered>,
5491}
5492
5493/// WITHIN GROUP clause (for ordered-set aggregate functions)
5494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5495#[cfg_attr(feature = "bindings", derive(TS))]
5496pub struct WithinGroup {
5497    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
5498    pub this: Expression,
5499    /// The ORDER BY clause within the group
5500    pub order_by: Vec<Ordered>,
5501}
5502
5503/// Represent the FROM clause of a SELECT statement.
5504///
5505/// Contains one or more table sources (tables, subqueries, table-valued
5506/// functions, etc.). Multiple entries represent comma-separated implicit joins.
5507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5508#[cfg_attr(feature = "bindings", derive(TS))]
5509pub struct From {
5510    /// The table source expressions.
5511    pub expressions: Vec<Expression>,
5512}
5513
5514/// Represent a JOIN clause between two table sources.
5515///
5516/// The join condition can be specified via `on` (ON predicate) or `using`
5517/// (USING column list), but not both. The `kind` field determines the join
5518/// type (INNER, LEFT, CROSS, etc.).
5519#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5520#[cfg_attr(feature = "bindings", derive(TS))]
5521pub struct Join {
5522    /// The right-hand table expression being joined.
5523    pub this: Expression,
5524    /// The ON condition (mutually exclusive with `using`).
5525    pub on: Option<Expression>,
5526    /// The USING column list (mutually exclusive with `on`).
5527    pub using: Vec<Identifier>,
5528    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5529    pub kind: JoinKind,
5530    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5531    pub use_inner_keyword: bool,
5532    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5533    pub use_outer_keyword: bool,
5534    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5535    pub deferred_condition: bool,
5536    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5537    #[serde(default, skip_serializing_if = "Option::is_none")]
5538    pub join_hint: Option<String>,
5539    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5540    #[serde(default, skip_serializing_if = "Option::is_none")]
5541    pub match_condition: Option<Expression>,
5542    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5543    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5544    pub pivots: Vec<Expression>,
5545    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5546    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5547    pub comments: Vec<String>,
5548    /// Nesting group identifier for nested join pretty-printing.
5549    /// Joins in the same group were parsed together; group boundaries come from
5550    /// deferred condition resolution phases.
5551    #[serde(default)]
5552    pub nesting_group: usize,
5553    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5554    #[serde(default)]
5555    pub directed: bool,
5556}
5557
5558/// Enumerate all supported SQL join types.
5559///
5560/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5561/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5562/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5563/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5564#[derive(
5565    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5566)]
5567#[cfg_attr(feature = "bindings", derive(TS))]
5568pub enum JoinKind {
5569    Inner,
5570    Left,
5571    Right,
5572    Full,
5573    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5574    Cross,
5575    Natural,
5576    NaturalLeft,
5577    NaturalRight,
5578    NaturalFull,
5579    Semi,
5580    Anti,
5581    // Directional SEMI/ANTI joins
5582    LeftSemi,
5583    LeftAnti,
5584    RightSemi,
5585    RightAnti,
5586    // SQL Server specific
5587    CrossApply,
5588    OuterApply,
5589    // Time-series specific
5590    AsOf,
5591    AsOfLeft,
5592    AsOfRight,
5593    // Lateral join
5594    Lateral,
5595    LeftLateral,
5596    // MySQL specific
5597    Straight,
5598    // Implicit join (comma-separated tables: FROM a, b)
5599    Implicit,
5600    // ClickHouse ARRAY JOIN
5601    Array,
5602    LeftArray,
5603    // ClickHouse PASTE JOIN (positional join)
5604    Paste,
5605    // DuckDB POSITIONAL JOIN
5606    Positional,
5607}
5608
5609impl Default for JoinKind {
5610    fn default() -> Self {
5611        JoinKind::Inner
5612    }
5613}
5614
5615/// Parenthesized table expression with joins
5616/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5617#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5618#[cfg_attr(feature = "bindings", derive(TS))]
5619pub struct JoinedTable {
5620    /// The left-hand side table expression
5621    pub left: Expression,
5622    /// The joins applied to the left table
5623    pub joins: Vec<Join>,
5624    /// LATERAL VIEW clauses (Hive/Spark)
5625    pub lateral_views: Vec<LateralView>,
5626    /// Optional alias for the joined table expression
5627    pub alias: Option<Identifier>,
5628}
5629
5630/// Represent a WHERE clause containing a boolean filter predicate.
5631#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5632#[cfg_attr(feature = "bindings", derive(TS))]
5633pub struct Where {
5634    /// The filter predicate expression.
5635    pub this: Expression,
5636}
5637
5638/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5639///
5640/// The `expressions` list may contain plain columns, ordinal positions,
5641/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5642#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5643#[cfg_attr(feature = "bindings", derive(TS))]
5644pub struct GroupBy {
5645    /// The grouping expressions.
5646    pub expressions: Vec<Expression>,
5647    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5648    #[serde(default)]
5649    pub all: Option<bool>,
5650    /// ClickHouse: WITH TOTALS modifier
5651    #[serde(default)]
5652    pub totals: bool,
5653    /// Leading comments that appeared before the GROUP BY keyword
5654    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5655    pub comments: Vec<String>,
5656}
5657
5658/// Represent a HAVING clause containing a predicate over aggregate results.
5659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5660#[cfg_attr(feature = "bindings", derive(TS))]
5661pub struct Having {
5662    /// The filter predicate, typically involving aggregate functions.
5663    pub this: Expression,
5664    /// Leading comments that appeared before the HAVING keyword
5665    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5666    pub comments: Vec<String>,
5667}
5668
5669/// Represent an ORDER BY clause containing one or more sort specifications.
5670#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5671#[cfg_attr(feature = "bindings", derive(TS))]
5672pub struct OrderBy {
5673    /// The sort specifications, each with direction and null ordering.
5674    pub expressions: Vec<Ordered>,
5675    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5676    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5677    pub siblings: bool,
5678    /// Leading comments that appeared before the ORDER BY keyword
5679    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5680    pub comments: Vec<String>,
5681}
5682
5683/// Represent an expression with sort direction and null ordering.
5684///
5685/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5686/// When `desc` is false the sort is ascending. The `nulls_first` field
5687/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5688/// (database default).
5689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5690#[cfg_attr(feature = "bindings", derive(TS))]
5691pub struct Ordered {
5692    /// Vertica lets the engine select null placement for aggregate/window ordering.
5693    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5694    pub nulls_auto: bool,
5695    /// The expression to sort by.
5696    pub this: Expression,
5697    /// Whether the sort direction is descending (true) or ascending (false).
5698    pub desc: bool,
5699    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5700    pub nulls_first: Option<bool>,
5701    /// Whether ASC was explicitly written (not just implied)
5702    #[serde(default)]
5703    pub explicit_asc: bool,
5704    /// ClickHouse WITH FILL clause
5705    #[serde(default, skip_serializing_if = "Option::is_none")]
5706    pub with_fill: Option<Box<WithFill>>,
5707}
5708
5709impl Ordered {
5710    pub fn asc(expr: Expression) -> Self {
5711        Self {
5712            nulls_auto: false,
5713            this: expr,
5714            desc: false,
5715            nulls_first: None,
5716            explicit_asc: false,
5717            with_fill: None,
5718        }
5719    }
5720
5721    pub fn desc(expr: Expression) -> Self {
5722        Self {
5723            nulls_auto: false,
5724            this: expr,
5725            desc: true,
5726            nulls_first: None,
5727            explicit_asc: false,
5728            with_fill: None,
5729        }
5730    }
5731}
5732
5733/// DISTRIBUTE BY clause (Hive/Spark)
5734/// Controls how rows are distributed across reducers
5735#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5736#[cfg_attr(feature = "bindings", derive(TS))]
5737#[cfg_attr(feature = "bindings", ts(export))]
5738pub struct DistributeBy {
5739    pub expressions: Vec<Expression>,
5740}
5741
5742/// CLUSTER BY clause (Hive/Spark)
5743/// Combines DISTRIBUTE BY and SORT BY on the same columns
5744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5745#[cfg_attr(feature = "bindings", derive(TS))]
5746#[cfg_attr(feature = "bindings", ts(export))]
5747pub struct ClusterBy {
5748    pub expressions: Vec<Ordered>,
5749}
5750
5751/// SORT BY clause (Hive/Spark)
5752/// Sorts data within each reducer (local sort, not global)
5753#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5754#[cfg_attr(feature = "bindings", derive(TS))]
5755#[cfg_attr(feature = "bindings", ts(export))]
5756pub struct SortBy {
5757    pub expressions: Vec<Ordered>,
5758}
5759
5760/// LATERAL VIEW clause (Hive/Spark)
5761/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5762#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5763#[cfg_attr(feature = "bindings", derive(TS))]
5764#[cfg_attr(feature = "bindings", ts(export))]
5765pub struct LateralView {
5766    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5767    pub this: Expression,
5768    /// Table alias for the generated table
5769    pub table_alias: Option<Identifier>,
5770    /// Column aliases for the generated columns
5771    pub column_aliases: Vec<Identifier>,
5772    /// OUTER keyword - preserve nulls when input is empty/null
5773    pub outer: bool,
5774}
5775
5776/// Query hint
5777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5778#[cfg_attr(feature = "bindings", derive(TS))]
5779#[cfg_attr(feature = "bindings", ts(export))]
5780pub struct Hint {
5781    #[serde(default, skip_serializing_if = "Option::is_none")]
5782    #[ast(skip)]
5783    pub source_dialect: Option<crate::dialects::DialectType>,
5784    pub expressions: Vec<HintExpression>,
5785}
5786
5787/// Individual hint expression
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 HintExpression {
5792    /// A structured hint directive with optional execution scope modifiers.
5793    Directive {
5794        name: Identifier,
5795        arguments: Option<Vec<Expression>>,
5796        remote: bool,
5797        cascade: bool,
5798    },
5799    /// Function-style hint: USE_HASH(table)
5800    Function { name: String, args: Vec<Expression> },
5801    /// Simple identifier hint: PARALLEL
5802    Identifier(String),
5803    /// Raw hint text (unparsed)
5804    Raw(String),
5805}
5806
5807/// Pseudocolumn type
5808#[derive(
5809    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5810)]
5811#[cfg_attr(feature = "bindings", derive(TS))]
5812#[cfg_attr(feature = "bindings", ts(export))]
5813pub enum PseudocolumnType {
5814    Rownum,      // Oracle ROWNUM
5815    Rowid,       // Oracle ROWID
5816    Level,       // Oracle LEVEL (for CONNECT BY)
5817    Sysdate,     // Oracle SYSDATE
5818    ObjectId,    // Oracle OBJECT_ID
5819    ObjectValue, // Oracle OBJECT_VALUE
5820}
5821
5822impl PseudocolumnType {
5823    pub fn as_str(&self) -> &'static str {
5824        match self {
5825            PseudocolumnType::Rownum => "ROWNUM",
5826            PseudocolumnType::Rowid => "ROWID",
5827            PseudocolumnType::Level => "LEVEL",
5828            PseudocolumnType::Sysdate => "SYSDATE",
5829            PseudocolumnType::ObjectId => "OBJECT_ID",
5830            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5831        }
5832    }
5833
5834    pub fn from_str(s: &str) -> Option<Self> {
5835        match s.to_uppercase().as_str() {
5836            "ROWNUM" => Some(PseudocolumnType::Rownum),
5837            "ROWID" => Some(PseudocolumnType::Rowid),
5838            "LEVEL" => Some(PseudocolumnType::Level),
5839            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5840            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5841            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5842            _ => None,
5843        }
5844    }
5845}
5846
5847/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5848/// These are special identifiers that should not be quoted
5849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5850#[cfg_attr(feature = "bindings", derive(TS))]
5851#[cfg_attr(feature = "bindings", ts(export))]
5852pub struct Pseudocolumn {
5853    pub kind: PseudocolumnType,
5854}
5855
5856impl Pseudocolumn {
5857    pub fn rownum() -> Self {
5858        Self {
5859            kind: PseudocolumnType::Rownum,
5860        }
5861    }
5862
5863    pub fn rowid() -> Self {
5864        Self {
5865            kind: PseudocolumnType::Rowid,
5866        }
5867    }
5868
5869    pub fn level() -> Self {
5870        Self {
5871            kind: PseudocolumnType::Level,
5872        }
5873    }
5874}
5875
5876/// Oracle CONNECT BY clause for hierarchical queries
5877#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5878#[cfg_attr(feature = "bindings", derive(TS))]
5879#[cfg_attr(feature = "bindings", ts(export))]
5880pub struct Connect {
5881    /// START WITH condition (optional, can come before or after CONNECT BY)
5882    pub start: Option<Expression>,
5883    /// CONNECT BY condition (required, contains PRIOR references)
5884    pub connect: Expression,
5885    /// NOCYCLE keyword to prevent infinite loops
5886    pub nocycle: bool,
5887}
5888
5889/// Oracle PRIOR expression - references parent row's value in CONNECT BY
5890#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5891#[cfg_attr(feature = "bindings", derive(TS))]
5892#[cfg_attr(feature = "bindings", ts(export))]
5893pub struct Prior {
5894    pub this: Expression,
5895}
5896
5897/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5898#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5899#[cfg_attr(feature = "bindings", derive(TS))]
5900#[cfg_attr(feature = "bindings", ts(export))]
5901pub struct ConnectByRoot {
5902    pub this: Expression,
5903}
5904
5905/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5906#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5907#[cfg_attr(feature = "bindings", derive(TS))]
5908#[cfg_attr(feature = "bindings", ts(export))]
5909pub struct MatchRecognize {
5910    /// Source table/expression
5911    pub this: Option<Box<Expression>>,
5912    /// PARTITION BY expressions
5913    pub partition_by: Option<Vec<Expression>>,
5914    /// ORDER BY expressions
5915    pub order_by: Option<Vec<Ordered>>,
5916    /// MEASURES definitions
5917    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5918    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5919    pub rows: Option<MatchRecognizeRows>,
5920    /// AFTER MATCH SKIP behavior
5921    pub after: Option<MatchRecognizeAfter>,
5922    /// PATTERN definition (stored as raw string for complex regex patterns)
5923    pub pattern: Option<String>,
5924    /// DEFINE clauses (pattern variable definitions)
5925    pub define: Option<Vec<(Identifier, Expression)>>,
5926    /// Optional alias for the result
5927    pub alias: Option<Identifier>,
5928    /// Whether AS keyword was explicitly present before alias
5929    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5930    pub alias_explicit_as: bool,
5931}
5932
5933/// MEASURES expression with optional RUNNING/FINAL semantics
5934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5935#[cfg_attr(feature = "bindings", derive(TS))]
5936#[cfg_attr(feature = "bindings", ts(export))]
5937pub struct MatchRecognizeMeasure {
5938    /// The measure expression
5939    pub this: Expression,
5940    /// RUNNING or FINAL semantics (Snowflake-specific)
5941    pub window_frame: Option<MatchRecognizeSemantics>,
5942}
5943
5944/// Semantics for MEASURES in MATCH_RECOGNIZE
5945#[derive(
5946    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5947)]
5948#[cfg_attr(feature = "bindings", derive(TS))]
5949#[cfg_attr(feature = "bindings", ts(export))]
5950pub enum MatchRecognizeSemantics {
5951    Running,
5952    Final,
5953}
5954
5955/// Row output semantics for MATCH_RECOGNIZE
5956#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5957#[cfg_attr(feature = "bindings", derive(TS))]
5958#[cfg_attr(feature = "bindings", ts(export))]
5959pub enum MatchRecognizeRows {
5960    OneRowPerMatch,
5961    AllRowsPerMatch,
5962    AllRowsPerMatchShowEmptyMatches,
5963    AllRowsPerMatchOmitEmptyMatches,
5964    AllRowsPerMatchWithUnmatchedRows,
5965}
5966
5967/// AFTER MATCH SKIP behavior
5968#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5969#[cfg_attr(feature = "bindings", derive(TS))]
5970#[cfg_attr(feature = "bindings", ts(export))]
5971pub enum MatchRecognizeAfter {
5972    PastLastRow,
5973    ToNextRow,
5974    ToFirst(Identifier),
5975    ToLast(Identifier),
5976}
5977
5978/// Represent a LIMIT clause that restricts the number of returned rows.
5979#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5980#[cfg_attr(feature = "bindings", derive(TS))]
5981pub struct Limit {
5982    /// The limit count expression.
5983    pub this: Expression,
5984    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5985    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5986    pub percent: bool,
5987    /// Comments from before the LIMIT keyword (emitted after the limit value)
5988    #[serde(default)]
5989    #[serde(skip_serializing_if = "Vec::is_empty")]
5990    pub comments: Vec<String>,
5991}
5992
5993impl Limit {
5994    /// Preserve the legacy count-only set-operation AST when no metadata is needed.
5995    pub(crate) fn into_set_limit(self) -> Box<Expression> {
5996        if self.percent || !self.comments.is_empty() {
5997            Box::new(Expression::Limit(Box::new(self)))
5998        } else {
5999            Box::new(self.this)
6000        }
6001    }
6002}
6003
6004/// Move a compound query's row limit onto a SELECT without losing clause options.
6005/// Bare expressions remain supported for existing builders and serialized ASTs.
6006pub(crate) fn split_set_limit(limit: Option<Box<Expression>>) -> (Option<Limit>, Option<Fetch>) {
6007    match limit.map(|limit| *limit) {
6008        Some(Expression::Limit(limit)) => (Some(*limit), None),
6009        Some(Expression::Fetch(fetch)) => (None, Some(*fetch)),
6010        Some(this) => (
6011            Some(Limit {
6012                this,
6013                percent: false,
6014                comments: Vec::new(),
6015            }),
6016            None,
6017        ),
6018        None => (None, None),
6019    }
6020}
6021
6022/// OFFSET clause
6023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6024#[cfg_attr(feature = "bindings", derive(TS))]
6025pub struct Offset {
6026    pub this: Expression,
6027    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
6028    #[serde(skip_serializing_if = "Option::is_none", default)]
6029    pub rows: Option<bool>,
6030}
6031
6032/// TOP clause (SQL Server)
6033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6034#[cfg_attr(feature = "bindings", derive(TS))]
6035pub struct Top {
6036    pub this: Expression,
6037    pub percent: bool,
6038    pub with_ties: bool,
6039    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
6040    #[serde(default)]
6041    pub parenthesized: bool,
6042}
6043
6044/// FETCH FIRST/NEXT clause (SQL standard)
6045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6046#[cfg_attr(feature = "bindings", derive(TS))]
6047pub struct Fetch {
6048    /// FIRST or NEXT
6049    pub direction: String,
6050    /// Count expression (optional)
6051    pub count: Option<Expression>,
6052    /// PERCENT modifier
6053    pub percent: bool,
6054    /// ROWS or ROW keyword present
6055    pub rows: bool,
6056    /// WITH TIES modifier
6057    pub with_ties: bool,
6058}
6059
6060/// Represent a QUALIFY clause for filtering on window function results.
6061///
6062/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
6063/// typically references a window function (e.g.
6064/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
6065#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6066#[cfg_attr(feature = "bindings", derive(TS))]
6067pub struct Qualify {
6068    /// The filter predicate over window function results.
6069    pub this: Expression,
6070}
6071
6072/// SAMPLE / TABLESAMPLE clause
6073#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6074#[cfg_attr(feature = "bindings", derive(TS))]
6075pub struct Sample {
6076    pub method: SampleMethod,
6077    pub size: Expression,
6078    pub seed: Option<Expression>,
6079    /// ClickHouse OFFSET expression after SAMPLE size
6080    #[serde(default)]
6081    pub offset: Option<Expression>,
6082    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
6083    pub unit_after_size: bool,
6084    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
6085    #[serde(default)]
6086    pub use_sample_keyword: bool,
6087    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
6088    #[serde(default)]
6089    pub explicit_method: bool,
6090    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
6091    #[serde(default)]
6092    pub method_before_size: bool,
6093    /// Whether SEED keyword was used (true) or REPEATABLE (false)
6094    #[serde(default)]
6095    pub use_seed_keyword: bool,
6096    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
6097    pub bucket_numerator: Option<Box<Expression>>,
6098    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
6099    pub bucket_denominator: Option<Box<Expression>>,
6100    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
6101    pub bucket_field: Option<Box<Expression>>,
6102    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
6103    #[serde(default)]
6104    pub is_using_sample: bool,
6105    /// Whether the unit was explicitly PERCENT (vs ROWS)
6106    #[serde(default)]
6107    pub is_percent: bool,
6108    /// Whether to suppress method output (for cross-dialect transpilation)
6109    #[serde(default)]
6110    pub suppress_method_output: bool,
6111}
6112
6113/// Sample method
6114#[derive(
6115    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6116)]
6117#[cfg_attr(feature = "bindings", derive(TS))]
6118pub enum SampleMethod {
6119    Bernoulli,
6120    System,
6121    Block,
6122    Row,
6123    Percent,
6124    /// Hive bucket sampling
6125    Bucket,
6126    /// DuckDB reservoir sampling
6127    Reservoir,
6128}
6129
6130/// Named window definition (WINDOW w AS (...))
6131#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6132#[cfg_attr(feature = "bindings", derive(TS))]
6133pub struct NamedWindow {
6134    pub name: Identifier,
6135    pub spec: Over,
6136}
6137
6138/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
6139///
6140/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
6141/// that reference themselves. Each CTE is defined in the `ctes` vector and
6142/// can be referenced by name in subsequent CTEs and in the main query body.
6143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6144#[cfg_attr(feature = "bindings", derive(TS))]
6145pub struct With {
6146    /// The list of CTE definitions, in order.
6147    pub ctes: Vec<Cte>,
6148    /// Whether the WITH RECURSIVE keyword was used.
6149    pub recursive: bool,
6150    /// Leading comments before the statement
6151    #[serde(default)]
6152    pub leading_comments: Vec<String>,
6153    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
6154    #[serde(default, skip_serializing_if = "Option::is_none")]
6155    pub search: Option<Box<Expression>>,
6156}
6157
6158/// Represent a single Common Table Expression definition.
6159///
6160/// A CTE has a name (`alias`), an optional column list, and a body query.
6161/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
6162/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
6163/// the expression comes before the alias (`alias_first`).
6164#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6165#[cfg_attr(feature = "bindings", derive(TS))]
6166pub struct Cte {
6167    /// The CTE name.
6168    pub alias: Identifier,
6169    /// The CTE body (typically a SELECT, UNION, etc.).
6170    pub this: Expression,
6171    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
6172    pub columns: Vec<Identifier>,
6173    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
6174    pub materialized: Option<bool>,
6175    /// USING KEY (columns) for DuckDB recursive CTEs
6176    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6177    pub key_expressions: Vec<Identifier>,
6178    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
6179    #[serde(default)]
6180    pub alias_first: bool,
6181    /// Comments associated with this CTE (placed after alias name, before AS)
6182    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6183    pub comments: Vec<String>,
6184}
6185
6186/// Window specification
6187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6188#[cfg_attr(feature = "bindings", derive(TS))]
6189pub struct WindowSpec {
6190    pub partition_by: Vec<Expression>,
6191    pub order_by: Vec<Ordered>,
6192    pub frame: Option<WindowFrame>,
6193}
6194
6195/// OVER clause
6196#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6197#[cfg_attr(feature = "bindings", derive(TS))]
6198pub struct Over {
6199    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
6200    pub window_name: Option<Identifier>,
6201    pub partition_by: Vec<Expression>,
6202    pub order_by: Vec<Ordered>,
6203    pub frame: Option<WindowFrame>,
6204    pub alias: Option<Identifier>,
6205}
6206
6207/// Window frame
6208#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6209#[cfg_attr(feature = "bindings", derive(TS))]
6210pub struct WindowFrame {
6211    pub kind: WindowFrameKind,
6212    pub start: WindowFrameBound,
6213    pub end: Option<WindowFrameBound>,
6214    pub exclude: Option<WindowFrameExclude>,
6215    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
6216    #[serde(default, skip_serializing_if = "Option::is_none")]
6217    pub kind_text: Option<String>,
6218    /// Original text of the start bound side keyword (e.g. "preceding")
6219    #[serde(default, skip_serializing_if = "Option::is_none")]
6220    pub start_side_text: Option<String>,
6221    /// Original text of the end bound side keyword
6222    #[serde(default, skip_serializing_if = "Option::is_none")]
6223    pub end_side_text: Option<String>,
6224}
6225
6226#[derive(
6227    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6228)]
6229#[cfg_attr(feature = "bindings", derive(TS))]
6230pub enum WindowFrameKind {
6231    Rows,
6232    Range,
6233    Groups,
6234}
6235
6236/// EXCLUDE clause for window frames
6237#[derive(
6238    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6239)]
6240#[cfg_attr(feature = "bindings", derive(TS))]
6241pub enum WindowFrameExclude {
6242    CurrentRow,
6243    Group,
6244    Ties,
6245    NoOthers,
6246}
6247
6248#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6249#[cfg_attr(feature = "bindings", derive(TS))]
6250pub enum WindowFrameBound {
6251    CurrentRow,
6252    UnboundedPreceding,
6253    UnboundedFollowing,
6254    Preceding(Box<Expression>),
6255    Following(Box<Expression>),
6256    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
6257    BarePreceding,
6258    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
6259    BareFollowing,
6260    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
6261    Value(Box<Expression>),
6262}
6263
6264/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
6265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6266#[cfg_attr(feature = "bindings", derive(TS))]
6267pub struct StructField {
6268    /// A raw field name, or a delimited identifier for compatibility with parsed ASTs.
6269    /// Parsed quoted names use double quotes with doubled internal quotes. An empty
6270    /// string denotes an anonymous field. Generation selects the target dialect's quotes.
6271    pub name: String,
6272    pub data_type: DataType,
6273    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6274    pub options: Vec<Expression>,
6275    #[serde(default, skip_serializing_if = "Option::is_none")]
6276    pub comment: Option<String>,
6277}
6278
6279impl StructField {
6280    /// Create a new struct field without options
6281    pub fn new(name: String, data_type: DataType) -> Self {
6282        Self {
6283            name,
6284            data_type,
6285            options: Vec::new(),
6286            comment: None,
6287        }
6288    }
6289
6290    /// Create a new struct field with options
6291    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
6292        Self {
6293            name,
6294            data_type,
6295            options,
6296            comment: None,
6297        }
6298    }
6299
6300    /// Create a new struct field with options and comment
6301    pub fn with_options_and_comment(
6302        name: String,
6303        data_type: DataType,
6304        options: Vec<Expression>,
6305        comment: Option<String>,
6306    ) -> Self {
6307        Self {
6308            name,
6309            data_type,
6310            options,
6311            comment,
6312        }
6313    }
6314}
6315
6316/// Oracle-specific data types whose semantics cannot be represented losslessly by the
6317/// generic [`DataType`] variants.
6318///
6319/// Keeping these types structured allows the Oracle parser to retain details such as a
6320/// negative `NUMBER` scale, `BYTE`/`CHAR` length semantics, interval precisions, and
6321/// `TIMESTAMP WITH LOCAL TIME ZONE` until the target dialect is known.
6322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6323#[cfg_attr(feature = "bindings", derive(TS))]
6324#[serde(tag = "oracle_data_type", rename_all = "snake_case")]
6325pub enum OracleDataType {
6326    Number {
6327        precision: Option<u32>,
6328        scale: Option<i32>,
6329    },
6330    BinaryFloat,
6331    BinaryDouble,
6332    Float {
6333        precision: Option<u32>,
6334    },
6335    Character {
6336        kind: OracleCharacterKind,
6337        length: Option<u32>,
6338        semantics: Option<OracleCharacterLengthSemantics>,
6339    },
6340    Date,
6341    Timestamp {
6342        precision: Option<u32>,
6343        timezone: OracleTimestampTimeZone,
6344    },
6345    IntervalYearToMonth {
6346        year_precision: Option<u32>,
6347    },
6348    IntervalDayToSecond {
6349        day_precision: Option<u32>,
6350        fractional_seconds_precision: Option<u32>,
6351    },
6352    Clob {
6353        national: bool,
6354    },
6355    Blob,
6356    Raw {
6357        length: Option<u32>,
6358    },
6359    Long {
6360        raw: bool,
6361    },
6362    RowId,
6363}
6364
6365#[derive(
6366    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6367)]
6368#[cfg_attr(feature = "bindings", derive(TS))]
6369#[serde(rename_all = "snake_case")]
6370pub enum OracleCharacterKind {
6371    Char,
6372    VarChar,
6373    NChar,
6374    NVarChar,
6375}
6376
6377#[derive(
6378    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6379)]
6380#[cfg_attr(feature = "bindings", derive(TS))]
6381#[serde(rename_all = "snake_case")]
6382pub enum OracleCharacterLengthSemantics {
6383    Byte,
6384    Char,
6385}
6386
6387#[derive(
6388    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6389)]
6390#[cfg_attr(feature = "bindings", derive(TS))]
6391#[serde(rename_all = "snake_case")]
6392pub enum OracleTimestampTimeZone {
6393    None,
6394    WithTimeZone,
6395    WithLocalTimeZone,
6396}
6397
6398/// Enumerate all SQL data types recognized by the parser.
6399///
6400/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
6401/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
6402/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
6403///
6404/// This enum is used in CAST expressions, column definitions, function return
6405/// types, and anywhere a data type specification appears in SQL.
6406///
6407/// Types that do not match any known variant fall through to `Custom { name }`,
6408/// preserving the original type name for round-trip fidelity.
6409#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6410#[cfg_attr(feature = "bindings", derive(TS))]
6411#[serde(tag = "data_type", rename_all = "snake_case")]
6412pub enum DataType {
6413    Vertica {
6414        vertica_type: Box<VerticaDataType>,
6415    },
6416    // Numeric
6417    Boolean,
6418    TinyInt {
6419        length: Option<u32>,
6420    },
6421    SmallInt {
6422        length: Option<u32>,
6423    },
6424    /// Int type with optional length. `integer_spelling` indicates whether the original
6425    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
6426    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
6427    Int {
6428        length: Option<u32>,
6429        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6430        integer_spelling: bool,
6431    },
6432    BigInt {
6433        length: Option<u32>,
6434    },
6435    /// Signed 128-bit integer (DuckDB HUGEINT, ClickHouse Int128, StarRocks LARGEINT).
6436    Int128,
6437    /// Unsigned 8-bit integer (DuckDB UTINYINT, ClickHouse UInt8).
6438    #[serde(rename = "uint8")]
6439    UInt8,
6440    /// Unsigned 16-bit integer (DuckDB USMALLINT, ClickHouse UInt16).
6441    #[serde(rename = "uint16")]
6442    UInt16,
6443    /// Unsigned 32-bit integer (DuckDB UINTEGER, ClickHouse UInt32).
6444    #[serde(rename = "uint32")]
6445    UInt32,
6446    /// Unsigned 64-bit integer (DuckDB UBIGINT, ClickHouse UInt64).
6447    #[serde(rename = "uint64")]
6448    UInt64,
6449    /// Unsigned 128-bit integer (DuckDB UHUGEINT, ClickHouse UInt128).
6450    #[serde(rename = "uint128")]
6451    UInt128,
6452    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
6453    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
6454    /// preserve the original spelling.
6455    Float {
6456        precision: Option<u32>,
6457        scale: Option<u32>,
6458        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6459        real_spelling: bool,
6460    },
6461    Double {
6462        precision: Option<u32>,
6463        scale: Option<u32>,
6464    },
6465    Decimal {
6466        precision: Option<u32>,
6467        scale: Option<u32>,
6468    },
6469    /// Structured Oracle data type retained until the target dialect is known.
6470    Oracle {
6471        oracle_type: OracleDataType,
6472    },
6473
6474    /// A HANA type whose domain or syntax is not represented by a common type.
6475    Hana {
6476        hana_type: HanaDataType,
6477    },
6478
6479    // String
6480    Char {
6481        length: Option<u32>,
6482    },
6483    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
6484    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
6485    VarChar {
6486        length: Option<u32>,
6487        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6488        parenthesized_length: bool,
6489    },
6490    /// String type with optional max length (BigQuery STRING(n))
6491    String {
6492        length: Option<u32>,
6493    },
6494    Text,
6495    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
6496    TextWithLength {
6497        length: u32,
6498    },
6499
6500    // Binary
6501    Binary {
6502        length: Option<u32>,
6503    },
6504    VarBinary {
6505        length: Option<u32>,
6506    },
6507    Blob,
6508
6509    // Bit
6510    Bit {
6511        length: Option<u32>,
6512    },
6513    VarBit {
6514        length: Option<u32>,
6515    },
6516
6517    // Date/Time
6518    Date,
6519    Time {
6520        precision: Option<u32>,
6521        #[serde(default)]
6522        timezone: bool,
6523    },
6524    Timestamp {
6525        precision: Option<u32>,
6526        timezone: bool,
6527    },
6528    Interval {
6529        unit: Option<String>,
6530        /// For range intervals like INTERVAL DAY TO HOUR
6531        #[serde(default, skip_serializing_if = "Option::is_none")]
6532        to: Option<String>,
6533    },
6534
6535    // JSON
6536    Json,
6537    JsonB,
6538
6539    // UUID
6540    Uuid,
6541
6542    // Array
6543    Array {
6544        element_type: Box<DataType>,
6545        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
6546        #[serde(default, skip_serializing_if = "Option::is_none")]
6547        dimension: Option<u32>,
6548    },
6549
6550    /// List type (Materialize): INT LIST, TEXT LIST LIST
6551    /// Uses postfix LIST syntax instead of ARRAY<T>
6552    List {
6553        element_type: Box<DataType>,
6554    },
6555
6556    // Struct/Map
6557    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
6558    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
6559    Struct {
6560        fields: Vec<StructField>,
6561        nested: bool,
6562    },
6563    Map {
6564        key_type: Box<DataType>,
6565        value_type: Box<DataType>,
6566    },
6567
6568    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
6569    Enum {
6570        values: Vec<String>,
6571        #[serde(default, skip_serializing_if = "Vec::is_empty")]
6572        assignments: Vec<Option<String>>,
6573    },
6574
6575    // Set type (MySQL): SET('a', 'b', 'c')
6576    Set {
6577        values: Vec<String>,
6578    },
6579
6580    // Union type (DuckDB): UNION(num INT, str TEXT)
6581    Union {
6582        fields: Vec<(String, DataType)>,
6583    },
6584
6585    // Vector (Snowflake / SingleStore)
6586    Vector {
6587        #[serde(default)]
6588        element_type: Option<Box<DataType>>,
6589        dimension: Option<u32>,
6590    },
6591
6592    // Object (Snowflake structured type)
6593    // fields: Vec of (field_name, field_type, not_null)
6594    Object {
6595        fields: Vec<(String, DataType, bool)>,
6596        modifier: Option<String>,
6597    },
6598
6599    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
6600    Nullable {
6601        inner: Box<DataType>,
6602    },
6603
6604    // Custom/User-defined
6605    Custom {
6606        name: String,
6607    },
6608
6609    // Spatial types
6610    Geometry {
6611        subtype: Option<String>,
6612        srid: Option<u32>,
6613    },
6614    Geography {
6615        subtype: Option<String>,
6616        srid: Option<u32>,
6617    },
6618
6619    // Character Set (for CONVERT USING in MySQL)
6620    // Renders as CHAR CHARACTER SET {name} in cast target
6621    CharacterSet {
6622        name: String,
6623    },
6624
6625    // Unknown
6626    Unknown,
6627}
6628
6629/// Source-specific HANA type, retained until a target is selected.
6630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6631#[cfg_attr(feature = "bindings", derive(TS))]
6632pub struct HanaDataType {
6633    pub name: String,
6634    pub parameters: Vec<u32>,
6635}
6636
6637impl DataType {
6638    /// Canonical unsigned names and their bit-width aliases. Parser entry points
6639    /// and legacy Custom-type normalization share this mapping.
6640    pub(crate) fn from_unsigned_name(name: &str) -> Option<Self> {
6641        match name.to_ascii_uppercase().as_str() {
6642            "UTINYINT" | "UINT8" => Some(Self::UInt8),
6643            "USMALLINT" | "UINT16" => Some(Self::UInt16),
6644            "UINTEGER" | "UINT32" => Some(Self::UInt32),
6645            "UBIGINT" | "UINT64" => Some(Self::UInt64),
6646            "UHUGEINT" | "UINT128" => Some(Self::UInt128),
6647            _ => None,
6648        }
6649    }
6650}
6651
6652/// Array expression
6653#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6654#[cfg_attr(feature = "bindings", derive(TS))]
6655#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
6656pub struct Array {
6657    pub expressions: Vec<Expression>,
6658    /// Inferred array data type from type annotation
6659    #[serde(default, skip_serializing_if = "Option::is_none")]
6660    #[ast(skip)]
6661    pub inferred_type: Option<DataType>,
6662}
6663
6664/// Struct expression
6665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6666#[cfg_attr(feature = "bindings", derive(TS))]
6667pub struct Struct {
6668    pub fields: Vec<(Option<String>, Expression)>,
6669}
6670
6671/// Tuple expression
6672#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6673#[cfg_attr(feature = "bindings", derive(TS))]
6674pub struct Tuple {
6675    pub expressions: Vec<Expression>,
6676}
6677
6678/// Interval expression
6679#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6680#[cfg_attr(feature = "bindings", derive(TS))]
6681pub struct Interval {
6682    /// The value expression (e.g., '1', 5, column_ref)
6683    pub this: Option<Expression>,
6684    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
6685    pub unit: Option<IntervalUnitSpec>,
6686}
6687
6688/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
6689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6690#[cfg_attr(feature = "bindings", derive(TS))]
6691#[serde(tag = "type", rename_all = "snake_case")]
6692pub enum IntervalUnitSpec {
6693    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
6694    Simple {
6695        unit: IntervalUnit,
6696        /// Whether to use plural form (e.g., DAYS vs DAY)
6697        use_plural: bool,
6698    },
6699    /// Interval span (e.g., HOUR TO SECOND)
6700    Span(IntervalSpan),
6701    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6702    /// The start and end can be expressions like function calls with precision
6703    ExprSpan(IntervalSpanExpr),
6704    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6705    Expr(Box<Expression>),
6706}
6707
6708/// Interval span for ranges like HOUR TO SECOND
6709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6710#[cfg_attr(feature = "bindings", derive(TS))]
6711pub struct IntervalSpan {
6712    /// Start unit (e.g., HOUR)
6713    pub this: IntervalUnit,
6714    /// End unit (e.g., SECOND)
6715    pub expression: IntervalUnit,
6716}
6717
6718/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6719/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6720#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6721#[cfg_attr(feature = "bindings", derive(TS))]
6722pub struct IntervalSpanExpr {
6723    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6724    pub this: Box<Expression>,
6725    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6726    pub expression: Box<Expression>,
6727}
6728
6729#[derive(
6730    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6731)]
6732#[cfg_attr(feature = "bindings", derive(TS))]
6733pub enum IntervalUnit {
6734    Year,
6735    Quarter,
6736    Month,
6737    Week,
6738    Day,
6739    Hour,
6740    Minute,
6741    Second,
6742    Millisecond,
6743    Microsecond,
6744    Nanosecond,
6745}
6746
6747/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6749#[cfg_attr(feature = "bindings", derive(TS))]
6750pub struct Command {
6751    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6752    pub this: String,
6753}
6754
6755/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6756/// Syntax: PREPARE name [(type, ...)] AS statement
6757#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6758#[cfg_attr(feature = "bindings", derive(TS))]
6759pub struct PrepareStatement {
6760    /// The prepared statement name.
6761    pub name: Identifier,
6762    /// Optional PostgreSQL parameter type list.
6763    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6764    pub parameter_types: Vec<DataType>,
6765    /// The statement to execute when the prepared statement is invoked.
6766    pub statement: Expression,
6767}
6768
6769/// T-SQL TRY/CATCH block.
6770#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6771#[cfg_attr(feature = "bindings", derive(TS))]
6772pub struct TryCatch {
6773    /// Statements inside BEGIN TRY ... END TRY.
6774    #[serde(default)]
6775    pub try_body: Vec<Expression>,
6776    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6777    #[serde(default, skip_serializing_if = "Option::is_none")]
6778    pub catch_body: Option<Vec<Expression>>,
6779}
6780
6781/// EXEC/EXECUTE statement (TSQL stored procedure call)
6782/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6784#[cfg_attr(feature = "bindings", derive(TS))]
6785pub struct ExecuteStatement {
6786    /// The procedure name (can be qualified: schema.proc_name)
6787    pub this: Expression,
6788    /// Optional T-SQL return-status variable (`EXECUTE @status = procedure`).
6789    #[serde(default, skip_serializing_if = "Option::is_none")]
6790    pub return_status: Option<String>,
6791    /// Named parameters: @param=value pairs
6792    #[serde(default)]
6793    pub parameters: Vec<ExecuteParameter>,
6794    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6795    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6796    pub arguments: Vec<Expression>,
6797    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6798    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6799    pub prepared: bool,
6800    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6801    #[serde(default, skip_serializing_if = "Option::is_none")]
6802    pub suffix: Option<String>,
6803}
6804
6805/// Named parameter in EXEC statement: @name=value
6806#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6807#[cfg_attr(feature = "bindings", derive(TS))]
6808pub struct ExecuteParameter {
6809    /// Parameter name (including @)
6810    pub name: String,
6811    /// Parameter value
6812    pub value: Expression,
6813    /// Whether this is a positional parameter (no = sign)
6814    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6815    pub positional: bool,
6816    /// TSQL OUTPUT modifier on parameter
6817    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6818    pub output: bool,
6819}
6820
6821/// KILL statement (MySQL/MariaDB)
6822/// KILL [CONNECTION | QUERY] <id>
6823#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6824#[cfg_attr(feature = "bindings", derive(TS))]
6825pub struct Kill {
6826    /// The target (process ID or connection ID)
6827    pub this: Expression,
6828    /// Optional kind: "CONNECTION" or "QUERY"
6829    pub kind: Option<String>,
6830}
6831
6832/// Snowflake CREATE TASK statement
6833#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6834#[cfg_attr(feature = "bindings", derive(TS))]
6835pub struct CreateTask {
6836    pub or_replace: bool,
6837    pub if_not_exists: bool,
6838    /// Task name (possibly qualified: db.schema.task)
6839    pub name: String,
6840    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6841    pub properties: String,
6842    /// The SQL statement body after AS
6843    pub body: Expression,
6844}
6845
6846/// Raw/unparsed SQL
6847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6848#[cfg_attr(feature = "bindings", derive(TS))]
6849pub struct Raw {
6850    pub sql: String,
6851}
6852
6853// ============================================================================
6854// Function expression types
6855// ============================================================================
6856
6857/// Generic unary function (takes a single argument)
6858#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6859#[cfg_attr(feature = "bindings", derive(TS))]
6860pub struct UnaryFunc {
6861    pub this: Expression,
6862    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6863    #[serde(skip_serializing_if = "Option::is_none", default)]
6864    pub original_name: Option<String>,
6865    /// Inferred data type from type annotation
6866    #[serde(default, skip_serializing_if = "Option::is_none")]
6867    #[ast(skip)]
6868    pub inferred_type: Option<DataType>,
6869}
6870
6871impl UnaryFunc {
6872    /// Create a new UnaryFunc with no original_name
6873    pub fn new(this: Expression) -> Self {
6874        Self {
6875            this,
6876            original_name: None,
6877            inferred_type: None,
6878        }
6879    }
6880
6881    /// Create a new UnaryFunc with an original name for round-trip preservation
6882    pub fn with_name(this: Expression, name: String) -> Self {
6883        Self {
6884            this,
6885            original_name: Some(name),
6886            inferred_type: None,
6887        }
6888    }
6889}
6890
6891/// CHAR/CHR function with multiple args and optional USING charset
6892/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6893/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6895#[cfg_attr(feature = "bindings", derive(TS))]
6896pub struct CharFunc {
6897    pub args: Vec<Expression>,
6898    #[serde(skip_serializing_if = "Option::is_none", default)]
6899    pub charset: Option<String>,
6900    /// Original function name (CHAR or CHR), defaults to CHAR
6901    #[serde(skip_serializing_if = "Option::is_none", default)]
6902    pub name: Option<String>,
6903}
6904
6905/// Generic binary function (takes two arguments)
6906#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6907#[cfg_attr(feature = "bindings", derive(TS))]
6908pub struct BinaryFunc {
6909    pub this: Expression,
6910    pub expression: Expression,
6911    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6912    #[serde(skip_serializing_if = "Option::is_none", default)]
6913    pub original_name: Option<String>,
6914    /// Inferred data type from type annotation
6915    #[serde(default, skip_serializing_if = "Option::is_none")]
6916    #[ast(skip)]
6917    pub inferred_type: Option<DataType>,
6918}
6919
6920/// Variable argument function
6921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6922#[cfg_attr(feature = "bindings", derive(TS))]
6923pub struct VarArgFunc {
6924    pub expressions: Vec<Expression>,
6925    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6926    #[serde(skip_serializing_if = "Option::is_none", default)]
6927    pub original_name: Option<String>,
6928    /// Inferred data type from type annotation
6929    #[serde(default, skip_serializing_if = "Option::is_none")]
6930    #[ast(skip)]
6931    pub inferred_type: Option<DataType>,
6932}
6933
6934/// CONCAT_WS function
6935#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6936#[cfg_attr(feature = "bindings", derive(TS))]
6937pub struct ConcatWs {
6938    pub separator: Expression,
6939    pub expressions: Vec<Expression>,
6940}
6941
6942/// SUBSTRING function
6943#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6944#[cfg_attr(feature = "bindings", derive(TS))]
6945pub struct SubstringFunc {
6946    pub this: Expression,
6947    pub start: Expression,
6948    pub length: Option<Expression>,
6949    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6950    #[serde(default)]
6951    pub from_for_syntax: bool,
6952}
6953
6954/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6956#[cfg_attr(feature = "bindings", derive(TS))]
6957pub struct OverlayFunc {
6958    pub this: Expression,
6959    pub replacement: Expression,
6960    pub from: Expression,
6961    pub length: Option<Expression>,
6962}
6963
6964/// TRIM function
6965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6966#[cfg_attr(feature = "bindings", derive(TS))]
6967pub struct TrimFunc {
6968    pub this: Expression,
6969    pub characters: Option<Expression>,
6970    pub position: TrimPosition,
6971    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6972    #[serde(default)]
6973    pub sql_standard_syntax: bool,
6974    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6975    #[serde(default)]
6976    pub position_explicit: bool,
6977    /// Inferred data type from type annotation
6978    #[serde(default, skip_serializing_if = "Option::is_none")]
6979    #[ast(skip)]
6980    pub inferred_type: Option<DataType>,
6981}
6982
6983#[derive(
6984    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6985)]
6986#[cfg_attr(feature = "bindings", derive(TS))]
6987pub enum TrimPosition {
6988    Both,
6989    Leading,
6990    Trailing,
6991}
6992
6993/// REPLACE function
6994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6995#[cfg_attr(feature = "bindings", derive(TS))]
6996pub struct ReplaceFunc {
6997    pub this: Expression,
6998    pub old: Expression,
6999    pub new: Expression,
7000}
7001
7002/// LEFT/RIGHT function
7003#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7004#[cfg_attr(feature = "bindings", derive(TS))]
7005pub struct LeftRightFunc {
7006    pub this: Expression,
7007    pub length: Expression,
7008}
7009
7010/// REPEAT function
7011#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7012#[cfg_attr(feature = "bindings", derive(TS))]
7013pub struct RepeatFunc {
7014    pub this: Expression,
7015    pub times: Expression,
7016}
7017
7018/// LPAD/RPAD function
7019#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7020#[cfg_attr(feature = "bindings", derive(TS))]
7021pub struct PadFunc {
7022    pub this: Expression,
7023    pub length: Expression,
7024    pub fill: Option<Expression>,
7025}
7026
7027/// SPLIT function
7028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7029#[cfg_attr(feature = "bindings", derive(TS))]
7030pub struct SplitFunc {
7031    pub this: Expression,
7032    pub delimiter: Expression,
7033}
7034
7035/// REGEXP_LIKE function
7036#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7037#[cfg_attr(feature = "bindings", derive(TS))]
7038pub struct RegexpFunc {
7039    /// Additional search boundaries and retained source semantics.
7040    #[serde(default, skip_serializing_if = "Option::is_none")]
7041    pub options: Option<RegexOptions>,
7042    pub this: Expression,
7043    pub pattern: Expression,
7044    pub flags: Option<Expression>,
7045}
7046
7047/// REGEXP_REPLACE function
7048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7049#[cfg_attr(feature = "bindings", derive(TS))]
7050pub struct RegexpReplaceFunc {
7051    /// Additional search boundaries and retained source semantics.
7052    #[serde(default, skip_serializing_if = "Option::is_none")]
7053    pub options: Option<RegexOptions>,
7054    pub this: Expression,
7055    pub pattern: Expression,
7056    pub replacement: Expression,
7057    pub flags: Option<Expression>,
7058}
7059
7060/// REGEXP_EXTRACT function
7061#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7062#[cfg_attr(feature = "bindings", derive(TS))]
7063pub struct RegexpExtractFunc {
7064    /// Additional search boundaries and retained source semantics.
7065    #[serde(default, skip_serializing_if = "Option::is_none")]
7066    pub options: Option<RegexOptions>,
7067    pub this: Expression,
7068    pub pattern: Expression,
7069    pub group: Option<Expression>,
7070}
7071
7072/// ROUND function
7073#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7074#[cfg_attr(feature = "bindings", derive(TS))]
7075pub struct RoundFunc {
7076    pub this: Expression,
7077    pub decimals: Option<Expression>,
7078}
7079
7080/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
7081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7082#[cfg_attr(feature = "bindings", derive(TS))]
7083pub struct FloorFunc {
7084    pub this: Expression,
7085    pub scale: Option<Expression>,
7086    /// Time unit for Druid-style FLOOR(time TO unit) syntax
7087    #[serde(skip_serializing_if = "Option::is_none", default)]
7088    pub to: Option<Expression>,
7089}
7090
7091/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
7092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7093#[cfg_attr(feature = "bindings", derive(TS))]
7094pub struct CeilFunc {
7095    pub this: Expression,
7096    #[serde(skip_serializing_if = "Option::is_none", default)]
7097    pub decimals: Option<Expression>,
7098    /// Time unit for Druid-style CEIL(time TO unit) syntax
7099    #[serde(skip_serializing_if = "Option::is_none", default)]
7100    pub to: Option<Expression>,
7101}
7102
7103/// LOG function
7104#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7105#[cfg_attr(feature = "bindings", derive(TS))]
7106pub struct LogFunc {
7107    pub this: Expression,
7108    pub base: Option<Expression>,
7109}
7110
7111/// CURRENT_DATE (no arguments)
7112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7113#[cfg_attr(feature = "bindings", derive(TS))]
7114pub struct CurrentDate;
7115
7116/// CURRENT_TIME
7117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7118#[cfg_attr(feature = "bindings", derive(TS))]
7119pub struct CurrentTime {
7120    pub precision: Option<u32>,
7121}
7122
7123/// CURRENT_TIMESTAMP
7124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7125#[cfg_attr(feature = "bindings", derive(TS))]
7126pub struct CurrentTimestamp {
7127    pub precision: Option<u32>,
7128    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
7129    #[serde(default)]
7130    pub sysdate: bool,
7131}
7132
7133/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
7134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7135#[cfg_attr(feature = "bindings", derive(TS))]
7136pub struct CurrentTimestampLTZ {
7137    pub precision: Option<u32>,
7138}
7139
7140/// AT TIME ZONE expression for timezone conversion
7141#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7142#[cfg_attr(feature = "bindings", derive(TS))]
7143pub struct AtTimeZone {
7144    /// The expression to convert
7145    pub this: Expression,
7146    /// The target timezone
7147    pub zone: Expression,
7148}
7149
7150/// DATE_ADD / DATE_SUB function
7151#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7152#[cfg_attr(feature = "bindings", derive(TS))]
7153pub struct DateAddFunc {
7154    pub this: Expression,
7155    pub interval: Expression,
7156    pub unit: IntervalUnit,
7157}
7158
7159/// DATEDIFF function
7160#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7161#[cfg_attr(feature = "bindings", derive(TS))]
7162pub struct DateDiffFunc {
7163    pub this: Expression,
7164    pub expression: Expression,
7165    pub unit: Option<IntervalUnit>,
7166}
7167
7168/// DATE_TRUNC function
7169#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7170#[cfg_attr(feature = "bindings", derive(TS))]
7171pub struct DateTruncFunc {
7172    pub this: Expression,
7173    pub unit: DateTimeField,
7174}
7175
7176/// EXTRACT function
7177#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7178#[cfg_attr(feature = "bindings", derive(TS))]
7179pub struct ExtractFunc {
7180    pub this: Expression,
7181    pub field: DateTimeField,
7182}
7183
7184#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7185#[cfg_attr(feature = "bindings", derive(TS))]
7186pub enum DateTimeField {
7187    Year,
7188    Month,
7189    Day,
7190    Hour,
7191    Minute,
7192    Second,
7193    Millisecond,
7194    Microsecond,
7195    DayOfWeek,
7196    DayOfYear,
7197    Week,
7198    /// Week with a modifier like WEEK(monday), WEEK(sunday)
7199    WeekWithModifier(String),
7200    Quarter,
7201    Epoch,
7202    Timezone,
7203    TimezoneHour,
7204    TimezoneMinute,
7205    Date,
7206    Time,
7207    /// Custom datetime field for dialect-specific or arbitrary fields
7208    Custom(String),
7209}
7210
7211/// TO_DATE function
7212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7213#[cfg_attr(feature = "bindings", derive(TS))]
7214pub struct ToDateFunc {
7215    pub this: Expression,
7216    pub format: Option<Expression>,
7217}
7218
7219/// TO_TIMESTAMP function
7220#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7221#[cfg_attr(feature = "bindings", derive(TS))]
7222pub struct ToTimestampFunc {
7223    pub this: Expression,
7224    pub format: Option<Expression>,
7225}
7226
7227/// IF function
7228#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7229#[cfg_attr(feature = "bindings", derive(TS))]
7230pub struct IfFunc {
7231    pub condition: Expression,
7232    pub true_value: Expression,
7233    pub false_value: Option<Expression>,
7234    /// Original function name (IF, IFF, IIF) for round-trip preservation
7235    #[serde(skip_serializing_if = "Option::is_none", default)]
7236    pub original_name: Option<String>,
7237    /// Inferred data type from type annotation
7238    #[serde(default, skip_serializing_if = "Option::is_none")]
7239    #[ast(skip)]
7240    pub inferred_type: Option<DataType>,
7241}
7242
7243/// NVL2 function
7244#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7245#[cfg_attr(feature = "bindings", derive(TS))]
7246pub struct Nvl2Func {
7247    pub this: Expression,
7248    pub true_value: Expression,
7249    pub false_value: Expression,
7250    /// Inferred data type from type annotation
7251    #[serde(default, skip_serializing_if = "Option::is_none")]
7252    #[ast(skip)]
7253    pub inferred_type: Option<DataType>,
7254}
7255
7256// ============================================================================
7257// Typed Aggregate Function types
7258// ============================================================================
7259
7260/// Generic aggregate function base type
7261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7262#[cfg_attr(feature = "bindings", derive(TS))]
7263pub struct AggFunc {
7264    pub this: Expression,
7265    pub distinct: bool,
7266    pub filter: Option<Expression>,
7267    pub order_by: Vec<Ordered>,
7268    /// Original function name (case-preserving) when parsed from SQL
7269    #[serde(skip_serializing_if = "Option::is_none", default)]
7270    pub name: Option<String>,
7271    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
7272    #[serde(skip_serializing_if = "Option::is_none", default)]
7273    pub ignore_nulls: Option<bool>,
7274    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
7275    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
7276    #[serde(skip_serializing_if = "Option::is_none", default)]
7277    pub having_max: Option<(Box<Expression>, bool)>,
7278    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
7279    #[serde(skip_serializing_if = "Option::is_none", default)]
7280    pub limit: Option<Box<Expression>>,
7281    /// Inferred data type from type annotation
7282    #[serde(default, skip_serializing_if = "Option::is_none")]
7283    #[ast(skip)]
7284    pub inferred_type: Option<DataType>,
7285}
7286
7287/// COUNT function with optional star
7288#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7289#[cfg_attr(feature = "bindings", derive(TS))]
7290pub struct CountFunc {
7291    pub this: Option<Expression>,
7292    pub star: bool,
7293    pub distinct: bool,
7294    pub filter: Option<Expression>,
7295    /// IGNORE NULLS (true) or RESPECT NULLS (false)
7296    #[serde(default, skip_serializing_if = "Option::is_none")]
7297    pub ignore_nulls: Option<bool>,
7298    /// Original function name for case preservation (e.g., "count" or "COUNT")
7299    #[serde(default, skip_serializing_if = "Option::is_none")]
7300    pub original_name: Option<String>,
7301    /// Inferred data type from type annotation
7302    #[serde(default, skip_serializing_if = "Option::is_none")]
7303    #[ast(skip)]
7304    pub inferred_type: Option<DataType>,
7305}
7306
7307/// GROUP_CONCAT function (MySQL style)
7308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7309#[cfg_attr(feature = "bindings", derive(TS))]
7310pub struct GroupConcatFunc {
7311    pub this: Expression,
7312    pub separator: Option<Expression>,
7313    pub order_by: Option<Vec<Ordered>>,
7314    pub distinct: bool,
7315    pub filter: Option<Expression>,
7316    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
7317    #[serde(default, skip_serializing_if = "Option::is_none")]
7318    pub limit: Option<Box<Expression>>,
7319    /// Inferred data type from type annotation
7320    #[serde(default, skip_serializing_if = "Option::is_none")]
7321    #[ast(skip)]
7322    pub inferred_type: Option<DataType>,
7323}
7324
7325/// STRING_AGG function (PostgreSQL/Standard SQL)
7326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7327#[cfg_attr(feature = "bindings", derive(TS))]
7328pub struct StringAggFunc {
7329    pub this: Expression,
7330    #[serde(default)]
7331    pub separator: Option<Expression>,
7332    #[serde(default)]
7333    pub order_by: Option<Vec<Ordered>>,
7334    #[serde(default)]
7335    pub distinct: bool,
7336    #[serde(default)]
7337    pub filter: Option<Expression>,
7338    /// BigQuery LIMIT inside STRING_AGG
7339    #[serde(default, skip_serializing_if = "Option::is_none")]
7340    pub limit: Option<Box<Expression>>,
7341    /// Inferred data type from type annotation
7342    #[serde(default, skip_serializing_if = "Option::is_none")]
7343    #[ast(skip)]
7344    pub inferred_type: Option<DataType>,
7345}
7346
7347/// LISTAGG function (Oracle style)
7348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7349#[cfg_attr(feature = "bindings", derive(TS))]
7350pub struct ListAggFunc {
7351    /// Retain source byte-limit and overflow semantics through AST generation.
7352    #[serde(default, skip_serializing_if = "Option::is_none")]
7353    #[ast(skip)]
7354    pub source_dialect: Option<crate::dialects::DialectType>,
7355    pub this: Expression,
7356    pub separator: Option<Expression>,
7357    pub on_overflow: Option<ListAggOverflow>,
7358    /// Vertica `USING PARAMETERS max_length = n`
7359    #[serde(default, skip_serializing_if = "Option::is_none")]
7360    pub max_length: Option<Box<Expression>>,
7361    pub order_by: Option<Vec<Ordered>>,
7362    pub distinct: bool,
7363    pub filter: Option<Expression>,
7364    /// Inferred data type from type annotation
7365    #[serde(default, skip_serializing_if = "Option::is_none")]
7366    #[ast(skip)]
7367    pub inferred_type: Option<DataType>,
7368}
7369
7370/// LISTAGG ON OVERFLOW behavior
7371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7372#[cfg_attr(feature = "bindings", derive(TS))]
7373pub enum ListAggOverflow {
7374    Error,
7375    Truncate {
7376        filler: Option<Expression>,
7377        with_count: bool,
7378    },
7379}
7380
7381/// SUM_IF / COUNT_IF function
7382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7383#[cfg_attr(feature = "bindings", derive(TS))]
7384pub struct SumIfFunc {
7385    pub this: Expression,
7386    pub condition: Expression,
7387    pub filter: Option<Expression>,
7388    /// Inferred data type from type annotation
7389    #[serde(default, skip_serializing_if = "Option::is_none")]
7390    #[ast(skip)]
7391    pub inferred_type: Option<DataType>,
7392}
7393
7394/// APPROX_PERCENTILE function
7395#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7396#[cfg_attr(feature = "bindings", derive(TS))]
7397pub struct ApproxPercentileFunc {
7398    pub this: Expression,
7399    pub percentile: Expression,
7400    pub accuracy: Option<Expression>,
7401    pub filter: Option<Expression>,
7402}
7403
7404/// PERCENTILE_CONT / PERCENTILE_DISC function
7405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7406#[cfg_attr(feature = "bindings", derive(TS))]
7407pub struct PercentileFunc {
7408    pub this: Expression,
7409    pub percentile: Expression,
7410    pub order_by: Option<Vec<Ordered>>,
7411    pub filter: Option<Expression>,
7412}
7413
7414// ============================================================================
7415// Typed Window Function types
7416// ============================================================================
7417
7418/// ROW_NUMBER function (no arguments)
7419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7420#[cfg_attr(feature = "bindings", derive(TS))]
7421pub struct RowNumber;
7422
7423/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7424#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7425#[cfg_attr(feature = "bindings", derive(TS))]
7426pub struct Rank {
7427    /// DuckDB: RANK(ORDER BY col) - order by inside function
7428    #[serde(default, skip_serializing_if = "Option::is_none")]
7429    pub order_by: Option<Vec<Ordered>>,
7430    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7431    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7432    pub args: Vec<Expression>,
7433}
7434
7435/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
7436#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7437#[cfg_attr(feature = "bindings", derive(TS))]
7438pub struct DenseRank {
7439    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7440    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7441    pub args: Vec<Expression>,
7442}
7443
7444/// NTILE function (DuckDB allows ORDER BY inside)
7445#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7446#[cfg_attr(feature = "bindings", derive(TS))]
7447pub struct NTileFunc {
7448    /// num_buckets is optional to support Databricks NTILE() without arguments
7449    #[serde(default, skip_serializing_if = "Option::is_none")]
7450    pub num_buckets: Option<Expression>,
7451    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
7452    #[serde(default, skip_serializing_if = "Option::is_none")]
7453    pub order_by: Option<Vec<Ordered>>,
7454}
7455
7456/// LEAD / LAG function
7457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7458#[cfg_attr(feature = "bindings", derive(TS))]
7459pub struct LeadLagFunc {
7460    pub this: Expression,
7461    pub offset: Option<Expression>,
7462    pub default: Option<Expression>,
7463    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7464    #[serde(default, skip_serializing_if = "Option::is_none")]
7465    pub ignore_nulls: Option<bool>,
7466}
7467
7468/// FIRST_VALUE / LAST_VALUE function
7469#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7470#[cfg_attr(feature = "bindings", derive(TS))]
7471pub struct ValueFunc {
7472    pub this: Expression,
7473    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7474    #[serde(default, skip_serializing_if = "Option::is_none")]
7475    pub ignore_nulls: Option<bool>,
7476    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
7477    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7478    pub order_by: Vec<Ordered>,
7479}
7480
7481/// NTH_VALUE function
7482#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7483#[cfg_attr(feature = "bindings", derive(TS))]
7484pub struct NthValueFunc {
7485    pub this: Expression,
7486    pub offset: Expression,
7487    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7488    #[serde(default, skip_serializing_if = "Option::is_none")]
7489    pub ignore_nulls: Option<bool>,
7490    /// Snowflake FROM FIRST / FROM LAST clause
7491    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
7492    #[serde(default, skip_serializing_if = "Option::is_none")]
7493    pub from_first: Option<bool>,
7494}
7495
7496/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7498#[cfg_attr(feature = "bindings", derive(TS))]
7499pub struct PercentRank {
7500    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
7501    #[serde(default, skip_serializing_if = "Option::is_none")]
7502    pub order_by: Option<Vec<Ordered>>,
7503    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7504    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7505    pub args: Vec<Expression>,
7506}
7507
7508/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7510#[cfg_attr(feature = "bindings", derive(TS))]
7511pub struct CumeDist {
7512    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
7513    #[serde(default, skip_serializing_if = "Option::is_none")]
7514    pub order_by: Option<Vec<Ordered>>,
7515    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7516    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7517    pub args: Vec<Expression>,
7518}
7519
7520// ============================================================================
7521// Additional String Function types
7522// ============================================================================
7523
7524/// POSITION/INSTR function
7525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7526#[cfg_attr(feature = "bindings", derive(TS))]
7527pub struct PositionFunc {
7528    pub substring: Expression,
7529    pub string: Expression,
7530    pub start: Option<Expression>,
7531}
7532
7533// ============================================================================
7534// Additional Math Function types
7535// ============================================================================
7536
7537/// RANDOM function (no arguments)
7538#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7539#[cfg_attr(feature = "bindings", derive(TS))]
7540pub struct Random;
7541
7542/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
7543#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7544#[cfg_attr(feature = "bindings", derive(TS))]
7545pub struct Rand {
7546    pub seed: Option<Box<Expression>>,
7547    /// Teradata RANDOM lower bound
7548    #[serde(default)]
7549    pub lower: Option<Box<Expression>>,
7550    /// Teradata RANDOM upper bound
7551    #[serde(default)]
7552    pub upper: Option<Box<Expression>>,
7553}
7554
7555/// TRUNCATE / TRUNC function
7556#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7557#[cfg_attr(feature = "bindings", derive(TS))]
7558pub struct TruncateFunc {
7559    pub this: Expression,
7560    pub decimals: Option<Expression>,
7561}
7562
7563/// PI function (no arguments)
7564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7565#[cfg_attr(feature = "bindings", derive(TS))]
7566pub struct Pi;
7567
7568// ============================================================================
7569// Control Flow Function types
7570// ============================================================================
7571
7572/// DECODE function (Oracle style)
7573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7574#[cfg_attr(feature = "bindings", derive(TS))]
7575pub struct DecodeFunc {
7576    pub this: Expression,
7577    pub search_results: Vec<(Expression, Expression)>,
7578    pub default: Option<Expression>,
7579}
7580
7581// ============================================================================
7582// Additional Date/Time Function types
7583// ============================================================================
7584
7585/// DATE_FORMAT / FORMAT_DATE function
7586#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7587#[cfg_attr(feature = "bindings", derive(TS))]
7588pub struct DateFormatFunc {
7589    pub this: Expression,
7590    pub format: Expression,
7591}
7592
7593/// FROM_UNIXTIME function
7594#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7595#[cfg_attr(feature = "bindings", derive(TS))]
7596pub struct FromUnixtimeFunc {
7597    pub this: Expression,
7598    pub format: Option<Expression>,
7599}
7600
7601/// UNIX_TIMESTAMP function
7602#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7603#[cfg_attr(feature = "bindings", derive(TS))]
7604pub struct UnixTimestampFunc {
7605    pub this: Option<Expression>,
7606    pub format: Option<Expression>,
7607}
7608
7609/// MAKE_DATE function
7610#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7611#[cfg_attr(feature = "bindings", derive(TS))]
7612pub struct MakeDateFunc {
7613    pub year: Expression,
7614    pub month: Expression,
7615    pub day: Expression,
7616}
7617
7618/// MAKE_TIMESTAMP function
7619#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7620#[cfg_attr(feature = "bindings", derive(TS))]
7621pub struct MakeTimestampFunc {
7622    pub year: Expression,
7623    pub month: Expression,
7624    pub day: Expression,
7625    pub hour: Expression,
7626    pub minute: Expression,
7627    pub second: Expression,
7628    pub timezone: Option<Expression>,
7629}
7630
7631/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
7632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7633#[cfg_attr(feature = "bindings", derive(TS))]
7634pub struct LastDayFunc {
7635    pub this: Expression,
7636    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
7637    #[serde(skip_serializing_if = "Option::is_none", default)]
7638    pub unit: Option<DateTimeField>,
7639}
7640
7641// ============================================================================
7642// Array Function types
7643// ============================================================================
7644
7645/// ARRAY constructor
7646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7647#[cfg_attr(feature = "bindings", derive(TS))]
7648pub struct ArrayConstructor {
7649    pub expressions: Vec<Expression>,
7650    pub bracket_notation: bool,
7651    /// True if LIST keyword was used instead of ARRAY (DuckDB)
7652    pub use_list_keyword: bool,
7653    /// Inferred array data type from type annotation
7654    #[serde(default, skip_serializing_if = "Option::is_none")]
7655    #[ast(skip)]
7656    pub inferred_type: Option<DataType>,
7657}
7658
7659/// ARRAY_SORT function
7660#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7661#[cfg_attr(feature = "bindings", derive(TS))]
7662pub struct ArraySortFunc {
7663    pub this: Expression,
7664    pub comparator: Option<Expression>,
7665    pub desc: bool,
7666    pub nulls_first: Option<bool>,
7667}
7668
7669/// ARRAY_JOIN / ARRAY_TO_STRING function
7670#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7671#[cfg_attr(feature = "bindings", derive(TS))]
7672pub struct ArrayJoinFunc {
7673    pub this: Expression,
7674    pub separator: Expression,
7675    pub null_replacement: Option<Expression>,
7676}
7677
7678/// UNNEST function
7679#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7680#[cfg_attr(feature = "bindings", derive(TS))]
7681pub struct UnnestFunc {
7682    pub this: Expression,
7683    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
7684    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7685    pub expressions: Vec<Expression>,
7686    pub with_ordinality: bool,
7687    pub alias: Option<Identifier>,
7688    /// BigQuery: offset alias for WITH OFFSET AS <name>
7689    #[serde(default, skip_serializing_if = "Option::is_none")]
7690    pub offset_alias: Option<Identifier>,
7691    /// Inferred type of the first UNNEST output column.
7692    #[serde(default, skip_serializing_if = "Option::is_none")]
7693    #[ast(skip)]
7694    pub inferred_type: Option<DataType>,
7695}
7696
7697/// ARRAY_FILTER function (with lambda)
7698#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7699#[cfg_attr(feature = "bindings", derive(TS))]
7700pub struct ArrayFilterFunc {
7701    pub this: Expression,
7702    pub filter: Expression,
7703}
7704
7705/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
7706#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7707#[cfg_attr(feature = "bindings", derive(TS))]
7708pub struct ArrayTransformFunc {
7709    pub this: Expression,
7710    pub transform: Expression,
7711}
7712
7713/// SEQUENCE / GENERATE_SERIES function
7714#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7715#[cfg_attr(feature = "bindings", derive(TS))]
7716pub struct SequenceFunc {
7717    pub start: Expression,
7718    pub stop: Expression,
7719    pub step: Option<Expression>,
7720}
7721
7722// ============================================================================
7723// Struct Function types
7724// ============================================================================
7725
7726/// STRUCT constructor
7727#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7728#[cfg_attr(feature = "bindings", derive(TS))]
7729pub struct StructConstructor {
7730    pub fields: Vec<(Option<Identifier>, Expression)>,
7731}
7732
7733/// STRUCT_EXTRACT function
7734#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7735#[cfg_attr(feature = "bindings", derive(TS))]
7736pub struct StructExtractFunc {
7737    pub this: Expression,
7738    pub field: Identifier,
7739}
7740
7741/// NAMED_STRUCT function
7742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7743#[cfg_attr(feature = "bindings", derive(TS))]
7744pub struct NamedStructFunc {
7745    pub pairs: Vec<(Expression, Expression)>,
7746}
7747
7748// ============================================================================
7749// Map Function types
7750// ============================================================================
7751
7752/// MAP constructor
7753#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7754#[cfg_attr(feature = "bindings", derive(TS))]
7755pub struct MapConstructor {
7756    pub keys: Vec<Expression>,
7757    pub values: Vec<Expression>,
7758    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7759    #[serde(default)]
7760    pub curly_brace_syntax: bool,
7761    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7762    #[serde(default)]
7763    pub with_map_keyword: bool,
7764}
7765
7766/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7768#[cfg_attr(feature = "bindings", derive(TS))]
7769pub struct TransformFunc {
7770    pub this: Expression,
7771    pub transform: Expression,
7772}
7773
7774/// Function call with EMITS clause (Exasol)
7775/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7777#[cfg_attr(feature = "bindings", derive(TS))]
7778pub struct FunctionEmits {
7779    /// The function call expression
7780    pub this: Expression,
7781    /// The EMITS schema definition
7782    pub emits: Expression,
7783}
7784
7785// ============================================================================
7786// JSON Function types
7787// ============================================================================
7788
7789/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7790#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7791#[cfg_attr(feature = "bindings", derive(TS))]
7792pub struct JsonExtractFunc {
7793    #[serde(default, skip_serializing_if = "Option::is_none")]
7794    #[ast(skip)]
7795    pub source_dialect: Option<crate::dialects::DialectType>,
7796    /// Structured SQL/JSON wrapper and error/empty behavior.
7797    #[serde(default, skip_serializing_if = "Option::is_none")]
7798    pub options: Option<JsonOptions>,
7799
7800    pub this: Expression,
7801    pub path: Expression,
7802    pub returning: Option<DataType>,
7803    /// True if parsed from -> or ->> operator syntax
7804    #[serde(default)]
7805    pub arrow_syntax: bool,
7806    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7807    #[serde(default)]
7808    pub hash_arrow_syntax: bool,
7809    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7810    #[serde(default)]
7811    pub wrapper_option: Option<String>,
7812    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7813    #[serde(default)]
7814    pub quotes_option: Option<String>,
7815    /// ON SCALAR STRING flag
7816    #[serde(default)]
7817    pub on_scalar_string: bool,
7818    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7819    #[serde(default)]
7820    pub on_error: Option<String>,
7821}
7822
7823/// JSON path extraction
7824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7825#[cfg_attr(feature = "bindings", derive(TS))]
7826pub struct JsonPathFunc {
7827    pub this: Expression,
7828    pub paths: Vec<Expression>,
7829}
7830
7831/// JSON_OBJECT function
7832#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7833#[cfg_attr(feature = "bindings", derive(TS))]
7834pub struct JsonObjectFunc {
7835    pub pairs: Vec<(Expression, Expression)>,
7836    pub null_handling: Option<JsonNullHandling>,
7837    #[serde(default)]
7838    pub with_unique_keys: bool,
7839    #[serde(default)]
7840    pub returning_type: Option<DataType>,
7841    #[serde(default)]
7842    pub format_json: bool,
7843    #[serde(default)]
7844    pub encoding: Option<String>,
7845    /// For JSON_OBJECT(*) syntax
7846    #[serde(default)]
7847    pub star: bool,
7848}
7849
7850/// JSON null handling options
7851#[derive(
7852    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7853)]
7854#[cfg_attr(feature = "bindings", derive(TS))]
7855pub enum JsonNullHandling {
7856    NullOnNull,
7857    AbsentOnNull,
7858}
7859
7860/// JSON_SET / JSON_INSERT function
7861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7862#[cfg_attr(feature = "bindings", derive(TS))]
7863pub struct JsonModifyFunc {
7864    pub this: Expression,
7865    pub path_values: Vec<(Expression, Expression)>,
7866}
7867
7868/// JSON_ARRAYAGG function
7869#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7870#[cfg_attr(feature = "bindings", derive(TS))]
7871pub struct JsonArrayAggFunc {
7872    pub this: Expression,
7873    pub order_by: Option<Vec<Ordered>>,
7874    pub null_handling: Option<JsonNullHandling>,
7875    pub filter: Option<Expression>,
7876}
7877
7878/// JSON_OBJECTAGG function
7879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7880#[cfg_attr(feature = "bindings", derive(TS))]
7881pub struct JsonObjectAggFunc {
7882    pub key: Expression,
7883    pub value: Expression,
7884    pub null_handling: Option<JsonNullHandling>,
7885    pub filter: Option<Expression>,
7886}
7887
7888// ============================================================================
7889// Type Casting Function types
7890// ============================================================================
7891
7892/// CONVERT function (SQL Server style)
7893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7894#[cfg_attr(feature = "bindings", derive(TS))]
7895pub struct ConvertFunc {
7896    pub this: Expression,
7897    pub to: DataType,
7898    pub style: Option<Expression>,
7899}
7900
7901// ============================================================================
7902// Additional Expression types
7903// ============================================================================
7904
7905/// Lambda expression
7906#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7907#[cfg_attr(feature = "bindings", derive(TS))]
7908pub struct LambdaExpr {
7909    pub parameters: Vec<Identifier>,
7910    pub body: Expression,
7911    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7912    #[serde(default)]
7913    pub colon: bool,
7914    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7915    /// Maps parameter index to data type
7916    #[serde(default)]
7917    pub parameter_types: Vec<Option<DataType>>,
7918}
7919
7920/// Parameter (parameterized queries)
7921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7922#[cfg_attr(feature = "bindings", derive(TS))]
7923pub struct Parameter {
7924    pub name: Option<String>,
7925    pub index: Option<u32>,
7926    pub style: ParameterStyle,
7927    /// Whether the name was quoted (e.g., @"x" vs @x)
7928    #[serde(default)]
7929    pub quoted: bool,
7930    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7931    #[serde(default)]
7932    pub string_quoted: bool,
7933    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7934    #[serde(default)]
7935    pub expression: Option<String>,
7936}
7937
7938/// Parameter placeholder styles
7939#[derive(
7940    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7941)]
7942#[cfg_attr(feature = "bindings", derive(TS))]
7943pub enum ParameterStyle {
7944    Question,     // ?
7945    Dollar,       // $1, $2
7946    DollarBrace,  // ${name} (Databricks, Hive template variables)
7947    Brace,        // {name} (Spark/Databricks widget/template variables)
7948    Colon,        // :name
7949    At,           // @name
7950    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7951    DoubleDollar, // $$name
7952    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7953}
7954
7955/// Placeholder expression
7956#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7957#[cfg_attr(feature = "bindings", derive(TS))]
7958pub struct Placeholder {
7959    pub index: Option<u32>,
7960}
7961
7962/// Named argument in function call: name => value or name := value
7963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7964#[cfg_attr(feature = "bindings", derive(TS))]
7965pub struct NamedArgument {
7966    pub name: Identifier,
7967    pub value: Expression,
7968    /// The separator used: `=>`, `:=`, or `=`
7969    pub separator: NamedArgSeparator,
7970}
7971
7972/// Separator style for named arguments
7973#[derive(
7974    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7975)]
7976#[cfg_attr(feature = "bindings", derive(TS))]
7977pub enum NamedArgSeparator {
7978    /// `=>` (standard SQL, Snowflake, BigQuery)
7979    DArrow,
7980    /// `:=` (Oracle, MySQL)
7981    ColonEq,
7982    /// `=` (simple equals, some dialects)
7983    Eq,
7984}
7985
7986/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7987/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7989#[cfg_attr(feature = "bindings", derive(TS))]
7990pub struct TableArgument {
7991    /// The keyword prefix: "TABLE" or "MODEL"
7992    pub prefix: String,
7993    /// The table/model reference expression
7994    pub this: Expression,
7995}
7996
7997/// SQL Comment preservation
7998#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7999#[cfg_attr(feature = "bindings", derive(TS))]
8000pub struct SqlComment {
8001    pub text: String,
8002    pub is_block: bool,
8003}
8004
8005// ============================================================================
8006// Additional Predicate types
8007// ============================================================================
8008
8009/// SIMILAR TO expression
8010#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8011#[cfg_attr(feature = "bindings", derive(TS))]
8012pub struct SimilarToExpr {
8013    pub this: Expression,
8014    pub pattern: Expression,
8015    pub escape: Option<Expression>,
8016    pub not: bool,
8017}
8018
8019/// ANY / ALL quantified expression
8020#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8021#[cfg_attr(feature = "bindings", derive(TS))]
8022pub struct QuantifiedExpr {
8023    pub this: Expression,
8024    pub subquery: Expression,
8025    pub op: Option<QuantifiedOp>,
8026}
8027
8028/// Comparison operator for quantified expressions
8029#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8030#[cfg_attr(feature = "bindings", derive(TS))]
8031pub enum QuantifiedOp {
8032    Eq,
8033    Neq,
8034    Lt,
8035    Lte,
8036    Gt,
8037    Gte,
8038}
8039
8040/// OVERLAPS expression
8041/// Supports two forms:
8042/// 1. Simple binary: a OVERLAPS b (this, expression are set)
8043/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
8044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8045#[cfg_attr(feature = "bindings", derive(TS))]
8046pub struct OverlapsExpr {
8047    /// Left operand for simple binary form
8048    #[serde(skip_serializing_if = "Option::is_none")]
8049    pub this: Option<Expression>,
8050    /// Right operand for simple binary form
8051    #[serde(skip_serializing_if = "Option::is_none")]
8052    pub expression: Option<Expression>,
8053    /// Left range start for full ANSI form
8054    #[serde(skip_serializing_if = "Option::is_none")]
8055    pub left_start: Option<Expression>,
8056    /// Left range end for full ANSI form
8057    #[serde(skip_serializing_if = "Option::is_none")]
8058    pub left_end: Option<Expression>,
8059    /// Right range start for full ANSI form
8060    #[serde(skip_serializing_if = "Option::is_none")]
8061    pub right_start: Option<Expression>,
8062    /// Right range end for full ANSI form
8063    #[serde(skip_serializing_if = "Option::is_none")]
8064    pub right_end: Option<Expression>,
8065}
8066
8067// ============================================================================
8068// Array/Struct/Map access
8069// ============================================================================
8070
8071/// Subscript access (array[index] or map[key])
8072#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8073#[cfg_attr(feature = "bindings", derive(TS))]
8074pub struct Subscript {
8075    pub this: Expression,
8076    pub index: Expression,
8077}
8078
8079/// Dot access (struct.field)
8080#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8081#[cfg_attr(feature = "bindings", derive(TS))]
8082pub struct DotAccess {
8083    pub this: Expression,
8084    pub field: Identifier,
8085    #[serde(default, skip_serializing_if = "Option::is_none")]
8086    pub inferred_type: Option<DataType>,
8087}
8088
8089/// Method call (expr.method(args))
8090#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8091#[cfg_attr(feature = "bindings", derive(TS))]
8092pub struct MethodCall {
8093    pub this: Expression,
8094    pub method: Identifier,
8095    pub args: Vec<Expression>,
8096}
8097
8098/// Array slice (array[start:end])
8099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8100#[cfg_attr(feature = "bindings", derive(TS))]
8101pub struct ArraySlice {
8102    pub this: Expression,
8103    pub start: Option<Expression>,
8104    pub end: Option<Expression>,
8105}
8106
8107// ============================================================================
8108// DDL (Data Definition Language) Statements
8109// ============================================================================
8110
8111/// ON COMMIT behavior for temporary tables
8112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8113#[cfg_attr(feature = "bindings", derive(TS))]
8114pub enum OnCommit {
8115    /// ON COMMIT PRESERVE ROWS
8116    PreserveRows,
8117    /// ON COMMIT DELETE ROWS
8118    DeleteRows,
8119}
8120
8121/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
8122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8123#[cfg_attr(feature = "bindings", derive(TS))]
8124pub struct TiDBAutoRandom {
8125    #[serde(default, skip_serializing_if = "Option::is_none")]
8126    pub shard_bits: Option<u64>,
8127    #[serde(default, skip_serializing_if = "Option::is_none")]
8128    pub range_bits: Option<u64>,
8129    /// Whether the attribute was wrapped in a TiDB executable comment.
8130    #[serde(default)]
8131    pub executable_comment: bool,
8132}
8133
8134/// A TiDB-specific table option and its source syntax.
8135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8136#[cfg_attr(feature = "bindings", derive(TS))]
8137pub struct TiDBTableOption {
8138    pub kind: TiDBTableOptionKind,
8139    /// Whether the option was wrapped in a TiDB executable comment.
8140    #[serde(default)]
8141    pub executable_comment: bool,
8142}
8143
8144/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
8145#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8146#[cfg_attr(feature = "bindings", derive(TS))]
8147#[serde(tag = "type", rename_all = "snake_case")]
8148pub enum TiDBTableOptionKind {
8149    ShardRowIdBits {
8150        bits: u64,
8151    },
8152    PreSplitRegions {
8153        regions: u64,
8154    },
8155    AutoRandomBase {
8156        value: u64,
8157    },
8158    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
8159    PlacementPolicy {
8160        policy: Option<Identifier>,
8161    },
8162    Ttl {
8163        column: Identifier,
8164        interval: Interval,
8165        #[serde(default, skip_serializing_if = "Option::is_none")]
8166        enabled: Option<bool>,
8167    },
8168    TtlEnable {
8169        enabled: bool,
8170    },
8171    TtlJobInterval {
8172        interval: String,
8173    },
8174}
8175
8176/// CREATE TABLE statement
8177#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8178#[cfg_attr(feature = "bindings", derive(TS))]
8179pub struct CreateTable {
8180    pub name: TableRef,
8181    /// ClickHouse: ON CLUSTER clause for distributed DDL
8182    #[serde(default, skip_serializing_if = "Option::is_none")]
8183    pub on_cluster: Option<OnCluster>,
8184    pub columns: Vec<ColumnDef>,
8185    pub constraints: Vec<TableConstraint>,
8186    pub if_not_exists: bool,
8187    pub temporary: bool,
8188    pub or_replace: bool,
8189    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
8190    #[serde(default, skip_serializing_if = "Option::is_none")]
8191    pub table_modifier: Option<String>,
8192    /// Dialect whose call semantics must be retained through independent generation.
8193    #[serde(default, skip_serializing_if = "Option::is_none")]
8194    #[ast(skip)]
8195    pub source_dialect: Option<crate::dialects::DialectType>,
8196
8197    pub as_select: Option<Expression>,
8198    /// Whether the AS SELECT was wrapped in parentheses
8199    #[serde(default)]
8200    pub as_select_parenthesized: bool,
8201    /// ON COMMIT behavior for temporary tables
8202    #[serde(default)]
8203    pub on_commit: Option<OnCommit>,
8204    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
8205    #[serde(default)]
8206    pub clone_source: Option<TableRef>,
8207    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
8208    #[serde(default, skip_serializing_if = "Option::is_none")]
8209    pub clone_at_clause: Option<Expression>,
8210    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
8211    #[serde(default)]
8212    pub is_copy: bool,
8213    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
8214    #[serde(default)]
8215    pub shallow_clone: bool,
8216    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
8217    #[serde(default)]
8218    pub deep_clone: bool,
8219    /// Leading comments before the statement
8220    #[serde(default)]
8221    pub leading_comments: Vec<String>,
8222    /// WITH properties (e.g., WITH (FORMAT='parquet'))
8223    #[serde(default)]
8224    pub with_properties: Vec<(String, String)>,
8225    /// Teradata: table options after name before columns (comma-separated)
8226    #[serde(default)]
8227    pub teradata_post_name_options: Vec<String>,
8228    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
8229    #[serde(default)]
8230    pub with_data: Option<bool>,
8231    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
8232    #[serde(default)]
8233    pub with_statistics: Option<bool>,
8234    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
8235    #[serde(default)]
8236    pub teradata_indexes: Vec<TeradataIndex>,
8237    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
8238    #[serde(default)]
8239    pub with_cte: Option<With>,
8240    /// Table properties like DEFAULT COLLATE (BigQuery)
8241    #[serde(default)]
8242    pub properties: Vec<Expression>,
8243    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
8244    #[serde(default, skip_serializing_if = "Option::is_none")]
8245    pub partition_of: Option<Expression>,
8246    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
8247    #[serde(default)]
8248    pub post_table_properties: Vec<Expression>,
8249    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
8250    #[serde(default)]
8251    pub mysql_table_options: Vec<(String, String)>,
8252    /// TiDB-specific table options after column definitions.
8253    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8254    pub tidb_table_options: Vec<TiDBTableOption>,
8255    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
8256    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8257    pub inherits: Vec<TableRef>,
8258    /// TSQL ON filegroup or ON filegroup (partition_column) clause
8259    #[serde(default, skip_serializing_if = "Option::is_none")]
8260    pub on_property: Option<OnProperty>,
8261    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
8262    #[serde(default)]
8263    pub copy_grants: bool,
8264    /// Snowflake: USING TEMPLATE expression for schema inference
8265    #[serde(default, skip_serializing_if = "Option::is_none")]
8266    pub using_template: Option<Box<Expression>>,
8267    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
8268    #[serde(default, skip_serializing_if = "Option::is_none")]
8269    pub rollup: Option<RollupProperty>,
8270    /// ClickHouse: UUID 'xxx' clause after table name
8271    #[serde(default, skip_serializing_if = "Option::is_none")]
8272    pub uuid: Option<String>,
8273    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
8274    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
8275    /// could appear in other engines.
8276    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8277    pub with_partition_columns: Vec<ColumnDef>,
8278    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
8279    /// for external tables that reference a Cloud Resource connection.
8280    #[serde(default, skip_serializing_if = "Option::is_none")]
8281    pub with_connection: Option<TableRef>,
8282}
8283
8284/// Teradata index specification for CREATE TABLE
8285#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8286#[cfg_attr(feature = "bindings", derive(TS))]
8287pub struct TeradataIndex {
8288    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
8289    pub kind: TeradataIndexKind,
8290    /// Optional index name
8291    pub name: Option<String>,
8292    /// Optional column list
8293    pub columns: Vec<String>,
8294}
8295
8296/// Kind of Teradata index
8297#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8298#[cfg_attr(feature = "bindings", derive(TS))]
8299pub enum TeradataIndexKind {
8300    /// NO PRIMARY INDEX
8301    NoPrimary,
8302    /// PRIMARY INDEX
8303    Primary,
8304    /// PRIMARY AMP INDEX
8305    PrimaryAmp,
8306    /// UNIQUE INDEX
8307    Unique,
8308    /// UNIQUE PRIMARY INDEX
8309    UniquePrimary,
8310    /// INDEX (secondary, non-primary)
8311    Secondary,
8312}
8313
8314impl CreateTable {
8315    pub fn new(name: impl Into<String>) -> Self {
8316        Self {
8317            name: TableRef::new(name),
8318            on_cluster: None,
8319            columns: Vec::new(),
8320            constraints: Vec::new(),
8321            if_not_exists: false,
8322            temporary: false,
8323            or_replace: false,
8324            table_modifier: None,
8325            source_dialect: None,
8326            as_select: None,
8327            as_select_parenthesized: false,
8328            on_commit: None,
8329            clone_source: None,
8330            clone_at_clause: None,
8331            shallow_clone: false,
8332            deep_clone: false,
8333            is_copy: false,
8334            leading_comments: Vec::new(),
8335            with_properties: Vec::new(),
8336            teradata_post_name_options: Vec::new(),
8337            with_data: None,
8338            with_statistics: None,
8339            teradata_indexes: Vec::new(),
8340            with_cte: None,
8341            properties: Vec::new(),
8342            partition_of: None,
8343            post_table_properties: Vec::new(),
8344            mysql_table_options: Vec::new(),
8345            tidb_table_options: Vec::new(),
8346            inherits: Vec::new(),
8347            on_property: None,
8348            copy_grants: false,
8349            using_template: None,
8350            rollup: None,
8351            uuid: None,
8352            with_partition_columns: Vec::new(),
8353            with_connection: None,
8354        }
8355    }
8356}
8357
8358/// Sort order for PRIMARY KEY ASC/DESC
8359#[derive(
8360    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
8361)]
8362#[cfg_attr(feature = "bindings", derive(TS))]
8363pub enum SortOrder {
8364    Asc,
8365    Desc,
8366}
8367
8368/// Type of column constraint for tracking order
8369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8370#[cfg_attr(feature = "bindings", derive(TS))]
8371pub enum ConstraintType {
8372    NotNull,
8373    Null,
8374    PrimaryKey,
8375    Unique,
8376    Default,
8377    AutoIncrement,
8378    AutoRandom,
8379    Collate,
8380    Comment,
8381    References,
8382    Check,
8383    GeneratedAsIdentity,
8384    /// Snowflake: TAG (key='value', ...)
8385    Tags,
8386    /// Computed/generated column
8387    ComputedColumn,
8388    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
8389    GeneratedAsRow,
8390    /// MySQL: ON UPDATE expression
8391    OnUpdate,
8392    /// PATH constraint for XMLTABLE/JSON_TABLE columns
8393    Path,
8394    /// Redshift: ENCODE encoding_type
8395    Encode,
8396}
8397
8398/// Column definition in CREATE TABLE
8399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8400#[cfg_attr(feature = "bindings", derive(TS))]
8401pub struct ColumnDef {
8402    pub name: Identifier,
8403    pub data_type: DataType,
8404    pub nullable: Option<bool>,
8405    pub default: Option<Expression>,
8406    pub primary_key: bool,
8407    /// Sort order for PRIMARY KEY (ASC/DESC)
8408    #[serde(default)]
8409    pub primary_key_order: Option<SortOrder>,
8410    pub unique: bool,
8411    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
8412    #[serde(default)]
8413    pub unique_nulls_not_distinct: bool,
8414    pub auto_increment: bool,
8415    /// TiDB distributed primary-key allocation attribute.
8416    #[serde(default, skip_serializing_if = "Option::is_none")]
8417    pub auto_random: Option<TiDBAutoRandom>,
8418    pub comment: Option<String>,
8419    pub constraints: Vec<ColumnConstraint>,
8420    /// Track original order of constraints for accurate regeneration
8421    #[serde(default)]
8422    pub constraint_order: Vec<ConstraintType>,
8423    /// Teradata: FORMAT 'pattern'
8424    #[serde(default)]
8425    pub format: Option<String>,
8426    /// Teradata: TITLE 'title'
8427    #[serde(default)]
8428    pub title: Option<String>,
8429    /// Teradata: INLINE LENGTH n
8430    #[serde(default)]
8431    pub inline_length: Option<u64>,
8432    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
8433    #[serde(default)]
8434    pub compress: Option<Vec<Expression>>,
8435    /// Teradata: CHARACTER SET name
8436    #[serde(default)]
8437    pub character_set: Option<String>,
8438    /// Teradata: UPPERCASE
8439    #[serde(default)]
8440    pub uppercase: bool,
8441    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
8442    #[serde(default)]
8443    pub casespecific: Option<bool>,
8444    /// Snowflake: AUTOINCREMENT START value
8445    #[serde(default)]
8446    pub auto_increment_start: Option<Box<Expression>>,
8447    /// Snowflake: AUTOINCREMENT INCREMENT value
8448    #[serde(default)]
8449    pub auto_increment_increment: Option<Box<Expression>>,
8450    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
8451    #[serde(default)]
8452    pub auto_increment_order: Option<bool>,
8453    /// MySQL: UNSIGNED modifier
8454    #[serde(default)]
8455    pub unsigned: bool,
8456    /// MySQL: ZEROFILL modifier
8457    #[serde(default)]
8458    pub zerofill: bool,
8459    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
8460    #[serde(default, skip_serializing_if = "Option::is_none")]
8461    pub on_update: Option<Expression>,
8462    /// MySQL: column VISIBLE/INVISIBLE modifier.
8463    #[serde(default, skip_serializing_if = "Option::is_none")]
8464    pub visible: Option<bool>,
8465    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
8466    #[serde(default, skip_serializing_if = "Option::is_none")]
8467    pub unique_constraint_name: Option<String>,
8468    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
8469    #[serde(default, skip_serializing_if = "Option::is_none")]
8470    pub not_null_constraint_name: Option<String>,
8471    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
8472    #[serde(default, skip_serializing_if = "Option::is_none")]
8473    pub primary_key_constraint_name: Option<String>,
8474    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
8475    #[serde(default, skip_serializing_if = "Option::is_none")]
8476    pub check_constraint_name: Option<String>,
8477    /// BigQuery: OPTIONS (key=value, ...) on column
8478    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8479    pub options: Vec<Expression>,
8480    /// SQLite: Column definition without explicit type
8481    #[serde(default)]
8482    pub no_type: bool,
8483    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
8484    #[serde(default, skip_serializing_if = "Option::is_none")]
8485    pub encoding: Option<String>,
8486    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
8487    #[serde(default, skip_serializing_if = "Option::is_none")]
8488    pub codec: Option<String>,
8489    /// ClickHouse: EPHEMERAL [expr] modifier
8490    #[serde(default, skip_serializing_if = "Option::is_none")]
8491    pub ephemeral: Option<Option<Box<Expression>>>,
8492    /// ClickHouse: MATERIALIZED expr modifier
8493    #[serde(default, skip_serializing_if = "Option::is_none")]
8494    pub materialized_expr: Option<Box<Expression>>,
8495    /// ClickHouse: ALIAS expr modifier
8496    #[serde(default, skip_serializing_if = "Option::is_none")]
8497    pub alias_expr: Option<Box<Expression>>,
8498    /// ClickHouse: TTL expr modifier on columns
8499    #[serde(default, skip_serializing_if = "Option::is_none")]
8500    pub ttl_expr: Option<Box<Expression>>,
8501    /// TSQL: NOT FOR REPLICATION
8502    #[serde(default)]
8503    pub not_for_replication: bool,
8504}
8505
8506impl ColumnDef {
8507    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
8508        Self {
8509            name: Identifier::new(name),
8510            data_type,
8511            nullable: None,
8512            default: None,
8513            primary_key: false,
8514            primary_key_order: None,
8515            unique: false,
8516            unique_nulls_not_distinct: false,
8517            auto_increment: false,
8518            auto_random: None,
8519            comment: None,
8520            constraints: Vec::new(),
8521            constraint_order: Vec::new(),
8522            format: None,
8523            title: None,
8524            inline_length: None,
8525            compress: None,
8526            character_set: None,
8527            uppercase: false,
8528            casespecific: None,
8529            auto_increment_start: None,
8530            auto_increment_increment: None,
8531            auto_increment_order: None,
8532            unsigned: false,
8533            zerofill: false,
8534            on_update: None,
8535            visible: None,
8536            unique_constraint_name: None,
8537            not_null_constraint_name: None,
8538            primary_key_constraint_name: None,
8539            check_constraint_name: None,
8540            options: Vec::new(),
8541            no_type: false,
8542            encoding: None,
8543            codec: None,
8544            ephemeral: None,
8545            materialized_expr: None,
8546            alias_expr: None,
8547            ttl_expr: None,
8548            not_for_replication: false,
8549        }
8550    }
8551}
8552
8553/// Column-level constraint
8554#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8555#[cfg_attr(feature = "bindings", derive(TS))]
8556pub enum ColumnConstraint {
8557    NotNull,
8558    Null,
8559    Unique,
8560    PrimaryKey,
8561    Default(Expression),
8562    Check(Expression),
8563    References(ForeignKeyRef),
8564    GeneratedAsIdentity(GeneratedAsIdentity),
8565    Collate(Identifier),
8566    Comment(String),
8567    /// Snowflake: TAG (key='value', ...)
8568    Tags(Tags),
8569    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
8570    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
8571    ComputedColumn(ComputedColumn),
8572    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8573    GeneratedAsRow(GeneratedAsRow),
8574    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
8575    Path(Expression),
8576}
8577
8578/// Computed/generated column constraint
8579#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8580#[cfg_attr(feature = "bindings", derive(TS))]
8581pub struct ComputedColumn {
8582    /// The expression that computes the column value
8583    pub expression: Box<Expression>,
8584    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
8585    #[serde(default)]
8586    pub persisted: bool,
8587    /// NOT NULL (TSQL computed columns)
8588    #[serde(default)]
8589    pub not_null: bool,
8590    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
8591    /// When None, defaults to dialect-appropriate output
8592    #[serde(default)]
8593    pub persistence_kind: Option<String>,
8594    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
8595    #[serde(default, skip_serializing_if = "Option::is_none")]
8596    pub data_type: Option<DataType>,
8597}
8598
8599/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8600#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8601#[cfg_attr(feature = "bindings", derive(TS))]
8602pub struct GeneratedAsRow {
8603    /// true = ROW START, false = ROW END
8604    pub start: bool,
8605    /// HIDDEN modifier
8606    #[serde(default)]
8607    pub hidden: bool,
8608}
8609
8610/// Generated identity column constraint
8611#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8612#[cfg_attr(feature = "bindings", derive(TS))]
8613pub struct GeneratedAsIdentity {
8614    /// True for ALWAYS, False for BY DEFAULT
8615    pub always: bool,
8616    /// ON NULL (only valid with BY DEFAULT)
8617    pub on_null: bool,
8618    /// START WITH value
8619    pub start: Option<Box<Expression>>,
8620    /// INCREMENT BY value
8621    pub increment: Option<Box<Expression>>,
8622    /// MINVALUE
8623    pub minvalue: Option<Box<Expression>>,
8624    /// MAXVALUE
8625    pub maxvalue: Option<Box<Expression>>,
8626    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
8627    pub cycle: Option<bool>,
8628}
8629
8630/// Constraint modifiers (shared between table-level constraints)
8631#[derive(
8632    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
8633)]
8634#[cfg_attr(feature = "bindings", derive(TS))]
8635pub struct ConstraintModifiers {
8636    /// ENFORCED / NOT ENFORCED
8637    pub enforced: Option<bool>,
8638    /// DEFERRABLE / NOT DEFERRABLE
8639    pub deferrable: Option<bool>,
8640    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
8641    pub initially_deferred: Option<bool>,
8642    /// NORELY (Oracle)
8643    pub norely: bool,
8644    /// RELY (Oracle)
8645    pub rely: bool,
8646    /// USING index type (MySQL): BTREE or HASH
8647    #[serde(default)]
8648    pub using: Option<String>,
8649    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
8650    #[serde(default)]
8651    pub using_before_columns: bool,
8652    /// MySQL index COMMENT 'text'
8653    #[serde(default, skip_serializing_if = "Option::is_none")]
8654    pub comment: Option<String>,
8655    /// MySQL index VISIBLE/INVISIBLE
8656    #[serde(default, skip_serializing_if = "Option::is_none")]
8657    pub visible: Option<bool>,
8658    /// MySQL ENGINE_ATTRIBUTE = 'value'
8659    #[serde(default, skip_serializing_if = "Option::is_none")]
8660    pub engine_attribute: Option<String>,
8661    /// MySQL WITH PARSER name
8662    #[serde(default, skip_serializing_if = "Option::is_none")]
8663    pub with_parser: Option<String>,
8664    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
8665    #[serde(default)]
8666    pub not_valid: bool,
8667    /// TSQL CLUSTERED/NONCLUSTERED modifier
8668    #[serde(default, skip_serializing_if = "Option::is_none")]
8669    pub clustered: Option<String>,
8670    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
8671    #[serde(default, skip_serializing_if = "Option::is_none")]
8672    pub on_conflict: Option<String>,
8673    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
8674    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8675    pub with_options: Vec<(String, String)>,
8676    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
8677    #[serde(default, skip_serializing_if = "Option::is_none")]
8678    pub on_filegroup: Option<Identifier>,
8679}
8680
8681/// Table-level constraint
8682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8683#[cfg_attr(feature = "bindings", derive(TS))]
8684pub enum TableConstraint {
8685    PrimaryKey {
8686        name: Option<Identifier>,
8687        columns: Vec<Identifier>,
8688        /// Structured quoted, prefixed or ordered keys. When present these are
8689        /// authoritative for rendering; `columns` retains the column names.
8690        /// Older ASTs can encode prefix/order syntax directly in `columns`.
8691        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8692        key_parts: Vec<IndexKeyPart>,
8693        /// Databricks primary-key columns marked with the TIMESERIES attribute.
8694        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8695        timeseries_columns: Vec<Identifier>,
8696        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
8697        #[serde(default)]
8698        include_columns: Vec<Identifier>,
8699        #[serde(default)]
8700        modifiers: ConstraintModifiers,
8701        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
8702        #[serde(default)]
8703        has_constraint_keyword: bool,
8704    },
8705    Unique {
8706        name: Option<Identifier>,
8707        columns: Vec<Identifier>,
8708        /// Structured quoted, prefixed or ordered keys, as for `PrimaryKey`.
8709        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8710        key_parts: Vec<IndexKeyPart>,
8711        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
8712        #[serde(default)]
8713        columns_parenthesized: bool,
8714        #[serde(default)]
8715        modifiers: ConstraintModifiers,
8716        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
8717        #[serde(default)]
8718        has_constraint_keyword: bool,
8719        /// PostgreSQL 15+: NULLS NOT DISTINCT
8720        #[serde(default)]
8721        nulls_not_distinct: bool,
8722    },
8723    ForeignKey {
8724        name: Option<Identifier>,
8725        columns: Vec<Identifier>,
8726        #[serde(default)]
8727        references: Option<ForeignKeyRef>,
8728        /// ON DELETE action when REFERENCES is absent
8729        #[serde(default)]
8730        on_delete: Option<ReferentialAction>,
8731        /// ON UPDATE action when REFERENCES is absent
8732        #[serde(default)]
8733        on_update: Option<ReferentialAction>,
8734        #[serde(default)]
8735        modifiers: ConstraintModifiers,
8736    },
8737    Check {
8738        name: Option<Identifier>,
8739        expression: Expression,
8740        #[serde(default)]
8741        modifiers: ConstraintModifiers,
8742    },
8743    /// ClickHouse ASSUME constraint (query optimization assumption)
8744    Assume {
8745        name: Option<Identifier>,
8746        expression: Expression,
8747    },
8748    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
8749    Default {
8750        name: Option<Identifier>,
8751        expression: Expression,
8752        column: Identifier,
8753    },
8754    /// INDEX / KEY constraint (MySQL)
8755    Index {
8756        name: Option<Identifier>,
8757        columns: Vec<Identifier>,
8758        /// Expression-capable index key parts. This is used when an index contains
8759        /// functional key parts that cannot be represented by `columns`.
8760        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8761        key_parts: Vec<IndexKeyPart>,
8762        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8763        #[serde(default)]
8764        kind: Option<String>,
8765        #[serde(default)]
8766        modifiers: ConstraintModifiers,
8767        /// True if KEY keyword was used instead of INDEX
8768        #[serde(default)]
8769        use_key_keyword: bool,
8770        /// ClickHouse: indexed expression (instead of columns)
8771        #[serde(default, skip_serializing_if = "Option::is_none")]
8772        expression: Option<Box<Expression>>,
8773        /// ClickHouse: TYPE type_func(args)
8774        #[serde(default, skip_serializing_if = "Option::is_none")]
8775        index_type: Option<Box<Expression>>,
8776        /// ClickHouse: GRANULARITY n
8777        #[serde(default, skip_serializing_if = "Option::is_none")]
8778        granularity: Option<Box<Expression>>,
8779    },
8780    /// ClickHouse PROJECTION definition
8781    Projection {
8782        name: Identifier,
8783        expression: Expression,
8784    },
8785    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8786    Like {
8787        source: TableRef,
8788        /// Options as (INCLUDING|EXCLUDING, property) pairs
8789        options: Vec<(LikeOptionAction, String)>,
8790    },
8791    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8792    PeriodForSystemTime {
8793        start_col: Identifier,
8794        end_col: Identifier,
8795    },
8796    /// PostgreSQL EXCLUDE constraint
8797    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8798    Exclude {
8799        name: Option<Identifier>,
8800        /// Index access method (gist, btree, etc.)
8801        #[serde(default)]
8802        using: Option<String>,
8803        /// Elements: (expression, operator) pairs
8804        elements: Vec<ExcludeElement>,
8805        /// INCLUDE columns
8806        #[serde(default)]
8807        include_columns: Vec<Identifier>,
8808        /// WHERE predicate
8809        #[serde(default)]
8810        where_clause: Option<Box<Expression>>,
8811        /// WITH (storage_parameters)
8812        #[serde(default)]
8813        with_params: Vec<(String, String)>,
8814        /// USING INDEX TABLESPACE tablespace_name
8815        #[serde(default)]
8816        using_index_tablespace: Option<String>,
8817        #[serde(default)]
8818        modifiers: ConstraintModifiers,
8819    },
8820    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8821    Tags(Tags),
8822    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8823    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8824    /// for all deferrable constraints in the table
8825    InitiallyDeferred {
8826        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8827        deferred: bool,
8828    },
8829}
8830
8831/// Element in an EXCLUDE constraint: expression WITH operator
8832#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8833#[cfg_attr(feature = "bindings", derive(TS))]
8834pub struct ExcludeElement {
8835    /// The column expression (may include operator class, ordering, nulls)
8836    pub expression: String,
8837    /// The operator (e.g., &&, =)
8838    pub operator: String,
8839}
8840
8841/// Action for LIKE clause options
8842#[derive(
8843    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8844)]
8845#[cfg_attr(feature = "bindings", derive(TS))]
8846pub enum LikeOptionAction {
8847    Including,
8848    Excluding,
8849}
8850
8851/// MATCH type for foreign keys
8852#[derive(
8853    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8854)]
8855#[cfg_attr(feature = "bindings", derive(TS))]
8856pub enum MatchType {
8857    Full,
8858    Partial,
8859    Simple,
8860}
8861
8862/// Foreign key reference
8863#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8864#[cfg_attr(feature = "bindings", derive(TS))]
8865pub struct ForeignKeyRef {
8866    pub table: TableRef,
8867    pub columns: Vec<Identifier>,
8868    pub on_delete: Option<ReferentialAction>,
8869    pub on_update: Option<ReferentialAction>,
8870    /// True if ON UPDATE appears before ON DELETE in the original SQL
8871    #[serde(default)]
8872    pub on_update_first: bool,
8873    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8874    #[serde(default)]
8875    pub match_type: Option<MatchType>,
8876    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8877    #[serde(default)]
8878    pub match_after_actions: bool,
8879    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8880    #[serde(default)]
8881    pub constraint_name: Option<String>,
8882    /// DEFERRABLE / NOT DEFERRABLE
8883    #[serde(default)]
8884    pub deferrable: Option<bool>,
8885    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8886    #[serde(default)]
8887    pub has_foreign_key_keywords: bool,
8888}
8889
8890/// Referential action for foreign keys
8891#[derive(
8892    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8893)]
8894#[cfg_attr(feature = "bindings", derive(TS))]
8895pub enum ReferentialAction {
8896    Cascade,
8897    SetNull,
8898    SetDefault,
8899    Restrict,
8900    NoAction,
8901}
8902
8903/// DROP TABLE statement
8904#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8905#[cfg_attr(feature = "bindings", derive(TS))]
8906pub struct DropTable {
8907    pub names: Vec<TableRef>,
8908    pub if_exists: bool,
8909    pub cascade: bool,
8910    /// Oracle: CASCADE CONSTRAINTS
8911    #[serde(default)]
8912    pub cascade_constraints: bool,
8913    /// Oracle: PURGE
8914    #[serde(default)]
8915    pub purge: bool,
8916    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8917    #[serde(default)]
8918    pub leading_comments: Vec<String>,
8919    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8920    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8921    #[serde(default, skip_serializing_if = "Option::is_none")]
8922    pub object_id_args: Option<String>,
8923    /// ClickHouse: SYNC modifier
8924    #[serde(default)]
8925    pub sync: bool,
8926    /// Snowflake: DROP ICEBERG TABLE
8927    #[serde(default)]
8928    pub iceberg: bool,
8929    /// RESTRICT modifier (opposite of CASCADE)
8930    #[serde(default)]
8931    pub restrict: bool,
8932}
8933
8934impl DropTable {
8935    pub fn new(name: impl Into<String>) -> Self {
8936        Self {
8937            names: vec![TableRef::new(name)],
8938            if_exists: false,
8939            cascade: false,
8940            cascade_constraints: false,
8941            purge: false,
8942            leading_comments: Vec::new(),
8943            object_id_args: None,
8944            sync: false,
8945            iceberg: false,
8946            restrict: false,
8947        }
8948    }
8949}
8950
8951/// UNDROP object statement (Snowflake, ClickHouse)
8952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8953#[cfg_attr(feature = "bindings", derive(TS))]
8954pub struct Undrop {
8955    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8956    pub kind: String,
8957    /// The object name
8958    pub name: TableRef,
8959    /// IF EXISTS clause
8960    #[serde(default)]
8961    pub if_exists: bool,
8962    /// Snowflake: optional RENAME TO target
8963    #[serde(default, skip_serializing_if = "Option::is_none")]
8964    pub rename_to: Option<TableRef>,
8965}
8966
8967/// Partition scope for a TiDB `SPLIT TABLE` statement.
8968#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8969#[cfg_attr(feature = "bindings", derive(TS))]
8970#[serde(tag = "type", rename_all = "snake_case")]
8971pub enum SplitTablePartitionScope {
8972    Table,
8973    AllPartitions,
8974    Partitions { names: Vec<Identifier> },
8975}
8976
8977/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8978#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8979#[cfg_attr(feature = "bindings", derive(TS))]
8980#[serde(tag = "type", rename_all = "snake_case")]
8981pub enum SplitTableMode {
8982    Between {
8983        lower: Vec<Expression>,
8984        upper: Vec<Expression>,
8985        regions: u64,
8986    },
8987    By {
8988        points: Vec<Vec<Expression>>,
8989    },
8990}
8991
8992/// TiDB `SPLIT [PARTITION] TABLE` statement.
8993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8994#[cfg_attr(feature = "bindings", derive(TS))]
8995pub struct SplitTable {
8996    pub table: TableRef,
8997    pub partition_scope: SplitTablePartitionScope,
8998    #[serde(default, skip_serializing_if = "Option::is_none")]
8999    pub index: Option<Identifier>,
9000    pub mode: SplitTableMode,
9001}
9002
9003/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
9004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9005#[cfg_attr(feature = "bindings", derive(TS))]
9006pub struct FlashbackTable {
9007    pub table: TableRef,
9008    #[serde(default, skip_serializing_if = "Option::is_none")]
9009    pub rename_to: Option<Identifier>,
9010}
9011
9012/// ALTER TABLE statement
9013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9014#[cfg_attr(feature = "bindings", derive(TS))]
9015pub struct AlterTable {
9016    pub name: TableRef,
9017    pub actions: Vec<AlterTableAction>,
9018    /// IF EXISTS clause
9019    #[serde(default)]
9020    pub if_exists: bool,
9021    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
9022    #[serde(default, skip_serializing_if = "Option::is_none")]
9023    pub algorithm: Option<String>,
9024    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
9025    #[serde(default, skip_serializing_if = "Option::is_none")]
9026    pub lock: Option<String>,
9027    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
9028    #[serde(default, skip_serializing_if = "Option::is_none")]
9029    pub with_check: Option<String>,
9030    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
9031    #[serde(default, skip_serializing_if = "Option::is_none")]
9032    pub partition: Option<Vec<(Identifier, Expression)>>,
9033    /// ClickHouse: ON CLUSTER clause for distributed DDL
9034    #[serde(default, skip_serializing_if = "Option::is_none")]
9035    pub on_cluster: Option<OnCluster>,
9036    /// Snowflake: ALTER ICEBERG TABLE
9037    #[serde(default, skip_serializing_if = "Option::is_none")]
9038    pub table_modifier: Option<String>,
9039}
9040
9041impl AlterTable {
9042    pub fn new(name: impl Into<String>) -> Self {
9043        Self {
9044            name: TableRef::new(name),
9045            actions: Vec::new(),
9046            if_exists: false,
9047            algorithm: None,
9048            lock: None,
9049            with_check: None,
9050            partition: None,
9051            on_cluster: None,
9052            table_modifier: None,
9053        }
9054    }
9055}
9056
9057/// Column position for ADD COLUMN (MySQL/MariaDB)
9058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9059#[cfg_attr(feature = "bindings", derive(TS))]
9060pub enum ColumnPosition {
9061    First,
9062    After(Identifier),
9063}
9064
9065/// Actions for ALTER TABLE
9066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9067#[cfg_attr(feature = "bindings", derive(TS))]
9068pub enum AlterTableAction {
9069    AddColumn {
9070        column: ColumnDef,
9071        if_not_exists: bool,
9072        position: Option<ColumnPosition>,
9073    },
9074    DropColumn {
9075        name: Identifier,
9076        if_exists: bool,
9077        cascade: bool,
9078    },
9079    RenameColumn {
9080        old_name: Identifier,
9081        new_name: Identifier,
9082        if_exists: bool,
9083    },
9084    AlterColumn {
9085        name: Identifier,
9086        action: AlterColumnAction,
9087        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
9088        #[serde(default)]
9089        use_modify_keyword: bool,
9090    },
9091    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
9092    ModifyColumn {
9093        column: ColumnDef,
9094        if_exists: bool,
9095        position: Option<ColumnPosition>,
9096    },
9097    RenameTable(TableRef),
9098    AddConstraint(TableConstraint),
9099    DropConstraint {
9100        name: Identifier,
9101        if_exists: bool,
9102    },
9103    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
9104    DropForeignKey {
9105        name: Identifier,
9106    },
9107    /// DROP PARTITION action (Hive/BigQuery)
9108    DropPartition {
9109        /// List of partitions to drop (each partition is a list of key=value pairs)
9110        partitions: Vec<Vec<(Identifier, Expression)>>,
9111        if_exists: bool,
9112    },
9113    /// ADD PARTITION action (Hive/Spark)
9114    AddPartition {
9115        /// The partition expression
9116        partition: Expression,
9117        if_not_exists: bool,
9118        location: Option<Expression>,
9119    },
9120    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
9121    Delete {
9122        where_clause: Expression,
9123    },
9124    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
9125    SwapWith(TableRef),
9126    /// SET property action (Snowflake): ALTER TABLE t SET property=value
9127    SetProperty {
9128        properties: Vec<(String, Expression)>,
9129    },
9130    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
9131    UnsetProperty {
9132        properties: Vec<String>,
9133    },
9134    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
9135    ClusterBy {
9136        expressions: Vec<Expression>,
9137    },
9138    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
9139    SetTag {
9140        expressions: Vec<(String, Expression)>,
9141    },
9142    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
9143    UnsetTag {
9144        names: Vec<String>,
9145    },
9146    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
9147    SetOptions {
9148        expressions: Vec<Expression>,
9149    },
9150    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
9151    AlterIndex {
9152        name: Identifier,
9153        visible: bool,
9154    },
9155    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
9156    SetAttribute {
9157        attribute: String,
9158    },
9159    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
9160    SetStageFileFormat {
9161        options: Option<Expression>,
9162    },
9163    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
9164    SetStageCopyOptions {
9165        options: Option<Expression>,
9166    },
9167    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
9168    AddColumns {
9169        columns: Vec<ColumnDef>,
9170        cascade: bool,
9171    },
9172    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
9173    DropColumns {
9174        names: Vec<Identifier>,
9175    },
9176    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
9177    /// In SingleStore, data_type can be omitted for simple column renames
9178    ChangeColumn {
9179        old_name: Identifier,
9180        new_name: Identifier,
9181        #[serde(default, skip_serializing_if = "Option::is_none")]
9182        data_type: Option<DataType>,
9183        comment: Option<String>,
9184        #[serde(default)]
9185        cascade: bool,
9186    },
9187    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
9188    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
9189    AlterSortKey {
9190        /// AUTO or NONE keyword
9191        this: Option<String>,
9192        /// Column list for (col1, col2) syntax
9193        expressions: Vec<Expression>,
9194        /// Whether COMPOUND keyword was present
9195        compound: bool,
9196    },
9197    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
9198    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
9199    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
9200    AlterDistStyle {
9201        /// Distribution style: ALL, EVEN, AUTO, or KEY
9202        style: String,
9203        /// DISTKEY column (only when style is KEY)
9204        distkey: Option<Identifier>,
9205    },
9206    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
9207    SetTableProperties {
9208        properties: Vec<(Expression, Expression)>,
9209    },
9210    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
9211    SetLocation {
9212        location: String,
9213    },
9214    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
9215    SetFileFormat {
9216        format: String,
9217    },
9218    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
9219    ReplacePartition {
9220        partition: Expression,
9221        source: Option<Box<Expression>>,
9222    },
9223    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
9224    SetTiDBTableOption {
9225        option: TiDBTableOption,
9226        #[serde(default)]
9227        force: bool,
9228    },
9229    /// TiDB `REMOVE TTL`.
9230    RemoveTiDBTtl {
9231        #[serde(default)]
9232        executable_comment: bool,
9233    },
9234    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
9235    Raw {
9236        sql: String,
9237    },
9238}
9239
9240/// Actions for ALTER COLUMN
9241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9242#[cfg_attr(feature = "bindings", derive(TS))]
9243pub enum AlterColumnAction {
9244    SetDataType {
9245        data_type: DataType,
9246        /// USING expression for type conversion (PostgreSQL)
9247        using: Option<Expression>,
9248        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
9249        #[serde(default, skip_serializing_if = "Option::is_none")]
9250        collate: Option<String>,
9251    },
9252    SetDefault(Expression),
9253    DropDefault,
9254    SetNotNull,
9255    DropNotNull,
9256    /// Set column comment
9257    Comment(String),
9258    /// MySQL: SET VISIBLE
9259    SetVisible,
9260    /// MySQL: SET INVISIBLE
9261    SetInvisible,
9262}
9263
9264/// CREATE INDEX statement
9265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9266#[cfg_attr(feature = "bindings", derive(TS))]
9267pub struct CreateIndex {
9268    pub name: Identifier,
9269    pub table: TableRef,
9270    pub columns: Vec<IndexColumn>,
9271    /// Expression-capable index key parts. This is used when an index contains
9272    /// functional key parts that cannot be represented by `columns`.
9273    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9274    pub key_parts: Vec<IndexKeyPart>,
9275    pub unique: bool,
9276    pub if_not_exists: bool,
9277    pub using: Option<String>,
9278    /// TSQL CLUSTERED/NONCLUSTERED modifier
9279    #[serde(default)]
9280    pub clustered: Option<String>,
9281    /// PostgreSQL CONCURRENTLY modifier
9282    #[serde(default)]
9283    pub concurrently: bool,
9284    /// PostgreSQL WHERE clause for partial indexes
9285    #[serde(default)]
9286    pub where_clause: Option<Box<Expression>>,
9287    /// PostgreSQL INCLUDE columns
9288    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9289    pub include_columns: Vec<Identifier>,
9290    /// TSQL WITH options (e.g., allow_page_locks=on)
9291    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9292    pub with_options: Vec<(String, String)>,
9293    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
9294    #[serde(default)]
9295    pub on_filegroup: Option<String>,
9296}
9297
9298impl CreateIndex {
9299    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
9300        Self {
9301            name: Identifier::new(name),
9302            table: TableRef::new(table),
9303            columns: Vec::new(),
9304            key_parts: Vec::new(),
9305            unique: false,
9306            if_not_exists: false,
9307            using: None,
9308            clustered: None,
9309            concurrently: false,
9310            where_clause: None,
9311            include_columns: Vec::new(),
9312            with_options: Vec::new(),
9313            on_filegroup: None,
9314        }
9315    }
9316}
9317
9318/// Index column specification
9319#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9320#[cfg_attr(feature = "bindings", derive(TS))]
9321pub struct IndexColumn {
9322    pub column: Identifier,
9323    pub desc: bool,
9324    /// Explicit ASC keyword was present
9325    #[serde(default)]
9326    pub asc: bool,
9327    pub nulls_first: Option<bool>,
9328    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
9329    #[serde(default, skip_serializing_if = "Option::is_none")]
9330    pub opclass: Option<String>,
9331}
9332
9333/// An expression-capable index key part.
9334#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9335#[cfg_attr(feature = "bindings", derive(TS))]
9336pub struct IndexKeyPart {
9337    pub expression: Box<Expression>,
9338    /// MySQL column prefix length, for example the `16` in `name(16)`.
9339    #[serde(default, skip_serializing_if = "Option::is_none")]
9340    pub prefix_length: Option<String>,
9341    pub desc: bool,
9342    /// Explicit ASC keyword was present.
9343    #[serde(default)]
9344    pub asc: bool,
9345    pub nulls_first: Option<bool>,
9346    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops).
9347    #[serde(default, skip_serializing_if = "Option::is_none")]
9348    pub opclass: Option<String>,
9349}
9350
9351/// DROP INDEX statement
9352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9353#[cfg_attr(feature = "bindings", derive(TS))]
9354pub struct DropIndex {
9355    pub name: TableRef,
9356    pub table: Option<TableRef>,
9357    pub if_exists: bool,
9358    /// PostgreSQL CONCURRENTLY modifier
9359    #[serde(default)]
9360    pub concurrently: bool,
9361}
9362
9363impl DropIndex {
9364    pub fn new(name: impl Into<String>) -> Self {
9365        Self {
9366            name: TableRef::new(name),
9367            table: None,
9368            if_exists: false,
9369            concurrently: false,
9370        }
9371    }
9372}
9373
9374/// View column definition with optional COMMENT and OPTIONS (BigQuery)
9375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9376#[cfg_attr(feature = "bindings", derive(TS))]
9377pub struct ViewColumn {
9378    pub name: Identifier,
9379    pub comment: Option<String>,
9380    /// BigQuery: OPTIONS (key=value, ...) on column
9381    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9382    pub options: Vec<Expression>,
9383}
9384
9385impl ViewColumn {
9386    pub fn new(name: impl Into<String>) -> Self {
9387        Self {
9388            name: Identifier::new(name),
9389            comment: None,
9390            options: Vec::new(),
9391        }
9392    }
9393
9394    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
9395        Self {
9396            name: Identifier::new(name),
9397            comment: Some(comment.into()),
9398            options: Vec::new(),
9399        }
9400    }
9401}
9402
9403/// CREATE VIEW statement
9404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9405#[cfg_attr(feature = "bindings", derive(TS))]
9406pub struct CreateView {
9407    pub name: TableRef,
9408    pub columns: Vec<ViewColumn>,
9409    pub query: Expression,
9410    pub or_replace: bool,
9411    /// TSQL: CREATE OR ALTER
9412    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9413    pub or_alter: bool,
9414    pub if_not_exists: bool,
9415    pub materialized: bool,
9416    pub temporary: bool,
9417    /// Snowflake: SECURE VIEW
9418    #[serde(default)]
9419    pub secure: bool,
9420    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
9421    #[serde(skip_serializing_if = "Option::is_none")]
9422    pub algorithm: Option<String>,
9423    /// MySQL: DEFINER=user@host
9424    #[serde(skip_serializing_if = "Option::is_none")]
9425    pub definer: Option<String>,
9426    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
9427    #[serde(skip_serializing_if = "Option::is_none")]
9428    pub security: Option<FunctionSecurity>,
9429    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
9430    #[serde(default = "default_true")]
9431    pub security_sql_style: bool,
9432    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
9433    #[serde(default)]
9434    pub security_after_name: bool,
9435    /// Whether the query was parenthesized: AS (SELECT ...)
9436    #[serde(default)]
9437    pub query_parenthesized: bool,
9438    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
9439    #[serde(skip_serializing_if = "Option::is_none")]
9440    pub locking_mode: Option<String>,
9441    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
9442    #[serde(skip_serializing_if = "Option::is_none")]
9443    pub locking_access: Option<String>,
9444    /// Snowflake: COPY GRANTS
9445    #[serde(default)]
9446    pub copy_grants: bool,
9447    /// Snowflake: COMMENT = 'text'
9448    #[serde(skip_serializing_if = "Option::is_none", default)]
9449    pub comment: Option<String>,
9450    /// Snowflake: WITH ROW ACCESS POLICY ... clause
9451    #[serde(skip_serializing_if = "Option::is_none", default)]
9452    pub row_access_policy: Option<String>,
9453    /// Snowflake: TAG (name='value', ...)
9454    #[serde(default)]
9455    pub tags: Vec<(String, String)>,
9456    /// BigQuery: OPTIONS (key=value, ...)
9457    #[serde(default)]
9458    pub options: Vec<Expression>,
9459    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
9460    #[serde(skip_serializing_if = "Option::is_none", default)]
9461    pub build: Option<String>,
9462    /// Doris: REFRESH property for materialized views
9463    #[serde(skip_serializing_if = "Option::is_none", default)]
9464    pub refresh: Option<Box<RefreshTriggerProperty>>,
9465    /// Doris: Schema with typed column definitions for materialized views
9466    /// This is used instead of `columns` when the view has typed column definitions
9467    #[serde(skip_serializing_if = "Option::is_none", default)]
9468    pub schema: Option<Box<Schema>>,
9469    /// Doris: KEY (columns) for materialized views
9470    #[serde(skip_serializing_if = "Option::is_none", default)]
9471    pub unique_key: Option<Box<UniqueKeyProperty>>,
9472    /// Redshift: WITH NO SCHEMA BINDING
9473    #[serde(default)]
9474    pub no_schema_binding: bool,
9475    /// Redshift: AUTO REFRESH YES|NO for materialized views
9476    #[serde(skip_serializing_if = "Option::is_none", default)]
9477    pub auto_refresh: Option<bool>,
9478    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
9479    #[serde(skip_serializing_if = "Option::is_none", default)]
9480    pub clickhouse_population: Option<String>,
9481    /// ClickHouse: ON CLUSTER clause
9482    #[serde(default, skip_serializing_if = "Option::is_none")]
9483    pub on_cluster: Option<OnCluster>,
9484    /// ClickHouse: TO destination_table
9485    #[serde(default, skip_serializing_if = "Option::is_none")]
9486    pub to_table: Option<TableRef>,
9487    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
9488    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9489    pub table_properties: Vec<Expression>,
9490}
9491
9492impl CreateView {
9493    pub fn new(name: impl Into<String>, query: Expression) -> Self {
9494        Self {
9495            name: TableRef::new(name),
9496            columns: Vec::new(),
9497            query,
9498            or_replace: false,
9499            or_alter: false,
9500            if_not_exists: false,
9501            materialized: false,
9502            temporary: false,
9503            secure: false,
9504            algorithm: None,
9505            definer: None,
9506            security: None,
9507            security_sql_style: true,
9508            security_after_name: false,
9509            query_parenthesized: false,
9510            locking_mode: None,
9511            locking_access: None,
9512            copy_grants: false,
9513            comment: None,
9514            row_access_policy: None,
9515            tags: Vec::new(),
9516            options: Vec::new(),
9517            build: None,
9518            refresh: None,
9519            schema: None,
9520            unique_key: None,
9521            no_schema_binding: false,
9522            auto_refresh: None,
9523            clickhouse_population: None,
9524            on_cluster: None,
9525            to_table: None,
9526            table_properties: Vec::new(),
9527        }
9528    }
9529}
9530
9531/// DROP VIEW statement
9532#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9533#[cfg_attr(feature = "bindings", derive(TS))]
9534pub struct DropView {
9535    pub name: TableRef,
9536    pub if_exists: bool,
9537    pub materialized: bool,
9538}
9539
9540impl DropView {
9541    pub fn new(name: impl Into<String>) -> Self {
9542        Self {
9543            name: TableRef::new(name),
9544            if_exists: false,
9545            materialized: false,
9546        }
9547    }
9548}
9549
9550/// TRUNCATE TABLE statement
9551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9552#[cfg_attr(feature = "bindings", derive(TS))]
9553pub struct Truncate {
9554    /// Target of TRUNCATE (TABLE vs DATABASE)
9555    #[serde(default)]
9556    pub target: TruncateTarget,
9557    /// IF EXISTS clause
9558    #[serde(default)]
9559    pub if_exists: bool,
9560    pub table: TableRef,
9561    /// ClickHouse: ON CLUSTER clause for distributed DDL
9562    #[serde(default, skip_serializing_if = "Option::is_none")]
9563    pub on_cluster: Option<OnCluster>,
9564    pub cascade: bool,
9565    /// Additional tables for multi-table TRUNCATE
9566    #[serde(default)]
9567    pub extra_tables: Vec<TruncateTableEntry>,
9568    /// RESTART IDENTITY or CONTINUE IDENTITY
9569    #[serde(default)]
9570    pub identity: Option<TruncateIdentity>,
9571    /// RESTRICT option (alternative to CASCADE)
9572    #[serde(default)]
9573    pub restrict: bool,
9574    /// Hive PARTITION clause: PARTITION(key=value, ...)
9575    #[serde(default, skip_serializing_if = "Option::is_none")]
9576    pub partition: Option<Box<Expression>>,
9577}
9578
9579/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
9580#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9581#[cfg_attr(feature = "bindings", derive(TS))]
9582pub struct TruncateTableEntry {
9583    pub table: TableRef,
9584    /// Whether the table has a * suffix (inherit children)
9585    #[serde(default)]
9586    pub star: bool,
9587}
9588
9589/// TRUNCATE target type
9590#[derive(
9591    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9592)]
9593#[cfg_attr(feature = "bindings", derive(TS))]
9594pub enum TruncateTarget {
9595    Table,
9596    Database,
9597}
9598
9599impl Default for TruncateTarget {
9600    fn default() -> Self {
9601        TruncateTarget::Table
9602    }
9603}
9604
9605/// TRUNCATE identity option
9606#[derive(
9607    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9608)]
9609#[cfg_attr(feature = "bindings", derive(TS))]
9610pub enum TruncateIdentity {
9611    Restart,
9612    Continue,
9613}
9614
9615impl Truncate {
9616    pub fn new(table: impl Into<String>) -> Self {
9617        Self {
9618            target: TruncateTarget::Table,
9619            if_exists: false,
9620            table: TableRef::new(table),
9621            on_cluster: None,
9622            cascade: false,
9623            extra_tables: Vec::new(),
9624            identity: None,
9625            restrict: false,
9626            partition: None,
9627        }
9628    }
9629}
9630
9631/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
9632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9633#[cfg_attr(feature = "bindings", derive(TS))]
9634pub struct Use {
9635    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
9636    pub kind: Option<UseKind>,
9637    /// The name of the object
9638    pub this: Identifier,
9639}
9640
9641/// Kind of USE statement
9642#[derive(
9643    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9644)]
9645#[cfg_attr(feature = "bindings", derive(TS))]
9646pub enum UseKind {
9647    Database,
9648    Schema,
9649    Role,
9650    Warehouse,
9651    Catalog,
9652    /// Snowflake: USE SECONDARY ROLES ALL|NONE
9653    SecondaryRoles,
9654}
9655
9656/// SET variable statement
9657#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9658#[cfg_attr(feature = "bindings", derive(TS))]
9659pub struct SetStatement {
9660    /// The items being set
9661    pub items: Vec<SetItem>,
9662}
9663
9664/// A single SET item (variable assignment)
9665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9666#[cfg_attr(feature = "bindings", derive(TS))]
9667pub struct SetItem {
9668    /// The variable name
9669    pub name: Expression,
9670    /// The value to set
9671    pub value: Expression,
9672    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
9673    pub kind: Option<String>,
9674    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
9675    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9676    pub no_equals: bool,
9677}
9678
9679/// CACHE TABLE statement (Spark)
9680#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9681#[cfg_attr(feature = "bindings", derive(TS))]
9682pub struct Cache {
9683    /// The table to cache
9684    pub table: Identifier,
9685    /// LAZY keyword - defer caching until first use
9686    pub lazy: bool,
9687    /// Optional OPTIONS clause (key-value pairs)
9688    pub options: Vec<(Expression, Expression)>,
9689    /// Optional AS clause with query
9690    pub query: Option<Expression>,
9691}
9692
9693/// UNCACHE TABLE statement (Spark)
9694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9695#[cfg_attr(feature = "bindings", derive(TS))]
9696pub struct Uncache {
9697    /// The table to uncache
9698    pub table: Identifier,
9699    /// IF EXISTS clause
9700    pub if_exists: bool,
9701}
9702
9703/// LOAD DATA statement (Hive)
9704#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9705#[cfg_attr(feature = "bindings", derive(TS))]
9706pub struct LoadData {
9707    /// LOCAL keyword - load from local filesystem
9708    pub local: bool,
9709    /// The path to load data from (INPATH value)
9710    pub inpath: String,
9711    /// Whether to overwrite existing data
9712    pub overwrite: bool,
9713    /// The target table
9714    pub table: Expression,
9715    /// Optional PARTITION clause with key-value pairs
9716    pub partition: Vec<(Identifier, Expression)>,
9717    /// Optional INPUTFORMAT clause
9718    pub input_format: Option<String>,
9719    /// Optional SERDE clause
9720    pub serde: Option<String>,
9721}
9722
9723/// PRAGMA statement (SQLite)
9724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9725#[cfg_attr(feature = "bindings", derive(TS))]
9726pub struct Pragma {
9727    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
9728    pub schema: Option<Identifier>,
9729    /// The pragma name
9730    pub name: Identifier,
9731    /// Optional value for assignment (PRAGMA name = value)
9732    pub value: Option<Expression>,
9733    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
9734    pub args: Vec<Expression>,
9735    /// Whether this pragma should be generated using assignment syntax.
9736    #[serde(default)]
9737    pub use_assignment_syntax: bool,
9738}
9739
9740/// A privilege with optional column list for GRANT/REVOKE
9741/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
9742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9743#[cfg_attr(feature = "bindings", derive(TS))]
9744pub struct Privilege {
9745    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
9746    pub name: String,
9747    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
9748    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9749    pub columns: Vec<String>,
9750}
9751
9752/// Principal in GRANT/REVOKE (user, role, etc.)
9753#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9754#[cfg_attr(feature = "bindings", derive(TS))]
9755pub struct GrantPrincipal {
9756    /// The name of the principal
9757    pub name: Identifier,
9758    /// Whether prefixed with ROLE keyword
9759    pub is_role: bool,
9760    /// Whether prefixed with GROUP keyword (Redshift)
9761    #[serde(default)]
9762    pub is_group: bool,
9763    /// Whether prefixed with SHARE keyword (Snowflake)
9764    #[serde(default)]
9765    pub is_share: bool,
9766}
9767
9768/// GRANT statement
9769#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9770#[cfg_attr(feature = "bindings", derive(TS))]
9771pub struct Grant {
9772    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
9773    pub privileges: Vec<Privilege>,
9774    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9775    pub kind: Option<String>,
9776    /// The object to grant on
9777    pub securable: Identifier,
9778    /// Function parameter types (for FUNCTION kind)
9779    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9780    pub function_params: Vec<String>,
9781    /// The grantees
9782    pub principals: Vec<GrantPrincipal>,
9783    /// WITH GRANT OPTION
9784    pub grant_option: bool,
9785    /// TSQL: AS principal (the grantor role)
9786    #[serde(default, skip_serializing_if = "Option::is_none")]
9787    pub as_principal: Option<Identifier>,
9788}
9789
9790/// REVOKE statement
9791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9792#[cfg_attr(feature = "bindings", derive(TS))]
9793pub struct Revoke {
9794    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9795    pub privileges: Vec<Privilege>,
9796    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9797    pub kind: Option<String>,
9798    /// The object to revoke from
9799    pub securable: Identifier,
9800    /// Function parameter types (for FUNCTION kind)
9801    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9802    pub function_params: Vec<String>,
9803    /// The grantees
9804    pub principals: Vec<GrantPrincipal>,
9805    /// GRANT OPTION FOR
9806    pub grant_option: bool,
9807    /// CASCADE
9808    pub cascade: bool,
9809    /// RESTRICT
9810    #[serde(default)]
9811    pub restrict: bool,
9812}
9813
9814/// COMMENT ON statement
9815#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9816#[cfg_attr(feature = "bindings", derive(TS))]
9817pub struct Comment {
9818    /// The object being commented on
9819    pub this: Expression,
9820    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9821    pub kind: String,
9822    /// The comment text expression
9823    pub expression: Expression,
9824    /// IF EXISTS clause
9825    pub exists: bool,
9826    /// MATERIALIZED keyword
9827    pub materialized: bool,
9828}
9829
9830// ============================================================================
9831// Phase 4: Additional DDL Statements
9832// ============================================================================
9833
9834/// ALTER VIEW statement
9835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9836#[cfg_attr(feature = "bindings", derive(TS))]
9837pub struct AlterView {
9838    pub name: TableRef,
9839    pub actions: Vec<AlterViewAction>,
9840    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9841    #[serde(default, skip_serializing_if = "Option::is_none")]
9842    pub algorithm: Option<String>,
9843    /// MySQL: DEFINER = 'user'@'host'
9844    #[serde(default, skip_serializing_if = "Option::is_none")]
9845    pub definer: Option<String>,
9846    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9847    #[serde(default, skip_serializing_if = "Option::is_none")]
9848    pub sql_security: Option<String>,
9849    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9850    #[serde(default, skip_serializing_if = "Option::is_none")]
9851    pub with_option: Option<String>,
9852    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9853    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9854    pub columns: Vec<ViewColumn>,
9855}
9856
9857/// Actions for ALTER VIEW
9858#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9859#[cfg_attr(feature = "bindings", derive(TS))]
9860pub enum AlterViewAction {
9861    /// Rename the view
9862    Rename(TableRef),
9863    /// Change owner
9864    OwnerTo(Identifier),
9865    /// Set schema
9866    SetSchema(Identifier),
9867    /// Set authorization (Trino/Presto)
9868    SetAuthorization(String),
9869    /// Alter column
9870    AlterColumn {
9871        name: Identifier,
9872        action: AlterColumnAction,
9873    },
9874    /// Redefine view as query (SELECT, UNION, etc.)
9875    AsSelect(Box<Expression>),
9876    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9877    SetTblproperties(Vec<(String, String)>),
9878    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9879    UnsetTblproperties(Vec<String>),
9880}
9881
9882impl AlterView {
9883    pub fn new(name: impl Into<String>) -> Self {
9884        Self {
9885            name: TableRef::new(name),
9886            actions: Vec::new(),
9887            algorithm: None,
9888            definer: None,
9889            sql_security: None,
9890            with_option: None,
9891            columns: Vec::new(),
9892        }
9893    }
9894}
9895
9896/// ALTER INDEX statement
9897#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9898#[cfg_attr(feature = "bindings", derive(TS))]
9899pub struct AlterIndex {
9900    pub name: Identifier,
9901    pub table: Option<TableRef>,
9902    pub actions: Vec<AlterIndexAction>,
9903}
9904
9905/// Actions for ALTER INDEX
9906#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9907#[cfg_attr(feature = "bindings", derive(TS))]
9908pub enum AlterIndexAction {
9909    /// Rename the index
9910    Rename(Identifier),
9911    /// Set tablespace
9912    SetTablespace(Identifier),
9913    /// Set visibility (MySQL)
9914    Visible(bool),
9915}
9916
9917impl AlterIndex {
9918    pub fn new(name: impl Into<String>) -> Self {
9919        Self {
9920            name: Identifier::new(name),
9921            table: None,
9922            actions: Vec::new(),
9923        }
9924    }
9925}
9926
9927/// CREATE SCHEMA statement
9928#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9929#[cfg_attr(feature = "bindings", derive(TS))]
9930pub struct CreateSchema {
9931    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9932    pub name: Vec<Identifier>,
9933    pub if_not_exists: bool,
9934    pub authorization: Option<Identifier>,
9935    /// CLONE source parts, possibly dot-qualified
9936    #[serde(default)]
9937    pub clone_from: Option<Vec<Identifier>>,
9938    /// AT/BEFORE clause for time travel (Snowflake)
9939    #[serde(default)]
9940    pub at_clause: Option<Expression>,
9941    /// Schema properties like DEFAULT COLLATE
9942    #[serde(default)]
9943    pub properties: Vec<Expression>,
9944    /// Leading comments before the statement
9945    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9946    pub leading_comments: Vec<String>,
9947}
9948
9949impl CreateSchema {
9950    pub fn new(name: impl Into<String>) -> Self {
9951        Self {
9952            name: vec![Identifier::new(name)],
9953            if_not_exists: false,
9954            authorization: None,
9955            clone_from: None,
9956            at_clause: None,
9957            properties: Vec::new(),
9958            leading_comments: Vec::new(),
9959        }
9960    }
9961}
9962
9963/// DROP SCHEMA statement
9964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9965#[cfg_attr(feature = "bindings", derive(TS))]
9966pub struct DropSchema {
9967    pub name: Identifier,
9968    pub if_exists: bool,
9969    pub cascade: bool,
9970}
9971
9972impl DropSchema {
9973    pub fn new(name: impl Into<String>) -> Self {
9974        Self {
9975            name: Identifier::new(name),
9976            if_exists: false,
9977            cascade: false,
9978        }
9979    }
9980}
9981
9982/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9984#[cfg_attr(feature = "bindings", derive(TS))]
9985pub struct DropNamespace {
9986    pub name: Identifier,
9987    pub if_exists: bool,
9988    pub cascade: bool,
9989}
9990
9991impl DropNamespace {
9992    pub fn new(name: impl Into<String>) -> Self {
9993        Self {
9994            name: Identifier::new(name),
9995            if_exists: false,
9996            cascade: false,
9997        }
9998    }
9999}
10000
10001/// CREATE DATABASE statement
10002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10003#[cfg_attr(feature = "bindings", derive(TS))]
10004pub struct CreateDatabase {
10005    pub name: Identifier,
10006    pub if_not_exists: bool,
10007    pub options: Vec<DatabaseOption>,
10008    /// Snowflake CLONE source
10009    #[serde(default)]
10010    pub clone_from: Option<Identifier>,
10011    /// AT/BEFORE clause for time travel (Snowflake)
10012    #[serde(default)]
10013    pub at_clause: Option<Expression>,
10014}
10015
10016/// Database option
10017#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10018#[cfg_attr(feature = "bindings", derive(TS))]
10019pub enum DatabaseOption {
10020    CharacterSet(String),
10021    Collate(String),
10022    Owner(Identifier),
10023    Template(Identifier),
10024    Encoding(String),
10025    Location(String),
10026}
10027
10028impl CreateDatabase {
10029    pub fn new(name: impl Into<String>) -> Self {
10030        Self {
10031            name: Identifier::new(name),
10032            if_not_exists: false,
10033            options: Vec::new(),
10034            clone_from: None,
10035            at_clause: None,
10036        }
10037    }
10038}
10039
10040/// DROP DATABASE statement
10041#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10042#[cfg_attr(feature = "bindings", derive(TS))]
10043pub struct DropDatabase {
10044    pub name: Identifier,
10045    pub if_exists: bool,
10046    /// ClickHouse: SYNC modifier
10047    #[serde(default)]
10048    pub sync: bool,
10049}
10050
10051impl DropDatabase {
10052    pub fn new(name: impl Into<String>) -> Self {
10053        Self {
10054            name: Identifier::new(name),
10055            if_exists: false,
10056            sync: false,
10057        }
10058    }
10059}
10060
10061/// CREATE FUNCTION statement
10062#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10063#[cfg_attr(feature = "bindings", derive(TS))]
10064pub struct CreateFunction {
10065    pub name: TableRef,
10066    pub parameters: Vec<FunctionParameter>,
10067    pub return_type: Option<DataType>,
10068    pub body: Option<FunctionBody>,
10069    pub or_replace: bool,
10070    /// TSQL: CREATE OR ALTER
10071    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10072    pub or_alter: bool,
10073    pub if_not_exists: bool,
10074    pub temporary: bool,
10075    pub language: Option<String>,
10076    pub deterministic: Option<bool>,
10077    pub returns_null_on_null_input: Option<bool>,
10078    pub security: Option<FunctionSecurity>,
10079    /// Whether parentheses were present in the original syntax
10080    #[serde(default = "default_true")]
10081    pub has_parens: bool,
10082    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
10083    #[serde(default)]
10084    pub sql_data_access: Option<SqlDataAccess>,
10085    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
10086    #[serde(default, skip_serializing_if = "Option::is_none")]
10087    pub returns_table_body: Option<String>,
10088    /// True if LANGUAGE clause appears before RETURNS clause
10089    #[serde(default)]
10090    pub language_first: bool,
10091    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
10092    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10093    pub set_options: Vec<FunctionSetOption>,
10094    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
10095    #[serde(default)]
10096    pub strict: bool,
10097    /// BigQuery: OPTIONS (key=value, ...)
10098    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10099    pub options: Vec<Expression>,
10100    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
10101    #[serde(default)]
10102    pub is_table_function: bool,
10103    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
10104    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10105    pub property_order: Vec<FunctionPropertyKind>,
10106    /// Hive: USING JAR|FILE|ARCHIVE '...'
10107    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10108    pub using_resources: Vec<FunctionUsingResource>,
10109    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
10110    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10111    pub environment: Vec<Expression>,
10112    /// HANDLER 'handler_function' clause (Databricks)
10113    #[serde(default, skip_serializing_if = "Option::is_none")]
10114    pub handler: Option<String>,
10115    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
10116    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10117    pub handler_uses_eq: bool,
10118    /// Snowflake: RUNTIME_VERSION='3.11'
10119    #[serde(default, skip_serializing_if = "Option::is_none")]
10120    pub runtime_version: Option<String>,
10121    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
10122    #[serde(default, skip_serializing_if = "Option::is_none")]
10123    pub packages: Option<Vec<String>>,
10124    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
10125    #[serde(default, skip_serializing_if = "Option::is_none")]
10126    pub parameter_style: Option<String>,
10127}
10128
10129/// A SET option in CREATE FUNCTION (PostgreSQL)
10130#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10131#[cfg_attr(feature = "bindings", derive(TS))]
10132pub struct FunctionSetOption {
10133    pub name: String,
10134    pub value: FunctionSetValue,
10135}
10136
10137/// The value of a SET option
10138#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10139#[cfg_attr(feature = "bindings", derive(TS))]
10140pub enum FunctionSetValue {
10141    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
10142    Value { value: String, use_to: bool },
10143    /// SET key FROM CURRENT
10144    FromCurrent,
10145}
10146
10147/// SQL data access characteristics for functions
10148#[derive(
10149    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10150)]
10151#[cfg_attr(feature = "bindings", derive(TS))]
10152pub enum SqlDataAccess {
10153    /// NO SQL
10154    NoSql,
10155    /// CONTAINS SQL
10156    ContainsSql,
10157    /// READS SQL DATA
10158    ReadsSqlData,
10159    /// MODIFIES SQL DATA
10160    ModifiesSqlData,
10161}
10162
10163/// Types of properties in CREATE FUNCTION for tracking their original order
10164#[derive(
10165    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10166)]
10167#[cfg_attr(feature = "bindings", derive(TS))]
10168pub enum FunctionPropertyKind {
10169    /// SET option
10170    Set,
10171    /// AS body
10172    As,
10173    /// Hive: USING JAR|FILE|ARCHIVE ...
10174    Using,
10175    /// LANGUAGE clause
10176    Language,
10177    /// IMMUTABLE/VOLATILE/STABLE (determinism)
10178    Determinism,
10179    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
10180    NullInput,
10181    /// SECURITY DEFINER/INVOKER
10182    Security,
10183    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
10184    SqlDataAccess,
10185    /// OPTIONS clause (BigQuery)
10186    Options,
10187    /// ENVIRONMENT clause (Databricks)
10188    Environment,
10189    /// HANDLER clause (Databricks)
10190    Handler,
10191    /// Snowflake: RUNTIME_VERSION='...'
10192    RuntimeVersion,
10193    /// Snowflake: PACKAGES=(...)
10194    Packages,
10195    /// PARAMETER STYLE clause (Databricks)
10196    ParameterStyle,
10197}
10198
10199/// Hive CREATE FUNCTION resource in a USING clause
10200#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10201#[cfg_attr(feature = "bindings", derive(TS))]
10202pub struct FunctionUsingResource {
10203    pub kind: String,
10204    pub uri: String,
10205}
10206
10207/// Function parameter
10208#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10209#[cfg_attr(feature = "bindings", derive(TS))]
10210pub struct FunctionParameter {
10211    pub name: Option<Identifier>,
10212    pub data_type: DataType,
10213    pub mode: Option<ParameterMode>,
10214    pub default: Option<Expression>,
10215    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
10216    #[serde(default, skip_serializing_if = "Option::is_none")]
10217    pub mode_text: Option<String>,
10218}
10219
10220/// Parameter mode (IN, OUT, INOUT, VARIADIC)
10221#[derive(
10222    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10223)]
10224#[cfg_attr(feature = "bindings", derive(TS))]
10225pub enum ParameterMode {
10226    In,
10227    Out,
10228    InOut,
10229    Variadic,
10230}
10231
10232/// Function body
10233#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10234#[cfg_attr(feature = "bindings", derive(TS))]
10235pub enum FunctionBody {
10236    /// AS $$ ... $$ (dollar-quoted)
10237    Block(String),
10238    /// AS 'string' (single-quoted string literal body)
10239    StringLiteral(String),
10240    /// AS 'expression'
10241    Expression(Expression),
10242    /// EXTERNAL NAME 'library'
10243    External(String),
10244    /// RETURN expression
10245    Return(Expression),
10246    /// BEGIN ... END block with parsed statements
10247    Statements(Vec<Expression>),
10248    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
10249    /// Stores (content, optional_tag)
10250    DollarQuoted {
10251        content: String,
10252        tag: Option<String>,
10253    },
10254    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
10255    RawBlock(String),
10256}
10257
10258/// Function security (DEFINER, INVOKER, or NONE)
10259#[derive(
10260    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10261)]
10262#[cfg_attr(feature = "bindings", derive(TS))]
10263pub enum FunctionSecurity {
10264    Definer,
10265    Invoker,
10266    /// StarRocks/MySQL: SECURITY NONE
10267    None,
10268}
10269
10270impl CreateFunction {
10271    pub fn new(name: impl Into<String>) -> Self {
10272        Self {
10273            name: TableRef::new(name),
10274            parameters: Vec::new(),
10275            return_type: None,
10276            body: None,
10277            or_replace: false,
10278            or_alter: false,
10279            if_not_exists: false,
10280            temporary: false,
10281            language: None,
10282            deterministic: None,
10283            returns_null_on_null_input: None,
10284            security: None,
10285            has_parens: true,
10286            sql_data_access: None,
10287            returns_table_body: None,
10288            language_first: false,
10289            set_options: Vec::new(),
10290            strict: false,
10291            options: Vec::new(),
10292            is_table_function: false,
10293            property_order: Vec::new(),
10294            using_resources: Vec::new(),
10295            environment: Vec::new(),
10296            handler: None,
10297            handler_uses_eq: false,
10298            runtime_version: None,
10299            packages: None,
10300            parameter_style: None,
10301        }
10302    }
10303}
10304
10305/// DROP FUNCTION statement
10306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10307#[cfg_attr(feature = "bindings", derive(TS))]
10308pub struct DropFunction {
10309    pub name: TableRef,
10310    pub parameters: Option<Vec<DataType>>,
10311    pub if_exists: bool,
10312    pub cascade: bool,
10313}
10314
10315impl DropFunction {
10316    pub fn new(name: impl Into<String>) -> Self {
10317        Self {
10318            name: TableRef::new(name),
10319            parameters: None,
10320            if_exists: false,
10321            cascade: false,
10322        }
10323    }
10324}
10325
10326/// CREATE PROCEDURE statement
10327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10328#[cfg_attr(feature = "bindings", derive(TS))]
10329pub struct CreateProcedure {
10330    pub name: TableRef,
10331    pub parameters: Vec<FunctionParameter>,
10332    pub body: Option<FunctionBody>,
10333    pub or_replace: bool,
10334    /// TSQL: CREATE OR ALTER
10335    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10336    pub or_alter: bool,
10337    pub if_not_exists: bool,
10338    pub language: Option<String>,
10339    pub security: Option<FunctionSecurity>,
10340    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
10341    #[serde(default)]
10342    pub return_type: Option<DataType>,
10343    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
10344    #[serde(default)]
10345    pub execute_as: Option<String>,
10346    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
10347    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10348    pub with_options: Vec<String>,
10349    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
10350    #[serde(default = "default_true", skip_serializing_if = "is_true")]
10351    pub has_parens: bool,
10352    /// Whether the short form PROC was used (instead of PROCEDURE)
10353    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10354    pub use_proc_keyword: bool,
10355}
10356
10357impl CreateProcedure {
10358    pub fn new(name: impl Into<String>) -> Self {
10359        Self {
10360            name: TableRef::new(name),
10361            parameters: Vec::new(),
10362            body: None,
10363            or_replace: false,
10364            or_alter: false,
10365            if_not_exists: false,
10366            language: None,
10367            security: None,
10368            return_type: None,
10369            execute_as: None,
10370            with_options: Vec::new(),
10371            has_parens: true,
10372            use_proc_keyword: false,
10373        }
10374    }
10375}
10376
10377/// DROP PROCEDURE statement
10378#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10379#[cfg_attr(feature = "bindings", derive(TS))]
10380pub struct DropProcedure {
10381    pub name: TableRef,
10382    pub parameters: Option<Vec<DataType>>,
10383    pub if_exists: bool,
10384    pub cascade: bool,
10385}
10386
10387impl DropProcedure {
10388    pub fn new(name: impl Into<String>) -> Self {
10389        Self {
10390            name: TableRef::new(name),
10391            parameters: None,
10392            if_exists: false,
10393            cascade: false,
10394        }
10395    }
10396}
10397
10398/// Sequence property tag for ordering
10399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10400#[cfg_attr(feature = "bindings", derive(TS))]
10401pub enum SeqPropKind {
10402    Start,
10403    Increment,
10404    Minvalue,
10405    Maxvalue,
10406    Cache,
10407    NoCache,
10408    Cycle,
10409    NoCycle,
10410    OwnedBy,
10411    Order,
10412    NoOrder,
10413    Comment,
10414    /// SHARING=<value> (Oracle)
10415    Sharing,
10416    /// KEEP (Oracle)
10417    Keep,
10418    /// NOKEEP (Oracle)
10419    NoKeep,
10420    /// SCALE [EXTEND|NOEXTEND] (Oracle)
10421    Scale,
10422    /// NOSCALE (Oracle)
10423    NoScale,
10424    /// SHARD [EXTEND|NOEXTEND] (Oracle)
10425    Shard,
10426    /// NOSHARD (Oracle)
10427    NoShard,
10428    /// SESSION (Oracle)
10429    Session,
10430    /// GLOBAL (Oracle)
10431    Global,
10432    /// NOCACHE (single word, Oracle)
10433    NoCacheWord,
10434    /// NOCYCLE (single word, Oracle)
10435    NoCycleWord,
10436    /// NOMINVALUE (single word, Oracle)
10437    NoMinvalueWord,
10438    /// NOMAXVALUE (single word, Oracle)
10439    NoMaxvalueWord,
10440}
10441
10442/// CREATE SYNONYM statement (TSQL)
10443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10444#[cfg_attr(feature = "bindings", derive(TS))]
10445pub struct CreateSynonym {
10446    /// The synonym name (can be qualified: schema.synonym_name)
10447    pub name: TableRef,
10448    /// The target object the synonym refers to
10449    pub target: TableRef,
10450}
10451
10452/// CREATE SEQUENCE statement
10453#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10454#[cfg_attr(feature = "bindings", derive(TS))]
10455pub struct CreateSequence {
10456    pub name: TableRef,
10457    pub if_not_exists: bool,
10458    pub temporary: bool,
10459    #[serde(default)]
10460    pub or_replace: bool,
10461    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
10462    #[serde(default, skip_serializing_if = "Option::is_none")]
10463    pub as_type: Option<DataType>,
10464    pub increment: Option<i64>,
10465    pub minvalue: Option<SequenceBound>,
10466    pub maxvalue: Option<SequenceBound>,
10467    pub start: Option<i64>,
10468    pub cache: Option<i64>,
10469    pub cycle: bool,
10470    pub owned_by: Option<TableRef>,
10471    /// Whether OWNED BY NONE was specified
10472    #[serde(default)]
10473    pub owned_by_none: bool,
10474    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
10475    #[serde(default)]
10476    pub order: Option<bool>,
10477    /// Snowflake: COMMENT = 'value'
10478    #[serde(default)]
10479    pub comment: Option<String>,
10480    /// SHARING=<value> (Oracle)
10481    #[serde(default, skip_serializing_if = "Option::is_none")]
10482    pub sharing: Option<String>,
10483    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
10484    #[serde(default, skip_serializing_if = "Option::is_none")]
10485    pub scale_modifier: Option<String>,
10486    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
10487    #[serde(default, skip_serializing_if = "Option::is_none")]
10488    pub shard_modifier: Option<String>,
10489    /// Tracks the order in which properties appeared in the source
10490    #[serde(default)]
10491    pub property_order: Vec<SeqPropKind>,
10492}
10493
10494/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
10495#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10496#[cfg_attr(feature = "bindings", derive(TS))]
10497pub enum SequenceBound {
10498    Value(i64),
10499    None,
10500}
10501
10502impl CreateSequence {
10503    pub fn new(name: impl Into<String>) -> Self {
10504        Self {
10505            name: TableRef::new(name),
10506            if_not_exists: false,
10507            temporary: false,
10508            or_replace: false,
10509            as_type: None,
10510            increment: None,
10511            minvalue: None,
10512            maxvalue: None,
10513            start: None,
10514            cache: None,
10515            cycle: false,
10516            owned_by: None,
10517            owned_by_none: false,
10518            order: None,
10519            comment: None,
10520            sharing: None,
10521            scale_modifier: None,
10522            shard_modifier: None,
10523            property_order: Vec::new(),
10524        }
10525    }
10526}
10527
10528/// DROP SEQUENCE statement
10529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10530#[cfg_attr(feature = "bindings", derive(TS))]
10531pub struct DropSequence {
10532    pub name: TableRef,
10533    pub if_exists: bool,
10534    pub cascade: bool,
10535}
10536
10537impl DropSequence {
10538    pub fn new(name: impl Into<String>) -> Self {
10539        Self {
10540            name: TableRef::new(name),
10541            if_exists: false,
10542            cascade: false,
10543        }
10544    }
10545}
10546
10547/// ALTER SEQUENCE statement
10548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10549#[cfg_attr(feature = "bindings", derive(TS))]
10550pub struct AlterSequence {
10551    pub name: TableRef,
10552    pub if_exists: bool,
10553    pub increment: Option<i64>,
10554    pub minvalue: Option<SequenceBound>,
10555    pub maxvalue: Option<SequenceBound>,
10556    pub start: Option<i64>,
10557    pub restart: Option<Option<i64>>,
10558    pub cache: Option<i64>,
10559    pub cycle: Option<bool>,
10560    pub owned_by: Option<Option<TableRef>>,
10561}
10562
10563impl AlterSequence {
10564    pub fn new(name: impl Into<String>) -> Self {
10565        Self {
10566            name: TableRef::new(name),
10567            if_exists: false,
10568            increment: None,
10569            minvalue: None,
10570            maxvalue: None,
10571            start: None,
10572            restart: None,
10573            cache: None,
10574            cycle: None,
10575            owned_by: None,
10576        }
10577    }
10578}
10579
10580/// CREATE TRIGGER statement
10581#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10582#[cfg_attr(feature = "bindings", derive(TS))]
10583pub struct CreateTrigger {
10584    pub name: Identifier,
10585    pub table: TableRef,
10586    pub timing: TriggerTiming,
10587    pub events: Vec<TriggerEvent>,
10588    #[serde(default, skip_serializing_if = "Option::is_none")]
10589    pub for_each: Option<TriggerForEach>,
10590    pub when: Option<Expression>,
10591    /// Whether the WHEN clause was parenthesized in the original SQL
10592    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10593    pub when_paren: bool,
10594    pub body: TriggerBody,
10595    pub or_replace: bool,
10596    /// TSQL: CREATE OR ALTER
10597    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10598    pub or_alter: bool,
10599    pub constraint: bool,
10600    pub deferrable: Option<bool>,
10601    pub initially_deferred: Option<bool>,
10602    pub referencing: Option<TriggerReferencing>,
10603}
10604
10605/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
10606#[derive(
10607    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10608)]
10609#[cfg_attr(feature = "bindings", derive(TS))]
10610pub enum TriggerTiming {
10611    Before,
10612    After,
10613    InsteadOf,
10614}
10615
10616/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
10617#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10618#[cfg_attr(feature = "bindings", derive(TS))]
10619pub enum TriggerEvent {
10620    Insert,
10621    Update(Option<Vec<Identifier>>),
10622    Delete,
10623    Truncate,
10624}
10625
10626/// Trigger FOR EACH clause
10627#[derive(
10628    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10629)]
10630#[cfg_attr(feature = "bindings", derive(TS))]
10631pub enum TriggerForEach {
10632    Row,
10633    Statement,
10634}
10635
10636/// Trigger body
10637#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10638#[cfg_attr(feature = "bindings", derive(TS))]
10639pub enum TriggerBody {
10640    /// EXECUTE FUNCTION/PROCEDURE name(args)
10641    Execute {
10642        function: TableRef,
10643        args: Vec<Expression>,
10644    },
10645    /// BEGIN ... END block
10646    Block(String),
10647}
10648
10649/// Trigger REFERENCING clause
10650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10651#[cfg_attr(feature = "bindings", derive(TS))]
10652pub struct TriggerReferencing {
10653    pub old_table: Option<Identifier>,
10654    pub new_table: Option<Identifier>,
10655    pub old_row: Option<Identifier>,
10656    pub new_row: Option<Identifier>,
10657}
10658
10659impl CreateTrigger {
10660    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
10661        Self {
10662            name: Identifier::new(name),
10663            table: TableRef::new(table),
10664            timing: TriggerTiming::Before,
10665            events: Vec::new(),
10666            for_each: Some(TriggerForEach::Row),
10667            when: None,
10668            when_paren: false,
10669            body: TriggerBody::Execute {
10670                function: TableRef::new(""),
10671                args: Vec::new(),
10672            },
10673            or_replace: false,
10674            or_alter: false,
10675            constraint: false,
10676            deferrable: None,
10677            initially_deferred: None,
10678            referencing: None,
10679        }
10680    }
10681}
10682
10683/// DROP TRIGGER statement
10684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10685#[cfg_attr(feature = "bindings", derive(TS))]
10686pub struct DropTrigger {
10687    pub name: Identifier,
10688    pub table: Option<TableRef>,
10689    pub if_exists: bool,
10690    pub cascade: bool,
10691}
10692
10693impl DropTrigger {
10694    pub fn new(name: impl Into<String>) -> Self {
10695        Self {
10696            name: Identifier::new(name),
10697            table: None,
10698            if_exists: false,
10699            cascade: false,
10700        }
10701    }
10702}
10703
10704/// CREATE TYPE statement
10705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10706#[cfg_attr(feature = "bindings", derive(TS))]
10707pub struct CreateType {
10708    pub name: TableRef,
10709    pub definition: TypeDefinition,
10710    pub if_not_exists: bool,
10711}
10712
10713/// Type definition
10714#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10715#[cfg_attr(feature = "bindings", derive(TS))]
10716pub enum TypeDefinition {
10717    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
10718    Enum(Vec<String>),
10719    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
10720    Composite(Vec<TypeAttribute>),
10721    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
10722    Range {
10723        subtype: DataType,
10724        subtype_diff: Option<String>,
10725        canonical: Option<String>,
10726    },
10727    /// Base type (for advanced usage)
10728    Base {
10729        input: String,
10730        output: String,
10731        internallength: Option<i32>,
10732    },
10733    /// Domain type
10734    Domain {
10735        base_type: DataType,
10736        default: Option<Expression>,
10737        constraints: Vec<DomainConstraint>,
10738    },
10739}
10740
10741/// Type attribute for composite types
10742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10743#[cfg_attr(feature = "bindings", derive(TS))]
10744pub struct TypeAttribute {
10745    pub name: Identifier,
10746    pub data_type: DataType,
10747    pub collate: Option<Identifier>,
10748}
10749
10750/// Domain constraint
10751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10752#[cfg_attr(feature = "bindings", derive(TS))]
10753pub struct DomainConstraint {
10754    pub name: Option<Identifier>,
10755    pub check: Expression,
10756}
10757
10758impl CreateType {
10759    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
10760        Self {
10761            name: TableRef::new(name),
10762            definition: TypeDefinition::Enum(values),
10763            if_not_exists: false,
10764        }
10765    }
10766
10767    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
10768        Self {
10769            name: TableRef::new(name),
10770            definition: TypeDefinition::Composite(attributes),
10771            if_not_exists: false,
10772        }
10773    }
10774}
10775
10776/// DROP TYPE statement
10777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10778#[cfg_attr(feature = "bindings", derive(TS))]
10779pub struct DropType {
10780    pub name: TableRef,
10781    pub if_exists: bool,
10782    pub cascade: bool,
10783}
10784
10785impl DropType {
10786    pub fn new(name: impl Into<String>) -> Self {
10787        Self {
10788            name: TableRef::new(name),
10789            if_exists: false,
10790            cascade: false,
10791        }
10792    }
10793}
10794
10795/// DESCRIBE statement - shows table structure or query plan
10796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10797#[cfg_attr(feature = "bindings", derive(TS))]
10798pub struct Describe {
10799    /// The target to describe (table name or query)
10800    pub target: Expression,
10801    /// EXTENDED format
10802    pub extended: bool,
10803    /// FORMATTED format
10804    pub formatted: bool,
10805    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10806    #[serde(default)]
10807    pub kind: Option<String>,
10808    /// Properties like type=stage
10809    #[serde(default)]
10810    pub properties: Vec<(String, String)>,
10811    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10812    #[serde(default, skip_serializing_if = "Option::is_none")]
10813    pub style: Option<String>,
10814    /// Partition specification for DESCRIBE PARTITION
10815    #[serde(default)]
10816    pub partition: Option<Box<Expression>>,
10817    /// Leading comments before the statement
10818    #[serde(default)]
10819    pub leading_comments: Vec<String>,
10820    /// AS JSON suffix (Databricks)
10821    #[serde(default)]
10822    pub as_json: bool,
10823    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10824    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10825    pub params: Vec<String>,
10826}
10827
10828impl Describe {
10829    pub fn new(target: Expression) -> Self {
10830        Self {
10831            target,
10832            extended: false,
10833            formatted: false,
10834            kind: None,
10835            properties: Vec::new(),
10836            style: None,
10837            partition: None,
10838            leading_comments: Vec::new(),
10839            as_json: false,
10840            params: Vec::new(),
10841        }
10842    }
10843}
10844
10845/// SHOW statement - displays database objects
10846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10847#[cfg_attr(feature = "bindings", derive(TS))]
10848pub struct Show {
10849    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10850    pub this: String,
10851    /// Whether TERSE was specified
10852    #[serde(default)]
10853    pub terse: bool,
10854    /// Whether HISTORY was specified
10855    #[serde(default)]
10856    pub history: bool,
10857    /// LIKE pattern
10858    pub like: Option<Expression>,
10859    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10860    pub scope_kind: Option<String>,
10861    /// IN scope object
10862    pub scope: Option<Expression>,
10863    /// STARTS WITH pattern
10864    pub starts_with: Option<Expression>,
10865    /// LIMIT clause
10866    pub limit: Option<Box<Limit>>,
10867    /// FROM clause (for specific object)
10868    pub from: Option<Expression>,
10869    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10870    #[serde(default, skip_serializing_if = "Option::is_none")]
10871    pub where_clause: Option<Expression>,
10872    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10873    #[serde(default, skip_serializing_if = "Option::is_none")]
10874    pub for_target: Option<Expression>,
10875    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10876    #[serde(default, skip_serializing_if = "Option::is_none")]
10877    pub db: Option<Expression>,
10878    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10879    #[serde(default, skip_serializing_if = "Option::is_none")]
10880    pub target: Option<Expression>,
10881    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10882    #[serde(default, skip_serializing_if = "Option::is_none")]
10883    pub mutex: Option<bool>,
10884    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10885    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10886    pub privileges: Vec<String>,
10887}
10888
10889impl Show {
10890    pub fn new(this: impl Into<String>) -> Self {
10891        Self {
10892            this: this.into(),
10893            terse: false,
10894            history: false,
10895            like: None,
10896            scope_kind: None,
10897            scope: None,
10898            starts_with: None,
10899            limit: None,
10900            from: None,
10901            where_clause: None,
10902            for_target: None,
10903            db: None,
10904            target: None,
10905            mutex: None,
10906            privileges: Vec::new(),
10907        }
10908    }
10909}
10910
10911/// Represent an explicit parenthesized expression for grouping precedence.
10912///
10913/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10914/// correctly instead of being flattened to `a + b * c`.
10915#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10916#[cfg_attr(feature = "bindings", derive(TS))]
10917pub struct Paren {
10918    /// The inner expression wrapped by parentheses.
10919    pub this: Expression,
10920    #[serde(default)]
10921    pub trailing_comments: Vec<String>,
10922}
10923
10924/// Expression annotated with trailing comments (for round-trip preservation)
10925#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10926#[cfg_attr(feature = "bindings", derive(TS))]
10927pub struct Annotated {
10928    pub this: Expression,
10929    pub trailing_comments: Vec<String>,
10930}
10931
10932// === BATCH GENERATED STRUCT DEFINITIONS ===
10933// Generated from Python sqlglot expressions.py
10934
10935/// Refresh
10936#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10937#[cfg_attr(feature = "bindings", derive(TS))]
10938pub struct Refresh {
10939    pub this: Box<Expression>,
10940    pub kind: String,
10941}
10942
10943/// LockingStatement
10944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10945#[cfg_attr(feature = "bindings", derive(TS))]
10946pub struct LockingStatement {
10947    pub this: Box<Expression>,
10948    pub expression: Box<Expression>,
10949}
10950
10951/// SequenceProperties
10952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10953#[cfg_attr(feature = "bindings", derive(TS))]
10954pub struct SequenceProperties {
10955    #[serde(default)]
10956    pub increment: Option<Box<Expression>>,
10957    #[serde(default)]
10958    pub minvalue: Option<Box<Expression>>,
10959    #[serde(default)]
10960    pub maxvalue: Option<Box<Expression>>,
10961    #[serde(default)]
10962    pub cache: Option<Box<Expression>>,
10963    #[serde(default)]
10964    pub start: Option<Box<Expression>>,
10965    #[serde(default)]
10966    pub owned: Option<Box<Expression>>,
10967    #[serde(default)]
10968    pub options: Vec<Expression>,
10969}
10970
10971/// TruncateTable
10972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10973#[cfg_attr(feature = "bindings", derive(TS))]
10974pub struct TruncateTable {
10975    #[serde(default)]
10976    pub expressions: Vec<Expression>,
10977    #[serde(default)]
10978    pub is_database: Option<Box<Expression>>,
10979    #[serde(default)]
10980    pub exists: bool,
10981    #[serde(default)]
10982    pub only: Option<Box<Expression>>,
10983    #[serde(default)]
10984    pub cluster: Option<Box<Expression>>,
10985    #[serde(default)]
10986    pub identity: Option<Box<Expression>>,
10987    #[serde(default)]
10988    pub option: Option<Box<Expression>>,
10989    #[serde(default)]
10990    pub partition: Option<Box<Expression>>,
10991}
10992
10993/// Clone
10994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10995#[cfg_attr(feature = "bindings", derive(TS))]
10996pub struct Clone {
10997    pub this: Box<Expression>,
10998    #[serde(default)]
10999    pub shallow: Option<Box<Expression>>,
11000    #[serde(default)]
11001    pub copy: Option<Box<Expression>>,
11002}
11003
11004/// Attach
11005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11006#[cfg_attr(feature = "bindings", derive(TS))]
11007pub struct Attach {
11008    pub this: Box<Expression>,
11009    #[serde(default)]
11010    pub exists: bool,
11011    #[serde(default)]
11012    pub expressions: Vec<Expression>,
11013}
11014
11015/// Detach
11016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11017#[cfg_attr(feature = "bindings", derive(TS))]
11018pub struct Detach {
11019    pub this: Box<Expression>,
11020    #[serde(default)]
11021    pub exists: bool,
11022}
11023
11024/// Install
11025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11026#[cfg_attr(feature = "bindings", derive(TS))]
11027pub struct Install {
11028    pub this: Box<Expression>,
11029    #[serde(default)]
11030    pub from_: Option<Box<Expression>>,
11031    #[serde(default)]
11032    pub force: Option<Box<Expression>>,
11033}
11034
11035/// Summarize
11036#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11037#[cfg_attr(feature = "bindings", derive(TS))]
11038pub struct Summarize {
11039    pub this: Box<Expression>,
11040    #[serde(default)]
11041    pub table: Option<Box<Expression>>,
11042}
11043
11044/// Declare
11045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11046#[cfg_attr(feature = "bindings", derive(TS))]
11047pub struct Declare {
11048    #[serde(default)]
11049    pub expressions: Vec<Expression>,
11050    #[serde(default)]
11051    pub replace: bool,
11052}
11053
11054/// DeclareItem
11055#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11056#[cfg_attr(feature = "bindings", derive(TS))]
11057pub struct DeclareItem {
11058    pub this: Box<Expression>,
11059    #[serde(default)]
11060    pub kind: Option<String>,
11061    #[serde(default)]
11062    pub default: Option<Box<Expression>>,
11063    #[serde(default)]
11064    pub has_as: bool,
11065    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
11066    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11067    pub additional_names: Vec<Expression>,
11068}
11069
11070/// Set
11071#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11072#[cfg_attr(feature = "bindings", derive(TS))]
11073pub struct Set {
11074    #[serde(default)]
11075    pub expressions: Vec<Expression>,
11076    #[serde(default)]
11077    pub unset: Option<Box<Expression>>,
11078    #[serde(default)]
11079    pub tag: Option<Box<Expression>>,
11080}
11081
11082/// Heredoc
11083#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11084#[cfg_attr(feature = "bindings", derive(TS))]
11085pub struct Heredoc {
11086    pub this: Box<Expression>,
11087    #[serde(default)]
11088    pub tag: Option<Box<Expression>>,
11089}
11090
11091/// QueryBand
11092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11093#[cfg_attr(feature = "bindings", derive(TS))]
11094pub struct QueryBand {
11095    pub this: Box<Expression>,
11096    #[serde(default)]
11097    pub scope: Option<Box<Expression>>,
11098    #[serde(default)]
11099    pub update: Option<Box<Expression>>,
11100}
11101
11102/// UserDefinedFunction
11103#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11104#[cfg_attr(feature = "bindings", derive(TS))]
11105pub struct UserDefinedFunction {
11106    pub this: Box<Expression>,
11107    #[serde(default)]
11108    pub expressions: Vec<Expression>,
11109    #[serde(default)]
11110    pub wrapped: Option<Box<Expression>>,
11111}
11112
11113/// RecursiveWithSearch
11114#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11115#[cfg_attr(feature = "bindings", derive(TS))]
11116pub struct RecursiveWithSearch {
11117    pub kind: String,
11118    pub this: Box<Expression>,
11119    pub expression: Box<Expression>,
11120    #[serde(default)]
11121    pub using: Option<Box<Expression>>,
11122}
11123
11124/// ProjectionDef
11125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11126#[cfg_attr(feature = "bindings", derive(TS))]
11127pub struct ProjectionDef {
11128    pub this: Box<Expression>,
11129    pub expression: Box<Expression>,
11130}
11131
11132/// TableAlias
11133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11134#[cfg_attr(feature = "bindings", derive(TS))]
11135pub struct TableAlias {
11136    #[serde(default)]
11137    pub this: Option<Box<Expression>>,
11138    #[serde(default)]
11139    pub columns: Vec<Expression>,
11140}
11141
11142/// ByteString
11143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11144#[cfg_attr(feature = "bindings", derive(TS))]
11145pub struct ByteString {
11146    pub this: Box<Expression>,
11147    #[serde(default)]
11148    pub is_bytes: Option<Box<Expression>>,
11149}
11150
11151/// HexStringExpr - Hex string expression (not literal)
11152/// BigQuery: converts to FROM_HEX(this)
11153#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11154#[cfg_attr(feature = "bindings", derive(TS))]
11155pub struct HexStringExpr {
11156    pub this: Box<Expression>,
11157    #[serde(default)]
11158    pub is_integer: Option<bool>,
11159}
11160
11161/// UnicodeString
11162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11163#[cfg_attr(feature = "bindings", derive(TS))]
11164pub struct UnicodeString {
11165    pub this: Box<Expression>,
11166    #[serde(default)]
11167    pub escape: Option<Box<Expression>>,
11168}
11169
11170/// AlterColumn
11171#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11172#[cfg_attr(feature = "bindings", derive(TS))]
11173pub struct AlterColumn {
11174    pub this: Box<Expression>,
11175    #[serde(default)]
11176    pub dtype: Option<Box<Expression>>,
11177    #[serde(default)]
11178    pub collate: Option<Box<Expression>>,
11179    #[serde(default)]
11180    pub using: Option<Box<Expression>>,
11181    #[serde(default)]
11182    pub default: Option<Box<Expression>>,
11183    #[serde(default)]
11184    pub drop: Option<Box<Expression>>,
11185    #[serde(default)]
11186    pub comment: Option<Box<Expression>>,
11187    #[serde(default)]
11188    pub allow_null: Option<Box<Expression>>,
11189    #[serde(default)]
11190    pub visible: Option<Box<Expression>>,
11191    #[serde(default)]
11192    pub rename_to: Option<Box<Expression>>,
11193}
11194
11195/// AlterSortKey
11196#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11197#[cfg_attr(feature = "bindings", derive(TS))]
11198pub struct AlterSortKey {
11199    #[serde(default)]
11200    pub this: Option<Box<Expression>>,
11201    #[serde(default)]
11202    pub expressions: Vec<Expression>,
11203    #[serde(default)]
11204    pub compound: Option<Box<Expression>>,
11205}
11206
11207/// AlterSet
11208#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11209#[cfg_attr(feature = "bindings", derive(TS))]
11210pub struct AlterSet {
11211    #[serde(default)]
11212    pub expressions: Vec<Expression>,
11213    #[serde(default)]
11214    pub option: Option<Box<Expression>>,
11215    #[serde(default)]
11216    pub tablespace: Option<Box<Expression>>,
11217    #[serde(default)]
11218    pub access_method: Option<Box<Expression>>,
11219    #[serde(default)]
11220    pub file_format: Option<Box<Expression>>,
11221    #[serde(default)]
11222    pub copy_options: Option<Box<Expression>>,
11223    #[serde(default)]
11224    pub tag: Option<Box<Expression>>,
11225    #[serde(default)]
11226    pub location: Option<Box<Expression>>,
11227    #[serde(default)]
11228    pub serde: Option<Box<Expression>>,
11229}
11230
11231/// RenameColumn
11232#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11233#[cfg_attr(feature = "bindings", derive(TS))]
11234pub struct RenameColumn {
11235    pub this: Box<Expression>,
11236    #[serde(default)]
11237    pub to: Option<Box<Expression>>,
11238    #[serde(default)]
11239    pub exists: bool,
11240}
11241
11242/// Comprehension
11243#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11244#[cfg_attr(feature = "bindings", derive(TS))]
11245pub struct Comprehension {
11246    pub this: Box<Expression>,
11247    pub expression: Box<Expression>,
11248    #[serde(default)]
11249    pub position: Option<Box<Expression>>,
11250    #[serde(default)]
11251    pub iterator: Option<Box<Expression>>,
11252    #[serde(default)]
11253    pub condition: Option<Box<Expression>>,
11254}
11255
11256/// MergeTreeTTLAction
11257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11258#[cfg_attr(feature = "bindings", derive(TS))]
11259pub struct MergeTreeTTLAction {
11260    pub this: Box<Expression>,
11261    #[serde(default)]
11262    pub delete: Option<Box<Expression>>,
11263    #[serde(default)]
11264    pub recompress: Option<Box<Expression>>,
11265    #[serde(default)]
11266    pub to_disk: Option<Box<Expression>>,
11267    #[serde(default)]
11268    pub to_volume: Option<Box<Expression>>,
11269}
11270
11271/// MergeTreeTTL
11272#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11273#[cfg_attr(feature = "bindings", derive(TS))]
11274pub struct MergeTreeTTL {
11275    #[serde(default)]
11276    pub expressions: Vec<Expression>,
11277    #[serde(default)]
11278    pub where_: Option<Box<Expression>>,
11279    #[serde(default)]
11280    pub group: Option<Box<Expression>>,
11281    #[serde(default)]
11282    pub aggregates: Option<Box<Expression>>,
11283}
11284
11285/// IndexConstraintOption
11286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11287#[cfg_attr(feature = "bindings", derive(TS))]
11288pub struct IndexConstraintOption {
11289    #[serde(default)]
11290    pub key_block_size: Option<Box<Expression>>,
11291    #[serde(default)]
11292    pub using: Option<Box<Expression>>,
11293    #[serde(default)]
11294    pub parser: Option<Box<Expression>>,
11295    #[serde(default)]
11296    pub comment: Option<Box<Expression>>,
11297    #[serde(default)]
11298    pub visible: Option<Box<Expression>>,
11299    #[serde(default)]
11300    pub engine_attr: Option<Box<Expression>>,
11301    #[serde(default)]
11302    pub secondary_engine_attr: Option<Box<Expression>>,
11303}
11304
11305/// PeriodForSystemTimeConstraint
11306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11307#[cfg_attr(feature = "bindings", derive(TS))]
11308pub struct PeriodForSystemTimeConstraint {
11309    pub this: Box<Expression>,
11310    pub expression: Box<Expression>,
11311}
11312
11313/// CaseSpecificColumnConstraint
11314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11315#[cfg_attr(feature = "bindings", derive(TS))]
11316pub struct CaseSpecificColumnConstraint {
11317    #[serde(default)]
11318    pub not_: Option<Box<Expression>>,
11319}
11320
11321/// CharacterSetColumnConstraint
11322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11323#[cfg_attr(feature = "bindings", derive(TS))]
11324pub struct CharacterSetColumnConstraint {
11325    pub this: Box<Expression>,
11326}
11327
11328/// CheckColumnConstraint
11329#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11330#[cfg_attr(feature = "bindings", derive(TS))]
11331pub struct CheckColumnConstraint {
11332    pub this: Box<Expression>,
11333    #[serde(default)]
11334    pub enforced: Option<Box<Expression>>,
11335}
11336
11337/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
11338#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11339#[cfg_attr(feature = "bindings", derive(TS))]
11340pub struct AssumeColumnConstraint {
11341    pub this: Box<Expression>,
11342}
11343
11344/// CompressColumnConstraint
11345#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11346#[cfg_attr(feature = "bindings", derive(TS))]
11347pub struct CompressColumnConstraint {
11348    #[serde(default)]
11349    pub this: Option<Box<Expression>>,
11350}
11351
11352/// DateFormatColumnConstraint
11353#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11354#[cfg_attr(feature = "bindings", derive(TS))]
11355pub struct DateFormatColumnConstraint {
11356    pub this: Box<Expression>,
11357}
11358
11359/// EphemeralColumnConstraint
11360#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11361#[cfg_attr(feature = "bindings", derive(TS))]
11362pub struct EphemeralColumnConstraint {
11363    #[serde(default)]
11364    pub this: Option<Box<Expression>>,
11365}
11366
11367/// WithOperator
11368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11369#[cfg_attr(feature = "bindings", derive(TS))]
11370pub struct WithOperator {
11371    pub this: Box<Expression>,
11372    pub op: String,
11373}
11374
11375/// GeneratedAsIdentityColumnConstraint
11376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11377#[cfg_attr(feature = "bindings", derive(TS))]
11378pub struct GeneratedAsIdentityColumnConstraint {
11379    #[serde(default)]
11380    pub this: Option<Box<Expression>>,
11381    #[serde(default)]
11382    pub expression: Option<Box<Expression>>,
11383    #[serde(default)]
11384    pub on_null: Option<Box<Expression>>,
11385    #[serde(default)]
11386    pub start: Option<Box<Expression>>,
11387    #[serde(default)]
11388    pub increment: Option<Box<Expression>>,
11389    #[serde(default)]
11390    pub minvalue: Option<Box<Expression>>,
11391    #[serde(default)]
11392    pub maxvalue: Option<Box<Expression>>,
11393    #[serde(default)]
11394    pub cycle: Option<Box<Expression>>,
11395    #[serde(default)]
11396    pub order: Option<Box<Expression>>,
11397}
11398
11399/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
11400/// TSQL: outputs "IDENTITY"
11401#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11402#[cfg_attr(feature = "bindings", derive(TS))]
11403pub struct AutoIncrementColumnConstraint;
11404
11405/// CommentColumnConstraint - Column comment marker
11406#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11407#[cfg_attr(feature = "bindings", derive(TS))]
11408pub struct CommentColumnConstraint;
11409
11410/// GeneratedAsRowColumnConstraint
11411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11412#[cfg_attr(feature = "bindings", derive(TS))]
11413pub struct GeneratedAsRowColumnConstraint {
11414    #[serde(default)]
11415    pub start: Option<Box<Expression>>,
11416    #[serde(default)]
11417    pub hidden: Option<Box<Expression>>,
11418}
11419
11420/// IndexColumnConstraint
11421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11422#[cfg_attr(feature = "bindings", derive(TS))]
11423pub struct IndexColumnConstraint {
11424    #[serde(default)]
11425    pub this: Option<Box<Expression>>,
11426    #[serde(default)]
11427    pub expressions: Vec<Expression>,
11428    #[serde(default)]
11429    pub kind: Option<String>,
11430    #[serde(default)]
11431    pub index_type: Option<Box<Expression>>,
11432    #[serde(default)]
11433    pub options: Vec<Expression>,
11434    #[serde(default)]
11435    pub expression: Option<Box<Expression>>,
11436    #[serde(default)]
11437    pub granularity: Option<Box<Expression>>,
11438}
11439
11440/// MaskingPolicyColumnConstraint
11441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11442#[cfg_attr(feature = "bindings", derive(TS))]
11443pub struct MaskingPolicyColumnConstraint {
11444    pub this: Box<Expression>,
11445    #[serde(default)]
11446    pub expressions: Vec<Expression>,
11447}
11448
11449/// NotNullColumnConstraint
11450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11451#[cfg_attr(feature = "bindings", derive(TS))]
11452pub struct NotNullColumnConstraint {
11453    #[serde(default)]
11454    pub allow_null: Option<Box<Expression>>,
11455}
11456
11457/// DefaultColumnConstraint - DEFAULT value for a column
11458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11459#[cfg_attr(feature = "bindings", derive(TS))]
11460pub struct DefaultColumnConstraint {
11461    pub this: Box<Expression>,
11462    /// TSQL: DEFAULT value FOR column (table-level default constraint)
11463    #[serde(default, skip_serializing_if = "Option::is_none")]
11464    pub for_column: Option<Identifier>,
11465}
11466
11467/// PrimaryKeyColumnConstraint
11468#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11469#[cfg_attr(feature = "bindings", derive(TS))]
11470pub struct PrimaryKeyColumnConstraint {
11471    #[serde(default)]
11472    pub desc: Option<Box<Expression>>,
11473    #[serde(default)]
11474    pub options: Vec<Expression>,
11475}
11476
11477/// UniqueColumnConstraint
11478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11479#[cfg_attr(feature = "bindings", derive(TS))]
11480pub struct UniqueColumnConstraint {
11481    #[serde(default)]
11482    pub this: Option<Box<Expression>>,
11483    #[serde(default)]
11484    pub index_type: Option<Box<Expression>>,
11485    #[serde(default)]
11486    pub on_conflict: Option<Box<Expression>>,
11487    #[serde(default)]
11488    pub nulls: Option<Box<Expression>>,
11489    #[serde(default)]
11490    pub options: Vec<Expression>,
11491}
11492
11493/// WatermarkColumnConstraint
11494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11495#[cfg_attr(feature = "bindings", derive(TS))]
11496pub struct WatermarkColumnConstraint {
11497    pub this: Box<Expression>,
11498    pub expression: Box<Expression>,
11499}
11500
11501/// ComputedColumnConstraint
11502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11503#[cfg_attr(feature = "bindings", derive(TS))]
11504pub struct ComputedColumnConstraint {
11505    pub this: Box<Expression>,
11506    #[serde(default)]
11507    pub persisted: Option<Box<Expression>>,
11508    #[serde(default)]
11509    pub not_null: Option<Box<Expression>>,
11510    #[serde(default)]
11511    pub data_type: Option<Box<Expression>>,
11512}
11513
11514/// InOutColumnConstraint
11515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11516#[cfg_attr(feature = "bindings", derive(TS))]
11517pub struct InOutColumnConstraint {
11518    #[serde(default)]
11519    pub input_: Option<Box<Expression>>,
11520    #[serde(default)]
11521    pub output: Option<Box<Expression>>,
11522}
11523
11524/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
11525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11526#[cfg_attr(feature = "bindings", derive(TS))]
11527pub struct PathColumnConstraint {
11528    pub this: Box<Expression>,
11529}
11530
11531/// Constraint
11532#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11533#[cfg_attr(feature = "bindings", derive(TS))]
11534pub struct Constraint {
11535    pub this: Box<Expression>,
11536    #[serde(default)]
11537    pub expressions: Vec<Expression>,
11538}
11539
11540/// Export
11541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11542#[cfg_attr(feature = "bindings", derive(TS))]
11543pub struct Export {
11544    pub this: Box<Expression>,
11545    #[serde(default)]
11546    pub connection: Option<Box<Expression>>,
11547    #[serde(default)]
11548    pub options: Vec<Expression>,
11549}
11550
11551/// Filter
11552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11553#[cfg_attr(feature = "bindings", derive(TS))]
11554pub struct Filter {
11555    pub this: Box<Expression>,
11556    pub expression: Box<Expression>,
11557}
11558
11559/// Changes
11560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11561#[cfg_attr(feature = "bindings", derive(TS))]
11562pub struct Changes {
11563    #[serde(default)]
11564    pub information: Option<Box<Expression>>,
11565    #[serde(default)]
11566    pub at_before: Option<Box<Expression>>,
11567    #[serde(default)]
11568    pub end: Option<Box<Expression>>,
11569}
11570
11571/// Directory
11572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11573#[cfg_attr(feature = "bindings", derive(TS))]
11574pub struct Directory {
11575    pub this: Box<Expression>,
11576    #[serde(default)]
11577    pub local: Option<Box<Expression>>,
11578    #[serde(default)]
11579    pub row_format: Option<Box<Expression>>,
11580}
11581
11582/// ForeignKey
11583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11584#[cfg_attr(feature = "bindings", derive(TS))]
11585pub struct ForeignKey {
11586    #[serde(default)]
11587    pub expressions: Vec<Expression>,
11588    #[serde(default)]
11589    pub reference: Option<Box<Expression>>,
11590    #[serde(default)]
11591    pub delete: Option<Box<Expression>>,
11592    #[serde(default)]
11593    pub update: Option<Box<Expression>>,
11594    #[serde(default)]
11595    pub options: Vec<Expression>,
11596}
11597
11598/// ColumnPrefix
11599#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11600#[cfg_attr(feature = "bindings", derive(TS))]
11601pub struct ColumnPrefix {
11602    pub this: Box<Expression>,
11603    pub expression: Box<Expression>,
11604}
11605
11606/// PrimaryKey
11607#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11608#[cfg_attr(feature = "bindings", derive(TS))]
11609pub struct PrimaryKey {
11610    #[serde(default)]
11611    pub this: Option<Box<Expression>>,
11612    #[serde(default)]
11613    pub expressions: Vec<Expression>,
11614    #[serde(default)]
11615    pub options: Vec<Expression>,
11616    #[serde(default)]
11617    pub include: Option<Box<Expression>>,
11618}
11619
11620/// Into
11621#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11622#[cfg_attr(feature = "bindings", derive(TS))]
11623pub struct IntoClause {
11624    #[serde(default)]
11625    pub this: Option<Box<Expression>>,
11626    #[serde(default)]
11627    pub temporary: bool,
11628    #[serde(default)]
11629    pub unlogged: Option<Box<Expression>>,
11630    #[serde(default)]
11631    pub bulk_collect: Option<Box<Expression>>,
11632    #[serde(default)]
11633    pub expressions: Vec<Expression>,
11634}
11635
11636/// JoinHint
11637#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11638#[cfg_attr(feature = "bindings", derive(TS))]
11639pub struct JoinHint {
11640    pub this: Box<Expression>,
11641    #[serde(default)]
11642    pub expressions: Vec<Expression>,
11643}
11644
11645/// Opclass
11646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11647#[cfg_attr(feature = "bindings", derive(TS))]
11648pub struct Opclass {
11649    pub this: Box<Expression>,
11650    pub expression: Box<Expression>,
11651}
11652
11653/// Index
11654#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11655#[cfg_attr(feature = "bindings", derive(TS))]
11656pub struct Index {
11657    #[serde(default)]
11658    pub this: Option<Box<Expression>>,
11659    #[serde(default)]
11660    pub table: Option<Box<Expression>>,
11661    #[serde(default)]
11662    pub unique: bool,
11663    #[serde(default)]
11664    pub primary: Option<Box<Expression>>,
11665    #[serde(default)]
11666    pub amp: Option<Box<Expression>>,
11667    #[serde(default)]
11668    pub params: Vec<Expression>,
11669}
11670
11671/// IndexParameters
11672#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11673#[cfg_attr(feature = "bindings", derive(TS))]
11674pub struct IndexParameters {
11675    #[serde(default)]
11676    pub using: Option<Box<Expression>>,
11677    #[serde(default)]
11678    pub include: Option<Box<Expression>>,
11679    #[serde(default)]
11680    pub columns: Vec<Expression>,
11681    #[serde(default)]
11682    pub with_storage: Option<Box<Expression>>,
11683    #[serde(default)]
11684    pub partition_by: Option<Box<Expression>>,
11685    #[serde(default)]
11686    pub tablespace: Option<Box<Expression>>,
11687    #[serde(default)]
11688    pub where_: Option<Box<Expression>>,
11689    #[serde(default)]
11690    pub on: Option<Box<Expression>>,
11691}
11692
11693/// ConditionalInsert
11694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11695#[cfg_attr(feature = "bindings", derive(TS))]
11696pub struct ConditionalInsert {
11697    pub this: Box<Expression>,
11698    #[serde(default)]
11699    pub expression: Option<Box<Expression>>,
11700    #[serde(default)]
11701    pub else_: Option<Box<Expression>>,
11702}
11703
11704/// MultitableInserts
11705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11706#[cfg_attr(feature = "bindings", derive(TS))]
11707pub struct MultitableInserts {
11708    #[serde(default)]
11709    pub expressions: Vec<Expression>,
11710    pub kind: String,
11711    #[serde(default)]
11712    pub source: Option<Box<Expression>>,
11713    /// Leading comments before the statement
11714    #[serde(default)]
11715    pub leading_comments: Vec<String>,
11716    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
11717    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11718    pub overwrite: bool,
11719}
11720
11721/// OnConflict
11722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11723#[cfg_attr(feature = "bindings", derive(TS))]
11724pub struct OnConflict {
11725    #[serde(default)]
11726    pub duplicate: Option<Box<Expression>>,
11727    #[serde(default)]
11728    pub expressions: Vec<Expression>,
11729    #[serde(default)]
11730    pub action: Option<Box<Expression>>,
11731    #[serde(default)]
11732    pub conflict_keys: Option<Box<Expression>>,
11733    #[serde(default)]
11734    pub index_predicate: Option<Box<Expression>>,
11735    #[serde(default)]
11736    pub constraint: Option<Box<Expression>>,
11737    #[serde(default)]
11738    pub where_: Option<Box<Expression>>,
11739}
11740
11741/// OnCondition
11742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11743#[cfg_attr(feature = "bindings", derive(TS))]
11744pub struct OnCondition {
11745    #[serde(default)]
11746    pub error: Option<Box<Expression>>,
11747    #[serde(default)]
11748    pub empty: Option<Box<Expression>>,
11749    #[serde(default)]
11750    pub null: Option<Box<Expression>>,
11751}
11752
11753/// Returning
11754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11755#[cfg_attr(feature = "bindings", derive(TS))]
11756pub struct Returning {
11757    #[serde(default)]
11758    pub expressions: Vec<Expression>,
11759    #[serde(default)]
11760    pub into: Option<Box<Expression>>,
11761}
11762
11763/// Introducer
11764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11765#[cfg_attr(feature = "bindings", derive(TS))]
11766pub struct Introducer {
11767    pub this: Box<Expression>,
11768    pub expression: Box<Expression>,
11769}
11770
11771/// PartitionRange
11772#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11773#[cfg_attr(feature = "bindings", derive(TS))]
11774pub struct PartitionRange {
11775    pub this: Box<Expression>,
11776    #[serde(default)]
11777    pub expression: Option<Box<Expression>>,
11778    #[serde(default)]
11779    pub expressions: Vec<Expression>,
11780}
11781
11782/// Group
11783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11784#[cfg_attr(feature = "bindings", derive(TS))]
11785pub struct Group {
11786    #[serde(default)]
11787    pub expressions: Vec<Expression>,
11788    #[serde(default)]
11789    pub grouping_sets: Option<Box<Expression>>,
11790    #[serde(default)]
11791    pub cube: Option<Box<Expression>>,
11792    #[serde(default)]
11793    pub rollup: Option<Box<Expression>>,
11794    #[serde(default)]
11795    pub totals: Option<Box<Expression>>,
11796    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11797    #[serde(default)]
11798    pub all: Option<bool>,
11799}
11800
11801/// Cube
11802#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11803#[cfg_attr(feature = "bindings", derive(TS))]
11804pub struct Cube {
11805    /// Selection, subtotal, and result-delivery options for this grouping operation.
11806    #[serde(default, skip_serializing_if = "Option::is_none")]
11807    pub options: Option<GroupingOptions>,
11808    #[serde(default)]
11809    pub expressions: Vec<Expression>,
11810}
11811
11812/// Rollup
11813#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11814#[cfg_attr(feature = "bindings", derive(TS))]
11815pub struct Rollup {
11816    /// Selection, subtotal, and result-delivery options for this grouping operation.
11817    #[serde(default, skip_serializing_if = "Option::is_none")]
11818    pub options: Option<GroupingOptions>,
11819    #[serde(default)]
11820    pub expressions: Vec<Expression>,
11821}
11822
11823/// GroupingSets
11824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11825#[cfg_attr(feature = "bindings", derive(TS))]
11826pub struct GroupingSets {
11827    /// Selection, subtotal, and result-delivery options for this grouping operation.
11828    #[serde(default, skip_serializing_if = "Option::is_none")]
11829    pub options: Option<GroupingOptions>,
11830    #[serde(default)]
11831    pub expressions: Vec<Expression>,
11832}
11833
11834/// LimitOptions
11835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11836#[cfg_attr(feature = "bindings", derive(TS))]
11837pub struct LimitOptions {
11838    #[serde(default)]
11839    pub percent: Option<Box<Expression>>,
11840    #[serde(default)]
11841    pub rows: Option<Box<Expression>>,
11842    #[serde(default)]
11843    pub with_ties: Option<Box<Expression>>,
11844}
11845
11846/// Lateral
11847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11848#[cfg_attr(feature = "bindings", derive(TS))]
11849pub struct Lateral {
11850    pub this: Box<Expression>,
11851    #[serde(default)]
11852    pub view: Option<Box<Expression>>,
11853    #[serde(default)]
11854    pub outer: Option<Box<Expression>>,
11855    #[serde(default)]
11856    pub alias: Option<String>,
11857    /// Whether the alias was originally quoted (backtick/double-quote)
11858    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11859    pub alias_quoted: bool,
11860    #[serde(default)]
11861    pub cross_apply: Option<Box<Expression>>,
11862    #[serde(default)]
11863    pub ordinality: Option<Box<Expression>>,
11864    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11865    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11866    pub column_aliases: Vec<String>,
11867    /// Quoting of each column alias, parallel to `column_aliases`.
11868    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11869    pub column_aliases_quoted: Vec<bool>,
11870}
11871
11872/// TableFromRows
11873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11874#[cfg_attr(feature = "bindings", derive(TS))]
11875pub struct TableFromRows {
11876    pub this: Box<Expression>,
11877    #[serde(default)]
11878    pub alias: Option<String>,
11879    #[serde(default)]
11880    pub joins: Vec<Expression>,
11881    #[serde(default)]
11882    pub pivots: Option<Box<Expression>>,
11883    #[serde(default)]
11884    pub sample: Option<Box<Expression>>,
11885}
11886
11887/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11888/// Used for set-returning functions with typed column definitions
11889#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11890#[cfg_attr(feature = "bindings", derive(TS))]
11891pub struct RowsFrom {
11892    /// List of function expressions, each potentially with an alias and typed columns
11893    pub expressions: Vec<Expression>,
11894    /// WITH ORDINALITY modifier
11895    #[serde(default)]
11896    pub ordinality: bool,
11897    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11898    #[serde(default)]
11899    pub alias: Option<Box<Expression>>,
11900}
11901
11902/// WithFill
11903#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11904#[cfg_attr(feature = "bindings", derive(TS))]
11905pub struct WithFill {
11906    #[serde(default)]
11907    pub from_: Option<Box<Expression>>,
11908    #[serde(default)]
11909    pub to: Option<Box<Expression>>,
11910    #[serde(default)]
11911    pub step: Option<Box<Expression>>,
11912    #[serde(default)]
11913    pub staleness: Option<Box<Expression>>,
11914    #[serde(default)]
11915    pub interpolate: Option<Box<Expression>>,
11916}
11917
11918/// Property
11919#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11920#[cfg_attr(feature = "bindings", derive(TS))]
11921pub struct Property {
11922    pub this: Box<Expression>,
11923    #[serde(default)]
11924    pub value: Option<Box<Expression>>,
11925}
11926
11927/// GrantPrivilege
11928#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11929#[cfg_attr(feature = "bindings", derive(TS))]
11930pub struct GrantPrivilege {
11931    pub this: Box<Expression>,
11932    #[serde(default)]
11933    pub expressions: Vec<Expression>,
11934}
11935
11936/// AllowedValuesProperty
11937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11938#[cfg_attr(feature = "bindings", derive(TS))]
11939pub struct AllowedValuesProperty {
11940    #[serde(default)]
11941    pub expressions: Vec<Expression>,
11942}
11943
11944/// AlgorithmProperty
11945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11946#[cfg_attr(feature = "bindings", derive(TS))]
11947pub struct AlgorithmProperty {
11948    pub this: Box<Expression>,
11949}
11950
11951/// AutoIncrementProperty
11952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11953#[cfg_attr(feature = "bindings", derive(TS))]
11954pub struct AutoIncrementProperty {
11955    pub this: Box<Expression>,
11956}
11957
11958/// AutoRefreshProperty
11959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11960#[cfg_attr(feature = "bindings", derive(TS))]
11961pub struct AutoRefreshProperty {
11962    pub this: Box<Expression>,
11963}
11964
11965/// BackupProperty
11966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11967#[cfg_attr(feature = "bindings", derive(TS))]
11968pub struct BackupProperty {
11969    pub this: Box<Expression>,
11970}
11971
11972/// BuildProperty
11973#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11974#[cfg_attr(feature = "bindings", derive(TS))]
11975pub struct BuildProperty {
11976    pub this: Box<Expression>,
11977}
11978
11979/// BlockCompressionProperty
11980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11981#[cfg_attr(feature = "bindings", derive(TS))]
11982pub struct BlockCompressionProperty {
11983    #[serde(default)]
11984    pub autotemp: Option<Box<Expression>>,
11985    #[serde(default)]
11986    pub always: Option<Box<Expression>>,
11987    #[serde(default)]
11988    pub default: Option<Box<Expression>>,
11989    #[serde(default)]
11990    pub manual: Option<Box<Expression>>,
11991    #[serde(default)]
11992    pub never: Option<Box<Expression>>,
11993}
11994
11995/// CharacterSetProperty
11996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11997#[cfg_attr(feature = "bindings", derive(TS))]
11998pub struct CharacterSetProperty {
11999    pub this: Box<Expression>,
12000    #[serde(default)]
12001    pub default: Option<Box<Expression>>,
12002}
12003
12004/// ChecksumProperty
12005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12006#[cfg_attr(feature = "bindings", derive(TS))]
12007pub struct ChecksumProperty {
12008    #[serde(default)]
12009    pub on: Option<Box<Expression>>,
12010    #[serde(default)]
12011    pub default: Option<Box<Expression>>,
12012}
12013
12014/// CollateProperty
12015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12016#[cfg_attr(feature = "bindings", derive(TS))]
12017pub struct CollateProperty {
12018    pub this: Box<Expression>,
12019    #[serde(default)]
12020    pub default: Option<Box<Expression>>,
12021}
12022
12023/// DataBlocksizeProperty
12024#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12025#[cfg_attr(feature = "bindings", derive(TS))]
12026pub struct DataBlocksizeProperty {
12027    #[serde(default)]
12028    pub size: Option<i64>,
12029    #[serde(default)]
12030    pub units: Option<Box<Expression>>,
12031    #[serde(default)]
12032    pub minimum: Option<Box<Expression>>,
12033    #[serde(default)]
12034    pub maximum: Option<Box<Expression>>,
12035    #[serde(default)]
12036    pub default: Option<Box<Expression>>,
12037}
12038
12039/// DataDeletionProperty
12040#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12041#[cfg_attr(feature = "bindings", derive(TS))]
12042pub struct DataDeletionProperty {
12043    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
12044    #[ast(skip)]
12045    pub on: Box<Expression>,
12046    #[serde(default)]
12047    pub filter_column: Option<Box<Expression>>,
12048    #[serde(default)]
12049    pub retention_period: Option<Box<Expression>>,
12050}
12051
12052/// DefinerProperty
12053#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12054#[cfg_attr(feature = "bindings", derive(TS))]
12055pub struct DefinerProperty {
12056    pub this: Box<Expression>,
12057}
12058
12059/// DistKeyProperty
12060#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12061#[cfg_attr(feature = "bindings", derive(TS))]
12062pub struct DistKeyProperty {
12063    pub this: Box<Expression>,
12064}
12065
12066/// DistributedByProperty
12067#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12068#[cfg_attr(feature = "bindings", derive(TS))]
12069pub struct DistributedByProperty {
12070    #[serde(default)]
12071    pub expressions: Vec<Expression>,
12072    pub kind: String,
12073    #[serde(default)]
12074    pub buckets: Option<Box<Expression>>,
12075    #[serde(default)]
12076    pub order: Option<Box<Expression>>,
12077}
12078
12079/// DistStyleProperty
12080#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12081#[cfg_attr(feature = "bindings", derive(TS))]
12082pub struct DistStyleProperty {
12083    pub this: Box<Expression>,
12084}
12085
12086/// DuplicateKeyProperty
12087#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12088#[cfg_attr(feature = "bindings", derive(TS))]
12089pub struct DuplicateKeyProperty {
12090    #[serde(default)]
12091    pub expressions: Vec<Expression>,
12092}
12093
12094/// EngineProperty
12095#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12096#[cfg_attr(feature = "bindings", derive(TS))]
12097pub struct EngineProperty {
12098    pub this: Box<Expression>,
12099}
12100
12101/// ToTableProperty
12102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12103#[cfg_attr(feature = "bindings", derive(TS))]
12104pub struct ToTableProperty {
12105    pub this: Box<Expression>,
12106}
12107
12108/// ExecuteAsProperty
12109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12110#[cfg_attr(feature = "bindings", derive(TS))]
12111pub struct ExecuteAsProperty {
12112    pub this: Box<Expression>,
12113}
12114
12115/// ExternalProperty
12116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12117#[cfg_attr(feature = "bindings", derive(TS))]
12118pub struct ExternalProperty {
12119    #[serde(default)]
12120    pub this: Option<Box<Expression>>,
12121}
12122
12123/// FallbackProperty
12124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12125#[cfg_attr(feature = "bindings", derive(TS))]
12126pub struct FallbackProperty {
12127    #[serde(default)]
12128    pub no: Option<Box<Expression>>,
12129    #[serde(default)]
12130    pub protection: Option<Box<Expression>>,
12131}
12132
12133/// FileFormatProperty
12134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12135#[cfg_attr(feature = "bindings", derive(TS))]
12136pub struct FileFormatProperty {
12137    #[serde(default)]
12138    pub this: Option<Box<Expression>>,
12139    #[serde(default)]
12140    pub expressions: Vec<Expression>,
12141    #[serde(default)]
12142    pub hive_format: Option<Box<Expression>>,
12143}
12144
12145/// CredentialsProperty
12146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12147#[cfg_attr(feature = "bindings", derive(TS))]
12148pub struct CredentialsProperty {
12149    #[serde(default)]
12150    pub expressions: Vec<Expression>,
12151}
12152
12153/// FreespaceProperty
12154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12155#[cfg_attr(feature = "bindings", derive(TS))]
12156pub struct FreespaceProperty {
12157    pub this: Box<Expression>,
12158    #[serde(default)]
12159    pub percent: Option<Box<Expression>>,
12160}
12161
12162/// InheritsProperty
12163#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12164#[cfg_attr(feature = "bindings", derive(TS))]
12165pub struct InheritsProperty {
12166    #[serde(default)]
12167    pub expressions: Vec<Expression>,
12168}
12169
12170/// InputModelProperty
12171#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12172#[cfg_attr(feature = "bindings", derive(TS))]
12173pub struct InputModelProperty {
12174    pub this: Box<Expression>,
12175}
12176
12177/// OutputModelProperty
12178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12179#[cfg_attr(feature = "bindings", derive(TS))]
12180pub struct OutputModelProperty {
12181    pub this: Box<Expression>,
12182}
12183
12184/// IsolatedLoadingProperty
12185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12186#[cfg_attr(feature = "bindings", derive(TS))]
12187pub struct IsolatedLoadingProperty {
12188    #[serde(default)]
12189    pub no: Option<Box<Expression>>,
12190    #[serde(default)]
12191    pub concurrent: Option<Box<Expression>>,
12192    #[serde(default)]
12193    pub target: Option<Box<Expression>>,
12194}
12195
12196/// JournalProperty
12197#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12198#[cfg_attr(feature = "bindings", derive(TS))]
12199pub struct JournalProperty {
12200    #[serde(default)]
12201    pub no: Option<Box<Expression>>,
12202    #[serde(default)]
12203    pub dual: Option<Box<Expression>>,
12204    #[serde(default)]
12205    pub before: Option<Box<Expression>>,
12206    #[serde(default)]
12207    pub local: Option<Box<Expression>>,
12208    #[serde(default)]
12209    pub after: Option<Box<Expression>>,
12210}
12211
12212/// LanguageProperty
12213#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12214#[cfg_attr(feature = "bindings", derive(TS))]
12215pub struct LanguageProperty {
12216    pub this: Box<Expression>,
12217}
12218
12219/// EnviromentProperty
12220#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12221#[cfg_attr(feature = "bindings", derive(TS))]
12222pub struct EnviromentProperty {
12223    #[serde(default)]
12224    pub expressions: Vec<Expression>,
12225}
12226
12227/// ClusteredByProperty
12228#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12229#[cfg_attr(feature = "bindings", derive(TS))]
12230pub struct ClusteredByProperty {
12231    #[serde(default)]
12232    pub expressions: Vec<Expression>,
12233    #[serde(default)]
12234    pub sorted_by: Option<Box<Expression>>,
12235    #[serde(default)]
12236    pub buckets: Option<Box<Expression>>,
12237}
12238
12239/// DictProperty
12240#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12241#[cfg_attr(feature = "bindings", derive(TS))]
12242pub struct DictProperty {
12243    pub this: Box<Expression>,
12244    pub kind: String,
12245    #[serde(default)]
12246    pub settings: Option<Box<Expression>>,
12247}
12248
12249/// DictRange
12250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12251#[cfg_attr(feature = "bindings", derive(TS))]
12252pub struct DictRange {
12253    pub this: Box<Expression>,
12254    #[serde(default)]
12255    pub min: Option<Box<Expression>>,
12256    #[serde(default)]
12257    pub max: Option<Box<Expression>>,
12258}
12259
12260/// OnCluster
12261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12262#[cfg_attr(feature = "bindings", derive(TS))]
12263pub struct OnCluster {
12264    pub this: Box<Expression>,
12265}
12266
12267/// LikeProperty
12268#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12269#[cfg_attr(feature = "bindings", derive(TS))]
12270pub struct LikeProperty {
12271    pub this: Box<Expression>,
12272    #[serde(default)]
12273    pub expressions: Vec<Expression>,
12274}
12275
12276/// LocationProperty
12277#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12278#[cfg_attr(feature = "bindings", derive(TS))]
12279pub struct LocationProperty {
12280    pub this: Box<Expression>,
12281}
12282
12283/// LockProperty
12284#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12285#[cfg_attr(feature = "bindings", derive(TS))]
12286pub struct LockProperty {
12287    pub this: Box<Expression>,
12288}
12289
12290/// LockingProperty
12291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12292#[cfg_attr(feature = "bindings", derive(TS))]
12293pub struct LockingProperty {
12294    #[serde(default)]
12295    pub this: Option<Box<Expression>>,
12296    pub kind: String,
12297    #[serde(default)]
12298    pub for_or_in: Option<Box<Expression>>,
12299    #[serde(default)]
12300    pub lock_type: Option<Box<Expression>>,
12301    #[serde(default)]
12302    pub override_: Option<Box<Expression>>,
12303}
12304
12305/// LogProperty
12306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12307#[cfg_attr(feature = "bindings", derive(TS))]
12308pub struct LogProperty {
12309    #[serde(default)]
12310    pub no: Option<Box<Expression>>,
12311}
12312
12313/// MaterializedProperty
12314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12315#[cfg_attr(feature = "bindings", derive(TS))]
12316pub struct MaterializedProperty {
12317    #[serde(default)]
12318    pub this: Option<Box<Expression>>,
12319}
12320
12321/// MergeBlockRatioProperty
12322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12323#[cfg_attr(feature = "bindings", derive(TS))]
12324pub struct MergeBlockRatioProperty {
12325    #[serde(default)]
12326    pub this: Option<Box<Expression>>,
12327    #[serde(default)]
12328    pub no: Option<Box<Expression>>,
12329    #[serde(default)]
12330    pub default: Option<Box<Expression>>,
12331    #[serde(default)]
12332    pub percent: Option<Box<Expression>>,
12333}
12334
12335/// OnProperty
12336#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12337#[cfg_attr(feature = "bindings", derive(TS))]
12338pub struct OnProperty {
12339    pub this: Box<Expression>,
12340}
12341
12342/// OnCommitProperty
12343#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12344#[cfg_attr(feature = "bindings", derive(TS))]
12345pub struct OnCommitProperty {
12346    #[serde(default)]
12347    pub delete: Option<Box<Expression>>,
12348}
12349
12350/// PartitionedByProperty
12351#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12352#[cfg_attr(feature = "bindings", derive(TS))]
12353pub struct PartitionedByProperty {
12354    pub this: Box<Expression>,
12355}
12356
12357/// BigQuery PARTITION BY property in CREATE TABLE statements.
12358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12359#[cfg_attr(feature = "bindings", derive(TS))]
12360pub struct PartitionByProperty {
12361    /// Structured partition scheme when the dialect supports methods and ranges.
12362    #[serde(default, skip_serializing_if = "Option::is_none")]
12363    pub specification: Option<PartitionSpec>,
12364    #[serde(default)]
12365    pub expressions: Vec<Expression>,
12366}
12367
12368/// PartitionedByBucket
12369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12370#[cfg_attr(feature = "bindings", derive(TS))]
12371pub struct PartitionedByBucket {
12372    pub this: Box<Expression>,
12373    pub expression: Box<Expression>,
12374}
12375
12376/// BigQuery CLUSTER BY property in CREATE TABLE statements.
12377#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12378#[cfg_attr(feature = "bindings", derive(TS))]
12379pub struct ClusterByColumnsProperty {
12380    #[serde(default)]
12381    pub columns: Vec<Identifier>,
12382}
12383
12384/// PartitionByTruncate
12385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12386#[cfg_attr(feature = "bindings", derive(TS))]
12387pub struct PartitionByTruncate {
12388    pub this: Box<Expression>,
12389    pub expression: Box<Expression>,
12390}
12391
12392/// PartitionByRangeProperty
12393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12394#[cfg_attr(feature = "bindings", derive(TS))]
12395pub struct PartitionByRangeProperty {
12396    #[serde(default)]
12397    pub partition_expressions: Option<Box<Expression>>,
12398    #[serde(default)]
12399    pub create_expressions: Option<Box<Expression>>,
12400}
12401
12402/// PartitionByRangePropertyDynamic
12403#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12404#[cfg_attr(feature = "bindings", derive(TS))]
12405pub struct PartitionByRangePropertyDynamic {
12406    #[serde(default)]
12407    pub this: Option<Box<Expression>>,
12408    #[serde(default)]
12409    pub start: Option<Box<Expression>>,
12410    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
12411    #[serde(default)]
12412    pub use_start_end: bool,
12413    #[serde(default)]
12414    pub end: Option<Box<Expression>>,
12415    #[serde(default)]
12416    pub every: Option<Box<Expression>>,
12417}
12418
12419/// PartitionByListProperty
12420#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12421#[cfg_attr(feature = "bindings", derive(TS))]
12422pub struct PartitionByListProperty {
12423    #[serde(default)]
12424    pub partition_expressions: Option<Box<Expression>>,
12425    #[serde(default)]
12426    pub create_expressions: Option<Box<Expression>>,
12427}
12428
12429/// PartitionList
12430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12431#[cfg_attr(feature = "bindings", derive(TS))]
12432pub struct PartitionList {
12433    pub this: Box<Expression>,
12434    #[serde(default)]
12435    pub expressions: Vec<Expression>,
12436}
12437
12438/// Partition - represents PARTITION/SUBPARTITION clause
12439#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12440#[cfg_attr(feature = "bindings", derive(TS))]
12441pub struct Partition {
12442    pub expressions: Vec<Expression>,
12443    #[serde(default)]
12444    pub subpartition: bool,
12445}
12446
12447/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
12448/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
12449#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12450#[cfg_attr(feature = "bindings", derive(TS))]
12451pub struct RefreshTriggerProperty {
12452    /// Method: COMPLETE or AUTO
12453    pub method: String,
12454    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
12455    #[serde(default)]
12456    pub kind: Option<String>,
12457    /// For SCHEDULE: EVERY n (the number)
12458    #[serde(default)]
12459    pub every: Option<Box<Expression>>,
12460    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
12461    #[serde(default)]
12462    pub unit: Option<String>,
12463    /// For SCHEDULE: STARTS 'datetime'
12464    #[serde(default)]
12465    pub starts: Option<Box<Expression>>,
12466}
12467
12468/// UniqueKeyProperty
12469#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12470#[cfg_attr(feature = "bindings", derive(TS))]
12471pub struct UniqueKeyProperty {
12472    #[serde(default)]
12473    pub expressions: Vec<Expression>,
12474}
12475
12476/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
12477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12478#[cfg_attr(feature = "bindings", derive(TS))]
12479pub struct RollupProperty {
12480    pub expressions: Vec<RollupIndex>,
12481}
12482
12483/// RollupIndex - A single rollup index: name(col1, col2)
12484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12485#[cfg_attr(feature = "bindings", derive(TS))]
12486pub struct RollupIndex {
12487    pub name: Identifier,
12488    pub expressions: Vec<Identifier>,
12489}
12490
12491/// PartitionBoundSpec
12492#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12493#[cfg_attr(feature = "bindings", derive(TS))]
12494pub struct PartitionBoundSpec {
12495    #[serde(default)]
12496    pub this: Option<Box<Expression>>,
12497    #[serde(default)]
12498    pub expression: Option<Box<Expression>>,
12499    #[serde(default)]
12500    pub from_expressions: Option<Box<Expression>>,
12501    #[serde(default)]
12502    pub to_expressions: Option<Box<Expression>>,
12503}
12504
12505/// PartitionedOfProperty
12506#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12507#[cfg_attr(feature = "bindings", derive(TS))]
12508pub struct PartitionedOfProperty {
12509    pub this: Box<Expression>,
12510    pub expression: Box<Expression>,
12511}
12512
12513/// RemoteWithConnectionModelProperty
12514#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12515#[cfg_attr(feature = "bindings", derive(TS))]
12516pub struct RemoteWithConnectionModelProperty {
12517    pub this: Box<Expression>,
12518}
12519
12520/// ReturnsProperty
12521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12522#[cfg_attr(feature = "bindings", derive(TS))]
12523pub struct ReturnsProperty {
12524    #[serde(default)]
12525    pub this: Option<Box<Expression>>,
12526    #[serde(default)]
12527    pub is_table: Option<Box<Expression>>,
12528    #[serde(default)]
12529    pub table: Option<Box<Expression>>,
12530    #[serde(default)]
12531    pub null: Option<Box<Expression>>,
12532}
12533
12534/// RowFormatProperty
12535#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12536#[cfg_attr(feature = "bindings", derive(TS))]
12537pub struct RowFormatProperty {
12538    pub this: Box<Expression>,
12539}
12540
12541/// RowFormatDelimitedProperty
12542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12543#[cfg_attr(feature = "bindings", derive(TS))]
12544pub struct RowFormatDelimitedProperty {
12545    #[serde(default)]
12546    pub fields: Option<Box<Expression>>,
12547    #[serde(default)]
12548    pub escaped: Option<Box<Expression>>,
12549    #[serde(default)]
12550    pub collection_items: Option<Box<Expression>>,
12551    #[serde(default)]
12552    pub map_keys: Option<Box<Expression>>,
12553    #[serde(default)]
12554    pub lines: Option<Box<Expression>>,
12555    #[serde(default)]
12556    pub null: Option<Box<Expression>>,
12557    #[serde(default)]
12558    pub serde: Option<Box<Expression>>,
12559}
12560
12561/// RowFormatSerdeProperty
12562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12563#[cfg_attr(feature = "bindings", derive(TS))]
12564pub struct RowFormatSerdeProperty {
12565    pub this: Box<Expression>,
12566    #[serde(default)]
12567    pub serde_properties: Option<Box<Expression>>,
12568}
12569
12570/// QueryTransform
12571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12572#[cfg_attr(feature = "bindings", derive(TS))]
12573pub struct QueryTransform {
12574    #[serde(default)]
12575    pub expressions: Vec<Expression>,
12576    #[serde(default)]
12577    pub command_script: Option<Box<Expression>>,
12578    #[serde(default)]
12579    pub schema: Option<Box<Expression>>,
12580    #[serde(default)]
12581    pub row_format_before: Option<Box<Expression>>,
12582    #[serde(default)]
12583    pub record_writer: Option<Box<Expression>>,
12584    #[serde(default)]
12585    pub row_format_after: Option<Box<Expression>>,
12586    #[serde(default)]
12587    pub record_reader: Option<Box<Expression>>,
12588}
12589
12590/// SampleProperty
12591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12592#[cfg_attr(feature = "bindings", derive(TS))]
12593pub struct SampleProperty {
12594    pub this: Box<Expression>,
12595}
12596
12597/// SecurityProperty
12598#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12599#[cfg_attr(feature = "bindings", derive(TS))]
12600pub struct SecurityProperty {
12601    pub this: Box<Expression>,
12602}
12603
12604/// SchemaCommentProperty
12605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12606#[cfg_attr(feature = "bindings", derive(TS))]
12607pub struct SchemaCommentProperty {
12608    pub this: Box<Expression>,
12609}
12610
12611/// SemanticView
12612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12613#[cfg_attr(feature = "bindings", derive(TS))]
12614pub struct SemanticView {
12615    pub this: Box<Expression>,
12616    #[serde(default)]
12617    pub metrics: Option<Box<Expression>>,
12618    #[serde(default)]
12619    pub dimensions: Option<Box<Expression>>,
12620    #[serde(default)]
12621    pub facts: Option<Box<Expression>>,
12622    #[serde(default)]
12623    pub where_: Option<Box<Expression>>,
12624}
12625
12626/// SerdeProperties
12627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12628#[cfg_attr(feature = "bindings", derive(TS))]
12629pub struct SerdeProperties {
12630    #[serde(default)]
12631    pub expressions: Vec<Expression>,
12632    #[serde(default)]
12633    pub with_: Option<Box<Expression>>,
12634}
12635
12636/// SetProperty
12637#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12638#[cfg_attr(feature = "bindings", derive(TS))]
12639pub struct SetProperty {
12640    #[serde(default)]
12641    pub multi: Option<Box<Expression>>,
12642}
12643
12644/// SharingProperty
12645#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12646#[cfg_attr(feature = "bindings", derive(TS))]
12647pub struct SharingProperty {
12648    #[serde(default)]
12649    pub this: Option<Box<Expression>>,
12650}
12651
12652/// SetConfigProperty
12653#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12654#[cfg_attr(feature = "bindings", derive(TS))]
12655pub struct SetConfigProperty {
12656    pub this: Box<Expression>,
12657}
12658
12659/// SettingsProperty
12660#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12661#[cfg_attr(feature = "bindings", derive(TS))]
12662pub struct SettingsProperty {
12663    #[serde(default)]
12664    pub expressions: Vec<Expression>,
12665}
12666
12667/// SortKeyProperty
12668#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12669#[cfg_attr(feature = "bindings", derive(TS))]
12670pub struct SortKeyProperty {
12671    pub this: Box<Expression>,
12672    #[serde(default)]
12673    pub compound: Option<Box<Expression>>,
12674}
12675
12676/// SqlReadWriteProperty
12677#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12678#[cfg_attr(feature = "bindings", derive(TS))]
12679pub struct SqlReadWriteProperty {
12680    pub this: Box<Expression>,
12681}
12682
12683/// SqlSecurityProperty
12684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12685#[cfg_attr(feature = "bindings", derive(TS))]
12686pub struct SqlSecurityProperty {
12687    pub this: Box<Expression>,
12688}
12689
12690/// StabilityProperty
12691#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12692#[cfg_attr(feature = "bindings", derive(TS))]
12693pub struct StabilityProperty {
12694    pub this: Box<Expression>,
12695}
12696
12697/// StorageHandlerProperty
12698#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12699#[cfg_attr(feature = "bindings", derive(TS))]
12700pub struct StorageHandlerProperty {
12701    pub this: Box<Expression>,
12702}
12703
12704/// TemporaryProperty
12705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12706#[cfg_attr(feature = "bindings", derive(TS))]
12707pub struct TemporaryProperty {
12708    #[serde(default)]
12709    pub this: Option<Box<Expression>>,
12710}
12711
12712/// Tags
12713#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12714#[cfg_attr(feature = "bindings", derive(TS))]
12715pub struct Tags {
12716    #[serde(default)]
12717    pub expressions: Vec<Expression>,
12718}
12719
12720/// TransformModelProperty
12721#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12722#[cfg_attr(feature = "bindings", derive(TS))]
12723pub struct TransformModelProperty {
12724    #[serde(default)]
12725    pub expressions: Vec<Expression>,
12726}
12727
12728/// TransientProperty
12729#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12730#[cfg_attr(feature = "bindings", derive(TS))]
12731pub struct TransientProperty {
12732    #[serde(default)]
12733    pub this: Option<Box<Expression>>,
12734}
12735
12736/// UsingTemplateProperty
12737#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12738#[cfg_attr(feature = "bindings", derive(TS))]
12739pub struct UsingTemplateProperty {
12740    pub this: Box<Expression>,
12741}
12742
12743/// ViewAttributeProperty
12744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12745#[cfg_attr(feature = "bindings", derive(TS))]
12746pub struct ViewAttributeProperty {
12747    pub this: Box<Expression>,
12748}
12749
12750/// VolatileProperty
12751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12752#[cfg_attr(feature = "bindings", derive(TS))]
12753pub struct VolatileProperty {
12754    #[serde(default)]
12755    pub this: Option<Box<Expression>>,
12756}
12757
12758/// WithDataProperty
12759#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12760#[cfg_attr(feature = "bindings", derive(TS))]
12761pub struct WithDataProperty {
12762    #[serde(default)]
12763    pub no: Option<Box<Expression>>,
12764    #[serde(default)]
12765    pub statistics: Option<Box<Expression>>,
12766}
12767
12768/// WithJournalTableProperty
12769#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12770#[cfg_attr(feature = "bindings", derive(TS))]
12771pub struct WithJournalTableProperty {
12772    pub this: Box<Expression>,
12773}
12774
12775/// WithSchemaBindingProperty
12776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12777#[cfg_attr(feature = "bindings", derive(TS))]
12778pub struct WithSchemaBindingProperty {
12779    pub this: Box<Expression>,
12780}
12781
12782/// WithSystemVersioningProperty
12783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12784#[cfg_attr(feature = "bindings", derive(TS))]
12785pub struct WithSystemVersioningProperty {
12786    #[serde(default)]
12787    pub on: Option<Box<Expression>>,
12788    #[serde(default)]
12789    pub this: Option<Box<Expression>>,
12790    #[serde(default)]
12791    pub data_consistency: Option<Box<Expression>>,
12792    #[serde(default)]
12793    pub retention_period: Option<Box<Expression>>,
12794    #[serde(default)]
12795    pub with_: Option<Box<Expression>>,
12796}
12797
12798/// WithProcedureOptions
12799#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12800#[cfg_attr(feature = "bindings", derive(TS))]
12801pub struct WithProcedureOptions {
12802    #[serde(default)]
12803    pub expressions: Vec<Expression>,
12804}
12805
12806/// EncodeProperty
12807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12808#[cfg_attr(feature = "bindings", derive(TS))]
12809pub struct EncodeProperty {
12810    pub this: Box<Expression>,
12811    #[serde(default)]
12812    pub properties: Vec<Expression>,
12813    #[serde(default)]
12814    pub key: Option<Box<Expression>>,
12815}
12816
12817/// IncludeProperty
12818#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12819#[cfg_attr(feature = "bindings", derive(TS))]
12820pub struct IncludeProperty {
12821    pub this: Box<Expression>,
12822    #[serde(default)]
12823    pub alias: Option<String>,
12824    #[serde(default)]
12825    pub column_def: Option<Box<Expression>>,
12826}
12827
12828/// Properties
12829#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12830#[cfg_attr(feature = "bindings", derive(TS))]
12831pub struct Properties {
12832    #[serde(default)]
12833    pub expressions: Vec<Expression>,
12834}
12835
12836/// Key/value pair in a BigQuery OPTIONS (...) clause.
12837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12838#[cfg_attr(feature = "bindings", derive(TS))]
12839pub struct OptionEntry {
12840    pub key: Identifier,
12841    pub value: Expression,
12842}
12843
12844/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12845#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12846#[cfg_attr(feature = "bindings", derive(TS))]
12847pub struct OptionsProperty {
12848    #[serde(default)]
12849    pub entries: Vec<OptionEntry>,
12850}
12851
12852/// InputOutputFormat
12853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12854#[cfg_attr(feature = "bindings", derive(TS))]
12855pub struct InputOutputFormat {
12856    #[serde(default)]
12857    pub input_format: Option<Box<Expression>>,
12858    #[serde(default)]
12859    pub output_format: Option<Box<Expression>>,
12860}
12861
12862/// Reference
12863#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12864#[cfg_attr(feature = "bindings", derive(TS))]
12865pub struct Reference {
12866    pub this: Box<Expression>,
12867    #[serde(default)]
12868    pub expressions: Vec<Expression>,
12869    #[serde(default)]
12870    pub options: Vec<Expression>,
12871}
12872
12873/// QueryOption
12874#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12875#[cfg_attr(feature = "bindings", derive(TS))]
12876pub struct QueryOption {
12877    pub this: Box<Expression>,
12878    #[serde(default)]
12879    pub expression: Option<Box<Expression>>,
12880}
12881
12882/// WithTableHint
12883#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12884#[cfg_attr(feature = "bindings", derive(TS))]
12885pub struct WithTableHint {
12886    #[serde(default)]
12887    pub expressions: Vec<Expression>,
12888}
12889
12890/// IndexTableHint
12891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12892#[cfg_attr(feature = "bindings", derive(TS))]
12893pub struct IndexTableHint {
12894    pub this: Box<Expression>,
12895    #[serde(default)]
12896    pub expressions: Vec<Expression>,
12897    #[serde(default)]
12898    pub target: Option<Box<Expression>>,
12899}
12900
12901/// Get
12902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12903#[cfg_attr(feature = "bindings", derive(TS))]
12904pub struct Get {
12905    pub this: Box<Expression>,
12906    #[serde(default)]
12907    pub target: Option<Box<Expression>>,
12908    #[serde(default)]
12909    pub properties: Vec<Expression>,
12910}
12911
12912/// SetOperation
12913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12914#[cfg_attr(feature = "bindings", derive(TS))]
12915pub struct SetOperation {
12916    #[serde(default)]
12917    pub with_: Option<Box<Expression>>,
12918    pub this: Box<Expression>,
12919    pub expression: Box<Expression>,
12920    #[serde(default)]
12921    pub distinct: bool,
12922    #[serde(default)]
12923    pub by_name: Option<Box<Expression>>,
12924    #[serde(default)]
12925    pub side: Option<Box<Expression>>,
12926    #[serde(default)]
12927    pub kind: Option<String>,
12928    #[serde(default)]
12929    pub on: Option<Box<Expression>>,
12930}
12931
12932/// Var - Simple variable reference (for SQL variables, keywords as values)
12933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12934#[cfg_attr(feature = "bindings", derive(TS))]
12935pub struct Var {
12936    pub this: String,
12937}
12938
12939/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12940#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12941#[cfg_attr(feature = "bindings", derive(TS))]
12942pub struct Variadic {
12943    pub this: Box<Expression>,
12944}
12945
12946/// Version
12947#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12948#[cfg_attr(feature = "bindings", derive(TS))]
12949pub struct Version {
12950    pub this: Box<Expression>,
12951    pub kind: String,
12952    #[serde(default)]
12953    pub expression: Option<Box<Expression>>,
12954}
12955
12956/// Schema
12957#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12958#[cfg_attr(feature = "bindings", derive(TS))]
12959pub struct Schema {
12960    #[serde(default)]
12961    pub this: Option<Box<Expression>>,
12962    #[serde(default)]
12963    pub expressions: Vec<Expression>,
12964}
12965
12966/// Lock
12967#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12968#[cfg_attr(feature = "bindings", derive(TS))]
12969pub struct Lock {
12970    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
12971    pub ignore_locked: bool,
12972    #[serde(default)]
12973    pub update: Option<Box<Expression>>,
12974    #[serde(default)]
12975    pub expressions: Vec<Expression>,
12976    #[serde(default)]
12977    pub wait: Option<Box<Expression>>,
12978    #[serde(default)]
12979    pub key: Option<Box<Expression>>,
12980}
12981
12982/// TableSample - wraps an expression with a TABLESAMPLE clause
12983/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12985#[cfg_attr(feature = "bindings", derive(TS))]
12986pub struct TableSample {
12987    /// The expression being sampled (subquery, function, etc.)
12988    #[serde(default, skip_serializing_if = "Option::is_none")]
12989    pub this: Option<Box<Expression>>,
12990    /// The sample specification
12991    #[serde(default, skip_serializing_if = "Option::is_none")]
12992    pub sample: Option<Box<Sample>>,
12993    #[serde(default)]
12994    pub expressions: Vec<Expression>,
12995    #[serde(default)]
12996    pub method: Option<String>,
12997    #[serde(default)]
12998    pub bucket_numerator: Option<Box<Expression>>,
12999    #[serde(default)]
13000    pub bucket_denominator: Option<Box<Expression>>,
13001    #[serde(default)]
13002    pub bucket_field: Option<Box<Expression>>,
13003    #[serde(default)]
13004    pub percent: Option<Box<Expression>>,
13005    #[serde(default)]
13006    pub rows: Option<Box<Expression>>,
13007    #[serde(default)]
13008    pub size: Option<i64>,
13009    #[serde(default)]
13010    pub seed: Option<Box<Expression>>,
13011}
13012
13013/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
13014#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13015#[cfg_attr(feature = "bindings", derive(TS))]
13016pub struct Tag {
13017    #[serde(default)]
13018    pub this: Option<Box<Expression>>,
13019    #[serde(default)]
13020    pub prefix: Option<Box<Expression>>,
13021    #[serde(default)]
13022    pub postfix: Option<Box<Expression>>,
13023}
13024
13025/// UnpivotColumns
13026#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13027#[cfg_attr(feature = "bindings", derive(TS))]
13028pub struct UnpivotColumns {
13029    pub this: Box<Expression>,
13030    #[serde(default)]
13031    pub expressions: Vec<Expression>,
13032}
13033
13034/// SessionParameter
13035#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13036#[cfg_attr(feature = "bindings", derive(TS))]
13037pub struct SessionParameter {
13038    pub this: Box<Expression>,
13039    #[serde(default)]
13040    pub kind: Option<String>,
13041}
13042
13043/// PseudoType
13044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13045#[cfg_attr(feature = "bindings", derive(TS))]
13046pub struct PseudoType {
13047    pub this: Box<Expression>,
13048}
13049
13050/// ObjectIdentifier
13051#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13052#[cfg_attr(feature = "bindings", derive(TS))]
13053pub struct ObjectIdentifier {
13054    pub this: Box<Expression>,
13055}
13056
13057/// Transaction
13058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13059#[cfg_attr(feature = "bindings", derive(TS))]
13060pub struct Transaction {
13061    #[serde(default)]
13062    pub this: Option<Box<Expression>>,
13063    #[serde(default)]
13064    pub modes: Option<Box<Expression>>,
13065    #[serde(default)]
13066    pub mark: Option<Box<Expression>>,
13067}
13068
13069/// Commit
13070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13071#[cfg_attr(feature = "bindings", derive(TS))]
13072pub struct Commit {
13073    #[serde(default)]
13074    pub chain: Option<Box<Expression>>,
13075    #[serde(default)]
13076    pub this: Option<Box<Expression>>,
13077    #[serde(default)]
13078    pub durability: Option<Box<Expression>>,
13079}
13080
13081/// Rollback
13082#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13083#[cfg_attr(feature = "bindings", derive(TS))]
13084pub struct Rollback {
13085    #[serde(default)]
13086    pub savepoint: Option<Box<Expression>>,
13087    #[serde(default)]
13088    pub this: Option<Box<Expression>>,
13089}
13090
13091/// AlterSession
13092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13093#[cfg_attr(feature = "bindings", derive(TS))]
13094pub struct AlterSession {
13095    #[serde(default)]
13096    pub expressions: Vec<Expression>,
13097    #[serde(default)]
13098    pub unset: Option<Box<Expression>>,
13099}
13100
13101/// Analyze
13102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13103#[cfg_attr(feature = "bindings", derive(TS))]
13104pub struct Analyze {
13105    #[serde(default)]
13106    pub kind: Option<String>,
13107    #[serde(default)]
13108    pub this: Option<Box<Expression>>,
13109    #[serde(default)]
13110    pub options: Vec<Expression>,
13111    #[serde(default)]
13112    pub mode: Option<Box<Expression>>,
13113    #[serde(default)]
13114    pub partition: Option<Box<Expression>>,
13115    #[serde(default)]
13116    pub expression: Option<Box<Expression>>,
13117    #[serde(default)]
13118    pub properties: Vec<Expression>,
13119    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
13120    #[serde(default, skip_serializing_if = "Vec::is_empty")]
13121    pub columns: Vec<String>,
13122}
13123
13124/// AnalyzeStatistics
13125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13126#[cfg_attr(feature = "bindings", derive(TS))]
13127pub struct AnalyzeStatistics {
13128    pub kind: String,
13129    #[serde(default)]
13130    pub option: Option<Box<Expression>>,
13131    #[serde(default)]
13132    pub this: Option<Box<Expression>>,
13133    #[serde(default)]
13134    pub expressions: Vec<Expression>,
13135}
13136
13137/// AnalyzeHistogram
13138#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13139#[cfg_attr(feature = "bindings", derive(TS))]
13140pub struct AnalyzeHistogram {
13141    pub this: Box<Expression>,
13142    #[serde(default)]
13143    pub expressions: Vec<Expression>,
13144    #[serde(default)]
13145    pub expression: Option<Box<Expression>>,
13146    #[serde(default)]
13147    pub update_options: Option<Box<Expression>>,
13148}
13149
13150/// AnalyzeSample
13151#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13152#[cfg_attr(feature = "bindings", derive(TS))]
13153pub struct AnalyzeSample {
13154    pub kind: String,
13155    #[serde(default)]
13156    pub sample: Option<Box<Expression>>,
13157}
13158
13159/// AnalyzeListChainedRows
13160#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13161#[cfg_attr(feature = "bindings", derive(TS))]
13162pub struct AnalyzeListChainedRows {
13163    #[serde(default)]
13164    pub expression: Option<Box<Expression>>,
13165}
13166
13167/// AnalyzeDelete
13168#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13169#[cfg_attr(feature = "bindings", derive(TS))]
13170pub struct AnalyzeDelete {
13171    #[serde(default)]
13172    pub kind: Option<String>,
13173}
13174
13175/// AnalyzeWith
13176#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13177#[cfg_attr(feature = "bindings", derive(TS))]
13178pub struct AnalyzeWith {
13179    #[serde(default)]
13180    pub expressions: Vec<Expression>,
13181}
13182
13183/// AnalyzeValidate
13184#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13185#[cfg_attr(feature = "bindings", derive(TS))]
13186pub struct AnalyzeValidate {
13187    pub kind: String,
13188    #[serde(default)]
13189    pub this: Option<Box<Expression>>,
13190    #[serde(default)]
13191    pub expression: Option<Box<Expression>>,
13192}
13193
13194/// AddPartition
13195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13196#[cfg_attr(feature = "bindings", derive(TS))]
13197pub struct AddPartition {
13198    pub this: Box<Expression>,
13199    #[serde(default)]
13200    pub exists: bool,
13201    #[serde(default)]
13202    pub location: Option<Box<Expression>>,
13203}
13204
13205/// AttachOption
13206#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13207#[cfg_attr(feature = "bindings", derive(TS))]
13208pub struct AttachOption {
13209    pub this: Box<Expression>,
13210    #[serde(default)]
13211    pub expression: Option<Box<Expression>>,
13212}
13213
13214/// DropPartition
13215#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13216#[cfg_attr(feature = "bindings", derive(TS))]
13217pub struct DropPartition {
13218    #[serde(default)]
13219    pub expressions: Vec<Expression>,
13220    #[serde(default)]
13221    pub exists: bool,
13222}
13223
13224/// ReplacePartition
13225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13226#[cfg_attr(feature = "bindings", derive(TS))]
13227pub struct ReplacePartition {
13228    pub expression: Box<Expression>,
13229    #[serde(default)]
13230    pub source: Option<Box<Expression>>,
13231}
13232
13233/// DPipe
13234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13235#[cfg_attr(feature = "bindings", derive(TS))]
13236pub struct DPipe {
13237    pub this: Box<Expression>,
13238    pub expression: Box<Expression>,
13239    #[serde(default)]
13240    pub safe: Option<Box<Expression>>,
13241}
13242
13243/// Operator
13244#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13245#[cfg_attr(feature = "bindings", derive(TS))]
13246pub struct Operator {
13247    pub this: Box<Expression>,
13248    #[serde(default)]
13249    pub operator: Option<Box<Expression>>,
13250    pub expression: Box<Expression>,
13251    /// Comments between OPERATOR() and the RHS expression
13252    #[serde(default, skip_serializing_if = "Vec::is_empty")]
13253    pub comments: Vec<String>,
13254}
13255
13256/// PivotAny
13257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13258#[cfg_attr(feature = "bindings", derive(TS))]
13259pub struct PivotAny {
13260    #[serde(default)]
13261    pub this: Option<Box<Expression>>,
13262}
13263
13264/// Aliases
13265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13266#[cfg_attr(feature = "bindings", derive(TS))]
13267pub struct Aliases {
13268    pub this: Box<Expression>,
13269    #[serde(default)]
13270    pub expressions: Vec<Expression>,
13271}
13272
13273/// AtIndex
13274#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13275#[cfg_attr(feature = "bindings", derive(TS))]
13276pub struct AtIndex {
13277    pub this: Box<Expression>,
13278    pub expression: Box<Expression>,
13279}
13280
13281/// FromTimeZone
13282#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13283#[cfg_attr(feature = "bindings", derive(TS))]
13284pub struct FromTimeZone {
13285    pub this: Box<Expression>,
13286    #[serde(default)]
13287    pub zone: Option<Box<Expression>>,
13288}
13289
13290/// Format override for a column in Teradata
13291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13292#[cfg_attr(feature = "bindings", derive(TS))]
13293pub struct FormatPhrase {
13294    pub this: Box<Expression>,
13295    pub format: String,
13296}
13297
13298/// ForIn
13299#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13300#[cfg_attr(feature = "bindings", derive(TS))]
13301pub struct ForIn {
13302    pub this: Box<Expression>,
13303    pub expression: Box<Expression>,
13304}
13305
13306/// Automatically converts unit arg into a var.
13307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13308#[cfg_attr(feature = "bindings", derive(TS))]
13309pub struct TimeUnit {
13310    #[serde(default)]
13311    pub unit: Option<String>,
13312}
13313
13314/// IntervalOp
13315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13316#[cfg_attr(feature = "bindings", derive(TS))]
13317pub struct IntervalOp {
13318    #[serde(default)]
13319    pub unit: Option<String>,
13320    pub expression: Box<Expression>,
13321}
13322
13323/// HavingMax
13324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13325#[cfg_attr(feature = "bindings", derive(TS))]
13326pub struct HavingMax {
13327    pub this: Box<Expression>,
13328    pub expression: Box<Expression>,
13329    #[serde(default)]
13330    pub max: Option<Box<Expression>>,
13331}
13332
13333/// CosineDistance
13334#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13335#[cfg_attr(feature = "bindings", derive(TS))]
13336pub struct CosineDistance {
13337    pub this: Box<Expression>,
13338    pub expression: Box<Expression>,
13339}
13340
13341/// DotProduct
13342#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13343#[cfg_attr(feature = "bindings", derive(TS))]
13344pub struct DotProduct {
13345    pub this: Box<Expression>,
13346    pub expression: Box<Expression>,
13347}
13348
13349/// EuclideanDistance
13350#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13351#[cfg_attr(feature = "bindings", derive(TS))]
13352pub struct EuclideanDistance {
13353    pub this: Box<Expression>,
13354    pub expression: Box<Expression>,
13355}
13356
13357/// ManhattanDistance
13358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13359#[cfg_attr(feature = "bindings", derive(TS))]
13360pub struct ManhattanDistance {
13361    pub this: Box<Expression>,
13362    pub expression: Box<Expression>,
13363}
13364
13365/// JarowinklerSimilarity
13366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13367#[cfg_attr(feature = "bindings", derive(TS))]
13368pub struct JarowinklerSimilarity {
13369    pub this: Box<Expression>,
13370    pub expression: Box<Expression>,
13371}
13372
13373/// Booland
13374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13375#[cfg_attr(feature = "bindings", derive(TS))]
13376pub struct Booland {
13377    pub this: Box<Expression>,
13378    pub expression: Box<Expression>,
13379}
13380
13381/// Boolor
13382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13383#[cfg_attr(feature = "bindings", derive(TS))]
13384pub struct Boolor {
13385    pub this: Box<Expression>,
13386    pub expression: Box<Expression>,
13387}
13388
13389/// ParameterizedAgg
13390#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13391#[cfg_attr(feature = "bindings", derive(TS))]
13392pub struct ParameterizedAgg {
13393    pub this: Box<Expression>,
13394    #[serde(default)]
13395    pub expressions: Vec<Expression>,
13396    #[serde(default)]
13397    pub params: Vec<Expression>,
13398}
13399
13400/// ArgMax
13401#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13402#[cfg_attr(feature = "bindings", derive(TS))]
13403pub struct ArgMax {
13404    pub this: Box<Expression>,
13405    pub expression: Box<Expression>,
13406    #[serde(default)]
13407    pub count: Option<Box<Expression>>,
13408}
13409
13410/// ArgMin
13411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13412#[cfg_attr(feature = "bindings", derive(TS))]
13413pub struct ArgMin {
13414    pub this: Box<Expression>,
13415    pub expression: Box<Expression>,
13416    #[serde(default)]
13417    pub count: Option<Box<Expression>>,
13418}
13419
13420/// ApproxTopK
13421#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13422#[cfg_attr(feature = "bindings", derive(TS))]
13423pub struct ApproxTopK {
13424    pub this: Box<Expression>,
13425    #[serde(default)]
13426    pub expression: Option<Box<Expression>>,
13427    #[serde(default)]
13428    pub counters: Option<Box<Expression>>,
13429}
13430
13431/// ApproxTopKAccumulate
13432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13433#[cfg_attr(feature = "bindings", derive(TS))]
13434pub struct ApproxTopKAccumulate {
13435    pub this: Box<Expression>,
13436    #[serde(default)]
13437    pub expression: Option<Box<Expression>>,
13438}
13439
13440/// ApproxTopKCombine
13441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13442#[cfg_attr(feature = "bindings", derive(TS))]
13443pub struct ApproxTopKCombine {
13444    pub this: Box<Expression>,
13445    #[serde(default)]
13446    pub expression: Option<Box<Expression>>,
13447}
13448
13449/// ApproxTopKEstimate
13450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13451#[cfg_attr(feature = "bindings", derive(TS))]
13452pub struct ApproxTopKEstimate {
13453    pub this: Box<Expression>,
13454    #[serde(default)]
13455    pub expression: Option<Box<Expression>>,
13456}
13457
13458/// ApproxTopSum
13459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13460#[cfg_attr(feature = "bindings", derive(TS))]
13461pub struct ApproxTopSum {
13462    pub this: Box<Expression>,
13463    pub expression: Box<Expression>,
13464    #[serde(default)]
13465    pub count: Option<Box<Expression>>,
13466}
13467
13468/// ApproxQuantiles
13469#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13470#[cfg_attr(feature = "bindings", derive(TS))]
13471pub struct ApproxQuantiles {
13472    pub this: Box<Expression>,
13473    #[serde(default)]
13474    pub expression: Option<Box<Expression>>,
13475}
13476
13477/// Minhash
13478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13479#[cfg_attr(feature = "bindings", derive(TS))]
13480pub struct Minhash {
13481    pub this: Box<Expression>,
13482    #[serde(default)]
13483    pub expressions: Vec<Expression>,
13484}
13485
13486/// FarmFingerprint
13487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13488#[cfg_attr(feature = "bindings", derive(TS))]
13489pub struct FarmFingerprint {
13490    #[serde(default)]
13491    pub expressions: Vec<Expression>,
13492}
13493
13494/// Float64
13495#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13496#[cfg_attr(feature = "bindings", derive(TS))]
13497pub struct Float64 {
13498    pub this: Box<Expression>,
13499    #[serde(default)]
13500    pub expression: Option<Box<Expression>>,
13501}
13502
13503/// Transform
13504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13505#[cfg_attr(feature = "bindings", derive(TS))]
13506pub struct Transform {
13507    pub this: Box<Expression>,
13508    pub expression: Box<Expression>,
13509}
13510
13511/// Translate
13512#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13513#[cfg_attr(feature = "bindings", derive(TS))]
13514pub struct Translate {
13515    pub this: Box<Expression>,
13516    #[serde(default)]
13517    pub from_: Option<Box<Expression>>,
13518    #[serde(default)]
13519    pub to: Option<Box<Expression>>,
13520}
13521
13522/// Grouping
13523#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13524#[cfg_attr(feature = "bindings", derive(TS))]
13525pub struct Grouping {
13526    #[serde(default)]
13527    pub expressions: Vec<Expression>,
13528}
13529
13530/// GroupingId
13531#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13532#[cfg_attr(feature = "bindings", derive(TS))]
13533pub struct GroupingId {
13534    #[serde(default)]
13535    pub expressions: Vec<Expression>,
13536}
13537
13538/// Anonymous
13539#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13540#[cfg_attr(feature = "bindings", derive(TS))]
13541pub struct Anonymous {
13542    pub this: Box<Expression>,
13543    #[serde(default)]
13544    pub expressions: Vec<Expression>,
13545}
13546
13547/// AnonymousAggFunc
13548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13549#[cfg_attr(feature = "bindings", derive(TS))]
13550pub struct AnonymousAggFunc {
13551    pub this: Box<Expression>,
13552    #[serde(default)]
13553    pub expressions: Vec<Expression>,
13554}
13555
13556/// CombinedAggFunc
13557#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13558#[cfg_attr(feature = "bindings", derive(TS))]
13559pub struct CombinedAggFunc {
13560    pub this: Box<Expression>,
13561    #[serde(default)]
13562    pub expressions: Vec<Expression>,
13563}
13564
13565/// CombinedParameterizedAgg
13566#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13567#[cfg_attr(feature = "bindings", derive(TS))]
13568pub struct CombinedParameterizedAgg {
13569    pub this: Box<Expression>,
13570    #[serde(default)]
13571    pub expressions: Vec<Expression>,
13572    #[serde(default)]
13573    pub params: Vec<Expression>,
13574}
13575
13576/// HashAgg
13577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13578#[cfg_attr(feature = "bindings", derive(TS))]
13579pub struct HashAgg {
13580    pub this: Box<Expression>,
13581    #[serde(default)]
13582    pub expressions: Vec<Expression>,
13583}
13584
13585/// Hll
13586#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13587#[cfg_attr(feature = "bindings", derive(TS))]
13588pub struct Hll {
13589    pub this: Box<Expression>,
13590    #[serde(default)]
13591    pub expressions: Vec<Expression>,
13592}
13593
13594/// Apply
13595#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13596#[cfg_attr(feature = "bindings", derive(TS))]
13597pub struct Apply {
13598    pub this: Box<Expression>,
13599    pub expression: Box<Expression>,
13600}
13601
13602/// ToBoolean
13603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13604#[cfg_attr(feature = "bindings", derive(TS))]
13605pub struct ToBoolean {
13606    pub this: Box<Expression>,
13607    #[serde(default)]
13608    pub safe: Option<Box<Expression>>,
13609}
13610
13611/// List
13612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13613#[cfg_attr(feature = "bindings", derive(TS))]
13614pub struct List {
13615    #[serde(default)]
13616    pub expressions: Vec<Expression>,
13617}
13618
13619/// ToMap - Materialize-style map constructor
13620/// Can hold either:
13621/// - A SELECT subquery (MAP(SELECT 'a', 1))
13622/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
13623#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13624#[cfg_attr(feature = "bindings", derive(TS))]
13625pub struct ToMap {
13626    /// Either a Select subquery or a Struct containing PropertyEQ entries
13627    pub this: Box<Expression>,
13628}
13629
13630/// Pad
13631#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13632#[cfg_attr(feature = "bindings", derive(TS))]
13633pub struct Pad {
13634    pub this: Box<Expression>,
13635    pub expression: Box<Expression>,
13636    #[serde(default)]
13637    pub fill_pattern: Option<Box<Expression>>,
13638    #[serde(default)]
13639    pub is_left: Option<Box<Expression>>,
13640}
13641
13642/// ToChar
13643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13644#[cfg_attr(feature = "bindings", derive(TS))]
13645pub struct ToChar {
13646    pub this: Box<Expression>,
13647    #[serde(default)]
13648    pub format: Option<String>,
13649    #[serde(default)]
13650    pub nlsparam: Option<Box<Expression>>,
13651    #[serde(default)]
13652    pub is_numeric: Option<Box<Expression>>,
13653}
13654
13655/// StringFunc - String type conversion function (BigQuery STRING)
13656#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13657#[cfg_attr(feature = "bindings", derive(TS))]
13658pub struct StringFunc {
13659    pub this: Box<Expression>,
13660    #[serde(default)]
13661    pub zone: Option<Box<Expression>>,
13662}
13663
13664/// ToNumber
13665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13666#[cfg_attr(feature = "bindings", derive(TS))]
13667pub struct ToNumber {
13668    pub this: Box<Expression>,
13669    #[serde(default)]
13670    pub format: Option<Box<Expression>>,
13671    #[serde(default)]
13672    pub nlsparam: Option<Box<Expression>>,
13673    #[serde(default)]
13674    pub precision: Option<Box<Expression>>,
13675    #[serde(default)]
13676    pub scale: Option<Box<Expression>>,
13677    #[serde(default)]
13678    pub safe: Option<Box<Expression>>,
13679    #[serde(default)]
13680    pub safe_name: Option<Box<Expression>>,
13681}
13682
13683/// ToDouble
13684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13685#[cfg_attr(feature = "bindings", derive(TS))]
13686pub struct ToDouble {
13687    pub this: Box<Expression>,
13688    #[serde(default)]
13689    pub format: Option<String>,
13690    #[serde(default)]
13691    pub safe: Option<Box<Expression>>,
13692}
13693
13694/// ToDecfloat
13695#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13696#[cfg_attr(feature = "bindings", derive(TS))]
13697pub struct ToDecfloat {
13698    pub this: Box<Expression>,
13699    #[serde(default)]
13700    pub format: Option<String>,
13701}
13702
13703/// TryToDecfloat
13704#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13705#[cfg_attr(feature = "bindings", derive(TS))]
13706pub struct TryToDecfloat {
13707    pub this: Box<Expression>,
13708    #[serde(default)]
13709    pub format: Option<String>,
13710}
13711
13712/// ToFile
13713#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13714#[cfg_attr(feature = "bindings", derive(TS))]
13715pub struct ToFile {
13716    pub this: Box<Expression>,
13717    #[serde(default)]
13718    pub path: Option<Box<Expression>>,
13719    #[serde(default)]
13720    pub safe: Option<Box<Expression>>,
13721}
13722
13723/// Columns
13724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13725#[cfg_attr(feature = "bindings", derive(TS))]
13726pub struct Columns {
13727    pub this: Box<Expression>,
13728    #[serde(default)]
13729    pub unpack: Option<Box<Expression>>,
13730}
13731
13732/// ConvertToCharset
13733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13734#[cfg_attr(feature = "bindings", derive(TS))]
13735pub struct ConvertToCharset {
13736    pub this: Box<Expression>,
13737    #[serde(default)]
13738    pub dest: Option<Box<Expression>>,
13739    #[serde(default)]
13740    pub source: Option<Box<Expression>>,
13741}
13742
13743/// ConvertTimezone
13744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13745#[cfg_attr(feature = "bindings", derive(TS))]
13746pub struct ConvertTimezone {
13747    #[serde(default)]
13748    pub source_tz: Option<Box<Expression>>,
13749    #[serde(default)]
13750    pub target_tz: Option<Box<Expression>>,
13751    #[serde(default)]
13752    pub timestamp: Option<Box<Expression>>,
13753    #[serde(default)]
13754    pub options: Vec<Expression>,
13755}
13756
13757/// GenerateSeries
13758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13759#[cfg_attr(feature = "bindings", derive(TS))]
13760pub struct GenerateSeries {
13761    #[serde(default)]
13762    pub start: Option<Box<Expression>>,
13763    #[serde(default)]
13764    pub end: Option<Box<Expression>>,
13765    #[serde(default)]
13766    pub step: Option<Box<Expression>>,
13767    #[serde(default)]
13768    pub is_end_exclusive: Option<Box<Expression>>,
13769}
13770
13771/// AIAgg
13772#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13773#[cfg_attr(feature = "bindings", derive(TS))]
13774pub struct AIAgg {
13775    pub this: Box<Expression>,
13776    pub expression: Box<Expression>,
13777}
13778
13779/// AIClassify
13780#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13781#[cfg_attr(feature = "bindings", derive(TS))]
13782pub struct AIClassify {
13783    pub this: Box<Expression>,
13784    #[serde(default)]
13785    pub categories: Option<Box<Expression>>,
13786    #[serde(default)]
13787    pub config: Option<Box<Expression>>,
13788}
13789
13790/// ArrayAll
13791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13792#[cfg_attr(feature = "bindings", derive(TS))]
13793pub struct ArrayAll {
13794    pub this: Box<Expression>,
13795    pub expression: Box<Expression>,
13796}
13797
13798/// ArrayAny
13799#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13800#[cfg_attr(feature = "bindings", derive(TS))]
13801pub struct ArrayAny {
13802    pub this: Box<Expression>,
13803    pub expression: Box<Expression>,
13804}
13805
13806/// ArrayConstructCompact
13807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13808#[cfg_attr(feature = "bindings", derive(TS))]
13809pub struct ArrayConstructCompact {
13810    #[serde(default)]
13811    pub expressions: Vec<Expression>,
13812}
13813
13814/// StPoint
13815#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13816#[cfg_attr(feature = "bindings", derive(TS))]
13817pub struct StPoint {
13818    pub this: Box<Expression>,
13819    pub expression: Box<Expression>,
13820    #[serde(default)]
13821    pub null: Option<Box<Expression>>,
13822}
13823
13824/// StDistance
13825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13826#[cfg_attr(feature = "bindings", derive(TS))]
13827pub struct StDistance {
13828    pub this: Box<Expression>,
13829    pub expression: Box<Expression>,
13830    #[serde(default)]
13831    pub use_spheroid: Option<Box<Expression>>,
13832}
13833
13834/// StringToArray
13835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13836#[cfg_attr(feature = "bindings", derive(TS))]
13837pub struct StringToArray {
13838    pub this: Box<Expression>,
13839    #[serde(default)]
13840    pub expression: Option<Box<Expression>>,
13841    #[serde(default)]
13842    pub null: Option<Box<Expression>>,
13843}
13844
13845/// ArraySum
13846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13847#[cfg_attr(feature = "bindings", derive(TS))]
13848pub struct ArraySum {
13849    pub this: Box<Expression>,
13850    #[serde(default)]
13851    pub expression: Option<Box<Expression>>,
13852}
13853
13854/// ObjectAgg
13855#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13856#[cfg_attr(feature = "bindings", derive(TS))]
13857pub struct ObjectAgg {
13858    pub this: Box<Expression>,
13859    pub expression: Box<Expression>,
13860}
13861
13862/// CastToStrType
13863#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13864#[cfg_attr(feature = "bindings", derive(TS))]
13865pub struct CastToStrType {
13866    pub this: Box<Expression>,
13867    #[serde(default)]
13868    pub to: Option<Box<Expression>>,
13869}
13870
13871/// CheckJson
13872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13873#[cfg_attr(feature = "bindings", derive(TS))]
13874pub struct CheckJson {
13875    pub this: Box<Expression>,
13876}
13877
13878/// CheckXml
13879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13880#[cfg_attr(feature = "bindings", derive(TS))]
13881pub struct CheckXml {
13882    pub this: Box<Expression>,
13883    #[serde(default)]
13884    pub disable_auto_convert: Option<Box<Expression>>,
13885}
13886
13887/// TranslateCharacters
13888#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13889#[cfg_attr(feature = "bindings", derive(TS))]
13890pub struct TranslateCharacters {
13891    pub this: Box<Expression>,
13892    pub expression: Box<Expression>,
13893    #[serde(default)]
13894    pub with_error: Option<Box<Expression>>,
13895}
13896
13897/// CurrentSchemas
13898#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13899#[cfg_attr(feature = "bindings", derive(TS))]
13900pub struct CurrentSchemas {
13901    #[serde(default)]
13902    pub this: Option<Box<Expression>>,
13903}
13904
13905/// CurrentDatetime
13906#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13907#[cfg_attr(feature = "bindings", derive(TS))]
13908pub struct CurrentDatetime {
13909    #[serde(default)]
13910    pub this: Option<Box<Expression>>,
13911}
13912
13913/// Localtime
13914#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13915#[cfg_attr(feature = "bindings", derive(TS))]
13916pub struct Localtime {
13917    #[serde(default)]
13918    pub this: Option<Box<Expression>>,
13919}
13920
13921/// Localtimestamp
13922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13923#[cfg_attr(feature = "bindings", derive(TS))]
13924pub struct Localtimestamp {
13925    #[serde(default)]
13926    pub this: Option<Box<Expression>>,
13927}
13928
13929/// Systimestamp
13930#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13931#[cfg_attr(feature = "bindings", derive(TS))]
13932pub struct Systimestamp {
13933    #[serde(default)]
13934    pub this: Option<Box<Expression>>,
13935}
13936
13937/// CurrentSchema
13938#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13939#[cfg_attr(feature = "bindings", derive(TS))]
13940pub struct CurrentSchema {
13941    #[serde(default)]
13942    pub this: Option<Box<Expression>>,
13943}
13944
13945/// CurrentUser
13946#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13947#[cfg_attr(feature = "bindings", derive(TS))]
13948pub struct CurrentUser {
13949    #[serde(default)]
13950    pub this: Option<Box<Expression>>,
13951}
13952
13953/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13955#[cfg_attr(feature = "bindings", derive(TS))]
13956pub struct SessionUser;
13957
13958/// JSONPathRoot - Represents $ in JSON path expressions
13959#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13960#[cfg_attr(feature = "bindings", derive(TS))]
13961pub struct JSONPathRoot;
13962
13963/// UtcTime
13964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13965#[cfg_attr(feature = "bindings", derive(TS))]
13966pub struct UtcTime {
13967    #[serde(default)]
13968    pub this: Option<Box<Expression>>,
13969}
13970
13971/// UtcTimestamp
13972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13973#[cfg_attr(feature = "bindings", derive(TS))]
13974pub struct UtcTimestamp {
13975    #[serde(default)]
13976    pub this: Option<Box<Expression>>,
13977}
13978
13979/// TimestampFunc - TIMESTAMP constructor function
13980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13981#[cfg_attr(feature = "bindings", derive(TS))]
13982pub struct TimestampFunc {
13983    #[serde(default)]
13984    pub this: Option<Box<Expression>>,
13985    #[serde(default)]
13986    pub zone: Option<Box<Expression>>,
13987    #[serde(default)]
13988    pub with_tz: Option<bool>,
13989    #[serde(default)]
13990    pub safe: Option<bool>,
13991}
13992
13993/// DateBin
13994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13995#[cfg_attr(feature = "bindings", derive(TS))]
13996pub struct DateBin {
13997    pub this: Box<Expression>,
13998    pub expression: Box<Expression>,
13999    #[serde(default)]
14000    pub unit: Option<String>,
14001    #[serde(default)]
14002    pub zone: Option<Box<Expression>>,
14003    #[serde(default)]
14004    pub origin: Option<Box<Expression>>,
14005}
14006
14007/// Datetime
14008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14009#[cfg_attr(feature = "bindings", derive(TS))]
14010pub struct Datetime {
14011    pub this: Box<Expression>,
14012    #[serde(default)]
14013    pub expression: Option<Box<Expression>>,
14014}
14015
14016/// DatetimeAdd
14017#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14018#[cfg_attr(feature = "bindings", derive(TS))]
14019pub struct DatetimeAdd {
14020    pub this: Box<Expression>,
14021    pub expression: Box<Expression>,
14022    #[serde(default)]
14023    pub unit: Option<String>,
14024}
14025
14026/// DatetimeSub
14027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14028#[cfg_attr(feature = "bindings", derive(TS))]
14029pub struct DatetimeSub {
14030    pub this: Box<Expression>,
14031    pub expression: Box<Expression>,
14032    #[serde(default)]
14033    pub unit: Option<String>,
14034}
14035
14036/// DatetimeDiff
14037#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14038#[cfg_attr(feature = "bindings", derive(TS))]
14039pub struct DatetimeDiff {
14040    pub this: Box<Expression>,
14041    pub expression: Box<Expression>,
14042    #[serde(default)]
14043    pub unit: Option<String>,
14044}
14045
14046/// DatetimeTrunc
14047#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14048#[cfg_attr(feature = "bindings", derive(TS))]
14049pub struct DatetimeTrunc {
14050    pub this: Box<Expression>,
14051    pub unit: String,
14052    #[serde(default)]
14053    pub zone: Option<Box<Expression>>,
14054}
14055
14056/// Dayname
14057#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14058#[cfg_attr(feature = "bindings", derive(TS))]
14059pub struct Dayname {
14060    pub this: Box<Expression>,
14061    #[serde(default)]
14062    pub abbreviated: Option<Box<Expression>>,
14063}
14064
14065/// MakeInterval
14066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14067#[cfg_attr(feature = "bindings", derive(TS))]
14068pub struct MakeInterval {
14069    #[serde(default)]
14070    pub year: Option<Box<Expression>>,
14071    #[serde(default)]
14072    pub month: Option<Box<Expression>>,
14073    #[serde(default)]
14074    pub week: Option<Box<Expression>>,
14075    #[serde(default)]
14076    pub day: Option<Box<Expression>>,
14077    #[serde(default)]
14078    pub hour: Option<Box<Expression>>,
14079    #[serde(default)]
14080    pub minute: Option<Box<Expression>>,
14081    #[serde(default)]
14082    pub second: Option<Box<Expression>>,
14083}
14084
14085/// PreviousDay
14086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14087#[cfg_attr(feature = "bindings", derive(TS))]
14088pub struct PreviousDay {
14089    pub this: Box<Expression>,
14090    pub expression: Box<Expression>,
14091}
14092
14093/// Elt
14094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14095#[cfg_attr(feature = "bindings", derive(TS))]
14096pub struct Elt {
14097    pub this: Box<Expression>,
14098    #[serde(default)]
14099    pub expressions: Vec<Expression>,
14100}
14101
14102/// TimestampAdd
14103#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14104#[cfg_attr(feature = "bindings", derive(TS))]
14105pub struct TimestampAdd {
14106    pub this: Box<Expression>,
14107    pub expression: Box<Expression>,
14108    #[serde(default)]
14109    pub unit: Option<String>,
14110}
14111
14112/// TimestampSub
14113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14114#[cfg_attr(feature = "bindings", derive(TS))]
14115pub struct TimestampSub {
14116    pub this: Box<Expression>,
14117    pub expression: Box<Expression>,
14118    #[serde(default)]
14119    pub unit: Option<String>,
14120}
14121
14122/// TimestampDiff
14123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14124#[cfg_attr(feature = "bindings", derive(TS))]
14125pub struct TimestampDiff {
14126    pub this: Box<Expression>,
14127    pub expression: Box<Expression>,
14128    #[serde(default)]
14129    pub unit: Option<String>,
14130}
14131
14132/// TimeSlice
14133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14134#[cfg_attr(feature = "bindings", derive(TS))]
14135pub struct TimeSlice {
14136    pub this: Box<Expression>,
14137    pub expression: Box<Expression>,
14138    pub unit: String,
14139    #[serde(default)]
14140    pub kind: Option<String>,
14141}
14142
14143/// TimeAdd
14144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14145#[cfg_attr(feature = "bindings", derive(TS))]
14146pub struct TimeAdd {
14147    pub this: Box<Expression>,
14148    pub expression: Box<Expression>,
14149    #[serde(default)]
14150    pub unit: Option<String>,
14151}
14152
14153/// TimeSub
14154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14155#[cfg_attr(feature = "bindings", derive(TS))]
14156pub struct TimeSub {
14157    pub this: Box<Expression>,
14158    pub expression: Box<Expression>,
14159    #[serde(default)]
14160    pub unit: Option<String>,
14161}
14162
14163/// TimeDiff
14164#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14165#[cfg_attr(feature = "bindings", derive(TS))]
14166pub struct TimeDiff {
14167    pub this: Box<Expression>,
14168    pub expression: Box<Expression>,
14169    #[serde(default)]
14170    pub unit: Option<String>,
14171}
14172
14173/// TimeTrunc
14174#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14175#[cfg_attr(feature = "bindings", derive(TS))]
14176pub struct TimeTrunc {
14177    pub this: Box<Expression>,
14178    pub unit: String,
14179    #[serde(default)]
14180    pub zone: Option<Box<Expression>>,
14181}
14182
14183/// DateFromParts
14184#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14185#[cfg_attr(feature = "bindings", derive(TS))]
14186pub struct DateFromParts {
14187    #[serde(default)]
14188    pub year: Option<Box<Expression>>,
14189    #[serde(default)]
14190    pub month: Option<Box<Expression>>,
14191    #[serde(default)]
14192    pub day: Option<Box<Expression>>,
14193    #[serde(default)]
14194    pub allow_overflow: Option<Box<Expression>>,
14195}
14196
14197/// TimeFromParts
14198#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14199#[cfg_attr(feature = "bindings", derive(TS))]
14200pub struct TimeFromParts {
14201    #[serde(default)]
14202    pub hour: Option<Box<Expression>>,
14203    #[serde(default)]
14204    pub min: Option<Box<Expression>>,
14205    #[serde(default)]
14206    pub sec: Option<Box<Expression>>,
14207    #[serde(default)]
14208    pub nano: Option<Box<Expression>>,
14209    #[serde(default)]
14210    pub fractions: Option<Box<Expression>>,
14211    #[serde(default)]
14212    pub precision: Option<i64>,
14213}
14214
14215/// DecodeCase
14216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14217#[cfg_attr(feature = "bindings", derive(TS))]
14218pub struct DecodeCase {
14219    #[serde(default)]
14220    pub expressions: Vec<Expression>,
14221}
14222
14223/// Decrypt
14224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14225#[cfg_attr(feature = "bindings", derive(TS))]
14226pub struct Decrypt {
14227    pub this: Box<Expression>,
14228    #[serde(default)]
14229    pub passphrase: Option<Box<Expression>>,
14230    #[serde(default)]
14231    pub aad: Option<Box<Expression>>,
14232    #[serde(default)]
14233    pub encryption_method: Option<Box<Expression>>,
14234    #[serde(default)]
14235    pub safe: Option<Box<Expression>>,
14236}
14237
14238/// DecryptRaw
14239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14240#[cfg_attr(feature = "bindings", derive(TS))]
14241pub struct DecryptRaw {
14242    pub this: Box<Expression>,
14243    #[serde(default)]
14244    pub key: Option<Box<Expression>>,
14245    #[serde(default)]
14246    pub iv: Option<Box<Expression>>,
14247    #[serde(default)]
14248    pub aad: Option<Box<Expression>>,
14249    #[serde(default)]
14250    pub encryption_method: Option<Box<Expression>>,
14251    #[serde(default)]
14252    pub aead: Option<Box<Expression>>,
14253    #[serde(default)]
14254    pub safe: Option<Box<Expression>>,
14255}
14256
14257/// Encode
14258#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14259#[cfg_attr(feature = "bindings", derive(TS))]
14260pub struct Encode {
14261    pub this: Box<Expression>,
14262    #[serde(default)]
14263    pub charset: Option<Box<Expression>>,
14264}
14265
14266/// Encrypt
14267#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14268#[cfg_attr(feature = "bindings", derive(TS))]
14269pub struct Encrypt {
14270    pub this: Box<Expression>,
14271    #[serde(default)]
14272    pub passphrase: Option<Box<Expression>>,
14273    #[serde(default)]
14274    pub aad: Option<Box<Expression>>,
14275    #[serde(default)]
14276    pub encryption_method: Option<Box<Expression>>,
14277}
14278
14279/// EncryptRaw
14280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14281#[cfg_attr(feature = "bindings", derive(TS))]
14282pub struct EncryptRaw {
14283    pub this: Box<Expression>,
14284    #[serde(default)]
14285    pub key: Option<Box<Expression>>,
14286    #[serde(default)]
14287    pub iv: Option<Box<Expression>>,
14288    #[serde(default)]
14289    pub aad: Option<Box<Expression>>,
14290    #[serde(default)]
14291    pub encryption_method: Option<Box<Expression>>,
14292}
14293
14294/// EqualNull
14295#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14296#[cfg_attr(feature = "bindings", derive(TS))]
14297pub struct EqualNull {
14298    pub this: Box<Expression>,
14299    pub expression: Box<Expression>,
14300}
14301
14302/// ToBinary
14303#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14304#[cfg_attr(feature = "bindings", derive(TS))]
14305pub struct ToBinary {
14306    pub this: Box<Expression>,
14307    #[serde(default)]
14308    pub format: Option<String>,
14309    #[serde(default)]
14310    pub safe: Option<Box<Expression>>,
14311}
14312
14313/// Base64DecodeBinary
14314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14315#[cfg_attr(feature = "bindings", derive(TS))]
14316pub struct Base64DecodeBinary {
14317    pub this: Box<Expression>,
14318    #[serde(default)]
14319    pub alphabet: Option<Box<Expression>>,
14320}
14321
14322/// Base64DecodeString
14323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14324#[cfg_attr(feature = "bindings", derive(TS))]
14325pub struct Base64DecodeString {
14326    pub this: Box<Expression>,
14327    #[serde(default)]
14328    pub alphabet: Option<Box<Expression>>,
14329}
14330
14331/// Base64Encode
14332#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14333#[cfg_attr(feature = "bindings", derive(TS))]
14334pub struct Base64Encode {
14335    pub this: Box<Expression>,
14336    #[serde(default)]
14337    pub max_line_length: Option<Box<Expression>>,
14338    #[serde(default)]
14339    pub alphabet: Option<Box<Expression>>,
14340}
14341
14342/// TryBase64DecodeBinary
14343#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14344#[cfg_attr(feature = "bindings", derive(TS))]
14345pub struct TryBase64DecodeBinary {
14346    pub this: Box<Expression>,
14347    #[serde(default)]
14348    pub alphabet: Option<Box<Expression>>,
14349}
14350
14351/// TryBase64DecodeString
14352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14353#[cfg_attr(feature = "bindings", derive(TS))]
14354pub struct TryBase64DecodeString {
14355    pub this: Box<Expression>,
14356    #[serde(default)]
14357    pub alphabet: Option<Box<Expression>>,
14358}
14359
14360/// GapFill
14361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14362#[cfg_attr(feature = "bindings", derive(TS))]
14363pub struct GapFill {
14364    pub this: Box<Expression>,
14365    #[serde(default)]
14366    pub ts_column: Option<Box<Expression>>,
14367    #[serde(default)]
14368    pub bucket_width: Option<Box<Expression>>,
14369    #[serde(default)]
14370    pub partitioning_columns: Option<Box<Expression>>,
14371    #[serde(default)]
14372    pub value_columns: Option<Box<Expression>>,
14373    #[serde(default)]
14374    pub origin: Option<Box<Expression>>,
14375    #[serde(default)]
14376    pub ignore_nulls: Option<Box<Expression>>,
14377}
14378
14379/// GenerateDateArray
14380#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14381#[cfg_attr(feature = "bindings", derive(TS))]
14382pub struct GenerateDateArray {
14383    #[serde(default)]
14384    pub start: Option<Box<Expression>>,
14385    #[serde(default)]
14386    pub end: Option<Box<Expression>>,
14387    #[serde(default)]
14388    pub step: Option<Box<Expression>>,
14389}
14390
14391/// GenerateTimestampArray
14392#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14393#[cfg_attr(feature = "bindings", derive(TS))]
14394pub struct GenerateTimestampArray {
14395    #[serde(default)]
14396    pub start: Option<Box<Expression>>,
14397    #[serde(default)]
14398    pub end: Option<Box<Expression>>,
14399    #[serde(default)]
14400    pub step: Option<Box<Expression>>,
14401}
14402
14403/// GetExtract
14404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14405#[cfg_attr(feature = "bindings", derive(TS))]
14406pub struct GetExtract {
14407    pub this: Box<Expression>,
14408    pub expression: Box<Expression>,
14409}
14410
14411/// Getbit
14412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14413#[cfg_attr(feature = "bindings", derive(TS))]
14414pub struct Getbit {
14415    pub this: Box<Expression>,
14416    pub expression: Box<Expression>,
14417    #[serde(default)]
14418    pub zero_is_msb: Option<Box<Expression>>,
14419}
14420
14421/// OverflowTruncateBehavior
14422#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14423#[cfg_attr(feature = "bindings", derive(TS))]
14424pub struct OverflowTruncateBehavior {
14425    #[serde(default)]
14426    pub this: Option<Box<Expression>>,
14427    #[serde(default)]
14428    pub with_count: Option<Box<Expression>>,
14429}
14430
14431/// HexEncode
14432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14433#[cfg_attr(feature = "bindings", derive(TS))]
14434pub struct HexEncode {
14435    pub this: Box<Expression>,
14436    #[serde(default)]
14437    pub case: Option<Box<Expression>>,
14438}
14439
14440/// Compress
14441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14442#[cfg_attr(feature = "bindings", derive(TS))]
14443pub struct Compress {
14444    pub this: Box<Expression>,
14445    #[serde(default)]
14446    pub method: Option<String>,
14447}
14448
14449/// DecompressBinary
14450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14451#[cfg_attr(feature = "bindings", derive(TS))]
14452pub struct DecompressBinary {
14453    pub this: Box<Expression>,
14454    pub method: String,
14455}
14456
14457/// DecompressString
14458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14459#[cfg_attr(feature = "bindings", derive(TS))]
14460pub struct DecompressString {
14461    pub this: Box<Expression>,
14462    pub method: String,
14463}
14464
14465/// Xor
14466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14467#[cfg_attr(feature = "bindings", derive(TS))]
14468pub struct Xor {
14469    #[serde(default)]
14470    pub this: Option<Box<Expression>>,
14471    #[serde(default)]
14472    pub expression: Option<Box<Expression>>,
14473    #[serde(default)]
14474    pub expressions: Vec<Expression>,
14475}
14476
14477/// Nullif
14478#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14479#[cfg_attr(feature = "bindings", derive(TS))]
14480pub struct Nullif {
14481    pub this: Box<Expression>,
14482    pub expression: Box<Expression>,
14483}
14484
14485/// JSON
14486#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14487#[cfg_attr(feature = "bindings", derive(TS))]
14488pub struct JSON {
14489    #[serde(default)]
14490    pub this: Option<Box<Expression>>,
14491    #[serde(default)]
14492    pub with_: Option<Box<Expression>>,
14493    #[serde(default)]
14494    pub unique: bool,
14495}
14496
14497/// JSONPath
14498#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14499#[cfg_attr(feature = "bindings", derive(TS))]
14500pub struct JSONPath {
14501    #[serde(default)]
14502    pub expressions: Vec<Expression>,
14503    #[serde(default)]
14504    pub escape: Option<Box<Expression>>,
14505}
14506
14507/// JSONPathFilter
14508#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14509#[cfg_attr(feature = "bindings", derive(TS))]
14510pub struct JSONPathFilter {
14511    pub this: Box<Expression>,
14512}
14513
14514/// JSONPathKey
14515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14516#[cfg_attr(feature = "bindings", derive(TS))]
14517pub struct JSONPathKey {
14518    pub this: Box<Expression>,
14519}
14520
14521/// JSONPathRecursive
14522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14523#[cfg_attr(feature = "bindings", derive(TS))]
14524pub struct JSONPathRecursive {
14525    #[serde(default)]
14526    pub this: Option<Box<Expression>>,
14527}
14528
14529/// JSONPathScript
14530#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14531#[cfg_attr(feature = "bindings", derive(TS))]
14532pub struct JSONPathScript {
14533    pub this: Box<Expression>,
14534}
14535
14536/// JSONPathSlice
14537#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14538#[cfg_attr(feature = "bindings", derive(TS))]
14539pub struct JSONPathSlice {
14540    #[serde(default)]
14541    pub start: Option<Box<Expression>>,
14542    #[serde(default)]
14543    pub end: Option<Box<Expression>>,
14544    #[serde(default)]
14545    pub step: Option<Box<Expression>>,
14546}
14547
14548/// JSONPathSelector
14549#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14550#[cfg_attr(feature = "bindings", derive(TS))]
14551pub struct JSONPathSelector {
14552    pub this: Box<Expression>,
14553}
14554
14555/// JSONPathSubscript
14556#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14557#[cfg_attr(feature = "bindings", derive(TS))]
14558pub struct JSONPathSubscript {
14559    pub this: Box<Expression>,
14560}
14561
14562/// JSONPathUnion
14563#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14564#[cfg_attr(feature = "bindings", derive(TS))]
14565pub struct JSONPathUnion {
14566    #[serde(default)]
14567    pub expressions: Vec<Expression>,
14568}
14569
14570/// Format
14571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14572#[cfg_attr(feature = "bindings", derive(TS))]
14573pub struct Format {
14574    pub this: Box<Expression>,
14575    #[serde(default)]
14576    pub expressions: Vec<Expression>,
14577}
14578
14579/// JSONKeys
14580#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14581#[cfg_attr(feature = "bindings", derive(TS))]
14582pub struct JSONKeys {
14583    pub this: Box<Expression>,
14584    #[serde(default)]
14585    pub expression: Option<Box<Expression>>,
14586    #[serde(default)]
14587    pub expressions: Vec<Expression>,
14588}
14589
14590/// JSONKeyValue
14591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14592#[cfg_attr(feature = "bindings", derive(TS))]
14593pub struct JSONKeyValue {
14594    pub this: Box<Expression>,
14595    pub expression: Box<Expression>,
14596}
14597
14598/// JSONKeysAtDepth
14599#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14600#[cfg_attr(feature = "bindings", derive(TS))]
14601pub struct JSONKeysAtDepth {
14602    pub this: Box<Expression>,
14603    #[serde(default)]
14604    pub expression: Option<Box<Expression>>,
14605    #[serde(default)]
14606    pub mode: Option<Box<Expression>>,
14607}
14608
14609/// JSONObject
14610#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14611#[cfg_attr(feature = "bindings", derive(TS))]
14612pub struct JSONObject {
14613    #[serde(default)]
14614    pub expressions: Vec<Expression>,
14615    #[serde(default)]
14616    pub null_handling: Option<Box<Expression>>,
14617    #[serde(default)]
14618    pub unique_keys: Option<Box<Expression>>,
14619    #[serde(default)]
14620    pub return_type: Option<Box<Expression>>,
14621    #[serde(default)]
14622    pub encoding: Option<Box<Expression>>,
14623}
14624
14625/// JSONObjectAgg
14626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14627#[cfg_attr(feature = "bindings", derive(TS))]
14628pub struct JSONObjectAgg {
14629    #[serde(default)]
14630    pub expressions: Vec<Expression>,
14631    #[serde(default)]
14632    pub null_handling: Option<Box<Expression>>,
14633    #[serde(default)]
14634    pub unique_keys: Option<Box<Expression>>,
14635    #[serde(default)]
14636    pub return_type: Option<Box<Expression>>,
14637    #[serde(default)]
14638    pub encoding: Option<Box<Expression>>,
14639}
14640
14641/// JSONBObjectAgg
14642#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14643#[cfg_attr(feature = "bindings", derive(TS))]
14644pub struct JSONBObjectAgg {
14645    pub this: Box<Expression>,
14646    pub expression: Box<Expression>,
14647}
14648
14649/// JSONArray
14650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14651#[cfg_attr(feature = "bindings", derive(TS))]
14652pub struct JSONArray {
14653    #[serde(default)]
14654    pub expressions: Vec<Expression>,
14655    #[serde(default)]
14656    pub null_handling: Option<Box<Expression>>,
14657    #[serde(default)]
14658    pub return_type: Option<Box<Expression>>,
14659    #[serde(default)]
14660    pub strict: Option<Box<Expression>>,
14661}
14662
14663/// JSONArrayAgg
14664#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14665#[cfg_attr(feature = "bindings", derive(TS))]
14666pub struct JSONArrayAgg {
14667    pub this: Box<Expression>,
14668    #[serde(default)]
14669    pub order: Option<Box<Expression>>,
14670    #[serde(default)]
14671    pub null_handling: Option<Box<Expression>>,
14672    #[serde(default)]
14673    pub return_type: Option<Box<Expression>>,
14674    #[serde(default)]
14675    pub strict: Option<Box<Expression>>,
14676}
14677
14678/// JSONExists
14679#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14680#[cfg_attr(feature = "bindings", derive(TS))]
14681pub struct JSONExists {
14682    pub this: Box<Expression>,
14683    #[serde(default)]
14684    pub path: Option<Box<Expression>>,
14685    #[serde(default)]
14686    pub passing: Option<Box<Expression>>,
14687    #[serde(default)]
14688    pub on_condition: Option<Box<Expression>>,
14689    #[serde(default)]
14690    pub from_dcolonqmark: Option<Box<Expression>>,
14691}
14692
14693/// JSONColumnDef
14694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14695#[cfg_attr(feature = "bindings", derive(TS))]
14696pub struct JSONColumnDef {
14697    /// Typed column definition; legacy dialects may use the textual kind field.
14698    #[serde(default, skip_serializing_if = "Option::is_none")]
14699    pub data_type: Option<DataType>,
14700    #[serde(default, skip_serializing_if = "Option::is_none")]
14701    pub encoding: Option<String>,
14702    #[serde(default, skip_serializing_if = "Option::is_none")]
14703    #[ast(skip)]
14704    pub source_dialect: Option<crate::dialects::DialectType>,
14705    /// Structured SQL/JSON wrapper and error/empty behavior.
14706    #[serde(default, skip_serializing_if = "Option::is_none")]
14707    pub options: Option<JsonOptions>,
14708
14709    #[serde(default)]
14710    pub this: Option<Box<Expression>>,
14711    #[serde(default)]
14712    pub kind: Option<String>,
14713    #[serde(default)]
14714    pub format_json: bool,
14715    #[serde(default)]
14716    pub path: Option<Box<Expression>>,
14717    #[serde(default)]
14718    pub nested_schema: Option<Box<Expression>>,
14719    #[serde(default)]
14720    pub ordinality: Option<Box<Expression>>,
14721}
14722
14723/// JSONSchema
14724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14725#[cfg_attr(feature = "bindings", derive(TS))]
14726pub struct JSONSchema {
14727    #[serde(default)]
14728    pub expressions: Vec<Expression>,
14729}
14730
14731/// JSONSet
14732#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14733#[cfg_attr(feature = "bindings", derive(TS))]
14734pub struct JSONSet {
14735    pub this: Box<Expression>,
14736    #[serde(default)]
14737    pub expressions: Vec<Expression>,
14738}
14739
14740/// JSONStripNulls
14741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14742#[cfg_attr(feature = "bindings", derive(TS))]
14743pub struct JSONStripNulls {
14744    pub this: Box<Expression>,
14745    #[serde(default)]
14746    pub expression: Option<Box<Expression>>,
14747    #[serde(default)]
14748    pub include_arrays: Option<Box<Expression>>,
14749    #[serde(default)]
14750    pub remove_empty: Option<Box<Expression>>,
14751}
14752
14753/// JSONValue
14754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14755#[cfg_attr(feature = "bindings", derive(TS))]
14756pub struct JSONValue {
14757    #[serde(default, skip_serializing_if = "Option::is_none")]
14758    #[ast(skip)]
14759    pub source_dialect: Option<crate::dialects::DialectType>,
14760    /// Structured SQL/JSON wrapper and error/empty behavior.
14761    #[serde(default, skip_serializing_if = "Option::is_none")]
14762    pub options: Option<JsonOptions>,
14763
14764    pub this: Box<Expression>,
14765    #[serde(default)]
14766    pub path: Option<Box<Expression>>,
14767    #[serde(default)]
14768    pub returning: Option<Box<Expression>>,
14769    #[serde(default)]
14770    pub on_condition: Option<Box<Expression>>,
14771}
14772
14773/// JSONValueArray
14774#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14775#[cfg_attr(feature = "bindings", derive(TS))]
14776pub struct JSONValueArray {
14777    pub this: Box<Expression>,
14778    #[serde(default)]
14779    pub expression: Option<Box<Expression>>,
14780}
14781
14782/// JSONRemove
14783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14784#[cfg_attr(feature = "bindings", derive(TS))]
14785pub struct JSONRemove {
14786    pub this: Box<Expression>,
14787    #[serde(default)]
14788    pub expressions: Vec<Expression>,
14789}
14790
14791/// JSONTable
14792#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14793#[cfg_attr(feature = "bindings", derive(TS))]
14794pub struct JSONTable {
14795    #[serde(default, skip_serializing_if = "Option::is_none")]
14796    #[ast(skip)]
14797    pub source_dialect: Option<crate::dialects::DialectType>,
14798    /// Structured SQL/JSON wrapper and error/empty behavior.
14799    #[serde(default, skip_serializing_if = "Option::is_none")]
14800    pub options: Option<JsonOptions>,
14801
14802    pub this: Box<Expression>,
14803    #[serde(default)]
14804    pub schema: Option<Box<Expression>>,
14805    #[serde(default)]
14806    pub path: Option<Box<Expression>>,
14807    #[serde(default)]
14808    pub error_handling: Option<Box<Expression>>,
14809    #[serde(default)]
14810    pub empty_handling: Option<Box<Expression>>,
14811}
14812
14813/// JSONType
14814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14815#[cfg_attr(feature = "bindings", derive(TS))]
14816pub struct JSONType {
14817    pub this: Box<Expression>,
14818    #[serde(default)]
14819    pub expression: Option<Box<Expression>>,
14820}
14821
14822/// ObjectInsert
14823#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14824#[cfg_attr(feature = "bindings", derive(TS))]
14825pub struct ObjectInsert {
14826    pub this: Box<Expression>,
14827    #[serde(default)]
14828    pub key: Option<Box<Expression>>,
14829    #[serde(default)]
14830    pub value: Option<Box<Expression>>,
14831    #[serde(default)]
14832    pub update_flag: Option<Box<Expression>>,
14833}
14834
14835/// OpenJSONColumnDef
14836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14837#[cfg_attr(feature = "bindings", derive(TS))]
14838pub struct OpenJSONColumnDef {
14839    pub this: Box<Expression>,
14840    pub kind: String,
14841    #[serde(default)]
14842    pub path: Option<Box<Expression>>,
14843    #[serde(default)]
14844    pub as_json: Option<Box<Expression>>,
14845    /// The parsed data type for proper generation
14846    #[serde(default, skip_serializing_if = "Option::is_none")]
14847    pub data_type: Option<DataType>,
14848}
14849
14850/// OpenJSON
14851#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14852#[cfg_attr(feature = "bindings", derive(TS))]
14853pub struct OpenJSON {
14854    pub this: Box<Expression>,
14855    #[serde(default)]
14856    pub path: Option<Box<Expression>>,
14857    #[serde(default)]
14858    pub expressions: Vec<Expression>,
14859}
14860
14861/// JSONBExists
14862#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14863#[cfg_attr(feature = "bindings", derive(TS))]
14864pub struct JSONBExists {
14865    pub this: Box<Expression>,
14866    #[serde(default)]
14867    pub path: Option<Box<Expression>>,
14868}
14869
14870/// JSONCast
14871#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14872#[cfg_attr(feature = "bindings", derive(TS))]
14873pub struct JSONCast {
14874    pub this: Box<Expression>,
14875    pub to: DataType,
14876}
14877
14878/// JSONExtract
14879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14880#[cfg_attr(feature = "bindings", derive(TS))]
14881pub struct JSONExtract {
14882    pub this: Box<Expression>,
14883    pub expression: Box<Expression>,
14884    #[serde(default)]
14885    pub only_json_types: Option<Box<Expression>>,
14886    #[serde(default)]
14887    pub expressions: Vec<Expression>,
14888    #[serde(default)]
14889    pub variant_extract: Option<Box<Expression>>,
14890    #[serde(default)]
14891    pub json_query: Option<Box<Expression>>,
14892    #[serde(default)]
14893    pub option: Option<Box<Expression>>,
14894    #[serde(default)]
14895    pub quote: Option<Box<Expression>>,
14896    #[serde(default)]
14897    pub on_condition: Option<Box<Expression>>,
14898    #[serde(default)]
14899    pub requires_json: Option<Box<Expression>>,
14900}
14901
14902/// JSONExtractQuote
14903#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14904#[cfg_attr(feature = "bindings", derive(TS))]
14905pub struct JSONExtractQuote {
14906    #[serde(default)]
14907    pub option: Option<Box<Expression>>,
14908    #[serde(default)]
14909    pub scalar: Option<Box<Expression>>,
14910}
14911
14912/// JSONExtractArray
14913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14914#[cfg_attr(feature = "bindings", derive(TS))]
14915pub struct JSONExtractArray {
14916    pub this: Box<Expression>,
14917    #[serde(default)]
14918    pub expression: Option<Box<Expression>>,
14919}
14920
14921/// JSONExtractScalar
14922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14923#[cfg_attr(feature = "bindings", derive(TS))]
14924pub struct JSONExtractScalar {
14925    pub this: Box<Expression>,
14926    pub expression: Box<Expression>,
14927    #[serde(default)]
14928    pub only_json_types: Option<Box<Expression>>,
14929    #[serde(default)]
14930    pub expressions: Vec<Expression>,
14931    #[serde(default)]
14932    pub json_type: Option<Box<Expression>>,
14933    #[serde(default)]
14934    pub scalar_only: Option<Box<Expression>>,
14935}
14936
14937/// JSONBExtractScalar
14938#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14939#[cfg_attr(feature = "bindings", derive(TS))]
14940pub struct JSONBExtractScalar {
14941    pub this: Box<Expression>,
14942    pub expression: Box<Expression>,
14943    #[serde(default)]
14944    pub json_type: Option<Box<Expression>>,
14945}
14946
14947/// JSONFormat
14948#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14949#[cfg_attr(feature = "bindings", derive(TS))]
14950pub struct JSONFormat {
14951    #[serde(default)]
14952    pub this: Option<Box<Expression>>,
14953    #[serde(default)]
14954    pub options: Vec<Expression>,
14955    #[serde(default)]
14956    pub is_json: Option<Box<Expression>>,
14957    #[serde(default)]
14958    pub to_json: Option<Box<Expression>>,
14959}
14960
14961/// JSONArrayAppend
14962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14963#[cfg_attr(feature = "bindings", derive(TS))]
14964pub struct JSONArrayAppend {
14965    pub this: Box<Expression>,
14966    #[serde(default)]
14967    pub expressions: Vec<Expression>,
14968}
14969
14970/// JSONArrayContains
14971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14972#[cfg_attr(feature = "bindings", derive(TS))]
14973pub struct JSONArrayContains {
14974    pub this: Box<Expression>,
14975    pub expression: Box<Expression>,
14976    #[serde(default)]
14977    pub json_type: Option<Box<Expression>>,
14978}
14979
14980/// JSONArrayInsert
14981#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14982#[cfg_attr(feature = "bindings", derive(TS))]
14983pub struct JSONArrayInsert {
14984    pub this: Box<Expression>,
14985    #[serde(default)]
14986    pub expressions: Vec<Expression>,
14987}
14988
14989/// ParseJSON
14990#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14991#[cfg_attr(feature = "bindings", derive(TS))]
14992pub struct ParseJSON {
14993    pub this: Box<Expression>,
14994    #[serde(default)]
14995    pub expression: Option<Box<Expression>>,
14996    #[serde(default)]
14997    pub safe: Option<Box<Expression>>,
14998}
14999
15000/// ParseUrl
15001#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15002#[cfg_attr(feature = "bindings", derive(TS))]
15003pub struct ParseUrl {
15004    pub this: Box<Expression>,
15005    #[serde(default)]
15006    pub part_to_extract: Option<Box<Expression>>,
15007    #[serde(default)]
15008    pub key: Option<Box<Expression>>,
15009    #[serde(default)]
15010    pub permissive: Option<Box<Expression>>,
15011}
15012
15013/// ParseIp
15014#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15015#[cfg_attr(feature = "bindings", derive(TS))]
15016pub struct ParseIp {
15017    pub this: Box<Expression>,
15018    #[serde(default)]
15019    pub type_: Option<Box<Expression>>,
15020    #[serde(default)]
15021    pub permissive: Option<Box<Expression>>,
15022}
15023
15024/// ParseTime
15025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15026#[cfg_attr(feature = "bindings", derive(TS))]
15027pub struct ParseTime {
15028    pub this: Box<Expression>,
15029    pub format: String,
15030}
15031
15032/// ParseDatetime
15033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15034#[cfg_attr(feature = "bindings", derive(TS))]
15035pub struct ParseDatetime {
15036    pub this: Box<Expression>,
15037    #[serde(default)]
15038    pub format: Option<String>,
15039    #[serde(default)]
15040    pub zone: Option<Box<Expression>>,
15041}
15042
15043/// Map
15044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15045#[cfg_attr(feature = "bindings", derive(TS))]
15046pub struct Map {
15047    #[serde(default)]
15048    pub keys: Vec<Expression>,
15049    #[serde(default)]
15050    pub values: Vec<Expression>,
15051}
15052
15053/// MapCat
15054#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15055#[cfg_attr(feature = "bindings", derive(TS))]
15056pub struct MapCat {
15057    pub this: Box<Expression>,
15058    pub expression: Box<Expression>,
15059}
15060
15061/// MapDelete
15062#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15063#[cfg_attr(feature = "bindings", derive(TS))]
15064pub struct MapDelete {
15065    pub this: Box<Expression>,
15066    #[serde(default)]
15067    pub expressions: Vec<Expression>,
15068}
15069
15070/// MapInsert
15071#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15072#[cfg_attr(feature = "bindings", derive(TS))]
15073pub struct MapInsert {
15074    pub this: Box<Expression>,
15075    #[serde(default)]
15076    pub key: Option<Box<Expression>>,
15077    #[serde(default)]
15078    pub value: Option<Box<Expression>>,
15079    #[serde(default)]
15080    pub update_flag: Option<Box<Expression>>,
15081}
15082
15083/// MapPick
15084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15085#[cfg_attr(feature = "bindings", derive(TS))]
15086pub struct MapPick {
15087    pub this: Box<Expression>,
15088    #[serde(default)]
15089    pub expressions: Vec<Expression>,
15090}
15091
15092/// ScopeResolution
15093#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15094#[cfg_attr(feature = "bindings", derive(TS))]
15095pub struct ScopeResolution {
15096    #[serde(default)]
15097    pub this: Option<Box<Expression>>,
15098    pub expression: Box<Expression>,
15099}
15100
15101/// Slice
15102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15103#[cfg_attr(feature = "bindings", derive(TS))]
15104pub struct Slice {
15105    #[serde(default)]
15106    pub this: Option<Box<Expression>>,
15107    #[serde(default)]
15108    pub expression: Option<Box<Expression>>,
15109    #[serde(default)]
15110    pub step: Option<Box<Expression>>,
15111}
15112
15113/// VarMap
15114#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15115#[cfg_attr(feature = "bindings", derive(TS))]
15116pub struct VarMap {
15117    #[serde(default)]
15118    pub keys: Vec<Expression>,
15119    #[serde(default)]
15120    pub values: Vec<Expression>,
15121}
15122
15123/// MatchAgainst
15124#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15125#[cfg_attr(feature = "bindings", derive(TS))]
15126pub struct MatchAgainst {
15127    pub this: Box<Expression>,
15128    #[serde(default)]
15129    pub expressions: Vec<Expression>,
15130    #[serde(default)]
15131    pub modifier: Option<Box<Expression>>,
15132}
15133
15134/// MD5Digest
15135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15136#[cfg_attr(feature = "bindings", derive(TS))]
15137pub struct MD5Digest {
15138    pub this: Box<Expression>,
15139    #[serde(default)]
15140    pub expressions: Vec<Expression>,
15141}
15142
15143/// Monthname
15144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15145#[cfg_attr(feature = "bindings", derive(TS))]
15146pub struct Monthname {
15147    pub this: Box<Expression>,
15148    #[serde(default)]
15149    pub abbreviated: Option<Box<Expression>>,
15150}
15151
15152/// Ntile
15153#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15154#[cfg_attr(feature = "bindings", derive(TS))]
15155pub struct Ntile {
15156    #[serde(default)]
15157    pub this: Option<Box<Expression>>,
15158}
15159
15160/// Normalize
15161#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15162#[cfg_attr(feature = "bindings", derive(TS))]
15163pub struct Normalize {
15164    pub this: Box<Expression>,
15165    #[serde(default)]
15166    pub form: Option<Box<Expression>>,
15167    #[serde(default)]
15168    pub is_casefold: Option<Box<Expression>>,
15169}
15170
15171/// Normal
15172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15173#[cfg_attr(feature = "bindings", derive(TS))]
15174pub struct Normal {
15175    pub this: Box<Expression>,
15176    #[serde(default)]
15177    pub stddev: Option<Box<Expression>>,
15178    #[serde(default)]
15179    pub gen: Option<Box<Expression>>,
15180}
15181
15182/// Predict
15183#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15184#[cfg_attr(feature = "bindings", derive(TS))]
15185pub struct Predict {
15186    pub this: Box<Expression>,
15187    pub expression: Box<Expression>,
15188    #[serde(default)]
15189    pub params_struct: Option<Box<Expression>>,
15190}
15191
15192/// MLTranslate
15193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15194#[cfg_attr(feature = "bindings", derive(TS))]
15195pub struct MLTranslate {
15196    pub this: Box<Expression>,
15197    pub expression: Box<Expression>,
15198    #[serde(default)]
15199    pub params_struct: Option<Box<Expression>>,
15200}
15201
15202/// FeaturesAtTime
15203#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15204#[cfg_attr(feature = "bindings", derive(TS))]
15205pub struct FeaturesAtTime {
15206    pub this: Box<Expression>,
15207    #[serde(default)]
15208    pub time: Option<Box<Expression>>,
15209    #[serde(default)]
15210    pub num_rows: Option<Box<Expression>>,
15211    #[serde(default)]
15212    pub ignore_feature_nulls: Option<Box<Expression>>,
15213}
15214
15215/// GenerateEmbedding
15216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15217#[cfg_attr(feature = "bindings", derive(TS))]
15218pub struct GenerateEmbedding {
15219    pub this: Box<Expression>,
15220    pub expression: Box<Expression>,
15221    #[serde(default)]
15222    pub params_struct: Option<Box<Expression>>,
15223    #[serde(default)]
15224    pub is_text: Option<Box<Expression>>,
15225}
15226
15227/// MLForecast
15228#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15229#[cfg_attr(feature = "bindings", derive(TS))]
15230pub struct MLForecast {
15231    pub this: Box<Expression>,
15232    #[serde(default)]
15233    pub expression: Option<Box<Expression>>,
15234    #[serde(default)]
15235    pub params_struct: Option<Box<Expression>>,
15236}
15237
15238/// ModelAttribute
15239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15240#[cfg_attr(feature = "bindings", derive(TS))]
15241pub struct ModelAttribute {
15242    pub this: Box<Expression>,
15243    pub expression: Box<Expression>,
15244}
15245
15246/// VectorSearch
15247#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15248#[cfg_attr(feature = "bindings", derive(TS))]
15249pub struct VectorSearch {
15250    pub this: Box<Expression>,
15251    #[serde(default)]
15252    pub column_to_search: Option<Box<Expression>>,
15253    #[serde(default)]
15254    pub query_table: Option<Box<Expression>>,
15255    #[serde(default)]
15256    pub query_column_to_search: Option<Box<Expression>>,
15257    #[serde(default)]
15258    pub top_k: Option<Box<Expression>>,
15259    #[serde(default)]
15260    pub distance_type: Option<Box<Expression>>,
15261    #[serde(default)]
15262    pub options: Vec<Expression>,
15263}
15264
15265/// Quantile
15266#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15267#[cfg_attr(feature = "bindings", derive(TS))]
15268pub struct Quantile {
15269    pub this: Box<Expression>,
15270    #[serde(default)]
15271    pub quantile: Option<Box<Expression>>,
15272}
15273
15274/// ApproxQuantile
15275#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15276#[cfg_attr(feature = "bindings", derive(TS))]
15277pub struct ApproxQuantile {
15278    pub this: Box<Expression>,
15279    #[serde(default)]
15280    pub quantile: Option<Box<Expression>>,
15281    #[serde(default)]
15282    pub accuracy: Option<Box<Expression>>,
15283    #[serde(default)]
15284    pub weight: Option<Box<Expression>>,
15285    #[serde(default)]
15286    pub error_tolerance: Option<Box<Expression>>,
15287}
15288
15289/// ApproxPercentileEstimate
15290#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15291#[cfg_attr(feature = "bindings", derive(TS))]
15292pub struct ApproxPercentileEstimate {
15293    pub this: Box<Expression>,
15294    #[serde(default)]
15295    pub percentile: Option<Box<Expression>>,
15296}
15297
15298/// Randn
15299#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15300#[cfg_attr(feature = "bindings", derive(TS))]
15301pub struct Randn {
15302    #[serde(default)]
15303    pub this: Option<Box<Expression>>,
15304}
15305
15306/// Randstr
15307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15308#[cfg_attr(feature = "bindings", derive(TS))]
15309pub struct Randstr {
15310    pub this: Box<Expression>,
15311    #[serde(default)]
15312    pub generator: Option<Box<Expression>>,
15313}
15314
15315/// RangeN
15316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15317#[cfg_attr(feature = "bindings", derive(TS))]
15318pub struct RangeN {
15319    pub this: Box<Expression>,
15320    #[serde(default)]
15321    pub expressions: Vec<Expression>,
15322    #[serde(default)]
15323    pub each: Option<Box<Expression>>,
15324}
15325
15326/// RangeBucket
15327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15328#[cfg_attr(feature = "bindings", derive(TS))]
15329pub struct RangeBucket {
15330    pub this: Box<Expression>,
15331    pub expression: Box<Expression>,
15332}
15333
15334/// ReadCSV
15335#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15336#[cfg_attr(feature = "bindings", derive(TS))]
15337pub struct ReadCSV {
15338    pub this: Box<Expression>,
15339    #[serde(default)]
15340    pub expressions: Vec<Expression>,
15341}
15342
15343/// ReadParquet
15344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15345#[cfg_attr(feature = "bindings", derive(TS))]
15346pub struct ReadParquet {
15347    #[serde(default)]
15348    pub expressions: Vec<Expression>,
15349}
15350
15351/// Reduce
15352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15353#[cfg_attr(feature = "bindings", derive(TS))]
15354pub struct Reduce {
15355    pub this: Box<Expression>,
15356    #[serde(default)]
15357    pub initial: Option<Box<Expression>>,
15358    #[serde(default)]
15359    pub merge: Option<Box<Expression>>,
15360    #[serde(default)]
15361    pub finish: Option<Box<Expression>>,
15362}
15363
15364/// RegexpExtractAll
15365#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15366#[cfg_attr(feature = "bindings", derive(TS))]
15367pub struct RegexpExtractAll {
15368    pub this: Box<Expression>,
15369    pub expression: Box<Expression>,
15370    #[serde(default)]
15371    pub group: Option<Box<Expression>>,
15372    #[serde(default)]
15373    pub parameters: Option<Box<Expression>>,
15374    #[serde(default)]
15375    pub position: Option<Box<Expression>>,
15376    #[serde(default)]
15377    pub occurrence: Option<Box<Expression>>,
15378}
15379
15380/// RegexpILike
15381#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15382#[cfg_attr(feature = "bindings", derive(TS))]
15383pub struct RegexpILike {
15384    pub this: Box<Expression>,
15385    pub expression: Box<Expression>,
15386    #[serde(default)]
15387    pub flag: Option<Box<Expression>>,
15388}
15389
15390/// RegexpFullMatch
15391#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15392#[cfg_attr(feature = "bindings", derive(TS))]
15393pub struct RegexpFullMatch {
15394    pub this: Box<Expression>,
15395    pub expression: Box<Expression>,
15396    #[serde(default)]
15397    pub options: Vec<Expression>,
15398}
15399
15400/// RegexpInstr
15401#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15402#[cfg_attr(feature = "bindings", derive(TS))]
15403pub struct RegexpInstr {
15404    /// Additional search boundaries and retained source semantics.
15405    #[serde(default, skip_serializing_if = "Option::is_none")]
15406    pub options: Option<RegexOptions>,
15407    pub this: Box<Expression>,
15408    pub expression: Box<Expression>,
15409    #[serde(default)]
15410    pub position: Option<Box<Expression>>,
15411    #[serde(default)]
15412    pub occurrence: Option<Box<Expression>>,
15413    #[serde(default)]
15414    pub option: Option<Box<Expression>>,
15415    #[serde(default)]
15416    pub parameters: Option<Box<Expression>>,
15417    #[serde(default)]
15418    pub group: Option<Box<Expression>>,
15419}
15420
15421/// RegexpSplit
15422#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15423#[cfg_attr(feature = "bindings", derive(TS))]
15424pub struct RegexpSplit {
15425    pub this: Box<Expression>,
15426    pub expression: Box<Expression>,
15427    #[serde(default)]
15428    pub limit: Option<Box<Expression>>,
15429}
15430
15431/// RegexpCount
15432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15433#[cfg_attr(feature = "bindings", derive(TS))]
15434pub struct RegexpCount {
15435    /// Additional search boundaries and retained source semantics.
15436    #[serde(default, skip_serializing_if = "Option::is_none")]
15437    pub options: Option<RegexOptions>,
15438    pub this: Box<Expression>,
15439    pub expression: Box<Expression>,
15440    #[serde(default)]
15441    pub position: Option<Box<Expression>>,
15442    #[serde(default)]
15443    pub parameters: Option<Box<Expression>>,
15444}
15445
15446/// RegrValx
15447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15448#[cfg_attr(feature = "bindings", derive(TS))]
15449pub struct RegrValx {
15450    pub this: Box<Expression>,
15451    pub expression: Box<Expression>,
15452}
15453
15454/// RegrValy
15455#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15456#[cfg_attr(feature = "bindings", derive(TS))]
15457pub struct RegrValy {
15458    pub this: Box<Expression>,
15459    pub expression: Box<Expression>,
15460}
15461
15462/// RegrAvgy
15463#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15464#[cfg_attr(feature = "bindings", derive(TS))]
15465pub struct RegrAvgy {
15466    pub this: Box<Expression>,
15467    pub expression: Box<Expression>,
15468}
15469
15470/// RegrAvgx
15471#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15472#[cfg_attr(feature = "bindings", derive(TS))]
15473pub struct RegrAvgx {
15474    pub this: Box<Expression>,
15475    pub expression: Box<Expression>,
15476}
15477
15478/// RegrCount
15479#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15480#[cfg_attr(feature = "bindings", derive(TS))]
15481pub struct RegrCount {
15482    pub this: Box<Expression>,
15483    pub expression: Box<Expression>,
15484}
15485
15486/// RegrIntercept
15487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15488#[cfg_attr(feature = "bindings", derive(TS))]
15489pub struct RegrIntercept {
15490    pub this: Box<Expression>,
15491    pub expression: Box<Expression>,
15492}
15493
15494/// RegrR2
15495#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15496#[cfg_attr(feature = "bindings", derive(TS))]
15497pub struct RegrR2 {
15498    pub this: Box<Expression>,
15499    pub expression: Box<Expression>,
15500}
15501
15502/// RegrSxx
15503#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15504#[cfg_attr(feature = "bindings", derive(TS))]
15505pub struct RegrSxx {
15506    pub this: Box<Expression>,
15507    pub expression: Box<Expression>,
15508}
15509
15510/// RegrSxy
15511#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15512#[cfg_attr(feature = "bindings", derive(TS))]
15513pub struct RegrSxy {
15514    pub this: Box<Expression>,
15515    pub expression: Box<Expression>,
15516}
15517
15518/// RegrSyy
15519#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15520#[cfg_attr(feature = "bindings", derive(TS))]
15521pub struct RegrSyy {
15522    pub this: Box<Expression>,
15523    pub expression: Box<Expression>,
15524}
15525
15526/// RegrSlope
15527#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15528#[cfg_attr(feature = "bindings", derive(TS))]
15529pub struct RegrSlope {
15530    pub this: Box<Expression>,
15531    pub expression: Box<Expression>,
15532}
15533
15534/// SafeAdd
15535#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15536#[cfg_attr(feature = "bindings", derive(TS))]
15537pub struct SafeAdd {
15538    pub this: Box<Expression>,
15539    pub expression: Box<Expression>,
15540}
15541
15542/// SafeDivide
15543#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15544#[cfg_attr(feature = "bindings", derive(TS))]
15545pub struct SafeDivide {
15546    pub this: Box<Expression>,
15547    pub expression: Box<Expression>,
15548}
15549
15550/// SafeMultiply
15551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15552#[cfg_attr(feature = "bindings", derive(TS))]
15553pub struct SafeMultiply {
15554    pub this: Box<Expression>,
15555    pub expression: Box<Expression>,
15556}
15557
15558/// SafeSubtract
15559#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15560#[cfg_attr(feature = "bindings", derive(TS))]
15561pub struct SafeSubtract {
15562    pub this: Box<Expression>,
15563    pub expression: Box<Expression>,
15564}
15565
15566/// SHA2
15567#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15568#[cfg_attr(feature = "bindings", derive(TS))]
15569pub struct SHA2 {
15570    pub this: Box<Expression>,
15571    #[serde(default)]
15572    pub length: Option<i64>,
15573}
15574
15575/// SHA2Digest
15576#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15577#[cfg_attr(feature = "bindings", derive(TS))]
15578pub struct SHA2Digest {
15579    pub this: Box<Expression>,
15580    #[serde(default)]
15581    pub length: Option<i64>,
15582}
15583
15584/// SortArray
15585#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15586#[cfg_attr(feature = "bindings", derive(TS))]
15587pub struct SortArray {
15588    pub this: Box<Expression>,
15589    #[serde(default)]
15590    pub asc: Option<Box<Expression>>,
15591    #[serde(default)]
15592    pub nulls_first: Option<Box<Expression>>,
15593}
15594
15595/// SplitPart
15596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15597#[cfg_attr(feature = "bindings", derive(TS))]
15598pub struct SplitPart {
15599    pub this: Box<Expression>,
15600    #[serde(default)]
15601    pub delimiter: Option<Box<Expression>>,
15602    #[serde(default)]
15603    pub part_index: Option<Box<Expression>>,
15604}
15605
15606/// SUBSTRING_INDEX(str, delim, count)
15607#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15608#[cfg_attr(feature = "bindings", derive(TS))]
15609pub struct SubstringIndex {
15610    pub this: Box<Expression>,
15611    #[serde(default)]
15612    pub delimiter: Option<Box<Expression>>,
15613    #[serde(default)]
15614    pub count: Option<Box<Expression>>,
15615}
15616
15617/// StandardHash
15618#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15619#[cfg_attr(feature = "bindings", derive(TS))]
15620pub struct StandardHash {
15621    pub this: Box<Expression>,
15622    #[serde(default)]
15623    pub expression: Option<Box<Expression>>,
15624}
15625
15626/// StrPosition
15627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15628#[cfg_attr(feature = "bindings", derive(TS))]
15629pub struct StrPosition {
15630    pub this: Box<Expression>,
15631    #[serde(default)]
15632    pub substr: Option<Box<Expression>>,
15633    #[serde(default)]
15634    pub position: Option<Box<Expression>>,
15635    #[serde(default)]
15636    pub occurrence: Option<Box<Expression>>,
15637}
15638
15639/// Search
15640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15641#[cfg_attr(feature = "bindings", derive(TS))]
15642pub struct Search {
15643    pub this: Box<Expression>,
15644    pub expression: Box<Expression>,
15645    #[serde(default)]
15646    pub json_scope: Option<Box<Expression>>,
15647    #[serde(default)]
15648    pub analyzer: Option<Box<Expression>>,
15649    #[serde(default)]
15650    pub analyzer_options: Option<Box<Expression>>,
15651    #[serde(default)]
15652    pub search_mode: Option<Box<Expression>>,
15653}
15654
15655/// SearchIp
15656#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15657#[cfg_attr(feature = "bindings", derive(TS))]
15658pub struct SearchIp {
15659    pub this: Box<Expression>,
15660    pub expression: Box<Expression>,
15661}
15662
15663/// StrToDate
15664#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15665#[cfg_attr(feature = "bindings", derive(TS))]
15666pub struct StrToDate {
15667    pub this: Box<Expression>,
15668    #[serde(default)]
15669    pub format: Option<String>,
15670    #[serde(default)]
15671    pub safe: Option<Box<Expression>>,
15672}
15673
15674/// StrToTime
15675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15676#[cfg_attr(feature = "bindings", derive(TS))]
15677pub struct StrToTime {
15678    pub this: Box<Expression>,
15679    pub format: String,
15680    #[serde(default)]
15681    pub zone: Option<Box<Expression>>,
15682    #[serde(default)]
15683    pub safe: Option<Box<Expression>>,
15684    #[serde(default)]
15685    pub target_type: Option<Box<Expression>>,
15686}
15687
15688/// StrToUnix
15689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15690#[cfg_attr(feature = "bindings", derive(TS))]
15691pub struct StrToUnix {
15692    #[serde(default)]
15693    pub this: Option<Box<Expression>>,
15694    #[serde(default)]
15695    pub format: Option<String>,
15696}
15697
15698/// StrToMap
15699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15700#[cfg_attr(feature = "bindings", derive(TS))]
15701pub struct StrToMap {
15702    pub this: Box<Expression>,
15703    #[serde(default)]
15704    pub pair_delim: Option<Box<Expression>>,
15705    #[serde(default)]
15706    pub key_value_delim: Option<Box<Expression>>,
15707    #[serde(default)]
15708    pub duplicate_resolution_callback: Option<Box<Expression>>,
15709}
15710
15711/// NumberToStr
15712#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15713#[cfg_attr(feature = "bindings", derive(TS))]
15714pub struct NumberToStr {
15715    pub this: Box<Expression>,
15716    pub format: String,
15717    #[serde(default)]
15718    pub culture: Option<Box<Expression>>,
15719}
15720
15721/// FromBase
15722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15723#[cfg_attr(feature = "bindings", derive(TS))]
15724pub struct FromBase {
15725    pub this: Box<Expression>,
15726    pub expression: Box<Expression>,
15727}
15728
15729/// Stuff
15730#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15731#[cfg_attr(feature = "bindings", derive(TS))]
15732pub struct Stuff {
15733    pub this: Box<Expression>,
15734    #[serde(default)]
15735    pub start: Option<Box<Expression>>,
15736    #[serde(default)]
15737    pub length: Option<i64>,
15738    pub expression: Box<Expression>,
15739}
15740
15741/// TimeToStr
15742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15743#[cfg_attr(feature = "bindings", derive(TS))]
15744pub struct TimeToStr {
15745    pub this: Box<Expression>,
15746    pub format: String,
15747    #[serde(default)]
15748    pub culture: Option<Box<Expression>>,
15749    #[serde(default)]
15750    pub zone: Option<Box<Expression>>,
15751}
15752
15753/// TimeStrToTime
15754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15755#[cfg_attr(feature = "bindings", derive(TS))]
15756pub struct TimeStrToTime {
15757    pub this: Box<Expression>,
15758    #[serde(default)]
15759    pub zone: Option<Box<Expression>>,
15760}
15761
15762/// TsOrDsAdd
15763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15764#[cfg_attr(feature = "bindings", derive(TS))]
15765pub struct TsOrDsAdd {
15766    pub this: Box<Expression>,
15767    pub expression: Box<Expression>,
15768    #[serde(default)]
15769    pub unit: Option<String>,
15770    #[serde(default)]
15771    pub return_type: Option<Box<Expression>>,
15772}
15773
15774/// TsOrDsDiff
15775#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15776#[cfg_attr(feature = "bindings", derive(TS))]
15777pub struct TsOrDsDiff {
15778    pub this: Box<Expression>,
15779    pub expression: Box<Expression>,
15780    #[serde(default)]
15781    pub unit: Option<String>,
15782}
15783
15784/// TsOrDsToDate
15785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15786#[cfg_attr(feature = "bindings", derive(TS))]
15787pub struct TsOrDsToDate {
15788    pub this: Box<Expression>,
15789    #[serde(default)]
15790    pub format: Option<String>,
15791    #[serde(default)]
15792    pub safe: Option<Box<Expression>>,
15793}
15794
15795/// TsOrDsToTime
15796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15797#[cfg_attr(feature = "bindings", derive(TS))]
15798pub struct TsOrDsToTime {
15799    pub this: Box<Expression>,
15800    #[serde(default)]
15801    pub format: Option<String>,
15802    #[serde(default)]
15803    pub safe: Option<Box<Expression>>,
15804}
15805
15806/// Unhex
15807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15808#[cfg_attr(feature = "bindings", derive(TS))]
15809pub struct Unhex {
15810    pub this: Box<Expression>,
15811    #[serde(default)]
15812    pub expression: Option<Box<Expression>>,
15813}
15814
15815/// Uniform
15816#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15817#[cfg_attr(feature = "bindings", derive(TS))]
15818pub struct Uniform {
15819    pub this: Box<Expression>,
15820    pub expression: Box<Expression>,
15821    #[serde(default)]
15822    pub gen: Option<Box<Expression>>,
15823    #[serde(default)]
15824    pub seed: Option<Box<Expression>>,
15825}
15826
15827/// UnixToStr
15828#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15829#[cfg_attr(feature = "bindings", derive(TS))]
15830pub struct UnixToStr {
15831    pub this: Box<Expression>,
15832    #[serde(default)]
15833    pub format: Option<String>,
15834}
15835
15836/// UnixToTime
15837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15838#[cfg_attr(feature = "bindings", derive(TS))]
15839pub struct UnixToTime {
15840    pub this: Box<Expression>,
15841    #[serde(default)]
15842    pub scale: Option<i64>,
15843    #[serde(default)]
15844    pub zone: Option<Box<Expression>>,
15845    #[serde(default)]
15846    pub hours: Option<Box<Expression>>,
15847    #[serde(default)]
15848    pub minutes: Option<Box<Expression>>,
15849    #[serde(default)]
15850    pub format: Option<String>,
15851    #[serde(default)]
15852    pub target_type: Option<Box<Expression>>,
15853}
15854
15855/// Uuid
15856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15857#[cfg_attr(feature = "bindings", derive(TS))]
15858pub struct Uuid {
15859    #[serde(default)]
15860    pub this: Option<Box<Expression>>,
15861    #[serde(default)]
15862    pub name: Option<String>,
15863    #[serde(default)]
15864    pub is_string: Option<Box<Expression>>,
15865}
15866
15867/// TimestampFromParts
15868#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15869#[cfg_attr(feature = "bindings", derive(TS))]
15870pub struct TimestampFromParts {
15871    #[serde(default)]
15872    pub zone: Option<Box<Expression>>,
15873    #[serde(default)]
15874    pub milli: Option<Box<Expression>>,
15875    #[serde(default)]
15876    pub this: Option<Box<Expression>>,
15877    #[serde(default)]
15878    pub expression: Option<Box<Expression>>,
15879}
15880
15881/// TimestampTzFromParts
15882#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15883#[cfg_attr(feature = "bindings", derive(TS))]
15884pub struct TimestampTzFromParts {
15885    #[serde(default)]
15886    pub zone: Option<Box<Expression>>,
15887}
15888
15889/// Corr
15890#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15891#[cfg_attr(feature = "bindings", derive(TS))]
15892pub struct Corr {
15893    pub this: Box<Expression>,
15894    pub expression: Box<Expression>,
15895    #[serde(default)]
15896    pub null_on_zero_variance: Option<Box<Expression>>,
15897}
15898
15899/// WidthBucket
15900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15901#[cfg_attr(feature = "bindings", derive(TS))]
15902pub struct WidthBucket {
15903    pub this: Box<Expression>,
15904    #[serde(default)]
15905    pub min_value: Option<Box<Expression>>,
15906    #[serde(default)]
15907    pub max_value: Option<Box<Expression>>,
15908    #[serde(default)]
15909    pub num_buckets: Option<Box<Expression>>,
15910    #[serde(default)]
15911    pub threshold: Option<Box<Expression>>,
15912}
15913
15914/// CovarSamp
15915#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15916#[cfg_attr(feature = "bindings", derive(TS))]
15917pub struct CovarSamp {
15918    pub this: Box<Expression>,
15919    pub expression: Box<Expression>,
15920}
15921
15922/// CovarPop
15923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15924#[cfg_attr(feature = "bindings", derive(TS))]
15925pub struct CovarPop {
15926    pub this: Box<Expression>,
15927    pub expression: Box<Expression>,
15928}
15929
15930/// Week
15931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15932#[cfg_attr(feature = "bindings", derive(TS))]
15933pub struct Week {
15934    pub this: Box<Expression>,
15935    #[serde(default)]
15936    pub mode: Option<Box<Expression>>,
15937}
15938
15939/// XMLElement
15940#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15941#[cfg_attr(feature = "bindings", derive(TS))]
15942pub struct XMLElement {
15943    pub this: Box<Expression>,
15944    #[serde(default)]
15945    pub expressions: Vec<Expression>,
15946    #[serde(default)]
15947    pub evalname: Option<Box<Expression>>,
15948}
15949
15950/// XMLGet
15951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15952#[cfg_attr(feature = "bindings", derive(TS))]
15953pub struct XMLGet {
15954    pub this: Box<Expression>,
15955    pub expression: Box<Expression>,
15956    #[serde(default)]
15957    pub instance: Option<Box<Expression>>,
15958}
15959
15960/// XMLTable
15961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15962#[cfg_attr(feature = "bindings", derive(TS))]
15963pub struct XMLTable {
15964    pub this: Box<Expression>,
15965    #[serde(default)]
15966    pub namespaces: Option<Box<Expression>>,
15967    #[serde(default)]
15968    pub passing: Option<Box<Expression>>,
15969    #[serde(default)]
15970    pub columns: Vec<Expression>,
15971    #[serde(default)]
15972    pub by_ref: Option<Box<Expression>>,
15973}
15974
15975/// XMLKeyValueOption
15976#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15977#[cfg_attr(feature = "bindings", derive(TS))]
15978pub struct XMLKeyValueOption {
15979    pub this: Box<Expression>,
15980    #[serde(default)]
15981    pub expression: Option<Box<Expression>>,
15982}
15983
15984/// Zipf
15985#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15986#[cfg_attr(feature = "bindings", derive(TS))]
15987pub struct Zipf {
15988    pub this: Box<Expression>,
15989    #[serde(default)]
15990    pub elementcount: Option<Box<Expression>>,
15991    #[serde(default)]
15992    pub gen: Option<Box<Expression>>,
15993}
15994
15995/// Merge
15996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15997#[cfg_attr(feature = "bindings", derive(TS))]
15998pub struct Merge {
15999    pub this: Box<Expression>,
16000    pub using: Box<Expression>,
16001    #[serde(default)]
16002    pub on: Option<Box<Expression>>,
16003    #[serde(default)]
16004    pub using_cond: Option<Box<Expression>>,
16005    #[serde(default)]
16006    pub whens: Option<Box<Expression>>,
16007    #[serde(default)]
16008    pub with_: Option<Box<Expression>>,
16009    #[serde(default)]
16010    pub returning: Option<Box<Expression>>,
16011}
16012
16013/// When
16014#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16015#[cfg_attr(feature = "bindings", derive(TS))]
16016pub struct When {
16017    #[serde(default)]
16018    pub matched: Option<Box<Expression>>,
16019    #[serde(default)]
16020    pub source: Option<Box<Expression>>,
16021    #[serde(default)]
16022    pub condition: Option<Box<Expression>>,
16023    pub then: Box<Expression>,
16024}
16025
16026/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
16027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16028#[cfg_attr(feature = "bindings", derive(TS))]
16029pub struct Whens {
16030    #[serde(default)]
16031    pub expressions: Vec<Expression>,
16032}
16033
16034/// NextValueFor
16035#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16036#[cfg_attr(feature = "bindings", derive(TS))]
16037pub struct NextValueFor {
16038    pub this: Box<Expression>,
16039    #[serde(default)]
16040    pub order: Option<Box<Expression>>,
16041}
16042
16043// Vertica dialect support.
16044/// Native Vertica syntax, retaining semantics through serialization and traversal.
16045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16046#[cfg_attr(feature = "bindings", derive(TS))]
16047#[serde(tag = "kind", rename_all = "snake_case")]
16048pub enum VerticaExpression {
16049    PhysicalTable {
16050        this: Expression,
16051        physical: VerticaPhysical,
16052    },
16053    FlexTable {
16054        this: Expression,
16055        physical: VerticaPhysical,
16056    },
16057    Projection {
16058        name: TableRef,
16059        columns: Vec<VerticaProjectionColumn>,
16060        query: Expression,
16061        physical: VerticaPhysical,
16062    },
16063    Copy {
16064        table: TableRef,
16065        columns: Vec<Identifier>,
16066        local: bool,
16067        sources: Vec<Expression>,
16068        parser: Option<VerticaParserCall>,
16069        options: Vec<VerticaParameter>,
16070    },
16071    ExportParquet {
16072        options: Vec<VerticaParameter>,
16073        over: Option<Over>,
16074        query: Expression,
16075    },
16076    Interpolate {
16077        left: Expression,
16078        right: Expression,
16079        previous: bool,
16080    },
16081    /// Zero-based array access retains source bounds semantics from parsing.
16082    ArrayAccess {
16083        this: Expression,
16084        indices: Vec<Expression>,
16085    },
16086    ArraySlice {
16087        this: Expression,
16088        start: Option<Expression>,
16089        end: Option<Expression>,
16090    },
16091    BoundaryDateDiff {
16092        start: Expression,
16093        end: Expression,
16094        unit: IntervalUnit,
16095    },
16096    UsingParameters {
16097        this: Expression,
16098        parameters: Vec<VerticaParameter>,
16099    },
16100    SafeCast {
16101        this: Expression,
16102        to: DataType,
16103    },
16104    Set {
16105        values: Vec<Expression>,
16106    },
16107    Interval {
16108        value: Expression,
16109        precision: Option<u32>,
16110        year_month: bool,
16111        unit: Option<String>,
16112        end_unit: Option<String>,
16113    },
16114    /// Hexadecimal byte value, distinct from PostgreSQL's bit strings.
16115    Binary {
16116        hex: String,
16117    },
16118    Historical {
16119        query: Expression,
16120        point: VerticaHistoricalPoint,
16121    },
16122    PartitionBest,
16123}
16124
16125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16126#[cfg_attr(feature = "bindings", derive(TS))]
16127pub struct VerticaParameter {
16128    pub name: Identifier,
16129    pub value: Expression,
16130}
16131
16132#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16133#[cfg_attr(feature = "bindings", derive(TS))]
16134#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
16135pub enum VerticaHistoricalPoint {
16136    Latest,
16137    Epoch(Expression),
16138    Time(Expression),
16139}
16140
16141#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16142#[cfg_attr(feature = "bindings", derive(TS))]
16143#[serde(tag = "kind", rename_all = "snake_case")]
16144pub enum VerticaDataType {
16145    Array {
16146        element_type: DataType,
16147        bound: Option<VerticaCollectionBound>,
16148    },
16149    Set {
16150        element_type: DataType,
16151        bound: Option<VerticaCollectionBound>,
16152    },
16153    Row {
16154        fields: Vec<StructField>,
16155    },
16156    LongVarBinary {
16157        length: Option<u32>,
16158    },
16159    Interval {
16160        precision: Option<u32>,
16161        year_month: bool,
16162        unit: Option<String>,
16163        end_unit: Option<String>,
16164    },
16165}
16166
16167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16168#[cfg_attr(feature = "bindings", derive(TS))]
16169#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
16170pub enum VerticaCollectionBound {
16171    Elements(u32),
16172    Bytes(u32),
16173}
16174
16175#[derive(
16176    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
16177)]
16178#[cfg_attr(feature = "bindings", derive(TS))]
16179pub struct VerticaSelectExtensions {
16180    pub timeseries: Option<VerticaTimeseries>,
16181    pub match_clause: Option<VerticaMatch>,
16182    pub limit_over: Option<Over>,
16183}
16184
16185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16186#[cfg_attr(feature = "bindings", derive(TS))]
16187pub struct VerticaTimeseries {
16188    pub alias: Identifier,
16189    pub interval: Expression,
16190    pub over: Over,
16191}
16192
16193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16194#[cfg_attr(feature = "bindings", derive(TS))]
16195pub struct VerticaMatch {
16196    pub partition_by: Vec<Expression>,
16197    pub order_by: Vec<Ordered>,
16198    pub definitions: Vec<VerticaParameter>,
16199    pub name: Identifier,
16200    pub pattern: VerticaPattern,
16201    /// None = default; true = FIRST EVENT; false = ALL EVENTS.
16202    pub first_event: Option<bool>,
16203}
16204
16205#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16206#[cfg_attr(feature = "bindings", derive(TS))]
16207#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
16208pub enum VerticaPattern {
16209    Event(Identifier),
16210    Sequence(Vec<VerticaPattern>),
16211    Alternative(Vec<VerticaPattern>),
16212    Group(Box<VerticaPattern>),
16213    Repeat {
16214        pattern: Box<VerticaPattern>,
16215        quantifier: String,
16216    },
16217}
16218
16219#[derive(
16220    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
16221)]
16222#[cfg_attr(feature = "bindings", derive(TS))]
16223pub struct VerticaPhysical {
16224    pub order_by: Vec<Ordered>,
16225    pub segmentation: Option<VerticaSegmentation>,
16226    pub ksafe: Option<VerticaKsafe>,
16227}
16228
16229#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16230#[cfg_attr(feature = "bindings", derive(TS))]
16231#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
16232pub enum VerticaKsafe {
16233    Default,
16234    Level(u32),
16235}
16236
16237#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16238#[cfg_attr(feature = "bindings", derive(TS))]
16239#[serde(tag = "kind", rename_all = "snake_case")]
16240pub enum VerticaSegmentation {
16241    Segmented {
16242        expression: Expression,
16243        offset: Option<u32>,
16244    },
16245    Unsegmented {
16246        node: Option<Identifier>,
16247    },
16248}
16249
16250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16251#[cfg_attr(feature = "bindings", derive(TS))]
16252pub struct VerticaProjectionColumn {
16253    pub name: Identifier,
16254    pub encoding: Option<Identifier>,
16255}
16256
16257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16258#[cfg_attr(feature = "bindings", derive(TS))]
16259pub struct VerticaParserCall {
16260    pub name: TableRef,
16261    pub parameters: Vec<VerticaParameter>,
16262}
16263
16264#[cfg(test)]
16265mod tests {
16266    use super::*;
16267
16268    #[test]
16269    fn test_source_spans_are_metadata_not_expression_identity() {
16270        let plain = Expression::column("customer_id");
16271        let mut positioned = plain.clone();
16272        if let Expression::Column(column) = &mut positioned {
16273            column.span = Some(Span::new(7, 18, 1, 19));
16274            column.name.span = column.span;
16275        }
16276        assert_eq!(plain, positioned);
16277        assert_ne!(
16278            serde_json::to_value(&plain).unwrap(),
16279            serde_json::to_value(&positioned).unwrap()
16280        );
16281        assert_eq!(
16282            Identifier::new("a"),
16283            Identifier::new("a").with_span(Span::new(3, 4, 1, 5))
16284        );
16285        assert_ne!(Identifier::new("a"), Identifier::quoted("a"));
16286        assert_ne!(plain, Expression::column("other"));
16287        let Expression::Column(column) = plain else {
16288            unreachable!()
16289        };
16290        assert!(column.span.is_none() && column.name.span.is_none());
16291    }
16292
16293    #[test]
16294    #[cfg(feature = "bindings")]
16295    fn export_typescript_types() {
16296        // This test exports TypeScript types to the generated directory
16297        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
16298        Expression::export_all(&ts_rs::Config::default())
16299            .expect("Failed to export Expression types");
16300
16301        let mut variant_names = String::from(
16302            "// This file was generated from the Rust Expression enum. Do not edit it manually.\n\n",
16303        );
16304        variant_names.push_str("export const EXPRESSION_VARIANT_NAMES = [\n");
16305        for name in Expression::SERIALIZED_VARIANT_NAMES {
16306            use std::fmt::Write;
16307            writeln!(variant_names, "  {name:?},").expect("writing to a String cannot fail");
16308        }
16309        variant_names.push_str("] as const;\n");
16310
16311        let output_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
16312            .join("bindings/ExpressionVariantNames.ts");
16313        std::fs::write(output_path, variant_names)
16314            .expect("Failed to export serialized Expression variant names");
16315    }
16316
16317    #[test]
16318    fn test_simple_select_builder() {
16319        let select = Select::new()
16320            .column(Expression::star())
16321            .from(Expression::Table(Box::new(TableRef::new("users"))));
16322
16323        assert_eq!(select.expressions.len(), 1);
16324        assert!(select.from.is_some());
16325    }
16326
16327    #[test]
16328    fn test_expression_alias() {
16329        let expr = Expression::column("id").alias("user_id");
16330
16331        match expr {
16332            Expression::Alias(a) => {
16333                assert_eq!(a.alias.name, "user_id");
16334            }
16335            _ => panic!("Expected Alias"),
16336        }
16337    }
16338
16339    #[test]
16340    fn test_literal_creation() {
16341        let num = Expression::number(42);
16342        let str = Expression::string("hello");
16343
16344        match num {
16345            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
16346                let Literal::Number(n) = lit.as_ref() else {
16347                    unreachable!()
16348                };
16349                assert_eq!(n, "42")
16350            }
16351            _ => panic!("Expected Number"),
16352        }
16353
16354        match str {
16355            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
16356                let Literal::String(s) = lit.as_ref() else {
16357                    unreachable!()
16358                };
16359                assert_eq!(s, "hello")
16360            }
16361            _ => panic!("Expected String"),
16362        }
16363    }
16364
16365    #[test]
16366    fn test_expression_sql() {
16367        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
16368        assert_eq!(expr.sql(), "SELECT 1 + 2");
16369    }
16370
16371    #[test]
16372    fn test_expression_sql_for() {
16373        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
16374        let sql = expr.sql_for(crate::DialectType::Generic);
16375        // Generic mode normalizes IF() to CASE WHEN
16376        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
16377    }
16378}