Skip to main content

polyglot_sql/
expressions.rs

1//! SQL Expression AST (Abstract Syntax Tree).
2//!
3//! This module defines all the AST node types used to represent parsed SQL
4//! statements and expressions. The design follows Python sqlglot's expression
5//! hierarchy, ported to a Rust enum-based AST.
6//!
7//! # Architecture
8//!
9//! The central type is [`Expression`], a large tagged enum with one variant per
10//! SQL construct. Inner structs carry the fields for each variant. Most
11//! heap-allocated variants are wrapped in `Box` to keep the enum size small.
12//!
13//! # Variant Groups
14//!
15//! | Group | Examples | Purpose |
16//! |---|---|---|
17//! | **Queries** | `Select`, `Union`, `Intersect`, `Except`, `Subquery` | Top-level query structures |
18//! | **DML** | `Insert`, `Update`, `Delete`, `Merge`, `Copy` | Data manipulation |
19//! | **DDL** | `CreateTable`, `AlterTable`, `DropView`, `CreateIndex` | Schema definition |
20//! | **Clauses** | `From`, `Join`, `Where`, `GroupBy`, `OrderBy`, `With` | Query clauses |
21//! | **Operators** | `And`, `Or`, `Add`, `Eq`, `Like`, `Not` | Binary and unary operations |
22//! | **Functions** | `Function`, `AggregateFunction`, `WindowFunction`, `Count`, `Sum` | Scalar, aggregate, and window functions |
23//! | **Literals** | `Literal`, `Boolean`, `Null`, `Interval` | Constant values |
24//! | **Types** | `DataType`, `Cast`, `TryCast`, `SafeCast` | Data types and casts |
25//! | **Identifiers** | `Identifier`, `Column`, `Table`, `Star` | Name references |
26//!
27//! # SQL Generation
28//!
29//! Every `Expression` can be rendered back to SQL via [`Expression::sql()`]
30//! (generic dialect) or [`Expression::sql_for()`] (specific dialect). The
31//! actual generation logic lives in the `generator` module.
32
33use crate::tokens::Span;
34use serde::{Deserialize, Serialize};
35use std::fmt;
36#[cfg(feature = "bindings")]
37use ts_rs::TS;
38
39/// Helper function for serde default value
40fn default_true() -> bool {
41    true
42}
43
44fn is_true(v: &bool) -> bool {
45    *v
46}
47
48/// Represent any SQL expression or statement as a single, recursive AST node.
49///
50/// `Expression` is the root type of the polyglot AST. Every parsed SQL
51/// construct -- from a simple integer literal to a multi-CTE query with
52/// window functions -- is represented as a variant of this enum.
53///
54/// Variants are organized into logical groups (see the module-level docs).
55/// Most non-trivial variants box their payload so that `size_of::<Expression>()`
56/// stays small (currently two words: tag + pointer).
57///
58/// # Constructing Expressions
59///
60/// Use the convenience constructors on `impl Expression` for common cases:
61///
62/// ```rust,ignore
63/// use polyglot_sql::expressions::Expression;
64///
65/// let col  = Expression::column("id");
66/// let lit  = Expression::number(42);
67/// let star = Expression::star();
68/// ```
69///
70/// # Generating SQL
71///
72/// ```rust,ignore
73/// let expr = Expression::column("name");
74/// assert_eq!(expr.sql(), "name");
75/// ```
76#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
77#[cfg_attr(feature = "bindings", derive(TS))]
78#[serde(rename_all = "snake_case")]
79#[cfg_attr(feature = "bindings", ts(export))]
80pub enum Expression {
81    /// Structured Vertica syntax whose semantics are not shared by other dialects.
82    Vertica(Box<VerticaExpression>),
83    // Literals
84    Literal(Box<Literal>),
85    Boolean(BooleanLiteral),
86    Null(Null),
87
88    // Identifiers
89    Identifier(Identifier),
90    Column(Box<Column>),
91    Table(Box<TableRef>),
92    Star(Star),
93    /// Snowflake braced wildcard syntax: {*}, {tbl.*}, {* EXCLUDE (...)}, {* ILIKE '...'}
94    BracedWildcard(Box<Expression>),
95
96    // Queries
97    Select(Box<Select>),
98    Union(Box<Union>),
99    Intersect(Box<Intersect>),
100    Except(Box<Except>),
101    Subquery(Box<Subquery>),
102    PipeOperator(Box<PipeOperator>),
103    Pivot(Box<Pivot>),
104    PivotAlias(Box<PivotAlias>),
105    Unpivot(Box<Unpivot>),
106    Values(Box<Values>),
107    PreWhere(Box<PreWhere>),
108    Stream(Box<Stream>),
109    UsingData(Box<UsingData>),
110    XmlNamespace(Box<XmlNamespace>),
111
112    // DML
113    Insert(Box<Insert>),
114    Update(Box<Update>),
115    Delete(Box<Delete>),
116    Copy(Box<CopyStmt>),
117    Put(Box<PutStmt>),
118    StageReference(Box<StageReference>),
119    TryCatch(Box<TryCatch>),
120
121    // Expressions
122    Alias(Box<Alias>),
123    Cast(Box<Cast>),
124    Collation(Box<CollationExpr>),
125    Case(Box<Case>),
126
127    // Binary operations
128    And(Box<BinaryOp>),
129    Or(Box<BinaryOp>),
130    Add(Box<BinaryOp>),
131    Sub(Box<BinaryOp>),
132    Mul(Box<BinaryOp>),
133    Div(Box<BinaryOp>),
134    Mod(Box<BinaryOp>),
135    Eq(Box<BinaryOp>),
136    Neq(Box<BinaryOp>),
137    Lt(Box<BinaryOp>),
138    Lte(Box<BinaryOp>),
139    Gt(Box<BinaryOp>),
140    Gte(Box<BinaryOp>),
141    Like(Box<LikeOp>),
142    ILike(Box<LikeOp>),
143    /// SQLite MATCH operator (FTS)
144    Match(Box<BinaryOp>),
145    BitwiseAnd(Box<BinaryOp>),
146    BitwiseOr(Box<BinaryOp>),
147    BitwiseXor(Box<BinaryOp>),
148    Concat(Box<BinaryOp>),
149    Adjacent(Box<BinaryOp>),   // PostgreSQL range adjacency operator (-|-)
150    TsMatch(Box<BinaryOp>),    // PostgreSQL text search match operator (@@)
151    PropertyEQ(Box<BinaryOp>), // := assignment operator (MySQL @var := val, DuckDB named args)
152
153    // PostgreSQL array/JSONB operators
154    ArrayContainsAll(Box<BinaryOp>), // @> operator (array contains all)
155    ArrayContainedBy(Box<BinaryOp>), // <@ operator (array contained by)
156    ArrayOverlaps(Box<BinaryOp>),    // && operator (array overlaps)
157    JSONBContainsAllTopKeys(Box<BinaryOp>), // ?& operator (JSONB contains all keys)
158    JSONBContainsAnyTopKeys(Box<BinaryOp>), // ?| operator (JSONB contains any key)
159    JSONBDeleteAtPath(Box<BinaryOp>), // #- operator (JSONB delete at path)
160    ExtendsLeft(Box<BinaryOp>),      // &< operator (PostgreSQL range extends left)
161    ExtendsRight(Box<BinaryOp>),     // &> operator (PostgreSQL range extends right)
162
163    // Unary operations
164    Not(Box<UnaryOp>),
165    Neg(Box<UnaryOp>),
166    BitwiseNot(Box<UnaryOp>),
167
168    // Predicates
169    In(Box<In>),
170    Between(Box<Between>),
171    IsNull(Box<IsNull>),
172    IsTrue(Box<IsTrueFalse>),
173    IsFalse(Box<IsTrueFalse>),
174    IsJson(Box<IsJson>),
175    Is(Box<BinaryOp>), // General IS expression (e.g., a IS ?)
176    Exists(Box<Exists>),
177    /// MySQL MEMBER OF operator: expr MEMBER OF(json_array)
178    MemberOf(Box<BinaryOp>),
179
180    // Functions
181    Function(Box<Function>),
182
183    Upsert(Box<Upsert>),
184    StorageProperty(Box<StorageProperty>),
185    Hierarchy(Box<Hierarchy>),
186    ViewParameter(Box<ViewParameter>),
187    Call(Box<Call>),
188
189    AggregateFunction(Box<AggregateFunction>),
190    WindowFunction(Box<WindowFunction>),
191
192    // Clauses
193    From(Box<From>),
194    Join(Box<Join>),
195    JoinedTable(Box<JoinedTable>),
196    Where(Box<Where>),
197    GroupBy(Box<GroupBy>),
198    Having(Box<Having>),
199    OrderBy(Box<OrderBy>),
200    Limit(Box<Limit>),
201    Offset(Box<Offset>),
202    Qualify(Box<Qualify>),
203    With(Box<With>),
204    Cte(Box<Cte>),
205    DistributeBy(Box<DistributeBy>),
206    ClusterBy(Box<ClusterBy>),
207    SortBy(Box<SortBy>),
208    LateralView(Box<LateralView>),
209    Hint(Box<Hint>),
210    Pseudocolumn(Pseudocolumn),
211
212    // Oracle hierarchical queries (CONNECT BY)
213    Connect(Box<Connect>),
214    Prior(Box<Prior>),
215    ConnectByRoot(Box<ConnectByRoot>),
216
217    // Pattern matching (MATCH_RECOGNIZE)
218    MatchRecognize(Box<MatchRecognize>),
219
220    // Order expressions
221    Ordered(Box<Ordered>),
222
223    // Window specifications
224    Window(Box<WindowSpec>),
225    Over(Box<Over>),
226    WithinGroup(Box<WithinGroup>),
227
228    // Data types
229    DataType(DataType),
230
231    // Arrays and structs
232    Array(Box<Array>),
233    Struct(Box<Struct>),
234    Tuple(Box<Tuple>),
235
236    // Interval
237    Interval(Box<Interval>),
238
239    // String functions
240    ConcatWs(Box<ConcatWs>),
241    Substring(Box<SubstringFunc>),
242    Upper(Box<UnaryFunc>),
243    Lower(Box<UnaryFunc>),
244    Length(Box<UnaryFunc>),
245    Trim(Box<TrimFunc>),
246    LTrim(Box<UnaryFunc>),
247    RTrim(Box<UnaryFunc>),
248    Replace(Box<ReplaceFunc>),
249    Reverse(Box<UnaryFunc>),
250    Left(Box<LeftRightFunc>),
251    Right(Box<LeftRightFunc>),
252    Repeat(Box<RepeatFunc>),
253    Lpad(Box<PadFunc>),
254    Rpad(Box<PadFunc>),
255    Split(Box<SplitFunc>),
256    RegexpLike(Box<RegexpFunc>),
257    RegexpReplace(Box<RegexpReplaceFunc>),
258    RegexpExtract(Box<RegexpExtractFunc>),
259    Overlay(Box<OverlayFunc>),
260
261    // Math functions
262    Abs(Box<UnaryFunc>),
263    Round(Box<RoundFunc>),
264    Floor(Box<FloorFunc>),
265    Ceil(Box<CeilFunc>),
266    Power(Box<BinaryFunc>),
267    Sqrt(Box<UnaryFunc>),
268    Cbrt(Box<UnaryFunc>),
269    Ln(Box<UnaryFunc>),
270    Log(Box<LogFunc>),
271    Exp(Box<UnaryFunc>),
272    Sign(Box<UnaryFunc>),
273    Greatest(Box<VarArgFunc>),
274    Least(Box<VarArgFunc>),
275
276    // Date/time functions
277    CurrentDate(CurrentDate),
278    CurrentTime(CurrentTime),
279    CurrentTimestamp(CurrentTimestamp),
280    CurrentTimestampLTZ(CurrentTimestampLTZ),
281    AtTimeZone(Box<AtTimeZone>),
282    DateAdd(Box<DateAddFunc>),
283    DateSub(Box<DateAddFunc>),
284    DateDiff(Box<DateDiffFunc>),
285    DateTrunc(Box<DateTruncFunc>),
286    Extract(Box<ExtractFunc>),
287    ToDate(Box<ToDateFunc>),
288    ToTimestamp(Box<ToTimestampFunc>),
289    Date(Box<UnaryFunc>),
290    Time(Box<UnaryFunc>),
291    DateFromUnixDate(Box<UnaryFunc>),
292    UnixDate(Box<UnaryFunc>),
293    UnixSeconds(Box<UnaryFunc>),
294    UnixMillis(Box<UnaryFunc>),
295    UnixMicros(Box<UnaryFunc>),
296    UnixToTimeStr(Box<BinaryFunc>),
297    TimeStrToDate(Box<UnaryFunc>),
298    DateToDi(Box<UnaryFunc>),
299    DiToDate(Box<UnaryFunc>),
300    TsOrDiToDi(Box<UnaryFunc>),
301    TsOrDsToDatetime(Box<UnaryFunc>),
302    TsOrDsToTimestamp(Box<UnaryFunc>),
303    YearOfWeek(Box<UnaryFunc>),
304    YearOfWeekIso(Box<UnaryFunc>),
305
306    // Control flow functions
307    Coalesce(Box<VarArgFunc>),
308    NullIf(Box<BinaryFunc>),
309    IfFunc(Box<IfFunc>),
310    IfNull(Box<BinaryFunc>),
311    Nvl(Box<BinaryFunc>),
312    Nvl2(Box<Nvl2Func>),
313
314    // Type conversion
315    TryCast(Box<Cast>),
316    SafeCast(Box<Cast>),
317
318    // Typed aggregate functions
319    Count(Box<CountFunc>),
320    Sum(Box<AggFunc>),
321    Avg(Box<AggFunc>),
322    Min(Box<AggFunc>),
323    Max(Box<AggFunc>),
324    GroupConcat(Box<GroupConcatFunc>),
325    StringAgg(Box<StringAggFunc>),
326    ListAgg(Box<ListAggFunc>),
327    ArrayAgg(Box<AggFunc>),
328    CountIf(Box<AggFunc>),
329    SumIf(Box<SumIfFunc>),
330    Stddev(Box<AggFunc>),
331    StddevPop(Box<AggFunc>),
332    StddevSamp(Box<AggFunc>),
333    Variance(Box<AggFunc>),
334    VarPop(Box<AggFunc>),
335    VarSamp(Box<AggFunc>),
336    Median(Box<AggFunc>),
337    Mode(Box<AggFunc>),
338    First(Box<AggFunc>),
339    Last(Box<AggFunc>),
340    AnyValue(Box<AggFunc>),
341    ApproxDistinct(Box<AggFunc>),
342    ApproxCountDistinct(Box<AggFunc>),
343    ApproxPercentile(Box<ApproxPercentileFunc>),
344    Percentile(Box<PercentileFunc>),
345    LogicalAnd(Box<AggFunc>),
346    LogicalOr(Box<AggFunc>),
347    Skewness(Box<AggFunc>),
348    BitwiseCount(Box<UnaryFunc>),
349    ArrayConcatAgg(Box<AggFunc>),
350    ArrayUniqueAgg(Box<AggFunc>),
351    BoolXorAgg(Box<AggFunc>),
352
353    // Typed window functions
354    RowNumber(RowNumber),
355    Rank(Rank),
356    DenseRank(DenseRank),
357    NTile(Box<NTileFunc>),
358    Lead(Box<LeadLagFunc>),
359    Lag(Box<LeadLagFunc>),
360    FirstValue(Box<ValueFunc>),
361    LastValue(Box<ValueFunc>),
362    NthValue(Box<NthValueFunc>),
363    PercentRank(PercentRank),
364    CumeDist(CumeDist),
365    PercentileCont(Box<PercentileFunc>),
366    PercentileDisc(Box<PercentileFunc>),
367
368    // Additional string functions
369    Contains(Box<BinaryFunc>),
370    StartsWith(Box<BinaryFunc>),
371    EndsWith(Box<BinaryFunc>),
372    Position(Box<PositionFunc>),
373    Initcap(Box<UnaryFunc>),
374    Ascii(Box<UnaryFunc>),
375    Chr(Box<UnaryFunc>),
376    /// MySQL CHAR function with multiple args and optional USING charset
377    CharFunc(Box<CharFunc>),
378    Soundex(Box<UnaryFunc>),
379    Levenshtein(Box<BinaryFunc>),
380    ByteLength(Box<UnaryFunc>),
381    Hex(Box<UnaryFunc>),
382    LowerHex(Box<UnaryFunc>),
383    Unicode(Box<UnaryFunc>),
384
385    // Additional math functions
386    ModFunc(Box<BinaryFunc>),
387    Random(Random),
388    Rand(Box<Rand>),
389    TruncFunc(Box<TruncateFunc>),
390    Pi(Pi),
391    Radians(Box<UnaryFunc>),
392    Degrees(Box<UnaryFunc>),
393    Sin(Box<UnaryFunc>),
394    Cos(Box<UnaryFunc>),
395    Tan(Box<UnaryFunc>),
396    Asin(Box<UnaryFunc>),
397    Acos(Box<UnaryFunc>),
398    Atan(Box<UnaryFunc>),
399    Atan2(Box<BinaryFunc>),
400    IsNan(Box<UnaryFunc>),
401    IsInf(Box<UnaryFunc>),
402    IntDiv(Box<BinaryFunc>),
403
404    // Control flow
405    Decode(Box<DecodeFunc>),
406
407    // Additional date/time functions
408    DateFormat(Box<DateFormatFunc>),
409    FormatDate(Box<DateFormatFunc>),
410    Year(Box<UnaryFunc>),
411    Month(Box<UnaryFunc>),
412    Day(Box<UnaryFunc>),
413    Hour(Box<UnaryFunc>),
414    Minute(Box<UnaryFunc>),
415    Second(Box<UnaryFunc>),
416    DayOfWeek(Box<UnaryFunc>),
417    DayOfWeekIso(Box<UnaryFunc>),
418    DayOfMonth(Box<UnaryFunc>),
419    DayOfYear(Box<UnaryFunc>),
420    WeekOfYear(Box<UnaryFunc>),
421    Quarter(Box<UnaryFunc>),
422    AddMonths(Box<BinaryFunc>),
423    MonthsBetween(Box<BinaryFunc>),
424    LastDay(Box<LastDayFunc>),
425    NextDay(Box<BinaryFunc>),
426    Epoch(Box<UnaryFunc>),
427    EpochMs(Box<UnaryFunc>),
428    FromUnixtime(Box<FromUnixtimeFunc>),
429    UnixTimestamp(Box<UnixTimestampFunc>),
430    MakeDate(Box<MakeDateFunc>),
431    MakeTimestamp(Box<MakeTimestampFunc>),
432    TimestampTrunc(Box<DateTruncFunc>),
433    TimeStrToUnix(Box<UnaryFunc>),
434
435    // Session/User functions
436    SessionUser(SessionUser),
437
438    // Hash/Crypto functions
439    SHA(Box<UnaryFunc>),
440    SHA1Digest(Box<UnaryFunc>),
441
442    // Time conversion functions
443    TimeToUnix(Box<UnaryFunc>),
444
445    // Array functions
446    ArrayFunc(Box<ArrayConstructor>),
447    ArrayLength(Box<UnaryFunc>),
448    ArraySize(Box<UnaryFunc>),
449    Cardinality(Box<UnaryFunc>),
450    ArrayContains(Box<BinaryFunc>),
451    ArrayPosition(Box<BinaryFunc>),
452    ArrayAppend(Box<BinaryFunc>),
453    ArrayPrepend(Box<BinaryFunc>),
454    ArrayConcat(Box<VarArgFunc>),
455    ArraySort(Box<ArraySortFunc>),
456    ArrayReverse(Box<UnaryFunc>),
457    ArrayDistinct(Box<UnaryFunc>),
458    ArrayJoin(Box<ArrayJoinFunc>),
459    ArrayToString(Box<ArrayJoinFunc>),
460    Unnest(Box<UnnestFunc>),
461    Explode(Box<UnaryFunc>),
462    ExplodeOuter(Box<UnaryFunc>),
463    ArrayFilter(Box<ArrayFilterFunc>),
464    ArrayTransform(Box<ArrayTransformFunc>),
465    ArrayFlatten(Box<UnaryFunc>),
466    ArrayCompact(Box<UnaryFunc>),
467    ArrayIntersect(Box<VarArgFunc>),
468    ArrayUnion(Box<BinaryFunc>),
469    ArrayExcept(Box<BinaryFunc>),
470    ArrayRemove(Box<BinaryFunc>),
471    ArrayZip(Box<VarArgFunc>),
472    Sequence(Box<SequenceFunc>),
473    Generate(Box<SequenceFunc>),
474    ExplodingGenerateSeries(Box<SequenceFunc>),
475    ToArray(Box<UnaryFunc>),
476    StarMap(Box<BinaryFunc>),
477
478    // Struct functions
479    StructFunc(Box<StructConstructor>),
480    StructExtract(Box<StructExtractFunc>),
481    NamedStruct(Box<NamedStructFunc>),
482
483    // Map functions
484    MapFunc(Box<MapConstructor>),
485    MapFromEntries(Box<UnaryFunc>),
486    MapFromArrays(Box<BinaryFunc>),
487    MapKeys(Box<UnaryFunc>),
488    MapValues(Box<UnaryFunc>),
489    MapContainsKey(Box<BinaryFunc>),
490    MapConcat(Box<VarArgFunc>),
491    ElementAt(Box<BinaryFunc>),
492    TransformKeys(Box<TransformFunc>),
493    TransformValues(Box<TransformFunc>),
494
495    // Exasol: function call with EMITS clause
496    FunctionEmits(Box<FunctionEmits>),
497
498    // JSON functions
499    JsonExtract(Box<JsonExtractFunc>),
500    JsonExtractScalar(Box<JsonExtractFunc>),
501    JsonExtractPath(Box<JsonPathFunc>),
502    JsonArray(Box<VarArgFunc>),
503    JsonObject(Box<JsonObjectFunc>),
504    JsonQuery(Box<JsonExtractFunc>),
505    JsonValue(Box<JsonExtractFunc>),
506    JsonArrayLength(Box<UnaryFunc>),
507    JsonKeys(Box<UnaryFunc>),
508    JsonType(Box<UnaryFunc>),
509    ParseJson(Box<UnaryFunc>),
510    ToJson(Box<UnaryFunc>),
511    JsonSet(Box<JsonModifyFunc>),
512    JsonInsert(Box<JsonModifyFunc>),
513    JsonRemove(Box<JsonPathFunc>),
514    JsonMergePatch(Box<BinaryFunc>),
515    JsonArrayAgg(Box<JsonArrayAggFunc>),
516    JsonObjectAgg(Box<JsonObjectAggFunc>),
517
518    // Type casting/conversion
519    Convert(Box<ConvertFunc>),
520    Typeof(Box<UnaryFunc>),
521
522    // Additional expressions
523    Lambda(Box<LambdaExpr>),
524    Parameter(Box<Parameter>),
525    Placeholder(Placeholder),
526    NamedArgument(Box<NamedArgument>),
527    /// TABLE ref or MODEL ref used as a function argument (BigQuery)
528    /// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
529    TableArgument(Box<TableArgument>),
530    SqlComment(Box<SqlComment>),
531
532    // Additional predicates
533    NullSafeEq(Box<BinaryOp>),
534    NullSafeNeq(Box<BinaryOp>),
535    Glob(Box<BinaryOp>),
536    SimilarTo(Box<SimilarToExpr>),
537    Any(Box<QuantifiedExpr>),
538    All(Box<QuantifiedExpr>),
539    Overlaps(Box<OverlapsExpr>),
540
541    // Bitwise operations
542    BitwiseLeftShift(Box<BinaryOp>),
543    BitwiseRightShift(Box<BinaryOp>),
544    BitwiseAndAgg(Box<AggFunc>),
545    BitwiseOrAgg(Box<AggFunc>),
546    BitwiseXorAgg(Box<AggFunc>),
547
548    // Array/struct/map access
549    Subscript(Box<Subscript>),
550    Dot(Box<DotAccess>),
551    MethodCall(Box<MethodCall>),
552    ArraySlice(Box<ArraySlice>),
553
554    // DDL statements
555    CreateTable(Box<CreateTable>),
556    DropTable(Box<DropTable>),
557    Undrop(Box<Undrop>),
558    AlterTable(Box<AlterTable>),
559    SplitTable(Box<SplitTable>),
560    FlashbackTable(Box<FlashbackTable>),
561    CreateIndex(Box<CreateIndex>),
562    DropIndex(Box<DropIndex>),
563    CreateView(Box<CreateView>),
564    DropView(Box<DropView>),
565    AlterView(Box<AlterView>),
566    AlterIndex(Box<AlterIndex>),
567    Truncate(Box<Truncate>),
568    Use(Box<Use>),
569    Cache(Box<Cache>),
570    Uncache(Box<Uncache>),
571    LoadData(Box<LoadData>),
572    Pragma(Box<Pragma>),
573    Grant(Box<Grant>),
574    Revoke(Box<Revoke>),
575    Comment(Box<Comment>),
576    SetStatement(Box<SetStatement>),
577    // Phase 4: Additional DDL statements
578    CreateSchema(Box<CreateSchema>),
579    DropSchema(Box<DropSchema>),
580    DropNamespace(Box<DropNamespace>),
581    CreateDatabase(Box<CreateDatabase>),
582    DropDatabase(Box<DropDatabase>),
583    CreateFunction(Box<CreateFunction>),
584    DropFunction(Box<DropFunction>),
585    CreateProcedure(Box<CreateProcedure>),
586    DropProcedure(Box<DropProcedure>),
587    CreateSequence(Box<CreateSequence>),
588    CreateSynonym(Box<CreateSynonym>),
589    DropSequence(Box<DropSequence>),
590    AlterSequence(Box<AlterSequence>),
591    CreateTrigger(Box<CreateTrigger>),
592    DropTrigger(Box<DropTrigger>),
593    CreateType(Box<CreateType>),
594    DropType(Box<DropType>),
595    Describe(Box<Describe>),
596    Show(Box<Show>),
597
598    // Transaction and other commands
599    Command(Box<Command>),
600    Kill(Box<Kill>),
601    /// PREPARE statement (PostgreSQL/generic prepared statement definition)
602    Prepare(Box<PrepareStatement>),
603    /// EXEC/EXECUTE statement (TSQL stored procedure call)
604    Execute(Box<ExecuteStatement>),
605
606    /// Snowflake CREATE TASK statement
607    CreateTask(Box<CreateTask>),
608
609    // Placeholder for unparsed/raw SQL
610    Raw(Raw),
611
612    // Paren for grouping
613    Paren(Box<Paren>),
614
615    // Expression with trailing comments (for round-trip preservation)
616    Annotated(Box<Annotated>),
617
618    // === BATCH GENERATED EXPRESSION TYPES ===
619    // Generated from Python sqlglot expressions.py
620    Refresh(Box<Refresh>),
621    LockingStatement(Box<LockingStatement>),
622    SequenceProperties(Box<SequenceProperties>),
623    TruncateTable(Box<TruncateTable>),
624    Clone(Box<Clone>),
625    Attach(Box<Attach>),
626    Detach(Box<Detach>),
627    Install(Box<Install>),
628    Summarize(Box<Summarize>),
629    Declare(Box<Declare>),
630    DeclareItem(Box<DeclareItem>),
631    Set(Box<Set>),
632    Heredoc(Box<Heredoc>),
633    SetItem(Box<SetItem>),
634    QueryBand(Box<QueryBand>),
635    UserDefinedFunction(Box<UserDefinedFunction>),
636    RecursiveWithSearch(Box<RecursiveWithSearch>),
637    ProjectionDef(Box<ProjectionDef>),
638    TableAlias(Box<TableAlias>),
639    ByteString(Box<ByteString>),
640    HexStringExpr(Box<HexStringExpr>),
641    UnicodeString(Box<UnicodeString>),
642    ColumnPosition(Box<ColumnPosition>),
643    ColumnDef(Box<ColumnDef>),
644    AlterColumn(Box<AlterColumn>),
645    AlterSortKey(Box<AlterSortKey>),
646    AlterSet(Box<AlterSet>),
647    RenameColumn(Box<RenameColumn>),
648    Comprehension(Box<Comprehension>),
649    MergeTreeTTLAction(Box<MergeTreeTTLAction>),
650    MergeTreeTTL(Box<MergeTreeTTL>),
651    IndexConstraintOption(Box<IndexConstraintOption>),
652    ColumnConstraint(Box<ColumnConstraint>),
653    PeriodForSystemTimeConstraint(Box<PeriodForSystemTimeConstraint>),
654    CaseSpecificColumnConstraint(Box<CaseSpecificColumnConstraint>),
655    CharacterSetColumnConstraint(Box<CharacterSetColumnConstraint>),
656    CheckColumnConstraint(Box<CheckColumnConstraint>),
657    AssumeColumnConstraint(Box<AssumeColumnConstraint>),
658    CompressColumnConstraint(Box<CompressColumnConstraint>),
659    DateFormatColumnConstraint(Box<DateFormatColumnConstraint>),
660    EphemeralColumnConstraint(Box<EphemeralColumnConstraint>),
661    WithOperator(Box<WithOperator>),
662    GeneratedAsIdentityColumnConstraint(Box<GeneratedAsIdentityColumnConstraint>),
663    AutoIncrementColumnConstraint(AutoIncrementColumnConstraint),
664    CommentColumnConstraint(CommentColumnConstraint),
665    GeneratedAsRowColumnConstraint(Box<GeneratedAsRowColumnConstraint>),
666    IndexColumnConstraint(Box<IndexColumnConstraint>),
667    MaskingPolicyColumnConstraint(Box<MaskingPolicyColumnConstraint>),
668    NotNullColumnConstraint(Box<NotNullColumnConstraint>),
669    PrimaryKeyColumnConstraint(Box<PrimaryKeyColumnConstraint>),
670    UniqueColumnConstraint(Box<UniqueColumnConstraint>),
671    WatermarkColumnConstraint(Box<WatermarkColumnConstraint>),
672    ComputedColumnConstraint(Box<ComputedColumnConstraint>),
673    InOutColumnConstraint(Box<InOutColumnConstraint>),
674    DefaultColumnConstraint(Box<DefaultColumnConstraint>),
675    PathColumnConstraint(Box<PathColumnConstraint>),
676    Constraint(Box<Constraint>),
677    Export(Box<Export>),
678    Filter(Box<Filter>),
679    Changes(Box<Changes>),
680    CopyParameter(Box<CopyParameter>),
681    Credentials(Box<Credentials>),
682    Directory(Box<Directory>),
683    ForeignKey(Box<ForeignKey>),
684    ColumnPrefix(Box<ColumnPrefix>),
685    PrimaryKey(Box<PrimaryKey>),
686    IntoClause(Box<IntoClause>),
687    JoinHint(Box<JoinHint>),
688    Opclass(Box<Opclass>),
689    Index(Box<Index>),
690    IndexParameters(Box<IndexParameters>),
691    ConditionalInsert(Box<ConditionalInsert>),
692    MultitableInserts(Box<MultitableInserts>),
693    OnConflict(Box<OnConflict>),
694    OnCondition(Box<OnCondition>),
695    Returning(Box<Returning>),
696    Introducer(Box<Introducer>),
697    PartitionRange(Box<PartitionRange>),
698    Fetch(Box<Fetch>),
699    Group(Box<Group>),
700    Cube(Box<Cube>),
701    Rollup(Box<Rollup>),
702    GroupingSets(Box<GroupingSets>),
703    LimitOptions(Box<LimitOptions>),
704    Lateral(Box<Lateral>),
705    TableFromRows(Box<TableFromRows>),
706    RowsFrom(Box<RowsFrom>),
707    MatchRecognizeMeasure(Box<MatchRecognizeMeasure>),
708    WithFill(Box<WithFill>),
709    Property(Box<Property>),
710    GrantPrivilege(Box<GrantPrivilege>),
711    GrantPrincipal(Box<GrantPrincipal>),
712    AllowedValuesProperty(Box<AllowedValuesProperty>),
713    AlgorithmProperty(Box<AlgorithmProperty>),
714    AutoIncrementProperty(Box<AutoIncrementProperty>),
715    AutoRefreshProperty(Box<AutoRefreshProperty>),
716    BackupProperty(Box<BackupProperty>),
717    BuildProperty(Box<BuildProperty>),
718    BlockCompressionProperty(Box<BlockCompressionProperty>),
719    CharacterSetProperty(Box<CharacterSetProperty>),
720    ChecksumProperty(Box<ChecksumProperty>),
721    CollateProperty(Box<CollateProperty>),
722    DataBlocksizeProperty(Box<DataBlocksizeProperty>),
723    DataDeletionProperty(Box<DataDeletionProperty>),
724    DefinerProperty(Box<DefinerProperty>),
725    DistKeyProperty(Box<DistKeyProperty>),
726    DistributedByProperty(Box<DistributedByProperty>),
727    DistStyleProperty(Box<DistStyleProperty>),
728    DuplicateKeyProperty(Box<DuplicateKeyProperty>),
729    EngineProperty(Box<EngineProperty>),
730    ToTableProperty(Box<ToTableProperty>),
731    ExecuteAsProperty(Box<ExecuteAsProperty>),
732    ExternalProperty(Box<ExternalProperty>),
733    FallbackProperty(Box<FallbackProperty>),
734    FileFormatProperty(Box<FileFormatProperty>),
735    CredentialsProperty(Box<CredentialsProperty>),
736    FreespaceProperty(Box<FreespaceProperty>),
737    InheritsProperty(Box<InheritsProperty>),
738    InputModelProperty(Box<InputModelProperty>),
739    OutputModelProperty(Box<OutputModelProperty>),
740    IsolatedLoadingProperty(Box<IsolatedLoadingProperty>),
741    JournalProperty(Box<JournalProperty>),
742    LanguageProperty(Box<LanguageProperty>),
743    EnviromentProperty(Box<EnviromentProperty>),
744    ClusteredByProperty(Box<ClusteredByProperty>),
745    DictProperty(Box<DictProperty>),
746    DictRange(Box<DictRange>),
747    OnCluster(Box<OnCluster>),
748    LikeProperty(Box<LikeProperty>),
749    LocationProperty(Box<LocationProperty>),
750    LockProperty(Box<LockProperty>),
751    LockingProperty(Box<LockingProperty>),
752    LogProperty(Box<LogProperty>),
753    MaterializedProperty(Box<MaterializedProperty>),
754    MergeBlockRatioProperty(Box<MergeBlockRatioProperty>),
755    OnProperty(Box<OnProperty>),
756    OnCommitProperty(Box<OnCommitProperty>),
757    PartitionedByProperty(Box<PartitionedByProperty>),
758    PartitionByProperty(Box<PartitionByProperty>),
759    PartitionedByBucket(Box<PartitionedByBucket>),
760    ClusterByColumnsProperty(Box<ClusterByColumnsProperty>),
761    PartitionByTruncate(Box<PartitionByTruncate>),
762    PartitionByRangeProperty(Box<PartitionByRangeProperty>),
763    PartitionByRangePropertyDynamic(Box<PartitionByRangePropertyDynamic>),
764    PartitionByListProperty(Box<PartitionByListProperty>),
765    PartitionList(Box<PartitionList>),
766    Partition(Box<Partition>),
767    RefreshTriggerProperty(Box<RefreshTriggerProperty>),
768    UniqueKeyProperty(Box<UniqueKeyProperty>),
769    RollupProperty(Box<RollupProperty>),
770    PartitionBoundSpec(Box<PartitionBoundSpec>),
771    PartitionedOfProperty(Box<PartitionedOfProperty>),
772    RemoteWithConnectionModelProperty(Box<RemoteWithConnectionModelProperty>),
773    ReturnsProperty(Box<ReturnsProperty>),
774    RowFormatProperty(Box<RowFormatProperty>),
775    RowFormatDelimitedProperty(Box<RowFormatDelimitedProperty>),
776    RowFormatSerdeProperty(Box<RowFormatSerdeProperty>),
777    QueryTransform(Box<QueryTransform>),
778    SampleProperty(Box<SampleProperty>),
779    SecurityProperty(Box<SecurityProperty>),
780    SchemaCommentProperty(Box<SchemaCommentProperty>),
781    SemanticView(Box<SemanticView>),
782    SerdeProperties(Box<SerdeProperties>),
783    SetProperty(Box<SetProperty>),
784    SharingProperty(Box<SharingProperty>),
785    SetConfigProperty(Box<SetConfigProperty>),
786    SettingsProperty(Box<SettingsProperty>),
787    SortKeyProperty(Box<SortKeyProperty>),
788    SqlReadWriteProperty(Box<SqlReadWriteProperty>),
789    SqlSecurityProperty(Box<SqlSecurityProperty>),
790    StabilityProperty(Box<StabilityProperty>),
791    StorageHandlerProperty(Box<StorageHandlerProperty>),
792    TemporaryProperty(Box<TemporaryProperty>),
793    Tags(Box<Tags>),
794    TransformModelProperty(Box<TransformModelProperty>),
795    TransientProperty(Box<TransientProperty>),
796    UsingTemplateProperty(Box<UsingTemplateProperty>),
797    ViewAttributeProperty(Box<ViewAttributeProperty>),
798    VolatileProperty(Box<VolatileProperty>),
799    WithDataProperty(Box<WithDataProperty>),
800    WithJournalTableProperty(Box<WithJournalTableProperty>),
801    WithSchemaBindingProperty(Box<WithSchemaBindingProperty>),
802    WithSystemVersioningProperty(Box<WithSystemVersioningProperty>),
803    WithProcedureOptions(Box<WithProcedureOptions>),
804    EncodeProperty(Box<EncodeProperty>),
805    IncludeProperty(Box<IncludeProperty>),
806    Properties(Box<Properties>),
807    OptionsProperty(Box<OptionsProperty>),
808    InputOutputFormat(Box<InputOutputFormat>),
809    Reference(Box<Reference>),
810    QueryOption(Box<QueryOption>),
811    WithTableHint(Box<WithTableHint>),
812    IndexTableHint(Box<IndexTableHint>),
813    HistoricalData(Box<HistoricalData>),
814    Get(Box<Get>),
815    SetOperation(Box<SetOperation>),
816    Var(Box<Var>),
817    Variadic(Box<Variadic>),
818    Version(Box<Version>),
819    Schema(Box<Schema>),
820    Lock(Box<Lock>),
821    TableSample(Box<TableSample>),
822    Tag(Box<Tag>),
823    UnpivotColumns(Box<UnpivotColumns>),
824    WindowSpec(Box<WindowSpec>),
825    SessionParameter(Box<SessionParameter>),
826    PseudoType(Box<PseudoType>),
827    ObjectIdentifier(Box<ObjectIdentifier>),
828    Transaction(Box<Transaction>),
829    Commit(Box<Commit>),
830    Rollback(Box<Rollback>),
831    AlterSession(Box<AlterSession>),
832    Analyze(Box<Analyze>),
833    AnalyzeStatistics(Box<AnalyzeStatistics>),
834    AnalyzeHistogram(Box<AnalyzeHistogram>),
835    AnalyzeSample(Box<AnalyzeSample>),
836    AnalyzeListChainedRows(Box<AnalyzeListChainedRows>),
837    AnalyzeDelete(Box<AnalyzeDelete>),
838    AnalyzeWith(Box<AnalyzeWith>),
839    AnalyzeValidate(Box<AnalyzeValidate>),
840    AddPartition(Box<AddPartition>),
841    AttachOption(Box<AttachOption>),
842    DropPartition(Box<DropPartition>),
843    ReplacePartition(Box<ReplacePartition>),
844    DPipe(Box<DPipe>),
845    Operator(Box<Operator>),
846    PivotAny(Box<PivotAny>),
847    Aliases(Box<Aliases>),
848    AtIndex(Box<AtIndex>),
849    FromTimeZone(Box<FromTimeZone>),
850    FormatPhrase(Box<FormatPhrase>),
851    ForIn(Box<ForIn>),
852    TimeUnit(Box<TimeUnit>),
853    IntervalOp(Box<IntervalOp>),
854    IntervalSpan(Box<IntervalSpan>),
855    HavingMax(Box<HavingMax>),
856    CosineDistance(Box<CosineDistance>),
857    DotProduct(Box<DotProduct>),
858    EuclideanDistance(Box<EuclideanDistance>),
859    ManhattanDistance(Box<ManhattanDistance>),
860    JarowinklerSimilarity(Box<JarowinklerSimilarity>),
861    Booland(Box<Booland>),
862    Boolor(Box<Boolor>),
863    ParameterizedAgg(Box<ParameterizedAgg>),
864    ArgMax(Box<ArgMax>),
865    ArgMin(Box<ArgMin>),
866    ApproxTopK(Box<ApproxTopK>),
867    ApproxTopKAccumulate(Box<ApproxTopKAccumulate>),
868    ApproxTopKCombine(Box<ApproxTopKCombine>),
869    ApproxTopKEstimate(Box<ApproxTopKEstimate>),
870    ApproxTopSum(Box<ApproxTopSum>),
871    ApproxQuantiles(Box<ApproxQuantiles>),
872    Minhash(Box<Minhash>),
873    FarmFingerprint(Box<FarmFingerprint>),
874    Float64(Box<Float64>),
875    Transform(Box<Transform>),
876    Translate(Box<Translate>),
877    Grouping(Box<Grouping>),
878    GroupingId(Box<GroupingId>),
879    Anonymous(Box<Anonymous>),
880    AnonymousAggFunc(Box<AnonymousAggFunc>),
881    CombinedAggFunc(Box<CombinedAggFunc>),
882    CombinedParameterizedAgg(Box<CombinedParameterizedAgg>),
883    HashAgg(Box<HashAgg>),
884    Hll(Box<Hll>),
885    Apply(Box<Apply>),
886    ToBoolean(Box<ToBoolean>),
887    List(Box<List>),
888    ToMap(Box<ToMap>),
889    Pad(Box<Pad>),
890    ToChar(Box<ToChar>),
891    ToNumber(Box<ToNumber>),
892    ToDouble(Box<ToDouble>),
893    Int64(Box<UnaryFunc>),
894    StringFunc(Box<StringFunc>),
895    ToDecfloat(Box<ToDecfloat>),
896    TryToDecfloat(Box<TryToDecfloat>),
897    ToFile(Box<ToFile>),
898    Columns(Box<Columns>),
899    ConvertToCharset(Box<ConvertToCharset>),
900    ConvertTimezone(Box<ConvertTimezone>),
901    GenerateSeries(Box<GenerateSeries>),
902    AIAgg(Box<AIAgg>),
903    AIClassify(Box<AIClassify>),
904    ArrayAll(Box<ArrayAll>),
905    ArrayAny(Box<ArrayAny>),
906    ArrayConstructCompact(Box<ArrayConstructCompact>),
907    StPoint(Box<StPoint>),
908    StDistance(Box<StDistance>),
909    StringToArray(Box<StringToArray>),
910    ArraySum(Box<ArraySum>),
911    ObjectAgg(Box<ObjectAgg>),
912    CastToStrType(Box<CastToStrType>),
913    CheckJson(Box<CheckJson>),
914    CheckXml(Box<CheckXml>),
915    TranslateCharacters(Box<TranslateCharacters>),
916    CurrentSchemas(Box<CurrentSchemas>),
917    CurrentDatetime(Box<CurrentDatetime>),
918    Localtime(Box<Localtime>),
919    Localtimestamp(Box<Localtimestamp>),
920    Systimestamp(Box<Systimestamp>),
921    CurrentSchema(Box<CurrentSchema>),
922    CurrentUser(Box<CurrentUser>),
923    UtcTime(Box<UtcTime>),
924    UtcTimestamp(Box<UtcTimestamp>),
925    Timestamp(Box<TimestampFunc>),
926    DateBin(Box<DateBin>),
927    Datetime(Box<Datetime>),
928    DatetimeAdd(Box<DatetimeAdd>),
929    DatetimeSub(Box<DatetimeSub>),
930    DatetimeDiff(Box<DatetimeDiff>),
931    DatetimeTrunc(Box<DatetimeTrunc>),
932    Dayname(Box<Dayname>),
933    MakeInterval(Box<MakeInterval>),
934    PreviousDay(Box<PreviousDay>),
935    Elt(Box<Elt>),
936    TimestampAdd(Box<TimestampAdd>),
937    TimestampSub(Box<TimestampSub>),
938    TimestampDiff(Box<TimestampDiff>),
939    TimeSlice(Box<TimeSlice>),
940    TimeAdd(Box<TimeAdd>),
941    TimeSub(Box<TimeSub>),
942    TimeDiff(Box<TimeDiff>),
943    TimeTrunc(Box<TimeTrunc>),
944    DateFromParts(Box<DateFromParts>),
945    TimeFromParts(Box<TimeFromParts>),
946    DecodeCase(Box<DecodeCase>),
947    Decrypt(Box<Decrypt>),
948    DecryptRaw(Box<DecryptRaw>),
949    Encode(Box<Encode>),
950    Encrypt(Box<Encrypt>),
951    EncryptRaw(Box<EncryptRaw>),
952    EqualNull(Box<EqualNull>),
953    ToBinary(Box<ToBinary>),
954    Base64DecodeBinary(Box<Base64DecodeBinary>),
955    Base64DecodeString(Box<Base64DecodeString>),
956    Base64Encode(Box<Base64Encode>),
957    TryBase64DecodeBinary(Box<TryBase64DecodeBinary>),
958    TryBase64DecodeString(Box<TryBase64DecodeString>),
959    GapFill(Box<GapFill>),
960    GenerateDateArray(Box<GenerateDateArray>),
961    GenerateTimestampArray(Box<GenerateTimestampArray>),
962    GetExtract(Box<GetExtract>),
963    Getbit(Box<Getbit>),
964    OverflowTruncateBehavior(Box<OverflowTruncateBehavior>),
965    HexEncode(Box<HexEncode>),
966    Compress(Box<Compress>),
967    DecompressBinary(Box<DecompressBinary>),
968    DecompressString(Box<DecompressString>),
969    Xor(Box<Xor>),
970    Nullif(Box<Nullif>),
971    JSON(Box<JSON>),
972    JSONPath(Box<JSONPath>),
973    JSONPathFilter(Box<JSONPathFilter>),
974    JSONPathKey(Box<JSONPathKey>),
975    JSONPathRecursive(Box<JSONPathRecursive>),
976    JSONPathScript(Box<JSONPathScript>),
977    JSONPathSlice(Box<JSONPathSlice>),
978    JSONPathSelector(Box<JSONPathSelector>),
979    JSONPathSubscript(Box<JSONPathSubscript>),
980    JSONPathUnion(Box<JSONPathUnion>),
981    Format(Box<Format>),
982    JSONKeys(Box<JSONKeys>),
983    JSONKeyValue(Box<JSONKeyValue>),
984    JSONKeysAtDepth(Box<JSONKeysAtDepth>),
985    JSONObject(Box<JSONObject>),
986    JSONObjectAgg(Box<JSONObjectAgg>),
987    JSONBObjectAgg(Box<JSONBObjectAgg>),
988    JSONArray(Box<JSONArray>),
989    JSONArrayAgg(Box<JSONArrayAgg>),
990    JSONExists(Box<JSONExists>),
991    JSONColumnDef(Box<JSONColumnDef>),
992    JSONSchema(Box<JSONSchema>),
993    JSONSet(Box<JSONSet>),
994    JSONStripNulls(Box<JSONStripNulls>),
995    JSONValue(Box<JSONValue>),
996    JSONValueArray(Box<JSONValueArray>),
997    JSONRemove(Box<JSONRemove>),
998    JSONTable(Box<JSONTable>),
999    JSONType(Box<JSONType>),
1000    ObjectInsert(Box<ObjectInsert>),
1001    OpenJSONColumnDef(Box<OpenJSONColumnDef>),
1002    OpenJSON(Box<OpenJSON>),
1003    JSONBExists(Box<JSONBExists>),
1004    JSONBContains(Box<BinaryFunc>),
1005    JSONBExtract(Box<BinaryFunc>),
1006    JSONCast(Box<JSONCast>),
1007    JSONExtract(Box<JSONExtract>),
1008    JSONExtractQuote(Box<JSONExtractQuote>),
1009    JSONExtractArray(Box<JSONExtractArray>),
1010    JSONExtractScalar(Box<JSONExtractScalar>),
1011    JSONBExtractScalar(Box<JSONBExtractScalar>),
1012    JSONFormat(Box<JSONFormat>),
1013    JSONBool(Box<UnaryFunc>),
1014    JSONPathRoot(JSONPathRoot),
1015    JSONArrayAppend(Box<JSONArrayAppend>),
1016    JSONArrayContains(Box<JSONArrayContains>),
1017    JSONArrayInsert(Box<JSONArrayInsert>),
1018    ParseJSON(Box<ParseJSON>),
1019    ParseUrl(Box<ParseUrl>),
1020    ParseIp(Box<ParseIp>),
1021    ParseTime(Box<ParseTime>),
1022    ParseDatetime(Box<ParseDatetime>),
1023    Map(Box<Map>),
1024    MapCat(Box<MapCat>),
1025    MapDelete(Box<MapDelete>),
1026    MapInsert(Box<MapInsert>),
1027    MapPick(Box<MapPick>),
1028    ScopeResolution(Box<ScopeResolution>),
1029    Slice(Box<Slice>),
1030    VarMap(Box<VarMap>),
1031    MatchAgainst(Box<MatchAgainst>),
1032    MD5Digest(Box<MD5Digest>),
1033    MD5NumberLower64(Box<UnaryFunc>),
1034    MD5NumberUpper64(Box<UnaryFunc>),
1035    Monthname(Box<Monthname>),
1036    Ntile(Box<Ntile>),
1037    Normalize(Box<Normalize>),
1038    Normal(Box<Normal>),
1039    Predict(Box<Predict>),
1040    MLTranslate(Box<MLTranslate>),
1041    FeaturesAtTime(Box<FeaturesAtTime>),
1042    GenerateEmbedding(Box<GenerateEmbedding>),
1043    MLForecast(Box<MLForecast>),
1044    ModelAttribute(Box<ModelAttribute>),
1045    VectorSearch(Box<VectorSearch>),
1046    Quantile(Box<Quantile>),
1047    ApproxQuantile(Box<ApproxQuantile>),
1048    ApproxPercentileEstimate(Box<ApproxPercentileEstimate>),
1049    Randn(Box<Randn>),
1050    Randstr(Box<Randstr>),
1051    RangeN(Box<RangeN>),
1052    RangeBucket(Box<RangeBucket>),
1053    ReadCSV(Box<ReadCSV>),
1054    ReadParquet(Box<ReadParquet>),
1055    Reduce(Box<Reduce>),
1056    RegexpExtractAll(Box<RegexpExtractAll>),
1057    RegexpILike(Box<RegexpILike>),
1058    RegexpFullMatch(Box<RegexpFullMatch>),
1059    RegexpInstr(Box<RegexpInstr>),
1060    RegexpSplit(Box<RegexpSplit>),
1061    RegexpCount(Box<RegexpCount>),
1062    RegrValx(Box<RegrValx>),
1063    RegrValy(Box<RegrValy>),
1064    RegrAvgy(Box<RegrAvgy>),
1065    RegrAvgx(Box<RegrAvgx>),
1066    RegrCount(Box<RegrCount>),
1067    RegrIntercept(Box<RegrIntercept>),
1068    RegrR2(Box<RegrR2>),
1069    RegrSxx(Box<RegrSxx>),
1070    RegrSxy(Box<RegrSxy>),
1071    RegrSyy(Box<RegrSyy>),
1072    RegrSlope(Box<RegrSlope>),
1073    SafeAdd(Box<SafeAdd>),
1074    SafeDivide(Box<SafeDivide>),
1075    SafeMultiply(Box<SafeMultiply>),
1076    SafeSubtract(Box<SafeSubtract>),
1077    SHA2(Box<SHA2>),
1078    SHA2Digest(Box<SHA2Digest>),
1079    SortArray(Box<SortArray>),
1080    SplitPart(Box<SplitPart>),
1081    SubstringIndex(Box<SubstringIndex>),
1082    StandardHash(Box<StandardHash>),
1083    StrPosition(Box<StrPosition>),
1084    Search(Box<Search>),
1085    SearchIp(Box<SearchIp>),
1086    StrToDate(Box<StrToDate>),
1087    DateStrToDate(Box<UnaryFunc>),
1088    DateToDateStr(Box<UnaryFunc>),
1089    StrToTime(Box<StrToTime>),
1090    StrToUnix(Box<StrToUnix>),
1091    StrToMap(Box<StrToMap>),
1092    NumberToStr(Box<NumberToStr>),
1093    FromBase(Box<FromBase>),
1094    Stuff(Box<Stuff>),
1095    TimeToStr(Box<TimeToStr>),
1096    TimeStrToTime(Box<TimeStrToTime>),
1097    TsOrDsAdd(Box<TsOrDsAdd>),
1098    TsOrDsDiff(Box<TsOrDsDiff>),
1099    TsOrDsToDate(Box<TsOrDsToDate>),
1100    TsOrDsToTime(Box<TsOrDsToTime>),
1101    Unhex(Box<Unhex>),
1102    Uniform(Box<Uniform>),
1103    UnixToStr(Box<UnixToStr>),
1104    UnixToTime(Box<UnixToTime>),
1105    Uuid(Box<Uuid>),
1106    TimestampFromParts(Box<TimestampFromParts>),
1107    TimestampTzFromParts(Box<TimestampTzFromParts>),
1108    Corr(Box<Corr>),
1109    WidthBucket(Box<WidthBucket>),
1110    CovarSamp(Box<CovarSamp>),
1111    CovarPop(Box<CovarPop>),
1112    Week(Box<Week>),
1113    XMLElement(Box<XMLElement>),
1114    XMLGet(Box<XMLGet>),
1115    XMLTable(Box<XMLTable>),
1116    XMLKeyValueOption(Box<XMLKeyValueOption>),
1117    Zipf(Box<Zipf>),
1118    Merge(Box<Merge>),
1119    When(Box<When>),
1120    Whens(Box<Whens>),
1121    NextValueFor(Box<NextValueFor>),
1122    /// RETURN statement (DuckDB stored procedures)
1123    ReturnStmt(Box<Expression>),
1124}
1125
1126impl Expression {
1127    /// Source semantics that still require dialect-aware lowering. This metadata
1128    /// survives JSON serialization and never changes generic traversal behavior.
1129    pub fn source_dialect(&self) -> Option<crate::dialects::DialectType> {
1130        use crate::dialects::DialectType;
1131        match self {
1132            Self::Function(f) => f.source_dialect,
1133            Self::AggregateFunction(f) => f.source_dialect,
1134            Self::ListAgg(f) => f.source_dialect,
1135            Self::Select(s) => s.source_dialect,
1136            Self::CreateTable(t) => t.source_dialect,
1137            Self::Upsert(u) => u.source_dialect,
1138            Self::Call(c) => c.source_dialect,
1139            Self::Hierarchy(h) => h.source_dialect,
1140            Self::ViewParameter(p) => p.source_dialect,
1141            Self::StorageProperty(p) => p.source_dialect,
1142            Self::Hint(h) => h.source_dialect,
1143            Self::JSONValue(j) => j.source_dialect,
1144            Self::JSONTable(j) => j.source_dialect,
1145            Self::JSONColumnDef(j) => j.source_dialect,
1146            Self::JsonQuery(j) | Self::JsonExtract(j) | Self::JsonExtractScalar(j) => {
1147                j.source_dialect
1148            }
1149            Self::RegexpLike(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1150            Self::RegexpReplace(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1151            Self::RegexpExtract(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1152            Self::RegexpInstr(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1153            Self::RegexpCount(r) => r.options.as_ref().and_then(|o| o.source_dialect),
1154            Self::Cube(g) => g.options.as_ref().and_then(|o| o.source_dialect),
1155            Self::Rollup(g) => g.options.as_ref().and_then(|o| o.source_dialect),
1156            Self::GroupingSets(g) => g.options.as_ref().and_then(|o| o.source_dialect),
1157            Self::PartitionByProperty(p) => p.specification.as_ref().and_then(|s| s.source_dialect),
1158            Self::DataType(DataType::Hana { .. }) => Some(DialectType::HANA),
1159            Self::Cast(c) if matches!(c.to, DataType::Hana { .. }) => Some(DialectType::HANA),
1160            _ => None,
1161        }
1162    }
1163
1164    /// Create a `Column` variant, boxing the value automatically.
1165    #[inline]
1166    pub fn boxed_column(col: Column) -> Self {
1167        Expression::Column(Box::new(col))
1168    }
1169
1170    /// Create a `Table` variant, boxing the value automatically.
1171    #[inline]
1172    pub fn boxed_table(t: TableRef) -> Self {
1173        Expression::Table(Box::new(t))
1174    }
1175
1176    /// Returns `true` if this expression is a valid top-level SQL statement.
1177    ///
1178    /// Bare expressions like identifiers, literals, and function calls are not
1179    /// valid statements. This is used by `validate()` to reject inputs like
1180    /// `SELECT scooby dooby doo` which the parser splits into `SELECT scooby AS dooby`
1181    /// plus the bare identifier `doo`.
1182    pub fn is_statement(&self) -> bool {
1183        match self {
1184            // Queries
1185            Expression::Select(_)
1186            | Expression::Union(_)
1187            | Expression::Intersect(_)
1188            | Expression::Except(_)
1189            | Expression::Subquery(_)
1190            | Expression::Values(_)
1191            | Expression::PipeOperator(_)
1192
1193            // DML
1194            | Expression::Upsert(_)
1195            | Expression::Call(_)
1196            | Expression::Insert(_)
1197            | Expression::Update(_)
1198            | Expression::Delete(_)
1199            | Expression::Copy(_)
1200            | Expression::Put(_)
1201            | Expression::Merge(_)
1202            | Expression::TryCatch(_)
1203
1204            // DDL
1205            | Expression::CreateTable(_)
1206            | Expression::DropTable(_)
1207            | Expression::Undrop(_)
1208            | Expression::AlterTable(_)
1209            | Expression::SplitTable(_)
1210            | Expression::FlashbackTable(_)
1211            | Expression::CreateIndex(_)
1212            | Expression::DropIndex(_)
1213            | Expression::CreateView(_)
1214            | Expression::DropView(_)
1215            | Expression::AlterView(_)
1216            | Expression::AlterIndex(_)
1217            | Expression::Truncate(_)
1218            | Expression::TruncateTable(_)
1219            | Expression::CreateSchema(_)
1220            | Expression::DropSchema(_)
1221            | Expression::DropNamespace(_)
1222            | Expression::CreateDatabase(_)
1223            | Expression::DropDatabase(_)
1224            | Expression::CreateFunction(_)
1225            | Expression::DropFunction(_)
1226            | Expression::CreateProcedure(_)
1227            | Expression::DropProcedure(_)
1228            | Expression::CreateSequence(_)
1229            | Expression::CreateSynonym(_)
1230            | Expression::DropSequence(_)
1231            | Expression::AlterSequence(_)
1232            | Expression::CreateTrigger(_)
1233            | Expression::DropTrigger(_)
1234            | Expression::CreateType(_)
1235            | Expression::DropType(_)
1236            | Expression::Comment(_)
1237
1238            // Session/Transaction/Control
1239            | Expression::Use(_)
1240            | Expression::Set(_)
1241            | Expression::SetStatement(_)
1242            | Expression::Transaction(_)
1243            | Expression::Commit(_)
1244            | Expression::Rollback(_)
1245            | Expression::Grant(_)
1246            | Expression::Revoke(_)
1247            | Expression::Cache(_)
1248            | Expression::Uncache(_)
1249            | Expression::LoadData(_)
1250            | Expression::Pragma(_)
1251            | Expression::Describe(_)
1252            | Expression::Show(_)
1253            | Expression::Kill(_)
1254            | Expression::Prepare(_)
1255            | Expression::Execute(_)
1256            | Expression::Declare(_)
1257            | Expression::Refresh(_)
1258            | Expression::AlterSession(_)
1259            | Expression::LockingStatement(_)
1260
1261            // Analyze
1262            | Expression::Analyze(_)
1263            | Expression::AnalyzeStatistics(_)
1264            | Expression::AnalyzeHistogram(_)
1265            | Expression::AnalyzeSample(_)
1266            | Expression::AnalyzeListChainedRows(_)
1267            | Expression::AnalyzeDelete(_)
1268
1269            // Attach/Detach/Install/Summarize
1270            | Expression::Attach(_)
1271            | Expression::Detach(_)
1272            | Expression::Install(_)
1273            | Expression::Summarize(_)
1274
1275            // Pivot at statement level
1276            | Expression::Pivot(_)
1277            | Expression::Unpivot(_)
1278
1279            // Command (raw/unparsed statements)
1280            | Expression::Command(_)
1281            | Expression::Raw(_)
1282            | Expression::CreateTask(_)
1283
1284            // Return statement
1285            | Expression::ReturnStmt(_) => true,
1286
1287            // Annotated wraps another expression with comments — check inner
1288            Expression::Annotated(a) => a.this.is_statement(),
1289
1290            // Alias at top level can wrap a statement (e.g., parenthesized subquery with alias)
1291            Expression::Alias(a) => a.this.is_statement(),
1292
1293            // Everything else (identifiers, literals, operators, functions, etc.)
1294            _ => false,
1295        }
1296    }
1297
1298    /// Create a literal number expression from an integer.
1299    pub fn number(n: i64) -> Self {
1300        Expression::Literal(Box::new(Literal::Number(n.to_string())))
1301    }
1302
1303    /// Create a single-quoted literal string expression.
1304    pub fn string(s: impl Into<String>) -> Self {
1305        Expression::Literal(Box::new(Literal::String(s.into())))
1306    }
1307
1308    /// Create a literal number expression from a float.
1309    pub fn float(f: f64) -> Self {
1310        Expression::Literal(Box::new(Literal::Number(f.to_string())))
1311    }
1312
1313    /// Get the inferred type annotation, if present.
1314    ///
1315    /// For value-producing expressions with an `inferred_type` field, returns
1316    /// the stored type. For literals and boolean constants, computes the type
1317    /// on the fly from the variant. For DDL/clause expressions, returns `None`.
1318    pub fn inferred_type(&self) -> Option<&DataType> {
1319        match self {
1320            // Structs with inferred_type field
1321            Expression::And(op)
1322            | Expression::Or(op)
1323            | Expression::Add(op)
1324            | Expression::Sub(op)
1325            | Expression::Mul(op)
1326            | Expression::Div(op)
1327            | Expression::Mod(op)
1328            | Expression::Eq(op)
1329            | Expression::Neq(op)
1330            | Expression::Lt(op)
1331            | Expression::Lte(op)
1332            | Expression::Gt(op)
1333            | Expression::Gte(op)
1334            | Expression::Concat(op)
1335            | Expression::BitwiseAnd(op)
1336            | Expression::BitwiseOr(op)
1337            | Expression::BitwiseXor(op)
1338            | Expression::Adjacent(op)
1339            | Expression::TsMatch(op)
1340            | Expression::PropertyEQ(op)
1341            | Expression::ArrayContainsAll(op)
1342            | Expression::ArrayContainedBy(op)
1343            | Expression::ArrayOverlaps(op)
1344            | Expression::JSONBContainsAllTopKeys(op)
1345            | Expression::JSONBContainsAnyTopKeys(op)
1346            | Expression::JSONBDeleteAtPath(op)
1347            | Expression::ExtendsLeft(op)
1348            | Expression::ExtendsRight(op)
1349            | Expression::Is(op)
1350            | Expression::MemberOf(op)
1351            | Expression::Match(op)
1352            | Expression::NullSafeEq(op)
1353            | Expression::NullSafeNeq(op)
1354            | Expression::Glob(op)
1355            | Expression::BitwiseLeftShift(op)
1356            | Expression::BitwiseRightShift(op) => op.inferred_type.as_ref(),
1357
1358            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1359                op.inferred_type.as_ref()
1360            }
1361
1362            Expression::Like(op) | Expression::ILike(op) => op.inferred_type.as_ref(),
1363
1364            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1365                c.inferred_type.as_ref()
1366            }
1367
1368            Expression::Column(c) => c.inferred_type.as_ref(),
1369            Expression::Dot(dot) => dot.inferred_type.as_ref(),
1370            Expression::Function(f) => f.inferred_type.as_ref(),
1371            Expression::AggregateFunction(f) => f.inferred_type.as_ref(),
1372            Expression::WindowFunction(f) => f.inferred_type.as_ref(),
1373            Expression::Case(c) => c.inferred_type.as_ref(),
1374            Expression::Array(a) => a.inferred_type.as_ref(),
1375            Expression::ArrayFunc(a) => a.inferred_type.as_ref(),
1376            Expression::Paren(p) => p.this.inferred_type(),
1377            Expression::Annotated(a) => a.this.inferred_type(),
1378            Expression::Subquery(s) => s.inferred_type.as_ref(),
1379            Expression::Alias(a) => a.inferred_type.as_ref(),
1380            Expression::Unnest(u) => u.inferred_type.as_ref(),
1381            Expression::IfFunc(f) => f.inferred_type.as_ref(),
1382            Expression::Nvl2(f) => f.inferred_type.as_ref(),
1383            Expression::Count(f) => f.inferred_type.as_ref(),
1384            Expression::GroupConcat(f) => f.inferred_type.as_ref(),
1385            Expression::StringAgg(f) => f.inferred_type.as_ref(),
1386            Expression::ListAgg(f) => f.inferred_type.as_ref(),
1387            Expression::SumIf(f) => f.inferred_type.as_ref(),
1388            Expression::Trim(f) => f.inferred_type.as_ref(),
1389
1390            // UnaryFunc variants
1391            Expression::Upper(f)
1392            | Expression::Lower(f)
1393            | Expression::Length(f)
1394            | Expression::LTrim(f)
1395            | Expression::RTrim(f)
1396            | Expression::Reverse(f)
1397            | Expression::Abs(f)
1398            | Expression::Sqrt(f)
1399            | Expression::Cbrt(f)
1400            | Expression::Ln(f)
1401            | Expression::Exp(f)
1402            | Expression::Sign(f)
1403            | Expression::Date(f)
1404            | Expression::Time(f)
1405            | Expression::Initcap(f)
1406            | Expression::Ascii(f)
1407            | Expression::Chr(f)
1408            | Expression::Soundex(f)
1409            | Expression::ByteLength(f)
1410            | Expression::Hex(f)
1411            | Expression::LowerHex(f)
1412            | Expression::Unicode(f)
1413            | Expression::Typeof(f)
1414            | Expression::Explode(f)
1415            | Expression::ExplodeOuter(f)
1416            | Expression::MapFromEntries(f)
1417            | Expression::MapKeys(f)
1418            | Expression::MapValues(f)
1419            | Expression::ArrayLength(f)
1420            | Expression::ArraySize(f)
1421            | Expression::Cardinality(f)
1422            | Expression::ArrayReverse(f)
1423            | Expression::ArrayDistinct(f)
1424            | Expression::ArrayFlatten(f)
1425            | Expression::ArrayCompact(f)
1426            | Expression::ToArray(f)
1427            | Expression::JsonArrayLength(f)
1428            | Expression::JsonKeys(f)
1429            | Expression::JsonType(f)
1430            | Expression::ParseJson(f)
1431            | Expression::ToJson(f)
1432            | Expression::Radians(f)
1433            | Expression::Degrees(f)
1434            | Expression::Sin(f)
1435            | Expression::Cos(f)
1436            | Expression::Tan(f)
1437            | Expression::Asin(f)
1438            | Expression::Acos(f)
1439            | Expression::Atan(f)
1440            | Expression::IsNan(f)
1441            | Expression::IsInf(f)
1442            | Expression::Year(f)
1443            | Expression::Month(f)
1444            | Expression::Day(f)
1445            | Expression::Hour(f)
1446            | Expression::Minute(f)
1447            | Expression::Second(f)
1448            | Expression::DayOfWeek(f)
1449            | Expression::DayOfWeekIso(f)
1450            | Expression::DayOfMonth(f)
1451            | Expression::DayOfYear(f)
1452            | Expression::WeekOfYear(f)
1453            | Expression::Quarter(f)
1454            | Expression::Epoch(f)
1455            | Expression::EpochMs(f)
1456            | Expression::BitwiseCount(f)
1457            | Expression::DateFromUnixDate(f)
1458            | Expression::UnixDate(f)
1459            | Expression::UnixSeconds(f)
1460            | Expression::UnixMillis(f)
1461            | Expression::UnixMicros(f)
1462            | Expression::TimeStrToDate(f)
1463            | Expression::DateToDi(f)
1464            | Expression::DiToDate(f)
1465            | Expression::TsOrDiToDi(f)
1466            | Expression::TsOrDsToDatetime(f)
1467            | Expression::TsOrDsToTimestamp(f)
1468            | Expression::YearOfWeek(f)
1469            | Expression::YearOfWeekIso(f)
1470            | Expression::SHA(f)
1471            | Expression::SHA1Digest(f)
1472            | Expression::TimeToUnix(f)
1473            | Expression::TimeStrToUnix(f) => f.inferred_type.as_ref(),
1474
1475            // BinaryFunc variants
1476            Expression::Power(f)
1477            | Expression::NullIf(f)
1478            | Expression::IfNull(f)
1479            | Expression::Nvl(f)
1480            | Expression::Contains(f)
1481            | Expression::StartsWith(f)
1482            | Expression::EndsWith(f)
1483            | Expression::Levenshtein(f)
1484            | Expression::ModFunc(f)
1485            | Expression::IntDiv(f)
1486            | Expression::Atan2(f)
1487            | Expression::AddMonths(f)
1488            | Expression::MonthsBetween(f)
1489            | Expression::NextDay(f)
1490            | Expression::UnixToTimeStr(f)
1491            | Expression::ArrayContains(f)
1492            | Expression::ArrayPosition(f)
1493            | Expression::ArrayAppend(f)
1494            | Expression::ArrayPrepend(f)
1495            | Expression::ArrayUnion(f)
1496            | Expression::ArrayExcept(f)
1497            | Expression::ArrayRemove(f)
1498            | Expression::StarMap(f)
1499            | Expression::MapFromArrays(f)
1500            | Expression::MapContainsKey(f)
1501            | Expression::ElementAt(f)
1502            | Expression::JsonMergePatch(f) => f.inferred_type.as_ref(),
1503
1504            // VarArgFunc variants
1505            Expression::Coalesce(f)
1506            | Expression::Greatest(f)
1507            | Expression::Least(f)
1508            | Expression::ArrayConcat(f)
1509            | Expression::ArrayIntersect(f)
1510            | Expression::ArrayZip(f)
1511            | Expression::MapConcat(f)
1512            | Expression::JsonArray(f) => f.inferred_type.as_ref(),
1513
1514            // AggFunc variants
1515            Expression::Sum(f)
1516            | Expression::Avg(f)
1517            | Expression::Min(f)
1518            | Expression::Max(f)
1519            | Expression::ArrayAgg(f)
1520            | Expression::CountIf(f)
1521            | Expression::Stddev(f)
1522            | Expression::StddevPop(f)
1523            | Expression::StddevSamp(f)
1524            | Expression::Variance(f)
1525            | Expression::VarPop(f)
1526            | Expression::VarSamp(f)
1527            | Expression::Median(f)
1528            | Expression::Mode(f)
1529            | Expression::First(f)
1530            | Expression::Last(f)
1531            | Expression::AnyValue(f)
1532            | Expression::ApproxDistinct(f)
1533            | Expression::ApproxCountDistinct(f)
1534            | Expression::LogicalAnd(f)
1535            | Expression::LogicalOr(f)
1536            | Expression::Skewness(f)
1537            | Expression::ArrayConcatAgg(f)
1538            | Expression::ArrayUniqueAgg(f)
1539            | Expression::BoolXorAgg(f)
1540            | Expression::BitwiseAndAgg(f)
1541            | Expression::BitwiseOrAgg(f)
1542            | Expression::BitwiseXorAgg(f) => f.inferred_type.as_ref(),
1543
1544            // Everything else: no inferred_type field
1545            _ => None,
1546        }
1547    }
1548
1549    /// Set the inferred type annotation on this expression.
1550    ///
1551    /// Only has an effect on value-producing expressions with an `inferred_type`
1552    /// field. For other expression types, this is a no-op.
1553    pub fn set_inferred_type(&mut self, dt: DataType) {
1554        match self {
1555            Expression::And(op)
1556            | Expression::Or(op)
1557            | Expression::Add(op)
1558            | Expression::Sub(op)
1559            | Expression::Mul(op)
1560            | Expression::Div(op)
1561            | Expression::Mod(op)
1562            | Expression::Eq(op)
1563            | Expression::Neq(op)
1564            | Expression::Lt(op)
1565            | Expression::Lte(op)
1566            | Expression::Gt(op)
1567            | Expression::Gte(op)
1568            | Expression::Concat(op)
1569            | Expression::BitwiseAnd(op)
1570            | Expression::BitwiseOr(op)
1571            | Expression::BitwiseXor(op)
1572            | Expression::Adjacent(op)
1573            | Expression::TsMatch(op)
1574            | Expression::PropertyEQ(op)
1575            | Expression::ArrayContainsAll(op)
1576            | Expression::ArrayContainedBy(op)
1577            | Expression::ArrayOverlaps(op)
1578            | Expression::JSONBContainsAllTopKeys(op)
1579            | Expression::JSONBContainsAnyTopKeys(op)
1580            | Expression::JSONBDeleteAtPath(op)
1581            | Expression::ExtendsLeft(op)
1582            | Expression::ExtendsRight(op)
1583            | Expression::Is(op)
1584            | Expression::MemberOf(op)
1585            | Expression::Match(op)
1586            | Expression::NullSafeEq(op)
1587            | Expression::NullSafeNeq(op)
1588            | Expression::Glob(op)
1589            | Expression::BitwiseLeftShift(op)
1590            | Expression::BitwiseRightShift(op) => op.inferred_type = Some(dt),
1591
1592            Expression::Not(op) | Expression::Neg(op) | Expression::BitwiseNot(op) => {
1593                op.inferred_type = Some(dt)
1594            }
1595
1596            Expression::Like(op) | Expression::ILike(op) => op.inferred_type = Some(dt),
1597
1598            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
1599                c.inferred_type = Some(dt)
1600            }
1601
1602            Expression::Column(c) => c.inferred_type = Some(dt),
1603            Expression::Dot(dot) => dot.inferred_type = Some(dt),
1604            Expression::Function(f) => f.inferred_type = Some(dt),
1605            Expression::AggregateFunction(f) => f.inferred_type = Some(dt),
1606            Expression::WindowFunction(f) => f.inferred_type = Some(dt),
1607            Expression::Case(c) => c.inferred_type = Some(dt),
1608            Expression::Array(a) => a.inferred_type = Some(dt),
1609            Expression::ArrayFunc(a) => a.inferred_type = Some(dt),
1610            Expression::Paren(p) => p.this.set_inferred_type(dt),
1611            Expression::Annotated(a) => a.this.set_inferred_type(dt),
1612            Expression::Subquery(s) => s.inferred_type = Some(dt),
1613            Expression::Alias(a) => a.inferred_type = Some(dt),
1614            Expression::Unnest(u) => u.inferred_type = Some(dt),
1615            Expression::IfFunc(f) => f.inferred_type = Some(dt),
1616            Expression::Nvl2(f) => f.inferred_type = Some(dt),
1617            Expression::Count(f) => f.inferred_type = Some(dt),
1618            Expression::GroupConcat(f) => f.inferred_type = Some(dt),
1619            Expression::StringAgg(f) => f.inferred_type = Some(dt),
1620            Expression::ListAgg(f) => f.inferred_type = Some(dt),
1621            Expression::SumIf(f) => f.inferred_type = Some(dt),
1622            Expression::Trim(f) => f.inferred_type = Some(dt),
1623
1624            // UnaryFunc variants
1625            Expression::Upper(f)
1626            | Expression::Lower(f)
1627            | Expression::Length(f)
1628            | Expression::LTrim(f)
1629            | Expression::RTrim(f)
1630            | Expression::Reverse(f)
1631            | Expression::Abs(f)
1632            | Expression::Sqrt(f)
1633            | Expression::Cbrt(f)
1634            | Expression::Ln(f)
1635            | Expression::Exp(f)
1636            | Expression::Sign(f)
1637            | Expression::Date(f)
1638            | Expression::Time(f)
1639            | Expression::Initcap(f)
1640            | Expression::Ascii(f)
1641            | Expression::Chr(f)
1642            | Expression::Soundex(f)
1643            | Expression::ByteLength(f)
1644            | Expression::Hex(f)
1645            | Expression::LowerHex(f)
1646            | Expression::Unicode(f)
1647            | Expression::Typeof(f)
1648            | Expression::Explode(f)
1649            | Expression::ExplodeOuter(f)
1650            | Expression::MapFromEntries(f)
1651            | Expression::MapKeys(f)
1652            | Expression::MapValues(f)
1653            | Expression::ArrayLength(f)
1654            | Expression::ArraySize(f)
1655            | Expression::Cardinality(f)
1656            | Expression::ArrayReverse(f)
1657            | Expression::ArrayDistinct(f)
1658            | Expression::ArrayFlatten(f)
1659            | Expression::ArrayCompact(f)
1660            | Expression::ToArray(f)
1661            | Expression::JsonArrayLength(f)
1662            | Expression::JsonKeys(f)
1663            | Expression::JsonType(f)
1664            | Expression::ParseJson(f)
1665            | Expression::ToJson(f)
1666            | Expression::Radians(f)
1667            | Expression::Degrees(f)
1668            | Expression::Sin(f)
1669            | Expression::Cos(f)
1670            | Expression::Tan(f)
1671            | Expression::Asin(f)
1672            | Expression::Acos(f)
1673            | Expression::Atan(f)
1674            | Expression::IsNan(f)
1675            | Expression::IsInf(f)
1676            | Expression::Year(f)
1677            | Expression::Month(f)
1678            | Expression::Day(f)
1679            | Expression::Hour(f)
1680            | Expression::Minute(f)
1681            | Expression::Second(f)
1682            | Expression::DayOfWeek(f)
1683            | Expression::DayOfWeekIso(f)
1684            | Expression::DayOfMonth(f)
1685            | Expression::DayOfYear(f)
1686            | Expression::WeekOfYear(f)
1687            | Expression::Quarter(f)
1688            | Expression::Epoch(f)
1689            | Expression::EpochMs(f)
1690            | Expression::BitwiseCount(f)
1691            | Expression::DateFromUnixDate(f)
1692            | Expression::UnixDate(f)
1693            | Expression::UnixSeconds(f)
1694            | Expression::UnixMillis(f)
1695            | Expression::UnixMicros(f)
1696            | Expression::TimeStrToDate(f)
1697            | Expression::DateToDi(f)
1698            | Expression::DiToDate(f)
1699            | Expression::TsOrDiToDi(f)
1700            | Expression::TsOrDsToDatetime(f)
1701            | Expression::TsOrDsToTimestamp(f)
1702            | Expression::YearOfWeek(f)
1703            | Expression::YearOfWeekIso(f)
1704            | Expression::SHA(f)
1705            | Expression::SHA1Digest(f)
1706            | Expression::TimeToUnix(f)
1707            | Expression::TimeStrToUnix(f) => f.inferred_type = Some(dt),
1708
1709            // BinaryFunc variants
1710            Expression::Power(f)
1711            | Expression::NullIf(f)
1712            | Expression::IfNull(f)
1713            | Expression::Nvl(f)
1714            | Expression::Contains(f)
1715            | Expression::StartsWith(f)
1716            | Expression::EndsWith(f)
1717            | Expression::Levenshtein(f)
1718            | Expression::ModFunc(f)
1719            | Expression::IntDiv(f)
1720            | Expression::Atan2(f)
1721            | Expression::AddMonths(f)
1722            | Expression::MonthsBetween(f)
1723            | Expression::NextDay(f)
1724            | Expression::UnixToTimeStr(f)
1725            | Expression::ArrayContains(f)
1726            | Expression::ArrayPosition(f)
1727            | Expression::ArrayAppend(f)
1728            | Expression::ArrayPrepend(f)
1729            | Expression::ArrayUnion(f)
1730            | Expression::ArrayExcept(f)
1731            | Expression::ArrayRemove(f)
1732            | Expression::StarMap(f)
1733            | Expression::MapFromArrays(f)
1734            | Expression::MapContainsKey(f)
1735            | Expression::ElementAt(f)
1736            | Expression::JsonMergePatch(f) => f.inferred_type = Some(dt),
1737
1738            // VarArgFunc variants
1739            Expression::Coalesce(f)
1740            | Expression::Greatest(f)
1741            | Expression::Least(f)
1742            | Expression::ArrayConcat(f)
1743            | Expression::ArrayIntersect(f)
1744            | Expression::ArrayZip(f)
1745            | Expression::MapConcat(f)
1746            | Expression::JsonArray(f) => f.inferred_type = Some(dt),
1747
1748            // AggFunc variants
1749            Expression::Sum(f)
1750            | Expression::Avg(f)
1751            | Expression::Min(f)
1752            | Expression::Max(f)
1753            | Expression::ArrayAgg(f)
1754            | Expression::CountIf(f)
1755            | Expression::Stddev(f)
1756            | Expression::StddevPop(f)
1757            | Expression::StddevSamp(f)
1758            | Expression::Variance(f)
1759            | Expression::VarPop(f)
1760            | Expression::VarSamp(f)
1761            | Expression::Median(f)
1762            | Expression::Mode(f)
1763            | Expression::First(f)
1764            | Expression::Last(f)
1765            | Expression::AnyValue(f)
1766            | Expression::ApproxDistinct(f)
1767            | Expression::ApproxCountDistinct(f)
1768            | Expression::LogicalAnd(f)
1769            | Expression::LogicalOr(f)
1770            | Expression::Skewness(f)
1771            | Expression::ArrayConcatAgg(f)
1772            | Expression::ArrayUniqueAgg(f)
1773            | Expression::BoolXorAgg(f)
1774            | Expression::BitwiseAndAgg(f)
1775            | Expression::BitwiseOrAgg(f)
1776            | Expression::BitwiseXorAgg(f) => f.inferred_type = Some(dt),
1777
1778            // Expressions without inferred_type field - no-op
1779            _ => {}
1780        }
1781    }
1782
1783    /// Create an unqualified column reference (e.g. `name`).
1784    pub fn column(name: impl Into<String>) -> Self {
1785        Expression::Column(Box::new(Column {
1786            name: Identifier::new(name),
1787            table: None,
1788            join_mark: false,
1789            trailing_comments: Vec::new(),
1790            span: None,
1791            inferred_type: None,
1792        }))
1793    }
1794
1795    /// Create a qualified column reference (`table.column`).
1796    pub fn qualified_column(table: impl Into<String>, column: impl Into<String>) -> Self {
1797        Expression::Column(Box::new(Column {
1798            name: Identifier::new(column),
1799            table: Some(Identifier::new(table)),
1800            join_mark: false,
1801            trailing_comments: Vec::new(),
1802            span: None,
1803            inferred_type: None,
1804        }))
1805    }
1806
1807    /// Create a bare identifier expression (not a column reference).
1808    pub fn identifier(name: impl Into<String>) -> Self {
1809        Expression::Identifier(Identifier::new(name))
1810    }
1811
1812    /// Create a NULL expression
1813    pub fn null() -> Self {
1814        Expression::Null(Null)
1815    }
1816
1817    /// Create a TRUE expression
1818    pub fn true_() -> Self {
1819        Expression::Boolean(BooleanLiteral { value: true })
1820    }
1821
1822    /// Create a FALSE expression
1823    pub fn false_() -> Self {
1824        Expression::Boolean(BooleanLiteral { value: false })
1825    }
1826
1827    /// Create a wildcard star (`*`) expression with no EXCEPT/REPLACE/RENAME modifiers.
1828    pub fn star() -> Self {
1829        Expression::Star(Star {
1830            table: None,
1831            except: None,
1832            replace: None,
1833            rename: None,
1834            trailing_comments: Vec::new(),
1835            span: None,
1836        })
1837    }
1838
1839    /// Wrap this expression in an `AS` alias (e.g. `expr AS name`).
1840    pub fn alias(self, name: impl Into<String>) -> Self {
1841        Expression::Alias(Box::new(Alias::new(self, Identifier::new(name))))
1842    }
1843
1844    /// Check if this is a SELECT expression
1845    pub fn is_select(&self) -> bool {
1846        matches!(self, Expression::Select(_))
1847    }
1848
1849    /// Try to get as a Select
1850    pub fn as_select(&self) -> Option<&Select> {
1851        match self {
1852            Expression::Select(s) => Some(s),
1853            _ => None,
1854        }
1855    }
1856
1857    /// Try to get as a mutable Select
1858    pub fn as_select_mut(&mut self) -> Option<&mut Select> {
1859        match self {
1860            Expression::Select(s) => Some(s),
1861            _ => None,
1862        }
1863    }
1864
1865    /// Generate a SQL string for this expression using the generic (dialect-agnostic) generator.
1866    ///
1867    /// Returns an empty string if generation fails. For dialect-specific output,
1868    /// use [`sql_for()`](Self::sql_for) instead.
1869    #[cfg(feature = "generate")]
1870    pub fn sql(&self) -> String {
1871        crate::generator::Generator::sql(self).unwrap_or_default()
1872    }
1873
1874    /// Generate a SQL string for this expression targeting a specific dialect.
1875    ///
1876    /// Dialect-specific rules (identifier quoting, function names, type mappings,
1877    /// syntax variations) are applied automatically.  Returns an empty string if
1878    /// generation fails.
1879    #[cfg(feature = "generate")]
1880    pub fn sql_for(&self, dialect: crate::dialects::DialectType) -> String {
1881        crate::generate(self, dialect).unwrap_or_default()
1882    }
1883}
1884
1885// === Python API accessor methods ===
1886
1887impl Expression {
1888    /// Returns the serde-compatible snake_case variant name without serialization.
1889    /// This is much faster than serializing to JSON and extracting the key.
1890    pub fn variant_name(&self) -> &'static str {
1891        match self {
1892            Expression::Vertica(_) => "vertica",
1893            Expression::Literal(_) => "literal",
1894            Expression::Boolean(_) => "boolean",
1895            Expression::Null(_) => "null",
1896            Expression::Identifier(_) => "identifier",
1897            Expression::Column(_) => "column",
1898            Expression::Table(_) => "table",
1899            Expression::Star(_) => "star",
1900            Expression::BracedWildcard(_) => "braced_wildcard",
1901            Expression::Select(_) => "select",
1902            Expression::Union(_) => "union",
1903            Expression::Intersect(_) => "intersect",
1904            Expression::Except(_) => "except",
1905            Expression::Subquery(_) => "subquery",
1906            Expression::PipeOperator(_) => "pipe_operator",
1907            Expression::Pivot(_) => "pivot",
1908            Expression::PivotAlias(_) => "pivot_alias",
1909            Expression::Unpivot(_) => "unpivot",
1910            Expression::Values(_) => "values",
1911            Expression::PreWhere(_) => "pre_where",
1912            Expression::Stream(_) => "stream",
1913            Expression::UsingData(_) => "using_data",
1914            Expression::XmlNamespace(_) => "xml_namespace",
1915            Expression::Insert(_) => "insert",
1916            Expression::Update(_) => "update",
1917            Expression::Delete(_) => "delete",
1918            Expression::Copy(_) => "copy",
1919            Expression::Put(_) => "put",
1920            Expression::StageReference(_) => "stage_reference",
1921            Expression::Alias(_) => "alias",
1922            Expression::Cast(_) => "cast",
1923            Expression::Collation(_) => "collation",
1924            Expression::Case(_) => "case",
1925            Expression::And(_) => "and",
1926            Expression::Or(_) => "or",
1927            Expression::Add(_) => "add",
1928            Expression::Sub(_) => "sub",
1929            Expression::Mul(_) => "mul",
1930            Expression::Div(_) => "div",
1931            Expression::Mod(_) => "mod",
1932            Expression::Eq(_) => "eq",
1933            Expression::Neq(_) => "neq",
1934            Expression::Lt(_) => "lt",
1935            Expression::Lte(_) => "lte",
1936            Expression::Gt(_) => "gt",
1937            Expression::Gte(_) => "gte",
1938            Expression::Like(_) => "like",
1939            Expression::ILike(_) => "i_like",
1940            Expression::Match(_) => "match",
1941            Expression::BitwiseAnd(_) => "bitwise_and",
1942            Expression::BitwiseOr(_) => "bitwise_or",
1943            Expression::BitwiseXor(_) => "bitwise_xor",
1944            Expression::Concat(_) => "concat",
1945            Expression::Adjacent(_) => "adjacent",
1946            Expression::TsMatch(_) => "ts_match",
1947            Expression::PropertyEQ(_) => "property_e_q",
1948            Expression::ArrayContainsAll(_) => "array_contains_all",
1949            Expression::ArrayContainedBy(_) => "array_contained_by",
1950            Expression::ArrayOverlaps(_) => "array_overlaps",
1951            Expression::JSONBContainsAllTopKeys(_) => "j_s_o_n_b_contains_all_top_keys",
1952            Expression::JSONBContainsAnyTopKeys(_) => "j_s_o_n_b_contains_any_top_keys",
1953            Expression::JSONBDeleteAtPath(_) => "j_s_o_n_b_delete_at_path",
1954            Expression::ExtendsLeft(_) => "extends_left",
1955            Expression::ExtendsRight(_) => "extends_right",
1956            Expression::Not(_) => "not",
1957            Expression::Neg(_) => "neg",
1958            Expression::BitwiseNot(_) => "bitwise_not",
1959            Expression::In(_) => "in",
1960            Expression::Between(_) => "between",
1961            Expression::IsNull(_) => "is_null",
1962            Expression::IsTrue(_) => "is_true",
1963            Expression::IsFalse(_) => "is_false",
1964            Expression::IsJson(_) => "is_json",
1965            Expression::Is(_) => "is",
1966            Expression::Exists(_) => "exists",
1967            Expression::MemberOf(_) => "member_of",
1968            Expression::Function(_) => "function",
1969            Expression::Upsert(_) => "upsert",
1970            Expression::StorageProperty(_) => "storage_property",
1971            Expression::Hierarchy(_) => "hierarchy",
1972            Expression::ViewParameter(_) => "view_parameter",
1973            Expression::Call(_) => "call",
1974            Expression::AggregateFunction(_) => "aggregate_function",
1975            Expression::WindowFunction(_) => "window_function",
1976            Expression::From(_) => "from",
1977            Expression::Join(_) => "join",
1978            Expression::JoinedTable(_) => "joined_table",
1979            Expression::Where(_) => "where",
1980            Expression::GroupBy(_) => "group_by",
1981            Expression::Having(_) => "having",
1982            Expression::OrderBy(_) => "order_by",
1983            Expression::Limit(_) => "limit",
1984            Expression::Offset(_) => "offset",
1985            Expression::Qualify(_) => "qualify",
1986            Expression::With(_) => "with",
1987            Expression::Cte(_) => "cte",
1988            Expression::DistributeBy(_) => "distribute_by",
1989            Expression::ClusterBy(_) => "cluster_by",
1990            Expression::SortBy(_) => "sort_by",
1991            Expression::LateralView(_) => "lateral_view",
1992            Expression::Hint(_) => "hint",
1993            Expression::Pseudocolumn(_) => "pseudocolumn",
1994            Expression::Connect(_) => "connect",
1995            Expression::Prior(_) => "prior",
1996            Expression::ConnectByRoot(_) => "connect_by_root",
1997            Expression::MatchRecognize(_) => "match_recognize",
1998            Expression::Ordered(_) => "ordered",
1999            Expression::Window(_) => "window",
2000            Expression::Over(_) => "over",
2001            Expression::WithinGroup(_) => "within_group",
2002            Expression::DataType(_) => "data_type",
2003            Expression::Array(_) => "array",
2004            Expression::Struct(_) => "struct",
2005            Expression::Tuple(_) => "tuple",
2006            Expression::Interval(_) => "interval",
2007            Expression::ConcatWs(_) => "concat_ws",
2008            Expression::Substring(_) => "substring",
2009            Expression::Upper(_) => "upper",
2010            Expression::Lower(_) => "lower",
2011            Expression::Length(_) => "length",
2012            Expression::Trim(_) => "trim",
2013            Expression::LTrim(_) => "l_trim",
2014            Expression::RTrim(_) => "r_trim",
2015            Expression::Replace(_) => "replace",
2016            Expression::Reverse(_) => "reverse",
2017            Expression::Left(_) => "left",
2018            Expression::Right(_) => "right",
2019            Expression::Repeat(_) => "repeat",
2020            Expression::Lpad(_) => "lpad",
2021            Expression::Rpad(_) => "rpad",
2022            Expression::Split(_) => "split",
2023            Expression::RegexpLike(_) => "regexp_like",
2024            Expression::RegexpReplace(_) => "regexp_replace",
2025            Expression::RegexpExtract(_) => "regexp_extract",
2026            Expression::Overlay(_) => "overlay",
2027            Expression::Abs(_) => "abs",
2028            Expression::Round(_) => "round",
2029            Expression::Floor(_) => "floor",
2030            Expression::Ceil(_) => "ceil",
2031            Expression::Power(_) => "power",
2032            Expression::Sqrt(_) => "sqrt",
2033            Expression::Cbrt(_) => "cbrt",
2034            Expression::Ln(_) => "ln",
2035            Expression::Log(_) => "log",
2036            Expression::Exp(_) => "exp",
2037            Expression::Sign(_) => "sign",
2038            Expression::Greatest(_) => "greatest",
2039            Expression::Least(_) => "least",
2040            Expression::CurrentDate(_) => "current_date",
2041            Expression::CurrentTime(_) => "current_time",
2042            Expression::CurrentTimestamp(_) => "current_timestamp",
2043            Expression::CurrentTimestampLTZ(_) => "current_timestamp_l_t_z",
2044            Expression::AtTimeZone(_) => "at_time_zone",
2045            Expression::DateAdd(_) => "date_add",
2046            Expression::DateSub(_) => "date_sub",
2047            Expression::DateDiff(_) => "date_diff",
2048            Expression::DateTrunc(_) => "date_trunc",
2049            Expression::Extract(_) => "extract",
2050            Expression::ToDate(_) => "to_date",
2051            Expression::ToTimestamp(_) => "to_timestamp",
2052            Expression::Date(_) => "date",
2053            Expression::Time(_) => "time",
2054            Expression::DateFromUnixDate(_) => "date_from_unix_date",
2055            Expression::UnixDate(_) => "unix_date",
2056            Expression::UnixSeconds(_) => "unix_seconds",
2057            Expression::UnixMillis(_) => "unix_millis",
2058            Expression::UnixMicros(_) => "unix_micros",
2059            Expression::UnixToTimeStr(_) => "unix_to_time_str",
2060            Expression::TimeStrToDate(_) => "time_str_to_date",
2061            Expression::DateToDi(_) => "date_to_di",
2062            Expression::DiToDate(_) => "di_to_date",
2063            Expression::TsOrDiToDi(_) => "ts_or_di_to_di",
2064            Expression::TsOrDsToDatetime(_) => "ts_or_ds_to_datetime",
2065            Expression::TsOrDsToTimestamp(_) => "ts_or_ds_to_timestamp",
2066            Expression::YearOfWeek(_) => "year_of_week",
2067            Expression::YearOfWeekIso(_) => "year_of_week_iso",
2068            Expression::Coalesce(_) => "coalesce",
2069            Expression::NullIf(_) => "null_if",
2070            Expression::IfFunc(_) => "if_func",
2071            Expression::IfNull(_) => "if_null",
2072            Expression::Nvl(_) => "nvl",
2073            Expression::Nvl2(_) => "nvl2",
2074            Expression::TryCast(_) => "try_cast",
2075            Expression::SafeCast(_) => "safe_cast",
2076            Expression::Count(_) => "count",
2077            Expression::Sum(_) => "sum",
2078            Expression::Avg(_) => "avg",
2079            Expression::Min(_) => "min",
2080            Expression::Max(_) => "max",
2081            Expression::GroupConcat(_) => "group_concat",
2082            Expression::StringAgg(_) => "string_agg",
2083            Expression::ListAgg(_) => "list_agg",
2084            Expression::ArrayAgg(_) => "array_agg",
2085            Expression::CountIf(_) => "count_if",
2086            Expression::SumIf(_) => "sum_if",
2087            Expression::Stddev(_) => "stddev",
2088            Expression::StddevPop(_) => "stddev_pop",
2089            Expression::StddevSamp(_) => "stddev_samp",
2090            Expression::Variance(_) => "variance",
2091            Expression::VarPop(_) => "var_pop",
2092            Expression::VarSamp(_) => "var_samp",
2093            Expression::Median(_) => "median",
2094            Expression::Mode(_) => "mode",
2095            Expression::First(_) => "first",
2096            Expression::Last(_) => "last",
2097            Expression::AnyValue(_) => "any_value",
2098            Expression::ApproxDistinct(_) => "approx_distinct",
2099            Expression::ApproxCountDistinct(_) => "approx_count_distinct",
2100            Expression::ApproxPercentile(_) => "approx_percentile",
2101            Expression::Percentile(_) => "percentile",
2102            Expression::LogicalAnd(_) => "logical_and",
2103            Expression::LogicalOr(_) => "logical_or",
2104            Expression::Skewness(_) => "skewness",
2105            Expression::BitwiseCount(_) => "bitwise_count",
2106            Expression::ArrayConcatAgg(_) => "array_concat_agg",
2107            Expression::ArrayUniqueAgg(_) => "array_unique_agg",
2108            Expression::BoolXorAgg(_) => "bool_xor_agg",
2109            Expression::RowNumber(_) => "row_number",
2110            Expression::Rank(_) => "rank",
2111            Expression::DenseRank(_) => "dense_rank",
2112            Expression::NTile(_) => "n_tile",
2113            Expression::Lead(_) => "lead",
2114            Expression::Lag(_) => "lag",
2115            Expression::FirstValue(_) => "first_value",
2116            Expression::LastValue(_) => "last_value",
2117            Expression::NthValue(_) => "nth_value",
2118            Expression::PercentRank(_) => "percent_rank",
2119            Expression::CumeDist(_) => "cume_dist",
2120            Expression::PercentileCont(_) => "percentile_cont",
2121            Expression::PercentileDisc(_) => "percentile_disc",
2122            Expression::Contains(_) => "contains",
2123            Expression::StartsWith(_) => "starts_with",
2124            Expression::EndsWith(_) => "ends_with",
2125            Expression::Position(_) => "position",
2126            Expression::Initcap(_) => "initcap",
2127            Expression::Ascii(_) => "ascii",
2128            Expression::Chr(_) => "chr",
2129            Expression::CharFunc(_) => "char_func",
2130            Expression::Soundex(_) => "soundex",
2131            Expression::Levenshtein(_) => "levenshtein",
2132            Expression::ByteLength(_) => "byte_length",
2133            Expression::Hex(_) => "hex",
2134            Expression::LowerHex(_) => "lower_hex",
2135            Expression::Unicode(_) => "unicode",
2136            Expression::ModFunc(_) => "mod_func",
2137            Expression::Random(_) => "random",
2138            Expression::Rand(_) => "rand",
2139            Expression::TruncFunc(_) => "trunc_func",
2140            Expression::Pi(_) => "pi",
2141            Expression::Radians(_) => "radians",
2142            Expression::Degrees(_) => "degrees",
2143            Expression::Sin(_) => "sin",
2144            Expression::Cos(_) => "cos",
2145            Expression::Tan(_) => "tan",
2146            Expression::Asin(_) => "asin",
2147            Expression::Acos(_) => "acos",
2148            Expression::Atan(_) => "atan",
2149            Expression::Atan2(_) => "atan2",
2150            Expression::IsNan(_) => "is_nan",
2151            Expression::IsInf(_) => "is_inf",
2152            Expression::IntDiv(_) => "int_div",
2153            Expression::Decode(_) => "decode",
2154            Expression::DateFormat(_) => "date_format",
2155            Expression::FormatDate(_) => "format_date",
2156            Expression::Year(_) => "year",
2157            Expression::Month(_) => "month",
2158            Expression::Day(_) => "day",
2159            Expression::Hour(_) => "hour",
2160            Expression::Minute(_) => "minute",
2161            Expression::Second(_) => "second",
2162            Expression::DayOfWeek(_) => "day_of_week",
2163            Expression::DayOfWeekIso(_) => "day_of_week_iso",
2164            Expression::DayOfMonth(_) => "day_of_month",
2165            Expression::DayOfYear(_) => "day_of_year",
2166            Expression::WeekOfYear(_) => "week_of_year",
2167            Expression::Quarter(_) => "quarter",
2168            Expression::AddMonths(_) => "add_months",
2169            Expression::MonthsBetween(_) => "months_between",
2170            Expression::LastDay(_) => "last_day",
2171            Expression::NextDay(_) => "next_day",
2172            Expression::Epoch(_) => "epoch",
2173            Expression::EpochMs(_) => "epoch_ms",
2174            Expression::FromUnixtime(_) => "from_unixtime",
2175            Expression::UnixTimestamp(_) => "unix_timestamp",
2176            Expression::MakeDate(_) => "make_date",
2177            Expression::MakeTimestamp(_) => "make_timestamp",
2178            Expression::TimestampTrunc(_) => "timestamp_trunc",
2179            Expression::TimeStrToUnix(_) => "time_str_to_unix",
2180            Expression::SessionUser(_) => "session_user",
2181            Expression::SHA(_) => "s_h_a",
2182            Expression::SHA1Digest(_) => "s_h_a1_digest",
2183            Expression::TimeToUnix(_) => "time_to_unix",
2184            Expression::ArrayFunc(_) => "array_func",
2185            Expression::ArrayLength(_) => "array_length",
2186            Expression::ArraySize(_) => "array_size",
2187            Expression::Cardinality(_) => "cardinality",
2188            Expression::ArrayContains(_) => "array_contains",
2189            Expression::ArrayPosition(_) => "array_position",
2190            Expression::ArrayAppend(_) => "array_append",
2191            Expression::ArrayPrepend(_) => "array_prepend",
2192            Expression::ArrayConcat(_) => "array_concat",
2193            Expression::ArraySort(_) => "array_sort",
2194            Expression::ArrayReverse(_) => "array_reverse",
2195            Expression::ArrayDistinct(_) => "array_distinct",
2196            Expression::ArrayJoin(_) => "array_join",
2197            Expression::ArrayToString(_) => "array_to_string",
2198            Expression::Unnest(_) => "unnest",
2199            Expression::Explode(_) => "explode",
2200            Expression::ExplodeOuter(_) => "explode_outer",
2201            Expression::ArrayFilter(_) => "array_filter",
2202            Expression::ArrayTransform(_) => "array_transform",
2203            Expression::ArrayFlatten(_) => "array_flatten",
2204            Expression::ArrayCompact(_) => "array_compact",
2205            Expression::ArrayIntersect(_) => "array_intersect",
2206            Expression::ArrayUnion(_) => "array_union",
2207            Expression::ArrayExcept(_) => "array_except",
2208            Expression::ArrayRemove(_) => "array_remove",
2209            Expression::ArrayZip(_) => "array_zip",
2210            Expression::Sequence(_) => "sequence",
2211            Expression::Generate(_) => "generate",
2212            Expression::ExplodingGenerateSeries(_) => "exploding_generate_series",
2213            Expression::ToArray(_) => "to_array",
2214            Expression::StarMap(_) => "star_map",
2215            Expression::StructFunc(_) => "struct_func",
2216            Expression::StructExtract(_) => "struct_extract",
2217            Expression::NamedStruct(_) => "named_struct",
2218            Expression::MapFunc(_) => "map_func",
2219            Expression::MapFromEntries(_) => "map_from_entries",
2220            Expression::MapFromArrays(_) => "map_from_arrays",
2221            Expression::MapKeys(_) => "map_keys",
2222            Expression::MapValues(_) => "map_values",
2223            Expression::MapContainsKey(_) => "map_contains_key",
2224            Expression::MapConcat(_) => "map_concat",
2225            Expression::ElementAt(_) => "element_at",
2226            Expression::TransformKeys(_) => "transform_keys",
2227            Expression::TransformValues(_) => "transform_values",
2228            Expression::FunctionEmits(_) => "function_emits",
2229            Expression::JsonExtract(_) => "json_extract",
2230            Expression::JsonExtractScalar(_) => "json_extract_scalar",
2231            Expression::JsonExtractPath(_) => "json_extract_path",
2232            Expression::JsonArray(_) => "json_array",
2233            Expression::JsonObject(_) => "json_object",
2234            Expression::JsonQuery(_) => "json_query",
2235            Expression::JsonValue(_) => "json_value",
2236            Expression::JsonArrayLength(_) => "json_array_length",
2237            Expression::JsonKeys(_) => "json_keys",
2238            Expression::JsonType(_) => "json_type",
2239            Expression::ParseJson(_) => "parse_json",
2240            Expression::ToJson(_) => "to_json",
2241            Expression::JsonSet(_) => "json_set",
2242            Expression::JsonInsert(_) => "json_insert",
2243            Expression::JsonRemove(_) => "json_remove",
2244            Expression::JsonMergePatch(_) => "json_merge_patch",
2245            Expression::JsonArrayAgg(_) => "json_array_agg",
2246            Expression::JsonObjectAgg(_) => "json_object_agg",
2247            Expression::Convert(_) => "convert",
2248            Expression::Typeof(_) => "typeof",
2249            Expression::Lambda(_) => "lambda",
2250            Expression::Parameter(_) => "parameter",
2251            Expression::Placeholder(_) => "placeholder",
2252            Expression::NamedArgument(_) => "named_argument",
2253            Expression::TableArgument(_) => "table_argument",
2254            Expression::SqlComment(_) => "sql_comment",
2255            Expression::NullSafeEq(_) => "null_safe_eq",
2256            Expression::NullSafeNeq(_) => "null_safe_neq",
2257            Expression::Glob(_) => "glob",
2258            Expression::SimilarTo(_) => "similar_to",
2259            Expression::Any(_) => "any",
2260            Expression::All(_) => "all",
2261            Expression::Overlaps(_) => "overlaps",
2262            Expression::BitwiseLeftShift(_) => "bitwise_left_shift",
2263            Expression::BitwiseRightShift(_) => "bitwise_right_shift",
2264            Expression::BitwiseAndAgg(_) => "bitwise_and_agg",
2265            Expression::BitwiseOrAgg(_) => "bitwise_or_agg",
2266            Expression::BitwiseXorAgg(_) => "bitwise_xor_agg",
2267            Expression::Subscript(_) => "subscript",
2268            Expression::Dot(_) => "dot",
2269            Expression::MethodCall(_) => "method_call",
2270            Expression::ArraySlice(_) => "array_slice",
2271            Expression::CreateTable(_) => "create_table",
2272            Expression::DropTable(_) => "drop_table",
2273            Expression::Undrop(_) => "undrop",
2274            Expression::AlterTable(_) => "alter_table",
2275            Expression::SplitTable(_) => "split_table",
2276            Expression::FlashbackTable(_) => "flashback_table",
2277            Expression::CreateIndex(_) => "create_index",
2278            Expression::DropIndex(_) => "drop_index",
2279            Expression::CreateView(_) => "create_view",
2280            Expression::DropView(_) => "drop_view",
2281            Expression::AlterView(_) => "alter_view",
2282            Expression::AlterIndex(_) => "alter_index",
2283            Expression::Truncate(_) => "truncate",
2284            Expression::Use(_) => "use",
2285            Expression::Cache(_) => "cache",
2286            Expression::Uncache(_) => "uncache",
2287            Expression::LoadData(_) => "load_data",
2288            Expression::Pragma(_) => "pragma",
2289            Expression::Grant(_) => "grant",
2290            Expression::Revoke(_) => "revoke",
2291            Expression::Comment(_) => "comment",
2292            Expression::SetStatement(_) => "set_statement",
2293            Expression::CreateSchema(_) => "create_schema",
2294            Expression::DropSchema(_) => "drop_schema",
2295            Expression::DropNamespace(_) => "drop_namespace",
2296            Expression::CreateDatabase(_) => "create_database",
2297            Expression::DropDatabase(_) => "drop_database",
2298            Expression::CreateFunction(_) => "create_function",
2299            Expression::DropFunction(_) => "drop_function",
2300            Expression::CreateProcedure(_) => "create_procedure",
2301            Expression::DropProcedure(_) => "drop_procedure",
2302            Expression::CreateSequence(_) => "create_sequence",
2303            Expression::CreateSynonym(_) => "create_synonym",
2304            Expression::DropSequence(_) => "drop_sequence",
2305            Expression::AlterSequence(_) => "alter_sequence",
2306            Expression::CreateTrigger(_) => "create_trigger",
2307            Expression::DropTrigger(_) => "drop_trigger",
2308            Expression::CreateType(_) => "create_type",
2309            Expression::DropType(_) => "drop_type",
2310            Expression::Describe(_) => "describe",
2311            Expression::Show(_) => "show",
2312            Expression::Command(_) => "command",
2313            Expression::TryCatch(_) => "try_catch",
2314            Expression::Kill(_) => "kill",
2315            Expression::Prepare(_) => "prepare",
2316            Expression::Execute(_) => "execute",
2317            Expression::Raw(_) => "raw",
2318            Expression::CreateTask(_) => "create_task",
2319            Expression::Paren(_) => "paren",
2320            Expression::Annotated(_) => "annotated",
2321            Expression::Refresh(_) => "refresh",
2322            Expression::LockingStatement(_) => "locking_statement",
2323            Expression::SequenceProperties(_) => "sequence_properties",
2324            Expression::TruncateTable(_) => "truncate_table",
2325            Expression::Clone(_) => "clone",
2326            Expression::Attach(_) => "attach",
2327            Expression::Detach(_) => "detach",
2328            Expression::Install(_) => "install",
2329            Expression::Summarize(_) => "summarize",
2330            Expression::Declare(_) => "declare",
2331            Expression::DeclareItem(_) => "declare_item",
2332            Expression::Set(_) => "set",
2333            Expression::Heredoc(_) => "heredoc",
2334            Expression::SetItem(_) => "set_item",
2335            Expression::QueryBand(_) => "query_band",
2336            Expression::UserDefinedFunction(_) => "user_defined_function",
2337            Expression::RecursiveWithSearch(_) => "recursive_with_search",
2338            Expression::ProjectionDef(_) => "projection_def",
2339            Expression::TableAlias(_) => "table_alias",
2340            Expression::ByteString(_) => "byte_string",
2341            Expression::HexStringExpr(_) => "hex_string_expr",
2342            Expression::UnicodeString(_) => "unicode_string",
2343            Expression::ColumnPosition(_) => "column_position",
2344            Expression::ColumnDef(_) => "column_def",
2345            Expression::AlterColumn(_) => "alter_column",
2346            Expression::AlterSortKey(_) => "alter_sort_key",
2347            Expression::AlterSet(_) => "alter_set",
2348            Expression::RenameColumn(_) => "rename_column",
2349            Expression::Comprehension(_) => "comprehension",
2350            Expression::MergeTreeTTLAction(_) => "merge_tree_t_t_l_action",
2351            Expression::MergeTreeTTL(_) => "merge_tree_t_t_l",
2352            Expression::IndexConstraintOption(_) => "index_constraint_option",
2353            Expression::ColumnConstraint(_) => "column_constraint",
2354            Expression::PeriodForSystemTimeConstraint(_) => "period_for_system_time_constraint",
2355            Expression::CaseSpecificColumnConstraint(_) => "case_specific_column_constraint",
2356            Expression::CharacterSetColumnConstraint(_) => "character_set_column_constraint",
2357            Expression::CheckColumnConstraint(_) => "check_column_constraint",
2358            Expression::AssumeColumnConstraint(_) => "assume_column_constraint",
2359            Expression::CompressColumnConstraint(_) => "compress_column_constraint",
2360            Expression::DateFormatColumnConstraint(_) => "date_format_column_constraint",
2361            Expression::EphemeralColumnConstraint(_) => "ephemeral_column_constraint",
2362            Expression::WithOperator(_) => "with_operator",
2363            Expression::GeneratedAsIdentityColumnConstraint(_) => {
2364                "generated_as_identity_column_constraint"
2365            }
2366            Expression::AutoIncrementColumnConstraint(_) => "auto_increment_column_constraint",
2367            Expression::CommentColumnConstraint(_) => "comment_column_constraint",
2368            Expression::GeneratedAsRowColumnConstraint(_) => "generated_as_row_column_constraint",
2369            Expression::IndexColumnConstraint(_) => "index_column_constraint",
2370            Expression::MaskingPolicyColumnConstraint(_) => "masking_policy_column_constraint",
2371            Expression::NotNullColumnConstraint(_) => "not_null_column_constraint",
2372            Expression::PrimaryKeyColumnConstraint(_) => "primary_key_column_constraint",
2373            Expression::UniqueColumnConstraint(_) => "unique_column_constraint",
2374            Expression::WatermarkColumnConstraint(_) => "watermark_column_constraint",
2375            Expression::ComputedColumnConstraint(_) => "computed_column_constraint",
2376            Expression::InOutColumnConstraint(_) => "in_out_column_constraint",
2377            Expression::DefaultColumnConstraint(_) => "default_column_constraint",
2378            Expression::PathColumnConstraint(_) => "path_column_constraint",
2379            Expression::Constraint(_) => "constraint",
2380            Expression::Export(_) => "export",
2381            Expression::Filter(_) => "filter",
2382            Expression::Changes(_) => "changes",
2383            Expression::CopyParameter(_) => "copy_parameter",
2384            Expression::Credentials(_) => "credentials",
2385            Expression::Directory(_) => "directory",
2386            Expression::ForeignKey(_) => "foreign_key",
2387            Expression::ColumnPrefix(_) => "column_prefix",
2388            Expression::PrimaryKey(_) => "primary_key",
2389            Expression::IntoClause(_) => "into_clause",
2390            Expression::JoinHint(_) => "join_hint",
2391            Expression::Opclass(_) => "opclass",
2392            Expression::Index(_) => "index",
2393            Expression::IndexParameters(_) => "index_parameters",
2394            Expression::ConditionalInsert(_) => "conditional_insert",
2395            Expression::MultitableInserts(_) => "multitable_inserts",
2396            Expression::OnConflict(_) => "on_conflict",
2397            Expression::OnCondition(_) => "on_condition",
2398            Expression::Returning(_) => "returning",
2399            Expression::Introducer(_) => "introducer",
2400            Expression::PartitionRange(_) => "partition_range",
2401            Expression::Fetch(_) => "fetch",
2402            Expression::Group(_) => "group",
2403            Expression::Cube(_) => "cube",
2404            Expression::Rollup(_) => "rollup",
2405            Expression::GroupingSets(_) => "grouping_sets",
2406            Expression::LimitOptions(_) => "limit_options",
2407            Expression::Lateral(_) => "lateral",
2408            Expression::TableFromRows(_) => "table_from_rows",
2409            Expression::RowsFrom(_) => "rows_from",
2410            Expression::MatchRecognizeMeasure(_) => "match_recognize_measure",
2411            Expression::WithFill(_) => "with_fill",
2412            Expression::Property(_) => "property",
2413            Expression::GrantPrivilege(_) => "grant_privilege",
2414            Expression::GrantPrincipal(_) => "grant_principal",
2415            Expression::AllowedValuesProperty(_) => "allowed_values_property",
2416            Expression::AlgorithmProperty(_) => "algorithm_property",
2417            Expression::AutoIncrementProperty(_) => "auto_increment_property",
2418            Expression::AutoRefreshProperty(_) => "auto_refresh_property",
2419            Expression::BackupProperty(_) => "backup_property",
2420            Expression::BuildProperty(_) => "build_property",
2421            Expression::BlockCompressionProperty(_) => "block_compression_property",
2422            Expression::CharacterSetProperty(_) => "character_set_property",
2423            Expression::ChecksumProperty(_) => "checksum_property",
2424            Expression::CollateProperty(_) => "collate_property",
2425            Expression::DataBlocksizeProperty(_) => "data_blocksize_property",
2426            Expression::DataDeletionProperty(_) => "data_deletion_property",
2427            Expression::DefinerProperty(_) => "definer_property",
2428            Expression::DistKeyProperty(_) => "dist_key_property",
2429            Expression::DistributedByProperty(_) => "distributed_by_property",
2430            Expression::DistStyleProperty(_) => "dist_style_property",
2431            Expression::DuplicateKeyProperty(_) => "duplicate_key_property",
2432            Expression::EngineProperty(_) => "engine_property",
2433            Expression::ToTableProperty(_) => "to_table_property",
2434            Expression::ExecuteAsProperty(_) => "execute_as_property",
2435            Expression::ExternalProperty(_) => "external_property",
2436            Expression::FallbackProperty(_) => "fallback_property",
2437            Expression::FileFormatProperty(_) => "file_format_property",
2438            Expression::CredentialsProperty(_) => "credentials_property",
2439            Expression::FreespaceProperty(_) => "freespace_property",
2440            Expression::InheritsProperty(_) => "inherits_property",
2441            Expression::InputModelProperty(_) => "input_model_property",
2442            Expression::OutputModelProperty(_) => "output_model_property",
2443            Expression::IsolatedLoadingProperty(_) => "isolated_loading_property",
2444            Expression::JournalProperty(_) => "journal_property",
2445            Expression::LanguageProperty(_) => "language_property",
2446            Expression::EnviromentProperty(_) => "enviroment_property",
2447            Expression::ClusteredByProperty(_) => "clustered_by_property",
2448            Expression::DictProperty(_) => "dict_property",
2449            Expression::DictRange(_) => "dict_range",
2450            Expression::OnCluster(_) => "on_cluster",
2451            Expression::LikeProperty(_) => "like_property",
2452            Expression::LocationProperty(_) => "location_property",
2453            Expression::LockProperty(_) => "lock_property",
2454            Expression::LockingProperty(_) => "locking_property",
2455            Expression::LogProperty(_) => "log_property",
2456            Expression::MaterializedProperty(_) => "materialized_property",
2457            Expression::MergeBlockRatioProperty(_) => "merge_block_ratio_property",
2458            Expression::OnProperty(_) => "on_property",
2459            Expression::OnCommitProperty(_) => "on_commit_property",
2460            Expression::PartitionedByProperty(_) => "partitioned_by_property",
2461            Expression::PartitionByProperty(_) => "partition_by_property",
2462            Expression::PartitionedByBucket(_) => "partitioned_by_bucket",
2463            Expression::ClusterByColumnsProperty(_) => "cluster_by_columns_property",
2464            Expression::PartitionByTruncate(_) => "partition_by_truncate",
2465            Expression::PartitionByRangeProperty(_) => "partition_by_range_property",
2466            Expression::PartitionByRangePropertyDynamic(_) => "partition_by_range_property_dynamic",
2467            Expression::PartitionByListProperty(_) => "partition_by_list_property",
2468            Expression::PartitionList(_) => "partition_list",
2469            Expression::Partition(_) => "partition",
2470            Expression::RefreshTriggerProperty(_) => "refresh_trigger_property",
2471            Expression::UniqueKeyProperty(_) => "unique_key_property",
2472            Expression::RollupProperty(_) => "rollup_property",
2473            Expression::PartitionBoundSpec(_) => "partition_bound_spec",
2474            Expression::PartitionedOfProperty(_) => "partitioned_of_property",
2475            Expression::RemoteWithConnectionModelProperty(_) => {
2476                "remote_with_connection_model_property"
2477            }
2478            Expression::ReturnsProperty(_) => "returns_property",
2479            Expression::RowFormatProperty(_) => "row_format_property",
2480            Expression::RowFormatDelimitedProperty(_) => "row_format_delimited_property",
2481            Expression::RowFormatSerdeProperty(_) => "row_format_serde_property",
2482            Expression::QueryTransform(_) => "query_transform",
2483            Expression::SampleProperty(_) => "sample_property",
2484            Expression::SecurityProperty(_) => "security_property",
2485            Expression::SchemaCommentProperty(_) => "schema_comment_property",
2486            Expression::SemanticView(_) => "semantic_view",
2487            Expression::SerdeProperties(_) => "serde_properties",
2488            Expression::SetProperty(_) => "set_property",
2489            Expression::SharingProperty(_) => "sharing_property",
2490            Expression::SetConfigProperty(_) => "set_config_property",
2491            Expression::SettingsProperty(_) => "settings_property",
2492            Expression::SortKeyProperty(_) => "sort_key_property",
2493            Expression::SqlReadWriteProperty(_) => "sql_read_write_property",
2494            Expression::SqlSecurityProperty(_) => "sql_security_property",
2495            Expression::StabilityProperty(_) => "stability_property",
2496            Expression::StorageHandlerProperty(_) => "storage_handler_property",
2497            Expression::TemporaryProperty(_) => "temporary_property",
2498            Expression::Tags(_) => "tags",
2499            Expression::TransformModelProperty(_) => "transform_model_property",
2500            Expression::TransientProperty(_) => "transient_property",
2501            Expression::UsingTemplateProperty(_) => "using_template_property",
2502            Expression::ViewAttributeProperty(_) => "view_attribute_property",
2503            Expression::VolatileProperty(_) => "volatile_property",
2504            Expression::WithDataProperty(_) => "with_data_property",
2505            Expression::WithJournalTableProperty(_) => "with_journal_table_property",
2506            Expression::WithSchemaBindingProperty(_) => "with_schema_binding_property",
2507            Expression::WithSystemVersioningProperty(_) => "with_system_versioning_property",
2508            Expression::WithProcedureOptions(_) => "with_procedure_options",
2509            Expression::EncodeProperty(_) => "encode_property",
2510            Expression::IncludeProperty(_) => "include_property",
2511            Expression::Properties(_) => "properties",
2512            Expression::OptionsProperty(_) => "options_property",
2513            Expression::InputOutputFormat(_) => "input_output_format",
2514            Expression::Reference(_) => "reference",
2515            Expression::QueryOption(_) => "query_option",
2516            Expression::WithTableHint(_) => "with_table_hint",
2517            Expression::IndexTableHint(_) => "index_table_hint",
2518            Expression::HistoricalData(_) => "historical_data",
2519            Expression::Get(_) => "get",
2520            Expression::SetOperation(_) => "set_operation",
2521            Expression::Var(_) => "var",
2522            Expression::Variadic(_) => "variadic",
2523            Expression::Version(_) => "version",
2524            Expression::Schema(_) => "schema",
2525            Expression::Lock(_) => "lock",
2526            Expression::TableSample(_) => "table_sample",
2527            Expression::Tag(_) => "tag",
2528            Expression::UnpivotColumns(_) => "unpivot_columns",
2529            Expression::WindowSpec(_) => "window_spec",
2530            Expression::SessionParameter(_) => "session_parameter",
2531            Expression::PseudoType(_) => "pseudo_type",
2532            Expression::ObjectIdentifier(_) => "object_identifier",
2533            Expression::Transaction(_) => "transaction",
2534            Expression::Commit(_) => "commit",
2535            Expression::Rollback(_) => "rollback",
2536            Expression::AlterSession(_) => "alter_session",
2537            Expression::Analyze(_) => "analyze",
2538            Expression::AnalyzeStatistics(_) => "analyze_statistics",
2539            Expression::AnalyzeHistogram(_) => "analyze_histogram",
2540            Expression::AnalyzeSample(_) => "analyze_sample",
2541            Expression::AnalyzeListChainedRows(_) => "analyze_list_chained_rows",
2542            Expression::AnalyzeDelete(_) => "analyze_delete",
2543            Expression::AnalyzeWith(_) => "analyze_with",
2544            Expression::AnalyzeValidate(_) => "analyze_validate",
2545            Expression::AddPartition(_) => "add_partition",
2546            Expression::AttachOption(_) => "attach_option",
2547            Expression::DropPartition(_) => "drop_partition",
2548            Expression::ReplacePartition(_) => "replace_partition",
2549            Expression::DPipe(_) => "d_pipe",
2550            Expression::Operator(_) => "operator",
2551            Expression::PivotAny(_) => "pivot_any",
2552            Expression::Aliases(_) => "aliases",
2553            Expression::AtIndex(_) => "at_index",
2554            Expression::FromTimeZone(_) => "from_time_zone",
2555            Expression::FormatPhrase(_) => "format_phrase",
2556            Expression::ForIn(_) => "for_in",
2557            Expression::TimeUnit(_) => "time_unit",
2558            Expression::IntervalOp(_) => "interval_op",
2559            Expression::IntervalSpan(_) => "interval_span",
2560            Expression::HavingMax(_) => "having_max",
2561            Expression::CosineDistance(_) => "cosine_distance",
2562            Expression::DotProduct(_) => "dot_product",
2563            Expression::EuclideanDistance(_) => "euclidean_distance",
2564            Expression::ManhattanDistance(_) => "manhattan_distance",
2565            Expression::JarowinklerSimilarity(_) => "jarowinkler_similarity",
2566            Expression::Booland(_) => "booland",
2567            Expression::Boolor(_) => "boolor",
2568            Expression::ParameterizedAgg(_) => "parameterized_agg",
2569            Expression::ArgMax(_) => "arg_max",
2570            Expression::ArgMin(_) => "arg_min",
2571            Expression::ApproxTopK(_) => "approx_top_k",
2572            Expression::ApproxTopKAccumulate(_) => "approx_top_k_accumulate",
2573            Expression::ApproxTopKCombine(_) => "approx_top_k_combine",
2574            Expression::ApproxTopKEstimate(_) => "approx_top_k_estimate",
2575            Expression::ApproxTopSum(_) => "approx_top_sum",
2576            Expression::ApproxQuantiles(_) => "approx_quantiles",
2577            Expression::Minhash(_) => "minhash",
2578            Expression::FarmFingerprint(_) => "farm_fingerprint",
2579            Expression::Float64(_) => "float64",
2580            Expression::Transform(_) => "transform",
2581            Expression::Translate(_) => "translate",
2582            Expression::Grouping(_) => "grouping",
2583            Expression::GroupingId(_) => "grouping_id",
2584            Expression::Anonymous(_) => "anonymous",
2585            Expression::AnonymousAggFunc(_) => "anonymous_agg_func",
2586            Expression::CombinedAggFunc(_) => "combined_agg_func",
2587            Expression::CombinedParameterizedAgg(_) => "combined_parameterized_agg",
2588            Expression::HashAgg(_) => "hash_agg",
2589            Expression::Hll(_) => "hll",
2590            Expression::Apply(_) => "apply",
2591            Expression::ToBoolean(_) => "to_boolean",
2592            Expression::List(_) => "list",
2593            Expression::ToMap(_) => "to_map",
2594            Expression::Pad(_) => "pad",
2595            Expression::ToChar(_) => "to_char",
2596            Expression::ToNumber(_) => "to_number",
2597            Expression::ToDouble(_) => "to_double",
2598            Expression::Int64(_) => "int64",
2599            Expression::StringFunc(_) => "string_func",
2600            Expression::ToDecfloat(_) => "to_decfloat",
2601            Expression::TryToDecfloat(_) => "try_to_decfloat",
2602            Expression::ToFile(_) => "to_file",
2603            Expression::Columns(_) => "columns",
2604            Expression::ConvertToCharset(_) => "convert_to_charset",
2605            Expression::ConvertTimezone(_) => "convert_timezone",
2606            Expression::GenerateSeries(_) => "generate_series",
2607            Expression::AIAgg(_) => "a_i_agg",
2608            Expression::AIClassify(_) => "a_i_classify",
2609            Expression::ArrayAll(_) => "array_all",
2610            Expression::ArrayAny(_) => "array_any",
2611            Expression::ArrayConstructCompact(_) => "array_construct_compact",
2612            Expression::StPoint(_) => "st_point",
2613            Expression::StDistance(_) => "st_distance",
2614            Expression::StringToArray(_) => "string_to_array",
2615            Expression::ArraySum(_) => "array_sum",
2616            Expression::ObjectAgg(_) => "object_agg",
2617            Expression::CastToStrType(_) => "cast_to_str_type",
2618            Expression::CheckJson(_) => "check_json",
2619            Expression::CheckXml(_) => "check_xml",
2620            Expression::TranslateCharacters(_) => "translate_characters",
2621            Expression::CurrentSchemas(_) => "current_schemas",
2622            Expression::CurrentDatetime(_) => "current_datetime",
2623            Expression::Localtime(_) => "localtime",
2624            Expression::Localtimestamp(_) => "localtimestamp",
2625            Expression::Systimestamp(_) => "systimestamp",
2626            Expression::CurrentSchema(_) => "current_schema",
2627            Expression::CurrentUser(_) => "current_user",
2628            Expression::UtcTime(_) => "utc_time",
2629            Expression::UtcTimestamp(_) => "utc_timestamp",
2630            Expression::Timestamp(_) => "timestamp",
2631            Expression::DateBin(_) => "date_bin",
2632            Expression::Datetime(_) => "datetime",
2633            Expression::DatetimeAdd(_) => "datetime_add",
2634            Expression::DatetimeSub(_) => "datetime_sub",
2635            Expression::DatetimeDiff(_) => "datetime_diff",
2636            Expression::DatetimeTrunc(_) => "datetime_trunc",
2637            Expression::Dayname(_) => "dayname",
2638            Expression::MakeInterval(_) => "make_interval",
2639            Expression::PreviousDay(_) => "previous_day",
2640            Expression::Elt(_) => "elt",
2641            Expression::TimestampAdd(_) => "timestamp_add",
2642            Expression::TimestampSub(_) => "timestamp_sub",
2643            Expression::TimestampDiff(_) => "timestamp_diff",
2644            Expression::TimeSlice(_) => "time_slice",
2645            Expression::TimeAdd(_) => "time_add",
2646            Expression::TimeSub(_) => "time_sub",
2647            Expression::TimeDiff(_) => "time_diff",
2648            Expression::TimeTrunc(_) => "time_trunc",
2649            Expression::DateFromParts(_) => "date_from_parts",
2650            Expression::TimeFromParts(_) => "time_from_parts",
2651            Expression::DecodeCase(_) => "decode_case",
2652            Expression::Decrypt(_) => "decrypt",
2653            Expression::DecryptRaw(_) => "decrypt_raw",
2654            Expression::Encode(_) => "encode",
2655            Expression::Encrypt(_) => "encrypt",
2656            Expression::EncryptRaw(_) => "encrypt_raw",
2657            Expression::EqualNull(_) => "equal_null",
2658            Expression::ToBinary(_) => "to_binary",
2659            Expression::Base64DecodeBinary(_) => "base64_decode_binary",
2660            Expression::Base64DecodeString(_) => "base64_decode_string",
2661            Expression::Base64Encode(_) => "base64_encode",
2662            Expression::TryBase64DecodeBinary(_) => "try_base64_decode_binary",
2663            Expression::TryBase64DecodeString(_) => "try_base64_decode_string",
2664            Expression::GapFill(_) => "gap_fill",
2665            Expression::GenerateDateArray(_) => "generate_date_array",
2666            Expression::GenerateTimestampArray(_) => "generate_timestamp_array",
2667            Expression::GetExtract(_) => "get_extract",
2668            Expression::Getbit(_) => "getbit",
2669            Expression::OverflowTruncateBehavior(_) => "overflow_truncate_behavior",
2670            Expression::HexEncode(_) => "hex_encode",
2671            Expression::Compress(_) => "compress",
2672            Expression::DecompressBinary(_) => "decompress_binary",
2673            Expression::DecompressString(_) => "decompress_string",
2674            Expression::Xor(_) => "xor",
2675            Expression::Nullif(_) => "nullif",
2676            Expression::JSON(_) => "j_s_o_n",
2677            Expression::JSONPath(_) => "j_s_o_n_path",
2678            Expression::JSONPathFilter(_) => "j_s_o_n_path_filter",
2679            Expression::JSONPathKey(_) => "j_s_o_n_path_key",
2680            Expression::JSONPathRecursive(_) => "j_s_o_n_path_recursive",
2681            Expression::JSONPathScript(_) => "j_s_o_n_path_script",
2682            Expression::JSONPathSlice(_) => "j_s_o_n_path_slice",
2683            Expression::JSONPathSelector(_) => "j_s_o_n_path_selector",
2684            Expression::JSONPathSubscript(_) => "j_s_o_n_path_subscript",
2685            Expression::JSONPathUnion(_) => "j_s_o_n_path_union",
2686            Expression::Format(_) => "format",
2687            Expression::JSONKeys(_) => "j_s_o_n_keys",
2688            Expression::JSONKeyValue(_) => "j_s_o_n_key_value",
2689            Expression::JSONKeysAtDepth(_) => "j_s_o_n_keys_at_depth",
2690            Expression::JSONObject(_) => "j_s_o_n_object",
2691            Expression::JSONObjectAgg(_) => "j_s_o_n_object_agg",
2692            Expression::JSONBObjectAgg(_) => "j_s_o_n_b_object_agg",
2693            Expression::JSONArray(_) => "j_s_o_n_array",
2694            Expression::JSONArrayAgg(_) => "j_s_o_n_array_agg",
2695            Expression::JSONExists(_) => "j_s_o_n_exists",
2696            Expression::JSONColumnDef(_) => "j_s_o_n_column_def",
2697            Expression::JSONSchema(_) => "j_s_o_n_schema",
2698            Expression::JSONSet(_) => "j_s_o_n_set",
2699            Expression::JSONStripNulls(_) => "j_s_o_n_strip_nulls",
2700            Expression::JSONValue(_) => "j_s_o_n_value",
2701            Expression::JSONValueArray(_) => "j_s_o_n_value_array",
2702            Expression::JSONRemove(_) => "j_s_o_n_remove",
2703            Expression::JSONTable(_) => "j_s_o_n_table",
2704            Expression::JSONType(_) => "j_s_o_n_type",
2705            Expression::ObjectInsert(_) => "object_insert",
2706            Expression::OpenJSONColumnDef(_) => "open_j_s_o_n_column_def",
2707            Expression::OpenJSON(_) => "open_j_s_o_n",
2708            Expression::JSONBExists(_) => "j_s_o_n_b_exists",
2709            Expression::JSONBContains(_) => "j_s_o_n_b_contains",
2710            Expression::JSONBExtract(_) => "j_s_o_n_b_extract",
2711            Expression::JSONCast(_) => "j_s_o_n_cast",
2712            Expression::JSONExtract(_) => "j_s_o_n_extract",
2713            Expression::JSONExtractQuote(_) => "j_s_o_n_extract_quote",
2714            Expression::JSONExtractArray(_) => "j_s_o_n_extract_array",
2715            Expression::JSONExtractScalar(_) => "j_s_o_n_extract_scalar",
2716            Expression::JSONBExtractScalar(_) => "j_s_o_n_b_extract_scalar",
2717            Expression::JSONFormat(_) => "j_s_o_n_format",
2718            Expression::JSONBool(_) => "j_s_o_n_bool",
2719            Expression::JSONPathRoot(_) => "j_s_o_n_path_root",
2720            Expression::JSONArrayAppend(_) => "j_s_o_n_array_append",
2721            Expression::JSONArrayContains(_) => "j_s_o_n_array_contains",
2722            Expression::JSONArrayInsert(_) => "j_s_o_n_array_insert",
2723            Expression::ParseJSON(_) => "parse_j_s_o_n",
2724            Expression::ParseUrl(_) => "parse_url",
2725            Expression::ParseIp(_) => "parse_ip",
2726            Expression::ParseTime(_) => "parse_time",
2727            Expression::ParseDatetime(_) => "parse_datetime",
2728            Expression::Map(_) => "map",
2729            Expression::MapCat(_) => "map_cat",
2730            Expression::MapDelete(_) => "map_delete",
2731            Expression::MapInsert(_) => "map_insert",
2732            Expression::MapPick(_) => "map_pick",
2733            Expression::ScopeResolution(_) => "scope_resolution",
2734            Expression::Slice(_) => "slice",
2735            Expression::VarMap(_) => "var_map",
2736            Expression::MatchAgainst(_) => "match_against",
2737            Expression::MD5Digest(_) => "m_d5_digest",
2738            Expression::MD5NumberLower64(_) => "m_d5_number_lower64",
2739            Expression::MD5NumberUpper64(_) => "m_d5_number_upper64",
2740            Expression::Monthname(_) => "monthname",
2741            Expression::Ntile(_) => "ntile",
2742            Expression::Normalize(_) => "normalize",
2743            Expression::Normal(_) => "normal",
2744            Expression::Predict(_) => "predict",
2745            Expression::MLTranslate(_) => "m_l_translate",
2746            Expression::FeaturesAtTime(_) => "features_at_time",
2747            Expression::GenerateEmbedding(_) => "generate_embedding",
2748            Expression::MLForecast(_) => "m_l_forecast",
2749            Expression::ModelAttribute(_) => "model_attribute",
2750            Expression::VectorSearch(_) => "vector_search",
2751            Expression::Quantile(_) => "quantile",
2752            Expression::ApproxQuantile(_) => "approx_quantile",
2753            Expression::ApproxPercentileEstimate(_) => "approx_percentile_estimate",
2754            Expression::Randn(_) => "randn",
2755            Expression::Randstr(_) => "randstr",
2756            Expression::RangeN(_) => "range_n",
2757            Expression::RangeBucket(_) => "range_bucket",
2758            Expression::ReadCSV(_) => "read_c_s_v",
2759            Expression::ReadParquet(_) => "read_parquet",
2760            Expression::Reduce(_) => "reduce",
2761            Expression::RegexpExtractAll(_) => "regexp_extract_all",
2762            Expression::RegexpILike(_) => "regexp_i_like",
2763            Expression::RegexpFullMatch(_) => "regexp_full_match",
2764            Expression::RegexpInstr(_) => "regexp_instr",
2765            Expression::RegexpSplit(_) => "regexp_split",
2766            Expression::RegexpCount(_) => "regexp_count",
2767            Expression::RegrValx(_) => "regr_valx",
2768            Expression::RegrValy(_) => "regr_valy",
2769            Expression::RegrAvgy(_) => "regr_avgy",
2770            Expression::RegrAvgx(_) => "regr_avgx",
2771            Expression::RegrCount(_) => "regr_count",
2772            Expression::RegrIntercept(_) => "regr_intercept",
2773            Expression::RegrR2(_) => "regr_r2",
2774            Expression::RegrSxx(_) => "regr_sxx",
2775            Expression::RegrSxy(_) => "regr_sxy",
2776            Expression::RegrSyy(_) => "regr_syy",
2777            Expression::RegrSlope(_) => "regr_slope",
2778            Expression::SafeAdd(_) => "safe_add",
2779            Expression::SafeDivide(_) => "safe_divide",
2780            Expression::SafeMultiply(_) => "safe_multiply",
2781            Expression::SafeSubtract(_) => "safe_subtract",
2782            Expression::SHA2(_) => "s_h_a2",
2783            Expression::SHA2Digest(_) => "s_h_a2_digest",
2784            Expression::SortArray(_) => "sort_array",
2785            Expression::SplitPart(_) => "split_part",
2786            Expression::SubstringIndex(_) => "substring_index",
2787            Expression::StandardHash(_) => "standard_hash",
2788            Expression::StrPosition(_) => "str_position",
2789            Expression::Search(_) => "search",
2790            Expression::SearchIp(_) => "search_ip",
2791            Expression::StrToDate(_) => "str_to_date",
2792            Expression::DateStrToDate(_) => "date_str_to_date",
2793            Expression::DateToDateStr(_) => "date_to_date_str",
2794            Expression::StrToTime(_) => "str_to_time",
2795            Expression::StrToUnix(_) => "str_to_unix",
2796            Expression::StrToMap(_) => "str_to_map",
2797            Expression::NumberToStr(_) => "number_to_str",
2798            Expression::FromBase(_) => "from_base",
2799            Expression::Stuff(_) => "stuff",
2800            Expression::TimeToStr(_) => "time_to_str",
2801            Expression::TimeStrToTime(_) => "time_str_to_time",
2802            Expression::TsOrDsAdd(_) => "ts_or_ds_add",
2803            Expression::TsOrDsDiff(_) => "ts_or_ds_diff",
2804            Expression::TsOrDsToDate(_) => "ts_or_ds_to_date",
2805            Expression::TsOrDsToTime(_) => "ts_or_ds_to_time",
2806            Expression::Unhex(_) => "unhex",
2807            Expression::Uniform(_) => "uniform",
2808            Expression::UnixToStr(_) => "unix_to_str",
2809            Expression::UnixToTime(_) => "unix_to_time",
2810            Expression::Uuid(_) => "uuid",
2811            Expression::TimestampFromParts(_) => "timestamp_from_parts",
2812            Expression::TimestampTzFromParts(_) => "timestamp_tz_from_parts",
2813            Expression::Corr(_) => "corr",
2814            Expression::WidthBucket(_) => "width_bucket",
2815            Expression::CovarSamp(_) => "covar_samp",
2816            Expression::CovarPop(_) => "covar_pop",
2817            Expression::Week(_) => "week",
2818            Expression::XMLElement(_) => "x_m_l_element",
2819            Expression::XMLGet(_) => "x_m_l_get",
2820            Expression::XMLTable(_) => "x_m_l_table",
2821            Expression::XMLKeyValueOption(_) => "x_m_l_key_value_option",
2822            Expression::Zipf(_) => "zipf",
2823            Expression::Merge(_) => "merge",
2824            Expression::When(_) => "when",
2825            Expression::Whens(_) => "whens",
2826            Expression::NextValueFor(_) => "next_value_for",
2827            Expression::ReturnStmt(_) => "return_stmt",
2828        }
2829    }
2830
2831    /// Returns the primary child expression (".this" in sqlglot).
2832    pub fn get_this(&self) -> Option<&Expression> {
2833        match self {
2834            Expression::JSONValue(j) => Some(&j.this),
2835            Expression::JSONTable(j) => Some(&j.this),
2836            Expression::JSONColumnDef(j) => j.this.as_deref(),
2837            Expression::Hierarchy(hierarchy) => Some(&hierarchy.source),
2838            Expression::Upsert(upsert) => Some(&upsert.source),
2839            // Unary ops
2840            Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this),
2841            // UnaryFunc variants
2842            Expression::Upper(f)
2843            | Expression::Lower(f)
2844            | Expression::Length(f)
2845            | Expression::LTrim(f)
2846            | Expression::RTrim(f)
2847            | Expression::Reverse(f)
2848            | Expression::Abs(f)
2849            | Expression::Sqrt(f)
2850            | Expression::Cbrt(f)
2851            | Expression::Ln(f)
2852            | Expression::Exp(f)
2853            | Expression::Sign(f)
2854            | Expression::Date(f)
2855            | Expression::Time(f)
2856            | Expression::Initcap(f)
2857            | Expression::Ascii(f)
2858            | Expression::Chr(f)
2859            | Expression::Soundex(f)
2860            | Expression::ByteLength(f)
2861            | Expression::Hex(f)
2862            | Expression::LowerHex(f)
2863            | Expression::Unicode(f)
2864            | Expression::Typeof(f)
2865            | Expression::Explode(f)
2866            | Expression::ExplodeOuter(f)
2867            | Expression::MapFromEntries(f)
2868            | Expression::MapKeys(f)
2869            | Expression::MapValues(f)
2870            | Expression::ArrayLength(f)
2871            | Expression::ArraySize(f)
2872            | Expression::Cardinality(f)
2873            | Expression::ArrayReverse(f)
2874            | Expression::ArrayDistinct(f)
2875            | Expression::ArrayFlatten(f)
2876            | Expression::ArrayCompact(f)
2877            | Expression::ToArray(f)
2878            | Expression::JsonArrayLength(f)
2879            | Expression::JsonKeys(f)
2880            | Expression::JsonType(f)
2881            | Expression::ParseJson(f)
2882            | Expression::ToJson(f)
2883            | Expression::Radians(f)
2884            | Expression::Degrees(f)
2885            | Expression::Sin(f)
2886            | Expression::Cos(f)
2887            | Expression::Tan(f)
2888            | Expression::Asin(f)
2889            | Expression::Acos(f)
2890            | Expression::Atan(f)
2891            | Expression::IsNan(f)
2892            | Expression::IsInf(f)
2893            | Expression::Year(f)
2894            | Expression::Month(f)
2895            | Expression::Day(f)
2896            | Expression::Hour(f)
2897            | Expression::Minute(f)
2898            | Expression::Second(f)
2899            | Expression::DayOfWeek(f)
2900            | Expression::DayOfWeekIso(f)
2901            | Expression::DayOfMonth(f)
2902            | Expression::DayOfYear(f)
2903            | Expression::WeekOfYear(f)
2904            | Expression::Quarter(f)
2905            | Expression::Epoch(f)
2906            | Expression::EpochMs(f)
2907            | Expression::BitwiseCount(f)
2908            | Expression::DateFromUnixDate(f)
2909            | Expression::UnixDate(f)
2910            | Expression::UnixSeconds(f)
2911            | Expression::UnixMillis(f)
2912            | Expression::UnixMicros(f)
2913            | Expression::TimeStrToDate(f)
2914            | Expression::DateToDi(f)
2915            | Expression::DiToDate(f)
2916            | Expression::TsOrDiToDi(f)
2917            | Expression::TsOrDsToDatetime(f)
2918            | Expression::TsOrDsToTimestamp(f)
2919            | Expression::YearOfWeek(f)
2920            | Expression::YearOfWeekIso(f)
2921            | Expression::SHA(f)
2922            | Expression::SHA1Digest(f)
2923            | Expression::TimeToUnix(f)
2924            | Expression::TimeStrToUnix(f)
2925            | Expression::Int64(f)
2926            | Expression::JSONBool(f)
2927            | Expression::MD5NumberLower64(f)
2928            | Expression::MD5NumberUpper64(f)
2929            | Expression::DateStrToDate(f)
2930            | Expression::DateToDateStr(f) => Some(&f.this),
2931            // BinaryFunc - this is the primary child
2932            Expression::Power(f)
2933            | Expression::NullIf(f)
2934            | Expression::IfNull(f)
2935            | Expression::Nvl(f)
2936            | Expression::Contains(f)
2937            | Expression::StartsWith(f)
2938            | Expression::EndsWith(f)
2939            | Expression::Levenshtein(f)
2940            | Expression::ModFunc(f)
2941            | Expression::IntDiv(f)
2942            | Expression::Atan2(f)
2943            | Expression::AddMonths(f)
2944            | Expression::MonthsBetween(f)
2945            | Expression::NextDay(f)
2946            | Expression::UnixToTimeStr(f)
2947            | Expression::ArrayContains(f)
2948            | Expression::ArrayPosition(f)
2949            | Expression::ArrayAppend(f)
2950            | Expression::ArrayPrepend(f)
2951            | Expression::ArrayUnion(f)
2952            | Expression::ArrayExcept(f)
2953            | Expression::ArrayRemove(f)
2954            | Expression::StarMap(f)
2955            | Expression::MapFromArrays(f)
2956            | Expression::MapContainsKey(f)
2957            | Expression::ElementAt(f)
2958            | Expression::JsonMergePatch(f)
2959            | Expression::JSONBContains(f)
2960            | Expression::JSONBExtract(f) => Some(&f.this),
2961            // AggFunc - this is the primary child
2962            Expression::Sum(af)
2963            | Expression::Avg(af)
2964            | Expression::Min(af)
2965            | Expression::Max(af)
2966            | Expression::ArrayAgg(af)
2967            | Expression::CountIf(af)
2968            | Expression::Stddev(af)
2969            | Expression::StddevPop(af)
2970            | Expression::StddevSamp(af)
2971            | Expression::Variance(af)
2972            | Expression::VarPop(af)
2973            | Expression::VarSamp(af)
2974            | Expression::Median(af)
2975            | Expression::Mode(af)
2976            | Expression::First(af)
2977            | Expression::Last(af)
2978            | Expression::AnyValue(af)
2979            | Expression::ApproxDistinct(af)
2980            | Expression::ApproxCountDistinct(af)
2981            | Expression::LogicalAnd(af)
2982            | Expression::LogicalOr(af)
2983            | Expression::Skewness(af)
2984            | Expression::ArrayConcatAgg(af)
2985            | Expression::ArrayUniqueAgg(af)
2986            | Expression::BoolXorAgg(af)
2987            | Expression::BitwiseAndAgg(af)
2988            | Expression::BitwiseOrAgg(af)
2989            | Expression::BitwiseXorAgg(af) => Some(&af.this),
2990            // Binary operations - left is "this" in sqlglot
2991            Expression::And(op)
2992            | Expression::Or(op)
2993            | Expression::Add(op)
2994            | Expression::Sub(op)
2995            | Expression::Mul(op)
2996            | Expression::Div(op)
2997            | Expression::Mod(op)
2998            | Expression::Eq(op)
2999            | Expression::Neq(op)
3000            | Expression::Lt(op)
3001            | Expression::Lte(op)
3002            | Expression::Gt(op)
3003            | Expression::Gte(op)
3004            | Expression::BitwiseAnd(op)
3005            | Expression::BitwiseOr(op)
3006            | Expression::BitwiseXor(op)
3007            | Expression::Concat(op)
3008            | Expression::Adjacent(op)
3009            | Expression::TsMatch(op)
3010            | Expression::PropertyEQ(op)
3011            | Expression::ArrayContainsAll(op)
3012            | Expression::ArrayContainedBy(op)
3013            | Expression::ArrayOverlaps(op)
3014            | Expression::JSONBContainsAllTopKeys(op)
3015            | Expression::JSONBContainsAnyTopKeys(op)
3016            | Expression::JSONBDeleteAtPath(op)
3017            | Expression::ExtendsLeft(op)
3018            | Expression::ExtendsRight(op)
3019            | Expression::Is(op)
3020            | Expression::MemberOf(op)
3021            | Expression::Match(op)
3022            | Expression::NullSafeEq(op)
3023            | Expression::NullSafeNeq(op)
3024            | Expression::Glob(op)
3025            | Expression::BitwiseLeftShift(op)
3026            | Expression::BitwiseRightShift(op) => Some(&op.left),
3027            // Like operations - left is "this"
3028            Expression::Like(op) | Expression::ILike(op) => Some(&op.left),
3029            // Structural types with .this
3030            Expression::Alias(a) => Some(&a.this),
3031            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => Some(&c.this),
3032            Expression::Paren(p) => Some(&p.this),
3033            Expression::Annotated(a) => Some(&a.this),
3034            Expression::Subquery(s) => Some(&s.this),
3035            Expression::Where(w) => Some(&w.this),
3036            Expression::Having(h) => Some(&h.this),
3037            Expression::Qualify(q) => Some(&q.this),
3038            Expression::IsNull(i) => Some(&i.this),
3039            Expression::Exists(e) => Some(&e.this),
3040            Expression::Ordered(o) => Some(&o.this),
3041            Expression::WindowFunction(wf) => Some(&wf.this),
3042            Expression::Cte(cte) => Some(&cte.this),
3043            Expression::Between(b) => Some(&b.this),
3044            Expression::In(i) => Some(&i.this),
3045            Expression::ReturnStmt(e) => Some(e),
3046            _ => None,
3047        }
3048    }
3049
3050    /// Returns the secondary child expression (".expression" in sqlglot).
3051    pub fn get_expression(&self) -> Option<&Expression> {
3052        match self {
3053            // Binary operations - right is "expression"
3054            Expression::And(op)
3055            | Expression::Or(op)
3056            | Expression::Add(op)
3057            | Expression::Sub(op)
3058            | Expression::Mul(op)
3059            | Expression::Div(op)
3060            | Expression::Mod(op)
3061            | Expression::Eq(op)
3062            | Expression::Neq(op)
3063            | Expression::Lt(op)
3064            | Expression::Lte(op)
3065            | Expression::Gt(op)
3066            | Expression::Gte(op)
3067            | Expression::BitwiseAnd(op)
3068            | Expression::BitwiseOr(op)
3069            | Expression::BitwiseXor(op)
3070            | Expression::Concat(op)
3071            | Expression::Adjacent(op)
3072            | Expression::TsMatch(op)
3073            | Expression::PropertyEQ(op)
3074            | Expression::ArrayContainsAll(op)
3075            | Expression::ArrayContainedBy(op)
3076            | Expression::ArrayOverlaps(op)
3077            | Expression::JSONBContainsAllTopKeys(op)
3078            | Expression::JSONBContainsAnyTopKeys(op)
3079            | Expression::JSONBDeleteAtPath(op)
3080            | Expression::ExtendsLeft(op)
3081            | Expression::ExtendsRight(op)
3082            | Expression::Is(op)
3083            | Expression::MemberOf(op)
3084            | Expression::Match(op)
3085            | Expression::NullSafeEq(op)
3086            | Expression::NullSafeNeq(op)
3087            | Expression::Glob(op)
3088            | Expression::BitwiseLeftShift(op)
3089            | Expression::BitwiseRightShift(op) => Some(&op.right),
3090            // Like operations - right is "expression"
3091            Expression::Like(op) | Expression::ILike(op) => Some(&op.right),
3092            // BinaryFunc - expression is the secondary
3093            Expression::Power(f)
3094            | Expression::NullIf(f)
3095            | Expression::IfNull(f)
3096            | Expression::Nvl(f)
3097            | Expression::Contains(f)
3098            | Expression::StartsWith(f)
3099            | Expression::EndsWith(f)
3100            | Expression::Levenshtein(f)
3101            | Expression::ModFunc(f)
3102            | Expression::IntDiv(f)
3103            | Expression::Atan2(f)
3104            | Expression::AddMonths(f)
3105            | Expression::MonthsBetween(f)
3106            | Expression::NextDay(f)
3107            | Expression::UnixToTimeStr(f)
3108            | Expression::ArrayContains(f)
3109            | Expression::ArrayPosition(f)
3110            | Expression::ArrayAppend(f)
3111            | Expression::ArrayPrepend(f)
3112            | Expression::ArrayUnion(f)
3113            | Expression::ArrayExcept(f)
3114            | Expression::ArrayRemove(f)
3115            | Expression::StarMap(f)
3116            | Expression::MapFromArrays(f)
3117            | Expression::MapContainsKey(f)
3118            | Expression::ElementAt(f)
3119            | Expression::JsonMergePatch(f)
3120            | Expression::JSONBContains(f)
3121            | Expression::JSONBExtract(f) => Some(&f.expression),
3122            _ => None,
3123        }
3124    }
3125
3126    /// Returns the list of child expressions (".expressions" in sqlglot).
3127    pub fn get_expressions(&self) -> &[Expression] {
3128        match self {
3129            Expression::Select(s) => &s.expressions,
3130            Expression::Function(f) => &f.args,
3131            Expression::AggregateFunction(f) => &f.args,
3132            Expression::Call(f) => &f.arguments,
3133            Expression::From(f) => &f.expressions,
3134            Expression::GroupBy(g) => &g.expressions,
3135            Expression::In(i) => &i.expressions,
3136            Expression::Array(a) => &a.expressions,
3137            Expression::ArrayFunc(a) => &a.expressions,
3138            Expression::Tuple(t) => &t.expressions,
3139            Expression::Coalesce(f)
3140            | Expression::Greatest(f)
3141            | Expression::Least(f)
3142            | Expression::ArrayConcat(f)
3143            | Expression::ArrayIntersect(f)
3144            | Expression::ArrayZip(f)
3145            | Expression::MapConcat(f)
3146            | Expression::JsonArray(f) => &f.expressions,
3147            _ => &[],
3148        }
3149    }
3150
3151    /// Returns the name of this expression as a string slice.
3152    pub fn get_name(&self) -> &str {
3153        match self {
3154            Expression::JSONValue(_) => "JSON_VALUE",
3155            Expression::JSONTable(_) => "JSON_TABLE",
3156            Expression::JsonQuery(_) => "JSON_QUERY",
3157            Expression::Identifier(id) => &id.name,
3158            Expression::Column(col) => &col.name.name,
3159            Expression::Table(t) => &t.name.name,
3160            Expression::Literal(lit) => lit.value_str(),
3161            Expression::Star(_) => "*",
3162            Expression::Function(f) => &f.name,
3163            Expression::AggregateFunction(f) => &f.name,
3164            Expression::Hierarchy(h) => &h.name,
3165            Expression::Alias(a) => a.this.get_name(),
3166            Expression::Boolean(b) => {
3167                if b.value {
3168                    "TRUE"
3169                } else {
3170                    "FALSE"
3171                }
3172            }
3173            Expression::Null(_) => "NULL",
3174            _ => "",
3175        }
3176    }
3177
3178    /// Returns the alias name if this expression has one.
3179    pub fn get_alias(&self) -> &str {
3180        match self {
3181            Expression::Alias(a) => &a.alias.name,
3182            Expression::Table(t) => t.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3183            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3184            _ => "",
3185        }
3186    }
3187
3188    /// Returns the output name of this expression (what it shows up as in a SELECT).
3189    pub fn get_output_name(&self) -> &str {
3190        match self {
3191            Expression::Alias(a) => &a.alias.name,
3192            Expression::Column(c) => &c.name.name,
3193            Expression::Identifier(id) => &id.name,
3194            Expression::Literal(lit) => lit.value_str(),
3195            Expression::Subquery(s) => s.alias.as_ref().map(|a| a.name.as_str()).unwrap_or(""),
3196            Expression::Star(_) => "*",
3197            _ => "",
3198        }
3199    }
3200
3201    /// Returns comments attached to this expression.
3202    pub fn get_comments(&self) -> Vec<&str> {
3203        match self {
3204            Expression::Identifier(id) => id.trailing_comments.iter().map(|s| s.as_str()).collect(),
3205            Expression::Column(c) => c.trailing_comments.iter().map(|s| s.as_str()).collect(),
3206            Expression::Star(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3207            Expression::Paren(p) => p.trailing_comments.iter().map(|s| s.as_str()).collect(),
3208            Expression::Annotated(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3209            Expression::Alias(a) => a.trailing_comments.iter().map(|s| s.as_str()).collect(),
3210            Expression::Cast(c) | Expression::TryCast(c) | Expression::SafeCast(c) => {
3211                c.trailing_comments.iter().map(|s| s.as_str()).collect()
3212            }
3213            Expression::And(op)
3214            | Expression::Or(op)
3215            | Expression::Add(op)
3216            | Expression::Sub(op)
3217            | Expression::Mul(op)
3218            | Expression::Div(op)
3219            | Expression::Mod(op)
3220            | Expression::Eq(op)
3221            | Expression::Neq(op)
3222            | Expression::Lt(op)
3223            | Expression::Lte(op)
3224            | Expression::Gt(op)
3225            | Expression::Gte(op)
3226            | Expression::Concat(op)
3227            | Expression::BitwiseAnd(op)
3228            | Expression::BitwiseOr(op)
3229            | Expression::BitwiseXor(op) => {
3230                op.trailing_comments.iter().map(|s| s.as_str()).collect()
3231            }
3232            Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(),
3233            Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(),
3234            _ => Vec::new(),
3235        }
3236    }
3237}
3238
3239impl fmt::Display for Expression {
3240    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3241        // Basic display - full SQL generation is in generator module
3242        match self {
3243            Expression::Literal(lit) => write!(f, "{}", lit),
3244            Expression::Identifier(id) => write!(f, "{}", id),
3245            Expression::Column(col) => write!(f, "{}", col),
3246            Expression::Star(_) => write!(f, "*"),
3247            Expression::Null(_) => write!(f, "NULL"),
3248            Expression::Boolean(b) => write!(f, "{}", if b.value { "TRUE" } else { "FALSE" }),
3249            Expression::Select(_) => write!(f, "SELECT ..."),
3250            _ => write!(f, "{:?}", self),
3251        }
3252    }
3253}
3254
3255/// Represent a SQL literal value.
3256///
3257/// Numeric values are stored as their original text representation (not parsed
3258/// to `i64`/`f64`) so that precision, trailing zeros, and hex notation are
3259/// preserved across round-trips.
3260///
3261/// Dialect-specific literal forms (triple-quoted strings, dollar-quoted
3262/// strings, raw strings, etc.) each have a dedicated variant so that the
3263/// generator can emit them with the correct syntax.
3264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3265#[cfg_attr(feature = "bindings", derive(TS))]
3266#[serde(tag = "literal_type", content = "value", rename_all = "snake_case")]
3267pub enum Literal {
3268    /// Single-quoted string literal: `'hello'`
3269    String(String),
3270    /// Numeric literal, stored as the original text: `42`, `3.14`, `1e10`
3271    Number(String),
3272    /// Hex string literal: `X'FF'`
3273    HexString(String),
3274    /// Hex number: 0xA, 0xFF (BigQuery, SQLite style) - represents an integer in hex notation
3275    HexNumber(String),
3276    BitString(String),
3277    /// Byte string: b"..." (BigQuery style)
3278    ByteString(String),
3279    /// National string: N'abc'
3280    NationalString(String),
3281    /// DATE literal: DATE '2024-01-15'
3282    Date(String),
3283    /// TIME literal: TIME '10:30:00'
3284    Time(String),
3285    /// TIMESTAMP literal: TIMESTAMP '2024-01-15 10:30:00'
3286    Timestamp(String),
3287    /// DATETIME literal: DATETIME '2024-01-15 10:30:00' (BigQuery)
3288    Datetime(String),
3289    /// Triple-quoted string: """...""" or '''...'''
3290    /// Contains (content, quote_char) where quote_char is '"' or '\''
3291    TripleQuotedString(String, char),
3292    /// Escape string: E'...' (PostgreSQL)
3293    EscapeString(String),
3294    /// Dollar-quoted string: $$...$$  (PostgreSQL)
3295    DollarString(String),
3296    /// Raw string: r"..." or r'...' (BigQuery, Spark, Databricks)
3297    /// In raw strings, backslashes are literal and not escape characters.
3298    /// When converting to a regular string, backslashes must be doubled.
3299    RawString(String),
3300}
3301
3302impl Literal {
3303    /// Returns the inner value as a string slice, regardless of literal type.
3304    pub fn value_str(&self) -> &str {
3305        match self {
3306            Literal::String(s)
3307            | Literal::Number(s)
3308            | Literal::HexString(s)
3309            | Literal::HexNumber(s)
3310            | Literal::BitString(s)
3311            | Literal::ByteString(s)
3312            | Literal::NationalString(s)
3313            | Literal::Date(s)
3314            | Literal::Time(s)
3315            | Literal::Timestamp(s)
3316            | Literal::Datetime(s)
3317            | Literal::EscapeString(s)
3318            | Literal::DollarString(s)
3319            | Literal::RawString(s) => s.as_str(),
3320            Literal::TripleQuotedString(s, _) => s.as_str(),
3321        }
3322    }
3323
3324    /// Returns `true` if this is a string-type literal.
3325    pub fn is_string(&self) -> bool {
3326        matches!(
3327            self,
3328            Literal::String(_)
3329                | Literal::NationalString(_)
3330                | Literal::EscapeString(_)
3331                | Literal::DollarString(_)
3332                | Literal::RawString(_)
3333                | Literal::TripleQuotedString(_, _)
3334        )
3335    }
3336
3337    /// Returns `true` if this is a numeric literal.
3338    pub fn is_number(&self) -> bool {
3339        matches!(self, Literal::Number(_) | Literal::HexNumber(_))
3340    }
3341}
3342
3343impl fmt::Display for Literal {
3344    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3345        match self {
3346            Literal::String(s) => write!(f, "'{}'", s),
3347            Literal::Number(n) => write!(f, "{}", n),
3348            Literal::HexString(h) => write!(f, "X'{}'", h),
3349            Literal::HexNumber(h) => write!(f, "0x{}", h),
3350            Literal::BitString(b) => write!(f, "B'{}'", b),
3351            Literal::ByteString(b) => write!(f, "b'{}'", b),
3352            Literal::NationalString(s) => write!(f, "N'{}'", s),
3353            Literal::Date(d) => write!(f, "DATE '{}'", d),
3354            Literal::Time(t) => write!(f, "TIME '{}'", t),
3355            Literal::Timestamp(ts) => write!(f, "TIMESTAMP '{}'", ts),
3356            Literal::Datetime(dt) => write!(f, "DATETIME '{}'", dt),
3357            Literal::TripleQuotedString(s, q) => {
3358                write!(f, "{0}{0}{0}{1}{0}{0}{0}", q, s)
3359            }
3360            Literal::EscapeString(s) => write!(f, "E'{}'", s),
3361            Literal::DollarString(s) => write!(f, "$${}$$", s),
3362            Literal::RawString(s) => write!(f, "r'{}'", s),
3363        }
3364    }
3365}
3366
3367/// Boolean literal
3368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3369#[cfg_attr(feature = "bindings", derive(TS))]
3370pub struct BooleanLiteral {
3371    pub value: bool,
3372}
3373
3374/// NULL literal
3375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3376#[cfg_attr(feature = "bindings", derive(TS))]
3377pub struct Null;
3378
3379/// Represent a SQL identifier (table name, column name, alias, keyword-as-name, etc.).
3380///
3381/// The `quoted` flag indicates whether the identifier was originally delimited
3382/// (double-quoted, backtick-quoted, or bracket-quoted depending on the
3383/// dialect). The generator uses this flag to decide whether to emit quoting
3384/// characters.
3385#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, Serialize, Deserialize)]
3386#[cfg_attr(feature = "bindings", derive(TS))]
3387pub struct Identifier {
3388    /// The raw text of the identifier, without any quoting characters.
3389    pub name: String,
3390    /// Whether the identifier was quoted in the source SQL.
3391    pub quoted: bool,
3392    #[serde(default)]
3393    pub trailing_comments: Vec<String>,
3394    /// Original source range, including quoting delimiters. Absent for synthetic
3395    /// or programmatically constructed identifiers. Not part of structural equality.
3396    #[serde(default, skip_serializing_if = "Option::is_none")]
3397    pub span: Option<Span>,
3398}
3399
3400impl PartialEq for Identifier {
3401    fn eq(&self, other: &Self) -> bool {
3402        self.name == other.name
3403            && self.quoted == other.quoted
3404            && self.trailing_comments == other.trailing_comments
3405    }
3406}
3407
3408impl Identifier {
3409    pub fn new(name: impl Into<String>) -> Self {
3410        Self {
3411            name: name.into(),
3412            quoted: false,
3413            trailing_comments: Vec::new(),
3414            span: None,
3415        }
3416    }
3417
3418    pub fn quoted(name: impl Into<String>) -> Self {
3419        Self {
3420            name: name.into(),
3421            quoted: true,
3422            trailing_comments: Vec::new(),
3423            span: None,
3424        }
3425    }
3426
3427    pub fn empty() -> Self {
3428        Self {
3429            name: String::new(),
3430            quoted: false,
3431            trailing_comments: Vec::new(),
3432            span: None,
3433        }
3434    }
3435
3436    pub fn is_empty(&self) -> bool {
3437        self.name.is_empty()
3438    }
3439
3440    /// Preserve quoting in the legacy string representation of named type fields.
3441    /// Always use SQL-standard delimiters internally, independent of the source dialect.
3442    pub(crate) fn to_type_field_name(&self) -> String {
3443        if self.quoted {
3444            format!("\"{}\"", self.name.replace('"', "\"\""))
3445        } else {
3446            self.name.clone()
3447        }
3448    }
3449
3450    /// Set the source span on this identifier
3451    pub fn with_span(mut self, span: Span) -> Self {
3452        self.span = Some(span);
3453        self
3454    }
3455}
3456
3457impl fmt::Display for Identifier {
3458    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3459        if self.quoted {
3460            write!(f, "\"{}\"", self.name)
3461        } else {
3462            write!(f, "{}", self.name)
3463        }
3464    }
3465}
3466
3467/// Represent a column reference, optionally qualified by a table name.
3468///
3469/// Renders as `name` when unqualified, or `table.name` when qualified.
3470/// Use [`Expression::column()`] or [`Expression::qualified_column()`] for
3471/// convenient construction.
3472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, Serialize, Deserialize)]
3473#[cfg_attr(feature = "bindings", derive(TS))]
3474pub struct Column {
3475    /// The column name.
3476    pub name: Identifier,
3477    /// Optional table qualifier (e.g. `t` in `t.col`).
3478    pub table: Option<Identifier>,
3479    /// Oracle-style join marker (+) for outer joins
3480    #[serde(default)]
3481    pub join_mark: bool,
3482    /// Trailing comments that appeared after this column reference
3483    #[serde(default)]
3484    pub trailing_comments: Vec<String>,
3485    /// Original column-reference range, including its qualifier when present.
3486    /// Absent for synthetic references. Not part of structural equality.
3487    #[serde(default, skip_serializing_if = "Option::is_none")]
3488    pub span: Option<Span>,
3489    /// Inferred data type from type annotation
3490    #[serde(default, skip_serializing_if = "Option::is_none")]
3491    #[ast(skip)]
3492    pub inferred_type: Option<DataType>,
3493}
3494
3495impl PartialEq for Column {
3496    fn eq(&self, other: &Self) -> bool {
3497        self.name == other.name
3498            && self.table == other.table
3499            && self.join_mark == other.join_mark
3500            && self.trailing_comments == other.trailing_comments
3501            && self.inferred_type == other.inferred_type
3502    }
3503}
3504
3505impl fmt::Display for Column {
3506    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3507        if let Some(table) = &self.table {
3508            write!(f, "{}.{}", table, self.name)
3509        } else {
3510            write!(f, "{}", self.name)
3511        }
3512    }
3513}
3514
3515/// Represent a table reference with optional schema and catalog qualifiers.
3516///
3517/// Renders as `name`, `schema.name`, or `catalog.schema.name` depending on
3518/// which qualifiers are present. Supports aliases, column alias lists,
3519/// time-travel clauses (Snowflake, BigQuery), table hints (TSQL), and
3520/// several other dialect-specific extensions.
3521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3522#[cfg_attr(feature = "bindings", derive(TS))]
3523pub struct TableRef {
3524    /// The unqualified table name.
3525    pub name: Identifier,
3526    /// Optional schema qualifier (e.g. `public` in `public.users`).
3527    pub schema: Option<Identifier>,
3528    /// Optional catalog qualifier (e.g. `mydb` in `mydb.public.users`).
3529    pub catalog: Option<Identifier>,
3530    /// Optional table alias (e.g. `t` in `FROM users AS t`).
3531    pub alias: Option<Identifier>,
3532    /// Whether AS keyword was explicitly used for the alias
3533    #[serde(default)]
3534    pub alias_explicit_as: bool,
3535    /// Column aliases for table alias: AS t(c1, c2)
3536    #[serde(default)]
3537    pub column_aliases: Vec<Identifier>,
3538    /// Leading comments that appeared before this table reference in a FROM clause
3539    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3540    pub leading_comments: Vec<String>,
3541    /// Trailing comments that appeared after this table reference
3542    #[serde(default)]
3543    pub trailing_comments: Vec<String>,
3544    /// Snowflake time travel: BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
3545    #[serde(default)]
3546    pub when: Option<Box<HistoricalData>>,
3547    /// PostgreSQL ONLY modifier: prevents scanning child tables in inheritance hierarchy
3548    #[serde(default)]
3549    pub only: bool,
3550    /// ClickHouse FINAL modifier: forces final aggregation for MergeTree tables
3551    #[serde(default)]
3552    pub final_: bool,
3553    /// TABLESAMPLE clause attached to this table reference (DuckDB, BigQuery)
3554    #[serde(default, skip_serializing_if = "Option::is_none")]
3555    pub table_sample: Option<Box<Sample>>,
3556    /// TSQL table hints: WITH (TABLOCK, INDEX(myindex), ...)
3557    #[serde(default)]
3558    pub hints: Vec<Expression>,
3559    /// TSQL: FOR SYSTEM_TIME temporal clause
3560    /// Contains the full clause text, e.g., "FOR SYSTEM_TIME BETWEEN c AND d"
3561    #[serde(default, skip_serializing_if = "Option::is_none")]
3562    pub system_time: Option<String>,
3563    /// MySQL: PARTITION(p0, p1, ...) hint for reading from specific partitions
3564    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3565    pub partitions: Vec<Identifier>,
3566    /// Snowflake IDENTIFIER() function: dynamic table name from string/variable
3567    /// When set, this is used instead of the name field
3568    #[serde(default, skip_serializing_if = "Option::is_none")]
3569    pub identifier_func: Option<Box<Expression>>,
3570    /// Snowflake CHANGES clause: CHANGES (INFORMATION => ...) AT (...) END (...)
3571    #[serde(default, skip_serializing_if = "Option::is_none")]
3572    pub changes: Option<Box<Changes>>,
3573    /// Time travel version clause: FOR VERSION AS OF / FOR TIMESTAMP AS OF (Presto/Trino, BigQuery, Databricks)
3574    #[serde(default, skip_serializing_if = "Option::is_none")]
3575    pub version: Option<Box<Version>>,
3576    /// Source position span
3577    #[serde(default, skip_serializing_if = "Option::is_none")]
3578    pub span: Option<Span>,
3579}
3580
3581impl TableRef {
3582    pub fn new(name: impl Into<String>) -> Self {
3583        Self {
3584            name: Identifier::new(name),
3585            schema: None,
3586            catalog: None,
3587            alias: None,
3588            alias_explicit_as: false,
3589            column_aliases: Vec::new(),
3590            leading_comments: Vec::new(),
3591            trailing_comments: Vec::new(),
3592            when: None,
3593            only: false,
3594            final_: false,
3595            table_sample: None,
3596            hints: Vec::new(),
3597            system_time: None,
3598            partitions: Vec::new(),
3599            identifier_func: None,
3600            changes: None,
3601            version: None,
3602            span: None,
3603        }
3604    }
3605
3606    /// Create with a schema qualifier.
3607    pub fn new_with_schema(name: impl Into<String>, schema: impl Into<String>) -> Self {
3608        let mut t = Self::new(name);
3609        t.schema = Some(Identifier::new(schema));
3610        t
3611    }
3612
3613    /// Create with catalog and schema qualifiers.
3614    pub fn new_with_catalog(
3615        name: impl Into<String>,
3616        schema: impl Into<String>,
3617        catalog: impl Into<String>,
3618    ) -> Self {
3619        let mut t = Self::new(name);
3620        t.schema = Some(Identifier::new(schema));
3621        t.catalog = Some(Identifier::new(catalog));
3622        t
3623    }
3624
3625    /// Create from an Identifier, preserving the quoted flag
3626    pub fn from_identifier(name: Identifier) -> Self {
3627        Self {
3628            name,
3629            schema: None,
3630            catalog: None,
3631            alias: None,
3632            alias_explicit_as: false,
3633            column_aliases: Vec::new(),
3634            leading_comments: Vec::new(),
3635            trailing_comments: Vec::new(),
3636            when: None,
3637            only: false,
3638            final_: false,
3639            table_sample: None,
3640            hints: Vec::new(),
3641            system_time: None,
3642            partitions: Vec::new(),
3643            identifier_func: None,
3644            changes: None,
3645            version: None,
3646            span: None,
3647        }
3648    }
3649
3650    pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
3651        self.alias = Some(Identifier::new(alias));
3652        self
3653    }
3654
3655    pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
3656        self.schema = Some(Identifier::new(schema));
3657        self
3658    }
3659}
3660
3661/// Represent a wildcard star expression (`*`, `table.*`).
3662///
3663/// Supports the EXCEPT/EXCLUDE, REPLACE, and RENAME modifiers found in
3664/// DuckDB, BigQuery, and Snowflake (e.g. `SELECT * EXCEPT (id) FROM t`).
3665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3666#[cfg_attr(feature = "bindings", derive(TS))]
3667pub struct Star {
3668    /// Optional table qualifier (e.g. `t` in `t.*`).
3669    pub table: Option<Identifier>,
3670    /// EXCLUDE / EXCEPT columns (DuckDB, BigQuery, Snowflake)
3671    pub except: Option<Vec<Identifier>>,
3672    /// REPLACE expressions (BigQuery, Snowflake)
3673    pub replace: Option<Vec<Alias>>,
3674    /// RENAME columns (Snowflake)
3675    pub rename: Option<Vec<(Identifier, Identifier)>>,
3676    /// Trailing comments that appeared after the star
3677    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3678    pub trailing_comments: Vec<String>,
3679    /// Source position span
3680    #[serde(default, skip_serializing_if = "Option::is_none")]
3681    pub span: Option<Span>,
3682}
3683
3684/// Represent a complete SELECT statement.
3685///
3686/// This is the most feature-rich AST node, covering the full surface area of
3687/// SELECT syntax across more than 30 SQL dialects. Fields that are `Option` or empty
3688/// `Vec` are omitted from the generated SQL when absent.
3689///
3690/// # Key Fields
3691///
3692/// - `expressions` -- the select-list (columns, `*`, computed expressions).
3693/// - `from` -- the FROM clause. `None` for `SELECT 1` style queries.
3694/// - `joins` -- zero or more JOIN clauses, each with a [`JoinKind`].
3695/// - `where_clause` -- the WHERE predicate.
3696/// - `group_by` -- GROUP BY, including ROLLUP/CUBE/GROUPING SETS.
3697/// - `having` -- HAVING predicate.
3698/// - `order_by` -- ORDER BY with ASC/DESC and NULLS FIRST/LAST.
3699/// - `limit` / `offset` / `fetch` -- result set limiting.
3700/// - `with` -- Common Table Expressions (CTEs).
3701/// - `distinct` / `distinct_on` -- DISTINCT and PostgreSQL DISTINCT ON.
3702/// - `windows` -- named window definitions (WINDOW w AS ...).
3703///
3704/// Dialect-specific extensions are supported via fields like `prewhere`
3705/// (ClickHouse), `qualify` (Snowflake/BigQuery/DuckDB), `connect` (Oracle
3706/// CONNECT BY), `for_xml` (TSQL), and `settings` (ClickHouse).
3707#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3708#[cfg_attr(feature = "bindings", derive(TS))]
3709pub struct Select {
3710    #[serde(default, skip_serializing_if = "Option::is_none")]
3711    pub vertica: Option<Box<VerticaSelectExtensions>>,
3712    /// The select-list: columns, expressions, aliases, and wildcards.
3713    pub expressions: Vec<Expression>,
3714    /// The FROM clause, containing one or more table sources.
3715    pub from: Option<From>,
3716    /// JOIN clauses applied after the FROM source.
3717    pub joins: Vec<Join>,
3718    pub lateral_views: Vec<LateralView>,
3719    /// ClickHouse PREWHERE clause
3720    #[serde(default, skip_serializing_if = "Option::is_none")]
3721    pub prewhere: Option<Expression>,
3722    pub where_clause: Option<Where>,
3723    pub group_by: Option<GroupBy>,
3724    pub having: Option<Having>,
3725    pub qualify: Option<Qualify>,
3726    pub order_by: Option<OrderBy>,
3727    pub distribute_by: Option<DistributeBy>,
3728    pub cluster_by: Option<ClusterBy>,
3729    pub sort_by: Option<SortBy>,
3730    pub limit: Option<Limit>,
3731    pub offset: Option<Offset>,
3732    /// ClickHouse LIMIT BY clause expressions
3733    #[serde(default, skip_serializing_if = "Option::is_none")]
3734    pub limit_by: Option<Vec<Expression>>,
3735    pub fetch: Option<Fetch>,
3736    pub distinct: bool,
3737    pub distinct_on: Option<Vec<Expression>>,
3738    pub top: Option<Top>,
3739    pub with: Option<With>,
3740    pub sample: Option<Sample>,
3741    /// ClickHouse SETTINGS clause (e.g., SETTINGS max_threads = 4)
3742    #[serde(default, skip_serializing_if = "Option::is_none")]
3743    pub settings: Option<Vec<Expression>>,
3744    /// ClickHouse FORMAT clause (e.g., FORMAT PrettyCompact)
3745    #[serde(default, skip_serializing_if = "Option::is_none")]
3746    pub format: Option<Expression>,
3747    pub windows: Option<Vec<NamedWindow>>,
3748    pub hint: Option<Hint>,
3749    /// Oracle CONNECT BY clause for hierarchical queries
3750    pub connect: Option<Connect>,
3751    /// SELECT ... INTO table_name for creating tables
3752    pub into: Option<SelectInto>,
3753    /// FOR UPDATE/SHARE locking clauses
3754    #[serde(default)]
3755    pub locks: Vec<Lock>,
3756    /// T-SQL FOR XML clause options (PATH, RAW, AUTO, EXPLICIT, BINARY BASE64, ELEMENTS XSINIL, etc.)
3757    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3758    pub for_xml: Vec<Expression>,
3759    /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)
3760    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3761    pub for_json: Vec<Expression>,
3762    /// Structured result serialization, including a bare FOR JSON/XML clause.
3763    #[serde(default, skip_serializing_if = "Option::is_none")]
3764    pub result_serialization: Option<ResultSerialization>,
3765    #[serde(default, skip_serializing_if = "Option::is_none")]
3766    pub query_collation: Option<Identifier>,
3767    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3768    pub query_hints: Vec<Expression>,
3769    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3770    pub total_rowcount: bool,
3771    #[serde(default, skip_serializing_if = "Option::is_none")]
3772    #[ast(skip)]
3773    pub source_dialect: Option<crate::dialects::DialectType>,
3774    /// Leading comments before the statement
3775    #[serde(default)]
3776    pub leading_comments: Vec<String>,
3777    /// Comments that appear after SELECT keyword (before expressions)
3778    /// Example: `SELECT <comment> col` -> `post_select_comments: ["<comment>"]`
3779    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3780    pub post_select_comments: Vec<String>,
3781    /// BigQuery SELECT AS STRUCT / SELECT AS VALUE kind
3782    #[serde(default, skip_serializing_if = "Option::is_none")]
3783    pub kind: Option<String>,
3784    /// MySQL operation modifiers (HIGH_PRIORITY, STRAIGHT_JOIN, SQL_CALC_FOUND_ROWS, etc.)
3785    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3786    pub operation_modifiers: Vec<String>,
3787    /// Whether QUALIFY appears after WINDOW (DuckDB) vs before (Snowflake/BigQuery default)
3788    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
3789    pub qualify_after_window: bool,
3790    /// TSQL OPTION clause (e.g., OPTION(LABEL = 'foo'))
3791    #[serde(default, skip_serializing_if = "Option::is_none")]
3792    pub option: Option<String>,
3793    /// Redshift-style EXCLUDE clause at the end of the projection list
3794    /// e.g., SELECT *, 4 AS col4 EXCLUDE (col2, col3) FROM ...
3795    #[serde(default, skip_serializing_if = "Option::is_none")]
3796    pub exclude: Option<Vec<Expression>>,
3797}
3798
3799impl Select {
3800    pub fn new() -> Self {
3801        Self {
3802            vertica: None,
3803            expressions: Vec::new(),
3804            from: None,
3805            joins: Vec::new(),
3806            lateral_views: Vec::new(),
3807            prewhere: None,
3808            where_clause: None,
3809            group_by: None,
3810            having: None,
3811            qualify: None,
3812            order_by: None,
3813            distribute_by: None,
3814            cluster_by: None,
3815            sort_by: None,
3816            limit: None,
3817            offset: None,
3818            limit_by: None,
3819            fetch: None,
3820            distinct: false,
3821            distinct_on: None,
3822            top: None,
3823            with: None,
3824            sample: None,
3825            settings: None,
3826            format: None,
3827            windows: None,
3828            hint: None,
3829            connect: None,
3830            into: None,
3831            locks: Vec::new(),
3832            for_xml: Vec::new(),
3833            for_json: Vec::new(),
3834            result_serialization: None,
3835            query_collation: None,
3836            query_hints: Vec::new(),
3837            total_rowcount: false,
3838            source_dialect: None,
3839            leading_comments: Vec::new(),
3840            post_select_comments: Vec::new(),
3841            kind: None,
3842            operation_modifiers: Vec::new(),
3843            qualify_after_window: false,
3844            option: None,
3845            exclude: None,
3846        }
3847    }
3848
3849    /// Add a column to select
3850    pub fn column(mut self, expr: Expression) -> Self {
3851        self.expressions.push(expr);
3852        self
3853    }
3854
3855    /// Set the FROM clause
3856    pub fn from(mut self, table: Expression) -> Self {
3857        self.from = Some(From {
3858            expressions: vec![table],
3859        });
3860        self
3861    }
3862
3863    /// Add a WHERE clause
3864    pub fn where_(mut self, condition: Expression) -> Self {
3865        self.where_clause = Some(Where { this: condition });
3866        self
3867    }
3868
3869    /// Set DISTINCT
3870    pub fn distinct(mut self) -> Self {
3871        self.distinct = true;
3872        self
3873    }
3874
3875    /// Add a JOIN
3876    pub fn join(mut self, join: Join) -> Self {
3877        self.joins.push(join);
3878        self
3879    }
3880
3881    /// Set ORDER BY
3882    pub fn order_by(mut self, expressions: Vec<Ordered>) -> Self {
3883        self.order_by = Some(OrderBy {
3884            expressions,
3885            siblings: false,
3886            comments: Vec::new(),
3887        });
3888        self
3889    }
3890
3891    /// Set LIMIT
3892    pub fn limit(mut self, n: Expression) -> Self {
3893        self.limit = Some(Limit {
3894            this: n,
3895            percent: false,
3896            comments: Vec::new(),
3897        });
3898        self
3899    }
3900
3901    /// Set OFFSET
3902    pub fn offset(mut self, n: Expression) -> Self {
3903        self.offset = Some(Offset {
3904            this: n,
3905            rows: None,
3906        });
3907        self
3908    }
3909}
3910
3911impl Default for Select {
3912    fn default() -> Self {
3913        Self::new()
3914    }
3915}
3916
3917/// Represent a UNION set operation between two query expressions.
3918///
3919/// When `all` is true, duplicate rows are preserved (UNION ALL).
3920/// ORDER BY, LIMIT, and OFFSET can be applied to the combined result.
3921/// Supports DuckDB/Snowflake BY NAME and BigQuery BY NAME/CORRESPONDING modifiers.
3922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3923#[cfg_attr(feature = "bindings", derive(TS))]
3924pub struct Union {
3925    /// The left-hand query operand.
3926    pub left: Expression,
3927    /// The right-hand query operand.
3928    pub right: Expression,
3929    /// Whether UNION ALL (true) or UNION (false, which deduplicates).
3930    pub all: bool,
3931    /// Whether DISTINCT was explicitly specified
3932    #[serde(default)]
3933    pub distinct: bool,
3934    /// Optional WITH clause
3935    pub with: Option<With>,
3936    /// ORDER BY applied to entire UNION result
3937    pub order_by: Option<OrderBy>,
3938    /// Row limit applied to the entire UNION result: a legacy count expression,
3939    /// or a complete `Expression::Limit` / `Expression::Fetch` with clause options.
3940    pub limit: Option<Box<Expression>>,
3941    /// OFFSET applied to entire UNION result
3942    pub offset: Option<Box<Expression>>,
3943    /// DISTRIBUTE BY clause (Hive/Spark)
3944    #[serde(default, skip_serializing_if = "Option::is_none")]
3945    pub distribute_by: Option<DistributeBy>,
3946    /// SORT BY clause (Hive/Spark)
3947    #[serde(default, skip_serializing_if = "Option::is_none")]
3948    pub sort_by: Option<SortBy>,
3949    /// CLUSTER BY clause (Hive/Spark)
3950    #[serde(default, skip_serializing_if = "Option::is_none")]
3951    pub cluster_by: Option<ClusterBy>,
3952    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3953    #[serde(default)]
3954    pub by_name: bool,
3955    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3956    #[serde(default, skip_serializing_if = "Option::is_none")]
3957    pub side: Option<String>,
3958    /// BigQuery: Set operation kind (INNER)
3959    #[serde(default, skip_serializing_if = "Option::is_none")]
3960    pub kind: Option<String>,
3961    /// BigQuery: CORRESPONDING modifier
3962    #[serde(default)]
3963    pub corresponding: bool,
3964    /// BigQuery: STRICT modifier (before CORRESPONDING)
3965    #[serde(default)]
3966    pub strict: bool,
3967    /// BigQuery: BY (columns) after CORRESPONDING
3968    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3969    pub on_columns: Vec<Expression>,
3970}
3971
3972/// Iteratively flatten the left-recursive chain to prevent stack overflow
3973/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3974impl Drop for Union {
3975    fn drop(&mut self) {
3976        loop {
3977            if let Expression::Union(ref mut inner) = self.left {
3978                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3979                let old_left = std::mem::replace(&mut self.left, next_left);
3980                drop(old_left);
3981            } else {
3982                break;
3983            }
3984        }
3985    }
3986}
3987
3988/// Represent an INTERSECT set operation between two query expressions.
3989///
3990/// Returns only rows that appear in both operands. When `all` is true,
3991/// duplicates are preserved according to their multiplicity.
3992#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3993#[cfg_attr(feature = "bindings", derive(TS))]
3994pub struct Intersect {
3995    /// The left-hand query operand.
3996    pub left: Expression,
3997    /// The right-hand query operand.
3998    pub right: Expression,
3999    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
4000    pub all: bool,
4001    /// Whether DISTINCT was explicitly specified
4002    #[serde(default)]
4003    pub distinct: bool,
4004    /// Optional WITH clause
4005    pub with: Option<With>,
4006    /// ORDER BY applied to entire INTERSECT result
4007    pub order_by: Option<OrderBy>,
4008    /// Row limit applied to the entire INTERSECT result: a legacy count expression,
4009    /// or a complete `Expression::Limit` / `Expression::Fetch` with clause options.
4010    pub limit: Option<Box<Expression>>,
4011    /// OFFSET applied to entire INTERSECT result
4012    pub offset: Option<Box<Expression>>,
4013    /// DISTRIBUTE BY clause (Hive/Spark)
4014    #[serde(default, skip_serializing_if = "Option::is_none")]
4015    pub distribute_by: Option<DistributeBy>,
4016    /// SORT BY clause (Hive/Spark)
4017    #[serde(default, skip_serializing_if = "Option::is_none")]
4018    pub sort_by: Option<SortBy>,
4019    /// CLUSTER BY clause (Hive/Spark)
4020    #[serde(default, skip_serializing_if = "Option::is_none")]
4021    pub cluster_by: Option<ClusterBy>,
4022    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4023    #[serde(default)]
4024    pub by_name: bool,
4025    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4026    #[serde(default, skip_serializing_if = "Option::is_none")]
4027    pub side: Option<String>,
4028    /// BigQuery: Set operation kind (INNER)
4029    #[serde(default, skip_serializing_if = "Option::is_none")]
4030    pub kind: Option<String>,
4031    /// BigQuery: CORRESPONDING modifier
4032    #[serde(default)]
4033    pub corresponding: bool,
4034    /// BigQuery: STRICT modifier (before CORRESPONDING)
4035    #[serde(default)]
4036    pub strict: bool,
4037    /// BigQuery: BY (columns) after CORRESPONDING
4038    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4039    pub on_columns: Vec<Expression>,
4040}
4041
4042impl Drop for Intersect {
4043    fn drop(&mut self) {
4044        loop {
4045            if let Expression::Intersect(ref mut inner) = self.left {
4046                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4047                let old_left = std::mem::replace(&mut self.left, next_left);
4048                drop(old_left);
4049            } else {
4050                break;
4051            }
4052        }
4053    }
4054}
4055
4056/// Represent an EXCEPT (MINUS) set operation between two query expressions.
4057///
4058/// Returns rows from the left operand that do not appear in the right operand.
4059/// When `all` is true, duplicates are subtracted according to their multiplicity.
4060#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4061#[cfg_attr(feature = "bindings", derive(TS))]
4062pub struct Except {
4063    /// The left-hand query operand.
4064    pub left: Expression,
4065    /// The right-hand query operand (rows to subtract).
4066    pub right: Expression,
4067    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
4068    pub all: bool,
4069    /// Whether DISTINCT was explicitly specified
4070    #[serde(default)]
4071    pub distinct: bool,
4072    /// Optional WITH clause
4073    pub with: Option<With>,
4074    /// ORDER BY applied to entire EXCEPT result
4075    pub order_by: Option<OrderBy>,
4076    /// Row limit applied to the entire EXCEPT result: a legacy count expression,
4077    /// or a complete `Expression::Limit` / `Expression::Fetch` with clause options.
4078    pub limit: Option<Box<Expression>>,
4079    /// OFFSET applied to entire EXCEPT result
4080    pub offset: Option<Box<Expression>>,
4081    /// DISTRIBUTE BY clause (Hive/Spark)
4082    #[serde(default, skip_serializing_if = "Option::is_none")]
4083    pub distribute_by: Option<DistributeBy>,
4084    /// SORT BY clause (Hive/Spark)
4085    #[serde(default, skip_serializing_if = "Option::is_none")]
4086    pub sort_by: Option<SortBy>,
4087    /// CLUSTER BY clause (Hive/Spark)
4088    #[serde(default, skip_serializing_if = "Option::is_none")]
4089    pub cluster_by: Option<ClusterBy>,
4090    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4091    #[serde(default)]
4092    pub by_name: bool,
4093    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4094    #[serde(default, skip_serializing_if = "Option::is_none")]
4095    pub side: Option<String>,
4096    /// BigQuery: Set operation kind (INNER)
4097    #[serde(default, skip_serializing_if = "Option::is_none")]
4098    pub kind: Option<String>,
4099    /// BigQuery: CORRESPONDING modifier
4100    #[serde(default)]
4101    pub corresponding: bool,
4102    /// BigQuery: STRICT modifier (before CORRESPONDING)
4103    #[serde(default)]
4104    pub strict: bool,
4105    /// BigQuery: BY (columns) after CORRESPONDING
4106    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4107    pub on_columns: Vec<Expression>,
4108}
4109
4110impl Drop for Except {
4111    fn drop(&mut self) {
4112        loop {
4113            if let Expression::Except(ref mut inner) = self.left {
4114                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4115                let old_left = std::mem::replace(&mut self.left, next_left);
4116                drop(old_left);
4117            } else {
4118                break;
4119            }
4120        }
4121    }
4122}
4123
4124/// INTO clause for SELECT INTO statements
4125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4126#[cfg_attr(feature = "bindings", derive(TS))]
4127pub struct SelectInto {
4128    /// Target table or variable (used when single target)
4129    pub this: Expression,
4130    /// Whether TEMPORARY keyword was used
4131    #[serde(default)]
4132    pub temporary: bool,
4133    /// Whether UNLOGGED keyword was used (PostgreSQL)
4134    #[serde(default)]
4135    pub unlogged: bool,
4136    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4137    #[serde(default)]
4138    pub bulk_collect: bool,
4139    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4140    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4141    pub expressions: Vec<Expression>,
4142}
4143
4144/// Represent a parenthesized subquery expression.
4145///
4146/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4147/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4148/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4149/// modifiers are rendered inside or outside the parentheses.
4150///
4151/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4152/// scalar subqueries in select-lists, and derived tables.
4153#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4154#[cfg_attr(feature = "bindings", derive(TS))]
4155pub struct Subquery {
4156    /// The inner query expression.
4157    pub this: Expression,
4158    /// Optional alias for the derived table.
4159    pub alias: Option<Identifier>,
4160    /// Optional column aliases: AS t(c1, c2)
4161    pub column_aliases: Vec<Identifier>,
4162    /// Whether AS keyword was explicitly used for the alias.
4163    #[serde(default)]
4164    pub alias_explicit_as: bool,
4165    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4166    #[serde(skip_serializing_if = "Option::is_none", default)]
4167    pub alias_keyword: Option<String>,
4168    /// ORDER BY clause (for parenthesized queries)
4169    pub order_by: Option<OrderBy>,
4170    /// LIMIT clause
4171    pub limit: Option<Limit>,
4172    /// OFFSET clause
4173    pub offset: Option<Offset>,
4174    /// DISTRIBUTE BY clause (Hive/Spark)
4175    #[serde(default, skip_serializing_if = "Option::is_none")]
4176    pub distribute_by: Option<DistributeBy>,
4177    /// SORT BY clause (Hive/Spark)
4178    #[serde(default, skip_serializing_if = "Option::is_none")]
4179    pub sort_by: Option<SortBy>,
4180    /// CLUSTER BY clause (Hive/Spark)
4181    #[serde(default, skip_serializing_if = "Option::is_none")]
4182    pub cluster_by: Option<ClusterBy>,
4183    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4184    #[serde(default)]
4185    pub lateral: bool,
4186    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4187    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4188    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4189    #[serde(default)]
4190    pub modifiers_inside: bool,
4191    /// Trailing comments after the closing paren
4192    #[serde(default)]
4193    pub trailing_comments: Vec<String>,
4194    /// Inferred data type from type annotation
4195    #[serde(default, skip_serializing_if = "Option::is_none")]
4196    #[ast(skip)]
4197    pub inferred_type: Option<DataType>,
4198}
4199
4200/// Pipe operator expression: query |> transform
4201///
4202/// Used in DataFusion and BigQuery pipe syntax:
4203///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4204#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4205#[cfg_attr(feature = "bindings", derive(TS))]
4206pub struct PipeOperator {
4207    /// The input query/expression (left side of |>)
4208    pub this: Expression,
4209    /// The piped operation (right side of |>)
4210    pub expression: Expression,
4211}
4212
4213/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4214#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4215#[cfg_attr(feature = "bindings", derive(TS))]
4216pub struct Values {
4217    /// The rows of values
4218    pub expressions: Vec<Tuple>,
4219    /// Optional alias for the table
4220    pub alias: Option<Identifier>,
4221    /// Optional column aliases: AS t(c1, c2)
4222    pub column_aliases: Vec<Identifier>,
4223}
4224
4225/// PIVOT operation - supports both standard and DuckDB simplified syntax
4226///
4227/// Standard syntax (in FROM clause):
4228///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4229///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4230///
4231/// DuckDB simplified syntax (statement-level):
4232///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4233///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4234#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4235#[cfg_attr(feature = "bindings", derive(TS))]
4236pub struct Pivot {
4237    /// Source table/expression
4238    pub this: Expression,
4239    /// For standard PIVOT: the aggregation function(s) (first is primary)
4240    /// For DuckDB simplified: unused (use `using` instead)
4241    #[serde(default)]
4242    pub expressions: Vec<Expression>,
4243    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4244    #[serde(default)]
4245    pub fields: Vec<Expression>,
4246    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4247    #[serde(default)]
4248    pub using: Vec<Expression>,
4249    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4250    #[serde(default)]
4251    pub group: Option<Box<Expression>>,
4252    /// Whether this is an UNPIVOT (vs PIVOT)
4253    #[serde(default)]
4254    pub unpivot: bool,
4255    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4256    #[serde(default)]
4257    pub into: Option<Box<Expression>>,
4258    /// Optional alias
4259    #[serde(default)]
4260    pub alias: Option<Identifier>,
4261    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4262    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4263    pub alias_columns: Vec<Identifier>,
4264    /// Include/exclude nulls (for UNPIVOT)
4265    #[serde(default)]
4266    pub include_nulls: Option<bool>,
4267    /// Default on null value (Snowflake)
4268    #[serde(default)]
4269    pub default_on_null: Option<Box<Expression>>,
4270    /// WITH clause (CTEs)
4271    #[serde(default, skip_serializing_if = "Option::is_none")]
4272    pub with: Option<With>,
4273}
4274
4275/// UNPIVOT operation
4276#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4277#[cfg_attr(feature = "bindings", derive(TS))]
4278pub struct Unpivot {
4279    pub this: Expression,
4280    pub value_column: Identifier,
4281    pub name_column: Identifier,
4282    pub columns: Vec<Expression>,
4283    pub alias: Option<Identifier>,
4284    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4285    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4286    pub alias_columns: Vec<Identifier>,
4287    /// Whether the value_column was parenthesized in the original SQL
4288    #[serde(default)]
4289    pub value_column_parenthesized: bool,
4290    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4291    #[serde(default)]
4292    pub include_nulls: Option<bool>,
4293    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4294    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4295    pub extra_value_columns: Vec<Identifier>,
4296}
4297
4298/// PIVOT alias for aliasing pivot expressions
4299/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4300#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4301#[cfg_attr(feature = "bindings", derive(TS))]
4302pub struct PivotAlias {
4303    pub this: Expression,
4304    pub alias: Expression,
4305}
4306
4307/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4309#[cfg_attr(feature = "bindings", derive(TS))]
4310pub struct PreWhere {
4311    pub this: Expression,
4312}
4313
4314/// STREAM definition (Snowflake) - for change data capture
4315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4316#[cfg_attr(feature = "bindings", derive(TS))]
4317pub struct Stream {
4318    pub this: Expression,
4319    #[serde(skip_serializing_if = "Option::is_none")]
4320    pub on: Option<Expression>,
4321    #[serde(skip_serializing_if = "Option::is_none")]
4322    pub show_initial_rows: Option<bool>,
4323}
4324
4325/// USING DATA clause for data import statements
4326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4327#[cfg_attr(feature = "bindings", derive(TS))]
4328pub struct UsingData {
4329    pub this: Expression,
4330}
4331
4332/// XML Namespace declaration
4333#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4334#[cfg_attr(feature = "bindings", derive(TS))]
4335pub struct XmlNamespace {
4336    pub this: Expression,
4337    #[serde(skip_serializing_if = "Option::is_none")]
4338    pub alias: Option<Identifier>,
4339}
4340
4341/// ROW FORMAT clause for Hive/Spark
4342#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4343#[cfg_attr(feature = "bindings", derive(TS))]
4344pub struct RowFormat {
4345    pub delimited: bool,
4346    pub fields_terminated_by: Option<String>,
4347    pub collection_items_terminated_by: Option<String>,
4348    pub map_keys_terminated_by: Option<String>,
4349    pub lines_terminated_by: Option<String>,
4350    pub null_defined_as: Option<String>,
4351}
4352
4353/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4354#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4355#[cfg_attr(feature = "bindings", derive(TS))]
4356pub struct DirectoryInsert {
4357    pub local: bool,
4358    pub path: String,
4359    pub row_format: Option<RowFormat>,
4360    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4361    #[serde(default)]
4362    pub stored_as: Option<String>,
4363}
4364
4365/// INSERT statement
4366#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4367#[cfg_attr(feature = "bindings", derive(TS))]
4368pub struct Insert {
4369    pub table: TableRef,
4370    pub columns: Vec<Identifier>,
4371    pub values: Vec<Vec<Expression>>,
4372    pub query: Option<Expression>,
4373    /// INSERT OVERWRITE for Hive/Spark
4374    pub overwrite: bool,
4375    /// PARTITION clause for Hive/Spark
4376    pub partition: Vec<(Identifier, Option<Expression>)>,
4377    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4378    #[serde(default)]
4379    pub directory: Option<DirectoryInsert>,
4380    /// RETURNING clause (PostgreSQL, SQLite)
4381    #[serde(default)]
4382    pub returning: Vec<Expression>,
4383    /// OUTPUT clause (TSQL)
4384    #[serde(default)]
4385    pub output: Option<OutputClause>,
4386    /// ON CONFLICT clause (PostgreSQL, SQLite)
4387    #[serde(default)]
4388    pub on_conflict: Option<Box<Expression>>,
4389    /// Leading comments before the statement
4390    #[serde(default)]
4391    pub leading_comments: Vec<String>,
4392    /// IF EXISTS clause (Hive)
4393    #[serde(default)]
4394    pub if_exists: bool,
4395    /// WITH clause (CTEs)
4396    #[serde(default)]
4397    pub with: Option<With>,
4398    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4399    #[serde(default)]
4400    pub ignore: bool,
4401    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4402    #[serde(default)]
4403    pub source_alias: Option<Identifier>,
4404    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4405    #[serde(default)]
4406    pub alias: Option<Identifier>,
4407    /// Whether the alias uses explicit AS keyword
4408    #[serde(default)]
4409    pub alias_explicit_as: bool,
4410    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4411    #[serde(default)]
4412    pub default_values: bool,
4413    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4414    #[serde(default)]
4415    pub by_name: bool,
4416    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4417    #[serde(default, skip_serializing_if = "Option::is_none")]
4418    pub conflict_action: Option<String>,
4419    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4420    #[serde(default)]
4421    pub is_replace: bool,
4422    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4423    #[serde(default, skip_serializing_if = "Option::is_none")]
4424    pub hint: Option<Hint>,
4425    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4426    #[serde(default)]
4427    pub replace_where: Option<Box<Expression>>,
4428    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4429    #[serde(default)]
4430    pub source: Option<Box<Expression>>,
4431    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4432    #[serde(default, skip_serializing_if = "Option::is_none")]
4433    pub function_target: Option<Box<Expression>>,
4434    /// ClickHouse: PARTITION BY expr
4435    #[serde(default, skip_serializing_if = "Option::is_none")]
4436    pub partition_by: Option<Box<Expression>>,
4437    /// ClickHouse: SETTINGS key = val, ...
4438    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4439    pub settings: Vec<Expression>,
4440}
4441
4442/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4444#[cfg_attr(feature = "bindings", derive(TS))]
4445pub struct OutputClause {
4446    /// Columns/expressions to output
4447    pub columns: Vec<Expression>,
4448    /// Optional INTO target table or table variable
4449    #[serde(default)]
4450    pub into_table: Option<Expression>,
4451}
4452
4453/// UPDATE statement
4454#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4455#[cfg_attr(feature = "bindings", derive(TS))]
4456pub struct Update {
4457    pub table: TableRef,
4458    #[serde(default)]
4459    pub hint: Option<Hint>,
4460    /// Additional tables for multi-table UPDATE (MySQL syntax)
4461    #[serde(default)]
4462    pub extra_tables: Vec<TableRef>,
4463    /// JOINs attached to the table list (MySQL multi-table syntax)
4464    #[serde(default)]
4465    pub table_joins: Vec<Join>,
4466    pub set: Vec<(Identifier, Expression)>,
4467    pub from_clause: Option<From>,
4468    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4469    #[serde(default)]
4470    pub from_joins: Vec<Join>,
4471    pub where_clause: Option<Where>,
4472    /// RETURNING clause (PostgreSQL, SQLite)
4473    #[serde(default)]
4474    pub returning: Vec<Expression>,
4475    /// OUTPUT clause (TSQL)
4476    #[serde(default)]
4477    pub output: Option<OutputClause>,
4478    /// WITH clause (CTEs)
4479    #[serde(default)]
4480    pub with: Option<With>,
4481    /// Leading comments before the statement
4482    #[serde(default)]
4483    pub leading_comments: Vec<String>,
4484    /// LIMIT clause (MySQL)
4485    #[serde(default)]
4486    pub limit: Option<Expression>,
4487    /// ORDER BY clause (MySQL)
4488    #[serde(default)]
4489    pub order_by: Option<OrderBy>,
4490    /// Whether FROM clause appears before SET (Snowflake syntax)
4491    #[serde(default)]
4492    pub from_before_set: bool,
4493}
4494
4495/// DELETE statement
4496#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4497#[cfg_attr(feature = "bindings", derive(TS))]
4498pub struct Delete {
4499    pub table: TableRef,
4500    #[serde(default)]
4501    pub hint: Option<Hint>,
4502    /// ClickHouse: ON CLUSTER clause for distributed DDL
4503    #[serde(default, skip_serializing_if = "Option::is_none")]
4504    pub on_cluster: Option<OnCluster>,
4505    /// Optional alias for the table
4506    pub alias: Option<Identifier>,
4507    /// Whether the alias was declared with explicit AS keyword
4508    #[serde(default)]
4509    pub alias_explicit_as: bool,
4510    /// PostgreSQL/DuckDB USING clause - additional tables to join
4511    pub using: Vec<TableRef>,
4512    pub where_clause: Option<Where>,
4513    /// OUTPUT clause (TSQL)
4514    #[serde(default)]
4515    pub output: Option<OutputClause>,
4516    /// Leading comments before the statement
4517    #[serde(default)]
4518    pub leading_comments: Vec<String>,
4519    /// WITH clause (CTEs)
4520    #[serde(default)]
4521    pub with: Option<With>,
4522    /// LIMIT clause (MySQL)
4523    #[serde(default)]
4524    pub limit: Option<Expression>,
4525    /// ORDER BY clause (MySQL)
4526    #[serde(default)]
4527    pub order_by: Option<OrderBy>,
4528    /// RETURNING clause (PostgreSQL)
4529    #[serde(default)]
4530    pub returning: Vec<Expression>,
4531    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4532    /// These are the target tables to delete from
4533    #[serde(default)]
4534    pub tables: Vec<TableRef>,
4535    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4536    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4537    #[serde(default)]
4538    pub tables_from_using: bool,
4539    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4540    #[serde(default)]
4541    pub joins: Vec<Join>,
4542    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4543    #[serde(default)]
4544    pub force_index: Option<String>,
4545    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4546    #[serde(default)]
4547    pub no_from: bool,
4548}
4549
4550/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4552#[cfg_attr(feature = "bindings", derive(TS))]
4553pub struct CopyStmt {
4554    /// Target table or query
4555    pub this: Expression,
4556    /// True for FROM (loading into table), false for TO (exporting)
4557    pub kind: bool,
4558    /// Source/destination file(s) or stage
4559    pub files: Vec<Expression>,
4560    /// Copy parameters
4561    #[serde(default)]
4562    pub params: Vec<CopyParameter>,
4563    /// Credentials for external access
4564    #[serde(default)]
4565    pub credentials: Option<Box<Credentials>>,
4566    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4567    #[serde(default)]
4568    pub is_into: bool,
4569    /// Whether parameters are wrapped in WITH (...) syntax
4570    #[serde(default)]
4571    pub with_wrapped: bool,
4572}
4573
4574/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4575#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4576#[cfg_attr(feature = "bindings", derive(TS))]
4577pub struct CopyParameter {
4578    pub name: String,
4579    pub value: Option<Expression>,
4580    pub values: Vec<Expression>,
4581    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4582    #[serde(default)]
4583    pub eq: bool,
4584}
4585
4586/// Credentials for external access (S3, Azure, etc.)
4587#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4588#[cfg_attr(feature = "bindings", derive(TS))]
4589pub struct Credentials {
4590    pub credentials: Vec<(String, String)>,
4591    pub encryption: Option<String>,
4592    pub storage: Option<String>,
4593}
4594
4595/// PUT statement (Snowflake)
4596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4597#[cfg_attr(feature = "bindings", derive(TS))]
4598pub struct PutStmt {
4599    /// Source file path
4600    pub source: String,
4601    /// Whether source was quoted in the original SQL
4602    #[serde(default)]
4603    pub source_quoted: bool,
4604    /// Target stage
4605    pub target: Expression,
4606    /// PUT parameters
4607    #[serde(default)]
4608    pub params: Vec<CopyParameter>,
4609}
4610
4611/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4613#[cfg_attr(feature = "bindings", derive(TS))]
4614pub struct StageReference {
4615    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4616    pub name: String,
4617    /// Optional path within the stage (e.g., "/path/to/file.csv")
4618    #[serde(default)]
4619    pub path: Option<String>,
4620    /// Optional FILE_FORMAT parameter
4621    #[serde(default)]
4622    pub file_format: Option<Expression>,
4623    /// Optional PATTERN parameter
4624    #[serde(default)]
4625    pub pattern: Option<String>,
4626    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4627    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4628    pub quoted: bool,
4629}
4630
4631/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4633#[cfg_attr(feature = "bindings", derive(TS))]
4634pub struct HistoricalData {
4635    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4636    pub this: Box<Expression>,
4637    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4638    pub kind: String,
4639    /// The expression value (e.g., the statement ID or timestamp)
4640    pub expression: Box<Expression>,
4641}
4642
4643/// Represent an aliased expression (`expr AS name`).
4644///
4645/// Used for column aliases in select-lists, table aliases on subqueries,
4646/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4647#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4648#[cfg_attr(feature = "bindings", derive(TS))]
4649pub struct Alias {
4650    /// The expression being aliased.
4651    pub this: Expression,
4652    /// The alias name (required for simple aliases, optional when only column aliases provided)
4653    pub alias: Identifier,
4654    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4655    #[serde(default)]
4656    pub column_aliases: Vec<Identifier>,
4657    /// Whether AS keyword was explicitly used for the alias.
4658    #[serde(default)]
4659    pub alias_explicit_as: bool,
4660    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4661    #[serde(skip_serializing_if = "Option::is_none", default)]
4662    pub alias_keyword: Option<String>,
4663    /// Comments that appeared between the expression and AS keyword
4664    #[serde(default)]
4665    pub pre_alias_comments: Vec<String>,
4666    /// Trailing comments that appeared after the alias
4667    #[serde(default)]
4668    pub trailing_comments: Vec<String>,
4669    /// Inferred data type from type annotation
4670    #[serde(default, skip_serializing_if = "Option::is_none")]
4671    #[ast(skip)]
4672    pub inferred_type: Option<DataType>,
4673}
4674
4675impl Alias {
4676    /// Create a simple alias
4677    pub fn new(this: Expression, alias: Identifier) -> Self {
4678        Self {
4679            this,
4680            alias,
4681            column_aliases: Vec::new(),
4682            alias_explicit_as: false,
4683            alias_keyword: None,
4684            pre_alias_comments: Vec::new(),
4685            trailing_comments: Vec::new(),
4686            inferred_type: None,
4687        }
4688    }
4689
4690    /// Create an alias with column aliases only (no table alias name)
4691    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4692        Self {
4693            this,
4694            alias: Identifier::empty(),
4695            column_aliases,
4696            alias_explicit_as: false,
4697            alias_keyword: None,
4698            pre_alias_comments: Vec::new(),
4699            trailing_comments: Vec::new(),
4700            inferred_type: None,
4701        }
4702    }
4703}
4704
4705/// Represent a type cast expression.
4706///
4707/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4708/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4709/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4710/// CONVERSION ERROR (Oracle) clauses.
4711#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4712#[cfg_attr(feature = "bindings", derive(TS))]
4713pub struct Cast {
4714    /// The expression being cast.
4715    pub this: Expression,
4716    /// The target data type.
4717    pub to: DataType,
4718    #[serde(default)]
4719    pub trailing_comments: Vec<String>,
4720    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4721    #[serde(default)]
4722    pub double_colon_syntax: bool,
4723    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4724    #[serde(skip_serializing_if = "Option::is_none", default)]
4725    pub format: Option<Box<Expression>>,
4726    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4727    #[serde(skip_serializing_if = "Option::is_none", default)]
4728    pub default: Option<Box<Expression>>,
4729    /// Inferred data type from type annotation
4730    #[serde(default, skip_serializing_if = "Option::is_none")]
4731    #[ast(skip)]
4732    pub inferred_type: Option<DataType>,
4733}
4734
4735///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4736#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4737#[cfg_attr(feature = "bindings", derive(TS))]
4738pub struct CollationExpr {
4739    pub this: Expression,
4740    pub collation: String,
4741    /// True if the collation was single-quoted in the original SQL (string literal)
4742    #[serde(default)]
4743    pub quoted: bool,
4744    /// True if the collation was double-quoted in the original SQL (identifier)
4745    #[serde(default)]
4746    pub double_quoted: bool,
4747}
4748
4749/// Represent a CASE expression (both simple and searched forms).
4750///
4751/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4752/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4753/// Each entry in `whens` is a `(condition, result)` pair.
4754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4755#[cfg_attr(feature = "bindings", derive(TS))]
4756pub struct Case {
4757    /// The operand for simple CASE, or `None` for searched CASE.
4758    pub operand: Option<Expression>,
4759    /// Pairs of (WHEN condition, THEN result).
4760    pub whens: Vec<(Expression, Expression)>,
4761    /// Optional ELSE result.
4762    pub else_: Option<Expression>,
4763    /// Comments from the CASE keyword (emitted after END)
4764    #[serde(default)]
4765    #[serde(skip_serializing_if = "Vec::is_empty")]
4766    pub comments: Vec<String>,
4767    /// Inferred data type from type annotation
4768    #[serde(default, skip_serializing_if = "Option::is_none")]
4769    #[ast(skip)]
4770    pub inferred_type: Option<DataType>,
4771}
4772
4773/// Represent a binary operation (two operands separated by an operator).
4774///
4775/// This is the shared payload struct for all binary operator variants in the
4776/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4777/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4778/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4779/// preservation of inline comments around operators.
4780#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4781#[cfg_attr(feature = "bindings", derive(TS))]
4782pub struct BinaryOp {
4783    pub left: Expression,
4784    pub right: Expression,
4785    /// Comments after the left operand (before the operator)
4786    #[serde(default)]
4787    pub left_comments: Vec<String>,
4788    /// Comments after the operator (before the right operand)
4789    #[serde(default)]
4790    pub operator_comments: Vec<String>,
4791    /// Comments after the right operand
4792    #[serde(default)]
4793    pub trailing_comments: Vec<String>,
4794    /// Inferred data type from type annotation
4795    #[serde(default, skip_serializing_if = "Option::is_none")]
4796    #[ast(skip)]
4797    pub inferred_type: Option<DataType>,
4798}
4799
4800impl BinaryOp {
4801    pub fn new(left: Expression, right: Expression) -> Self {
4802        Self {
4803            left,
4804            right,
4805            left_comments: Vec::new(),
4806            operator_comments: Vec::new(),
4807            trailing_comments: Vec::new(),
4808            inferred_type: None,
4809        }
4810    }
4811}
4812
4813/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4815#[cfg_attr(feature = "bindings", derive(TS))]
4816pub struct LikeOp {
4817    pub left: Expression,
4818    pub right: Expression,
4819    /// ESCAPE character/expression
4820    #[serde(default)]
4821    pub escape: Option<Expression>,
4822    /// Quantifier: ANY, ALL, or SOME
4823    #[serde(default)]
4824    pub quantifier: Option<String>,
4825    /// Inferred data type from type annotation
4826    #[serde(default, skip_serializing_if = "Option::is_none")]
4827    #[ast(skip)]
4828    pub inferred_type: Option<DataType>,
4829}
4830
4831impl LikeOp {
4832    pub fn new(left: Expression, right: Expression) -> Self {
4833        Self {
4834            left,
4835            right,
4836            escape: None,
4837            quantifier: None,
4838            inferred_type: None,
4839        }
4840    }
4841
4842    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4843        Self {
4844            left,
4845            right,
4846            escape: Some(escape),
4847            quantifier: None,
4848            inferred_type: None,
4849        }
4850    }
4851}
4852
4853/// Represent a unary operation (single operand with a prefix operator).
4854///
4855/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4857#[cfg_attr(feature = "bindings", derive(TS))]
4858pub struct UnaryOp {
4859    /// The operand expression.
4860    pub this: Expression,
4861    /// Inferred data type from type annotation
4862    #[serde(default, skip_serializing_if = "Option::is_none")]
4863    #[ast(skip)]
4864    pub inferred_type: Option<DataType>,
4865}
4866
4867impl UnaryOp {
4868    pub fn new(this: Expression) -> Self {
4869        Self {
4870            this,
4871            inferred_type: None,
4872        }
4873    }
4874}
4875
4876/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4877///
4878/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4879/// but not both. When `not` is true, the predicate is `NOT IN`.
4880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4881#[cfg_attr(feature = "bindings", derive(TS))]
4882pub struct In {
4883    /// The expression being tested.
4884    pub this: Expression,
4885    /// The value list (mutually exclusive with `query`).
4886    pub expressions: Vec<Expression>,
4887    /// A subquery (mutually exclusive with `expressions`).
4888    pub query: Option<Expression>,
4889    /// Whether this is NOT IN.
4890    pub not: bool,
4891    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4892    pub global: bool,
4893    /// BigQuery: IN UNNEST(expr)
4894    #[serde(default, skip_serializing_if = "Option::is_none")]
4895    pub unnest: Option<Box<Expression>>,
4896    /// Whether the right side is a bare field reference (no parentheses).
4897    /// Matches Python sqlglot's `field` attribute on `In` expression.
4898    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4899    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4900    pub is_field: bool,
4901}
4902
4903/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4904#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4905#[cfg_attr(feature = "bindings", derive(TS))]
4906pub struct Between {
4907    /// The expression being tested.
4908    pub this: Expression,
4909    /// The lower bound.
4910    pub low: Expression,
4911    /// The upper bound.
4912    pub high: Expression,
4913    /// Whether this is NOT BETWEEN.
4914    pub not: bool,
4915    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4916    #[serde(default)]
4917    pub symmetric: Option<bool>,
4918}
4919
4920/// IS NULL predicate
4921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4922#[cfg_attr(feature = "bindings", derive(TS))]
4923pub struct IsNull {
4924    pub this: Expression,
4925    pub not: bool,
4926    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4927    #[serde(default)]
4928    pub postfix_form: bool,
4929}
4930
4931/// IS TRUE / IS FALSE predicate
4932#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4933#[cfg_attr(feature = "bindings", derive(TS))]
4934pub struct IsTrueFalse {
4935    pub this: Expression,
4936    pub not: bool,
4937}
4938
4939/// IS JSON predicate (SQL standard)
4940/// Checks if a value is valid JSON
4941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4942#[cfg_attr(feature = "bindings", derive(TS))]
4943pub struct IsJson {
4944    pub this: Expression,
4945    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4946    pub json_type: Option<String>,
4947    /// Key uniqueness constraint
4948    pub unique_keys: Option<JsonUniqueKeys>,
4949    /// Whether IS NOT JSON
4950    pub negated: bool,
4951}
4952
4953/// JSON unique keys constraint variants
4954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4955#[cfg_attr(feature = "bindings", derive(TS))]
4956pub enum JsonUniqueKeys {
4957    /// WITH UNIQUE KEYS
4958    With,
4959    /// WITHOUT UNIQUE KEYS
4960    Without,
4961    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4962    Shorthand,
4963}
4964
4965/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4967#[cfg_attr(feature = "bindings", derive(TS))]
4968pub struct Exists {
4969    /// The subquery expression.
4970    pub this: Expression,
4971    /// Whether this is NOT EXISTS.
4972    pub not: bool,
4973}
4974
4975#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4976#[cfg_attr(feature = "bindings", derive(TS))]
4977pub struct Upsert {
4978    /// Retained source semantics; serialized independently of generator configuration.
4979    #[serde(default, skip_serializing_if = "Option::is_none")]
4980    #[ast(skip)]
4981    pub source_dialect: Option<crate::dialects::DialectType>,
4982
4983    pub table: TableRef,
4984    pub partition: Option<Expression>,
4985    pub columns: Vec<Identifier>,
4986    pub source: Expression,
4987    pub condition: Option<Expression>,
4988    pub primary_key: bool,
4989}
4990
4991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4992#[cfg_attr(feature = "bindings", derive(TS))]
4993pub struct PartitionSpec {
4994    /// Retained source semantics; serialized independently of generator configuration.
4995    #[serde(default, skip_serializing_if = "Option::is_none")]
4996    #[ast(skip)]
4997    pub source_dialect: Option<crate::dialects::DialectType>,
4998
4999    pub method: String,
5000    pub columns: Vec<Expression>,
5001    pub partitions: Option<Expression>,
5002    pub ranges: Vec<PartitionRangeSpec>,
5003    pub primary_key_check: Option<bool>,
5004    pub properties: Vec<Expression>,
5005    pub subpartition: Option<Box<PartitionSpec>>,
5006}
5007
5008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5009#[cfg_attr(feature = "bindings", derive(TS))]
5010pub struct PartitionRangeSpec {
5011    pub name: Option<Identifier>,
5012    pub kind: String,
5013    pub values: Vec<Expression>,
5014    pub dynamic: bool,
5015    pub direction: Option<String>,
5016    pub threshold: Option<Expression>,
5017    pub interval: Option<(Expression, Option<String>)>,
5018    pub properties: Vec<Expression>,
5019}
5020
5021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5022#[cfg_attr(feature = "bindings", derive(TS))]
5023pub struct StorageProperty {
5024    /// Retained source semantics; serialized independently of generator configuration.
5025    #[serde(default, skip_serializing_if = "Option::is_none")]
5026    #[ast(skip)]
5027    pub source_dialect: Option<crate::dialects::DialectType>,
5028
5029    pub name: String,
5030    pub values: Vec<Expression>,
5031}
5032
5033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5034#[cfg_attr(feature = "bindings", derive(TS))]
5035pub struct Hierarchy {
5036    /// Retained source semantics; serialized independently of generator configuration.
5037    #[serde(default, skip_serializing_if = "Option::is_none")]
5038    #[ast(skip)]
5039    pub source_dialect: Option<crate::dialects::DialectType>,
5040
5041    pub name: String,
5042    pub source: Expression,
5043    pub start: Option<Expression>,
5044    pub siblings: Vec<Ordered>,
5045    pub depth: Option<Expression>,
5046    pub multiparent: Option<String>,
5047    pub orphan: Option<String>,
5048    pub cycle: Option<String>,
5049    pub cache: Option<String>,
5050}
5051
5052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5053#[cfg_attr(feature = "bindings", derive(TS))]
5054pub struct ViewParameter {
5055    /// Retained source semantics; serialized independently of generator configuration.
5056    #[serde(default, skip_serializing_if = "Option::is_none")]
5057    #[ast(skip)]
5058    pub source_dialect: Option<crate::dialects::DialectType>,
5059
5060    pub name: Identifier,
5061    pub value: Expression,
5062}
5063
5064#[derive(
5065    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
5066)]
5067#[cfg_attr(feature = "bindings", derive(TS))]
5068pub struct JsonOptions {
5069    pub wrapper: Option<String>,
5070    pub on_empty: Option<SqlBehavior>,
5071    pub on_error: Option<SqlBehavior>,
5072}
5073
5074#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5075#[cfg_attr(feature = "bindings", derive(TS))]
5076pub struct SqlBehavior {
5077    /// ERROR, NULL, DEFAULT, EMPTY ARRAY, or EMPTY OBJECT.
5078    pub kind: String,
5079    pub value: Option<Expression>,
5080}
5081
5082/// Procedure invocation, including library member calls and asynchronous execution.
5083#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5084#[cfg_attr(feature = "bindings", derive(TS))]
5085pub struct Call {
5086    /// Retained source semantics; serialized independently of generator configuration.
5087    #[serde(default, skip_serializing_if = "Option::is_none")]
5088    #[ast(skip)]
5089    pub source_dialect: Option<crate::dialects::DialectType>,
5090
5091    pub name: Vec<Identifier>,
5092    pub member: Option<Identifier>,
5093    pub arguments: Vec<Expression>,
5094    pub asynchronous: bool,
5095    pub hints: Vec<Expression>,
5096}
5097
5098/// Regex search options shared by predicates, extraction, replacement, and position calls.
5099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5100#[cfg_attr(feature = "bindings", derive(TS))]
5101pub struct RegexOptions {
5102    #[serde(default, skip_serializing_if = "Option::is_none")]
5103    #[ast(skip)]
5104    pub source_dialect: Option<crate::dialects::DialectType>,
5105    /// Original spelling when a dialect has more than one native alias.
5106    pub source_name: String,
5107    #[serde(default)]
5108    pub negated: bool,
5109    pub start: Option<Expression>,
5110    pub occurrence: Option<Expression>,
5111    pub flags: Option<Expression>,
5112    pub position_after: Option<bool>,
5113}
5114
5115/// Grouping-set selection and result-delivery options.
5116#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5117#[cfg_attr(feature = "bindings", derive(TS))]
5118pub struct GroupingOptions {
5119    #[serde(default, skip_serializing_if = "Option::is_none")]
5120    #[ast(skip)]
5121    pub source_dialect: Option<crate::dialects::DialectType>,
5122    pub best: Option<Expression>,
5123    pub limit: Option<Expression>,
5124    pub offset: Option<Expression>,
5125    pub subtotal: bool,
5126    pub balance: bool,
5127    pub total: bool,
5128    pub structured: bool,
5129    pub overview: bool,
5130    pub prefix: Option<Expression>,
5131    pub multiple_resultsets: bool,
5132}
5133
5134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5135#[cfg_attr(feature = "bindings", derive(TS))]
5136pub struct ResultSerialization {
5137    /// JSON or XML, validated by the HANA parser.
5138    pub format: String,
5139    pub options: Vec<(String, String)>,
5140    #[serde(default, skip_serializing_if = "Option::is_none")]
5141    pub returning: Option<DataType>,
5142}
5143
5144/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
5145///
5146/// This is the generic function node. Well-known aggregates, window functions,
5147/// and built-in functions each have their own dedicated `Expression` variants
5148/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
5149/// not recognize as built-ins are represented with this struct.
5150#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5151#[cfg_attr(feature = "bindings", derive(TS))]
5152pub struct Function {
5153    /// Qualified name components preserve quoting without changing the node kind.
5154    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5155    pub qualified_name: Vec<Identifier>,
5156    /// Optional DEFAULT/NULL/ERROR behavior after the arguments.
5157    #[serde(default, skip_serializing_if = "Option::is_none")]
5158    pub on_error: Option<Box<SqlBehavior>>,
5159    /// Dialect whose call semantics must be retained through independent generation.
5160    #[serde(default, skip_serializing_if = "Option::is_none")]
5161    #[ast(skip)]
5162    pub source_dialect: Option<crate::dialects::DialectType>,
5163
5164    /// The function name, as originally written (may be schema-qualified).
5165    pub name: String,
5166    /// Positional arguments to the function.
5167    pub args: Vec<Expression>,
5168    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
5169    pub distinct: bool,
5170    #[serde(default)]
5171    pub trailing_comments: Vec<String>,
5172    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
5173    #[serde(default)]
5174    pub use_bracket_syntax: bool,
5175    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
5176    #[serde(default)]
5177    pub no_parens: bool,
5178    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
5179    #[serde(default)]
5180    pub quoted: bool,
5181    /// Source position span
5182    #[serde(default, skip_serializing_if = "Option::is_none")]
5183    pub span: Option<Span>,
5184    /// Inferred data type from type annotation
5185    #[serde(default, skip_serializing_if = "Option::is_none")]
5186    #[ast(skip)]
5187    pub inferred_type: Option<DataType>,
5188}
5189
5190impl Default for Function {
5191    fn default() -> Self {
5192        Self {
5193            source_dialect: None,
5194            qualified_name: Vec::new(),
5195            on_error: None,
5196            name: String::new(),
5197            args: Vec::new(),
5198            distinct: false,
5199            trailing_comments: Vec::new(),
5200            use_bracket_syntax: false,
5201            no_parens: false,
5202            quoted: false,
5203            span: None,
5204            inferred_type: None,
5205        }
5206    }
5207}
5208
5209impl Function {
5210    /// Construct a call with individually quoted qualified name components.
5211    pub fn qualified(name: Vec<Identifier>, args: Vec<Expression>) -> Self {
5212        Self {
5213            name: name
5214                .iter()
5215                .map(|part| part.name.as_str())
5216                .collect::<Vec<_>>()
5217                .join("."),
5218            qualified_name: name,
5219            args,
5220            ..Default::default()
5221        }
5222    }
5223    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
5224        Self {
5225            source_dialect: None,
5226            qualified_name: Vec::new(),
5227            on_error: None,
5228            name: name.into(),
5229            args,
5230            distinct: false,
5231            trailing_comments: Vec::new(),
5232            use_bracket_syntax: false,
5233            no_parens: false,
5234            quoted: false,
5235            span: None,
5236            inferred_type: None,
5237        }
5238    }
5239}
5240
5241/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
5242///
5243/// This struct is used for aggregate function calls that are not covered by
5244/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
5245/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
5246/// IGNORE NULLS / RESPECT NULLS modifiers.
5247#[derive(
5248    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
5249)]
5250#[cfg_attr(feature = "bindings", derive(TS))]
5251pub struct AggregateFunction {
5252    /// Dialect whose call semantics must be retained through independent generation.
5253    #[serde(default, skip_serializing_if = "Option::is_none")]
5254    #[ast(skip)]
5255    pub source_dialect: Option<crate::dialects::DialectType>,
5256
5257    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
5258    pub name: String,
5259    /// Positional arguments.
5260    pub args: Vec<Expression>,
5261    /// Whether DISTINCT was specified.
5262    pub distinct: bool,
5263    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
5264    pub filter: Option<Expression>,
5265    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
5266    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5267    pub order_by: Vec<Ordered>,
5268    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
5269    #[serde(default, skip_serializing_if = "Option::is_none")]
5270    pub limit: Option<Box<Expression>>,
5271    /// IGNORE NULLS / RESPECT NULLS
5272    #[serde(default, skip_serializing_if = "Option::is_none")]
5273    pub ignore_nulls: Option<bool>,
5274    /// Inferred data type from type annotation
5275    #[serde(default, skip_serializing_if = "Option::is_none")]
5276    #[ast(skip)]
5277    pub inferred_type: Option<DataType>,
5278}
5279
5280/// Represent a window function call with its OVER clause.
5281///
5282/// The inner `this` expression is typically a window-specific expression
5283/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
5284/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
5285/// frame specification.
5286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5287#[cfg_attr(feature = "bindings", derive(TS))]
5288pub struct WindowFunction {
5289    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
5290    pub this: Expression,
5291    /// The OVER clause defining the window partitioning, ordering, and frame.
5292    pub over: Over,
5293    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
5294    #[serde(default, skip_serializing_if = "Option::is_none")]
5295    pub keep: Option<Keep>,
5296    /// Inferred data type from type annotation
5297    #[serde(default, skip_serializing_if = "Option::is_none")]
5298    #[ast(skip)]
5299    pub inferred_type: Option<DataType>,
5300}
5301
5302/// Oracle KEEP clause for aggregate functions
5303/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
5304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5305#[cfg_attr(feature = "bindings", derive(TS))]
5306pub struct Keep {
5307    /// true = FIRST, false = LAST
5308    pub first: bool,
5309    /// ORDER BY clause inside KEEP
5310    pub order_by: Vec<Ordered>,
5311}
5312
5313/// WITHIN GROUP clause (for ordered-set aggregate functions)
5314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5315#[cfg_attr(feature = "bindings", derive(TS))]
5316pub struct WithinGroup {
5317    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
5318    pub this: Expression,
5319    /// The ORDER BY clause within the group
5320    pub order_by: Vec<Ordered>,
5321}
5322
5323/// Represent the FROM clause of a SELECT statement.
5324///
5325/// Contains one or more table sources (tables, subqueries, table-valued
5326/// functions, etc.). Multiple entries represent comma-separated implicit joins.
5327#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5328#[cfg_attr(feature = "bindings", derive(TS))]
5329pub struct From {
5330    /// The table source expressions.
5331    pub expressions: Vec<Expression>,
5332}
5333
5334/// Represent a JOIN clause between two table sources.
5335///
5336/// The join condition can be specified via `on` (ON predicate) or `using`
5337/// (USING column list), but not both. The `kind` field determines the join
5338/// type (INNER, LEFT, CROSS, etc.).
5339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5340#[cfg_attr(feature = "bindings", derive(TS))]
5341pub struct Join {
5342    /// The right-hand table expression being joined.
5343    pub this: Expression,
5344    /// The ON condition (mutually exclusive with `using`).
5345    pub on: Option<Expression>,
5346    /// The USING column list (mutually exclusive with `on`).
5347    pub using: Vec<Identifier>,
5348    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5349    pub kind: JoinKind,
5350    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5351    pub use_inner_keyword: bool,
5352    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5353    pub use_outer_keyword: bool,
5354    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5355    pub deferred_condition: bool,
5356    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5357    #[serde(default, skip_serializing_if = "Option::is_none")]
5358    pub join_hint: Option<String>,
5359    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5360    #[serde(default, skip_serializing_if = "Option::is_none")]
5361    pub match_condition: Option<Expression>,
5362    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5363    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5364    pub pivots: Vec<Expression>,
5365    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5366    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5367    pub comments: Vec<String>,
5368    /// Nesting group identifier for nested join pretty-printing.
5369    /// Joins in the same group were parsed together; group boundaries come from
5370    /// deferred condition resolution phases.
5371    #[serde(default)]
5372    pub nesting_group: usize,
5373    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5374    #[serde(default)]
5375    pub directed: bool,
5376}
5377
5378/// Enumerate all supported SQL join types.
5379///
5380/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5381/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5382/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5383/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5384#[derive(
5385    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5386)]
5387#[cfg_attr(feature = "bindings", derive(TS))]
5388pub enum JoinKind {
5389    Inner,
5390    Left,
5391    Right,
5392    Full,
5393    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5394    Cross,
5395    Natural,
5396    NaturalLeft,
5397    NaturalRight,
5398    NaturalFull,
5399    Semi,
5400    Anti,
5401    // Directional SEMI/ANTI joins
5402    LeftSemi,
5403    LeftAnti,
5404    RightSemi,
5405    RightAnti,
5406    // SQL Server specific
5407    CrossApply,
5408    OuterApply,
5409    // Time-series specific
5410    AsOf,
5411    AsOfLeft,
5412    AsOfRight,
5413    // Lateral join
5414    Lateral,
5415    LeftLateral,
5416    // MySQL specific
5417    Straight,
5418    // Implicit join (comma-separated tables: FROM a, b)
5419    Implicit,
5420    // ClickHouse ARRAY JOIN
5421    Array,
5422    LeftArray,
5423    // ClickHouse PASTE JOIN (positional join)
5424    Paste,
5425    // DuckDB POSITIONAL JOIN
5426    Positional,
5427}
5428
5429impl Default for JoinKind {
5430    fn default() -> Self {
5431        JoinKind::Inner
5432    }
5433}
5434
5435/// Parenthesized table expression with joins
5436/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5438#[cfg_attr(feature = "bindings", derive(TS))]
5439pub struct JoinedTable {
5440    /// The left-hand side table expression
5441    pub left: Expression,
5442    /// The joins applied to the left table
5443    pub joins: Vec<Join>,
5444    /// LATERAL VIEW clauses (Hive/Spark)
5445    pub lateral_views: Vec<LateralView>,
5446    /// Optional alias for the joined table expression
5447    pub alias: Option<Identifier>,
5448}
5449
5450/// Represent a WHERE clause containing a boolean filter predicate.
5451#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5452#[cfg_attr(feature = "bindings", derive(TS))]
5453pub struct Where {
5454    /// The filter predicate expression.
5455    pub this: Expression,
5456}
5457
5458/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5459///
5460/// The `expressions` list may contain plain columns, ordinal positions,
5461/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5463#[cfg_attr(feature = "bindings", derive(TS))]
5464pub struct GroupBy {
5465    /// The grouping expressions.
5466    pub expressions: Vec<Expression>,
5467    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5468    #[serde(default)]
5469    pub all: Option<bool>,
5470    /// ClickHouse: WITH TOTALS modifier
5471    #[serde(default)]
5472    pub totals: bool,
5473    /// Leading comments that appeared before the GROUP BY keyword
5474    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5475    pub comments: Vec<String>,
5476}
5477
5478/// Represent a HAVING clause containing a predicate over aggregate results.
5479#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5480#[cfg_attr(feature = "bindings", derive(TS))]
5481pub struct Having {
5482    /// The filter predicate, typically involving aggregate functions.
5483    pub this: Expression,
5484    /// Leading comments that appeared before the HAVING keyword
5485    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5486    pub comments: Vec<String>,
5487}
5488
5489/// Represent an ORDER BY clause containing one or more sort specifications.
5490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5491#[cfg_attr(feature = "bindings", derive(TS))]
5492pub struct OrderBy {
5493    /// The sort specifications, each with direction and null ordering.
5494    pub expressions: Vec<Ordered>,
5495    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5496    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5497    pub siblings: bool,
5498    /// Leading comments that appeared before the ORDER BY keyword
5499    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5500    pub comments: Vec<String>,
5501}
5502
5503/// Represent an expression with sort direction and null ordering.
5504///
5505/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5506/// When `desc` is false the sort is ascending. The `nulls_first` field
5507/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5508/// (database default).
5509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5510#[cfg_attr(feature = "bindings", derive(TS))]
5511pub struct Ordered {
5512    /// Vertica lets the engine select null placement for aggregate/window ordering.
5513    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5514    pub nulls_auto: bool,
5515    /// The expression to sort by.
5516    pub this: Expression,
5517    /// Whether the sort direction is descending (true) or ascending (false).
5518    pub desc: bool,
5519    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5520    pub nulls_first: Option<bool>,
5521    /// Whether ASC was explicitly written (not just implied)
5522    #[serde(default)]
5523    pub explicit_asc: bool,
5524    /// ClickHouse WITH FILL clause
5525    #[serde(default, skip_serializing_if = "Option::is_none")]
5526    pub with_fill: Option<Box<WithFill>>,
5527}
5528
5529impl Ordered {
5530    pub fn asc(expr: Expression) -> Self {
5531        Self {
5532            nulls_auto: false,
5533            this: expr,
5534            desc: false,
5535            nulls_first: None,
5536            explicit_asc: false,
5537            with_fill: None,
5538        }
5539    }
5540
5541    pub fn desc(expr: Expression) -> Self {
5542        Self {
5543            nulls_auto: false,
5544            this: expr,
5545            desc: true,
5546            nulls_first: None,
5547            explicit_asc: false,
5548            with_fill: None,
5549        }
5550    }
5551}
5552
5553/// DISTRIBUTE BY clause (Hive/Spark)
5554/// Controls how rows are distributed across reducers
5555#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5556#[cfg_attr(feature = "bindings", derive(TS))]
5557#[cfg_attr(feature = "bindings", ts(export))]
5558pub struct DistributeBy {
5559    pub expressions: Vec<Expression>,
5560}
5561
5562/// CLUSTER BY clause (Hive/Spark)
5563/// Combines DISTRIBUTE BY and SORT BY on the same columns
5564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5565#[cfg_attr(feature = "bindings", derive(TS))]
5566#[cfg_attr(feature = "bindings", ts(export))]
5567pub struct ClusterBy {
5568    pub expressions: Vec<Ordered>,
5569}
5570
5571/// SORT BY clause (Hive/Spark)
5572/// Sorts data within each reducer (local sort, not global)
5573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5574#[cfg_attr(feature = "bindings", derive(TS))]
5575#[cfg_attr(feature = "bindings", ts(export))]
5576pub struct SortBy {
5577    pub expressions: Vec<Ordered>,
5578}
5579
5580/// LATERAL VIEW clause (Hive/Spark)
5581/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5582#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5583#[cfg_attr(feature = "bindings", derive(TS))]
5584#[cfg_attr(feature = "bindings", ts(export))]
5585pub struct LateralView {
5586    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5587    pub this: Expression,
5588    /// Table alias for the generated table
5589    pub table_alias: Option<Identifier>,
5590    /// Column aliases for the generated columns
5591    pub column_aliases: Vec<Identifier>,
5592    /// OUTER keyword - preserve nulls when input is empty/null
5593    pub outer: bool,
5594}
5595
5596/// Query hint
5597#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5598#[cfg_attr(feature = "bindings", derive(TS))]
5599#[cfg_attr(feature = "bindings", ts(export))]
5600pub struct Hint {
5601    #[serde(default, skip_serializing_if = "Option::is_none")]
5602    #[ast(skip)]
5603    pub source_dialect: Option<crate::dialects::DialectType>,
5604    pub expressions: Vec<HintExpression>,
5605}
5606
5607/// Individual hint expression
5608#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5609#[cfg_attr(feature = "bindings", derive(TS))]
5610#[cfg_attr(feature = "bindings", ts(export))]
5611pub enum HintExpression {
5612    /// A structured hint directive with optional execution scope modifiers.
5613    Directive {
5614        name: Identifier,
5615        arguments: Option<Vec<Expression>>,
5616        remote: bool,
5617        cascade: bool,
5618    },
5619    /// Function-style hint: USE_HASH(table)
5620    Function { name: String, args: Vec<Expression> },
5621    /// Simple identifier hint: PARALLEL
5622    Identifier(String),
5623    /// Raw hint text (unparsed)
5624    Raw(String),
5625}
5626
5627/// Pseudocolumn type
5628#[derive(
5629    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5630)]
5631#[cfg_attr(feature = "bindings", derive(TS))]
5632#[cfg_attr(feature = "bindings", ts(export))]
5633pub enum PseudocolumnType {
5634    Rownum,      // Oracle ROWNUM
5635    Rowid,       // Oracle ROWID
5636    Level,       // Oracle LEVEL (for CONNECT BY)
5637    Sysdate,     // Oracle SYSDATE
5638    ObjectId,    // Oracle OBJECT_ID
5639    ObjectValue, // Oracle OBJECT_VALUE
5640}
5641
5642impl PseudocolumnType {
5643    pub fn as_str(&self) -> &'static str {
5644        match self {
5645            PseudocolumnType::Rownum => "ROWNUM",
5646            PseudocolumnType::Rowid => "ROWID",
5647            PseudocolumnType::Level => "LEVEL",
5648            PseudocolumnType::Sysdate => "SYSDATE",
5649            PseudocolumnType::ObjectId => "OBJECT_ID",
5650            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5651        }
5652    }
5653
5654    pub fn from_str(s: &str) -> Option<Self> {
5655        match s.to_uppercase().as_str() {
5656            "ROWNUM" => Some(PseudocolumnType::Rownum),
5657            "ROWID" => Some(PseudocolumnType::Rowid),
5658            "LEVEL" => Some(PseudocolumnType::Level),
5659            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5660            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5661            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5662            _ => None,
5663        }
5664    }
5665}
5666
5667/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5668/// These are special identifiers that should not be quoted
5669#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5670#[cfg_attr(feature = "bindings", derive(TS))]
5671#[cfg_attr(feature = "bindings", ts(export))]
5672pub struct Pseudocolumn {
5673    pub kind: PseudocolumnType,
5674}
5675
5676impl Pseudocolumn {
5677    pub fn rownum() -> Self {
5678        Self {
5679            kind: PseudocolumnType::Rownum,
5680        }
5681    }
5682
5683    pub fn rowid() -> Self {
5684        Self {
5685            kind: PseudocolumnType::Rowid,
5686        }
5687    }
5688
5689    pub fn level() -> Self {
5690        Self {
5691            kind: PseudocolumnType::Level,
5692        }
5693    }
5694}
5695
5696/// Oracle CONNECT BY clause for hierarchical queries
5697#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5698#[cfg_attr(feature = "bindings", derive(TS))]
5699#[cfg_attr(feature = "bindings", ts(export))]
5700pub struct Connect {
5701    /// START WITH condition (optional, can come before or after CONNECT BY)
5702    pub start: Option<Expression>,
5703    /// CONNECT BY condition (required, contains PRIOR references)
5704    pub connect: Expression,
5705    /// NOCYCLE keyword to prevent infinite loops
5706    pub nocycle: bool,
5707}
5708
5709/// Oracle PRIOR expression - references parent row's value in CONNECT BY
5710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5711#[cfg_attr(feature = "bindings", derive(TS))]
5712#[cfg_attr(feature = "bindings", ts(export))]
5713pub struct Prior {
5714    pub this: Expression,
5715}
5716
5717/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5719#[cfg_attr(feature = "bindings", derive(TS))]
5720#[cfg_attr(feature = "bindings", ts(export))]
5721pub struct ConnectByRoot {
5722    pub this: Expression,
5723}
5724
5725/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5727#[cfg_attr(feature = "bindings", derive(TS))]
5728#[cfg_attr(feature = "bindings", ts(export))]
5729pub struct MatchRecognize {
5730    /// Source table/expression
5731    pub this: Option<Box<Expression>>,
5732    /// PARTITION BY expressions
5733    pub partition_by: Option<Vec<Expression>>,
5734    /// ORDER BY expressions
5735    pub order_by: Option<Vec<Ordered>>,
5736    /// MEASURES definitions
5737    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5738    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5739    pub rows: Option<MatchRecognizeRows>,
5740    /// AFTER MATCH SKIP behavior
5741    pub after: Option<MatchRecognizeAfter>,
5742    /// PATTERN definition (stored as raw string for complex regex patterns)
5743    pub pattern: Option<String>,
5744    /// DEFINE clauses (pattern variable definitions)
5745    pub define: Option<Vec<(Identifier, Expression)>>,
5746    /// Optional alias for the result
5747    pub alias: Option<Identifier>,
5748    /// Whether AS keyword was explicitly present before alias
5749    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5750    pub alias_explicit_as: bool,
5751}
5752
5753/// MEASURES expression with optional RUNNING/FINAL semantics
5754#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5755#[cfg_attr(feature = "bindings", derive(TS))]
5756#[cfg_attr(feature = "bindings", ts(export))]
5757pub struct MatchRecognizeMeasure {
5758    /// The measure expression
5759    pub this: Expression,
5760    /// RUNNING or FINAL semantics (Snowflake-specific)
5761    pub window_frame: Option<MatchRecognizeSemantics>,
5762}
5763
5764/// Semantics for MEASURES in MATCH_RECOGNIZE
5765#[derive(
5766    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5767)]
5768#[cfg_attr(feature = "bindings", derive(TS))]
5769#[cfg_attr(feature = "bindings", ts(export))]
5770pub enum MatchRecognizeSemantics {
5771    Running,
5772    Final,
5773}
5774
5775/// Row output semantics for MATCH_RECOGNIZE
5776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5777#[cfg_attr(feature = "bindings", derive(TS))]
5778#[cfg_attr(feature = "bindings", ts(export))]
5779pub enum MatchRecognizeRows {
5780    OneRowPerMatch,
5781    AllRowsPerMatch,
5782    AllRowsPerMatchShowEmptyMatches,
5783    AllRowsPerMatchOmitEmptyMatches,
5784    AllRowsPerMatchWithUnmatchedRows,
5785}
5786
5787/// AFTER MATCH SKIP behavior
5788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5789#[cfg_attr(feature = "bindings", derive(TS))]
5790#[cfg_attr(feature = "bindings", ts(export))]
5791pub enum MatchRecognizeAfter {
5792    PastLastRow,
5793    ToNextRow,
5794    ToFirst(Identifier),
5795    ToLast(Identifier),
5796}
5797
5798/// Represent a LIMIT clause that restricts the number of returned rows.
5799#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5800#[cfg_attr(feature = "bindings", derive(TS))]
5801pub struct Limit {
5802    /// The limit count expression.
5803    pub this: Expression,
5804    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5805    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5806    pub percent: bool,
5807    /// Comments from before the LIMIT keyword (emitted after the limit value)
5808    #[serde(default)]
5809    #[serde(skip_serializing_if = "Vec::is_empty")]
5810    pub comments: Vec<String>,
5811}
5812
5813impl Limit {
5814    /// Preserve the legacy count-only set-operation AST when no metadata is needed.
5815    pub(crate) fn into_set_limit(self) -> Box<Expression> {
5816        if self.percent || !self.comments.is_empty() {
5817            Box::new(Expression::Limit(Box::new(self)))
5818        } else {
5819            Box::new(self.this)
5820        }
5821    }
5822}
5823
5824/// Move a compound query's row limit onto a SELECT without losing clause options.
5825/// Bare expressions remain supported for existing builders and serialized ASTs.
5826pub(crate) fn split_set_limit(limit: Option<Box<Expression>>) -> (Option<Limit>, Option<Fetch>) {
5827    match limit.map(|limit| *limit) {
5828        Some(Expression::Limit(limit)) => (Some(*limit), None),
5829        Some(Expression::Fetch(fetch)) => (None, Some(*fetch)),
5830        Some(this) => (
5831            Some(Limit {
5832                this,
5833                percent: false,
5834                comments: Vec::new(),
5835            }),
5836            None,
5837        ),
5838        None => (None, None),
5839    }
5840}
5841
5842/// OFFSET clause
5843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5844#[cfg_attr(feature = "bindings", derive(TS))]
5845pub struct Offset {
5846    pub this: Expression,
5847    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5848    #[serde(skip_serializing_if = "Option::is_none", default)]
5849    pub rows: Option<bool>,
5850}
5851
5852/// TOP clause (SQL Server)
5853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5854#[cfg_attr(feature = "bindings", derive(TS))]
5855pub struct Top {
5856    pub this: Expression,
5857    pub percent: bool,
5858    pub with_ties: bool,
5859    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5860    #[serde(default)]
5861    pub parenthesized: bool,
5862}
5863
5864/// FETCH FIRST/NEXT clause (SQL standard)
5865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5866#[cfg_attr(feature = "bindings", derive(TS))]
5867pub struct Fetch {
5868    /// FIRST or NEXT
5869    pub direction: String,
5870    /// Count expression (optional)
5871    pub count: Option<Expression>,
5872    /// PERCENT modifier
5873    pub percent: bool,
5874    /// ROWS or ROW keyword present
5875    pub rows: bool,
5876    /// WITH TIES modifier
5877    pub with_ties: bool,
5878}
5879
5880/// Represent a QUALIFY clause for filtering on window function results.
5881///
5882/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5883/// typically references a window function (e.g.
5884/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5885#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5886#[cfg_attr(feature = "bindings", derive(TS))]
5887pub struct Qualify {
5888    /// The filter predicate over window function results.
5889    pub this: Expression,
5890}
5891
5892/// SAMPLE / TABLESAMPLE clause
5893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5894#[cfg_attr(feature = "bindings", derive(TS))]
5895pub struct Sample {
5896    pub method: SampleMethod,
5897    pub size: Expression,
5898    pub seed: Option<Expression>,
5899    /// ClickHouse OFFSET expression after SAMPLE size
5900    #[serde(default)]
5901    pub offset: Option<Expression>,
5902    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5903    pub unit_after_size: bool,
5904    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5905    #[serde(default)]
5906    pub use_sample_keyword: bool,
5907    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5908    #[serde(default)]
5909    pub explicit_method: bool,
5910    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5911    #[serde(default)]
5912    pub method_before_size: bool,
5913    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5914    #[serde(default)]
5915    pub use_seed_keyword: bool,
5916    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5917    pub bucket_numerator: Option<Box<Expression>>,
5918    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5919    pub bucket_denominator: Option<Box<Expression>>,
5920    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5921    pub bucket_field: Option<Box<Expression>>,
5922    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5923    #[serde(default)]
5924    pub is_using_sample: bool,
5925    /// Whether the unit was explicitly PERCENT (vs ROWS)
5926    #[serde(default)]
5927    pub is_percent: bool,
5928    /// Whether to suppress method output (for cross-dialect transpilation)
5929    #[serde(default)]
5930    pub suppress_method_output: bool,
5931}
5932
5933/// Sample method
5934#[derive(
5935    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5936)]
5937#[cfg_attr(feature = "bindings", derive(TS))]
5938pub enum SampleMethod {
5939    Bernoulli,
5940    System,
5941    Block,
5942    Row,
5943    Percent,
5944    /// Hive bucket sampling
5945    Bucket,
5946    /// DuckDB reservoir sampling
5947    Reservoir,
5948}
5949
5950/// Named window definition (WINDOW w AS (...))
5951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5952#[cfg_attr(feature = "bindings", derive(TS))]
5953pub struct NamedWindow {
5954    pub name: Identifier,
5955    pub spec: Over,
5956}
5957
5958/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5959///
5960/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5961/// that reference themselves. Each CTE is defined in the `ctes` vector and
5962/// can be referenced by name in subsequent CTEs and in the main query body.
5963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5964#[cfg_attr(feature = "bindings", derive(TS))]
5965pub struct With {
5966    /// The list of CTE definitions, in order.
5967    pub ctes: Vec<Cte>,
5968    /// Whether the WITH RECURSIVE keyword was used.
5969    pub recursive: bool,
5970    /// Leading comments before the statement
5971    #[serde(default)]
5972    pub leading_comments: Vec<String>,
5973    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5974    #[serde(default, skip_serializing_if = "Option::is_none")]
5975    pub search: Option<Box<Expression>>,
5976}
5977
5978/// Represent a single Common Table Expression definition.
5979///
5980/// A CTE has a name (`alias`), an optional column list, and a body query.
5981/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5982/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5983/// the expression comes before the alias (`alias_first`).
5984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5985#[cfg_attr(feature = "bindings", derive(TS))]
5986pub struct Cte {
5987    /// The CTE name.
5988    pub alias: Identifier,
5989    /// The CTE body (typically a SELECT, UNION, etc.).
5990    pub this: Expression,
5991    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5992    pub columns: Vec<Identifier>,
5993    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5994    pub materialized: Option<bool>,
5995    /// USING KEY (columns) for DuckDB recursive CTEs
5996    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5997    pub key_expressions: Vec<Identifier>,
5998    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5999    #[serde(default)]
6000    pub alias_first: bool,
6001    /// Comments associated with this CTE (placed after alias name, before AS)
6002    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6003    pub comments: Vec<String>,
6004}
6005
6006/// Window specification
6007#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6008#[cfg_attr(feature = "bindings", derive(TS))]
6009pub struct WindowSpec {
6010    pub partition_by: Vec<Expression>,
6011    pub order_by: Vec<Ordered>,
6012    pub frame: Option<WindowFrame>,
6013}
6014
6015/// OVER clause
6016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6017#[cfg_attr(feature = "bindings", derive(TS))]
6018pub struct Over {
6019    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
6020    pub window_name: Option<Identifier>,
6021    pub partition_by: Vec<Expression>,
6022    pub order_by: Vec<Ordered>,
6023    pub frame: Option<WindowFrame>,
6024    pub alias: Option<Identifier>,
6025}
6026
6027/// Window frame
6028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6029#[cfg_attr(feature = "bindings", derive(TS))]
6030pub struct WindowFrame {
6031    pub kind: WindowFrameKind,
6032    pub start: WindowFrameBound,
6033    pub end: Option<WindowFrameBound>,
6034    pub exclude: Option<WindowFrameExclude>,
6035    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
6036    #[serde(default, skip_serializing_if = "Option::is_none")]
6037    pub kind_text: Option<String>,
6038    /// Original text of the start bound side keyword (e.g. "preceding")
6039    #[serde(default, skip_serializing_if = "Option::is_none")]
6040    pub start_side_text: Option<String>,
6041    /// Original text of the end bound side keyword
6042    #[serde(default, skip_serializing_if = "Option::is_none")]
6043    pub end_side_text: Option<String>,
6044}
6045
6046#[derive(
6047    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6048)]
6049#[cfg_attr(feature = "bindings", derive(TS))]
6050pub enum WindowFrameKind {
6051    Rows,
6052    Range,
6053    Groups,
6054}
6055
6056/// EXCLUDE clause for window frames
6057#[derive(
6058    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6059)]
6060#[cfg_attr(feature = "bindings", derive(TS))]
6061pub enum WindowFrameExclude {
6062    CurrentRow,
6063    Group,
6064    Ties,
6065    NoOthers,
6066}
6067
6068#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6069#[cfg_attr(feature = "bindings", derive(TS))]
6070pub enum WindowFrameBound {
6071    CurrentRow,
6072    UnboundedPreceding,
6073    UnboundedFollowing,
6074    Preceding(Box<Expression>),
6075    Following(Box<Expression>),
6076    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
6077    BarePreceding,
6078    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
6079    BareFollowing,
6080    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
6081    Value(Box<Expression>),
6082}
6083
6084/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
6085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6086#[cfg_attr(feature = "bindings", derive(TS))]
6087pub struct StructField {
6088    /// A raw field name, or a delimited identifier for compatibility with parsed ASTs.
6089    /// Parsed quoted names use double quotes with doubled internal quotes. An empty
6090    /// string denotes an anonymous field. Generation selects the target dialect's quotes.
6091    pub name: String,
6092    pub data_type: DataType,
6093    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6094    pub options: Vec<Expression>,
6095    #[serde(default, skip_serializing_if = "Option::is_none")]
6096    pub comment: Option<String>,
6097}
6098
6099impl StructField {
6100    /// Create a new struct field without options
6101    pub fn new(name: String, data_type: DataType) -> Self {
6102        Self {
6103            name,
6104            data_type,
6105            options: Vec::new(),
6106            comment: None,
6107        }
6108    }
6109
6110    /// Create a new struct field with options
6111    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
6112        Self {
6113            name,
6114            data_type,
6115            options,
6116            comment: None,
6117        }
6118    }
6119
6120    /// Create a new struct field with options and comment
6121    pub fn with_options_and_comment(
6122        name: String,
6123        data_type: DataType,
6124        options: Vec<Expression>,
6125        comment: Option<String>,
6126    ) -> Self {
6127        Self {
6128            name,
6129            data_type,
6130            options,
6131            comment,
6132        }
6133    }
6134}
6135
6136/// Oracle-specific data types whose semantics cannot be represented losslessly by the
6137/// generic [`DataType`] variants.
6138///
6139/// Keeping these types structured allows the Oracle parser to retain details such as a
6140/// negative `NUMBER` scale, `BYTE`/`CHAR` length semantics, interval precisions, and
6141/// `TIMESTAMP WITH LOCAL TIME ZONE` until the target dialect is known.
6142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6143#[cfg_attr(feature = "bindings", derive(TS))]
6144#[serde(tag = "oracle_data_type", rename_all = "snake_case")]
6145pub enum OracleDataType {
6146    Number {
6147        precision: Option<u32>,
6148        scale: Option<i32>,
6149    },
6150    BinaryFloat,
6151    BinaryDouble,
6152    Float {
6153        precision: Option<u32>,
6154    },
6155    Character {
6156        kind: OracleCharacterKind,
6157        length: Option<u32>,
6158        semantics: Option<OracleCharacterLengthSemantics>,
6159    },
6160    Date,
6161    Timestamp {
6162        precision: Option<u32>,
6163        timezone: OracleTimestampTimeZone,
6164    },
6165    IntervalYearToMonth {
6166        year_precision: Option<u32>,
6167    },
6168    IntervalDayToSecond {
6169        day_precision: Option<u32>,
6170        fractional_seconds_precision: Option<u32>,
6171    },
6172    Clob {
6173        national: bool,
6174    },
6175    Blob,
6176    Raw {
6177        length: Option<u32>,
6178    },
6179    Long {
6180        raw: bool,
6181    },
6182    RowId,
6183}
6184
6185#[derive(
6186    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6187)]
6188#[cfg_attr(feature = "bindings", derive(TS))]
6189#[serde(rename_all = "snake_case")]
6190pub enum OracleCharacterKind {
6191    Char,
6192    VarChar,
6193    NChar,
6194    NVarChar,
6195}
6196
6197#[derive(
6198    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6199)]
6200#[cfg_attr(feature = "bindings", derive(TS))]
6201#[serde(rename_all = "snake_case")]
6202pub enum OracleCharacterLengthSemantics {
6203    Byte,
6204    Char,
6205}
6206
6207#[derive(
6208    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6209)]
6210#[cfg_attr(feature = "bindings", derive(TS))]
6211#[serde(rename_all = "snake_case")]
6212pub enum OracleTimestampTimeZone {
6213    None,
6214    WithTimeZone,
6215    WithLocalTimeZone,
6216}
6217
6218/// Enumerate all SQL data types recognized by the parser.
6219///
6220/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
6221/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
6222/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
6223///
6224/// This enum is used in CAST expressions, column definitions, function return
6225/// types, and anywhere a data type specification appears in SQL.
6226///
6227/// Types that do not match any known variant fall through to `Custom { name }`,
6228/// preserving the original type name for round-trip fidelity.
6229#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6230#[cfg_attr(feature = "bindings", derive(TS))]
6231#[serde(tag = "data_type", rename_all = "snake_case")]
6232pub enum DataType {
6233    Vertica {
6234        vertica_type: Box<VerticaDataType>,
6235    },
6236    // Numeric
6237    Boolean,
6238    TinyInt {
6239        length: Option<u32>,
6240    },
6241    SmallInt {
6242        length: Option<u32>,
6243    },
6244    /// Int type with optional length. `integer_spelling` indicates whether the original
6245    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
6246    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
6247    Int {
6248        length: Option<u32>,
6249        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6250        integer_spelling: bool,
6251    },
6252    BigInt {
6253        length: Option<u32>,
6254    },
6255    /// Signed 128-bit integer (DuckDB HUGEINT, ClickHouse Int128, StarRocks LARGEINT).
6256    Int128,
6257    /// Unsigned 8-bit integer (DuckDB UTINYINT, ClickHouse UInt8).
6258    #[serde(rename = "uint8")]
6259    UInt8,
6260    /// Unsigned 16-bit integer (DuckDB USMALLINT, ClickHouse UInt16).
6261    #[serde(rename = "uint16")]
6262    UInt16,
6263    /// Unsigned 32-bit integer (DuckDB UINTEGER, ClickHouse UInt32).
6264    #[serde(rename = "uint32")]
6265    UInt32,
6266    /// Unsigned 64-bit integer (DuckDB UBIGINT, ClickHouse UInt64).
6267    #[serde(rename = "uint64")]
6268    UInt64,
6269    /// Unsigned 128-bit integer (DuckDB UHUGEINT, ClickHouse UInt128).
6270    #[serde(rename = "uint128")]
6271    UInt128,
6272    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
6273    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
6274    /// preserve the original spelling.
6275    Float {
6276        precision: Option<u32>,
6277        scale: Option<u32>,
6278        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6279        real_spelling: bool,
6280    },
6281    Double {
6282        precision: Option<u32>,
6283        scale: Option<u32>,
6284    },
6285    Decimal {
6286        precision: Option<u32>,
6287        scale: Option<u32>,
6288    },
6289    /// Structured Oracle data type retained until the target dialect is known.
6290    Oracle {
6291        oracle_type: OracleDataType,
6292    },
6293
6294    /// A HANA type whose domain or syntax is not represented by a common type.
6295    Hana {
6296        hana_type: HanaDataType,
6297    },
6298
6299    // String
6300    Char {
6301        length: Option<u32>,
6302    },
6303    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
6304    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
6305    VarChar {
6306        length: Option<u32>,
6307        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6308        parenthesized_length: bool,
6309    },
6310    /// String type with optional max length (BigQuery STRING(n))
6311    String {
6312        length: Option<u32>,
6313    },
6314    Text,
6315    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
6316    TextWithLength {
6317        length: u32,
6318    },
6319
6320    // Binary
6321    Binary {
6322        length: Option<u32>,
6323    },
6324    VarBinary {
6325        length: Option<u32>,
6326    },
6327    Blob,
6328
6329    // Bit
6330    Bit {
6331        length: Option<u32>,
6332    },
6333    VarBit {
6334        length: Option<u32>,
6335    },
6336
6337    // Date/Time
6338    Date,
6339    Time {
6340        precision: Option<u32>,
6341        #[serde(default)]
6342        timezone: bool,
6343    },
6344    Timestamp {
6345        precision: Option<u32>,
6346        timezone: bool,
6347    },
6348    Interval {
6349        unit: Option<String>,
6350        /// For range intervals like INTERVAL DAY TO HOUR
6351        #[serde(default, skip_serializing_if = "Option::is_none")]
6352        to: Option<String>,
6353    },
6354
6355    // JSON
6356    Json,
6357    JsonB,
6358
6359    // UUID
6360    Uuid,
6361
6362    // Array
6363    Array {
6364        element_type: Box<DataType>,
6365        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
6366        #[serde(default, skip_serializing_if = "Option::is_none")]
6367        dimension: Option<u32>,
6368    },
6369
6370    /// List type (Materialize): INT LIST, TEXT LIST LIST
6371    /// Uses postfix LIST syntax instead of ARRAY<T>
6372    List {
6373        element_type: Box<DataType>,
6374    },
6375
6376    // Struct/Map
6377    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
6378    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
6379    Struct {
6380        fields: Vec<StructField>,
6381        nested: bool,
6382    },
6383    Map {
6384        key_type: Box<DataType>,
6385        value_type: Box<DataType>,
6386    },
6387
6388    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
6389    Enum {
6390        values: Vec<String>,
6391        #[serde(default, skip_serializing_if = "Vec::is_empty")]
6392        assignments: Vec<Option<String>>,
6393    },
6394
6395    // Set type (MySQL): SET('a', 'b', 'c')
6396    Set {
6397        values: Vec<String>,
6398    },
6399
6400    // Union type (DuckDB): UNION(num INT, str TEXT)
6401    Union {
6402        fields: Vec<(String, DataType)>,
6403    },
6404
6405    // Vector (Snowflake / SingleStore)
6406    Vector {
6407        #[serde(default)]
6408        element_type: Option<Box<DataType>>,
6409        dimension: Option<u32>,
6410    },
6411
6412    // Object (Snowflake structured type)
6413    // fields: Vec of (field_name, field_type, not_null)
6414    Object {
6415        fields: Vec<(String, DataType, bool)>,
6416        modifier: Option<String>,
6417    },
6418
6419    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
6420    Nullable {
6421        inner: Box<DataType>,
6422    },
6423
6424    // Custom/User-defined
6425    Custom {
6426        name: String,
6427    },
6428
6429    // Spatial types
6430    Geometry {
6431        subtype: Option<String>,
6432        srid: Option<u32>,
6433    },
6434    Geography {
6435        subtype: Option<String>,
6436        srid: Option<u32>,
6437    },
6438
6439    // Character Set (for CONVERT USING in MySQL)
6440    // Renders as CHAR CHARACTER SET {name} in cast target
6441    CharacterSet {
6442        name: String,
6443    },
6444
6445    // Unknown
6446    Unknown,
6447}
6448
6449/// Source-specific HANA type, retained until a target is selected.
6450#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6451#[cfg_attr(feature = "bindings", derive(TS))]
6452pub struct HanaDataType {
6453    pub name: String,
6454    pub parameters: Vec<u32>,
6455}
6456
6457impl DataType {
6458    /// Canonical unsigned names and their bit-width aliases. Parser entry points
6459    /// and legacy Custom-type normalization share this mapping.
6460    pub(crate) fn from_unsigned_name(name: &str) -> Option<Self> {
6461        match name.to_ascii_uppercase().as_str() {
6462            "UTINYINT" | "UINT8" => Some(Self::UInt8),
6463            "USMALLINT" | "UINT16" => Some(Self::UInt16),
6464            "UINTEGER" | "UINT32" => Some(Self::UInt32),
6465            "UBIGINT" | "UINT64" => Some(Self::UInt64),
6466            "UHUGEINT" | "UINT128" => Some(Self::UInt128),
6467            _ => None,
6468        }
6469    }
6470}
6471
6472/// Array expression
6473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6474#[cfg_attr(feature = "bindings", derive(TS))]
6475#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
6476pub struct Array {
6477    pub expressions: Vec<Expression>,
6478    /// Inferred array data type from type annotation
6479    #[serde(default, skip_serializing_if = "Option::is_none")]
6480    #[ast(skip)]
6481    pub inferred_type: Option<DataType>,
6482}
6483
6484/// Struct expression
6485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6486#[cfg_attr(feature = "bindings", derive(TS))]
6487pub struct Struct {
6488    pub fields: Vec<(Option<String>, Expression)>,
6489}
6490
6491/// Tuple expression
6492#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6493#[cfg_attr(feature = "bindings", derive(TS))]
6494pub struct Tuple {
6495    pub expressions: Vec<Expression>,
6496}
6497
6498/// Interval expression
6499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6500#[cfg_attr(feature = "bindings", derive(TS))]
6501pub struct Interval {
6502    /// The value expression (e.g., '1', 5, column_ref)
6503    pub this: Option<Expression>,
6504    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
6505    pub unit: Option<IntervalUnitSpec>,
6506}
6507
6508/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
6509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6510#[cfg_attr(feature = "bindings", derive(TS))]
6511#[serde(tag = "type", rename_all = "snake_case")]
6512pub enum IntervalUnitSpec {
6513    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
6514    Simple {
6515        unit: IntervalUnit,
6516        /// Whether to use plural form (e.g., DAYS vs DAY)
6517        use_plural: bool,
6518    },
6519    /// Interval span (e.g., HOUR TO SECOND)
6520    Span(IntervalSpan),
6521    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6522    /// The start and end can be expressions like function calls with precision
6523    ExprSpan(IntervalSpanExpr),
6524    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6525    Expr(Box<Expression>),
6526}
6527
6528/// Interval span for ranges like HOUR TO SECOND
6529#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6530#[cfg_attr(feature = "bindings", derive(TS))]
6531pub struct IntervalSpan {
6532    /// Start unit (e.g., HOUR)
6533    pub this: IntervalUnit,
6534    /// End unit (e.g., SECOND)
6535    pub expression: IntervalUnit,
6536}
6537
6538/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6539/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6541#[cfg_attr(feature = "bindings", derive(TS))]
6542pub struct IntervalSpanExpr {
6543    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6544    pub this: Box<Expression>,
6545    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6546    pub expression: Box<Expression>,
6547}
6548
6549#[derive(
6550    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6551)]
6552#[cfg_attr(feature = "bindings", derive(TS))]
6553pub enum IntervalUnit {
6554    Year,
6555    Quarter,
6556    Month,
6557    Week,
6558    Day,
6559    Hour,
6560    Minute,
6561    Second,
6562    Millisecond,
6563    Microsecond,
6564    Nanosecond,
6565}
6566
6567/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6568#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6569#[cfg_attr(feature = "bindings", derive(TS))]
6570pub struct Command {
6571    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6572    pub this: String,
6573}
6574
6575/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6576/// Syntax: PREPARE name [(type, ...)] AS statement
6577#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6578#[cfg_attr(feature = "bindings", derive(TS))]
6579pub struct PrepareStatement {
6580    /// The prepared statement name.
6581    pub name: Identifier,
6582    /// Optional PostgreSQL parameter type list.
6583    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6584    pub parameter_types: Vec<DataType>,
6585    /// The statement to execute when the prepared statement is invoked.
6586    pub statement: Expression,
6587}
6588
6589/// T-SQL TRY/CATCH block.
6590#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6591#[cfg_attr(feature = "bindings", derive(TS))]
6592pub struct TryCatch {
6593    /// Statements inside BEGIN TRY ... END TRY.
6594    #[serde(default)]
6595    pub try_body: Vec<Expression>,
6596    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6597    #[serde(default, skip_serializing_if = "Option::is_none")]
6598    pub catch_body: Option<Vec<Expression>>,
6599}
6600
6601/// EXEC/EXECUTE statement (TSQL stored procedure call)
6602/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6604#[cfg_attr(feature = "bindings", derive(TS))]
6605pub struct ExecuteStatement {
6606    /// The procedure name (can be qualified: schema.proc_name)
6607    pub this: Expression,
6608    /// Optional T-SQL return-status variable (`EXECUTE @status = procedure`).
6609    #[serde(default, skip_serializing_if = "Option::is_none")]
6610    pub return_status: Option<String>,
6611    /// Named parameters: @param=value pairs
6612    #[serde(default)]
6613    pub parameters: Vec<ExecuteParameter>,
6614    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6615    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6616    pub arguments: Vec<Expression>,
6617    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6618    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6619    pub prepared: bool,
6620    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6621    #[serde(default, skip_serializing_if = "Option::is_none")]
6622    pub suffix: Option<String>,
6623}
6624
6625/// Named parameter in EXEC statement: @name=value
6626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6627#[cfg_attr(feature = "bindings", derive(TS))]
6628pub struct ExecuteParameter {
6629    /// Parameter name (including @)
6630    pub name: String,
6631    /// Parameter value
6632    pub value: Expression,
6633    /// Whether this is a positional parameter (no = sign)
6634    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6635    pub positional: bool,
6636    /// TSQL OUTPUT modifier on parameter
6637    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6638    pub output: bool,
6639}
6640
6641/// KILL statement (MySQL/MariaDB)
6642/// KILL [CONNECTION | QUERY] <id>
6643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6644#[cfg_attr(feature = "bindings", derive(TS))]
6645pub struct Kill {
6646    /// The target (process ID or connection ID)
6647    pub this: Expression,
6648    /// Optional kind: "CONNECTION" or "QUERY"
6649    pub kind: Option<String>,
6650}
6651
6652/// Snowflake CREATE TASK statement
6653#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6654#[cfg_attr(feature = "bindings", derive(TS))]
6655pub struct CreateTask {
6656    pub or_replace: bool,
6657    pub if_not_exists: bool,
6658    /// Task name (possibly qualified: db.schema.task)
6659    pub name: String,
6660    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6661    pub properties: String,
6662    /// The SQL statement body after AS
6663    pub body: Expression,
6664}
6665
6666/// Raw/unparsed SQL
6667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6668#[cfg_attr(feature = "bindings", derive(TS))]
6669pub struct Raw {
6670    pub sql: String,
6671}
6672
6673// ============================================================================
6674// Function expression types
6675// ============================================================================
6676
6677/// Generic unary function (takes a single argument)
6678#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6679#[cfg_attr(feature = "bindings", derive(TS))]
6680pub struct UnaryFunc {
6681    pub this: Expression,
6682    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6683    #[serde(skip_serializing_if = "Option::is_none", default)]
6684    pub original_name: Option<String>,
6685    /// Inferred data type from type annotation
6686    #[serde(default, skip_serializing_if = "Option::is_none")]
6687    #[ast(skip)]
6688    pub inferred_type: Option<DataType>,
6689}
6690
6691impl UnaryFunc {
6692    /// Create a new UnaryFunc with no original_name
6693    pub fn new(this: Expression) -> Self {
6694        Self {
6695            this,
6696            original_name: None,
6697            inferred_type: None,
6698        }
6699    }
6700
6701    /// Create a new UnaryFunc with an original name for round-trip preservation
6702    pub fn with_name(this: Expression, name: String) -> Self {
6703        Self {
6704            this,
6705            original_name: Some(name),
6706            inferred_type: None,
6707        }
6708    }
6709}
6710
6711/// CHAR/CHR function with multiple args and optional USING charset
6712/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6713/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6714#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6715#[cfg_attr(feature = "bindings", derive(TS))]
6716pub struct CharFunc {
6717    pub args: Vec<Expression>,
6718    #[serde(skip_serializing_if = "Option::is_none", default)]
6719    pub charset: Option<String>,
6720    /// Original function name (CHAR or CHR), defaults to CHAR
6721    #[serde(skip_serializing_if = "Option::is_none", default)]
6722    pub name: Option<String>,
6723}
6724
6725/// Generic binary function (takes two arguments)
6726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6727#[cfg_attr(feature = "bindings", derive(TS))]
6728pub struct BinaryFunc {
6729    pub this: Expression,
6730    pub expression: Expression,
6731    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6732    #[serde(skip_serializing_if = "Option::is_none", default)]
6733    pub original_name: Option<String>,
6734    /// Inferred data type from type annotation
6735    #[serde(default, skip_serializing_if = "Option::is_none")]
6736    #[ast(skip)]
6737    pub inferred_type: Option<DataType>,
6738}
6739
6740/// Variable argument function
6741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6742#[cfg_attr(feature = "bindings", derive(TS))]
6743pub struct VarArgFunc {
6744    pub expressions: Vec<Expression>,
6745    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6746    #[serde(skip_serializing_if = "Option::is_none", default)]
6747    pub original_name: Option<String>,
6748    /// Inferred data type from type annotation
6749    #[serde(default, skip_serializing_if = "Option::is_none")]
6750    #[ast(skip)]
6751    pub inferred_type: Option<DataType>,
6752}
6753
6754/// CONCAT_WS function
6755#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6756#[cfg_attr(feature = "bindings", derive(TS))]
6757pub struct ConcatWs {
6758    pub separator: Expression,
6759    pub expressions: Vec<Expression>,
6760}
6761
6762/// SUBSTRING function
6763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6764#[cfg_attr(feature = "bindings", derive(TS))]
6765pub struct SubstringFunc {
6766    pub this: Expression,
6767    pub start: Expression,
6768    pub length: Option<Expression>,
6769    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6770    #[serde(default)]
6771    pub from_for_syntax: bool,
6772}
6773
6774/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6775#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6776#[cfg_attr(feature = "bindings", derive(TS))]
6777pub struct OverlayFunc {
6778    pub this: Expression,
6779    pub replacement: Expression,
6780    pub from: Expression,
6781    pub length: Option<Expression>,
6782}
6783
6784/// TRIM function
6785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6786#[cfg_attr(feature = "bindings", derive(TS))]
6787pub struct TrimFunc {
6788    pub this: Expression,
6789    pub characters: Option<Expression>,
6790    pub position: TrimPosition,
6791    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6792    #[serde(default)]
6793    pub sql_standard_syntax: bool,
6794    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6795    #[serde(default)]
6796    pub position_explicit: bool,
6797    /// Inferred data type from type annotation
6798    #[serde(default, skip_serializing_if = "Option::is_none")]
6799    #[ast(skip)]
6800    pub inferred_type: Option<DataType>,
6801}
6802
6803#[derive(
6804    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6805)]
6806#[cfg_attr(feature = "bindings", derive(TS))]
6807pub enum TrimPosition {
6808    Both,
6809    Leading,
6810    Trailing,
6811}
6812
6813/// REPLACE function
6814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6815#[cfg_attr(feature = "bindings", derive(TS))]
6816pub struct ReplaceFunc {
6817    pub this: Expression,
6818    pub old: Expression,
6819    pub new: Expression,
6820}
6821
6822/// LEFT/RIGHT function
6823#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6824#[cfg_attr(feature = "bindings", derive(TS))]
6825pub struct LeftRightFunc {
6826    pub this: Expression,
6827    pub length: Expression,
6828}
6829
6830/// REPEAT function
6831#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6832#[cfg_attr(feature = "bindings", derive(TS))]
6833pub struct RepeatFunc {
6834    pub this: Expression,
6835    pub times: Expression,
6836}
6837
6838/// LPAD/RPAD function
6839#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6840#[cfg_attr(feature = "bindings", derive(TS))]
6841pub struct PadFunc {
6842    pub this: Expression,
6843    pub length: Expression,
6844    pub fill: Option<Expression>,
6845}
6846
6847/// SPLIT function
6848#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6849#[cfg_attr(feature = "bindings", derive(TS))]
6850pub struct SplitFunc {
6851    pub this: Expression,
6852    pub delimiter: Expression,
6853}
6854
6855/// REGEXP_LIKE function
6856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6857#[cfg_attr(feature = "bindings", derive(TS))]
6858pub struct RegexpFunc {
6859    /// Additional search boundaries and retained source semantics.
6860    #[serde(default, skip_serializing_if = "Option::is_none")]
6861    pub options: Option<RegexOptions>,
6862    pub this: Expression,
6863    pub pattern: Expression,
6864    pub flags: Option<Expression>,
6865}
6866
6867/// REGEXP_REPLACE function
6868#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6869#[cfg_attr(feature = "bindings", derive(TS))]
6870pub struct RegexpReplaceFunc {
6871    /// Additional search boundaries and retained source semantics.
6872    #[serde(default, skip_serializing_if = "Option::is_none")]
6873    pub options: Option<RegexOptions>,
6874    pub this: Expression,
6875    pub pattern: Expression,
6876    pub replacement: Expression,
6877    pub flags: Option<Expression>,
6878}
6879
6880/// REGEXP_EXTRACT function
6881#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6882#[cfg_attr(feature = "bindings", derive(TS))]
6883pub struct RegexpExtractFunc {
6884    /// Additional search boundaries and retained source semantics.
6885    #[serde(default, skip_serializing_if = "Option::is_none")]
6886    pub options: Option<RegexOptions>,
6887    pub this: Expression,
6888    pub pattern: Expression,
6889    pub group: Option<Expression>,
6890}
6891
6892/// ROUND function
6893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6894#[cfg_attr(feature = "bindings", derive(TS))]
6895pub struct RoundFunc {
6896    pub this: Expression,
6897    pub decimals: Option<Expression>,
6898}
6899
6900/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6902#[cfg_attr(feature = "bindings", derive(TS))]
6903pub struct FloorFunc {
6904    pub this: Expression,
6905    pub scale: Option<Expression>,
6906    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6907    #[serde(skip_serializing_if = "Option::is_none", default)]
6908    pub to: Option<Expression>,
6909}
6910
6911/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6913#[cfg_attr(feature = "bindings", derive(TS))]
6914pub struct CeilFunc {
6915    pub this: Expression,
6916    #[serde(skip_serializing_if = "Option::is_none", default)]
6917    pub decimals: Option<Expression>,
6918    /// Time unit for Druid-style CEIL(time TO unit) syntax
6919    #[serde(skip_serializing_if = "Option::is_none", default)]
6920    pub to: Option<Expression>,
6921}
6922
6923/// LOG function
6924#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6925#[cfg_attr(feature = "bindings", derive(TS))]
6926pub struct LogFunc {
6927    pub this: Expression,
6928    pub base: Option<Expression>,
6929}
6930
6931/// CURRENT_DATE (no arguments)
6932#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6933#[cfg_attr(feature = "bindings", derive(TS))]
6934pub struct CurrentDate;
6935
6936/// CURRENT_TIME
6937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6938#[cfg_attr(feature = "bindings", derive(TS))]
6939pub struct CurrentTime {
6940    pub precision: Option<u32>,
6941}
6942
6943/// CURRENT_TIMESTAMP
6944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6945#[cfg_attr(feature = "bindings", derive(TS))]
6946pub struct CurrentTimestamp {
6947    pub precision: Option<u32>,
6948    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6949    #[serde(default)]
6950    pub sysdate: bool,
6951}
6952
6953/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6955#[cfg_attr(feature = "bindings", derive(TS))]
6956pub struct CurrentTimestampLTZ {
6957    pub precision: Option<u32>,
6958}
6959
6960/// AT TIME ZONE expression for timezone conversion
6961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6962#[cfg_attr(feature = "bindings", derive(TS))]
6963pub struct AtTimeZone {
6964    /// The expression to convert
6965    pub this: Expression,
6966    /// The target timezone
6967    pub zone: Expression,
6968}
6969
6970/// DATE_ADD / DATE_SUB function
6971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6972#[cfg_attr(feature = "bindings", derive(TS))]
6973pub struct DateAddFunc {
6974    pub this: Expression,
6975    pub interval: Expression,
6976    pub unit: IntervalUnit,
6977}
6978
6979/// DATEDIFF function
6980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6981#[cfg_attr(feature = "bindings", derive(TS))]
6982pub struct DateDiffFunc {
6983    pub this: Expression,
6984    pub expression: Expression,
6985    pub unit: Option<IntervalUnit>,
6986}
6987
6988/// DATE_TRUNC function
6989#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6990#[cfg_attr(feature = "bindings", derive(TS))]
6991pub struct DateTruncFunc {
6992    pub this: Expression,
6993    pub unit: DateTimeField,
6994}
6995
6996/// EXTRACT function
6997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6998#[cfg_attr(feature = "bindings", derive(TS))]
6999pub struct ExtractFunc {
7000    pub this: Expression,
7001    pub field: DateTimeField,
7002}
7003
7004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7005#[cfg_attr(feature = "bindings", derive(TS))]
7006pub enum DateTimeField {
7007    Year,
7008    Month,
7009    Day,
7010    Hour,
7011    Minute,
7012    Second,
7013    Millisecond,
7014    Microsecond,
7015    DayOfWeek,
7016    DayOfYear,
7017    Week,
7018    /// Week with a modifier like WEEK(monday), WEEK(sunday)
7019    WeekWithModifier(String),
7020    Quarter,
7021    Epoch,
7022    Timezone,
7023    TimezoneHour,
7024    TimezoneMinute,
7025    Date,
7026    Time,
7027    /// Custom datetime field for dialect-specific or arbitrary fields
7028    Custom(String),
7029}
7030
7031/// TO_DATE function
7032#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7033#[cfg_attr(feature = "bindings", derive(TS))]
7034pub struct ToDateFunc {
7035    pub this: Expression,
7036    pub format: Option<Expression>,
7037}
7038
7039/// TO_TIMESTAMP function
7040#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7041#[cfg_attr(feature = "bindings", derive(TS))]
7042pub struct ToTimestampFunc {
7043    pub this: Expression,
7044    pub format: Option<Expression>,
7045}
7046
7047/// IF function
7048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7049#[cfg_attr(feature = "bindings", derive(TS))]
7050pub struct IfFunc {
7051    pub condition: Expression,
7052    pub true_value: Expression,
7053    pub false_value: Option<Expression>,
7054    /// Original function name (IF, IFF, IIF) for round-trip preservation
7055    #[serde(skip_serializing_if = "Option::is_none", default)]
7056    pub original_name: Option<String>,
7057    /// Inferred data type from type annotation
7058    #[serde(default, skip_serializing_if = "Option::is_none")]
7059    #[ast(skip)]
7060    pub inferred_type: Option<DataType>,
7061}
7062
7063/// NVL2 function
7064#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7065#[cfg_attr(feature = "bindings", derive(TS))]
7066pub struct Nvl2Func {
7067    pub this: Expression,
7068    pub true_value: Expression,
7069    pub false_value: Expression,
7070    /// Inferred data type from type annotation
7071    #[serde(default, skip_serializing_if = "Option::is_none")]
7072    #[ast(skip)]
7073    pub inferred_type: Option<DataType>,
7074}
7075
7076// ============================================================================
7077// Typed Aggregate Function types
7078// ============================================================================
7079
7080/// Generic aggregate function base type
7081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7082#[cfg_attr(feature = "bindings", derive(TS))]
7083pub struct AggFunc {
7084    pub this: Expression,
7085    pub distinct: bool,
7086    pub filter: Option<Expression>,
7087    pub order_by: Vec<Ordered>,
7088    /// Original function name (case-preserving) when parsed from SQL
7089    #[serde(skip_serializing_if = "Option::is_none", default)]
7090    pub name: Option<String>,
7091    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
7092    #[serde(skip_serializing_if = "Option::is_none", default)]
7093    pub ignore_nulls: Option<bool>,
7094    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
7095    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
7096    #[serde(skip_serializing_if = "Option::is_none", default)]
7097    pub having_max: Option<(Box<Expression>, bool)>,
7098    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
7099    #[serde(skip_serializing_if = "Option::is_none", default)]
7100    pub limit: Option<Box<Expression>>,
7101    /// Inferred data type from type annotation
7102    #[serde(default, skip_serializing_if = "Option::is_none")]
7103    #[ast(skip)]
7104    pub inferred_type: Option<DataType>,
7105}
7106
7107/// COUNT function with optional star
7108#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7109#[cfg_attr(feature = "bindings", derive(TS))]
7110pub struct CountFunc {
7111    pub this: Option<Expression>,
7112    pub star: bool,
7113    pub distinct: bool,
7114    pub filter: Option<Expression>,
7115    /// IGNORE NULLS (true) or RESPECT NULLS (false)
7116    #[serde(default, skip_serializing_if = "Option::is_none")]
7117    pub ignore_nulls: Option<bool>,
7118    /// Original function name for case preservation (e.g., "count" or "COUNT")
7119    #[serde(default, skip_serializing_if = "Option::is_none")]
7120    pub original_name: Option<String>,
7121    /// Inferred data type from type annotation
7122    #[serde(default, skip_serializing_if = "Option::is_none")]
7123    #[ast(skip)]
7124    pub inferred_type: Option<DataType>,
7125}
7126
7127/// GROUP_CONCAT function (MySQL style)
7128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7129#[cfg_attr(feature = "bindings", derive(TS))]
7130pub struct GroupConcatFunc {
7131    pub this: Expression,
7132    pub separator: Option<Expression>,
7133    pub order_by: Option<Vec<Ordered>>,
7134    pub distinct: bool,
7135    pub filter: Option<Expression>,
7136    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
7137    #[serde(default, skip_serializing_if = "Option::is_none")]
7138    pub limit: Option<Box<Expression>>,
7139    /// Inferred data type from type annotation
7140    #[serde(default, skip_serializing_if = "Option::is_none")]
7141    #[ast(skip)]
7142    pub inferred_type: Option<DataType>,
7143}
7144
7145/// STRING_AGG function (PostgreSQL/Standard SQL)
7146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7147#[cfg_attr(feature = "bindings", derive(TS))]
7148pub struct StringAggFunc {
7149    pub this: Expression,
7150    #[serde(default)]
7151    pub separator: Option<Expression>,
7152    #[serde(default)]
7153    pub order_by: Option<Vec<Ordered>>,
7154    #[serde(default)]
7155    pub distinct: bool,
7156    #[serde(default)]
7157    pub filter: Option<Expression>,
7158    /// BigQuery LIMIT inside STRING_AGG
7159    #[serde(default, skip_serializing_if = "Option::is_none")]
7160    pub limit: Option<Box<Expression>>,
7161    /// Inferred data type from type annotation
7162    #[serde(default, skip_serializing_if = "Option::is_none")]
7163    #[ast(skip)]
7164    pub inferred_type: Option<DataType>,
7165}
7166
7167/// LISTAGG function (Oracle style)
7168#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7169#[cfg_attr(feature = "bindings", derive(TS))]
7170pub struct ListAggFunc {
7171    /// Retain source byte-limit and overflow semantics through AST generation.
7172    #[serde(default, skip_serializing_if = "Option::is_none")]
7173    #[ast(skip)]
7174    pub source_dialect: Option<crate::dialects::DialectType>,
7175    pub this: Expression,
7176    pub separator: Option<Expression>,
7177    pub on_overflow: Option<ListAggOverflow>,
7178    /// Vertica `USING PARAMETERS max_length = n`
7179    #[serde(default, skip_serializing_if = "Option::is_none")]
7180    pub max_length: Option<Box<Expression>>,
7181    pub order_by: Option<Vec<Ordered>>,
7182    pub distinct: bool,
7183    pub filter: Option<Expression>,
7184    /// Inferred data type from type annotation
7185    #[serde(default, skip_serializing_if = "Option::is_none")]
7186    #[ast(skip)]
7187    pub inferred_type: Option<DataType>,
7188}
7189
7190/// LISTAGG ON OVERFLOW behavior
7191#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7192#[cfg_attr(feature = "bindings", derive(TS))]
7193pub enum ListAggOverflow {
7194    Error,
7195    Truncate {
7196        filler: Option<Expression>,
7197        with_count: bool,
7198    },
7199}
7200
7201/// SUM_IF / COUNT_IF function
7202#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7203#[cfg_attr(feature = "bindings", derive(TS))]
7204pub struct SumIfFunc {
7205    pub this: Expression,
7206    pub condition: Expression,
7207    pub filter: Option<Expression>,
7208    /// Inferred data type from type annotation
7209    #[serde(default, skip_serializing_if = "Option::is_none")]
7210    #[ast(skip)]
7211    pub inferred_type: Option<DataType>,
7212}
7213
7214/// APPROX_PERCENTILE function
7215#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7216#[cfg_attr(feature = "bindings", derive(TS))]
7217pub struct ApproxPercentileFunc {
7218    pub this: Expression,
7219    pub percentile: Expression,
7220    pub accuracy: Option<Expression>,
7221    pub filter: Option<Expression>,
7222}
7223
7224/// PERCENTILE_CONT / PERCENTILE_DISC function
7225#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7226#[cfg_attr(feature = "bindings", derive(TS))]
7227pub struct PercentileFunc {
7228    pub this: Expression,
7229    pub percentile: Expression,
7230    pub order_by: Option<Vec<Ordered>>,
7231    pub filter: Option<Expression>,
7232}
7233
7234// ============================================================================
7235// Typed Window Function types
7236// ============================================================================
7237
7238/// ROW_NUMBER function (no arguments)
7239#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7240#[cfg_attr(feature = "bindings", derive(TS))]
7241pub struct RowNumber;
7242
7243/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7244#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7245#[cfg_attr(feature = "bindings", derive(TS))]
7246pub struct Rank {
7247    /// DuckDB: RANK(ORDER BY col) - order by inside function
7248    #[serde(default, skip_serializing_if = "Option::is_none")]
7249    pub order_by: Option<Vec<Ordered>>,
7250    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7251    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7252    pub args: Vec<Expression>,
7253}
7254
7255/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
7256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7257#[cfg_attr(feature = "bindings", derive(TS))]
7258pub struct DenseRank {
7259    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7260    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7261    pub args: Vec<Expression>,
7262}
7263
7264/// NTILE function (DuckDB allows ORDER BY inside)
7265#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7266#[cfg_attr(feature = "bindings", derive(TS))]
7267pub struct NTileFunc {
7268    /// num_buckets is optional to support Databricks NTILE() without arguments
7269    #[serde(default, skip_serializing_if = "Option::is_none")]
7270    pub num_buckets: Option<Expression>,
7271    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
7272    #[serde(default, skip_serializing_if = "Option::is_none")]
7273    pub order_by: Option<Vec<Ordered>>,
7274}
7275
7276/// LEAD / LAG function
7277#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7278#[cfg_attr(feature = "bindings", derive(TS))]
7279pub struct LeadLagFunc {
7280    pub this: Expression,
7281    pub offset: Option<Expression>,
7282    pub default: Option<Expression>,
7283    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7284    #[serde(default, skip_serializing_if = "Option::is_none")]
7285    pub ignore_nulls: Option<bool>,
7286}
7287
7288/// FIRST_VALUE / LAST_VALUE function
7289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7290#[cfg_attr(feature = "bindings", derive(TS))]
7291pub struct ValueFunc {
7292    pub this: Expression,
7293    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7294    #[serde(default, skip_serializing_if = "Option::is_none")]
7295    pub ignore_nulls: Option<bool>,
7296    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
7297    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7298    pub order_by: Vec<Ordered>,
7299}
7300
7301/// NTH_VALUE function
7302#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7303#[cfg_attr(feature = "bindings", derive(TS))]
7304pub struct NthValueFunc {
7305    pub this: Expression,
7306    pub offset: Expression,
7307    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7308    #[serde(default, skip_serializing_if = "Option::is_none")]
7309    pub ignore_nulls: Option<bool>,
7310    /// Snowflake FROM FIRST / FROM LAST clause
7311    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
7312    #[serde(default, skip_serializing_if = "Option::is_none")]
7313    pub from_first: Option<bool>,
7314}
7315
7316/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7317#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7318#[cfg_attr(feature = "bindings", derive(TS))]
7319pub struct PercentRank {
7320    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
7321    #[serde(default, skip_serializing_if = "Option::is_none")]
7322    pub order_by: Option<Vec<Ordered>>,
7323    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7324    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7325    pub args: Vec<Expression>,
7326}
7327
7328/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7329#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7330#[cfg_attr(feature = "bindings", derive(TS))]
7331pub struct CumeDist {
7332    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
7333    #[serde(default, skip_serializing_if = "Option::is_none")]
7334    pub order_by: Option<Vec<Ordered>>,
7335    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7336    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7337    pub args: Vec<Expression>,
7338}
7339
7340// ============================================================================
7341// Additional String Function types
7342// ============================================================================
7343
7344/// POSITION/INSTR function
7345#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7346#[cfg_attr(feature = "bindings", derive(TS))]
7347pub struct PositionFunc {
7348    pub substring: Expression,
7349    pub string: Expression,
7350    pub start: Option<Expression>,
7351}
7352
7353// ============================================================================
7354// Additional Math Function types
7355// ============================================================================
7356
7357/// RANDOM function (no arguments)
7358#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7359#[cfg_attr(feature = "bindings", derive(TS))]
7360pub struct Random;
7361
7362/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
7363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7364#[cfg_attr(feature = "bindings", derive(TS))]
7365pub struct Rand {
7366    pub seed: Option<Box<Expression>>,
7367    /// Teradata RANDOM lower bound
7368    #[serde(default)]
7369    pub lower: Option<Box<Expression>>,
7370    /// Teradata RANDOM upper bound
7371    #[serde(default)]
7372    pub upper: Option<Box<Expression>>,
7373}
7374
7375/// TRUNCATE / TRUNC function
7376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7377#[cfg_attr(feature = "bindings", derive(TS))]
7378pub struct TruncateFunc {
7379    pub this: Expression,
7380    pub decimals: Option<Expression>,
7381}
7382
7383/// PI function (no arguments)
7384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7385#[cfg_attr(feature = "bindings", derive(TS))]
7386pub struct Pi;
7387
7388// ============================================================================
7389// Control Flow Function types
7390// ============================================================================
7391
7392/// DECODE function (Oracle style)
7393#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7394#[cfg_attr(feature = "bindings", derive(TS))]
7395pub struct DecodeFunc {
7396    pub this: Expression,
7397    pub search_results: Vec<(Expression, Expression)>,
7398    pub default: Option<Expression>,
7399}
7400
7401// ============================================================================
7402// Additional Date/Time Function types
7403// ============================================================================
7404
7405/// DATE_FORMAT / FORMAT_DATE function
7406#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7407#[cfg_attr(feature = "bindings", derive(TS))]
7408pub struct DateFormatFunc {
7409    pub this: Expression,
7410    pub format: Expression,
7411}
7412
7413/// FROM_UNIXTIME function
7414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7415#[cfg_attr(feature = "bindings", derive(TS))]
7416pub struct FromUnixtimeFunc {
7417    pub this: Expression,
7418    pub format: Option<Expression>,
7419}
7420
7421/// UNIX_TIMESTAMP function
7422#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7423#[cfg_attr(feature = "bindings", derive(TS))]
7424pub struct UnixTimestampFunc {
7425    pub this: Option<Expression>,
7426    pub format: Option<Expression>,
7427}
7428
7429/// MAKE_DATE function
7430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7431#[cfg_attr(feature = "bindings", derive(TS))]
7432pub struct MakeDateFunc {
7433    pub year: Expression,
7434    pub month: Expression,
7435    pub day: Expression,
7436}
7437
7438/// MAKE_TIMESTAMP function
7439#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7440#[cfg_attr(feature = "bindings", derive(TS))]
7441pub struct MakeTimestampFunc {
7442    pub year: Expression,
7443    pub month: Expression,
7444    pub day: Expression,
7445    pub hour: Expression,
7446    pub minute: Expression,
7447    pub second: Expression,
7448    pub timezone: Option<Expression>,
7449}
7450
7451/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
7452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7453#[cfg_attr(feature = "bindings", derive(TS))]
7454pub struct LastDayFunc {
7455    pub this: Expression,
7456    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
7457    #[serde(skip_serializing_if = "Option::is_none", default)]
7458    pub unit: Option<DateTimeField>,
7459}
7460
7461// ============================================================================
7462// Array Function types
7463// ============================================================================
7464
7465/// ARRAY constructor
7466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7467#[cfg_attr(feature = "bindings", derive(TS))]
7468pub struct ArrayConstructor {
7469    pub expressions: Vec<Expression>,
7470    pub bracket_notation: bool,
7471    /// True if LIST keyword was used instead of ARRAY (DuckDB)
7472    pub use_list_keyword: bool,
7473    /// Inferred array data type from type annotation
7474    #[serde(default, skip_serializing_if = "Option::is_none")]
7475    #[ast(skip)]
7476    pub inferred_type: Option<DataType>,
7477}
7478
7479/// ARRAY_SORT function
7480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7481#[cfg_attr(feature = "bindings", derive(TS))]
7482pub struct ArraySortFunc {
7483    pub this: Expression,
7484    pub comparator: Option<Expression>,
7485    pub desc: bool,
7486    pub nulls_first: Option<bool>,
7487}
7488
7489/// ARRAY_JOIN / ARRAY_TO_STRING function
7490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7491#[cfg_attr(feature = "bindings", derive(TS))]
7492pub struct ArrayJoinFunc {
7493    pub this: Expression,
7494    pub separator: Expression,
7495    pub null_replacement: Option<Expression>,
7496}
7497
7498/// UNNEST function
7499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7500#[cfg_attr(feature = "bindings", derive(TS))]
7501pub struct UnnestFunc {
7502    pub this: Expression,
7503    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
7504    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7505    pub expressions: Vec<Expression>,
7506    pub with_ordinality: bool,
7507    pub alias: Option<Identifier>,
7508    /// BigQuery: offset alias for WITH OFFSET AS <name>
7509    #[serde(default, skip_serializing_if = "Option::is_none")]
7510    pub offset_alias: Option<Identifier>,
7511    /// Inferred type of the first UNNEST output column.
7512    #[serde(default, skip_serializing_if = "Option::is_none")]
7513    #[ast(skip)]
7514    pub inferred_type: Option<DataType>,
7515}
7516
7517/// ARRAY_FILTER function (with lambda)
7518#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7519#[cfg_attr(feature = "bindings", derive(TS))]
7520pub struct ArrayFilterFunc {
7521    pub this: Expression,
7522    pub filter: Expression,
7523}
7524
7525/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
7526#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7527#[cfg_attr(feature = "bindings", derive(TS))]
7528pub struct ArrayTransformFunc {
7529    pub this: Expression,
7530    pub transform: Expression,
7531}
7532
7533/// SEQUENCE / GENERATE_SERIES function
7534#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7535#[cfg_attr(feature = "bindings", derive(TS))]
7536pub struct SequenceFunc {
7537    pub start: Expression,
7538    pub stop: Expression,
7539    pub step: Option<Expression>,
7540}
7541
7542// ============================================================================
7543// Struct Function types
7544// ============================================================================
7545
7546/// STRUCT constructor
7547#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7548#[cfg_attr(feature = "bindings", derive(TS))]
7549pub struct StructConstructor {
7550    pub fields: Vec<(Option<Identifier>, Expression)>,
7551}
7552
7553/// STRUCT_EXTRACT function
7554#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7555#[cfg_attr(feature = "bindings", derive(TS))]
7556pub struct StructExtractFunc {
7557    pub this: Expression,
7558    pub field: Identifier,
7559}
7560
7561/// NAMED_STRUCT function
7562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7563#[cfg_attr(feature = "bindings", derive(TS))]
7564pub struct NamedStructFunc {
7565    pub pairs: Vec<(Expression, Expression)>,
7566}
7567
7568// ============================================================================
7569// Map Function types
7570// ============================================================================
7571
7572/// MAP constructor
7573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7574#[cfg_attr(feature = "bindings", derive(TS))]
7575pub struct MapConstructor {
7576    pub keys: Vec<Expression>,
7577    pub values: Vec<Expression>,
7578    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7579    #[serde(default)]
7580    pub curly_brace_syntax: bool,
7581    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7582    #[serde(default)]
7583    pub with_map_keyword: bool,
7584}
7585
7586/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7587#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7588#[cfg_attr(feature = "bindings", derive(TS))]
7589pub struct TransformFunc {
7590    pub this: Expression,
7591    pub transform: Expression,
7592}
7593
7594/// Function call with EMITS clause (Exasol)
7595/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7597#[cfg_attr(feature = "bindings", derive(TS))]
7598pub struct FunctionEmits {
7599    /// The function call expression
7600    pub this: Expression,
7601    /// The EMITS schema definition
7602    pub emits: Expression,
7603}
7604
7605// ============================================================================
7606// JSON Function types
7607// ============================================================================
7608
7609/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7610#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7611#[cfg_attr(feature = "bindings", derive(TS))]
7612pub struct JsonExtractFunc {
7613    #[serde(default, skip_serializing_if = "Option::is_none")]
7614    #[ast(skip)]
7615    pub source_dialect: Option<crate::dialects::DialectType>,
7616    /// Structured SQL/JSON wrapper and error/empty behavior.
7617    #[serde(default, skip_serializing_if = "Option::is_none")]
7618    pub options: Option<JsonOptions>,
7619
7620    pub this: Expression,
7621    pub path: Expression,
7622    pub returning: Option<DataType>,
7623    /// True if parsed from -> or ->> operator syntax
7624    #[serde(default)]
7625    pub arrow_syntax: bool,
7626    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7627    #[serde(default)]
7628    pub hash_arrow_syntax: bool,
7629    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7630    #[serde(default)]
7631    pub wrapper_option: Option<String>,
7632    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7633    #[serde(default)]
7634    pub quotes_option: Option<String>,
7635    /// ON SCALAR STRING flag
7636    #[serde(default)]
7637    pub on_scalar_string: bool,
7638    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7639    #[serde(default)]
7640    pub on_error: Option<String>,
7641}
7642
7643/// JSON path extraction
7644#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7645#[cfg_attr(feature = "bindings", derive(TS))]
7646pub struct JsonPathFunc {
7647    pub this: Expression,
7648    pub paths: Vec<Expression>,
7649}
7650
7651/// JSON_OBJECT function
7652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7653#[cfg_attr(feature = "bindings", derive(TS))]
7654pub struct JsonObjectFunc {
7655    pub pairs: Vec<(Expression, Expression)>,
7656    pub null_handling: Option<JsonNullHandling>,
7657    #[serde(default)]
7658    pub with_unique_keys: bool,
7659    #[serde(default)]
7660    pub returning_type: Option<DataType>,
7661    #[serde(default)]
7662    pub format_json: bool,
7663    #[serde(default)]
7664    pub encoding: Option<String>,
7665    /// For JSON_OBJECT(*) syntax
7666    #[serde(default)]
7667    pub star: bool,
7668}
7669
7670/// JSON null handling options
7671#[derive(
7672    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7673)]
7674#[cfg_attr(feature = "bindings", derive(TS))]
7675pub enum JsonNullHandling {
7676    NullOnNull,
7677    AbsentOnNull,
7678}
7679
7680/// JSON_SET / JSON_INSERT function
7681#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7682#[cfg_attr(feature = "bindings", derive(TS))]
7683pub struct JsonModifyFunc {
7684    pub this: Expression,
7685    pub path_values: Vec<(Expression, Expression)>,
7686}
7687
7688/// JSON_ARRAYAGG function
7689#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7690#[cfg_attr(feature = "bindings", derive(TS))]
7691pub struct JsonArrayAggFunc {
7692    pub this: Expression,
7693    pub order_by: Option<Vec<Ordered>>,
7694    pub null_handling: Option<JsonNullHandling>,
7695    pub filter: Option<Expression>,
7696}
7697
7698/// JSON_OBJECTAGG function
7699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7700#[cfg_attr(feature = "bindings", derive(TS))]
7701pub struct JsonObjectAggFunc {
7702    pub key: Expression,
7703    pub value: Expression,
7704    pub null_handling: Option<JsonNullHandling>,
7705    pub filter: Option<Expression>,
7706}
7707
7708// ============================================================================
7709// Type Casting Function types
7710// ============================================================================
7711
7712/// CONVERT function (SQL Server style)
7713#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7714#[cfg_attr(feature = "bindings", derive(TS))]
7715pub struct ConvertFunc {
7716    pub this: Expression,
7717    pub to: DataType,
7718    pub style: Option<Expression>,
7719}
7720
7721// ============================================================================
7722// Additional Expression types
7723// ============================================================================
7724
7725/// Lambda expression
7726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7727#[cfg_attr(feature = "bindings", derive(TS))]
7728pub struct LambdaExpr {
7729    pub parameters: Vec<Identifier>,
7730    pub body: Expression,
7731    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7732    #[serde(default)]
7733    pub colon: bool,
7734    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7735    /// Maps parameter index to data type
7736    #[serde(default)]
7737    pub parameter_types: Vec<Option<DataType>>,
7738}
7739
7740/// Parameter (parameterized queries)
7741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7742#[cfg_attr(feature = "bindings", derive(TS))]
7743pub struct Parameter {
7744    pub name: Option<String>,
7745    pub index: Option<u32>,
7746    pub style: ParameterStyle,
7747    /// Whether the name was quoted (e.g., @"x" vs @x)
7748    #[serde(default)]
7749    pub quoted: bool,
7750    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7751    #[serde(default)]
7752    pub string_quoted: bool,
7753    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7754    #[serde(default)]
7755    pub expression: Option<String>,
7756}
7757
7758/// Parameter placeholder styles
7759#[derive(
7760    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7761)]
7762#[cfg_attr(feature = "bindings", derive(TS))]
7763pub enum ParameterStyle {
7764    Question,     // ?
7765    Dollar,       // $1, $2
7766    DollarBrace,  // ${name} (Databricks, Hive template variables)
7767    Brace,        // {name} (Spark/Databricks widget/template variables)
7768    Colon,        // :name
7769    At,           // @name
7770    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7771    DoubleDollar, // $$name
7772    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7773}
7774
7775/// Placeholder expression
7776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7777#[cfg_attr(feature = "bindings", derive(TS))]
7778pub struct Placeholder {
7779    pub index: Option<u32>,
7780}
7781
7782/// Named argument in function call: name => value or name := value
7783#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7784#[cfg_attr(feature = "bindings", derive(TS))]
7785pub struct NamedArgument {
7786    pub name: Identifier,
7787    pub value: Expression,
7788    /// The separator used: `=>`, `:=`, or `=`
7789    pub separator: NamedArgSeparator,
7790}
7791
7792/// Separator style for named arguments
7793#[derive(
7794    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7795)]
7796#[cfg_attr(feature = "bindings", derive(TS))]
7797pub enum NamedArgSeparator {
7798    /// `=>` (standard SQL, Snowflake, BigQuery)
7799    DArrow,
7800    /// `:=` (Oracle, MySQL)
7801    ColonEq,
7802    /// `=` (simple equals, some dialects)
7803    Eq,
7804}
7805
7806/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7807/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7809#[cfg_attr(feature = "bindings", derive(TS))]
7810pub struct TableArgument {
7811    /// The keyword prefix: "TABLE" or "MODEL"
7812    pub prefix: String,
7813    /// The table/model reference expression
7814    pub this: Expression,
7815}
7816
7817/// SQL Comment preservation
7818#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7819#[cfg_attr(feature = "bindings", derive(TS))]
7820pub struct SqlComment {
7821    pub text: String,
7822    pub is_block: bool,
7823}
7824
7825// ============================================================================
7826// Additional Predicate types
7827// ============================================================================
7828
7829/// SIMILAR TO expression
7830#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7831#[cfg_attr(feature = "bindings", derive(TS))]
7832pub struct SimilarToExpr {
7833    pub this: Expression,
7834    pub pattern: Expression,
7835    pub escape: Option<Expression>,
7836    pub not: bool,
7837}
7838
7839/// ANY / ALL quantified expression
7840#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7841#[cfg_attr(feature = "bindings", derive(TS))]
7842pub struct QuantifiedExpr {
7843    pub this: Expression,
7844    pub subquery: Expression,
7845    pub op: Option<QuantifiedOp>,
7846}
7847
7848/// Comparison operator for quantified expressions
7849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7850#[cfg_attr(feature = "bindings", derive(TS))]
7851pub enum QuantifiedOp {
7852    Eq,
7853    Neq,
7854    Lt,
7855    Lte,
7856    Gt,
7857    Gte,
7858}
7859
7860/// OVERLAPS expression
7861/// Supports two forms:
7862/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7863/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7865#[cfg_attr(feature = "bindings", derive(TS))]
7866pub struct OverlapsExpr {
7867    /// Left operand for simple binary form
7868    #[serde(skip_serializing_if = "Option::is_none")]
7869    pub this: Option<Expression>,
7870    /// Right operand for simple binary form
7871    #[serde(skip_serializing_if = "Option::is_none")]
7872    pub expression: Option<Expression>,
7873    /// Left range start for full ANSI form
7874    #[serde(skip_serializing_if = "Option::is_none")]
7875    pub left_start: Option<Expression>,
7876    /// Left range end for full ANSI form
7877    #[serde(skip_serializing_if = "Option::is_none")]
7878    pub left_end: Option<Expression>,
7879    /// Right range start for full ANSI form
7880    #[serde(skip_serializing_if = "Option::is_none")]
7881    pub right_start: Option<Expression>,
7882    /// Right range end for full ANSI form
7883    #[serde(skip_serializing_if = "Option::is_none")]
7884    pub right_end: Option<Expression>,
7885}
7886
7887// ============================================================================
7888// Array/Struct/Map access
7889// ============================================================================
7890
7891/// Subscript access (array[index] or map[key])
7892#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7893#[cfg_attr(feature = "bindings", derive(TS))]
7894pub struct Subscript {
7895    pub this: Expression,
7896    pub index: Expression,
7897}
7898
7899/// Dot access (struct.field)
7900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7901#[cfg_attr(feature = "bindings", derive(TS))]
7902pub struct DotAccess {
7903    pub this: Expression,
7904    pub field: Identifier,
7905    #[serde(default, skip_serializing_if = "Option::is_none")]
7906    pub inferred_type: Option<DataType>,
7907}
7908
7909/// Method call (expr.method(args))
7910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7911#[cfg_attr(feature = "bindings", derive(TS))]
7912pub struct MethodCall {
7913    pub this: Expression,
7914    pub method: Identifier,
7915    pub args: Vec<Expression>,
7916}
7917
7918/// Array slice (array[start:end])
7919#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7920#[cfg_attr(feature = "bindings", derive(TS))]
7921pub struct ArraySlice {
7922    pub this: Expression,
7923    pub start: Option<Expression>,
7924    pub end: Option<Expression>,
7925}
7926
7927// ============================================================================
7928// DDL (Data Definition Language) Statements
7929// ============================================================================
7930
7931/// ON COMMIT behavior for temporary tables
7932#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7933#[cfg_attr(feature = "bindings", derive(TS))]
7934pub enum OnCommit {
7935    /// ON COMMIT PRESERVE ROWS
7936    PreserveRows,
7937    /// ON COMMIT DELETE ROWS
7938    DeleteRows,
7939}
7940
7941/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
7942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7943#[cfg_attr(feature = "bindings", derive(TS))]
7944pub struct TiDBAutoRandom {
7945    #[serde(default, skip_serializing_if = "Option::is_none")]
7946    pub shard_bits: Option<u64>,
7947    #[serde(default, skip_serializing_if = "Option::is_none")]
7948    pub range_bits: Option<u64>,
7949    /// Whether the attribute was wrapped in a TiDB executable comment.
7950    #[serde(default)]
7951    pub executable_comment: bool,
7952}
7953
7954/// A TiDB-specific table option and its source syntax.
7955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7956#[cfg_attr(feature = "bindings", derive(TS))]
7957pub struct TiDBTableOption {
7958    pub kind: TiDBTableOptionKind,
7959    /// Whether the option was wrapped in a TiDB executable comment.
7960    #[serde(default)]
7961    pub executable_comment: bool,
7962}
7963
7964/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
7965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7966#[cfg_attr(feature = "bindings", derive(TS))]
7967#[serde(tag = "type", rename_all = "snake_case")]
7968pub enum TiDBTableOptionKind {
7969    ShardRowIdBits {
7970        bits: u64,
7971    },
7972    PreSplitRegions {
7973        regions: u64,
7974    },
7975    AutoRandomBase {
7976        value: u64,
7977    },
7978    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
7979    PlacementPolicy {
7980        policy: Option<Identifier>,
7981    },
7982    Ttl {
7983        column: Identifier,
7984        interval: Interval,
7985        #[serde(default, skip_serializing_if = "Option::is_none")]
7986        enabled: Option<bool>,
7987    },
7988    TtlEnable {
7989        enabled: bool,
7990    },
7991    TtlJobInterval {
7992        interval: String,
7993    },
7994}
7995
7996/// CREATE TABLE statement
7997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7998#[cfg_attr(feature = "bindings", derive(TS))]
7999pub struct CreateTable {
8000    pub name: TableRef,
8001    /// ClickHouse: ON CLUSTER clause for distributed DDL
8002    #[serde(default, skip_serializing_if = "Option::is_none")]
8003    pub on_cluster: Option<OnCluster>,
8004    pub columns: Vec<ColumnDef>,
8005    pub constraints: Vec<TableConstraint>,
8006    pub if_not_exists: bool,
8007    pub temporary: bool,
8008    pub or_replace: bool,
8009    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
8010    #[serde(default, skip_serializing_if = "Option::is_none")]
8011    pub table_modifier: Option<String>,
8012    /// Dialect whose call semantics must be retained through independent generation.
8013    #[serde(default, skip_serializing_if = "Option::is_none")]
8014    #[ast(skip)]
8015    pub source_dialect: Option<crate::dialects::DialectType>,
8016
8017    pub as_select: Option<Expression>,
8018    /// Whether the AS SELECT was wrapped in parentheses
8019    #[serde(default)]
8020    pub as_select_parenthesized: bool,
8021    /// ON COMMIT behavior for temporary tables
8022    #[serde(default)]
8023    pub on_commit: Option<OnCommit>,
8024    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
8025    #[serde(default)]
8026    pub clone_source: Option<TableRef>,
8027    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
8028    #[serde(default, skip_serializing_if = "Option::is_none")]
8029    pub clone_at_clause: Option<Expression>,
8030    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
8031    #[serde(default)]
8032    pub is_copy: bool,
8033    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
8034    #[serde(default)]
8035    pub shallow_clone: bool,
8036    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
8037    #[serde(default)]
8038    pub deep_clone: bool,
8039    /// Leading comments before the statement
8040    #[serde(default)]
8041    pub leading_comments: Vec<String>,
8042    /// WITH properties (e.g., WITH (FORMAT='parquet'))
8043    #[serde(default)]
8044    pub with_properties: Vec<(String, String)>,
8045    /// Teradata: table options after name before columns (comma-separated)
8046    #[serde(default)]
8047    pub teradata_post_name_options: Vec<String>,
8048    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
8049    #[serde(default)]
8050    pub with_data: Option<bool>,
8051    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
8052    #[serde(default)]
8053    pub with_statistics: Option<bool>,
8054    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
8055    #[serde(default)]
8056    pub teradata_indexes: Vec<TeradataIndex>,
8057    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
8058    #[serde(default)]
8059    pub with_cte: Option<With>,
8060    /// Table properties like DEFAULT COLLATE (BigQuery)
8061    #[serde(default)]
8062    pub properties: Vec<Expression>,
8063    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
8064    #[serde(default, skip_serializing_if = "Option::is_none")]
8065    pub partition_of: Option<Expression>,
8066    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
8067    #[serde(default)]
8068    pub post_table_properties: Vec<Expression>,
8069    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
8070    #[serde(default)]
8071    pub mysql_table_options: Vec<(String, String)>,
8072    /// TiDB-specific table options after column definitions.
8073    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8074    pub tidb_table_options: Vec<TiDBTableOption>,
8075    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
8076    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8077    pub inherits: Vec<TableRef>,
8078    /// TSQL ON filegroup or ON filegroup (partition_column) clause
8079    #[serde(default, skip_serializing_if = "Option::is_none")]
8080    pub on_property: Option<OnProperty>,
8081    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
8082    #[serde(default)]
8083    pub copy_grants: bool,
8084    /// Snowflake: USING TEMPLATE expression for schema inference
8085    #[serde(default, skip_serializing_if = "Option::is_none")]
8086    pub using_template: Option<Box<Expression>>,
8087    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
8088    #[serde(default, skip_serializing_if = "Option::is_none")]
8089    pub rollup: Option<RollupProperty>,
8090    /// ClickHouse: UUID 'xxx' clause after table name
8091    #[serde(default, skip_serializing_if = "Option::is_none")]
8092    pub uuid: Option<String>,
8093    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
8094    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
8095    /// could appear in other engines.
8096    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8097    pub with_partition_columns: Vec<ColumnDef>,
8098    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
8099    /// for external tables that reference a Cloud Resource connection.
8100    #[serde(default, skip_serializing_if = "Option::is_none")]
8101    pub with_connection: Option<TableRef>,
8102}
8103
8104/// Teradata index specification for CREATE TABLE
8105#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8106#[cfg_attr(feature = "bindings", derive(TS))]
8107pub struct TeradataIndex {
8108    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
8109    pub kind: TeradataIndexKind,
8110    /// Optional index name
8111    pub name: Option<String>,
8112    /// Optional column list
8113    pub columns: Vec<String>,
8114}
8115
8116/// Kind of Teradata index
8117#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8118#[cfg_attr(feature = "bindings", derive(TS))]
8119pub enum TeradataIndexKind {
8120    /// NO PRIMARY INDEX
8121    NoPrimary,
8122    /// PRIMARY INDEX
8123    Primary,
8124    /// PRIMARY AMP INDEX
8125    PrimaryAmp,
8126    /// UNIQUE INDEX
8127    Unique,
8128    /// UNIQUE PRIMARY INDEX
8129    UniquePrimary,
8130    /// INDEX (secondary, non-primary)
8131    Secondary,
8132}
8133
8134impl CreateTable {
8135    pub fn new(name: impl Into<String>) -> Self {
8136        Self {
8137            name: TableRef::new(name),
8138            on_cluster: None,
8139            columns: Vec::new(),
8140            constraints: Vec::new(),
8141            if_not_exists: false,
8142            temporary: false,
8143            or_replace: false,
8144            table_modifier: None,
8145            source_dialect: None,
8146            as_select: None,
8147            as_select_parenthesized: false,
8148            on_commit: None,
8149            clone_source: None,
8150            clone_at_clause: None,
8151            shallow_clone: false,
8152            deep_clone: false,
8153            is_copy: false,
8154            leading_comments: Vec::new(),
8155            with_properties: Vec::new(),
8156            teradata_post_name_options: Vec::new(),
8157            with_data: None,
8158            with_statistics: None,
8159            teradata_indexes: Vec::new(),
8160            with_cte: None,
8161            properties: Vec::new(),
8162            partition_of: None,
8163            post_table_properties: Vec::new(),
8164            mysql_table_options: Vec::new(),
8165            tidb_table_options: Vec::new(),
8166            inherits: Vec::new(),
8167            on_property: None,
8168            copy_grants: false,
8169            using_template: None,
8170            rollup: None,
8171            uuid: None,
8172            with_partition_columns: Vec::new(),
8173            with_connection: None,
8174        }
8175    }
8176}
8177
8178/// Sort order for PRIMARY KEY ASC/DESC
8179#[derive(
8180    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
8181)]
8182#[cfg_attr(feature = "bindings", derive(TS))]
8183pub enum SortOrder {
8184    Asc,
8185    Desc,
8186}
8187
8188/// Type of column constraint for tracking order
8189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8190#[cfg_attr(feature = "bindings", derive(TS))]
8191pub enum ConstraintType {
8192    NotNull,
8193    Null,
8194    PrimaryKey,
8195    Unique,
8196    Default,
8197    AutoIncrement,
8198    AutoRandom,
8199    Collate,
8200    Comment,
8201    References,
8202    Check,
8203    GeneratedAsIdentity,
8204    /// Snowflake: TAG (key='value', ...)
8205    Tags,
8206    /// Computed/generated column
8207    ComputedColumn,
8208    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
8209    GeneratedAsRow,
8210    /// MySQL: ON UPDATE expression
8211    OnUpdate,
8212    /// PATH constraint for XMLTABLE/JSON_TABLE columns
8213    Path,
8214    /// Redshift: ENCODE encoding_type
8215    Encode,
8216}
8217
8218/// Column definition in CREATE TABLE
8219#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8220#[cfg_attr(feature = "bindings", derive(TS))]
8221pub struct ColumnDef {
8222    pub name: Identifier,
8223    pub data_type: DataType,
8224    pub nullable: Option<bool>,
8225    pub default: Option<Expression>,
8226    pub primary_key: bool,
8227    /// Sort order for PRIMARY KEY (ASC/DESC)
8228    #[serde(default)]
8229    pub primary_key_order: Option<SortOrder>,
8230    pub unique: bool,
8231    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
8232    #[serde(default)]
8233    pub unique_nulls_not_distinct: bool,
8234    pub auto_increment: bool,
8235    /// TiDB distributed primary-key allocation attribute.
8236    #[serde(default, skip_serializing_if = "Option::is_none")]
8237    pub auto_random: Option<TiDBAutoRandom>,
8238    pub comment: Option<String>,
8239    pub constraints: Vec<ColumnConstraint>,
8240    /// Track original order of constraints for accurate regeneration
8241    #[serde(default)]
8242    pub constraint_order: Vec<ConstraintType>,
8243    /// Teradata: FORMAT 'pattern'
8244    #[serde(default)]
8245    pub format: Option<String>,
8246    /// Teradata: TITLE 'title'
8247    #[serde(default)]
8248    pub title: Option<String>,
8249    /// Teradata: INLINE LENGTH n
8250    #[serde(default)]
8251    pub inline_length: Option<u64>,
8252    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
8253    #[serde(default)]
8254    pub compress: Option<Vec<Expression>>,
8255    /// Teradata: CHARACTER SET name
8256    #[serde(default)]
8257    pub character_set: Option<String>,
8258    /// Teradata: UPPERCASE
8259    #[serde(default)]
8260    pub uppercase: bool,
8261    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
8262    #[serde(default)]
8263    pub casespecific: Option<bool>,
8264    /// Snowflake: AUTOINCREMENT START value
8265    #[serde(default)]
8266    pub auto_increment_start: Option<Box<Expression>>,
8267    /// Snowflake: AUTOINCREMENT INCREMENT value
8268    #[serde(default)]
8269    pub auto_increment_increment: Option<Box<Expression>>,
8270    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
8271    #[serde(default)]
8272    pub auto_increment_order: Option<bool>,
8273    /// MySQL: UNSIGNED modifier
8274    #[serde(default)]
8275    pub unsigned: bool,
8276    /// MySQL: ZEROFILL modifier
8277    #[serde(default)]
8278    pub zerofill: bool,
8279    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
8280    #[serde(default, skip_serializing_if = "Option::is_none")]
8281    pub on_update: Option<Expression>,
8282    /// MySQL: column VISIBLE/INVISIBLE modifier.
8283    #[serde(default, skip_serializing_if = "Option::is_none")]
8284    pub visible: Option<bool>,
8285    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
8286    #[serde(default, skip_serializing_if = "Option::is_none")]
8287    pub unique_constraint_name: Option<String>,
8288    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
8289    #[serde(default, skip_serializing_if = "Option::is_none")]
8290    pub not_null_constraint_name: Option<String>,
8291    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
8292    #[serde(default, skip_serializing_if = "Option::is_none")]
8293    pub primary_key_constraint_name: Option<String>,
8294    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
8295    #[serde(default, skip_serializing_if = "Option::is_none")]
8296    pub check_constraint_name: Option<String>,
8297    /// BigQuery: OPTIONS (key=value, ...) on column
8298    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8299    pub options: Vec<Expression>,
8300    /// SQLite: Column definition without explicit type
8301    #[serde(default)]
8302    pub no_type: bool,
8303    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
8304    #[serde(default, skip_serializing_if = "Option::is_none")]
8305    pub encoding: Option<String>,
8306    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
8307    #[serde(default, skip_serializing_if = "Option::is_none")]
8308    pub codec: Option<String>,
8309    /// ClickHouse: EPHEMERAL [expr] modifier
8310    #[serde(default, skip_serializing_if = "Option::is_none")]
8311    pub ephemeral: Option<Option<Box<Expression>>>,
8312    /// ClickHouse: MATERIALIZED expr modifier
8313    #[serde(default, skip_serializing_if = "Option::is_none")]
8314    pub materialized_expr: Option<Box<Expression>>,
8315    /// ClickHouse: ALIAS expr modifier
8316    #[serde(default, skip_serializing_if = "Option::is_none")]
8317    pub alias_expr: Option<Box<Expression>>,
8318    /// ClickHouse: TTL expr modifier on columns
8319    #[serde(default, skip_serializing_if = "Option::is_none")]
8320    pub ttl_expr: Option<Box<Expression>>,
8321    /// TSQL: NOT FOR REPLICATION
8322    #[serde(default)]
8323    pub not_for_replication: bool,
8324}
8325
8326impl ColumnDef {
8327    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
8328        Self {
8329            name: Identifier::new(name),
8330            data_type,
8331            nullable: None,
8332            default: None,
8333            primary_key: false,
8334            primary_key_order: None,
8335            unique: false,
8336            unique_nulls_not_distinct: false,
8337            auto_increment: false,
8338            auto_random: None,
8339            comment: None,
8340            constraints: Vec::new(),
8341            constraint_order: Vec::new(),
8342            format: None,
8343            title: None,
8344            inline_length: None,
8345            compress: None,
8346            character_set: None,
8347            uppercase: false,
8348            casespecific: None,
8349            auto_increment_start: None,
8350            auto_increment_increment: None,
8351            auto_increment_order: None,
8352            unsigned: false,
8353            zerofill: false,
8354            on_update: None,
8355            visible: None,
8356            unique_constraint_name: None,
8357            not_null_constraint_name: None,
8358            primary_key_constraint_name: None,
8359            check_constraint_name: None,
8360            options: Vec::new(),
8361            no_type: false,
8362            encoding: None,
8363            codec: None,
8364            ephemeral: None,
8365            materialized_expr: None,
8366            alias_expr: None,
8367            ttl_expr: None,
8368            not_for_replication: false,
8369        }
8370    }
8371}
8372
8373/// Column-level constraint
8374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8375#[cfg_attr(feature = "bindings", derive(TS))]
8376pub enum ColumnConstraint {
8377    NotNull,
8378    Null,
8379    Unique,
8380    PrimaryKey,
8381    Default(Expression),
8382    Check(Expression),
8383    References(ForeignKeyRef),
8384    GeneratedAsIdentity(GeneratedAsIdentity),
8385    Collate(Identifier),
8386    Comment(String),
8387    /// Snowflake: TAG (key='value', ...)
8388    Tags(Tags),
8389    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
8390    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
8391    ComputedColumn(ComputedColumn),
8392    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8393    GeneratedAsRow(GeneratedAsRow),
8394    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
8395    Path(Expression),
8396}
8397
8398/// Computed/generated column constraint
8399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8400#[cfg_attr(feature = "bindings", derive(TS))]
8401pub struct ComputedColumn {
8402    /// The expression that computes the column value
8403    pub expression: Box<Expression>,
8404    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
8405    #[serde(default)]
8406    pub persisted: bool,
8407    /// NOT NULL (TSQL computed columns)
8408    #[serde(default)]
8409    pub not_null: bool,
8410    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
8411    /// When None, defaults to dialect-appropriate output
8412    #[serde(default)]
8413    pub persistence_kind: Option<String>,
8414    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
8415    #[serde(default, skip_serializing_if = "Option::is_none")]
8416    pub data_type: Option<DataType>,
8417}
8418
8419/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8420#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8421#[cfg_attr(feature = "bindings", derive(TS))]
8422pub struct GeneratedAsRow {
8423    /// true = ROW START, false = ROW END
8424    pub start: bool,
8425    /// HIDDEN modifier
8426    #[serde(default)]
8427    pub hidden: bool,
8428}
8429
8430/// Generated identity column constraint
8431#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8432#[cfg_attr(feature = "bindings", derive(TS))]
8433pub struct GeneratedAsIdentity {
8434    /// True for ALWAYS, False for BY DEFAULT
8435    pub always: bool,
8436    /// ON NULL (only valid with BY DEFAULT)
8437    pub on_null: bool,
8438    /// START WITH value
8439    pub start: Option<Box<Expression>>,
8440    /// INCREMENT BY value
8441    pub increment: Option<Box<Expression>>,
8442    /// MINVALUE
8443    pub minvalue: Option<Box<Expression>>,
8444    /// MAXVALUE
8445    pub maxvalue: Option<Box<Expression>>,
8446    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
8447    pub cycle: Option<bool>,
8448}
8449
8450/// Constraint modifiers (shared between table-level constraints)
8451#[derive(
8452    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
8453)]
8454#[cfg_attr(feature = "bindings", derive(TS))]
8455pub struct ConstraintModifiers {
8456    /// ENFORCED / NOT ENFORCED
8457    pub enforced: Option<bool>,
8458    /// DEFERRABLE / NOT DEFERRABLE
8459    pub deferrable: Option<bool>,
8460    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
8461    pub initially_deferred: Option<bool>,
8462    /// NORELY (Oracle)
8463    pub norely: bool,
8464    /// RELY (Oracle)
8465    pub rely: bool,
8466    /// USING index type (MySQL): BTREE or HASH
8467    #[serde(default)]
8468    pub using: Option<String>,
8469    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
8470    #[serde(default)]
8471    pub using_before_columns: bool,
8472    /// MySQL index COMMENT 'text'
8473    #[serde(default, skip_serializing_if = "Option::is_none")]
8474    pub comment: Option<String>,
8475    /// MySQL index VISIBLE/INVISIBLE
8476    #[serde(default, skip_serializing_if = "Option::is_none")]
8477    pub visible: Option<bool>,
8478    /// MySQL ENGINE_ATTRIBUTE = 'value'
8479    #[serde(default, skip_serializing_if = "Option::is_none")]
8480    pub engine_attribute: Option<String>,
8481    /// MySQL WITH PARSER name
8482    #[serde(default, skip_serializing_if = "Option::is_none")]
8483    pub with_parser: Option<String>,
8484    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
8485    #[serde(default)]
8486    pub not_valid: bool,
8487    /// TSQL CLUSTERED/NONCLUSTERED modifier
8488    #[serde(default, skip_serializing_if = "Option::is_none")]
8489    pub clustered: Option<String>,
8490    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
8491    #[serde(default, skip_serializing_if = "Option::is_none")]
8492    pub on_conflict: Option<String>,
8493    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
8494    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8495    pub with_options: Vec<(String, String)>,
8496    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
8497    #[serde(default, skip_serializing_if = "Option::is_none")]
8498    pub on_filegroup: Option<Identifier>,
8499}
8500
8501/// Table-level constraint
8502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8503#[cfg_attr(feature = "bindings", derive(TS))]
8504pub enum TableConstraint {
8505    PrimaryKey {
8506        name: Option<Identifier>,
8507        columns: Vec<Identifier>,
8508        /// Structured quoted, prefixed or ordered keys. When present these are
8509        /// authoritative for rendering; `columns` retains the column names.
8510        /// Older ASTs can encode prefix/order syntax directly in `columns`.
8511        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8512        key_parts: Vec<IndexKeyPart>,
8513        /// Databricks primary-key columns marked with the TIMESERIES attribute.
8514        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8515        timeseries_columns: Vec<Identifier>,
8516        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
8517        #[serde(default)]
8518        include_columns: Vec<Identifier>,
8519        #[serde(default)]
8520        modifiers: ConstraintModifiers,
8521        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
8522        #[serde(default)]
8523        has_constraint_keyword: bool,
8524    },
8525    Unique {
8526        name: Option<Identifier>,
8527        columns: Vec<Identifier>,
8528        /// Structured quoted, prefixed or ordered keys, as for `PrimaryKey`.
8529        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8530        key_parts: Vec<IndexKeyPart>,
8531        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
8532        #[serde(default)]
8533        columns_parenthesized: bool,
8534        #[serde(default)]
8535        modifiers: ConstraintModifiers,
8536        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
8537        #[serde(default)]
8538        has_constraint_keyword: bool,
8539        /// PostgreSQL 15+: NULLS NOT DISTINCT
8540        #[serde(default)]
8541        nulls_not_distinct: bool,
8542    },
8543    ForeignKey {
8544        name: Option<Identifier>,
8545        columns: Vec<Identifier>,
8546        #[serde(default)]
8547        references: Option<ForeignKeyRef>,
8548        /// ON DELETE action when REFERENCES is absent
8549        #[serde(default)]
8550        on_delete: Option<ReferentialAction>,
8551        /// ON UPDATE action when REFERENCES is absent
8552        #[serde(default)]
8553        on_update: Option<ReferentialAction>,
8554        #[serde(default)]
8555        modifiers: ConstraintModifiers,
8556    },
8557    Check {
8558        name: Option<Identifier>,
8559        expression: Expression,
8560        #[serde(default)]
8561        modifiers: ConstraintModifiers,
8562    },
8563    /// ClickHouse ASSUME constraint (query optimization assumption)
8564    Assume {
8565        name: Option<Identifier>,
8566        expression: Expression,
8567    },
8568    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
8569    Default {
8570        name: Option<Identifier>,
8571        expression: Expression,
8572        column: Identifier,
8573    },
8574    /// INDEX / KEY constraint (MySQL)
8575    Index {
8576        name: Option<Identifier>,
8577        columns: Vec<Identifier>,
8578        /// Expression-capable index key parts. This is used when an index contains
8579        /// functional key parts that cannot be represented by `columns`.
8580        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8581        key_parts: Vec<IndexKeyPart>,
8582        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8583        #[serde(default)]
8584        kind: Option<String>,
8585        #[serde(default)]
8586        modifiers: ConstraintModifiers,
8587        /// True if KEY keyword was used instead of INDEX
8588        #[serde(default)]
8589        use_key_keyword: bool,
8590        /// ClickHouse: indexed expression (instead of columns)
8591        #[serde(default, skip_serializing_if = "Option::is_none")]
8592        expression: Option<Box<Expression>>,
8593        /// ClickHouse: TYPE type_func(args)
8594        #[serde(default, skip_serializing_if = "Option::is_none")]
8595        index_type: Option<Box<Expression>>,
8596        /// ClickHouse: GRANULARITY n
8597        #[serde(default, skip_serializing_if = "Option::is_none")]
8598        granularity: Option<Box<Expression>>,
8599    },
8600    /// ClickHouse PROJECTION definition
8601    Projection {
8602        name: Identifier,
8603        expression: Expression,
8604    },
8605    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8606    Like {
8607        source: TableRef,
8608        /// Options as (INCLUDING|EXCLUDING, property) pairs
8609        options: Vec<(LikeOptionAction, String)>,
8610    },
8611    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8612    PeriodForSystemTime {
8613        start_col: Identifier,
8614        end_col: Identifier,
8615    },
8616    /// PostgreSQL EXCLUDE constraint
8617    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8618    Exclude {
8619        name: Option<Identifier>,
8620        /// Index access method (gist, btree, etc.)
8621        #[serde(default)]
8622        using: Option<String>,
8623        /// Elements: (expression, operator) pairs
8624        elements: Vec<ExcludeElement>,
8625        /// INCLUDE columns
8626        #[serde(default)]
8627        include_columns: Vec<Identifier>,
8628        /// WHERE predicate
8629        #[serde(default)]
8630        where_clause: Option<Box<Expression>>,
8631        /// WITH (storage_parameters)
8632        #[serde(default)]
8633        with_params: Vec<(String, String)>,
8634        /// USING INDEX TABLESPACE tablespace_name
8635        #[serde(default)]
8636        using_index_tablespace: Option<String>,
8637        #[serde(default)]
8638        modifiers: ConstraintModifiers,
8639    },
8640    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8641    Tags(Tags),
8642    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8643    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8644    /// for all deferrable constraints in the table
8645    InitiallyDeferred {
8646        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8647        deferred: bool,
8648    },
8649}
8650
8651/// Element in an EXCLUDE constraint: expression WITH operator
8652#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8653#[cfg_attr(feature = "bindings", derive(TS))]
8654pub struct ExcludeElement {
8655    /// The column expression (may include operator class, ordering, nulls)
8656    pub expression: String,
8657    /// The operator (e.g., &&, =)
8658    pub operator: String,
8659}
8660
8661/// Action for LIKE clause options
8662#[derive(
8663    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8664)]
8665#[cfg_attr(feature = "bindings", derive(TS))]
8666pub enum LikeOptionAction {
8667    Including,
8668    Excluding,
8669}
8670
8671/// MATCH type for foreign keys
8672#[derive(
8673    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8674)]
8675#[cfg_attr(feature = "bindings", derive(TS))]
8676pub enum MatchType {
8677    Full,
8678    Partial,
8679    Simple,
8680}
8681
8682/// Foreign key reference
8683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8684#[cfg_attr(feature = "bindings", derive(TS))]
8685pub struct ForeignKeyRef {
8686    pub table: TableRef,
8687    pub columns: Vec<Identifier>,
8688    pub on_delete: Option<ReferentialAction>,
8689    pub on_update: Option<ReferentialAction>,
8690    /// True if ON UPDATE appears before ON DELETE in the original SQL
8691    #[serde(default)]
8692    pub on_update_first: bool,
8693    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8694    #[serde(default)]
8695    pub match_type: Option<MatchType>,
8696    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8697    #[serde(default)]
8698    pub match_after_actions: bool,
8699    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8700    #[serde(default)]
8701    pub constraint_name: Option<String>,
8702    /// DEFERRABLE / NOT DEFERRABLE
8703    #[serde(default)]
8704    pub deferrable: Option<bool>,
8705    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8706    #[serde(default)]
8707    pub has_foreign_key_keywords: bool,
8708}
8709
8710/// Referential action for foreign keys
8711#[derive(
8712    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8713)]
8714#[cfg_attr(feature = "bindings", derive(TS))]
8715pub enum ReferentialAction {
8716    Cascade,
8717    SetNull,
8718    SetDefault,
8719    Restrict,
8720    NoAction,
8721}
8722
8723/// DROP TABLE statement
8724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8725#[cfg_attr(feature = "bindings", derive(TS))]
8726pub struct DropTable {
8727    pub names: Vec<TableRef>,
8728    pub if_exists: bool,
8729    pub cascade: bool,
8730    /// Oracle: CASCADE CONSTRAINTS
8731    #[serde(default)]
8732    pub cascade_constraints: bool,
8733    /// Oracle: PURGE
8734    #[serde(default)]
8735    pub purge: bool,
8736    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8737    #[serde(default)]
8738    pub leading_comments: Vec<String>,
8739    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8740    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8741    #[serde(default, skip_serializing_if = "Option::is_none")]
8742    pub object_id_args: Option<String>,
8743    /// ClickHouse: SYNC modifier
8744    #[serde(default)]
8745    pub sync: bool,
8746    /// Snowflake: DROP ICEBERG TABLE
8747    #[serde(default)]
8748    pub iceberg: bool,
8749    /// RESTRICT modifier (opposite of CASCADE)
8750    #[serde(default)]
8751    pub restrict: bool,
8752}
8753
8754impl DropTable {
8755    pub fn new(name: impl Into<String>) -> Self {
8756        Self {
8757            names: vec![TableRef::new(name)],
8758            if_exists: false,
8759            cascade: false,
8760            cascade_constraints: false,
8761            purge: false,
8762            leading_comments: Vec::new(),
8763            object_id_args: None,
8764            sync: false,
8765            iceberg: false,
8766            restrict: false,
8767        }
8768    }
8769}
8770
8771/// UNDROP object statement (Snowflake, ClickHouse)
8772#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8773#[cfg_attr(feature = "bindings", derive(TS))]
8774pub struct Undrop {
8775    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8776    pub kind: String,
8777    /// The object name
8778    pub name: TableRef,
8779    /// IF EXISTS clause
8780    #[serde(default)]
8781    pub if_exists: bool,
8782    /// Snowflake: optional RENAME TO target
8783    #[serde(default, skip_serializing_if = "Option::is_none")]
8784    pub rename_to: Option<TableRef>,
8785}
8786
8787/// Partition scope for a TiDB `SPLIT TABLE` statement.
8788#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8789#[cfg_attr(feature = "bindings", derive(TS))]
8790#[serde(tag = "type", rename_all = "snake_case")]
8791pub enum SplitTablePartitionScope {
8792    Table,
8793    AllPartitions,
8794    Partitions { names: Vec<Identifier> },
8795}
8796
8797/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8798#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8799#[cfg_attr(feature = "bindings", derive(TS))]
8800#[serde(tag = "type", rename_all = "snake_case")]
8801pub enum SplitTableMode {
8802    Between {
8803        lower: Vec<Expression>,
8804        upper: Vec<Expression>,
8805        regions: u64,
8806    },
8807    By {
8808        points: Vec<Vec<Expression>>,
8809    },
8810}
8811
8812/// TiDB `SPLIT [PARTITION] TABLE` statement.
8813#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8814#[cfg_attr(feature = "bindings", derive(TS))]
8815pub struct SplitTable {
8816    pub table: TableRef,
8817    pub partition_scope: SplitTablePartitionScope,
8818    #[serde(default, skip_serializing_if = "Option::is_none")]
8819    pub index: Option<Identifier>,
8820    pub mode: SplitTableMode,
8821}
8822
8823/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
8824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8825#[cfg_attr(feature = "bindings", derive(TS))]
8826pub struct FlashbackTable {
8827    pub table: TableRef,
8828    #[serde(default, skip_serializing_if = "Option::is_none")]
8829    pub rename_to: Option<Identifier>,
8830}
8831
8832/// ALTER TABLE statement
8833#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8834#[cfg_attr(feature = "bindings", derive(TS))]
8835pub struct AlterTable {
8836    pub name: TableRef,
8837    pub actions: Vec<AlterTableAction>,
8838    /// IF EXISTS clause
8839    #[serde(default)]
8840    pub if_exists: bool,
8841    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8842    #[serde(default, skip_serializing_if = "Option::is_none")]
8843    pub algorithm: Option<String>,
8844    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8845    #[serde(default, skip_serializing_if = "Option::is_none")]
8846    pub lock: Option<String>,
8847    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8848    #[serde(default, skip_serializing_if = "Option::is_none")]
8849    pub with_check: Option<String>,
8850    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8851    #[serde(default, skip_serializing_if = "Option::is_none")]
8852    pub partition: Option<Vec<(Identifier, Expression)>>,
8853    /// ClickHouse: ON CLUSTER clause for distributed DDL
8854    #[serde(default, skip_serializing_if = "Option::is_none")]
8855    pub on_cluster: Option<OnCluster>,
8856    /// Snowflake: ALTER ICEBERG TABLE
8857    #[serde(default, skip_serializing_if = "Option::is_none")]
8858    pub table_modifier: Option<String>,
8859}
8860
8861impl AlterTable {
8862    pub fn new(name: impl Into<String>) -> Self {
8863        Self {
8864            name: TableRef::new(name),
8865            actions: Vec::new(),
8866            if_exists: false,
8867            algorithm: None,
8868            lock: None,
8869            with_check: None,
8870            partition: None,
8871            on_cluster: None,
8872            table_modifier: None,
8873        }
8874    }
8875}
8876
8877/// Column position for ADD COLUMN (MySQL/MariaDB)
8878#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8879#[cfg_attr(feature = "bindings", derive(TS))]
8880pub enum ColumnPosition {
8881    First,
8882    After(Identifier),
8883}
8884
8885/// Actions for ALTER TABLE
8886#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8887#[cfg_attr(feature = "bindings", derive(TS))]
8888pub enum AlterTableAction {
8889    AddColumn {
8890        column: ColumnDef,
8891        if_not_exists: bool,
8892        position: Option<ColumnPosition>,
8893    },
8894    DropColumn {
8895        name: Identifier,
8896        if_exists: bool,
8897        cascade: bool,
8898    },
8899    RenameColumn {
8900        old_name: Identifier,
8901        new_name: Identifier,
8902        if_exists: bool,
8903    },
8904    AlterColumn {
8905        name: Identifier,
8906        action: AlterColumnAction,
8907        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8908        #[serde(default)]
8909        use_modify_keyword: bool,
8910    },
8911    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
8912    ModifyColumn {
8913        column: ColumnDef,
8914        if_exists: bool,
8915        position: Option<ColumnPosition>,
8916    },
8917    RenameTable(TableRef),
8918    AddConstraint(TableConstraint),
8919    DropConstraint {
8920        name: Identifier,
8921        if_exists: bool,
8922    },
8923    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8924    DropForeignKey {
8925        name: Identifier,
8926    },
8927    /// DROP PARTITION action (Hive/BigQuery)
8928    DropPartition {
8929        /// List of partitions to drop (each partition is a list of key=value pairs)
8930        partitions: Vec<Vec<(Identifier, Expression)>>,
8931        if_exists: bool,
8932    },
8933    /// ADD PARTITION action (Hive/Spark)
8934    AddPartition {
8935        /// The partition expression
8936        partition: Expression,
8937        if_not_exists: bool,
8938        location: Option<Expression>,
8939    },
8940    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8941    Delete {
8942        where_clause: Expression,
8943    },
8944    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8945    SwapWith(TableRef),
8946    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8947    SetProperty {
8948        properties: Vec<(String, Expression)>,
8949    },
8950    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8951    UnsetProperty {
8952        properties: Vec<String>,
8953    },
8954    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8955    ClusterBy {
8956        expressions: Vec<Expression>,
8957    },
8958    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8959    SetTag {
8960        expressions: Vec<(String, Expression)>,
8961    },
8962    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8963    UnsetTag {
8964        names: Vec<String>,
8965    },
8966    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8967    SetOptions {
8968        expressions: Vec<Expression>,
8969    },
8970    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8971    AlterIndex {
8972        name: Identifier,
8973        visible: bool,
8974    },
8975    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8976    SetAttribute {
8977        attribute: String,
8978    },
8979    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8980    SetStageFileFormat {
8981        options: Option<Expression>,
8982    },
8983    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8984    SetStageCopyOptions {
8985        options: Option<Expression>,
8986    },
8987    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8988    AddColumns {
8989        columns: Vec<ColumnDef>,
8990        cascade: bool,
8991    },
8992    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8993    DropColumns {
8994        names: Vec<Identifier>,
8995    },
8996    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8997    /// In SingleStore, data_type can be omitted for simple column renames
8998    ChangeColumn {
8999        old_name: Identifier,
9000        new_name: Identifier,
9001        #[serde(default, skip_serializing_if = "Option::is_none")]
9002        data_type: Option<DataType>,
9003        comment: Option<String>,
9004        #[serde(default)]
9005        cascade: bool,
9006    },
9007    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
9008    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
9009    AlterSortKey {
9010        /// AUTO or NONE keyword
9011        this: Option<String>,
9012        /// Column list for (col1, col2) syntax
9013        expressions: Vec<Expression>,
9014        /// Whether COMPOUND keyword was present
9015        compound: bool,
9016    },
9017    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
9018    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
9019    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
9020    AlterDistStyle {
9021        /// Distribution style: ALL, EVEN, AUTO, or KEY
9022        style: String,
9023        /// DISTKEY column (only when style is KEY)
9024        distkey: Option<Identifier>,
9025    },
9026    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
9027    SetTableProperties {
9028        properties: Vec<(Expression, Expression)>,
9029    },
9030    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
9031    SetLocation {
9032        location: String,
9033    },
9034    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
9035    SetFileFormat {
9036        format: String,
9037    },
9038    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
9039    ReplacePartition {
9040        partition: Expression,
9041        source: Option<Box<Expression>>,
9042    },
9043    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
9044    SetTiDBTableOption {
9045        option: TiDBTableOption,
9046        #[serde(default)]
9047        force: bool,
9048    },
9049    /// TiDB `REMOVE TTL`.
9050    RemoveTiDBTtl {
9051        #[serde(default)]
9052        executable_comment: bool,
9053    },
9054    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
9055    Raw {
9056        sql: String,
9057    },
9058}
9059
9060/// Actions for ALTER COLUMN
9061#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9062#[cfg_attr(feature = "bindings", derive(TS))]
9063pub enum AlterColumnAction {
9064    SetDataType {
9065        data_type: DataType,
9066        /// USING expression for type conversion (PostgreSQL)
9067        using: Option<Expression>,
9068        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
9069        #[serde(default, skip_serializing_if = "Option::is_none")]
9070        collate: Option<String>,
9071    },
9072    SetDefault(Expression),
9073    DropDefault,
9074    SetNotNull,
9075    DropNotNull,
9076    /// Set column comment
9077    Comment(String),
9078    /// MySQL: SET VISIBLE
9079    SetVisible,
9080    /// MySQL: SET INVISIBLE
9081    SetInvisible,
9082}
9083
9084/// CREATE INDEX statement
9085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9086#[cfg_attr(feature = "bindings", derive(TS))]
9087pub struct CreateIndex {
9088    pub name: Identifier,
9089    pub table: TableRef,
9090    pub columns: Vec<IndexColumn>,
9091    /// Expression-capable index key parts. This is used when an index contains
9092    /// functional key parts that cannot be represented by `columns`.
9093    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9094    pub key_parts: Vec<IndexKeyPart>,
9095    pub unique: bool,
9096    pub if_not_exists: bool,
9097    pub using: Option<String>,
9098    /// TSQL CLUSTERED/NONCLUSTERED modifier
9099    #[serde(default)]
9100    pub clustered: Option<String>,
9101    /// PostgreSQL CONCURRENTLY modifier
9102    #[serde(default)]
9103    pub concurrently: bool,
9104    /// PostgreSQL WHERE clause for partial indexes
9105    #[serde(default)]
9106    pub where_clause: Option<Box<Expression>>,
9107    /// PostgreSQL INCLUDE columns
9108    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9109    pub include_columns: Vec<Identifier>,
9110    /// TSQL WITH options (e.g., allow_page_locks=on)
9111    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9112    pub with_options: Vec<(String, String)>,
9113    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
9114    #[serde(default)]
9115    pub on_filegroup: Option<String>,
9116}
9117
9118impl CreateIndex {
9119    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
9120        Self {
9121            name: Identifier::new(name),
9122            table: TableRef::new(table),
9123            columns: Vec::new(),
9124            key_parts: Vec::new(),
9125            unique: false,
9126            if_not_exists: false,
9127            using: None,
9128            clustered: None,
9129            concurrently: false,
9130            where_clause: None,
9131            include_columns: Vec::new(),
9132            with_options: Vec::new(),
9133            on_filegroup: None,
9134        }
9135    }
9136}
9137
9138/// Index column specification
9139#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9140#[cfg_attr(feature = "bindings", derive(TS))]
9141pub struct IndexColumn {
9142    pub column: Identifier,
9143    pub desc: bool,
9144    /// Explicit ASC keyword was present
9145    #[serde(default)]
9146    pub asc: bool,
9147    pub nulls_first: Option<bool>,
9148    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
9149    #[serde(default, skip_serializing_if = "Option::is_none")]
9150    pub opclass: Option<String>,
9151}
9152
9153/// An expression-capable index key part.
9154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9155#[cfg_attr(feature = "bindings", derive(TS))]
9156pub struct IndexKeyPart {
9157    pub expression: Box<Expression>,
9158    /// MySQL column prefix length, for example the `16` in `name(16)`.
9159    #[serde(default, skip_serializing_if = "Option::is_none")]
9160    pub prefix_length: Option<String>,
9161    pub desc: bool,
9162    /// Explicit ASC keyword was present.
9163    #[serde(default)]
9164    pub asc: bool,
9165    pub nulls_first: Option<bool>,
9166    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops).
9167    #[serde(default, skip_serializing_if = "Option::is_none")]
9168    pub opclass: Option<String>,
9169}
9170
9171/// DROP INDEX statement
9172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9173#[cfg_attr(feature = "bindings", derive(TS))]
9174pub struct DropIndex {
9175    pub name: TableRef,
9176    pub table: Option<TableRef>,
9177    pub if_exists: bool,
9178    /// PostgreSQL CONCURRENTLY modifier
9179    #[serde(default)]
9180    pub concurrently: bool,
9181}
9182
9183impl DropIndex {
9184    pub fn new(name: impl Into<String>) -> Self {
9185        Self {
9186            name: TableRef::new(name),
9187            table: None,
9188            if_exists: false,
9189            concurrently: false,
9190        }
9191    }
9192}
9193
9194/// View column definition with optional COMMENT and OPTIONS (BigQuery)
9195#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9196#[cfg_attr(feature = "bindings", derive(TS))]
9197pub struct ViewColumn {
9198    pub name: Identifier,
9199    pub comment: Option<String>,
9200    /// BigQuery: OPTIONS (key=value, ...) on column
9201    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9202    pub options: Vec<Expression>,
9203}
9204
9205impl ViewColumn {
9206    pub fn new(name: impl Into<String>) -> Self {
9207        Self {
9208            name: Identifier::new(name),
9209            comment: None,
9210            options: Vec::new(),
9211        }
9212    }
9213
9214    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
9215        Self {
9216            name: Identifier::new(name),
9217            comment: Some(comment.into()),
9218            options: Vec::new(),
9219        }
9220    }
9221}
9222
9223/// CREATE VIEW statement
9224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9225#[cfg_attr(feature = "bindings", derive(TS))]
9226pub struct CreateView {
9227    pub name: TableRef,
9228    pub columns: Vec<ViewColumn>,
9229    pub query: Expression,
9230    pub or_replace: bool,
9231    /// TSQL: CREATE OR ALTER
9232    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9233    pub or_alter: bool,
9234    pub if_not_exists: bool,
9235    pub materialized: bool,
9236    pub temporary: bool,
9237    /// Snowflake: SECURE VIEW
9238    #[serde(default)]
9239    pub secure: bool,
9240    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
9241    #[serde(skip_serializing_if = "Option::is_none")]
9242    pub algorithm: Option<String>,
9243    /// MySQL: DEFINER=user@host
9244    #[serde(skip_serializing_if = "Option::is_none")]
9245    pub definer: Option<String>,
9246    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
9247    #[serde(skip_serializing_if = "Option::is_none")]
9248    pub security: Option<FunctionSecurity>,
9249    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
9250    #[serde(default = "default_true")]
9251    pub security_sql_style: bool,
9252    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
9253    #[serde(default)]
9254    pub security_after_name: bool,
9255    /// Whether the query was parenthesized: AS (SELECT ...)
9256    #[serde(default)]
9257    pub query_parenthesized: bool,
9258    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
9259    #[serde(skip_serializing_if = "Option::is_none")]
9260    pub locking_mode: Option<String>,
9261    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
9262    #[serde(skip_serializing_if = "Option::is_none")]
9263    pub locking_access: Option<String>,
9264    /// Snowflake: COPY GRANTS
9265    #[serde(default)]
9266    pub copy_grants: bool,
9267    /// Snowflake: COMMENT = 'text'
9268    #[serde(skip_serializing_if = "Option::is_none", default)]
9269    pub comment: Option<String>,
9270    /// Snowflake: WITH ROW ACCESS POLICY ... clause
9271    #[serde(skip_serializing_if = "Option::is_none", default)]
9272    pub row_access_policy: Option<String>,
9273    /// Snowflake: TAG (name='value', ...)
9274    #[serde(default)]
9275    pub tags: Vec<(String, String)>,
9276    /// BigQuery: OPTIONS (key=value, ...)
9277    #[serde(default)]
9278    pub options: Vec<Expression>,
9279    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
9280    #[serde(skip_serializing_if = "Option::is_none", default)]
9281    pub build: Option<String>,
9282    /// Doris: REFRESH property for materialized views
9283    #[serde(skip_serializing_if = "Option::is_none", default)]
9284    pub refresh: Option<Box<RefreshTriggerProperty>>,
9285    /// Doris: Schema with typed column definitions for materialized views
9286    /// This is used instead of `columns` when the view has typed column definitions
9287    #[serde(skip_serializing_if = "Option::is_none", default)]
9288    pub schema: Option<Box<Schema>>,
9289    /// Doris: KEY (columns) for materialized views
9290    #[serde(skip_serializing_if = "Option::is_none", default)]
9291    pub unique_key: Option<Box<UniqueKeyProperty>>,
9292    /// Redshift: WITH NO SCHEMA BINDING
9293    #[serde(default)]
9294    pub no_schema_binding: bool,
9295    /// Redshift: AUTO REFRESH YES|NO for materialized views
9296    #[serde(skip_serializing_if = "Option::is_none", default)]
9297    pub auto_refresh: Option<bool>,
9298    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
9299    #[serde(skip_serializing_if = "Option::is_none", default)]
9300    pub clickhouse_population: Option<String>,
9301    /// ClickHouse: ON CLUSTER clause
9302    #[serde(default, skip_serializing_if = "Option::is_none")]
9303    pub on_cluster: Option<OnCluster>,
9304    /// ClickHouse: TO destination_table
9305    #[serde(default, skip_serializing_if = "Option::is_none")]
9306    pub to_table: Option<TableRef>,
9307    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
9308    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9309    pub table_properties: Vec<Expression>,
9310}
9311
9312impl CreateView {
9313    pub fn new(name: impl Into<String>, query: Expression) -> Self {
9314        Self {
9315            name: TableRef::new(name),
9316            columns: Vec::new(),
9317            query,
9318            or_replace: false,
9319            or_alter: false,
9320            if_not_exists: false,
9321            materialized: false,
9322            temporary: false,
9323            secure: false,
9324            algorithm: None,
9325            definer: None,
9326            security: None,
9327            security_sql_style: true,
9328            security_after_name: false,
9329            query_parenthesized: false,
9330            locking_mode: None,
9331            locking_access: None,
9332            copy_grants: false,
9333            comment: None,
9334            row_access_policy: None,
9335            tags: Vec::new(),
9336            options: Vec::new(),
9337            build: None,
9338            refresh: None,
9339            schema: None,
9340            unique_key: None,
9341            no_schema_binding: false,
9342            auto_refresh: None,
9343            clickhouse_population: None,
9344            on_cluster: None,
9345            to_table: None,
9346            table_properties: Vec::new(),
9347        }
9348    }
9349}
9350
9351/// DROP VIEW statement
9352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9353#[cfg_attr(feature = "bindings", derive(TS))]
9354pub struct DropView {
9355    pub name: TableRef,
9356    pub if_exists: bool,
9357    pub materialized: bool,
9358}
9359
9360impl DropView {
9361    pub fn new(name: impl Into<String>) -> Self {
9362        Self {
9363            name: TableRef::new(name),
9364            if_exists: false,
9365            materialized: false,
9366        }
9367    }
9368}
9369
9370/// TRUNCATE TABLE statement
9371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9372#[cfg_attr(feature = "bindings", derive(TS))]
9373pub struct Truncate {
9374    /// Target of TRUNCATE (TABLE vs DATABASE)
9375    #[serde(default)]
9376    pub target: TruncateTarget,
9377    /// IF EXISTS clause
9378    #[serde(default)]
9379    pub if_exists: bool,
9380    pub table: TableRef,
9381    /// ClickHouse: ON CLUSTER clause for distributed DDL
9382    #[serde(default, skip_serializing_if = "Option::is_none")]
9383    pub on_cluster: Option<OnCluster>,
9384    pub cascade: bool,
9385    /// Additional tables for multi-table TRUNCATE
9386    #[serde(default)]
9387    pub extra_tables: Vec<TruncateTableEntry>,
9388    /// RESTART IDENTITY or CONTINUE IDENTITY
9389    #[serde(default)]
9390    pub identity: Option<TruncateIdentity>,
9391    /// RESTRICT option (alternative to CASCADE)
9392    #[serde(default)]
9393    pub restrict: bool,
9394    /// Hive PARTITION clause: PARTITION(key=value, ...)
9395    #[serde(default, skip_serializing_if = "Option::is_none")]
9396    pub partition: Option<Box<Expression>>,
9397}
9398
9399/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
9400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9401#[cfg_attr(feature = "bindings", derive(TS))]
9402pub struct TruncateTableEntry {
9403    pub table: TableRef,
9404    /// Whether the table has a * suffix (inherit children)
9405    #[serde(default)]
9406    pub star: bool,
9407}
9408
9409/// TRUNCATE target type
9410#[derive(
9411    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9412)]
9413#[cfg_attr(feature = "bindings", derive(TS))]
9414pub enum TruncateTarget {
9415    Table,
9416    Database,
9417}
9418
9419impl Default for TruncateTarget {
9420    fn default() -> Self {
9421        TruncateTarget::Table
9422    }
9423}
9424
9425/// TRUNCATE identity option
9426#[derive(
9427    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9428)]
9429#[cfg_attr(feature = "bindings", derive(TS))]
9430pub enum TruncateIdentity {
9431    Restart,
9432    Continue,
9433}
9434
9435impl Truncate {
9436    pub fn new(table: impl Into<String>) -> Self {
9437        Self {
9438            target: TruncateTarget::Table,
9439            if_exists: false,
9440            table: TableRef::new(table),
9441            on_cluster: None,
9442            cascade: false,
9443            extra_tables: Vec::new(),
9444            identity: None,
9445            restrict: false,
9446            partition: None,
9447        }
9448    }
9449}
9450
9451/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
9452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9453#[cfg_attr(feature = "bindings", derive(TS))]
9454pub struct Use {
9455    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
9456    pub kind: Option<UseKind>,
9457    /// The name of the object
9458    pub this: Identifier,
9459}
9460
9461/// Kind of USE statement
9462#[derive(
9463    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9464)]
9465#[cfg_attr(feature = "bindings", derive(TS))]
9466pub enum UseKind {
9467    Database,
9468    Schema,
9469    Role,
9470    Warehouse,
9471    Catalog,
9472    /// Snowflake: USE SECONDARY ROLES ALL|NONE
9473    SecondaryRoles,
9474}
9475
9476/// SET variable statement
9477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9478#[cfg_attr(feature = "bindings", derive(TS))]
9479pub struct SetStatement {
9480    /// The items being set
9481    pub items: Vec<SetItem>,
9482}
9483
9484/// A single SET item (variable assignment)
9485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9486#[cfg_attr(feature = "bindings", derive(TS))]
9487pub struct SetItem {
9488    /// The variable name
9489    pub name: Expression,
9490    /// The value to set
9491    pub value: Expression,
9492    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
9493    pub kind: Option<String>,
9494    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
9495    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9496    pub no_equals: bool,
9497}
9498
9499/// CACHE TABLE statement (Spark)
9500#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9501#[cfg_attr(feature = "bindings", derive(TS))]
9502pub struct Cache {
9503    /// The table to cache
9504    pub table: Identifier,
9505    /// LAZY keyword - defer caching until first use
9506    pub lazy: bool,
9507    /// Optional OPTIONS clause (key-value pairs)
9508    pub options: Vec<(Expression, Expression)>,
9509    /// Optional AS clause with query
9510    pub query: Option<Expression>,
9511}
9512
9513/// UNCACHE TABLE statement (Spark)
9514#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9515#[cfg_attr(feature = "bindings", derive(TS))]
9516pub struct Uncache {
9517    /// The table to uncache
9518    pub table: Identifier,
9519    /// IF EXISTS clause
9520    pub if_exists: bool,
9521}
9522
9523/// LOAD DATA statement (Hive)
9524#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9525#[cfg_attr(feature = "bindings", derive(TS))]
9526pub struct LoadData {
9527    /// LOCAL keyword - load from local filesystem
9528    pub local: bool,
9529    /// The path to load data from (INPATH value)
9530    pub inpath: String,
9531    /// Whether to overwrite existing data
9532    pub overwrite: bool,
9533    /// The target table
9534    pub table: Expression,
9535    /// Optional PARTITION clause with key-value pairs
9536    pub partition: Vec<(Identifier, Expression)>,
9537    /// Optional INPUTFORMAT clause
9538    pub input_format: Option<String>,
9539    /// Optional SERDE clause
9540    pub serde: Option<String>,
9541}
9542
9543/// PRAGMA statement (SQLite)
9544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9545#[cfg_attr(feature = "bindings", derive(TS))]
9546pub struct Pragma {
9547    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
9548    pub schema: Option<Identifier>,
9549    /// The pragma name
9550    pub name: Identifier,
9551    /// Optional value for assignment (PRAGMA name = value)
9552    pub value: Option<Expression>,
9553    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
9554    pub args: Vec<Expression>,
9555    /// Whether this pragma should be generated using assignment syntax.
9556    #[serde(default)]
9557    pub use_assignment_syntax: bool,
9558}
9559
9560/// A privilege with optional column list for GRANT/REVOKE
9561/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
9562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9563#[cfg_attr(feature = "bindings", derive(TS))]
9564pub struct Privilege {
9565    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
9566    pub name: String,
9567    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
9568    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9569    pub columns: Vec<String>,
9570}
9571
9572/// Principal in GRANT/REVOKE (user, role, etc.)
9573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9574#[cfg_attr(feature = "bindings", derive(TS))]
9575pub struct GrantPrincipal {
9576    /// The name of the principal
9577    pub name: Identifier,
9578    /// Whether prefixed with ROLE keyword
9579    pub is_role: bool,
9580    /// Whether prefixed with GROUP keyword (Redshift)
9581    #[serde(default)]
9582    pub is_group: bool,
9583    /// Whether prefixed with SHARE keyword (Snowflake)
9584    #[serde(default)]
9585    pub is_share: bool,
9586}
9587
9588/// GRANT statement
9589#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9590#[cfg_attr(feature = "bindings", derive(TS))]
9591pub struct Grant {
9592    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
9593    pub privileges: Vec<Privilege>,
9594    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9595    pub kind: Option<String>,
9596    /// The object to grant on
9597    pub securable: Identifier,
9598    /// Function parameter types (for FUNCTION kind)
9599    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9600    pub function_params: Vec<String>,
9601    /// The grantees
9602    pub principals: Vec<GrantPrincipal>,
9603    /// WITH GRANT OPTION
9604    pub grant_option: bool,
9605    /// TSQL: AS principal (the grantor role)
9606    #[serde(default, skip_serializing_if = "Option::is_none")]
9607    pub as_principal: Option<Identifier>,
9608}
9609
9610/// REVOKE statement
9611#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9612#[cfg_attr(feature = "bindings", derive(TS))]
9613pub struct Revoke {
9614    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9615    pub privileges: Vec<Privilege>,
9616    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9617    pub kind: Option<String>,
9618    /// The object to revoke from
9619    pub securable: Identifier,
9620    /// Function parameter types (for FUNCTION kind)
9621    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9622    pub function_params: Vec<String>,
9623    /// The grantees
9624    pub principals: Vec<GrantPrincipal>,
9625    /// GRANT OPTION FOR
9626    pub grant_option: bool,
9627    /// CASCADE
9628    pub cascade: bool,
9629    /// RESTRICT
9630    #[serde(default)]
9631    pub restrict: bool,
9632}
9633
9634/// COMMENT ON statement
9635#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9636#[cfg_attr(feature = "bindings", derive(TS))]
9637pub struct Comment {
9638    /// The object being commented on
9639    pub this: Expression,
9640    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9641    pub kind: String,
9642    /// The comment text expression
9643    pub expression: Expression,
9644    /// IF EXISTS clause
9645    pub exists: bool,
9646    /// MATERIALIZED keyword
9647    pub materialized: bool,
9648}
9649
9650// ============================================================================
9651// Phase 4: Additional DDL Statements
9652// ============================================================================
9653
9654/// ALTER VIEW statement
9655#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9656#[cfg_attr(feature = "bindings", derive(TS))]
9657pub struct AlterView {
9658    pub name: TableRef,
9659    pub actions: Vec<AlterViewAction>,
9660    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9661    #[serde(default, skip_serializing_if = "Option::is_none")]
9662    pub algorithm: Option<String>,
9663    /// MySQL: DEFINER = 'user'@'host'
9664    #[serde(default, skip_serializing_if = "Option::is_none")]
9665    pub definer: Option<String>,
9666    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9667    #[serde(default, skip_serializing_if = "Option::is_none")]
9668    pub sql_security: Option<String>,
9669    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9670    #[serde(default, skip_serializing_if = "Option::is_none")]
9671    pub with_option: Option<String>,
9672    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9673    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9674    pub columns: Vec<ViewColumn>,
9675}
9676
9677/// Actions for ALTER VIEW
9678#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9679#[cfg_attr(feature = "bindings", derive(TS))]
9680pub enum AlterViewAction {
9681    /// Rename the view
9682    Rename(TableRef),
9683    /// Change owner
9684    OwnerTo(Identifier),
9685    /// Set schema
9686    SetSchema(Identifier),
9687    /// Set authorization (Trino/Presto)
9688    SetAuthorization(String),
9689    /// Alter column
9690    AlterColumn {
9691        name: Identifier,
9692        action: AlterColumnAction,
9693    },
9694    /// Redefine view as query (SELECT, UNION, etc.)
9695    AsSelect(Box<Expression>),
9696    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9697    SetTblproperties(Vec<(String, String)>),
9698    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9699    UnsetTblproperties(Vec<String>),
9700}
9701
9702impl AlterView {
9703    pub fn new(name: impl Into<String>) -> Self {
9704        Self {
9705            name: TableRef::new(name),
9706            actions: Vec::new(),
9707            algorithm: None,
9708            definer: None,
9709            sql_security: None,
9710            with_option: None,
9711            columns: Vec::new(),
9712        }
9713    }
9714}
9715
9716/// ALTER INDEX statement
9717#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9718#[cfg_attr(feature = "bindings", derive(TS))]
9719pub struct AlterIndex {
9720    pub name: Identifier,
9721    pub table: Option<TableRef>,
9722    pub actions: Vec<AlterIndexAction>,
9723}
9724
9725/// Actions for ALTER INDEX
9726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9727#[cfg_attr(feature = "bindings", derive(TS))]
9728pub enum AlterIndexAction {
9729    /// Rename the index
9730    Rename(Identifier),
9731    /// Set tablespace
9732    SetTablespace(Identifier),
9733    /// Set visibility (MySQL)
9734    Visible(bool),
9735}
9736
9737impl AlterIndex {
9738    pub fn new(name: impl Into<String>) -> Self {
9739        Self {
9740            name: Identifier::new(name),
9741            table: None,
9742            actions: Vec::new(),
9743        }
9744    }
9745}
9746
9747/// CREATE SCHEMA statement
9748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9749#[cfg_attr(feature = "bindings", derive(TS))]
9750pub struct CreateSchema {
9751    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9752    pub name: Vec<Identifier>,
9753    pub if_not_exists: bool,
9754    pub authorization: Option<Identifier>,
9755    /// CLONE source parts, possibly dot-qualified
9756    #[serde(default)]
9757    pub clone_from: Option<Vec<Identifier>>,
9758    /// AT/BEFORE clause for time travel (Snowflake)
9759    #[serde(default)]
9760    pub at_clause: Option<Expression>,
9761    /// Schema properties like DEFAULT COLLATE
9762    #[serde(default)]
9763    pub properties: Vec<Expression>,
9764    /// Leading comments before the statement
9765    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9766    pub leading_comments: Vec<String>,
9767}
9768
9769impl CreateSchema {
9770    pub fn new(name: impl Into<String>) -> Self {
9771        Self {
9772            name: vec![Identifier::new(name)],
9773            if_not_exists: false,
9774            authorization: None,
9775            clone_from: None,
9776            at_clause: None,
9777            properties: Vec::new(),
9778            leading_comments: Vec::new(),
9779        }
9780    }
9781}
9782
9783/// DROP SCHEMA statement
9784#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9785#[cfg_attr(feature = "bindings", derive(TS))]
9786pub struct DropSchema {
9787    pub name: Identifier,
9788    pub if_exists: bool,
9789    pub cascade: bool,
9790}
9791
9792impl DropSchema {
9793    pub fn new(name: impl Into<String>) -> Self {
9794        Self {
9795            name: Identifier::new(name),
9796            if_exists: false,
9797            cascade: false,
9798        }
9799    }
9800}
9801
9802/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9803#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9804#[cfg_attr(feature = "bindings", derive(TS))]
9805pub struct DropNamespace {
9806    pub name: Identifier,
9807    pub if_exists: bool,
9808    pub cascade: bool,
9809}
9810
9811impl DropNamespace {
9812    pub fn new(name: impl Into<String>) -> Self {
9813        Self {
9814            name: Identifier::new(name),
9815            if_exists: false,
9816            cascade: false,
9817        }
9818    }
9819}
9820
9821/// CREATE DATABASE statement
9822#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9823#[cfg_attr(feature = "bindings", derive(TS))]
9824pub struct CreateDatabase {
9825    pub name: Identifier,
9826    pub if_not_exists: bool,
9827    pub options: Vec<DatabaseOption>,
9828    /// Snowflake CLONE source
9829    #[serde(default)]
9830    pub clone_from: Option<Identifier>,
9831    /// AT/BEFORE clause for time travel (Snowflake)
9832    #[serde(default)]
9833    pub at_clause: Option<Expression>,
9834}
9835
9836/// Database option
9837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9838#[cfg_attr(feature = "bindings", derive(TS))]
9839pub enum DatabaseOption {
9840    CharacterSet(String),
9841    Collate(String),
9842    Owner(Identifier),
9843    Template(Identifier),
9844    Encoding(String),
9845    Location(String),
9846}
9847
9848impl CreateDatabase {
9849    pub fn new(name: impl Into<String>) -> Self {
9850        Self {
9851            name: Identifier::new(name),
9852            if_not_exists: false,
9853            options: Vec::new(),
9854            clone_from: None,
9855            at_clause: None,
9856        }
9857    }
9858}
9859
9860/// DROP DATABASE statement
9861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9862#[cfg_attr(feature = "bindings", derive(TS))]
9863pub struct DropDatabase {
9864    pub name: Identifier,
9865    pub if_exists: bool,
9866    /// ClickHouse: SYNC modifier
9867    #[serde(default)]
9868    pub sync: bool,
9869}
9870
9871impl DropDatabase {
9872    pub fn new(name: impl Into<String>) -> Self {
9873        Self {
9874            name: Identifier::new(name),
9875            if_exists: false,
9876            sync: false,
9877        }
9878    }
9879}
9880
9881/// CREATE FUNCTION statement
9882#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9883#[cfg_attr(feature = "bindings", derive(TS))]
9884pub struct CreateFunction {
9885    pub name: TableRef,
9886    pub parameters: Vec<FunctionParameter>,
9887    pub return_type: Option<DataType>,
9888    pub body: Option<FunctionBody>,
9889    pub or_replace: bool,
9890    /// TSQL: CREATE OR ALTER
9891    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9892    pub or_alter: bool,
9893    pub if_not_exists: bool,
9894    pub temporary: bool,
9895    pub language: Option<String>,
9896    pub deterministic: Option<bool>,
9897    pub returns_null_on_null_input: Option<bool>,
9898    pub security: Option<FunctionSecurity>,
9899    /// Whether parentheses were present in the original syntax
9900    #[serde(default = "default_true")]
9901    pub has_parens: bool,
9902    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9903    #[serde(default)]
9904    pub sql_data_access: Option<SqlDataAccess>,
9905    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9906    #[serde(default, skip_serializing_if = "Option::is_none")]
9907    pub returns_table_body: Option<String>,
9908    /// True if LANGUAGE clause appears before RETURNS clause
9909    #[serde(default)]
9910    pub language_first: bool,
9911    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9912    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9913    pub set_options: Vec<FunctionSetOption>,
9914    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9915    #[serde(default)]
9916    pub strict: bool,
9917    /// BigQuery: OPTIONS (key=value, ...)
9918    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9919    pub options: Vec<Expression>,
9920    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9921    #[serde(default)]
9922    pub is_table_function: bool,
9923    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9924    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9925    pub property_order: Vec<FunctionPropertyKind>,
9926    /// Hive: USING JAR|FILE|ARCHIVE '...'
9927    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9928    pub using_resources: Vec<FunctionUsingResource>,
9929    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9930    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9931    pub environment: Vec<Expression>,
9932    /// HANDLER 'handler_function' clause (Databricks)
9933    #[serde(default, skip_serializing_if = "Option::is_none")]
9934    pub handler: Option<String>,
9935    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9936    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9937    pub handler_uses_eq: bool,
9938    /// Snowflake: RUNTIME_VERSION='3.11'
9939    #[serde(default, skip_serializing_if = "Option::is_none")]
9940    pub runtime_version: Option<String>,
9941    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9942    #[serde(default, skip_serializing_if = "Option::is_none")]
9943    pub packages: Option<Vec<String>>,
9944    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9945    #[serde(default, skip_serializing_if = "Option::is_none")]
9946    pub parameter_style: Option<String>,
9947}
9948
9949/// A SET option in CREATE FUNCTION (PostgreSQL)
9950#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9951#[cfg_attr(feature = "bindings", derive(TS))]
9952pub struct FunctionSetOption {
9953    pub name: String,
9954    pub value: FunctionSetValue,
9955}
9956
9957/// The value of a SET option
9958#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9959#[cfg_attr(feature = "bindings", derive(TS))]
9960pub enum FunctionSetValue {
9961    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9962    Value { value: String, use_to: bool },
9963    /// SET key FROM CURRENT
9964    FromCurrent,
9965}
9966
9967/// SQL data access characteristics for functions
9968#[derive(
9969    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9970)]
9971#[cfg_attr(feature = "bindings", derive(TS))]
9972pub enum SqlDataAccess {
9973    /// NO SQL
9974    NoSql,
9975    /// CONTAINS SQL
9976    ContainsSql,
9977    /// READS SQL DATA
9978    ReadsSqlData,
9979    /// MODIFIES SQL DATA
9980    ModifiesSqlData,
9981}
9982
9983/// Types of properties in CREATE FUNCTION for tracking their original order
9984#[derive(
9985    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9986)]
9987#[cfg_attr(feature = "bindings", derive(TS))]
9988pub enum FunctionPropertyKind {
9989    /// SET option
9990    Set,
9991    /// AS body
9992    As,
9993    /// Hive: USING JAR|FILE|ARCHIVE ...
9994    Using,
9995    /// LANGUAGE clause
9996    Language,
9997    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9998    Determinism,
9999    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
10000    NullInput,
10001    /// SECURITY DEFINER/INVOKER
10002    Security,
10003    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
10004    SqlDataAccess,
10005    /// OPTIONS clause (BigQuery)
10006    Options,
10007    /// ENVIRONMENT clause (Databricks)
10008    Environment,
10009    /// HANDLER clause (Databricks)
10010    Handler,
10011    /// Snowflake: RUNTIME_VERSION='...'
10012    RuntimeVersion,
10013    /// Snowflake: PACKAGES=(...)
10014    Packages,
10015    /// PARAMETER STYLE clause (Databricks)
10016    ParameterStyle,
10017}
10018
10019/// Hive CREATE FUNCTION resource in a USING clause
10020#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10021#[cfg_attr(feature = "bindings", derive(TS))]
10022pub struct FunctionUsingResource {
10023    pub kind: String,
10024    pub uri: String,
10025}
10026
10027/// Function parameter
10028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10029#[cfg_attr(feature = "bindings", derive(TS))]
10030pub struct FunctionParameter {
10031    pub name: Option<Identifier>,
10032    pub data_type: DataType,
10033    pub mode: Option<ParameterMode>,
10034    pub default: Option<Expression>,
10035    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
10036    #[serde(default, skip_serializing_if = "Option::is_none")]
10037    pub mode_text: Option<String>,
10038}
10039
10040/// Parameter mode (IN, OUT, INOUT, VARIADIC)
10041#[derive(
10042    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10043)]
10044#[cfg_attr(feature = "bindings", derive(TS))]
10045pub enum ParameterMode {
10046    In,
10047    Out,
10048    InOut,
10049    Variadic,
10050}
10051
10052/// Function body
10053#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10054#[cfg_attr(feature = "bindings", derive(TS))]
10055pub enum FunctionBody {
10056    /// AS $$ ... $$ (dollar-quoted)
10057    Block(String),
10058    /// AS 'string' (single-quoted string literal body)
10059    StringLiteral(String),
10060    /// AS 'expression'
10061    Expression(Expression),
10062    /// EXTERNAL NAME 'library'
10063    External(String),
10064    /// RETURN expression
10065    Return(Expression),
10066    /// BEGIN ... END block with parsed statements
10067    Statements(Vec<Expression>),
10068    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
10069    /// Stores (content, optional_tag)
10070    DollarQuoted {
10071        content: String,
10072        tag: Option<String>,
10073    },
10074    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
10075    RawBlock(String),
10076}
10077
10078/// Function security (DEFINER, INVOKER, or NONE)
10079#[derive(
10080    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10081)]
10082#[cfg_attr(feature = "bindings", derive(TS))]
10083pub enum FunctionSecurity {
10084    Definer,
10085    Invoker,
10086    /// StarRocks/MySQL: SECURITY NONE
10087    None,
10088}
10089
10090impl CreateFunction {
10091    pub fn new(name: impl Into<String>) -> Self {
10092        Self {
10093            name: TableRef::new(name),
10094            parameters: Vec::new(),
10095            return_type: None,
10096            body: None,
10097            or_replace: false,
10098            or_alter: false,
10099            if_not_exists: false,
10100            temporary: false,
10101            language: None,
10102            deterministic: None,
10103            returns_null_on_null_input: None,
10104            security: None,
10105            has_parens: true,
10106            sql_data_access: None,
10107            returns_table_body: None,
10108            language_first: false,
10109            set_options: Vec::new(),
10110            strict: false,
10111            options: Vec::new(),
10112            is_table_function: false,
10113            property_order: Vec::new(),
10114            using_resources: Vec::new(),
10115            environment: Vec::new(),
10116            handler: None,
10117            handler_uses_eq: false,
10118            runtime_version: None,
10119            packages: None,
10120            parameter_style: None,
10121        }
10122    }
10123}
10124
10125/// DROP FUNCTION statement
10126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10127#[cfg_attr(feature = "bindings", derive(TS))]
10128pub struct DropFunction {
10129    pub name: TableRef,
10130    pub parameters: Option<Vec<DataType>>,
10131    pub if_exists: bool,
10132    pub cascade: bool,
10133}
10134
10135impl DropFunction {
10136    pub fn new(name: impl Into<String>) -> Self {
10137        Self {
10138            name: TableRef::new(name),
10139            parameters: None,
10140            if_exists: false,
10141            cascade: false,
10142        }
10143    }
10144}
10145
10146/// CREATE PROCEDURE statement
10147#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10148#[cfg_attr(feature = "bindings", derive(TS))]
10149pub struct CreateProcedure {
10150    pub name: TableRef,
10151    pub parameters: Vec<FunctionParameter>,
10152    pub body: Option<FunctionBody>,
10153    pub or_replace: bool,
10154    /// TSQL: CREATE OR ALTER
10155    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10156    pub or_alter: bool,
10157    pub if_not_exists: bool,
10158    pub language: Option<String>,
10159    pub security: Option<FunctionSecurity>,
10160    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
10161    #[serde(default)]
10162    pub return_type: Option<DataType>,
10163    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
10164    #[serde(default)]
10165    pub execute_as: Option<String>,
10166    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
10167    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10168    pub with_options: Vec<String>,
10169    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
10170    #[serde(default = "default_true", skip_serializing_if = "is_true")]
10171    pub has_parens: bool,
10172    /// Whether the short form PROC was used (instead of PROCEDURE)
10173    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10174    pub use_proc_keyword: bool,
10175}
10176
10177impl CreateProcedure {
10178    pub fn new(name: impl Into<String>) -> Self {
10179        Self {
10180            name: TableRef::new(name),
10181            parameters: Vec::new(),
10182            body: None,
10183            or_replace: false,
10184            or_alter: false,
10185            if_not_exists: false,
10186            language: None,
10187            security: None,
10188            return_type: None,
10189            execute_as: None,
10190            with_options: Vec::new(),
10191            has_parens: true,
10192            use_proc_keyword: false,
10193        }
10194    }
10195}
10196
10197/// DROP PROCEDURE statement
10198#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10199#[cfg_attr(feature = "bindings", derive(TS))]
10200pub struct DropProcedure {
10201    pub name: TableRef,
10202    pub parameters: Option<Vec<DataType>>,
10203    pub if_exists: bool,
10204    pub cascade: bool,
10205}
10206
10207impl DropProcedure {
10208    pub fn new(name: impl Into<String>) -> Self {
10209        Self {
10210            name: TableRef::new(name),
10211            parameters: None,
10212            if_exists: false,
10213            cascade: false,
10214        }
10215    }
10216}
10217
10218/// Sequence property tag for ordering
10219#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10220#[cfg_attr(feature = "bindings", derive(TS))]
10221pub enum SeqPropKind {
10222    Start,
10223    Increment,
10224    Minvalue,
10225    Maxvalue,
10226    Cache,
10227    NoCache,
10228    Cycle,
10229    NoCycle,
10230    OwnedBy,
10231    Order,
10232    NoOrder,
10233    Comment,
10234    /// SHARING=<value> (Oracle)
10235    Sharing,
10236    /// KEEP (Oracle)
10237    Keep,
10238    /// NOKEEP (Oracle)
10239    NoKeep,
10240    /// SCALE [EXTEND|NOEXTEND] (Oracle)
10241    Scale,
10242    /// NOSCALE (Oracle)
10243    NoScale,
10244    /// SHARD [EXTEND|NOEXTEND] (Oracle)
10245    Shard,
10246    /// NOSHARD (Oracle)
10247    NoShard,
10248    /// SESSION (Oracle)
10249    Session,
10250    /// GLOBAL (Oracle)
10251    Global,
10252    /// NOCACHE (single word, Oracle)
10253    NoCacheWord,
10254    /// NOCYCLE (single word, Oracle)
10255    NoCycleWord,
10256    /// NOMINVALUE (single word, Oracle)
10257    NoMinvalueWord,
10258    /// NOMAXVALUE (single word, Oracle)
10259    NoMaxvalueWord,
10260}
10261
10262/// CREATE SYNONYM statement (TSQL)
10263#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10264#[cfg_attr(feature = "bindings", derive(TS))]
10265pub struct CreateSynonym {
10266    /// The synonym name (can be qualified: schema.synonym_name)
10267    pub name: TableRef,
10268    /// The target object the synonym refers to
10269    pub target: TableRef,
10270}
10271
10272/// CREATE SEQUENCE statement
10273#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10274#[cfg_attr(feature = "bindings", derive(TS))]
10275pub struct CreateSequence {
10276    pub name: TableRef,
10277    pub if_not_exists: bool,
10278    pub temporary: bool,
10279    #[serde(default)]
10280    pub or_replace: bool,
10281    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
10282    #[serde(default, skip_serializing_if = "Option::is_none")]
10283    pub as_type: Option<DataType>,
10284    pub increment: Option<i64>,
10285    pub minvalue: Option<SequenceBound>,
10286    pub maxvalue: Option<SequenceBound>,
10287    pub start: Option<i64>,
10288    pub cache: Option<i64>,
10289    pub cycle: bool,
10290    pub owned_by: Option<TableRef>,
10291    /// Whether OWNED BY NONE was specified
10292    #[serde(default)]
10293    pub owned_by_none: bool,
10294    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
10295    #[serde(default)]
10296    pub order: Option<bool>,
10297    /// Snowflake: COMMENT = 'value'
10298    #[serde(default)]
10299    pub comment: Option<String>,
10300    /// SHARING=<value> (Oracle)
10301    #[serde(default, skip_serializing_if = "Option::is_none")]
10302    pub sharing: Option<String>,
10303    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
10304    #[serde(default, skip_serializing_if = "Option::is_none")]
10305    pub scale_modifier: Option<String>,
10306    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
10307    #[serde(default, skip_serializing_if = "Option::is_none")]
10308    pub shard_modifier: Option<String>,
10309    /// Tracks the order in which properties appeared in the source
10310    #[serde(default)]
10311    pub property_order: Vec<SeqPropKind>,
10312}
10313
10314/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
10315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10316#[cfg_attr(feature = "bindings", derive(TS))]
10317pub enum SequenceBound {
10318    Value(i64),
10319    None,
10320}
10321
10322impl CreateSequence {
10323    pub fn new(name: impl Into<String>) -> Self {
10324        Self {
10325            name: TableRef::new(name),
10326            if_not_exists: false,
10327            temporary: false,
10328            or_replace: false,
10329            as_type: None,
10330            increment: None,
10331            minvalue: None,
10332            maxvalue: None,
10333            start: None,
10334            cache: None,
10335            cycle: false,
10336            owned_by: None,
10337            owned_by_none: false,
10338            order: None,
10339            comment: None,
10340            sharing: None,
10341            scale_modifier: None,
10342            shard_modifier: None,
10343            property_order: Vec::new(),
10344        }
10345    }
10346}
10347
10348/// DROP SEQUENCE statement
10349#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10350#[cfg_attr(feature = "bindings", derive(TS))]
10351pub struct DropSequence {
10352    pub name: TableRef,
10353    pub if_exists: bool,
10354    pub cascade: bool,
10355}
10356
10357impl DropSequence {
10358    pub fn new(name: impl Into<String>) -> Self {
10359        Self {
10360            name: TableRef::new(name),
10361            if_exists: false,
10362            cascade: false,
10363        }
10364    }
10365}
10366
10367/// ALTER SEQUENCE statement
10368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10369#[cfg_attr(feature = "bindings", derive(TS))]
10370pub struct AlterSequence {
10371    pub name: TableRef,
10372    pub if_exists: bool,
10373    pub increment: Option<i64>,
10374    pub minvalue: Option<SequenceBound>,
10375    pub maxvalue: Option<SequenceBound>,
10376    pub start: Option<i64>,
10377    pub restart: Option<Option<i64>>,
10378    pub cache: Option<i64>,
10379    pub cycle: Option<bool>,
10380    pub owned_by: Option<Option<TableRef>>,
10381}
10382
10383impl AlterSequence {
10384    pub fn new(name: impl Into<String>) -> Self {
10385        Self {
10386            name: TableRef::new(name),
10387            if_exists: false,
10388            increment: None,
10389            minvalue: None,
10390            maxvalue: None,
10391            start: None,
10392            restart: None,
10393            cache: None,
10394            cycle: None,
10395            owned_by: None,
10396        }
10397    }
10398}
10399
10400/// CREATE TRIGGER statement
10401#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10402#[cfg_attr(feature = "bindings", derive(TS))]
10403pub struct CreateTrigger {
10404    pub name: Identifier,
10405    pub table: TableRef,
10406    pub timing: TriggerTiming,
10407    pub events: Vec<TriggerEvent>,
10408    #[serde(default, skip_serializing_if = "Option::is_none")]
10409    pub for_each: Option<TriggerForEach>,
10410    pub when: Option<Expression>,
10411    /// Whether the WHEN clause was parenthesized in the original SQL
10412    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10413    pub when_paren: bool,
10414    pub body: TriggerBody,
10415    pub or_replace: bool,
10416    /// TSQL: CREATE OR ALTER
10417    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10418    pub or_alter: bool,
10419    pub constraint: bool,
10420    pub deferrable: Option<bool>,
10421    pub initially_deferred: Option<bool>,
10422    pub referencing: Option<TriggerReferencing>,
10423}
10424
10425/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
10426#[derive(
10427    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10428)]
10429#[cfg_attr(feature = "bindings", derive(TS))]
10430pub enum TriggerTiming {
10431    Before,
10432    After,
10433    InsteadOf,
10434}
10435
10436/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
10437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10438#[cfg_attr(feature = "bindings", derive(TS))]
10439pub enum TriggerEvent {
10440    Insert,
10441    Update(Option<Vec<Identifier>>),
10442    Delete,
10443    Truncate,
10444}
10445
10446/// Trigger FOR EACH clause
10447#[derive(
10448    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10449)]
10450#[cfg_attr(feature = "bindings", derive(TS))]
10451pub enum TriggerForEach {
10452    Row,
10453    Statement,
10454}
10455
10456/// Trigger body
10457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10458#[cfg_attr(feature = "bindings", derive(TS))]
10459pub enum TriggerBody {
10460    /// EXECUTE FUNCTION/PROCEDURE name(args)
10461    Execute {
10462        function: TableRef,
10463        args: Vec<Expression>,
10464    },
10465    /// BEGIN ... END block
10466    Block(String),
10467}
10468
10469/// Trigger REFERENCING clause
10470#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10471#[cfg_attr(feature = "bindings", derive(TS))]
10472pub struct TriggerReferencing {
10473    pub old_table: Option<Identifier>,
10474    pub new_table: Option<Identifier>,
10475    pub old_row: Option<Identifier>,
10476    pub new_row: Option<Identifier>,
10477}
10478
10479impl CreateTrigger {
10480    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
10481        Self {
10482            name: Identifier::new(name),
10483            table: TableRef::new(table),
10484            timing: TriggerTiming::Before,
10485            events: Vec::new(),
10486            for_each: Some(TriggerForEach::Row),
10487            when: None,
10488            when_paren: false,
10489            body: TriggerBody::Execute {
10490                function: TableRef::new(""),
10491                args: Vec::new(),
10492            },
10493            or_replace: false,
10494            or_alter: false,
10495            constraint: false,
10496            deferrable: None,
10497            initially_deferred: None,
10498            referencing: None,
10499        }
10500    }
10501}
10502
10503/// DROP TRIGGER statement
10504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10505#[cfg_attr(feature = "bindings", derive(TS))]
10506pub struct DropTrigger {
10507    pub name: Identifier,
10508    pub table: Option<TableRef>,
10509    pub if_exists: bool,
10510    pub cascade: bool,
10511}
10512
10513impl DropTrigger {
10514    pub fn new(name: impl Into<String>) -> Self {
10515        Self {
10516            name: Identifier::new(name),
10517            table: None,
10518            if_exists: false,
10519            cascade: false,
10520        }
10521    }
10522}
10523
10524/// CREATE TYPE statement
10525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10526#[cfg_attr(feature = "bindings", derive(TS))]
10527pub struct CreateType {
10528    pub name: TableRef,
10529    pub definition: TypeDefinition,
10530    pub if_not_exists: bool,
10531}
10532
10533/// Type definition
10534#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10535#[cfg_attr(feature = "bindings", derive(TS))]
10536pub enum TypeDefinition {
10537    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
10538    Enum(Vec<String>),
10539    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
10540    Composite(Vec<TypeAttribute>),
10541    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
10542    Range {
10543        subtype: DataType,
10544        subtype_diff: Option<String>,
10545        canonical: Option<String>,
10546    },
10547    /// Base type (for advanced usage)
10548    Base {
10549        input: String,
10550        output: String,
10551        internallength: Option<i32>,
10552    },
10553    /// Domain type
10554    Domain {
10555        base_type: DataType,
10556        default: Option<Expression>,
10557        constraints: Vec<DomainConstraint>,
10558    },
10559}
10560
10561/// Type attribute for composite types
10562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10563#[cfg_attr(feature = "bindings", derive(TS))]
10564pub struct TypeAttribute {
10565    pub name: Identifier,
10566    pub data_type: DataType,
10567    pub collate: Option<Identifier>,
10568}
10569
10570/// Domain constraint
10571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10572#[cfg_attr(feature = "bindings", derive(TS))]
10573pub struct DomainConstraint {
10574    pub name: Option<Identifier>,
10575    pub check: Expression,
10576}
10577
10578impl CreateType {
10579    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
10580        Self {
10581            name: TableRef::new(name),
10582            definition: TypeDefinition::Enum(values),
10583            if_not_exists: false,
10584        }
10585    }
10586
10587    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
10588        Self {
10589            name: TableRef::new(name),
10590            definition: TypeDefinition::Composite(attributes),
10591            if_not_exists: false,
10592        }
10593    }
10594}
10595
10596/// DROP TYPE statement
10597#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10598#[cfg_attr(feature = "bindings", derive(TS))]
10599pub struct DropType {
10600    pub name: TableRef,
10601    pub if_exists: bool,
10602    pub cascade: bool,
10603}
10604
10605impl DropType {
10606    pub fn new(name: impl Into<String>) -> Self {
10607        Self {
10608            name: TableRef::new(name),
10609            if_exists: false,
10610            cascade: false,
10611        }
10612    }
10613}
10614
10615/// DESCRIBE statement - shows table structure or query plan
10616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10617#[cfg_attr(feature = "bindings", derive(TS))]
10618pub struct Describe {
10619    /// The target to describe (table name or query)
10620    pub target: Expression,
10621    /// EXTENDED format
10622    pub extended: bool,
10623    /// FORMATTED format
10624    pub formatted: bool,
10625    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10626    #[serde(default)]
10627    pub kind: Option<String>,
10628    /// Properties like type=stage
10629    #[serde(default)]
10630    pub properties: Vec<(String, String)>,
10631    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10632    #[serde(default, skip_serializing_if = "Option::is_none")]
10633    pub style: Option<String>,
10634    /// Partition specification for DESCRIBE PARTITION
10635    #[serde(default)]
10636    pub partition: Option<Box<Expression>>,
10637    /// Leading comments before the statement
10638    #[serde(default)]
10639    pub leading_comments: Vec<String>,
10640    /// AS JSON suffix (Databricks)
10641    #[serde(default)]
10642    pub as_json: bool,
10643    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10644    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10645    pub params: Vec<String>,
10646}
10647
10648impl Describe {
10649    pub fn new(target: Expression) -> Self {
10650        Self {
10651            target,
10652            extended: false,
10653            formatted: false,
10654            kind: None,
10655            properties: Vec::new(),
10656            style: None,
10657            partition: None,
10658            leading_comments: Vec::new(),
10659            as_json: false,
10660            params: Vec::new(),
10661        }
10662    }
10663}
10664
10665/// SHOW statement - displays database objects
10666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10667#[cfg_attr(feature = "bindings", derive(TS))]
10668pub struct Show {
10669    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10670    pub this: String,
10671    /// Whether TERSE was specified
10672    #[serde(default)]
10673    pub terse: bool,
10674    /// Whether HISTORY was specified
10675    #[serde(default)]
10676    pub history: bool,
10677    /// LIKE pattern
10678    pub like: Option<Expression>,
10679    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10680    pub scope_kind: Option<String>,
10681    /// IN scope object
10682    pub scope: Option<Expression>,
10683    /// STARTS WITH pattern
10684    pub starts_with: Option<Expression>,
10685    /// LIMIT clause
10686    pub limit: Option<Box<Limit>>,
10687    /// FROM clause (for specific object)
10688    pub from: Option<Expression>,
10689    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10690    #[serde(default, skip_serializing_if = "Option::is_none")]
10691    pub where_clause: Option<Expression>,
10692    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10693    #[serde(default, skip_serializing_if = "Option::is_none")]
10694    pub for_target: Option<Expression>,
10695    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10696    #[serde(default, skip_serializing_if = "Option::is_none")]
10697    pub db: Option<Expression>,
10698    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10699    #[serde(default, skip_serializing_if = "Option::is_none")]
10700    pub target: Option<Expression>,
10701    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10702    #[serde(default, skip_serializing_if = "Option::is_none")]
10703    pub mutex: Option<bool>,
10704    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10705    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10706    pub privileges: Vec<String>,
10707}
10708
10709impl Show {
10710    pub fn new(this: impl Into<String>) -> Self {
10711        Self {
10712            this: this.into(),
10713            terse: false,
10714            history: false,
10715            like: None,
10716            scope_kind: None,
10717            scope: None,
10718            starts_with: None,
10719            limit: None,
10720            from: None,
10721            where_clause: None,
10722            for_target: None,
10723            db: None,
10724            target: None,
10725            mutex: None,
10726            privileges: Vec::new(),
10727        }
10728    }
10729}
10730
10731/// Represent an explicit parenthesized expression for grouping precedence.
10732///
10733/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10734/// correctly instead of being flattened to `a + b * c`.
10735#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10736#[cfg_attr(feature = "bindings", derive(TS))]
10737pub struct Paren {
10738    /// The inner expression wrapped by parentheses.
10739    pub this: Expression,
10740    #[serde(default)]
10741    pub trailing_comments: Vec<String>,
10742}
10743
10744/// Expression annotated with trailing comments (for round-trip preservation)
10745#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10746#[cfg_attr(feature = "bindings", derive(TS))]
10747pub struct Annotated {
10748    pub this: Expression,
10749    pub trailing_comments: Vec<String>,
10750}
10751
10752// === BATCH GENERATED STRUCT DEFINITIONS ===
10753// Generated from Python sqlglot expressions.py
10754
10755/// Refresh
10756#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10757#[cfg_attr(feature = "bindings", derive(TS))]
10758pub struct Refresh {
10759    pub this: Box<Expression>,
10760    pub kind: String,
10761}
10762
10763/// LockingStatement
10764#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10765#[cfg_attr(feature = "bindings", derive(TS))]
10766pub struct LockingStatement {
10767    pub this: Box<Expression>,
10768    pub expression: Box<Expression>,
10769}
10770
10771/// SequenceProperties
10772#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10773#[cfg_attr(feature = "bindings", derive(TS))]
10774pub struct SequenceProperties {
10775    #[serde(default)]
10776    pub increment: Option<Box<Expression>>,
10777    #[serde(default)]
10778    pub minvalue: Option<Box<Expression>>,
10779    #[serde(default)]
10780    pub maxvalue: Option<Box<Expression>>,
10781    #[serde(default)]
10782    pub cache: Option<Box<Expression>>,
10783    #[serde(default)]
10784    pub start: Option<Box<Expression>>,
10785    #[serde(default)]
10786    pub owned: Option<Box<Expression>>,
10787    #[serde(default)]
10788    pub options: Vec<Expression>,
10789}
10790
10791/// TruncateTable
10792#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10793#[cfg_attr(feature = "bindings", derive(TS))]
10794pub struct TruncateTable {
10795    #[serde(default)]
10796    pub expressions: Vec<Expression>,
10797    #[serde(default)]
10798    pub is_database: Option<Box<Expression>>,
10799    #[serde(default)]
10800    pub exists: bool,
10801    #[serde(default)]
10802    pub only: Option<Box<Expression>>,
10803    #[serde(default)]
10804    pub cluster: Option<Box<Expression>>,
10805    #[serde(default)]
10806    pub identity: Option<Box<Expression>>,
10807    #[serde(default)]
10808    pub option: Option<Box<Expression>>,
10809    #[serde(default)]
10810    pub partition: Option<Box<Expression>>,
10811}
10812
10813/// Clone
10814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10815#[cfg_attr(feature = "bindings", derive(TS))]
10816pub struct Clone {
10817    pub this: Box<Expression>,
10818    #[serde(default)]
10819    pub shallow: Option<Box<Expression>>,
10820    #[serde(default)]
10821    pub copy: Option<Box<Expression>>,
10822}
10823
10824/// Attach
10825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10826#[cfg_attr(feature = "bindings", derive(TS))]
10827pub struct Attach {
10828    pub this: Box<Expression>,
10829    #[serde(default)]
10830    pub exists: bool,
10831    #[serde(default)]
10832    pub expressions: Vec<Expression>,
10833}
10834
10835/// Detach
10836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10837#[cfg_attr(feature = "bindings", derive(TS))]
10838pub struct Detach {
10839    pub this: Box<Expression>,
10840    #[serde(default)]
10841    pub exists: bool,
10842}
10843
10844/// Install
10845#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10846#[cfg_attr(feature = "bindings", derive(TS))]
10847pub struct Install {
10848    pub this: Box<Expression>,
10849    #[serde(default)]
10850    pub from_: Option<Box<Expression>>,
10851    #[serde(default)]
10852    pub force: Option<Box<Expression>>,
10853}
10854
10855/// Summarize
10856#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10857#[cfg_attr(feature = "bindings", derive(TS))]
10858pub struct Summarize {
10859    pub this: Box<Expression>,
10860    #[serde(default)]
10861    pub table: Option<Box<Expression>>,
10862}
10863
10864/// Declare
10865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10866#[cfg_attr(feature = "bindings", derive(TS))]
10867pub struct Declare {
10868    #[serde(default)]
10869    pub expressions: Vec<Expression>,
10870    #[serde(default)]
10871    pub replace: bool,
10872}
10873
10874/// DeclareItem
10875#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10876#[cfg_attr(feature = "bindings", derive(TS))]
10877pub struct DeclareItem {
10878    pub this: Box<Expression>,
10879    #[serde(default)]
10880    pub kind: Option<String>,
10881    #[serde(default)]
10882    pub default: Option<Box<Expression>>,
10883    #[serde(default)]
10884    pub has_as: bool,
10885    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10886    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10887    pub additional_names: Vec<Expression>,
10888}
10889
10890/// Set
10891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10892#[cfg_attr(feature = "bindings", derive(TS))]
10893pub struct Set {
10894    #[serde(default)]
10895    pub expressions: Vec<Expression>,
10896    #[serde(default)]
10897    pub unset: Option<Box<Expression>>,
10898    #[serde(default)]
10899    pub tag: Option<Box<Expression>>,
10900}
10901
10902/// Heredoc
10903#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10904#[cfg_attr(feature = "bindings", derive(TS))]
10905pub struct Heredoc {
10906    pub this: Box<Expression>,
10907    #[serde(default)]
10908    pub tag: Option<Box<Expression>>,
10909}
10910
10911/// QueryBand
10912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10913#[cfg_attr(feature = "bindings", derive(TS))]
10914pub struct QueryBand {
10915    pub this: Box<Expression>,
10916    #[serde(default)]
10917    pub scope: Option<Box<Expression>>,
10918    #[serde(default)]
10919    pub update: Option<Box<Expression>>,
10920}
10921
10922/// UserDefinedFunction
10923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10924#[cfg_attr(feature = "bindings", derive(TS))]
10925pub struct UserDefinedFunction {
10926    pub this: Box<Expression>,
10927    #[serde(default)]
10928    pub expressions: Vec<Expression>,
10929    #[serde(default)]
10930    pub wrapped: Option<Box<Expression>>,
10931}
10932
10933/// RecursiveWithSearch
10934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10935#[cfg_attr(feature = "bindings", derive(TS))]
10936pub struct RecursiveWithSearch {
10937    pub kind: String,
10938    pub this: Box<Expression>,
10939    pub expression: Box<Expression>,
10940    #[serde(default)]
10941    pub using: Option<Box<Expression>>,
10942}
10943
10944/// ProjectionDef
10945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10946#[cfg_attr(feature = "bindings", derive(TS))]
10947pub struct ProjectionDef {
10948    pub this: Box<Expression>,
10949    pub expression: Box<Expression>,
10950}
10951
10952/// TableAlias
10953#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10954#[cfg_attr(feature = "bindings", derive(TS))]
10955pub struct TableAlias {
10956    #[serde(default)]
10957    pub this: Option<Box<Expression>>,
10958    #[serde(default)]
10959    pub columns: Vec<Expression>,
10960}
10961
10962/// ByteString
10963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10964#[cfg_attr(feature = "bindings", derive(TS))]
10965pub struct ByteString {
10966    pub this: Box<Expression>,
10967    #[serde(default)]
10968    pub is_bytes: Option<Box<Expression>>,
10969}
10970
10971/// HexStringExpr - Hex string expression (not literal)
10972/// BigQuery: converts to FROM_HEX(this)
10973#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10974#[cfg_attr(feature = "bindings", derive(TS))]
10975pub struct HexStringExpr {
10976    pub this: Box<Expression>,
10977    #[serde(default)]
10978    pub is_integer: Option<bool>,
10979}
10980
10981/// UnicodeString
10982#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10983#[cfg_attr(feature = "bindings", derive(TS))]
10984pub struct UnicodeString {
10985    pub this: Box<Expression>,
10986    #[serde(default)]
10987    pub escape: Option<Box<Expression>>,
10988}
10989
10990/// AlterColumn
10991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10992#[cfg_attr(feature = "bindings", derive(TS))]
10993pub struct AlterColumn {
10994    pub this: Box<Expression>,
10995    #[serde(default)]
10996    pub dtype: Option<Box<Expression>>,
10997    #[serde(default)]
10998    pub collate: Option<Box<Expression>>,
10999    #[serde(default)]
11000    pub using: Option<Box<Expression>>,
11001    #[serde(default)]
11002    pub default: Option<Box<Expression>>,
11003    #[serde(default)]
11004    pub drop: Option<Box<Expression>>,
11005    #[serde(default)]
11006    pub comment: Option<Box<Expression>>,
11007    #[serde(default)]
11008    pub allow_null: Option<Box<Expression>>,
11009    #[serde(default)]
11010    pub visible: Option<Box<Expression>>,
11011    #[serde(default)]
11012    pub rename_to: Option<Box<Expression>>,
11013}
11014
11015/// AlterSortKey
11016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11017#[cfg_attr(feature = "bindings", derive(TS))]
11018pub struct AlterSortKey {
11019    #[serde(default)]
11020    pub this: Option<Box<Expression>>,
11021    #[serde(default)]
11022    pub expressions: Vec<Expression>,
11023    #[serde(default)]
11024    pub compound: Option<Box<Expression>>,
11025}
11026
11027/// AlterSet
11028#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11029#[cfg_attr(feature = "bindings", derive(TS))]
11030pub struct AlterSet {
11031    #[serde(default)]
11032    pub expressions: Vec<Expression>,
11033    #[serde(default)]
11034    pub option: Option<Box<Expression>>,
11035    #[serde(default)]
11036    pub tablespace: Option<Box<Expression>>,
11037    #[serde(default)]
11038    pub access_method: Option<Box<Expression>>,
11039    #[serde(default)]
11040    pub file_format: Option<Box<Expression>>,
11041    #[serde(default)]
11042    pub copy_options: Option<Box<Expression>>,
11043    #[serde(default)]
11044    pub tag: Option<Box<Expression>>,
11045    #[serde(default)]
11046    pub location: Option<Box<Expression>>,
11047    #[serde(default)]
11048    pub serde: Option<Box<Expression>>,
11049}
11050
11051/// RenameColumn
11052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11053#[cfg_attr(feature = "bindings", derive(TS))]
11054pub struct RenameColumn {
11055    pub this: Box<Expression>,
11056    #[serde(default)]
11057    pub to: Option<Box<Expression>>,
11058    #[serde(default)]
11059    pub exists: bool,
11060}
11061
11062/// Comprehension
11063#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11064#[cfg_attr(feature = "bindings", derive(TS))]
11065pub struct Comprehension {
11066    pub this: Box<Expression>,
11067    pub expression: Box<Expression>,
11068    #[serde(default)]
11069    pub position: Option<Box<Expression>>,
11070    #[serde(default)]
11071    pub iterator: Option<Box<Expression>>,
11072    #[serde(default)]
11073    pub condition: Option<Box<Expression>>,
11074}
11075
11076/// MergeTreeTTLAction
11077#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11078#[cfg_attr(feature = "bindings", derive(TS))]
11079pub struct MergeTreeTTLAction {
11080    pub this: Box<Expression>,
11081    #[serde(default)]
11082    pub delete: Option<Box<Expression>>,
11083    #[serde(default)]
11084    pub recompress: Option<Box<Expression>>,
11085    #[serde(default)]
11086    pub to_disk: Option<Box<Expression>>,
11087    #[serde(default)]
11088    pub to_volume: Option<Box<Expression>>,
11089}
11090
11091/// MergeTreeTTL
11092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11093#[cfg_attr(feature = "bindings", derive(TS))]
11094pub struct MergeTreeTTL {
11095    #[serde(default)]
11096    pub expressions: Vec<Expression>,
11097    #[serde(default)]
11098    pub where_: Option<Box<Expression>>,
11099    #[serde(default)]
11100    pub group: Option<Box<Expression>>,
11101    #[serde(default)]
11102    pub aggregates: Option<Box<Expression>>,
11103}
11104
11105/// IndexConstraintOption
11106#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11107#[cfg_attr(feature = "bindings", derive(TS))]
11108pub struct IndexConstraintOption {
11109    #[serde(default)]
11110    pub key_block_size: Option<Box<Expression>>,
11111    #[serde(default)]
11112    pub using: Option<Box<Expression>>,
11113    #[serde(default)]
11114    pub parser: Option<Box<Expression>>,
11115    #[serde(default)]
11116    pub comment: Option<Box<Expression>>,
11117    #[serde(default)]
11118    pub visible: Option<Box<Expression>>,
11119    #[serde(default)]
11120    pub engine_attr: Option<Box<Expression>>,
11121    #[serde(default)]
11122    pub secondary_engine_attr: Option<Box<Expression>>,
11123}
11124
11125/// PeriodForSystemTimeConstraint
11126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11127#[cfg_attr(feature = "bindings", derive(TS))]
11128pub struct PeriodForSystemTimeConstraint {
11129    pub this: Box<Expression>,
11130    pub expression: Box<Expression>,
11131}
11132
11133/// CaseSpecificColumnConstraint
11134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11135#[cfg_attr(feature = "bindings", derive(TS))]
11136pub struct CaseSpecificColumnConstraint {
11137    #[serde(default)]
11138    pub not_: Option<Box<Expression>>,
11139}
11140
11141/// CharacterSetColumnConstraint
11142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11143#[cfg_attr(feature = "bindings", derive(TS))]
11144pub struct CharacterSetColumnConstraint {
11145    pub this: Box<Expression>,
11146}
11147
11148/// CheckColumnConstraint
11149#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11150#[cfg_attr(feature = "bindings", derive(TS))]
11151pub struct CheckColumnConstraint {
11152    pub this: Box<Expression>,
11153    #[serde(default)]
11154    pub enforced: Option<Box<Expression>>,
11155}
11156
11157/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
11158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11159#[cfg_attr(feature = "bindings", derive(TS))]
11160pub struct AssumeColumnConstraint {
11161    pub this: Box<Expression>,
11162}
11163
11164/// CompressColumnConstraint
11165#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11166#[cfg_attr(feature = "bindings", derive(TS))]
11167pub struct CompressColumnConstraint {
11168    #[serde(default)]
11169    pub this: Option<Box<Expression>>,
11170}
11171
11172/// DateFormatColumnConstraint
11173#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11174#[cfg_attr(feature = "bindings", derive(TS))]
11175pub struct DateFormatColumnConstraint {
11176    pub this: Box<Expression>,
11177}
11178
11179/// EphemeralColumnConstraint
11180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11181#[cfg_attr(feature = "bindings", derive(TS))]
11182pub struct EphemeralColumnConstraint {
11183    #[serde(default)]
11184    pub this: Option<Box<Expression>>,
11185}
11186
11187/// WithOperator
11188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11189#[cfg_attr(feature = "bindings", derive(TS))]
11190pub struct WithOperator {
11191    pub this: Box<Expression>,
11192    pub op: String,
11193}
11194
11195/// GeneratedAsIdentityColumnConstraint
11196#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11197#[cfg_attr(feature = "bindings", derive(TS))]
11198pub struct GeneratedAsIdentityColumnConstraint {
11199    #[serde(default)]
11200    pub this: Option<Box<Expression>>,
11201    #[serde(default)]
11202    pub expression: Option<Box<Expression>>,
11203    #[serde(default)]
11204    pub on_null: Option<Box<Expression>>,
11205    #[serde(default)]
11206    pub start: Option<Box<Expression>>,
11207    #[serde(default)]
11208    pub increment: Option<Box<Expression>>,
11209    #[serde(default)]
11210    pub minvalue: Option<Box<Expression>>,
11211    #[serde(default)]
11212    pub maxvalue: Option<Box<Expression>>,
11213    #[serde(default)]
11214    pub cycle: Option<Box<Expression>>,
11215    #[serde(default)]
11216    pub order: Option<Box<Expression>>,
11217}
11218
11219/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
11220/// TSQL: outputs "IDENTITY"
11221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11222#[cfg_attr(feature = "bindings", derive(TS))]
11223pub struct AutoIncrementColumnConstraint;
11224
11225/// CommentColumnConstraint - Column comment marker
11226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11227#[cfg_attr(feature = "bindings", derive(TS))]
11228pub struct CommentColumnConstraint;
11229
11230/// GeneratedAsRowColumnConstraint
11231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11232#[cfg_attr(feature = "bindings", derive(TS))]
11233pub struct GeneratedAsRowColumnConstraint {
11234    #[serde(default)]
11235    pub start: Option<Box<Expression>>,
11236    #[serde(default)]
11237    pub hidden: Option<Box<Expression>>,
11238}
11239
11240/// IndexColumnConstraint
11241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11242#[cfg_attr(feature = "bindings", derive(TS))]
11243pub struct IndexColumnConstraint {
11244    #[serde(default)]
11245    pub this: Option<Box<Expression>>,
11246    #[serde(default)]
11247    pub expressions: Vec<Expression>,
11248    #[serde(default)]
11249    pub kind: Option<String>,
11250    #[serde(default)]
11251    pub index_type: Option<Box<Expression>>,
11252    #[serde(default)]
11253    pub options: Vec<Expression>,
11254    #[serde(default)]
11255    pub expression: Option<Box<Expression>>,
11256    #[serde(default)]
11257    pub granularity: Option<Box<Expression>>,
11258}
11259
11260/// MaskingPolicyColumnConstraint
11261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11262#[cfg_attr(feature = "bindings", derive(TS))]
11263pub struct MaskingPolicyColumnConstraint {
11264    pub this: Box<Expression>,
11265    #[serde(default)]
11266    pub expressions: Vec<Expression>,
11267}
11268
11269/// NotNullColumnConstraint
11270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11271#[cfg_attr(feature = "bindings", derive(TS))]
11272pub struct NotNullColumnConstraint {
11273    #[serde(default)]
11274    pub allow_null: Option<Box<Expression>>,
11275}
11276
11277/// DefaultColumnConstraint - DEFAULT value for a column
11278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11279#[cfg_attr(feature = "bindings", derive(TS))]
11280pub struct DefaultColumnConstraint {
11281    pub this: Box<Expression>,
11282    /// TSQL: DEFAULT value FOR column (table-level default constraint)
11283    #[serde(default, skip_serializing_if = "Option::is_none")]
11284    pub for_column: Option<Identifier>,
11285}
11286
11287/// PrimaryKeyColumnConstraint
11288#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11289#[cfg_attr(feature = "bindings", derive(TS))]
11290pub struct PrimaryKeyColumnConstraint {
11291    #[serde(default)]
11292    pub desc: Option<Box<Expression>>,
11293    #[serde(default)]
11294    pub options: Vec<Expression>,
11295}
11296
11297/// UniqueColumnConstraint
11298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11299#[cfg_attr(feature = "bindings", derive(TS))]
11300pub struct UniqueColumnConstraint {
11301    #[serde(default)]
11302    pub this: Option<Box<Expression>>,
11303    #[serde(default)]
11304    pub index_type: Option<Box<Expression>>,
11305    #[serde(default)]
11306    pub on_conflict: Option<Box<Expression>>,
11307    #[serde(default)]
11308    pub nulls: Option<Box<Expression>>,
11309    #[serde(default)]
11310    pub options: Vec<Expression>,
11311}
11312
11313/// WatermarkColumnConstraint
11314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11315#[cfg_attr(feature = "bindings", derive(TS))]
11316pub struct WatermarkColumnConstraint {
11317    pub this: Box<Expression>,
11318    pub expression: Box<Expression>,
11319}
11320
11321/// ComputedColumnConstraint
11322#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11323#[cfg_attr(feature = "bindings", derive(TS))]
11324pub struct ComputedColumnConstraint {
11325    pub this: Box<Expression>,
11326    #[serde(default)]
11327    pub persisted: Option<Box<Expression>>,
11328    #[serde(default)]
11329    pub not_null: Option<Box<Expression>>,
11330    #[serde(default)]
11331    pub data_type: Option<Box<Expression>>,
11332}
11333
11334/// InOutColumnConstraint
11335#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11336#[cfg_attr(feature = "bindings", derive(TS))]
11337pub struct InOutColumnConstraint {
11338    #[serde(default)]
11339    pub input_: Option<Box<Expression>>,
11340    #[serde(default)]
11341    pub output: Option<Box<Expression>>,
11342}
11343
11344/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
11345#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11346#[cfg_attr(feature = "bindings", derive(TS))]
11347pub struct PathColumnConstraint {
11348    pub this: Box<Expression>,
11349}
11350
11351/// Constraint
11352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11353#[cfg_attr(feature = "bindings", derive(TS))]
11354pub struct Constraint {
11355    pub this: Box<Expression>,
11356    #[serde(default)]
11357    pub expressions: Vec<Expression>,
11358}
11359
11360/// Export
11361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11362#[cfg_attr(feature = "bindings", derive(TS))]
11363pub struct Export {
11364    pub this: Box<Expression>,
11365    #[serde(default)]
11366    pub connection: Option<Box<Expression>>,
11367    #[serde(default)]
11368    pub options: Vec<Expression>,
11369}
11370
11371/// Filter
11372#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11373#[cfg_attr(feature = "bindings", derive(TS))]
11374pub struct Filter {
11375    pub this: Box<Expression>,
11376    pub expression: Box<Expression>,
11377}
11378
11379/// Changes
11380#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11381#[cfg_attr(feature = "bindings", derive(TS))]
11382pub struct Changes {
11383    #[serde(default)]
11384    pub information: Option<Box<Expression>>,
11385    #[serde(default)]
11386    pub at_before: Option<Box<Expression>>,
11387    #[serde(default)]
11388    pub end: Option<Box<Expression>>,
11389}
11390
11391/// Directory
11392#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11393#[cfg_attr(feature = "bindings", derive(TS))]
11394pub struct Directory {
11395    pub this: Box<Expression>,
11396    #[serde(default)]
11397    pub local: Option<Box<Expression>>,
11398    #[serde(default)]
11399    pub row_format: Option<Box<Expression>>,
11400}
11401
11402/// ForeignKey
11403#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11404#[cfg_attr(feature = "bindings", derive(TS))]
11405pub struct ForeignKey {
11406    #[serde(default)]
11407    pub expressions: Vec<Expression>,
11408    #[serde(default)]
11409    pub reference: Option<Box<Expression>>,
11410    #[serde(default)]
11411    pub delete: Option<Box<Expression>>,
11412    #[serde(default)]
11413    pub update: Option<Box<Expression>>,
11414    #[serde(default)]
11415    pub options: Vec<Expression>,
11416}
11417
11418/// ColumnPrefix
11419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11420#[cfg_attr(feature = "bindings", derive(TS))]
11421pub struct ColumnPrefix {
11422    pub this: Box<Expression>,
11423    pub expression: Box<Expression>,
11424}
11425
11426/// PrimaryKey
11427#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11428#[cfg_attr(feature = "bindings", derive(TS))]
11429pub struct PrimaryKey {
11430    #[serde(default)]
11431    pub this: Option<Box<Expression>>,
11432    #[serde(default)]
11433    pub expressions: Vec<Expression>,
11434    #[serde(default)]
11435    pub options: Vec<Expression>,
11436    #[serde(default)]
11437    pub include: Option<Box<Expression>>,
11438}
11439
11440/// Into
11441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11442#[cfg_attr(feature = "bindings", derive(TS))]
11443pub struct IntoClause {
11444    #[serde(default)]
11445    pub this: Option<Box<Expression>>,
11446    #[serde(default)]
11447    pub temporary: bool,
11448    #[serde(default)]
11449    pub unlogged: Option<Box<Expression>>,
11450    #[serde(default)]
11451    pub bulk_collect: Option<Box<Expression>>,
11452    #[serde(default)]
11453    pub expressions: Vec<Expression>,
11454}
11455
11456/// JoinHint
11457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11458#[cfg_attr(feature = "bindings", derive(TS))]
11459pub struct JoinHint {
11460    pub this: Box<Expression>,
11461    #[serde(default)]
11462    pub expressions: Vec<Expression>,
11463}
11464
11465/// Opclass
11466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11467#[cfg_attr(feature = "bindings", derive(TS))]
11468pub struct Opclass {
11469    pub this: Box<Expression>,
11470    pub expression: Box<Expression>,
11471}
11472
11473/// Index
11474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11475#[cfg_attr(feature = "bindings", derive(TS))]
11476pub struct Index {
11477    #[serde(default)]
11478    pub this: Option<Box<Expression>>,
11479    #[serde(default)]
11480    pub table: Option<Box<Expression>>,
11481    #[serde(default)]
11482    pub unique: bool,
11483    #[serde(default)]
11484    pub primary: Option<Box<Expression>>,
11485    #[serde(default)]
11486    pub amp: Option<Box<Expression>>,
11487    #[serde(default)]
11488    pub params: Vec<Expression>,
11489}
11490
11491/// IndexParameters
11492#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11493#[cfg_attr(feature = "bindings", derive(TS))]
11494pub struct IndexParameters {
11495    #[serde(default)]
11496    pub using: Option<Box<Expression>>,
11497    #[serde(default)]
11498    pub include: Option<Box<Expression>>,
11499    #[serde(default)]
11500    pub columns: Vec<Expression>,
11501    #[serde(default)]
11502    pub with_storage: Option<Box<Expression>>,
11503    #[serde(default)]
11504    pub partition_by: Option<Box<Expression>>,
11505    #[serde(default)]
11506    pub tablespace: Option<Box<Expression>>,
11507    #[serde(default)]
11508    pub where_: Option<Box<Expression>>,
11509    #[serde(default)]
11510    pub on: Option<Box<Expression>>,
11511}
11512
11513/// ConditionalInsert
11514#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11515#[cfg_attr(feature = "bindings", derive(TS))]
11516pub struct ConditionalInsert {
11517    pub this: Box<Expression>,
11518    #[serde(default)]
11519    pub expression: Option<Box<Expression>>,
11520    #[serde(default)]
11521    pub else_: Option<Box<Expression>>,
11522}
11523
11524/// MultitableInserts
11525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11526#[cfg_attr(feature = "bindings", derive(TS))]
11527pub struct MultitableInserts {
11528    #[serde(default)]
11529    pub expressions: Vec<Expression>,
11530    pub kind: String,
11531    #[serde(default)]
11532    pub source: Option<Box<Expression>>,
11533    /// Leading comments before the statement
11534    #[serde(default)]
11535    pub leading_comments: Vec<String>,
11536    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
11537    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11538    pub overwrite: bool,
11539}
11540
11541/// OnConflict
11542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11543#[cfg_attr(feature = "bindings", derive(TS))]
11544pub struct OnConflict {
11545    #[serde(default)]
11546    pub duplicate: Option<Box<Expression>>,
11547    #[serde(default)]
11548    pub expressions: Vec<Expression>,
11549    #[serde(default)]
11550    pub action: Option<Box<Expression>>,
11551    #[serde(default)]
11552    pub conflict_keys: Option<Box<Expression>>,
11553    #[serde(default)]
11554    pub index_predicate: Option<Box<Expression>>,
11555    #[serde(default)]
11556    pub constraint: Option<Box<Expression>>,
11557    #[serde(default)]
11558    pub where_: Option<Box<Expression>>,
11559}
11560
11561/// OnCondition
11562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11563#[cfg_attr(feature = "bindings", derive(TS))]
11564pub struct OnCondition {
11565    #[serde(default)]
11566    pub error: Option<Box<Expression>>,
11567    #[serde(default)]
11568    pub empty: Option<Box<Expression>>,
11569    #[serde(default)]
11570    pub null: Option<Box<Expression>>,
11571}
11572
11573/// Returning
11574#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11575#[cfg_attr(feature = "bindings", derive(TS))]
11576pub struct Returning {
11577    #[serde(default)]
11578    pub expressions: Vec<Expression>,
11579    #[serde(default)]
11580    pub into: Option<Box<Expression>>,
11581}
11582
11583/// Introducer
11584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11585#[cfg_attr(feature = "bindings", derive(TS))]
11586pub struct Introducer {
11587    pub this: Box<Expression>,
11588    pub expression: Box<Expression>,
11589}
11590
11591/// PartitionRange
11592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11593#[cfg_attr(feature = "bindings", derive(TS))]
11594pub struct PartitionRange {
11595    pub this: Box<Expression>,
11596    #[serde(default)]
11597    pub expression: Option<Box<Expression>>,
11598    #[serde(default)]
11599    pub expressions: Vec<Expression>,
11600}
11601
11602/// Group
11603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11604#[cfg_attr(feature = "bindings", derive(TS))]
11605pub struct Group {
11606    #[serde(default)]
11607    pub expressions: Vec<Expression>,
11608    #[serde(default)]
11609    pub grouping_sets: Option<Box<Expression>>,
11610    #[serde(default)]
11611    pub cube: Option<Box<Expression>>,
11612    #[serde(default)]
11613    pub rollup: Option<Box<Expression>>,
11614    #[serde(default)]
11615    pub totals: Option<Box<Expression>>,
11616    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11617    #[serde(default)]
11618    pub all: Option<bool>,
11619}
11620
11621/// Cube
11622#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11623#[cfg_attr(feature = "bindings", derive(TS))]
11624pub struct Cube {
11625    /// Selection, subtotal, and result-delivery options for this grouping operation.
11626    #[serde(default, skip_serializing_if = "Option::is_none")]
11627    pub options: Option<GroupingOptions>,
11628    #[serde(default)]
11629    pub expressions: Vec<Expression>,
11630}
11631
11632/// Rollup
11633#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11634#[cfg_attr(feature = "bindings", derive(TS))]
11635pub struct Rollup {
11636    /// Selection, subtotal, and result-delivery options for this grouping operation.
11637    #[serde(default, skip_serializing_if = "Option::is_none")]
11638    pub options: Option<GroupingOptions>,
11639    #[serde(default)]
11640    pub expressions: Vec<Expression>,
11641}
11642
11643/// GroupingSets
11644#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11645#[cfg_attr(feature = "bindings", derive(TS))]
11646pub struct GroupingSets {
11647    /// Selection, subtotal, and result-delivery options for this grouping operation.
11648    #[serde(default, skip_serializing_if = "Option::is_none")]
11649    pub options: Option<GroupingOptions>,
11650    #[serde(default)]
11651    pub expressions: Vec<Expression>,
11652}
11653
11654/// LimitOptions
11655#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11656#[cfg_attr(feature = "bindings", derive(TS))]
11657pub struct LimitOptions {
11658    #[serde(default)]
11659    pub percent: Option<Box<Expression>>,
11660    #[serde(default)]
11661    pub rows: Option<Box<Expression>>,
11662    #[serde(default)]
11663    pub with_ties: Option<Box<Expression>>,
11664}
11665
11666/// Lateral
11667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11668#[cfg_attr(feature = "bindings", derive(TS))]
11669pub struct Lateral {
11670    pub this: Box<Expression>,
11671    #[serde(default)]
11672    pub view: Option<Box<Expression>>,
11673    #[serde(default)]
11674    pub outer: Option<Box<Expression>>,
11675    #[serde(default)]
11676    pub alias: Option<String>,
11677    /// Whether the alias was originally quoted (backtick/double-quote)
11678    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11679    pub alias_quoted: bool,
11680    #[serde(default)]
11681    pub cross_apply: Option<Box<Expression>>,
11682    #[serde(default)]
11683    pub ordinality: Option<Box<Expression>>,
11684    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11685    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11686    pub column_aliases: Vec<String>,
11687    /// Quoting of each column alias, parallel to `column_aliases`.
11688    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11689    pub column_aliases_quoted: Vec<bool>,
11690}
11691
11692/// TableFromRows
11693#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11694#[cfg_attr(feature = "bindings", derive(TS))]
11695pub struct TableFromRows {
11696    pub this: Box<Expression>,
11697    #[serde(default)]
11698    pub alias: Option<String>,
11699    #[serde(default)]
11700    pub joins: Vec<Expression>,
11701    #[serde(default)]
11702    pub pivots: Option<Box<Expression>>,
11703    #[serde(default)]
11704    pub sample: Option<Box<Expression>>,
11705}
11706
11707/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11708/// Used for set-returning functions with typed column definitions
11709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11710#[cfg_attr(feature = "bindings", derive(TS))]
11711pub struct RowsFrom {
11712    /// List of function expressions, each potentially with an alias and typed columns
11713    pub expressions: Vec<Expression>,
11714    /// WITH ORDINALITY modifier
11715    #[serde(default)]
11716    pub ordinality: bool,
11717    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11718    #[serde(default)]
11719    pub alias: Option<Box<Expression>>,
11720}
11721
11722/// WithFill
11723#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11724#[cfg_attr(feature = "bindings", derive(TS))]
11725pub struct WithFill {
11726    #[serde(default)]
11727    pub from_: Option<Box<Expression>>,
11728    #[serde(default)]
11729    pub to: Option<Box<Expression>>,
11730    #[serde(default)]
11731    pub step: Option<Box<Expression>>,
11732    #[serde(default)]
11733    pub staleness: Option<Box<Expression>>,
11734    #[serde(default)]
11735    pub interpolate: Option<Box<Expression>>,
11736}
11737
11738/// Property
11739#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11740#[cfg_attr(feature = "bindings", derive(TS))]
11741pub struct Property {
11742    pub this: Box<Expression>,
11743    #[serde(default)]
11744    pub value: Option<Box<Expression>>,
11745}
11746
11747/// GrantPrivilege
11748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11749#[cfg_attr(feature = "bindings", derive(TS))]
11750pub struct GrantPrivilege {
11751    pub this: Box<Expression>,
11752    #[serde(default)]
11753    pub expressions: Vec<Expression>,
11754}
11755
11756/// AllowedValuesProperty
11757#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11758#[cfg_attr(feature = "bindings", derive(TS))]
11759pub struct AllowedValuesProperty {
11760    #[serde(default)]
11761    pub expressions: Vec<Expression>,
11762}
11763
11764/// AlgorithmProperty
11765#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11766#[cfg_attr(feature = "bindings", derive(TS))]
11767pub struct AlgorithmProperty {
11768    pub this: Box<Expression>,
11769}
11770
11771/// AutoIncrementProperty
11772#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11773#[cfg_attr(feature = "bindings", derive(TS))]
11774pub struct AutoIncrementProperty {
11775    pub this: Box<Expression>,
11776}
11777
11778/// AutoRefreshProperty
11779#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11780#[cfg_attr(feature = "bindings", derive(TS))]
11781pub struct AutoRefreshProperty {
11782    pub this: Box<Expression>,
11783}
11784
11785/// BackupProperty
11786#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11787#[cfg_attr(feature = "bindings", derive(TS))]
11788pub struct BackupProperty {
11789    pub this: Box<Expression>,
11790}
11791
11792/// BuildProperty
11793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11794#[cfg_attr(feature = "bindings", derive(TS))]
11795pub struct BuildProperty {
11796    pub this: Box<Expression>,
11797}
11798
11799/// BlockCompressionProperty
11800#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11801#[cfg_attr(feature = "bindings", derive(TS))]
11802pub struct BlockCompressionProperty {
11803    #[serde(default)]
11804    pub autotemp: Option<Box<Expression>>,
11805    #[serde(default)]
11806    pub always: Option<Box<Expression>>,
11807    #[serde(default)]
11808    pub default: Option<Box<Expression>>,
11809    #[serde(default)]
11810    pub manual: Option<Box<Expression>>,
11811    #[serde(default)]
11812    pub never: Option<Box<Expression>>,
11813}
11814
11815/// CharacterSetProperty
11816#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11817#[cfg_attr(feature = "bindings", derive(TS))]
11818pub struct CharacterSetProperty {
11819    pub this: Box<Expression>,
11820    #[serde(default)]
11821    pub default: Option<Box<Expression>>,
11822}
11823
11824/// ChecksumProperty
11825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11826#[cfg_attr(feature = "bindings", derive(TS))]
11827pub struct ChecksumProperty {
11828    #[serde(default)]
11829    pub on: Option<Box<Expression>>,
11830    #[serde(default)]
11831    pub default: Option<Box<Expression>>,
11832}
11833
11834/// CollateProperty
11835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11836#[cfg_attr(feature = "bindings", derive(TS))]
11837pub struct CollateProperty {
11838    pub this: Box<Expression>,
11839    #[serde(default)]
11840    pub default: Option<Box<Expression>>,
11841}
11842
11843/// DataBlocksizeProperty
11844#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11845#[cfg_attr(feature = "bindings", derive(TS))]
11846pub struct DataBlocksizeProperty {
11847    #[serde(default)]
11848    pub size: Option<i64>,
11849    #[serde(default)]
11850    pub units: Option<Box<Expression>>,
11851    #[serde(default)]
11852    pub minimum: Option<Box<Expression>>,
11853    #[serde(default)]
11854    pub maximum: Option<Box<Expression>>,
11855    #[serde(default)]
11856    pub default: Option<Box<Expression>>,
11857}
11858
11859/// DataDeletionProperty
11860#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11861#[cfg_attr(feature = "bindings", derive(TS))]
11862pub struct DataDeletionProperty {
11863    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11864    #[ast(skip)]
11865    pub on: Box<Expression>,
11866    #[serde(default)]
11867    pub filter_column: Option<Box<Expression>>,
11868    #[serde(default)]
11869    pub retention_period: Option<Box<Expression>>,
11870}
11871
11872/// DefinerProperty
11873#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11874#[cfg_attr(feature = "bindings", derive(TS))]
11875pub struct DefinerProperty {
11876    pub this: Box<Expression>,
11877}
11878
11879/// DistKeyProperty
11880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11881#[cfg_attr(feature = "bindings", derive(TS))]
11882pub struct DistKeyProperty {
11883    pub this: Box<Expression>,
11884}
11885
11886/// DistributedByProperty
11887#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11888#[cfg_attr(feature = "bindings", derive(TS))]
11889pub struct DistributedByProperty {
11890    #[serde(default)]
11891    pub expressions: Vec<Expression>,
11892    pub kind: String,
11893    #[serde(default)]
11894    pub buckets: Option<Box<Expression>>,
11895    #[serde(default)]
11896    pub order: Option<Box<Expression>>,
11897}
11898
11899/// DistStyleProperty
11900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11901#[cfg_attr(feature = "bindings", derive(TS))]
11902pub struct DistStyleProperty {
11903    pub this: Box<Expression>,
11904}
11905
11906/// DuplicateKeyProperty
11907#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11908#[cfg_attr(feature = "bindings", derive(TS))]
11909pub struct DuplicateKeyProperty {
11910    #[serde(default)]
11911    pub expressions: Vec<Expression>,
11912}
11913
11914/// EngineProperty
11915#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11916#[cfg_attr(feature = "bindings", derive(TS))]
11917pub struct EngineProperty {
11918    pub this: Box<Expression>,
11919}
11920
11921/// ToTableProperty
11922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11923#[cfg_attr(feature = "bindings", derive(TS))]
11924pub struct ToTableProperty {
11925    pub this: Box<Expression>,
11926}
11927
11928/// ExecuteAsProperty
11929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11930#[cfg_attr(feature = "bindings", derive(TS))]
11931pub struct ExecuteAsProperty {
11932    pub this: Box<Expression>,
11933}
11934
11935/// ExternalProperty
11936#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11937#[cfg_attr(feature = "bindings", derive(TS))]
11938pub struct ExternalProperty {
11939    #[serde(default)]
11940    pub this: Option<Box<Expression>>,
11941}
11942
11943/// FallbackProperty
11944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11945#[cfg_attr(feature = "bindings", derive(TS))]
11946pub struct FallbackProperty {
11947    #[serde(default)]
11948    pub no: Option<Box<Expression>>,
11949    #[serde(default)]
11950    pub protection: Option<Box<Expression>>,
11951}
11952
11953/// FileFormatProperty
11954#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11955#[cfg_attr(feature = "bindings", derive(TS))]
11956pub struct FileFormatProperty {
11957    #[serde(default)]
11958    pub this: Option<Box<Expression>>,
11959    #[serde(default)]
11960    pub expressions: Vec<Expression>,
11961    #[serde(default)]
11962    pub hive_format: Option<Box<Expression>>,
11963}
11964
11965/// CredentialsProperty
11966#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11967#[cfg_attr(feature = "bindings", derive(TS))]
11968pub struct CredentialsProperty {
11969    #[serde(default)]
11970    pub expressions: Vec<Expression>,
11971}
11972
11973/// FreespaceProperty
11974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11975#[cfg_attr(feature = "bindings", derive(TS))]
11976pub struct FreespaceProperty {
11977    pub this: Box<Expression>,
11978    #[serde(default)]
11979    pub percent: Option<Box<Expression>>,
11980}
11981
11982/// InheritsProperty
11983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11984#[cfg_attr(feature = "bindings", derive(TS))]
11985pub struct InheritsProperty {
11986    #[serde(default)]
11987    pub expressions: Vec<Expression>,
11988}
11989
11990/// InputModelProperty
11991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11992#[cfg_attr(feature = "bindings", derive(TS))]
11993pub struct InputModelProperty {
11994    pub this: Box<Expression>,
11995}
11996
11997/// OutputModelProperty
11998#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11999#[cfg_attr(feature = "bindings", derive(TS))]
12000pub struct OutputModelProperty {
12001    pub this: Box<Expression>,
12002}
12003
12004/// IsolatedLoadingProperty
12005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12006#[cfg_attr(feature = "bindings", derive(TS))]
12007pub struct IsolatedLoadingProperty {
12008    #[serde(default)]
12009    pub no: Option<Box<Expression>>,
12010    #[serde(default)]
12011    pub concurrent: Option<Box<Expression>>,
12012    #[serde(default)]
12013    pub target: Option<Box<Expression>>,
12014}
12015
12016/// JournalProperty
12017#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12018#[cfg_attr(feature = "bindings", derive(TS))]
12019pub struct JournalProperty {
12020    #[serde(default)]
12021    pub no: Option<Box<Expression>>,
12022    #[serde(default)]
12023    pub dual: Option<Box<Expression>>,
12024    #[serde(default)]
12025    pub before: Option<Box<Expression>>,
12026    #[serde(default)]
12027    pub local: Option<Box<Expression>>,
12028    #[serde(default)]
12029    pub after: Option<Box<Expression>>,
12030}
12031
12032/// LanguageProperty
12033#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12034#[cfg_attr(feature = "bindings", derive(TS))]
12035pub struct LanguageProperty {
12036    pub this: Box<Expression>,
12037}
12038
12039/// EnviromentProperty
12040#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12041#[cfg_attr(feature = "bindings", derive(TS))]
12042pub struct EnviromentProperty {
12043    #[serde(default)]
12044    pub expressions: Vec<Expression>,
12045}
12046
12047/// ClusteredByProperty
12048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12049#[cfg_attr(feature = "bindings", derive(TS))]
12050pub struct ClusteredByProperty {
12051    #[serde(default)]
12052    pub expressions: Vec<Expression>,
12053    #[serde(default)]
12054    pub sorted_by: Option<Box<Expression>>,
12055    #[serde(default)]
12056    pub buckets: Option<Box<Expression>>,
12057}
12058
12059/// DictProperty
12060#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12061#[cfg_attr(feature = "bindings", derive(TS))]
12062pub struct DictProperty {
12063    pub this: Box<Expression>,
12064    pub kind: String,
12065    #[serde(default)]
12066    pub settings: Option<Box<Expression>>,
12067}
12068
12069/// DictRange
12070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12071#[cfg_attr(feature = "bindings", derive(TS))]
12072pub struct DictRange {
12073    pub this: Box<Expression>,
12074    #[serde(default)]
12075    pub min: Option<Box<Expression>>,
12076    #[serde(default)]
12077    pub max: Option<Box<Expression>>,
12078}
12079
12080/// OnCluster
12081#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12082#[cfg_attr(feature = "bindings", derive(TS))]
12083pub struct OnCluster {
12084    pub this: Box<Expression>,
12085}
12086
12087/// LikeProperty
12088#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12089#[cfg_attr(feature = "bindings", derive(TS))]
12090pub struct LikeProperty {
12091    pub this: Box<Expression>,
12092    #[serde(default)]
12093    pub expressions: Vec<Expression>,
12094}
12095
12096/// LocationProperty
12097#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12098#[cfg_attr(feature = "bindings", derive(TS))]
12099pub struct LocationProperty {
12100    pub this: Box<Expression>,
12101}
12102
12103/// LockProperty
12104#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12105#[cfg_attr(feature = "bindings", derive(TS))]
12106pub struct LockProperty {
12107    pub this: Box<Expression>,
12108}
12109
12110/// LockingProperty
12111#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12112#[cfg_attr(feature = "bindings", derive(TS))]
12113pub struct LockingProperty {
12114    #[serde(default)]
12115    pub this: Option<Box<Expression>>,
12116    pub kind: String,
12117    #[serde(default)]
12118    pub for_or_in: Option<Box<Expression>>,
12119    #[serde(default)]
12120    pub lock_type: Option<Box<Expression>>,
12121    #[serde(default)]
12122    pub override_: Option<Box<Expression>>,
12123}
12124
12125/// LogProperty
12126#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12127#[cfg_attr(feature = "bindings", derive(TS))]
12128pub struct LogProperty {
12129    #[serde(default)]
12130    pub no: Option<Box<Expression>>,
12131}
12132
12133/// MaterializedProperty
12134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12135#[cfg_attr(feature = "bindings", derive(TS))]
12136pub struct MaterializedProperty {
12137    #[serde(default)]
12138    pub this: Option<Box<Expression>>,
12139}
12140
12141/// MergeBlockRatioProperty
12142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12143#[cfg_attr(feature = "bindings", derive(TS))]
12144pub struct MergeBlockRatioProperty {
12145    #[serde(default)]
12146    pub this: Option<Box<Expression>>,
12147    #[serde(default)]
12148    pub no: Option<Box<Expression>>,
12149    #[serde(default)]
12150    pub default: Option<Box<Expression>>,
12151    #[serde(default)]
12152    pub percent: Option<Box<Expression>>,
12153}
12154
12155/// OnProperty
12156#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12157#[cfg_attr(feature = "bindings", derive(TS))]
12158pub struct OnProperty {
12159    pub this: Box<Expression>,
12160}
12161
12162/// OnCommitProperty
12163#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12164#[cfg_attr(feature = "bindings", derive(TS))]
12165pub struct OnCommitProperty {
12166    #[serde(default)]
12167    pub delete: Option<Box<Expression>>,
12168}
12169
12170/// PartitionedByProperty
12171#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12172#[cfg_attr(feature = "bindings", derive(TS))]
12173pub struct PartitionedByProperty {
12174    pub this: Box<Expression>,
12175}
12176
12177/// BigQuery PARTITION BY property in CREATE TABLE statements.
12178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12179#[cfg_attr(feature = "bindings", derive(TS))]
12180pub struct PartitionByProperty {
12181    /// Structured partition scheme when the dialect supports methods and ranges.
12182    #[serde(default, skip_serializing_if = "Option::is_none")]
12183    pub specification: Option<PartitionSpec>,
12184    #[serde(default)]
12185    pub expressions: Vec<Expression>,
12186}
12187
12188/// PartitionedByBucket
12189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12190#[cfg_attr(feature = "bindings", derive(TS))]
12191pub struct PartitionedByBucket {
12192    pub this: Box<Expression>,
12193    pub expression: Box<Expression>,
12194}
12195
12196/// BigQuery CLUSTER BY property in CREATE TABLE statements.
12197#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12198#[cfg_attr(feature = "bindings", derive(TS))]
12199pub struct ClusterByColumnsProperty {
12200    #[serde(default)]
12201    pub columns: Vec<Identifier>,
12202}
12203
12204/// PartitionByTruncate
12205#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12206#[cfg_attr(feature = "bindings", derive(TS))]
12207pub struct PartitionByTruncate {
12208    pub this: Box<Expression>,
12209    pub expression: Box<Expression>,
12210}
12211
12212/// PartitionByRangeProperty
12213#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12214#[cfg_attr(feature = "bindings", derive(TS))]
12215pub struct PartitionByRangeProperty {
12216    #[serde(default)]
12217    pub partition_expressions: Option<Box<Expression>>,
12218    #[serde(default)]
12219    pub create_expressions: Option<Box<Expression>>,
12220}
12221
12222/// PartitionByRangePropertyDynamic
12223#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12224#[cfg_attr(feature = "bindings", derive(TS))]
12225pub struct PartitionByRangePropertyDynamic {
12226    #[serde(default)]
12227    pub this: Option<Box<Expression>>,
12228    #[serde(default)]
12229    pub start: Option<Box<Expression>>,
12230    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
12231    #[serde(default)]
12232    pub use_start_end: bool,
12233    #[serde(default)]
12234    pub end: Option<Box<Expression>>,
12235    #[serde(default)]
12236    pub every: Option<Box<Expression>>,
12237}
12238
12239/// PartitionByListProperty
12240#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12241#[cfg_attr(feature = "bindings", derive(TS))]
12242pub struct PartitionByListProperty {
12243    #[serde(default)]
12244    pub partition_expressions: Option<Box<Expression>>,
12245    #[serde(default)]
12246    pub create_expressions: Option<Box<Expression>>,
12247}
12248
12249/// PartitionList
12250#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12251#[cfg_attr(feature = "bindings", derive(TS))]
12252pub struct PartitionList {
12253    pub this: Box<Expression>,
12254    #[serde(default)]
12255    pub expressions: Vec<Expression>,
12256}
12257
12258/// Partition - represents PARTITION/SUBPARTITION clause
12259#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12260#[cfg_attr(feature = "bindings", derive(TS))]
12261pub struct Partition {
12262    pub expressions: Vec<Expression>,
12263    #[serde(default)]
12264    pub subpartition: bool,
12265}
12266
12267/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
12268/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
12269#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12270#[cfg_attr(feature = "bindings", derive(TS))]
12271pub struct RefreshTriggerProperty {
12272    /// Method: COMPLETE or AUTO
12273    pub method: String,
12274    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
12275    #[serde(default)]
12276    pub kind: Option<String>,
12277    /// For SCHEDULE: EVERY n (the number)
12278    #[serde(default)]
12279    pub every: Option<Box<Expression>>,
12280    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
12281    #[serde(default)]
12282    pub unit: Option<String>,
12283    /// For SCHEDULE: STARTS 'datetime'
12284    #[serde(default)]
12285    pub starts: Option<Box<Expression>>,
12286}
12287
12288/// UniqueKeyProperty
12289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12290#[cfg_attr(feature = "bindings", derive(TS))]
12291pub struct UniqueKeyProperty {
12292    #[serde(default)]
12293    pub expressions: Vec<Expression>,
12294}
12295
12296/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
12297#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12298#[cfg_attr(feature = "bindings", derive(TS))]
12299pub struct RollupProperty {
12300    pub expressions: Vec<RollupIndex>,
12301}
12302
12303/// RollupIndex - A single rollup index: name(col1, col2)
12304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12305#[cfg_attr(feature = "bindings", derive(TS))]
12306pub struct RollupIndex {
12307    pub name: Identifier,
12308    pub expressions: Vec<Identifier>,
12309}
12310
12311/// PartitionBoundSpec
12312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12313#[cfg_attr(feature = "bindings", derive(TS))]
12314pub struct PartitionBoundSpec {
12315    #[serde(default)]
12316    pub this: Option<Box<Expression>>,
12317    #[serde(default)]
12318    pub expression: Option<Box<Expression>>,
12319    #[serde(default)]
12320    pub from_expressions: Option<Box<Expression>>,
12321    #[serde(default)]
12322    pub to_expressions: Option<Box<Expression>>,
12323}
12324
12325/// PartitionedOfProperty
12326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12327#[cfg_attr(feature = "bindings", derive(TS))]
12328pub struct PartitionedOfProperty {
12329    pub this: Box<Expression>,
12330    pub expression: Box<Expression>,
12331}
12332
12333/// RemoteWithConnectionModelProperty
12334#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12335#[cfg_attr(feature = "bindings", derive(TS))]
12336pub struct RemoteWithConnectionModelProperty {
12337    pub this: Box<Expression>,
12338}
12339
12340/// ReturnsProperty
12341#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12342#[cfg_attr(feature = "bindings", derive(TS))]
12343pub struct ReturnsProperty {
12344    #[serde(default)]
12345    pub this: Option<Box<Expression>>,
12346    #[serde(default)]
12347    pub is_table: Option<Box<Expression>>,
12348    #[serde(default)]
12349    pub table: Option<Box<Expression>>,
12350    #[serde(default)]
12351    pub null: Option<Box<Expression>>,
12352}
12353
12354/// RowFormatProperty
12355#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12356#[cfg_attr(feature = "bindings", derive(TS))]
12357pub struct RowFormatProperty {
12358    pub this: Box<Expression>,
12359}
12360
12361/// RowFormatDelimitedProperty
12362#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12363#[cfg_attr(feature = "bindings", derive(TS))]
12364pub struct RowFormatDelimitedProperty {
12365    #[serde(default)]
12366    pub fields: Option<Box<Expression>>,
12367    #[serde(default)]
12368    pub escaped: Option<Box<Expression>>,
12369    #[serde(default)]
12370    pub collection_items: Option<Box<Expression>>,
12371    #[serde(default)]
12372    pub map_keys: Option<Box<Expression>>,
12373    #[serde(default)]
12374    pub lines: Option<Box<Expression>>,
12375    #[serde(default)]
12376    pub null: Option<Box<Expression>>,
12377    #[serde(default)]
12378    pub serde: Option<Box<Expression>>,
12379}
12380
12381/// RowFormatSerdeProperty
12382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12383#[cfg_attr(feature = "bindings", derive(TS))]
12384pub struct RowFormatSerdeProperty {
12385    pub this: Box<Expression>,
12386    #[serde(default)]
12387    pub serde_properties: Option<Box<Expression>>,
12388}
12389
12390/// QueryTransform
12391#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12392#[cfg_attr(feature = "bindings", derive(TS))]
12393pub struct QueryTransform {
12394    #[serde(default)]
12395    pub expressions: Vec<Expression>,
12396    #[serde(default)]
12397    pub command_script: Option<Box<Expression>>,
12398    #[serde(default)]
12399    pub schema: Option<Box<Expression>>,
12400    #[serde(default)]
12401    pub row_format_before: Option<Box<Expression>>,
12402    #[serde(default)]
12403    pub record_writer: Option<Box<Expression>>,
12404    #[serde(default)]
12405    pub row_format_after: Option<Box<Expression>>,
12406    #[serde(default)]
12407    pub record_reader: Option<Box<Expression>>,
12408}
12409
12410/// SampleProperty
12411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12412#[cfg_attr(feature = "bindings", derive(TS))]
12413pub struct SampleProperty {
12414    pub this: Box<Expression>,
12415}
12416
12417/// SecurityProperty
12418#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12419#[cfg_attr(feature = "bindings", derive(TS))]
12420pub struct SecurityProperty {
12421    pub this: Box<Expression>,
12422}
12423
12424/// SchemaCommentProperty
12425#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12426#[cfg_attr(feature = "bindings", derive(TS))]
12427pub struct SchemaCommentProperty {
12428    pub this: Box<Expression>,
12429}
12430
12431/// SemanticView
12432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12433#[cfg_attr(feature = "bindings", derive(TS))]
12434pub struct SemanticView {
12435    pub this: Box<Expression>,
12436    #[serde(default)]
12437    pub metrics: Option<Box<Expression>>,
12438    #[serde(default)]
12439    pub dimensions: Option<Box<Expression>>,
12440    #[serde(default)]
12441    pub facts: Option<Box<Expression>>,
12442    #[serde(default)]
12443    pub where_: Option<Box<Expression>>,
12444}
12445
12446/// SerdeProperties
12447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12448#[cfg_attr(feature = "bindings", derive(TS))]
12449pub struct SerdeProperties {
12450    #[serde(default)]
12451    pub expressions: Vec<Expression>,
12452    #[serde(default)]
12453    pub with_: Option<Box<Expression>>,
12454}
12455
12456/// SetProperty
12457#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12458#[cfg_attr(feature = "bindings", derive(TS))]
12459pub struct SetProperty {
12460    #[serde(default)]
12461    pub multi: Option<Box<Expression>>,
12462}
12463
12464/// SharingProperty
12465#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12466#[cfg_attr(feature = "bindings", derive(TS))]
12467pub struct SharingProperty {
12468    #[serde(default)]
12469    pub this: Option<Box<Expression>>,
12470}
12471
12472/// SetConfigProperty
12473#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12474#[cfg_attr(feature = "bindings", derive(TS))]
12475pub struct SetConfigProperty {
12476    pub this: Box<Expression>,
12477}
12478
12479/// SettingsProperty
12480#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12481#[cfg_attr(feature = "bindings", derive(TS))]
12482pub struct SettingsProperty {
12483    #[serde(default)]
12484    pub expressions: Vec<Expression>,
12485}
12486
12487/// SortKeyProperty
12488#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12489#[cfg_attr(feature = "bindings", derive(TS))]
12490pub struct SortKeyProperty {
12491    pub this: Box<Expression>,
12492    #[serde(default)]
12493    pub compound: Option<Box<Expression>>,
12494}
12495
12496/// SqlReadWriteProperty
12497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12498#[cfg_attr(feature = "bindings", derive(TS))]
12499pub struct SqlReadWriteProperty {
12500    pub this: Box<Expression>,
12501}
12502
12503/// SqlSecurityProperty
12504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12505#[cfg_attr(feature = "bindings", derive(TS))]
12506pub struct SqlSecurityProperty {
12507    pub this: Box<Expression>,
12508}
12509
12510/// StabilityProperty
12511#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12512#[cfg_attr(feature = "bindings", derive(TS))]
12513pub struct StabilityProperty {
12514    pub this: Box<Expression>,
12515}
12516
12517/// StorageHandlerProperty
12518#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12519#[cfg_attr(feature = "bindings", derive(TS))]
12520pub struct StorageHandlerProperty {
12521    pub this: Box<Expression>,
12522}
12523
12524/// TemporaryProperty
12525#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12526#[cfg_attr(feature = "bindings", derive(TS))]
12527pub struct TemporaryProperty {
12528    #[serde(default)]
12529    pub this: Option<Box<Expression>>,
12530}
12531
12532/// Tags
12533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12534#[cfg_attr(feature = "bindings", derive(TS))]
12535pub struct Tags {
12536    #[serde(default)]
12537    pub expressions: Vec<Expression>,
12538}
12539
12540/// TransformModelProperty
12541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12542#[cfg_attr(feature = "bindings", derive(TS))]
12543pub struct TransformModelProperty {
12544    #[serde(default)]
12545    pub expressions: Vec<Expression>,
12546}
12547
12548/// TransientProperty
12549#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12550#[cfg_attr(feature = "bindings", derive(TS))]
12551pub struct TransientProperty {
12552    #[serde(default)]
12553    pub this: Option<Box<Expression>>,
12554}
12555
12556/// UsingTemplateProperty
12557#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12558#[cfg_attr(feature = "bindings", derive(TS))]
12559pub struct UsingTemplateProperty {
12560    pub this: Box<Expression>,
12561}
12562
12563/// ViewAttributeProperty
12564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12565#[cfg_attr(feature = "bindings", derive(TS))]
12566pub struct ViewAttributeProperty {
12567    pub this: Box<Expression>,
12568}
12569
12570/// VolatileProperty
12571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12572#[cfg_attr(feature = "bindings", derive(TS))]
12573pub struct VolatileProperty {
12574    #[serde(default)]
12575    pub this: Option<Box<Expression>>,
12576}
12577
12578/// WithDataProperty
12579#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12580#[cfg_attr(feature = "bindings", derive(TS))]
12581pub struct WithDataProperty {
12582    #[serde(default)]
12583    pub no: Option<Box<Expression>>,
12584    #[serde(default)]
12585    pub statistics: Option<Box<Expression>>,
12586}
12587
12588/// WithJournalTableProperty
12589#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12590#[cfg_attr(feature = "bindings", derive(TS))]
12591pub struct WithJournalTableProperty {
12592    pub this: Box<Expression>,
12593}
12594
12595/// WithSchemaBindingProperty
12596#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12597#[cfg_attr(feature = "bindings", derive(TS))]
12598pub struct WithSchemaBindingProperty {
12599    pub this: Box<Expression>,
12600}
12601
12602/// WithSystemVersioningProperty
12603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12604#[cfg_attr(feature = "bindings", derive(TS))]
12605pub struct WithSystemVersioningProperty {
12606    #[serde(default)]
12607    pub on: Option<Box<Expression>>,
12608    #[serde(default)]
12609    pub this: Option<Box<Expression>>,
12610    #[serde(default)]
12611    pub data_consistency: Option<Box<Expression>>,
12612    #[serde(default)]
12613    pub retention_period: Option<Box<Expression>>,
12614    #[serde(default)]
12615    pub with_: Option<Box<Expression>>,
12616}
12617
12618/// WithProcedureOptions
12619#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12620#[cfg_attr(feature = "bindings", derive(TS))]
12621pub struct WithProcedureOptions {
12622    #[serde(default)]
12623    pub expressions: Vec<Expression>,
12624}
12625
12626/// EncodeProperty
12627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12628#[cfg_attr(feature = "bindings", derive(TS))]
12629pub struct EncodeProperty {
12630    pub this: Box<Expression>,
12631    #[serde(default)]
12632    pub properties: Vec<Expression>,
12633    #[serde(default)]
12634    pub key: Option<Box<Expression>>,
12635}
12636
12637/// IncludeProperty
12638#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12639#[cfg_attr(feature = "bindings", derive(TS))]
12640pub struct IncludeProperty {
12641    pub this: Box<Expression>,
12642    #[serde(default)]
12643    pub alias: Option<String>,
12644    #[serde(default)]
12645    pub column_def: Option<Box<Expression>>,
12646}
12647
12648/// Properties
12649#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12650#[cfg_attr(feature = "bindings", derive(TS))]
12651pub struct Properties {
12652    #[serde(default)]
12653    pub expressions: Vec<Expression>,
12654}
12655
12656/// Key/value pair in a BigQuery OPTIONS (...) clause.
12657#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12658#[cfg_attr(feature = "bindings", derive(TS))]
12659pub struct OptionEntry {
12660    pub key: Identifier,
12661    pub value: Expression,
12662}
12663
12664/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12666#[cfg_attr(feature = "bindings", derive(TS))]
12667pub struct OptionsProperty {
12668    #[serde(default)]
12669    pub entries: Vec<OptionEntry>,
12670}
12671
12672/// InputOutputFormat
12673#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12674#[cfg_attr(feature = "bindings", derive(TS))]
12675pub struct InputOutputFormat {
12676    #[serde(default)]
12677    pub input_format: Option<Box<Expression>>,
12678    #[serde(default)]
12679    pub output_format: Option<Box<Expression>>,
12680}
12681
12682/// Reference
12683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12684#[cfg_attr(feature = "bindings", derive(TS))]
12685pub struct Reference {
12686    pub this: Box<Expression>,
12687    #[serde(default)]
12688    pub expressions: Vec<Expression>,
12689    #[serde(default)]
12690    pub options: Vec<Expression>,
12691}
12692
12693/// QueryOption
12694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12695#[cfg_attr(feature = "bindings", derive(TS))]
12696pub struct QueryOption {
12697    pub this: Box<Expression>,
12698    #[serde(default)]
12699    pub expression: Option<Box<Expression>>,
12700}
12701
12702/// WithTableHint
12703#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12704#[cfg_attr(feature = "bindings", derive(TS))]
12705pub struct WithTableHint {
12706    #[serde(default)]
12707    pub expressions: Vec<Expression>,
12708}
12709
12710/// IndexTableHint
12711#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12712#[cfg_attr(feature = "bindings", derive(TS))]
12713pub struct IndexTableHint {
12714    pub this: Box<Expression>,
12715    #[serde(default)]
12716    pub expressions: Vec<Expression>,
12717    #[serde(default)]
12718    pub target: Option<Box<Expression>>,
12719}
12720
12721/// Get
12722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12723#[cfg_attr(feature = "bindings", derive(TS))]
12724pub struct Get {
12725    pub this: Box<Expression>,
12726    #[serde(default)]
12727    pub target: Option<Box<Expression>>,
12728    #[serde(default)]
12729    pub properties: Vec<Expression>,
12730}
12731
12732/// SetOperation
12733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12734#[cfg_attr(feature = "bindings", derive(TS))]
12735pub struct SetOperation {
12736    #[serde(default)]
12737    pub with_: Option<Box<Expression>>,
12738    pub this: Box<Expression>,
12739    pub expression: Box<Expression>,
12740    #[serde(default)]
12741    pub distinct: bool,
12742    #[serde(default)]
12743    pub by_name: Option<Box<Expression>>,
12744    #[serde(default)]
12745    pub side: Option<Box<Expression>>,
12746    #[serde(default)]
12747    pub kind: Option<String>,
12748    #[serde(default)]
12749    pub on: Option<Box<Expression>>,
12750}
12751
12752/// Var - Simple variable reference (for SQL variables, keywords as values)
12753#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12754#[cfg_attr(feature = "bindings", derive(TS))]
12755pub struct Var {
12756    pub this: String,
12757}
12758
12759/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12760#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12761#[cfg_attr(feature = "bindings", derive(TS))]
12762pub struct Variadic {
12763    pub this: Box<Expression>,
12764}
12765
12766/// Version
12767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12768#[cfg_attr(feature = "bindings", derive(TS))]
12769pub struct Version {
12770    pub this: Box<Expression>,
12771    pub kind: String,
12772    #[serde(default)]
12773    pub expression: Option<Box<Expression>>,
12774}
12775
12776/// Schema
12777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12778#[cfg_attr(feature = "bindings", derive(TS))]
12779pub struct Schema {
12780    #[serde(default)]
12781    pub this: Option<Box<Expression>>,
12782    #[serde(default)]
12783    pub expressions: Vec<Expression>,
12784}
12785
12786/// Lock
12787#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12788#[cfg_attr(feature = "bindings", derive(TS))]
12789pub struct Lock {
12790    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
12791    pub ignore_locked: bool,
12792    #[serde(default)]
12793    pub update: Option<Box<Expression>>,
12794    #[serde(default)]
12795    pub expressions: Vec<Expression>,
12796    #[serde(default)]
12797    pub wait: Option<Box<Expression>>,
12798    #[serde(default)]
12799    pub key: Option<Box<Expression>>,
12800}
12801
12802/// TableSample - wraps an expression with a TABLESAMPLE clause
12803/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12804#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12805#[cfg_attr(feature = "bindings", derive(TS))]
12806pub struct TableSample {
12807    /// The expression being sampled (subquery, function, etc.)
12808    #[serde(default, skip_serializing_if = "Option::is_none")]
12809    pub this: Option<Box<Expression>>,
12810    /// The sample specification
12811    #[serde(default, skip_serializing_if = "Option::is_none")]
12812    pub sample: Option<Box<Sample>>,
12813    #[serde(default)]
12814    pub expressions: Vec<Expression>,
12815    #[serde(default)]
12816    pub method: Option<String>,
12817    #[serde(default)]
12818    pub bucket_numerator: Option<Box<Expression>>,
12819    #[serde(default)]
12820    pub bucket_denominator: Option<Box<Expression>>,
12821    #[serde(default)]
12822    pub bucket_field: Option<Box<Expression>>,
12823    #[serde(default)]
12824    pub percent: Option<Box<Expression>>,
12825    #[serde(default)]
12826    pub rows: Option<Box<Expression>>,
12827    #[serde(default)]
12828    pub size: Option<i64>,
12829    #[serde(default)]
12830    pub seed: Option<Box<Expression>>,
12831}
12832
12833/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12835#[cfg_attr(feature = "bindings", derive(TS))]
12836pub struct Tag {
12837    #[serde(default)]
12838    pub this: Option<Box<Expression>>,
12839    #[serde(default)]
12840    pub prefix: Option<Box<Expression>>,
12841    #[serde(default)]
12842    pub postfix: Option<Box<Expression>>,
12843}
12844
12845/// UnpivotColumns
12846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12847#[cfg_attr(feature = "bindings", derive(TS))]
12848pub struct UnpivotColumns {
12849    pub this: Box<Expression>,
12850    #[serde(default)]
12851    pub expressions: Vec<Expression>,
12852}
12853
12854/// SessionParameter
12855#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12856#[cfg_attr(feature = "bindings", derive(TS))]
12857pub struct SessionParameter {
12858    pub this: Box<Expression>,
12859    #[serde(default)]
12860    pub kind: Option<String>,
12861}
12862
12863/// PseudoType
12864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12865#[cfg_attr(feature = "bindings", derive(TS))]
12866pub struct PseudoType {
12867    pub this: Box<Expression>,
12868}
12869
12870/// ObjectIdentifier
12871#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12872#[cfg_attr(feature = "bindings", derive(TS))]
12873pub struct ObjectIdentifier {
12874    pub this: Box<Expression>,
12875}
12876
12877/// Transaction
12878#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12879#[cfg_attr(feature = "bindings", derive(TS))]
12880pub struct Transaction {
12881    #[serde(default)]
12882    pub this: Option<Box<Expression>>,
12883    #[serde(default)]
12884    pub modes: Option<Box<Expression>>,
12885    #[serde(default)]
12886    pub mark: Option<Box<Expression>>,
12887}
12888
12889/// Commit
12890#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12891#[cfg_attr(feature = "bindings", derive(TS))]
12892pub struct Commit {
12893    #[serde(default)]
12894    pub chain: Option<Box<Expression>>,
12895    #[serde(default)]
12896    pub this: Option<Box<Expression>>,
12897    #[serde(default)]
12898    pub durability: Option<Box<Expression>>,
12899}
12900
12901/// Rollback
12902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12903#[cfg_attr(feature = "bindings", derive(TS))]
12904pub struct Rollback {
12905    #[serde(default)]
12906    pub savepoint: Option<Box<Expression>>,
12907    #[serde(default)]
12908    pub this: Option<Box<Expression>>,
12909}
12910
12911/// AlterSession
12912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12913#[cfg_attr(feature = "bindings", derive(TS))]
12914pub struct AlterSession {
12915    #[serde(default)]
12916    pub expressions: Vec<Expression>,
12917    #[serde(default)]
12918    pub unset: Option<Box<Expression>>,
12919}
12920
12921/// Analyze
12922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12923#[cfg_attr(feature = "bindings", derive(TS))]
12924pub struct Analyze {
12925    #[serde(default)]
12926    pub kind: Option<String>,
12927    #[serde(default)]
12928    pub this: Option<Box<Expression>>,
12929    #[serde(default)]
12930    pub options: Vec<Expression>,
12931    #[serde(default)]
12932    pub mode: Option<Box<Expression>>,
12933    #[serde(default)]
12934    pub partition: Option<Box<Expression>>,
12935    #[serde(default)]
12936    pub expression: Option<Box<Expression>>,
12937    #[serde(default)]
12938    pub properties: Vec<Expression>,
12939    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12940    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12941    pub columns: Vec<String>,
12942}
12943
12944/// AnalyzeStatistics
12945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12946#[cfg_attr(feature = "bindings", derive(TS))]
12947pub struct AnalyzeStatistics {
12948    pub kind: String,
12949    #[serde(default)]
12950    pub option: Option<Box<Expression>>,
12951    #[serde(default)]
12952    pub this: Option<Box<Expression>>,
12953    #[serde(default)]
12954    pub expressions: Vec<Expression>,
12955}
12956
12957/// AnalyzeHistogram
12958#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12959#[cfg_attr(feature = "bindings", derive(TS))]
12960pub struct AnalyzeHistogram {
12961    pub this: Box<Expression>,
12962    #[serde(default)]
12963    pub expressions: Vec<Expression>,
12964    #[serde(default)]
12965    pub expression: Option<Box<Expression>>,
12966    #[serde(default)]
12967    pub update_options: Option<Box<Expression>>,
12968}
12969
12970/// AnalyzeSample
12971#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12972#[cfg_attr(feature = "bindings", derive(TS))]
12973pub struct AnalyzeSample {
12974    pub kind: String,
12975    #[serde(default)]
12976    pub sample: Option<Box<Expression>>,
12977}
12978
12979/// AnalyzeListChainedRows
12980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12981#[cfg_attr(feature = "bindings", derive(TS))]
12982pub struct AnalyzeListChainedRows {
12983    #[serde(default)]
12984    pub expression: Option<Box<Expression>>,
12985}
12986
12987/// AnalyzeDelete
12988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12989#[cfg_attr(feature = "bindings", derive(TS))]
12990pub struct AnalyzeDelete {
12991    #[serde(default)]
12992    pub kind: Option<String>,
12993}
12994
12995/// AnalyzeWith
12996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12997#[cfg_attr(feature = "bindings", derive(TS))]
12998pub struct AnalyzeWith {
12999    #[serde(default)]
13000    pub expressions: Vec<Expression>,
13001}
13002
13003/// AnalyzeValidate
13004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13005#[cfg_attr(feature = "bindings", derive(TS))]
13006pub struct AnalyzeValidate {
13007    pub kind: String,
13008    #[serde(default)]
13009    pub this: Option<Box<Expression>>,
13010    #[serde(default)]
13011    pub expression: Option<Box<Expression>>,
13012}
13013
13014/// AddPartition
13015#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13016#[cfg_attr(feature = "bindings", derive(TS))]
13017pub struct AddPartition {
13018    pub this: Box<Expression>,
13019    #[serde(default)]
13020    pub exists: bool,
13021    #[serde(default)]
13022    pub location: Option<Box<Expression>>,
13023}
13024
13025/// AttachOption
13026#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13027#[cfg_attr(feature = "bindings", derive(TS))]
13028pub struct AttachOption {
13029    pub this: Box<Expression>,
13030    #[serde(default)]
13031    pub expression: Option<Box<Expression>>,
13032}
13033
13034/// DropPartition
13035#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13036#[cfg_attr(feature = "bindings", derive(TS))]
13037pub struct DropPartition {
13038    #[serde(default)]
13039    pub expressions: Vec<Expression>,
13040    #[serde(default)]
13041    pub exists: bool,
13042}
13043
13044/// ReplacePartition
13045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13046#[cfg_attr(feature = "bindings", derive(TS))]
13047pub struct ReplacePartition {
13048    pub expression: Box<Expression>,
13049    #[serde(default)]
13050    pub source: Option<Box<Expression>>,
13051}
13052
13053/// DPipe
13054#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13055#[cfg_attr(feature = "bindings", derive(TS))]
13056pub struct DPipe {
13057    pub this: Box<Expression>,
13058    pub expression: Box<Expression>,
13059    #[serde(default)]
13060    pub safe: Option<Box<Expression>>,
13061}
13062
13063/// Operator
13064#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13065#[cfg_attr(feature = "bindings", derive(TS))]
13066pub struct Operator {
13067    pub this: Box<Expression>,
13068    #[serde(default)]
13069    pub operator: Option<Box<Expression>>,
13070    pub expression: Box<Expression>,
13071    /// Comments between OPERATOR() and the RHS expression
13072    #[serde(default, skip_serializing_if = "Vec::is_empty")]
13073    pub comments: Vec<String>,
13074}
13075
13076/// PivotAny
13077#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13078#[cfg_attr(feature = "bindings", derive(TS))]
13079pub struct PivotAny {
13080    #[serde(default)]
13081    pub this: Option<Box<Expression>>,
13082}
13083
13084/// Aliases
13085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13086#[cfg_attr(feature = "bindings", derive(TS))]
13087pub struct Aliases {
13088    pub this: Box<Expression>,
13089    #[serde(default)]
13090    pub expressions: Vec<Expression>,
13091}
13092
13093/// AtIndex
13094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13095#[cfg_attr(feature = "bindings", derive(TS))]
13096pub struct AtIndex {
13097    pub this: Box<Expression>,
13098    pub expression: Box<Expression>,
13099}
13100
13101/// FromTimeZone
13102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13103#[cfg_attr(feature = "bindings", derive(TS))]
13104pub struct FromTimeZone {
13105    pub this: Box<Expression>,
13106    #[serde(default)]
13107    pub zone: Option<Box<Expression>>,
13108}
13109
13110/// Format override for a column in Teradata
13111#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13112#[cfg_attr(feature = "bindings", derive(TS))]
13113pub struct FormatPhrase {
13114    pub this: Box<Expression>,
13115    pub format: String,
13116}
13117
13118/// ForIn
13119#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13120#[cfg_attr(feature = "bindings", derive(TS))]
13121pub struct ForIn {
13122    pub this: Box<Expression>,
13123    pub expression: Box<Expression>,
13124}
13125
13126/// Automatically converts unit arg into a var.
13127#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13128#[cfg_attr(feature = "bindings", derive(TS))]
13129pub struct TimeUnit {
13130    #[serde(default)]
13131    pub unit: Option<String>,
13132}
13133
13134/// IntervalOp
13135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13136#[cfg_attr(feature = "bindings", derive(TS))]
13137pub struct IntervalOp {
13138    #[serde(default)]
13139    pub unit: Option<String>,
13140    pub expression: Box<Expression>,
13141}
13142
13143/// HavingMax
13144#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13145#[cfg_attr(feature = "bindings", derive(TS))]
13146pub struct HavingMax {
13147    pub this: Box<Expression>,
13148    pub expression: Box<Expression>,
13149    #[serde(default)]
13150    pub max: Option<Box<Expression>>,
13151}
13152
13153/// CosineDistance
13154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13155#[cfg_attr(feature = "bindings", derive(TS))]
13156pub struct CosineDistance {
13157    pub this: Box<Expression>,
13158    pub expression: Box<Expression>,
13159}
13160
13161/// DotProduct
13162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13163#[cfg_attr(feature = "bindings", derive(TS))]
13164pub struct DotProduct {
13165    pub this: Box<Expression>,
13166    pub expression: Box<Expression>,
13167}
13168
13169/// EuclideanDistance
13170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13171#[cfg_attr(feature = "bindings", derive(TS))]
13172pub struct EuclideanDistance {
13173    pub this: Box<Expression>,
13174    pub expression: Box<Expression>,
13175}
13176
13177/// ManhattanDistance
13178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13179#[cfg_attr(feature = "bindings", derive(TS))]
13180pub struct ManhattanDistance {
13181    pub this: Box<Expression>,
13182    pub expression: Box<Expression>,
13183}
13184
13185/// JarowinklerSimilarity
13186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13187#[cfg_attr(feature = "bindings", derive(TS))]
13188pub struct JarowinklerSimilarity {
13189    pub this: Box<Expression>,
13190    pub expression: Box<Expression>,
13191}
13192
13193/// Booland
13194#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13195#[cfg_attr(feature = "bindings", derive(TS))]
13196pub struct Booland {
13197    pub this: Box<Expression>,
13198    pub expression: Box<Expression>,
13199}
13200
13201/// Boolor
13202#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13203#[cfg_attr(feature = "bindings", derive(TS))]
13204pub struct Boolor {
13205    pub this: Box<Expression>,
13206    pub expression: Box<Expression>,
13207}
13208
13209/// ParameterizedAgg
13210#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13211#[cfg_attr(feature = "bindings", derive(TS))]
13212pub struct ParameterizedAgg {
13213    pub this: Box<Expression>,
13214    #[serde(default)]
13215    pub expressions: Vec<Expression>,
13216    #[serde(default)]
13217    pub params: Vec<Expression>,
13218}
13219
13220/// ArgMax
13221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13222#[cfg_attr(feature = "bindings", derive(TS))]
13223pub struct ArgMax {
13224    pub this: Box<Expression>,
13225    pub expression: Box<Expression>,
13226    #[serde(default)]
13227    pub count: Option<Box<Expression>>,
13228}
13229
13230/// ArgMin
13231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13232#[cfg_attr(feature = "bindings", derive(TS))]
13233pub struct ArgMin {
13234    pub this: Box<Expression>,
13235    pub expression: Box<Expression>,
13236    #[serde(default)]
13237    pub count: Option<Box<Expression>>,
13238}
13239
13240/// ApproxTopK
13241#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13242#[cfg_attr(feature = "bindings", derive(TS))]
13243pub struct ApproxTopK {
13244    pub this: Box<Expression>,
13245    #[serde(default)]
13246    pub expression: Option<Box<Expression>>,
13247    #[serde(default)]
13248    pub counters: Option<Box<Expression>>,
13249}
13250
13251/// ApproxTopKAccumulate
13252#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13253#[cfg_attr(feature = "bindings", derive(TS))]
13254pub struct ApproxTopKAccumulate {
13255    pub this: Box<Expression>,
13256    #[serde(default)]
13257    pub expression: Option<Box<Expression>>,
13258}
13259
13260/// ApproxTopKCombine
13261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13262#[cfg_attr(feature = "bindings", derive(TS))]
13263pub struct ApproxTopKCombine {
13264    pub this: Box<Expression>,
13265    #[serde(default)]
13266    pub expression: Option<Box<Expression>>,
13267}
13268
13269/// ApproxTopKEstimate
13270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13271#[cfg_attr(feature = "bindings", derive(TS))]
13272pub struct ApproxTopKEstimate {
13273    pub this: Box<Expression>,
13274    #[serde(default)]
13275    pub expression: Option<Box<Expression>>,
13276}
13277
13278/// ApproxTopSum
13279#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13280#[cfg_attr(feature = "bindings", derive(TS))]
13281pub struct ApproxTopSum {
13282    pub this: Box<Expression>,
13283    pub expression: Box<Expression>,
13284    #[serde(default)]
13285    pub count: Option<Box<Expression>>,
13286}
13287
13288/// ApproxQuantiles
13289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13290#[cfg_attr(feature = "bindings", derive(TS))]
13291pub struct ApproxQuantiles {
13292    pub this: Box<Expression>,
13293    #[serde(default)]
13294    pub expression: Option<Box<Expression>>,
13295}
13296
13297/// Minhash
13298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13299#[cfg_attr(feature = "bindings", derive(TS))]
13300pub struct Minhash {
13301    pub this: Box<Expression>,
13302    #[serde(default)]
13303    pub expressions: Vec<Expression>,
13304}
13305
13306/// FarmFingerprint
13307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13308#[cfg_attr(feature = "bindings", derive(TS))]
13309pub struct FarmFingerprint {
13310    #[serde(default)]
13311    pub expressions: Vec<Expression>,
13312}
13313
13314/// Float64
13315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13316#[cfg_attr(feature = "bindings", derive(TS))]
13317pub struct Float64 {
13318    pub this: Box<Expression>,
13319    #[serde(default)]
13320    pub expression: Option<Box<Expression>>,
13321}
13322
13323/// Transform
13324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13325#[cfg_attr(feature = "bindings", derive(TS))]
13326pub struct Transform {
13327    pub this: Box<Expression>,
13328    pub expression: Box<Expression>,
13329}
13330
13331/// Translate
13332#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13333#[cfg_attr(feature = "bindings", derive(TS))]
13334pub struct Translate {
13335    pub this: Box<Expression>,
13336    #[serde(default)]
13337    pub from_: Option<Box<Expression>>,
13338    #[serde(default)]
13339    pub to: Option<Box<Expression>>,
13340}
13341
13342/// Grouping
13343#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13344#[cfg_attr(feature = "bindings", derive(TS))]
13345pub struct Grouping {
13346    #[serde(default)]
13347    pub expressions: Vec<Expression>,
13348}
13349
13350/// GroupingId
13351#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13352#[cfg_attr(feature = "bindings", derive(TS))]
13353pub struct GroupingId {
13354    #[serde(default)]
13355    pub expressions: Vec<Expression>,
13356}
13357
13358/// Anonymous
13359#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13360#[cfg_attr(feature = "bindings", derive(TS))]
13361pub struct Anonymous {
13362    pub this: Box<Expression>,
13363    #[serde(default)]
13364    pub expressions: Vec<Expression>,
13365}
13366
13367/// AnonymousAggFunc
13368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13369#[cfg_attr(feature = "bindings", derive(TS))]
13370pub struct AnonymousAggFunc {
13371    pub this: Box<Expression>,
13372    #[serde(default)]
13373    pub expressions: Vec<Expression>,
13374}
13375
13376/// CombinedAggFunc
13377#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13378#[cfg_attr(feature = "bindings", derive(TS))]
13379pub struct CombinedAggFunc {
13380    pub this: Box<Expression>,
13381    #[serde(default)]
13382    pub expressions: Vec<Expression>,
13383}
13384
13385/// CombinedParameterizedAgg
13386#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13387#[cfg_attr(feature = "bindings", derive(TS))]
13388pub struct CombinedParameterizedAgg {
13389    pub this: Box<Expression>,
13390    #[serde(default)]
13391    pub expressions: Vec<Expression>,
13392    #[serde(default)]
13393    pub params: Vec<Expression>,
13394}
13395
13396/// HashAgg
13397#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13398#[cfg_attr(feature = "bindings", derive(TS))]
13399pub struct HashAgg {
13400    pub this: Box<Expression>,
13401    #[serde(default)]
13402    pub expressions: Vec<Expression>,
13403}
13404
13405/// Hll
13406#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13407#[cfg_attr(feature = "bindings", derive(TS))]
13408pub struct Hll {
13409    pub this: Box<Expression>,
13410    #[serde(default)]
13411    pub expressions: Vec<Expression>,
13412}
13413
13414/// Apply
13415#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13416#[cfg_attr(feature = "bindings", derive(TS))]
13417pub struct Apply {
13418    pub this: Box<Expression>,
13419    pub expression: Box<Expression>,
13420}
13421
13422/// ToBoolean
13423#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13424#[cfg_attr(feature = "bindings", derive(TS))]
13425pub struct ToBoolean {
13426    pub this: Box<Expression>,
13427    #[serde(default)]
13428    pub safe: Option<Box<Expression>>,
13429}
13430
13431/// List
13432#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13433#[cfg_attr(feature = "bindings", derive(TS))]
13434pub struct List {
13435    #[serde(default)]
13436    pub expressions: Vec<Expression>,
13437}
13438
13439/// ToMap - Materialize-style map constructor
13440/// Can hold either:
13441/// - A SELECT subquery (MAP(SELECT 'a', 1))
13442/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
13443#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13444#[cfg_attr(feature = "bindings", derive(TS))]
13445pub struct ToMap {
13446    /// Either a Select subquery or a Struct containing PropertyEQ entries
13447    pub this: Box<Expression>,
13448}
13449
13450/// Pad
13451#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13452#[cfg_attr(feature = "bindings", derive(TS))]
13453pub struct Pad {
13454    pub this: Box<Expression>,
13455    pub expression: Box<Expression>,
13456    #[serde(default)]
13457    pub fill_pattern: Option<Box<Expression>>,
13458    #[serde(default)]
13459    pub is_left: Option<Box<Expression>>,
13460}
13461
13462/// ToChar
13463#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13464#[cfg_attr(feature = "bindings", derive(TS))]
13465pub struct ToChar {
13466    pub this: Box<Expression>,
13467    #[serde(default)]
13468    pub format: Option<String>,
13469    #[serde(default)]
13470    pub nlsparam: Option<Box<Expression>>,
13471    #[serde(default)]
13472    pub is_numeric: Option<Box<Expression>>,
13473}
13474
13475/// StringFunc - String type conversion function (BigQuery STRING)
13476#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13477#[cfg_attr(feature = "bindings", derive(TS))]
13478pub struct StringFunc {
13479    pub this: Box<Expression>,
13480    #[serde(default)]
13481    pub zone: Option<Box<Expression>>,
13482}
13483
13484/// ToNumber
13485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13486#[cfg_attr(feature = "bindings", derive(TS))]
13487pub struct ToNumber {
13488    pub this: Box<Expression>,
13489    #[serde(default)]
13490    pub format: Option<Box<Expression>>,
13491    #[serde(default)]
13492    pub nlsparam: Option<Box<Expression>>,
13493    #[serde(default)]
13494    pub precision: Option<Box<Expression>>,
13495    #[serde(default)]
13496    pub scale: Option<Box<Expression>>,
13497    #[serde(default)]
13498    pub safe: Option<Box<Expression>>,
13499    #[serde(default)]
13500    pub safe_name: Option<Box<Expression>>,
13501}
13502
13503/// ToDouble
13504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13505#[cfg_attr(feature = "bindings", derive(TS))]
13506pub struct ToDouble {
13507    pub this: Box<Expression>,
13508    #[serde(default)]
13509    pub format: Option<String>,
13510    #[serde(default)]
13511    pub safe: Option<Box<Expression>>,
13512}
13513
13514/// ToDecfloat
13515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13516#[cfg_attr(feature = "bindings", derive(TS))]
13517pub struct ToDecfloat {
13518    pub this: Box<Expression>,
13519    #[serde(default)]
13520    pub format: Option<String>,
13521}
13522
13523/// TryToDecfloat
13524#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13525#[cfg_attr(feature = "bindings", derive(TS))]
13526pub struct TryToDecfloat {
13527    pub this: Box<Expression>,
13528    #[serde(default)]
13529    pub format: Option<String>,
13530}
13531
13532/// ToFile
13533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13534#[cfg_attr(feature = "bindings", derive(TS))]
13535pub struct ToFile {
13536    pub this: Box<Expression>,
13537    #[serde(default)]
13538    pub path: Option<Box<Expression>>,
13539    #[serde(default)]
13540    pub safe: Option<Box<Expression>>,
13541}
13542
13543/// Columns
13544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13545#[cfg_attr(feature = "bindings", derive(TS))]
13546pub struct Columns {
13547    pub this: Box<Expression>,
13548    #[serde(default)]
13549    pub unpack: Option<Box<Expression>>,
13550}
13551
13552/// ConvertToCharset
13553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13554#[cfg_attr(feature = "bindings", derive(TS))]
13555pub struct ConvertToCharset {
13556    pub this: Box<Expression>,
13557    #[serde(default)]
13558    pub dest: Option<Box<Expression>>,
13559    #[serde(default)]
13560    pub source: Option<Box<Expression>>,
13561}
13562
13563/// ConvertTimezone
13564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13565#[cfg_attr(feature = "bindings", derive(TS))]
13566pub struct ConvertTimezone {
13567    #[serde(default)]
13568    pub source_tz: Option<Box<Expression>>,
13569    #[serde(default)]
13570    pub target_tz: Option<Box<Expression>>,
13571    #[serde(default)]
13572    pub timestamp: Option<Box<Expression>>,
13573    #[serde(default)]
13574    pub options: Vec<Expression>,
13575}
13576
13577/// GenerateSeries
13578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13579#[cfg_attr(feature = "bindings", derive(TS))]
13580pub struct GenerateSeries {
13581    #[serde(default)]
13582    pub start: Option<Box<Expression>>,
13583    #[serde(default)]
13584    pub end: Option<Box<Expression>>,
13585    #[serde(default)]
13586    pub step: Option<Box<Expression>>,
13587    #[serde(default)]
13588    pub is_end_exclusive: Option<Box<Expression>>,
13589}
13590
13591/// AIAgg
13592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13593#[cfg_attr(feature = "bindings", derive(TS))]
13594pub struct AIAgg {
13595    pub this: Box<Expression>,
13596    pub expression: Box<Expression>,
13597}
13598
13599/// AIClassify
13600#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13601#[cfg_attr(feature = "bindings", derive(TS))]
13602pub struct AIClassify {
13603    pub this: Box<Expression>,
13604    #[serde(default)]
13605    pub categories: Option<Box<Expression>>,
13606    #[serde(default)]
13607    pub config: Option<Box<Expression>>,
13608}
13609
13610/// ArrayAll
13611#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13612#[cfg_attr(feature = "bindings", derive(TS))]
13613pub struct ArrayAll {
13614    pub this: Box<Expression>,
13615    pub expression: Box<Expression>,
13616}
13617
13618/// ArrayAny
13619#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13620#[cfg_attr(feature = "bindings", derive(TS))]
13621pub struct ArrayAny {
13622    pub this: Box<Expression>,
13623    pub expression: Box<Expression>,
13624}
13625
13626/// ArrayConstructCompact
13627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13628#[cfg_attr(feature = "bindings", derive(TS))]
13629pub struct ArrayConstructCompact {
13630    #[serde(default)]
13631    pub expressions: Vec<Expression>,
13632}
13633
13634/// StPoint
13635#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13636#[cfg_attr(feature = "bindings", derive(TS))]
13637pub struct StPoint {
13638    pub this: Box<Expression>,
13639    pub expression: Box<Expression>,
13640    #[serde(default)]
13641    pub null: Option<Box<Expression>>,
13642}
13643
13644/// StDistance
13645#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13646#[cfg_attr(feature = "bindings", derive(TS))]
13647pub struct StDistance {
13648    pub this: Box<Expression>,
13649    pub expression: Box<Expression>,
13650    #[serde(default)]
13651    pub use_spheroid: Option<Box<Expression>>,
13652}
13653
13654/// StringToArray
13655#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13656#[cfg_attr(feature = "bindings", derive(TS))]
13657pub struct StringToArray {
13658    pub this: Box<Expression>,
13659    #[serde(default)]
13660    pub expression: Option<Box<Expression>>,
13661    #[serde(default)]
13662    pub null: Option<Box<Expression>>,
13663}
13664
13665/// ArraySum
13666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13667#[cfg_attr(feature = "bindings", derive(TS))]
13668pub struct ArraySum {
13669    pub this: Box<Expression>,
13670    #[serde(default)]
13671    pub expression: Option<Box<Expression>>,
13672}
13673
13674/// ObjectAgg
13675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13676#[cfg_attr(feature = "bindings", derive(TS))]
13677pub struct ObjectAgg {
13678    pub this: Box<Expression>,
13679    pub expression: Box<Expression>,
13680}
13681
13682/// CastToStrType
13683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13684#[cfg_attr(feature = "bindings", derive(TS))]
13685pub struct CastToStrType {
13686    pub this: Box<Expression>,
13687    #[serde(default)]
13688    pub to: Option<Box<Expression>>,
13689}
13690
13691/// CheckJson
13692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13693#[cfg_attr(feature = "bindings", derive(TS))]
13694pub struct CheckJson {
13695    pub this: Box<Expression>,
13696}
13697
13698/// CheckXml
13699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13700#[cfg_attr(feature = "bindings", derive(TS))]
13701pub struct CheckXml {
13702    pub this: Box<Expression>,
13703    #[serde(default)]
13704    pub disable_auto_convert: Option<Box<Expression>>,
13705}
13706
13707/// TranslateCharacters
13708#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13709#[cfg_attr(feature = "bindings", derive(TS))]
13710pub struct TranslateCharacters {
13711    pub this: Box<Expression>,
13712    pub expression: Box<Expression>,
13713    #[serde(default)]
13714    pub with_error: Option<Box<Expression>>,
13715}
13716
13717/// CurrentSchemas
13718#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13719#[cfg_attr(feature = "bindings", derive(TS))]
13720pub struct CurrentSchemas {
13721    #[serde(default)]
13722    pub this: Option<Box<Expression>>,
13723}
13724
13725/// CurrentDatetime
13726#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13727#[cfg_attr(feature = "bindings", derive(TS))]
13728pub struct CurrentDatetime {
13729    #[serde(default)]
13730    pub this: Option<Box<Expression>>,
13731}
13732
13733/// Localtime
13734#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13735#[cfg_attr(feature = "bindings", derive(TS))]
13736pub struct Localtime {
13737    #[serde(default)]
13738    pub this: Option<Box<Expression>>,
13739}
13740
13741/// Localtimestamp
13742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13743#[cfg_attr(feature = "bindings", derive(TS))]
13744pub struct Localtimestamp {
13745    #[serde(default)]
13746    pub this: Option<Box<Expression>>,
13747}
13748
13749/// Systimestamp
13750#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13751#[cfg_attr(feature = "bindings", derive(TS))]
13752pub struct Systimestamp {
13753    #[serde(default)]
13754    pub this: Option<Box<Expression>>,
13755}
13756
13757/// CurrentSchema
13758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13759#[cfg_attr(feature = "bindings", derive(TS))]
13760pub struct CurrentSchema {
13761    #[serde(default)]
13762    pub this: Option<Box<Expression>>,
13763}
13764
13765/// CurrentUser
13766#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13767#[cfg_attr(feature = "bindings", derive(TS))]
13768pub struct CurrentUser {
13769    #[serde(default)]
13770    pub this: Option<Box<Expression>>,
13771}
13772
13773/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13774#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13775#[cfg_attr(feature = "bindings", derive(TS))]
13776pub struct SessionUser;
13777
13778/// JSONPathRoot - Represents $ in JSON path expressions
13779#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13780#[cfg_attr(feature = "bindings", derive(TS))]
13781pub struct JSONPathRoot;
13782
13783/// UtcTime
13784#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13785#[cfg_attr(feature = "bindings", derive(TS))]
13786pub struct UtcTime {
13787    #[serde(default)]
13788    pub this: Option<Box<Expression>>,
13789}
13790
13791/// UtcTimestamp
13792#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13793#[cfg_attr(feature = "bindings", derive(TS))]
13794pub struct UtcTimestamp {
13795    #[serde(default)]
13796    pub this: Option<Box<Expression>>,
13797}
13798
13799/// TimestampFunc - TIMESTAMP constructor function
13800#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13801#[cfg_attr(feature = "bindings", derive(TS))]
13802pub struct TimestampFunc {
13803    #[serde(default)]
13804    pub this: Option<Box<Expression>>,
13805    #[serde(default)]
13806    pub zone: Option<Box<Expression>>,
13807    #[serde(default)]
13808    pub with_tz: Option<bool>,
13809    #[serde(default)]
13810    pub safe: Option<bool>,
13811}
13812
13813/// DateBin
13814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13815#[cfg_attr(feature = "bindings", derive(TS))]
13816pub struct DateBin {
13817    pub this: Box<Expression>,
13818    pub expression: Box<Expression>,
13819    #[serde(default)]
13820    pub unit: Option<String>,
13821    #[serde(default)]
13822    pub zone: Option<Box<Expression>>,
13823    #[serde(default)]
13824    pub origin: Option<Box<Expression>>,
13825}
13826
13827/// Datetime
13828#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13829#[cfg_attr(feature = "bindings", derive(TS))]
13830pub struct Datetime {
13831    pub this: Box<Expression>,
13832    #[serde(default)]
13833    pub expression: Option<Box<Expression>>,
13834}
13835
13836/// DatetimeAdd
13837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13838#[cfg_attr(feature = "bindings", derive(TS))]
13839pub struct DatetimeAdd {
13840    pub this: Box<Expression>,
13841    pub expression: Box<Expression>,
13842    #[serde(default)]
13843    pub unit: Option<String>,
13844}
13845
13846/// DatetimeSub
13847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13848#[cfg_attr(feature = "bindings", derive(TS))]
13849pub struct DatetimeSub {
13850    pub this: Box<Expression>,
13851    pub expression: Box<Expression>,
13852    #[serde(default)]
13853    pub unit: Option<String>,
13854}
13855
13856/// DatetimeDiff
13857#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13858#[cfg_attr(feature = "bindings", derive(TS))]
13859pub struct DatetimeDiff {
13860    pub this: Box<Expression>,
13861    pub expression: Box<Expression>,
13862    #[serde(default)]
13863    pub unit: Option<String>,
13864}
13865
13866/// DatetimeTrunc
13867#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13868#[cfg_attr(feature = "bindings", derive(TS))]
13869pub struct DatetimeTrunc {
13870    pub this: Box<Expression>,
13871    pub unit: String,
13872    #[serde(default)]
13873    pub zone: Option<Box<Expression>>,
13874}
13875
13876/// Dayname
13877#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13878#[cfg_attr(feature = "bindings", derive(TS))]
13879pub struct Dayname {
13880    pub this: Box<Expression>,
13881    #[serde(default)]
13882    pub abbreviated: Option<Box<Expression>>,
13883}
13884
13885/// MakeInterval
13886#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13887#[cfg_attr(feature = "bindings", derive(TS))]
13888pub struct MakeInterval {
13889    #[serde(default)]
13890    pub year: Option<Box<Expression>>,
13891    #[serde(default)]
13892    pub month: Option<Box<Expression>>,
13893    #[serde(default)]
13894    pub week: Option<Box<Expression>>,
13895    #[serde(default)]
13896    pub day: Option<Box<Expression>>,
13897    #[serde(default)]
13898    pub hour: Option<Box<Expression>>,
13899    #[serde(default)]
13900    pub minute: Option<Box<Expression>>,
13901    #[serde(default)]
13902    pub second: Option<Box<Expression>>,
13903}
13904
13905/// PreviousDay
13906#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13907#[cfg_attr(feature = "bindings", derive(TS))]
13908pub struct PreviousDay {
13909    pub this: Box<Expression>,
13910    pub expression: Box<Expression>,
13911}
13912
13913/// Elt
13914#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13915#[cfg_attr(feature = "bindings", derive(TS))]
13916pub struct Elt {
13917    pub this: Box<Expression>,
13918    #[serde(default)]
13919    pub expressions: Vec<Expression>,
13920}
13921
13922/// TimestampAdd
13923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13924#[cfg_attr(feature = "bindings", derive(TS))]
13925pub struct TimestampAdd {
13926    pub this: Box<Expression>,
13927    pub expression: Box<Expression>,
13928    #[serde(default)]
13929    pub unit: Option<String>,
13930}
13931
13932/// TimestampSub
13933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13934#[cfg_attr(feature = "bindings", derive(TS))]
13935pub struct TimestampSub {
13936    pub this: Box<Expression>,
13937    pub expression: Box<Expression>,
13938    #[serde(default)]
13939    pub unit: Option<String>,
13940}
13941
13942/// TimestampDiff
13943#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13944#[cfg_attr(feature = "bindings", derive(TS))]
13945pub struct TimestampDiff {
13946    pub this: Box<Expression>,
13947    pub expression: Box<Expression>,
13948    #[serde(default)]
13949    pub unit: Option<String>,
13950}
13951
13952/// TimeSlice
13953#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13954#[cfg_attr(feature = "bindings", derive(TS))]
13955pub struct TimeSlice {
13956    pub this: Box<Expression>,
13957    pub expression: Box<Expression>,
13958    pub unit: String,
13959    #[serde(default)]
13960    pub kind: Option<String>,
13961}
13962
13963/// TimeAdd
13964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13965#[cfg_attr(feature = "bindings", derive(TS))]
13966pub struct TimeAdd {
13967    pub this: Box<Expression>,
13968    pub expression: Box<Expression>,
13969    #[serde(default)]
13970    pub unit: Option<String>,
13971}
13972
13973/// TimeSub
13974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13975#[cfg_attr(feature = "bindings", derive(TS))]
13976pub struct TimeSub {
13977    pub this: Box<Expression>,
13978    pub expression: Box<Expression>,
13979    #[serde(default)]
13980    pub unit: Option<String>,
13981}
13982
13983/// TimeDiff
13984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13985#[cfg_attr(feature = "bindings", derive(TS))]
13986pub struct TimeDiff {
13987    pub this: Box<Expression>,
13988    pub expression: Box<Expression>,
13989    #[serde(default)]
13990    pub unit: Option<String>,
13991}
13992
13993/// TimeTrunc
13994#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13995#[cfg_attr(feature = "bindings", derive(TS))]
13996pub struct TimeTrunc {
13997    pub this: Box<Expression>,
13998    pub unit: String,
13999    #[serde(default)]
14000    pub zone: Option<Box<Expression>>,
14001}
14002
14003/// DateFromParts
14004#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14005#[cfg_attr(feature = "bindings", derive(TS))]
14006pub struct DateFromParts {
14007    #[serde(default)]
14008    pub year: Option<Box<Expression>>,
14009    #[serde(default)]
14010    pub month: Option<Box<Expression>>,
14011    #[serde(default)]
14012    pub day: Option<Box<Expression>>,
14013    #[serde(default)]
14014    pub allow_overflow: Option<Box<Expression>>,
14015}
14016
14017/// TimeFromParts
14018#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14019#[cfg_attr(feature = "bindings", derive(TS))]
14020pub struct TimeFromParts {
14021    #[serde(default)]
14022    pub hour: Option<Box<Expression>>,
14023    #[serde(default)]
14024    pub min: Option<Box<Expression>>,
14025    #[serde(default)]
14026    pub sec: Option<Box<Expression>>,
14027    #[serde(default)]
14028    pub nano: Option<Box<Expression>>,
14029    #[serde(default)]
14030    pub fractions: Option<Box<Expression>>,
14031    #[serde(default)]
14032    pub precision: Option<i64>,
14033}
14034
14035/// DecodeCase
14036#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14037#[cfg_attr(feature = "bindings", derive(TS))]
14038pub struct DecodeCase {
14039    #[serde(default)]
14040    pub expressions: Vec<Expression>,
14041}
14042
14043/// Decrypt
14044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14045#[cfg_attr(feature = "bindings", derive(TS))]
14046pub struct Decrypt {
14047    pub this: Box<Expression>,
14048    #[serde(default)]
14049    pub passphrase: Option<Box<Expression>>,
14050    #[serde(default)]
14051    pub aad: Option<Box<Expression>>,
14052    #[serde(default)]
14053    pub encryption_method: Option<Box<Expression>>,
14054    #[serde(default)]
14055    pub safe: Option<Box<Expression>>,
14056}
14057
14058/// DecryptRaw
14059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14060#[cfg_attr(feature = "bindings", derive(TS))]
14061pub struct DecryptRaw {
14062    pub this: Box<Expression>,
14063    #[serde(default)]
14064    pub key: Option<Box<Expression>>,
14065    #[serde(default)]
14066    pub iv: Option<Box<Expression>>,
14067    #[serde(default)]
14068    pub aad: Option<Box<Expression>>,
14069    #[serde(default)]
14070    pub encryption_method: Option<Box<Expression>>,
14071    #[serde(default)]
14072    pub aead: Option<Box<Expression>>,
14073    #[serde(default)]
14074    pub safe: Option<Box<Expression>>,
14075}
14076
14077/// Encode
14078#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14079#[cfg_attr(feature = "bindings", derive(TS))]
14080pub struct Encode {
14081    pub this: Box<Expression>,
14082    #[serde(default)]
14083    pub charset: Option<Box<Expression>>,
14084}
14085
14086/// Encrypt
14087#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14088#[cfg_attr(feature = "bindings", derive(TS))]
14089pub struct Encrypt {
14090    pub this: Box<Expression>,
14091    #[serde(default)]
14092    pub passphrase: Option<Box<Expression>>,
14093    #[serde(default)]
14094    pub aad: Option<Box<Expression>>,
14095    #[serde(default)]
14096    pub encryption_method: Option<Box<Expression>>,
14097}
14098
14099/// EncryptRaw
14100#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14101#[cfg_attr(feature = "bindings", derive(TS))]
14102pub struct EncryptRaw {
14103    pub this: Box<Expression>,
14104    #[serde(default)]
14105    pub key: Option<Box<Expression>>,
14106    #[serde(default)]
14107    pub iv: Option<Box<Expression>>,
14108    #[serde(default)]
14109    pub aad: Option<Box<Expression>>,
14110    #[serde(default)]
14111    pub encryption_method: Option<Box<Expression>>,
14112}
14113
14114/// EqualNull
14115#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14116#[cfg_attr(feature = "bindings", derive(TS))]
14117pub struct EqualNull {
14118    pub this: Box<Expression>,
14119    pub expression: Box<Expression>,
14120}
14121
14122/// ToBinary
14123#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14124#[cfg_attr(feature = "bindings", derive(TS))]
14125pub struct ToBinary {
14126    pub this: Box<Expression>,
14127    #[serde(default)]
14128    pub format: Option<String>,
14129    #[serde(default)]
14130    pub safe: Option<Box<Expression>>,
14131}
14132
14133/// Base64DecodeBinary
14134#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14135#[cfg_attr(feature = "bindings", derive(TS))]
14136pub struct Base64DecodeBinary {
14137    pub this: Box<Expression>,
14138    #[serde(default)]
14139    pub alphabet: Option<Box<Expression>>,
14140}
14141
14142/// Base64DecodeString
14143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14144#[cfg_attr(feature = "bindings", derive(TS))]
14145pub struct Base64DecodeString {
14146    pub this: Box<Expression>,
14147    #[serde(default)]
14148    pub alphabet: Option<Box<Expression>>,
14149}
14150
14151/// Base64Encode
14152#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14153#[cfg_attr(feature = "bindings", derive(TS))]
14154pub struct Base64Encode {
14155    pub this: Box<Expression>,
14156    #[serde(default)]
14157    pub max_line_length: Option<Box<Expression>>,
14158    #[serde(default)]
14159    pub alphabet: Option<Box<Expression>>,
14160}
14161
14162/// TryBase64DecodeBinary
14163#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14164#[cfg_attr(feature = "bindings", derive(TS))]
14165pub struct TryBase64DecodeBinary {
14166    pub this: Box<Expression>,
14167    #[serde(default)]
14168    pub alphabet: Option<Box<Expression>>,
14169}
14170
14171/// TryBase64DecodeString
14172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14173#[cfg_attr(feature = "bindings", derive(TS))]
14174pub struct TryBase64DecodeString {
14175    pub this: Box<Expression>,
14176    #[serde(default)]
14177    pub alphabet: Option<Box<Expression>>,
14178}
14179
14180/// GapFill
14181#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14182#[cfg_attr(feature = "bindings", derive(TS))]
14183pub struct GapFill {
14184    pub this: Box<Expression>,
14185    #[serde(default)]
14186    pub ts_column: Option<Box<Expression>>,
14187    #[serde(default)]
14188    pub bucket_width: Option<Box<Expression>>,
14189    #[serde(default)]
14190    pub partitioning_columns: Option<Box<Expression>>,
14191    #[serde(default)]
14192    pub value_columns: Option<Box<Expression>>,
14193    #[serde(default)]
14194    pub origin: Option<Box<Expression>>,
14195    #[serde(default)]
14196    pub ignore_nulls: Option<Box<Expression>>,
14197}
14198
14199/// GenerateDateArray
14200#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14201#[cfg_attr(feature = "bindings", derive(TS))]
14202pub struct GenerateDateArray {
14203    #[serde(default)]
14204    pub start: Option<Box<Expression>>,
14205    #[serde(default)]
14206    pub end: Option<Box<Expression>>,
14207    #[serde(default)]
14208    pub step: Option<Box<Expression>>,
14209}
14210
14211/// GenerateTimestampArray
14212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14213#[cfg_attr(feature = "bindings", derive(TS))]
14214pub struct GenerateTimestampArray {
14215    #[serde(default)]
14216    pub start: Option<Box<Expression>>,
14217    #[serde(default)]
14218    pub end: Option<Box<Expression>>,
14219    #[serde(default)]
14220    pub step: Option<Box<Expression>>,
14221}
14222
14223/// GetExtract
14224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14225#[cfg_attr(feature = "bindings", derive(TS))]
14226pub struct GetExtract {
14227    pub this: Box<Expression>,
14228    pub expression: Box<Expression>,
14229}
14230
14231/// Getbit
14232#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14233#[cfg_attr(feature = "bindings", derive(TS))]
14234pub struct Getbit {
14235    pub this: Box<Expression>,
14236    pub expression: Box<Expression>,
14237    #[serde(default)]
14238    pub zero_is_msb: Option<Box<Expression>>,
14239}
14240
14241/// OverflowTruncateBehavior
14242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14243#[cfg_attr(feature = "bindings", derive(TS))]
14244pub struct OverflowTruncateBehavior {
14245    #[serde(default)]
14246    pub this: Option<Box<Expression>>,
14247    #[serde(default)]
14248    pub with_count: Option<Box<Expression>>,
14249}
14250
14251/// HexEncode
14252#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14253#[cfg_attr(feature = "bindings", derive(TS))]
14254pub struct HexEncode {
14255    pub this: Box<Expression>,
14256    #[serde(default)]
14257    pub case: Option<Box<Expression>>,
14258}
14259
14260/// Compress
14261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14262#[cfg_attr(feature = "bindings", derive(TS))]
14263pub struct Compress {
14264    pub this: Box<Expression>,
14265    #[serde(default)]
14266    pub method: Option<String>,
14267}
14268
14269/// DecompressBinary
14270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14271#[cfg_attr(feature = "bindings", derive(TS))]
14272pub struct DecompressBinary {
14273    pub this: Box<Expression>,
14274    pub method: String,
14275}
14276
14277/// DecompressString
14278#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14279#[cfg_attr(feature = "bindings", derive(TS))]
14280pub struct DecompressString {
14281    pub this: Box<Expression>,
14282    pub method: String,
14283}
14284
14285/// Xor
14286#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14287#[cfg_attr(feature = "bindings", derive(TS))]
14288pub struct Xor {
14289    #[serde(default)]
14290    pub this: Option<Box<Expression>>,
14291    #[serde(default)]
14292    pub expression: Option<Box<Expression>>,
14293    #[serde(default)]
14294    pub expressions: Vec<Expression>,
14295}
14296
14297/// Nullif
14298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14299#[cfg_attr(feature = "bindings", derive(TS))]
14300pub struct Nullif {
14301    pub this: Box<Expression>,
14302    pub expression: Box<Expression>,
14303}
14304
14305/// JSON
14306#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14307#[cfg_attr(feature = "bindings", derive(TS))]
14308pub struct JSON {
14309    #[serde(default)]
14310    pub this: Option<Box<Expression>>,
14311    #[serde(default)]
14312    pub with_: Option<Box<Expression>>,
14313    #[serde(default)]
14314    pub unique: bool,
14315}
14316
14317/// JSONPath
14318#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14319#[cfg_attr(feature = "bindings", derive(TS))]
14320pub struct JSONPath {
14321    #[serde(default)]
14322    pub expressions: Vec<Expression>,
14323    #[serde(default)]
14324    pub escape: Option<Box<Expression>>,
14325}
14326
14327/// JSONPathFilter
14328#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14329#[cfg_attr(feature = "bindings", derive(TS))]
14330pub struct JSONPathFilter {
14331    pub this: Box<Expression>,
14332}
14333
14334/// JSONPathKey
14335#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14336#[cfg_attr(feature = "bindings", derive(TS))]
14337pub struct JSONPathKey {
14338    pub this: Box<Expression>,
14339}
14340
14341/// JSONPathRecursive
14342#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14343#[cfg_attr(feature = "bindings", derive(TS))]
14344pub struct JSONPathRecursive {
14345    #[serde(default)]
14346    pub this: Option<Box<Expression>>,
14347}
14348
14349/// JSONPathScript
14350#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14351#[cfg_attr(feature = "bindings", derive(TS))]
14352pub struct JSONPathScript {
14353    pub this: Box<Expression>,
14354}
14355
14356/// JSONPathSlice
14357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14358#[cfg_attr(feature = "bindings", derive(TS))]
14359pub struct JSONPathSlice {
14360    #[serde(default)]
14361    pub start: Option<Box<Expression>>,
14362    #[serde(default)]
14363    pub end: Option<Box<Expression>>,
14364    #[serde(default)]
14365    pub step: Option<Box<Expression>>,
14366}
14367
14368/// JSONPathSelector
14369#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14370#[cfg_attr(feature = "bindings", derive(TS))]
14371pub struct JSONPathSelector {
14372    pub this: Box<Expression>,
14373}
14374
14375/// JSONPathSubscript
14376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14377#[cfg_attr(feature = "bindings", derive(TS))]
14378pub struct JSONPathSubscript {
14379    pub this: Box<Expression>,
14380}
14381
14382/// JSONPathUnion
14383#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14384#[cfg_attr(feature = "bindings", derive(TS))]
14385pub struct JSONPathUnion {
14386    #[serde(default)]
14387    pub expressions: Vec<Expression>,
14388}
14389
14390/// Format
14391#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14392#[cfg_attr(feature = "bindings", derive(TS))]
14393pub struct Format {
14394    pub this: Box<Expression>,
14395    #[serde(default)]
14396    pub expressions: Vec<Expression>,
14397}
14398
14399/// JSONKeys
14400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14401#[cfg_attr(feature = "bindings", derive(TS))]
14402pub struct JSONKeys {
14403    pub this: Box<Expression>,
14404    #[serde(default)]
14405    pub expression: Option<Box<Expression>>,
14406    #[serde(default)]
14407    pub expressions: Vec<Expression>,
14408}
14409
14410/// JSONKeyValue
14411#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14412#[cfg_attr(feature = "bindings", derive(TS))]
14413pub struct JSONKeyValue {
14414    pub this: Box<Expression>,
14415    pub expression: Box<Expression>,
14416}
14417
14418/// JSONKeysAtDepth
14419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14420#[cfg_attr(feature = "bindings", derive(TS))]
14421pub struct JSONKeysAtDepth {
14422    pub this: Box<Expression>,
14423    #[serde(default)]
14424    pub expression: Option<Box<Expression>>,
14425    #[serde(default)]
14426    pub mode: Option<Box<Expression>>,
14427}
14428
14429/// JSONObject
14430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14431#[cfg_attr(feature = "bindings", derive(TS))]
14432pub struct JSONObject {
14433    #[serde(default)]
14434    pub expressions: Vec<Expression>,
14435    #[serde(default)]
14436    pub null_handling: Option<Box<Expression>>,
14437    #[serde(default)]
14438    pub unique_keys: Option<Box<Expression>>,
14439    #[serde(default)]
14440    pub return_type: Option<Box<Expression>>,
14441    #[serde(default)]
14442    pub encoding: Option<Box<Expression>>,
14443}
14444
14445/// JSONObjectAgg
14446#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14447#[cfg_attr(feature = "bindings", derive(TS))]
14448pub struct JSONObjectAgg {
14449    #[serde(default)]
14450    pub expressions: Vec<Expression>,
14451    #[serde(default)]
14452    pub null_handling: Option<Box<Expression>>,
14453    #[serde(default)]
14454    pub unique_keys: Option<Box<Expression>>,
14455    #[serde(default)]
14456    pub return_type: Option<Box<Expression>>,
14457    #[serde(default)]
14458    pub encoding: Option<Box<Expression>>,
14459}
14460
14461/// JSONBObjectAgg
14462#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14463#[cfg_attr(feature = "bindings", derive(TS))]
14464pub struct JSONBObjectAgg {
14465    pub this: Box<Expression>,
14466    pub expression: Box<Expression>,
14467}
14468
14469/// JSONArray
14470#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14471#[cfg_attr(feature = "bindings", derive(TS))]
14472pub struct JSONArray {
14473    #[serde(default)]
14474    pub expressions: Vec<Expression>,
14475    #[serde(default)]
14476    pub null_handling: Option<Box<Expression>>,
14477    #[serde(default)]
14478    pub return_type: Option<Box<Expression>>,
14479    #[serde(default)]
14480    pub strict: Option<Box<Expression>>,
14481}
14482
14483/// JSONArrayAgg
14484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14485#[cfg_attr(feature = "bindings", derive(TS))]
14486pub struct JSONArrayAgg {
14487    pub this: Box<Expression>,
14488    #[serde(default)]
14489    pub order: Option<Box<Expression>>,
14490    #[serde(default)]
14491    pub null_handling: Option<Box<Expression>>,
14492    #[serde(default)]
14493    pub return_type: Option<Box<Expression>>,
14494    #[serde(default)]
14495    pub strict: Option<Box<Expression>>,
14496}
14497
14498/// JSONExists
14499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14500#[cfg_attr(feature = "bindings", derive(TS))]
14501pub struct JSONExists {
14502    pub this: Box<Expression>,
14503    #[serde(default)]
14504    pub path: Option<Box<Expression>>,
14505    #[serde(default)]
14506    pub passing: Option<Box<Expression>>,
14507    #[serde(default)]
14508    pub on_condition: Option<Box<Expression>>,
14509    #[serde(default)]
14510    pub from_dcolonqmark: Option<Box<Expression>>,
14511}
14512
14513/// JSONColumnDef
14514#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14515#[cfg_attr(feature = "bindings", derive(TS))]
14516pub struct JSONColumnDef {
14517    /// Typed column definition; legacy dialects may use the textual kind field.
14518    #[serde(default, skip_serializing_if = "Option::is_none")]
14519    pub data_type: Option<DataType>,
14520    #[serde(default, skip_serializing_if = "Option::is_none")]
14521    pub encoding: Option<String>,
14522    #[serde(default, skip_serializing_if = "Option::is_none")]
14523    #[ast(skip)]
14524    pub source_dialect: Option<crate::dialects::DialectType>,
14525    /// Structured SQL/JSON wrapper and error/empty behavior.
14526    #[serde(default, skip_serializing_if = "Option::is_none")]
14527    pub options: Option<JsonOptions>,
14528
14529    #[serde(default)]
14530    pub this: Option<Box<Expression>>,
14531    #[serde(default)]
14532    pub kind: Option<String>,
14533    #[serde(default)]
14534    pub format_json: bool,
14535    #[serde(default)]
14536    pub path: Option<Box<Expression>>,
14537    #[serde(default)]
14538    pub nested_schema: Option<Box<Expression>>,
14539    #[serde(default)]
14540    pub ordinality: Option<Box<Expression>>,
14541}
14542
14543/// JSONSchema
14544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14545#[cfg_attr(feature = "bindings", derive(TS))]
14546pub struct JSONSchema {
14547    #[serde(default)]
14548    pub expressions: Vec<Expression>,
14549}
14550
14551/// JSONSet
14552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14553#[cfg_attr(feature = "bindings", derive(TS))]
14554pub struct JSONSet {
14555    pub this: Box<Expression>,
14556    #[serde(default)]
14557    pub expressions: Vec<Expression>,
14558}
14559
14560/// JSONStripNulls
14561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14562#[cfg_attr(feature = "bindings", derive(TS))]
14563pub struct JSONStripNulls {
14564    pub this: Box<Expression>,
14565    #[serde(default)]
14566    pub expression: Option<Box<Expression>>,
14567    #[serde(default)]
14568    pub include_arrays: Option<Box<Expression>>,
14569    #[serde(default)]
14570    pub remove_empty: Option<Box<Expression>>,
14571}
14572
14573/// JSONValue
14574#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14575#[cfg_attr(feature = "bindings", derive(TS))]
14576pub struct JSONValue {
14577    #[serde(default, skip_serializing_if = "Option::is_none")]
14578    #[ast(skip)]
14579    pub source_dialect: Option<crate::dialects::DialectType>,
14580    /// Structured SQL/JSON wrapper and error/empty behavior.
14581    #[serde(default, skip_serializing_if = "Option::is_none")]
14582    pub options: Option<JsonOptions>,
14583
14584    pub this: Box<Expression>,
14585    #[serde(default)]
14586    pub path: Option<Box<Expression>>,
14587    #[serde(default)]
14588    pub returning: Option<Box<Expression>>,
14589    #[serde(default)]
14590    pub on_condition: Option<Box<Expression>>,
14591}
14592
14593/// JSONValueArray
14594#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14595#[cfg_attr(feature = "bindings", derive(TS))]
14596pub struct JSONValueArray {
14597    pub this: Box<Expression>,
14598    #[serde(default)]
14599    pub expression: Option<Box<Expression>>,
14600}
14601
14602/// JSONRemove
14603#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14604#[cfg_attr(feature = "bindings", derive(TS))]
14605pub struct JSONRemove {
14606    pub this: Box<Expression>,
14607    #[serde(default)]
14608    pub expressions: Vec<Expression>,
14609}
14610
14611/// JSONTable
14612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14613#[cfg_attr(feature = "bindings", derive(TS))]
14614pub struct JSONTable {
14615    #[serde(default, skip_serializing_if = "Option::is_none")]
14616    #[ast(skip)]
14617    pub source_dialect: Option<crate::dialects::DialectType>,
14618    /// Structured SQL/JSON wrapper and error/empty behavior.
14619    #[serde(default, skip_serializing_if = "Option::is_none")]
14620    pub options: Option<JsonOptions>,
14621
14622    pub this: Box<Expression>,
14623    #[serde(default)]
14624    pub schema: Option<Box<Expression>>,
14625    #[serde(default)]
14626    pub path: Option<Box<Expression>>,
14627    #[serde(default)]
14628    pub error_handling: Option<Box<Expression>>,
14629    #[serde(default)]
14630    pub empty_handling: Option<Box<Expression>>,
14631}
14632
14633/// JSONType
14634#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14635#[cfg_attr(feature = "bindings", derive(TS))]
14636pub struct JSONType {
14637    pub this: Box<Expression>,
14638    #[serde(default)]
14639    pub expression: Option<Box<Expression>>,
14640}
14641
14642/// ObjectInsert
14643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14644#[cfg_attr(feature = "bindings", derive(TS))]
14645pub struct ObjectInsert {
14646    pub this: Box<Expression>,
14647    #[serde(default)]
14648    pub key: Option<Box<Expression>>,
14649    #[serde(default)]
14650    pub value: Option<Box<Expression>>,
14651    #[serde(default)]
14652    pub update_flag: Option<Box<Expression>>,
14653}
14654
14655/// OpenJSONColumnDef
14656#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14657#[cfg_attr(feature = "bindings", derive(TS))]
14658pub struct OpenJSONColumnDef {
14659    pub this: Box<Expression>,
14660    pub kind: String,
14661    #[serde(default)]
14662    pub path: Option<Box<Expression>>,
14663    #[serde(default)]
14664    pub as_json: Option<Box<Expression>>,
14665    /// The parsed data type for proper generation
14666    #[serde(default, skip_serializing_if = "Option::is_none")]
14667    pub data_type: Option<DataType>,
14668}
14669
14670/// OpenJSON
14671#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14672#[cfg_attr(feature = "bindings", derive(TS))]
14673pub struct OpenJSON {
14674    pub this: Box<Expression>,
14675    #[serde(default)]
14676    pub path: Option<Box<Expression>>,
14677    #[serde(default)]
14678    pub expressions: Vec<Expression>,
14679}
14680
14681/// JSONBExists
14682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14683#[cfg_attr(feature = "bindings", derive(TS))]
14684pub struct JSONBExists {
14685    pub this: Box<Expression>,
14686    #[serde(default)]
14687    pub path: Option<Box<Expression>>,
14688}
14689
14690/// JSONCast
14691#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14692#[cfg_attr(feature = "bindings", derive(TS))]
14693pub struct JSONCast {
14694    pub this: Box<Expression>,
14695    pub to: DataType,
14696}
14697
14698/// JSONExtract
14699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14700#[cfg_attr(feature = "bindings", derive(TS))]
14701pub struct JSONExtract {
14702    pub this: Box<Expression>,
14703    pub expression: Box<Expression>,
14704    #[serde(default)]
14705    pub only_json_types: Option<Box<Expression>>,
14706    #[serde(default)]
14707    pub expressions: Vec<Expression>,
14708    #[serde(default)]
14709    pub variant_extract: Option<Box<Expression>>,
14710    #[serde(default)]
14711    pub json_query: Option<Box<Expression>>,
14712    #[serde(default)]
14713    pub option: Option<Box<Expression>>,
14714    #[serde(default)]
14715    pub quote: Option<Box<Expression>>,
14716    #[serde(default)]
14717    pub on_condition: Option<Box<Expression>>,
14718    #[serde(default)]
14719    pub requires_json: Option<Box<Expression>>,
14720}
14721
14722/// JSONExtractQuote
14723#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14724#[cfg_attr(feature = "bindings", derive(TS))]
14725pub struct JSONExtractQuote {
14726    #[serde(default)]
14727    pub option: Option<Box<Expression>>,
14728    #[serde(default)]
14729    pub scalar: Option<Box<Expression>>,
14730}
14731
14732/// JSONExtractArray
14733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14734#[cfg_attr(feature = "bindings", derive(TS))]
14735pub struct JSONExtractArray {
14736    pub this: Box<Expression>,
14737    #[serde(default)]
14738    pub expression: Option<Box<Expression>>,
14739}
14740
14741/// JSONExtractScalar
14742#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14743#[cfg_attr(feature = "bindings", derive(TS))]
14744pub struct JSONExtractScalar {
14745    pub this: Box<Expression>,
14746    pub expression: Box<Expression>,
14747    #[serde(default)]
14748    pub only_json_types: Option<Box<Expression>>,
14749    #[serde(default)]
14750    pub expressions: Vec<Expression>,
14751    #[serde(default)]
14752    pub json_type: Option<Box<Expression>>,
14753    #[serde(default)]
14754    pub scalar_only: Option<Box<Expression>>,
14755}
14756
14757/// JSONBExtractScalar
14758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14759#[cfg_attr(feature = "bindings", derive(TS))]
14760pub struct JSONBExtractScalar {
14761    pub this: Box<Expression>,
14762    pub expression: Box<Expression>,
14763    #[serde(default)]
14764    pub json_type: Option<Box<Expression>>,
14765}
14766
14767/// JSONFormat
14768#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14769#[cfg_attr(feature = "bindings", derive(TS))]
14770pub struct JSONFormat {
14771    #[serde(default)]
14772    pub this: Option<Box<Expression>>,
14773    #[serde(default)]
14774    pub options: Vec<Expression>,
14775    #[serde(default)]
14776    pub is_json: Option<Box<Expression>>,
14777    #[serde(default)]
14778    pub to_json: Option<Box<Expression>>,
14779}
14780
14781/// JSONArrayAppend
14782#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14783#[cfg_attr(feature = "bindings", derive(TS))]
14784pub struct JSONArrayAppend {
14785    pub this: Box<Expression>,
14786    #[serde(default)]
14787    pub expressions: Vec<Expression>,
14788}
14789
14790/// JSONArrayContains
14791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14792#[cfg_attr(feature = "bindings", derive(TS))]
14793pub struct JSONArrayContains {
14794    pub this: Box<Expression>,
14795    pub expression: Box<Expression>,
14796    #[serde(default)]
14797    pub json_type: Option<Box<Expression>>,
14798}
14799
14800/// JSONArrayInsert
14801#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14802#[cfg_attr(feature = "bindings", derive(TS))]
14803pub struct JSONArrayInsert {
14804    pub this: Box<Expression>,
14805    #[serde(default)]
14806    pub expressions: Vec<Expression>,
14807}
14808
14809/// ParseJSON
14810#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14811#[cfg_attr(feature = "bindings", derive(TS))]
14812pub struct ParseJSON {
14813    pub this: Box<Expression>,
14814    #[serde(default)]
14815    pub expression: Option<Box<Expression>>,
14816    #[serde(default)]
14817    pub safe: Option<Box<Expression>>,
14818}
14819
14820/// ParseUrl
14821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14822#[cfg_attr(feature = "bindings", derive(TS))]
14823pub struct ParseUrl {
14824    pub this: Box<Expression>,
14825    #[serde(default)]
14826    pub part_to_extract: Option<Box<Expression>>,
14827    #[serde(default)]
14828    pub key: Option<Box<Expression>>,
14829    #[serde(default)]
14830    pub permissive: Option<Box<Expression>>,
14831}
14832
14833/// ParseIp
14834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14835#[cfg_attr(feature = "bindings", derive(TS))]
14836pub struct ParseIp {
14837    pub this: Box<Expression>,
14838    #[serde(default)]
14839    pub type_: Option<Box<Expression>>,
14840    #[serde(default)]
14841    pub permissive: Option<Box<Expression>>,
14842}
14843
14844/// ParseTime
14845#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14846#[cfg_attr(feature = "bindings", derive(TS))]
14847pub struct ParseTime {
14848    pub this: Box<Expression>,
14849    pub format: String,
14850}
14851
14852/// ParseDatetime
14853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14854#[cfg_attr(feature = "bindings", derive(TS))]
14855pub struct ParseDatetime {
14856    pub this: Box<Expression>,
14857    #[serde(default)]
14858    pub format: Option<String>,
14859    #[serde(default)]
14860    pub zone: Option<Box<Expression>>,
14861}
14862
14863/// Map
14864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14865#[cfg_attr(feature = "bindings", derive(TS))]
14866pub struct Map {
14867    #[serde(default)]
14868    pub keys: Vec<Expression>,
14869    #[serde(default)]
14870    pub values: Vec<Expression>,
14871}
14872
14873/// MapCat
14874#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14875#[cfg_attr(feature = "bindings", derive(TS))]
14876pub struct MapCat {
14877    pub this: Box<Expression>,
14878    pub expression: Box<Expression>,
14879}
14880
14881/// MapDelete
14882#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14883#[cfg_attr(feature = "bindings", derive(TS))]
14884pub struct MapDelete {
14885    pub this: Box<Expression>,
14886    #[serde(default)]
14887    pub expressions: Vec<Expression>,
14888}
14889
14890/// MapInsert
14891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14892#[cfg_attr(feature = "bindings", derive(TS))]
14893pub struct MapInsert {
14894    pub this: Box<Expression>,
14895    #[serde(default)]
14896    pub key: Option<Box<Expression>>,
14897    #[serde(default)]
14898    pub value: Option<Box<Expression>>,
14899    #[serde(default)]
14900    pub update_flag: Option<Box<Expression>>,
14901}
14902
14903/// MapPick
14904#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14905#[cfg_attr(feature = "bindings", derive(TS))]
14906pub struct MapPick {
14907    pub this: Box<Expression>,
14908    #[serde(default)]
14909    pub expressions: Vec<Expression>,
14910}
14911
14912/// ScopeResolution
14913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14914#[cfg_attr(feature = "bindings", derive(TS))]
14915pub struct ScopeResolution {
14916    #[serde(default)]
14917    pub this: Option<Box<Expression>>,
14918    pub expression: Box<Expression>,
14919}
14920
14921/// Slice
14922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14923#[cfg_attr(feature = "bindings", derive(TS))]
14924pub struct Slice {
14925    #[serde(default)]
14926    pub this: Option<Box<Expression>>,
14927    #[serde(default)]
14928    pub expression: Option<Box<Expression>>,
14929    #[serde(default)]
14930    pub step: Option<Box<Expression>>,
14931}
14932
14933/// VarMap
14934#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14935#[cfg_attr(feature = "bindings", derive(TS))]
14936pub struct VarMap {
14937    #[serde(default)]
14938    pub keys: Vec<Expression>,
14939    #[serde(default)]
14940    pub values: Vec<Expression>,
14941}
14942
14943/// MatchAgainst
14944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14945#[cfg_attr(feature = "bindings", derive(TS))]
14946pub struct MatchAgainst {
14947    pub this: Box<Expression>,
14948    #[serde(default)]
14949    pub expressions: Vec<Expression>,
14950    #[serde(default)]
14951    pub modifier: Option<Box<Expression>>,
14952}
14953
14954/// MD5Digest
14955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14956#[cfg_attr(feature = "bindings", derive(TS))]
14957pub struct MD5Digest {
14958    pub this: Box<Expression>,
14959    #[serde(default)]
14960    pub expressions: Vec<Expression>,
14961}
14962
14963/// Monthname
14964#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14965#[cfg_attr(feature = "bindings", derive(TS))]
14966pub struct Monthname {
14967    pub this: Box<Expression>,
14968    #[serde(default)]
14969    pub abbreviated: Option<Box<Expression>>,
14970}
14971
14972/// Ntile
14973#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14974#[cfg_attr(feature = "bindings", derive(TS))]
14975pub struct Ntile {
14976    #[serde(default)]
14977    pub this: Option<Box<Expression>>,
14978}
14979
14980/// Normalize
14981#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14982#[cfg_attr(feature = "bindings", derive(TS))]
14983pub struct Normalize {
14984    pub this: Box<Expression>,
14985    #[serde(default)]
14986    pub form: Option<Box<Expression>>,
14987    #[serde(default)]
14988    pub is_casefold: Option<Box<Expression>>,
14989}
14990
14991/// Normal
14992#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14993#[cfg_attr(feature = "bindings", derive(TS))]
14994pub struct Normal {
14995    pub this: Box<Expression>,
14996    #[serde(default)]
14997    pub stddev: Option<Box<Expression>>,
14998    #[serde(default)]
14999    pub gen: Option<Box<Expression>>,
15000}
15001
15002/// Predict
15003#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15004#[cfg_attr(feature = "bindings", derive(TS))]
15005pub struct Predict {
15006    pub this: Box<Expression>,
15007    pub expression: Box<Expression>,
15008    #[serde(default)]
15009    pub params_struct: Option<Box<Expression>>,
15010}
15011
15012/// MLTranslate
15013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15014#[cfg_attr(feature = "bindings", derive(TS))]
15015pub struct MLTranslate {
15016    pub this: Box<Expression>,
15017    pub expression: Box<Expression>,
15018    #[serde(default)]
15019    pub params_struct: Option<Box<Expression>>,
15020}
15021
15022/// FeaturesAtTime
15023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15024#[cfg_attr(feature = "bindings", derive(TS))]
15025pub struct FeaturesAtTime {
15026    pub this: Box<Expression>,
15027    #[serde(default)]
15028    pub time: Option<Box<Expression>>,
15029    #[serde(default)]
15030    pub num_rows: Option<Box<Expression>>,
15031    #[serde(default)]
15032    pub ignore_feature_nulls: Option<Box<Expression>>,
15033}
15034
15035/// GenerateEmbedding
15036#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15037#[cfg_attr(feature = "bindings", derive(TS))]
15038pub struct GenerateEmbedding {
15039    pub this: Box<Expression>,
15040    pub expression: Box<Expression>,
15041    #[serde(default)]
15042    pub params_struct: Option<Box<Expression>>,
15043    #[serde(default)]
15044    pub is_text: Option<Box<Expression>>,
15045}
15046
15047/// MLForecast
15048#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15049#[cfg_attr(feature = "bindings", derive(TS))]
15050pub struct MLForecast {
15051    pub this: Box<Expression>,
15052    #[serde(default)]
15053    pub expression: Option<Box<Expression>>,
15054    #[serde(default)]
15055    pub params_struct: Option<Box<Expression>>,
15056}
15057
15058/// ModelAttribute
15059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15060#[cfg_attr(feature = "bindings", derive(TS))]
15061pub struct ModelAttribute {
15062    pub this: Box<Expression>,
15063    pub expression: Box<Expression>,
15064}
15065
15066/// VectorSearch
15067#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15068#[cfg_attr(feature = "bindings", derive(TS))]
15069pub struct VectorSearch {
15070    pub this: Box<Expression>,
15071    #[serde(default)]
15072    pub column_to_search: Option<Box<Expression>>,
15073    #[serde(default)]
15074    pub query_table: Option<Box<Expression>>,
15075    #[serde(default)]
15076    pub query_column_to_search: Option<Box<Expression>>,
15077    #[serde(default)]
15078    pub top_k: Option<Box<Expression>>,
15079    #[serde(default)]
15080    pub distance_type: Option<Box<Expression>>,
15081    #[serde(default)]
15082    pub options: Vec<Expression>,
15083}
15084
15085/// Quantile
15086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15087#[cfg_attr(feature = "bindings", derive(TS))]
15088pub struct Quantile {
15089    pub this: Box<Expression>,
15090    #[serde(default)]
15091    pub quantile: Option<Box<Expression>>,
15092}
15093
15094/// ApproxQuantile
15095#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15096#[cfg_attr(feature = "bindings", derive(TS))]
15097pub struct ApproxQuantile {
15098    pub this: Box<Expression>,
15099    #[serde(default)]
15100    pub quantile: Option<Box<Expression>>,
15101    #[serde(default)]
15102    pub accuracy: Option<Box<Expression>>,
15103    #[serde(default)]
15104    pub weight: Option<Box<Expression>>,
15105    #[serde(default)]
15106    pub error_tolerance: Option<Box<Expression>>,
15107}
15108
15109/// ApproxPercentileEstimate
15110#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15111#[cfg_attr(feature = "bindings", derive(TS))]
15112pub struct ApproxPercentileEstimate {
15113    pub this: Box<Expression>,
15114    #[serde(default)]
15115    pub percentile: Option<Box<Expression>>,
15116}
15117
15118/// Randn
15119#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15120#[cfg_attr(feature = "bindings", derive(TS))]
15121pub struct Randn {
15122    #[serde(default)]
15123    pub this: Option<Box<Expression>>,
15124}
15125
15126/// Randstr
15127#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15128#[cfg_attr(feature = "bindings", derive(TS))]
15129pub struct Randstr {
15130    pub this: Box<Expression>,
15131    #[serde(default)]
15132    pub generator: Option<Box<Expression>>,
15133}
15134
15135/// RangeN
15136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15137#[cfg_attr(feature = "bindings", derive(TS))]
15138pub struct RangeN {
15139    pub this: Box<Expression>,
15140    #[serde(default)]
15141    pub expressions: Vec<Expression>,
15142    #[serde(default)]
15143    pub each: Option<Box<Expression>>,
15144}
15145
15146/// RangeBucket
15147#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15148#[cfg_attr(feature = "bindings", derive(TS))]
15149pub struct RangeBucket {
15150    pub this: Box<Expression>,
15151    pub expression: Box<Expression>,
15152}
15153
15154/// ReadCSV
15155#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15156#[cfg_attr(feature = "bindings", derive(TS))]
15157pub struct ReadCSV {
15158    pub this: Box<Expression>,
15159    #[serde(default)]
15160    pub expressions: Vec<Expression>,
15161}
15162
15163/// ReadParquet
15164#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15165#[cfg_attr(feature = "bindings", derive(TS))]
15166pub struct ReadParquet {
15167    #[serde(default)]
15168    pub expressions: Vec<Expression>,
15169}
15170
15171/// Reduce
15172#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15173#[cfg_attr(feature = "bindings", derive(TS))]
15174pub struct Reduce {
15175    pub this: Box<Expression>,
15176    #[serde(default)]
15177    pub initial: Option<Box<Expression>>,
15178    #[serde(default)]
15179    pub merge: Option<Box<Expression>>,
15180    #[serde(default)]
15181    pub finish: Option<Box<Expression>>,
15182}
15183
15184/// RegexpExtractAll
15185#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15186#[cfg_attr(feature = "bindings", derive(TS))]
15187pub struct RegexpExtractAll {
15188    pub this: Box<Expression>,
15189    pub expression: Box<Expression>,
15190    #[serde(default)]
15191    pub group: Option<Box<Expression>>,
15192    #[serde(default)]
15193    pub parameters: Option<Box<Expression>>,
15194    #[serde(default)]
15195    pub position: Option<Box<Expression>>,
15196    #[serde(default)]
15197    pub occurrence: Option<Box<Expression>>,
15198}
15199
15200/// RegexpILike
15201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15202#[cfg_attr(feature = "bindings", derive(TS))]
15203pub struct RegexpILike {
15204    pub this: Box<Expression>,
15205    pub expression: Box<Expression>,
15206    #[serde(default)]
15207    pub flag: Option<Box<Expression>>,
15208}
15209
15210/// RegexpFullMatch
15211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15212#[cfg_attr(feature = "bindings", derive(TS))]
15213pub struct RegexpFullMatch {
15214    pub this: Box<Expression>,
15215    pub expression: Box<Expression>,
15216    #[serde(default)]
15217    pub options: Vec<Expression>,
15218}
15219
15220/// RegexpInstr
15221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15222#[cfg_attr(feature = "bindings", derive(TS))]
15223pub struct RegexpInstr {
15224    /// Additional search boundaries and retained source semantics.
15225    #[serde(default, skip_serializing_if = "Option::is_none")]
15226    pub options: Option<RegexOptions>,
15227    pub this: Box<Expression>,
15228    pub expression: Box<Expression>,
15229    #[serde(default)]
15230    pub position: Option<Box<Expression>>,
15231    #[serde(default)]
15232    pub occurrence: Option<Box<Expression>>,
15233    #[serde(default)]
15234    pub option: Option<Box<Expression>>,
15235    #[serde(default)]
15236    pub parameters: Option<Box<Expression>>,
15237    #[serde(default)]
15238    pub group: Option<Box<Expression>>,
15239}
15240
15241/// RegexpSplit
15242#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15243#[cfg_attr(feature = "bindings", derive(TS))]
15244pub struct RegexpSplit {
15245    pub this: Box<Expression>,
15246    pub expression: Box<Expression>,
15247    #[serde(default)]
15248    pub limit: Option<Box<Expression>>,
15249}
15250
15251/// RegexpCount
15252#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15253#[cfg_attr(feature = "bindings", derive(TS))]
15254pub struct RegexpCount {
15255    /// Additional search boundaries and retained source semantics.
15256    #[serde(default, skip_serializing_if = "Option::is_none")]
15257    pub options: Option<RegexOptions>,
15258    pub this: Box<Expression>,
15259    pub expression: Box<Expression>,
15260    #[serde(default)]
15261    pub position: Option<Box<Expression>>,
15262    #[serde(default)]
15263    pub parameters: Option<Box<Expression>>,
15264}
15265
15266/// RegrValx
15267#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15268#[cfg_attr(feature = "bindings", derive(TS))]
15269pub struct RegrValx {
15270    pub this: Box<Expression>,
15271    pub expression: Box<Expression>,
15272}
15273
15274/// RegrValy
15275#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15276#[cfg_attr(feature = "bindings", derive(TS))]
15277pub struct RegrValy {
15278    pub this: Box<Expression>,
15279    pub expression: Box<Expression>,
15280}
15281
15282/// RegrAvgy
15283#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15284#[cfg_attr(feature = "bindings", derive(TS))]
15285pub struct RegrAvgy {
15286    pub this: Box<Expression>,
15287    pub expression: Box<Expression>,
15288}
15289
15290/// RegrAvgx
15291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15292#[cfg_attr(feature = "bindings", derive(TS))]
15293pub struct RegrAvgx {
15294    pub this: Box<Expression>,
15295    pub expression: Box<Expression>,
15296}
15297
15298/// RegrCount
15299#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15300#[cfg_attr(feature = "bindings", derive(TS))]
15301pub struct RegrCount {
15302    pub this: Box<Expression>,
15303    pub expression: Box<Expression>,
15304}
15305
15306/// RegrIntercept
15307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15308#[cfg_attr(feature = "bindings", derive(TS))]
15309pub struct RegrIntercept {
15310    pub this: Box<Expression>,
15311    pub expression: Box<Expression>,
15312}
15313
15314/// RegrR2
15315#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15316#[cfg_attr(feature = "bindings", derive(TS))]
15317pub struct RegrR2 {
15318    pub this: Box<Expression>,
15319    pub expression: Box<Expression>,
15320}
15321
15322/// RegrSxx
15323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15324#[cfg_attr(feature = "bindings", derive(TS))]
15325pub struct RegrSxx {
15326    pub this: Box<Expression>,
15327    pub expression: Box<Expression>,
15328}
15329
15330/// RegrSxy
15331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15332#[cfg_attr(feature = "bindings", derive(TS))]
15333pub struct RegrSxy {
15334    pub this: Box<Expression>,
15335    pub expression: Box<Expression>,
15336}
15337
15338/// RegrSyy
15339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15340#[cfg_attr(feature = "bindings", derive(TS))]
15341pub struct RegrSyy {
15342    pub this: Box<Expression>,
15343    pub expression: Box<Expression>,
15344}
15345
15346/// RegrSlope
15347#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15348#[cfg_attr(feature = "bindings", derive(TS))]
15349pub struct RegrSlope {
15350    pub this: Box<Expression>,
15351    pub expression: Box<Expression>,
15352}
15353
15354/// SafeAdd
15355#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15356#[cfg_attr(feature = "bindings", derive(TS))]
15357pub struct SafeAdd {
15358    pub this: Box<Expression>,
15359    pub expression: Box<Expression>,
15360}
15361
15362/// SafeDivide
15363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15364#[cfg_attr(feature = "bindings", derive(TS))]
15365pub struct SafeDivide {
15366    pub this: Box<Expression>,
15367    pub expression: Box<Expression>,
15368}
15369
15370/// SafeMultiply
15371#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15372#[cfg_attr(feature = "bindings", derive(TS))]
15373pub struct SafeMultiply {
15374    pub this: Box<Expression>,
15375    pub expression: Box<Expression>,
15376}
15377
15378/// SafeSubtract
15379#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15380#[cfg_attr(feature = "bindings", derive(TS))]
15381pub struct SafeSubtract {
15382    pub this: Box<Expression>,
15383    pub expression: Box<Expression>,
15384}
15385
15386/// SHA2
15387#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15388#[cfg_attr(feature = "bindings", derive(TS))]
15389pub struct SHA2 {
15390    pub this: Box<Expression>,
15391    #[serde(default)]
15392    pub length: Option<i64>,
15393}
15394
15395/// SHA2Digest
15396#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15397#[cfg_attr(feature = "bindings", derive(TS))]
15398pub struct SHA2Digest {
15399    pub this: Box<Expression>,
15400    #[serde(default)]
15401    pub length: Option<i64>,
15402}
15403
15404/// SortArray
15405#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15406#[cfg_attr(feature = "bindings", derive(TS))]
15407pub struct SortArray {
15408    pub this: Box<Expression>,
15409    #[serde(default)]
15410    pub asc: Option<Box<Expression>>,
15411    #[serde(default)]
15412    pub nulls_first: Option<Box<Expression>>,
15413}
15414
15415/// SplitPart
15416#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15417#[cfg_attr(feature = "bindings", derive(TS))]
15418pub struct SplitPart {
15419    pub this: Box<Expression>,
15420    #[serde(default)]
15421    pub delimiter: Option<Box<Expression>>,
15422    #[serde(default)]
15423    pub part_index: Option<Box<Expression>>,
15424}
15425
15426/// SUBSTRING_INDEX(str, delim, count)
15427#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15428#[cfg_attr(feature = "bindings", derive(TS))]
15429pub struct SubstringIndex {
15430    pub this: Box<Expression>,
15431    #[serde(default)]
15432    pub delimiter: Option<Box<Expression>>,
15433    #[serde(default)]
15434    pub count: Option<Box<Expression>>,
15435}
15436
15437/// StandardHash
15438#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15439#[cfg_attr(feature = "bindings", derive(TS))]
15440pub struct StandardHash {
15441    pub this: Box<Expression>,
15442    #[serde(default)]
15443    pub expression: Option<Box<Expression>>,
15444}
15445
15446/// StrPosition
15447#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15448#[cfg_attr(feature = "bindings", derive(TS))]
15449pub struct StrPosition {
15450    pub this: Box<Expression>,
15451    #[serde(default)]
15452    pub substr: Option<Box<Expression>>,
15453    #[serde(default)]
15454    pub position: Option<Box<Expression>>,
15455    #[serde(default)]
15456    pub occurrence: Option<Box<Expression>>,
15457}
15458
15459/// Search
15460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15461#[cfg_attr(feature = "bindings", derive(TS))]
15462pub struct Search {
15463    pub this: Box<Expression>,
15464    pub expression: Box<Expression>,
15465    #[serde(default)]
15466    pub json_scope: Option<Box<Expression>>,
15467    #[serde(default)]
15468    pub analyzer: Option<Box<Expression>>,
15469    #[serde(default)]
15470    pub analyzer_options: Option<Box<Expression>>,
15471    #[serde(default)]
15472    pub search_mode: Option<Box<Expression>>,
15473}
15474
15475/// SearchIp
15476#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15477#[cfg_attr(feature = "bindings", derive(TS))]
15478pub struct SearchIp {
15479    pub this: Box<Expression>,
15480    pub expression: Box<Expression>,
15481}
15482
15483/// StrToDate
15484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15485#[cfg_attr(feature = "bindings", derive(TS))]
15486pub struct StrToDate {
15487    pub this: Box<Expression>,
15488    #[serde(default)]
15489    pub format: Option<String>,
15490    #[serde(default)]
15491    pub safe: Option<Box<Expression>>,
15492}
15493
15494/// StrToTime
15495#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15496#[cfg_attr(feature = "bindings", derive(TS))]
15497pub struct StrToTime {
15498    pub this: Box<Expression>,
15499    pub format: String,
15500    #[serde(default)]
15501    pub zone: Option<Box<Expression>>,
15502    #[serde(default)]
15503    pub safe: Option<Box<Expression>>,
15504    #[serde(default)]
15505    pub target_type: Option<Box<Expression>>,
15506}
15507
15508/// StrToUnix
15509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15510#[cfg_attr(feature = "bindings", derive(TS))]
15511pub struct StrToUnix {
15512    #[serde(default)]
15513    pub this: Option<Box<Expression>>,
15514    #[serde(default)]
15515    pub format: Option<String>,
15516}
15517
15518/// StrToMap
15519#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15520#[cfg_attr(feature = "bindings", derive(TS))]
15521pub struct StrToMap {
15522    pub this: Box<Expression>,
15523    #[serde(default)]
15524    pub pair_delim: Option<Box<Expression>>,
15525    #[serde(default)]
15526    pub key_value_delim: Option<Box<Expression>>,
15527    #[serde(default)]
15528    pub duplicate_resolution_callback: Option<Box<Expression>>,
15529}
15530
15531/// NumberToStr
15532#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15533#[cfg_attr(feature = "bindings", derive(TS))]
15534pub struct NumberToStr {
15535    pub this: Box<Expression>,
15536    pub format: String,
15537    #[serde(default)]
15538    pub culture: Option<Box<Expression>>,
15539}
15540
15541/// FromBase
15542#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15543#[cfg_attr(feature = "bindings", derive(TS))]
15544pub struct FromBase {
15545    pub this: Box<Expression>,
15546    pub expression: Box<Expression>,
15547}
15548
15549/// Stuff
15550#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15551#[cfg_attr(feature = "bindings", derive(TS))]
15552pub struct Stuff {
15553    pub this: Box<Expression>,
15554    #[serde(default)]
15555    pub start: Option<Box<Expression>>,
15556    #[serde(default)]
15557    pub length: Option<i64>,
15558    pub expression: Box<Expression>,
15559}
15560
15561/// TimeToStr
15562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15563#[cfg_attr(feature = "bindings", derive(TS))]
15564pub struct TimeToStr {
15565    pub this: Box<Expression>,
15566    pub format: String,
15567    #[serde(default)]
15568    pub culture: Option<Box<Expression>>,
15569    #[serde(default)]
15570    pub zone: Option<Box<Expression>>,
15571}
15572
15573/// TimeStrToTime
15574#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15575#[cfg_attr(feature = "bindings", derive(TS))]
15576pub struct TimeStrToTime {
15577    pub this: Box<Expression>,
15578    #[serde(default)]
15579    pub zone: Option<Box<Expression>>,
15580}
15581
15582/// TsOrDsAdd
15583#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15584#[cfg_attr(feature = "bindings", derive(TS))]
15585pub struct TsOrDsAdd {
15586    pub this: Box<Expression>,
15587    pub expression: Box<Expression>,
15588    #[serde(default)]
15589    pub unit: Option<String>,
15590    #[serde(default)]
15591    pub return_type: Option<Box<Expression>>,
15592}
15593
15594/// TsOrDsDiff
15595#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15596#[cfg_attr(feature = "bindings", derive(TS))]
15597pub struct TsOrDsDiff {
15598    pub this: Box<Expression>,
15599    pub expression: Box<Expression>,
15600    #[serde(default)]
15601    pub unit: Option<String>,
15602}
15603
15604/// TsOrDsToDate
15605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15606#[cfg_attr(feature = "bindings", derive(TS))]
15607pub struct TsOrDsToDate {
15608    pub this: Box<Expression>,
15609    #[serde(default)]
15610    pub format: Option<String>,
15611    #[serde(default)]
15612    pub safe: Option<Box<Expression>>,
15613}
15614
15615/// TsOrDsToTime
15616#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15617#[cfg_attr(feature = "bindings", derive(TS))]
15618pub struct TsOrDsToTime {
15619    pub this: Box<Expression>,
15620    #[serde(default)]
15621    pub format: Option<String>,
15622    #[serde(default)]
15623    pub safe: Option<Box<Expression>>,
15624}
15625
15626/// Unhex
15627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15628#[cfg_attr(feature = "bindings", derive(TS))]
15629pub struct Unhex {
15630    pub this: Box<Expression>,
15631    #[serde(default)]
15632    pub expression: Option<Box<Expression>>,
15633}
15634
15635/// Uniform
15636#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15637#[cfg_attr(feature = "bindings", derive(TS))]
15638pub struct Uniform {
15639    pub this: Box<Expression>,
15640    pub expression: Box<Expression>,
15641    #[serde(default)]
15642    pub gen: Option<Box<Expression>>,
15643    #[serde(default)]
15644    pub seed: Option<Box<Expression>>,
15645}
15646
15647/// UnixToStr
15648#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15649#[cfg_attr(feature = "bindings", derive(TS))]
15650pub struct UnixToStr {
15651    pub this: Box<Expression>,
15652    #[serde(default)]
15653    pub format: Option<String>,
15654}
15655
15656/// UnixToTime
15657#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15658#[cfg_attr(feature = "bindings", derive(TS))]
15659pub struct UnixToTime {
15660    pub this: Box<Expression>,
15661    #[serde(default)]
15662    pub scale: Option<i64>,
15663    #[serde(default)]
15664    pub zone: Option<Box<Expression>>,
15665    #[serde(default)]
15666    pub hours: Option<Box<Expression>>,
15667    #[serde(default)]
15668    pub minutes: Option<Box<Expression>>,
15669    #[serde(default)]
15670    pub format: Option<String>,
15671    #[serde(default)]
15672    pub target_type: Option<Box<Expression>>,
15673}
15674
15675/// Uuid
15676#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15677#[cfg_attr(feature = "bindings", derive(TS))]
15678pub struct Uuid {
15679    #[serde(default)]
15680    pub this: Option<Box<Expression>>,
15681    #[serde(default)]
15682    pub name: Option<String>,
15683    #[serde(default)]
15684    pub is_string: Option<Box<Expression>>,
15685}
15686
15687/// TimestampFromParts
15688#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15689#[cfg_attr(feature = "bindings", derive(TS))]
15690pub struct TimestampFromParts {
15691    #[serde(default)]
15692    pub zone: Option<Box<Expression>>,
15693    #[serde(default)]
15694    pub milli: Option<Box<Expression>>,
15695    #[serde(default)]
15696    pub this: Option<Box<Expression>>,
15697    #[serde(default)]
15698    pub expression: Option<Box<Expression>>,
15699}
15700
15701/// TimestampTzFromParts
15702#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15703#[cfg_attr(feature = "bindings", derive(TS))]
15704pub struct TimestampTzFromParts {
15705    #[serde(default)]
15706    pub zone: Option<Box<Expression>>,
15707}
15708
15709/// Corr
15710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15711#[cfg_attr(feature = "bindings", derive(TS))]
15712pub struct Corr {
15713    pub this: Box<Expression>,
15714    pub expression: Box<Expression>,
15715    #[serde(default)]
15716    pub null_on_zero_variance: Option<Box<Expression>>,
15717}
15718
15719/// WidthBucket
15720#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15721#[cfg_attr(feature = "bindings", derive(TS))]
15722pub struct WidthBucket {
15723    pub this: Box<Expression>,
15724    #[serde(default)]
15725    pub min_value: Option<Box<Expression>>,
15726    #[serde(default)]
15727    pub max_value: Option<Box<Expression>>,
15728    #[serde(default)]
15729    pub num_buckets: Option<Box<Expression>>,
15730    #[serde(default)]
15731    pub threshold: Option<Box<Expression>>,
15732}
15733
15734/// CovarSamp
15735#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15736#[cfg_attr(feature = "bindings", derive(TS))]
15737pub struct CovarSamp {
15738    pub this: Box<Expression>,
15739    pub expression: Box<Expression>,
15740}
15741
15742/// CovarPop
15743#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15744#[cfg_attr(feature = "bindings", derive(TS))]
15745pub struct CovarPop {
15746    pub this: Box<Expression>,
15747    pub expression: Box<Expression>,
15748}
15749
15750/// Week
15751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15752#[cfg_attr(feature = "bindings", derive(TS))]
15753pub struct Week {
15754    pub this: Box<Expression>,
15755    #[serde(default)]
15756    pub mode: Option<Box<Expression>>,
15757}
15758
15759/// XMLElement
15760#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15761#[cfg_attr(feature = "bindings", derive(TS))]
15762pub struct XMLElement {
15763    pub this: Box<Expression>,
15764    #[serde(default)]
15765    pub expressions: Vec<Expression>,
15766    #[serde(default)]
15767    pub evalname: Option<Box<Expression>>,
15768}
15769
15770/// XMLGet
15771#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15772#[cfg_attr(feature = "bindings", derive(TS))]
15773pub struct XMLGet {
15774    pub this: Box<Expression>,
15775    pub expression: Box<Expression>,
15776    #[serde(default)]
15777    pub instance: Option<Box<Expression>>,
15778}
15779
15780/// XMLTable
15781#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15782#[cfg_attr(feature = "bindings", derive(TS))]
15783pub struct XMLTable {
15784    pub this: Box<Expression>,
15785    #[serde(default)]
15786    pub namespaces: Option<Box<Expression>>,
15787    #[serde(default)]
15788    pub passing: Option<Box<Expression>>,
15789    #[serde(default)]
15790    pub columns: Vec<Expression>,
15791    #[serde(default)]
15792    pub by_ref: Option<Box<Expression>>,
15793}
15794
15795/// XMLKeyValueOption
15796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15797#[cfg_attr(feature = "bindings", derive(TS))]
15798pub struct XMLKeyValueOption {
15799    pub this: Box<Expression>,
15800    #[serde(default)]
15801    pub expression: Option<Box<Expression>>,
15802}
15803
15804/// Zipf
15805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15806#[cfg_attr(feature = "bindings", derive(TS))]
15807pub struct Zipf {
15808    pub this: Box<Expression>,
15809    #[serde(default)]
15810    pub elementcount: Option<Box<Expression>>,
15811    #[serde(default)]
15812    pub gen: Option<Box<Expression>>,
15813}
15814
15815/// Merge
15816#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15817#[cfg_attr(feature = "bindings", derive(TS))]
15818pub struct Merge {
15819    pub this: Box<Expression>,
15820    pub using: Box<Expression>,
15821    #[serde(default)]
15822    pub on: Option<Box<Expression>>,
15823    #[serde(default)]
15824    pub using_cond: Option<Box<Expression>>,
15825    #[serde(default)]
15826    pub whens: Option<Box<Expression>>,
15827    #[serde(default)]
15828    pub with_: Option<Box<Expression>>,
15829    #[serde(default)]
15830    pub returning: Option<Box<Expression>>,
15831}
15832
15833/// When
15834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15835#[cfg_attr(feature = "bindings", derive(TS))]
15836pub struct When {
15837    #[serde(default)]
15838    pub matched: Option<Box<Expression>>,
15839    #[serde(default)]
15840    pub source: Option<Box<Expression>>,
15841    #[serde(default)]
15842    pub condition: Option<Box<Expression>>,
15843    pub then: Box<Expression>,
15844}
15845
15846/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15848#[cfg_attr(feature = "bindings", derive(TS))]
15849pub struct Whens {
15850    #[serde(default)]
15851    pub expressions: Vec<Expression>,
15852}
15853
15854/// NextValueFor
15855#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15856#[cfg_attr(feature = "bindings", derive(TS))]
15857pub struct NextValueFor {
15858    pub this: Box<Expression>,
15859    #[serde(default)]
15860    pub order: Option<Box<Expression>>,
15861}
15862
15863// Vertica dialect support.
15864/// Native Vertica syntax, retaining semantics through serialization and traversal.
15865#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15866#[cfg_attr(feature = "bindings", derive(TS))]
15867#[serde(tag = "kind", rename_all = "snake_case")]
15868pub enum VerticaExpression {
15869    PhysicalTable {
15870        this: Expression,
15871        physical: VerticaPhysical,
15872    },
15873    FlexTable {
15874        this: Expression,
15875        physical: VerticaPhysical,
15876    },
15877    Projection {
15878        name: TableRef,
15879        columns: Vec<VerticaProjectionColumn>,
15880        query: Expression,
15881        physical: VerticaPhysical,
15882    },
15883    Copy {
15884        table: TableRef,
15885        columns: Vec<Identifier>,
15886        local: bool,
15887        sources: Vec<Expression>,
15888        parser: Option<VerticaParserCall>,
15889        options: Vec<VerticaParameter>,
15890    },
15891    ExportParquet {
15892        options: Vec<VerticaParameter>,
15893        over: Option<Over>,
15894        query: Expression,
15895    },
15896    Interpolate {
15897        left: Expression,
15898        right: Expression,
15899        previous: bool,
15900    },
15901    /// Zero-based array access retains source bounds semantics from parsing.
15902    ArrayAccess {
15903        this: Expression,
15904        indices: Vec<Expression>,
15905    },
15906    ArraySlice {
15907        this: Expression,
15908        start: Option<Expression>,
15909        end: Option<Expression>,
15910    },
15911    BoundaryDateDiff {
15912        start: Expression,
15913        end: Expression,
15914        unit: IntervalUnit,
15915    },
15916    UsingParameters {
15917        this: Expression,
15918        parameters: Vec<VerticaParameter>,
15919    },
15920    SafeCast {
15921        this: Expression,
15922        to: DataType,
15923    },
15924    Set {
15925        values: Vec<Expression>,
15926    },
15927    Interval {
15928        value: Expression,
15929        precision: Option<u32>,
15930        year_month: bool,
15931        unit: Option<String>,
15932        end_unit: Option<String>,
15933    },
15934    /// Hexadecimal byte value, distinct from PostgreSQL's bit strings.
15935    Binary {
15936        hex: String,
15937    },
15938    Historical {
15939        query: Expression,
15940        point: VerticaHistoricalPoint,
15941    },
15942    PartitionBest,
15943}
15944
15945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15946#[cfg_attr(feature = "bindings", derive(TS))]
15947pub struct VerticaParameter {
15948    pub name: Identifier,
15949    pub value: Expression,
15950}
15951
15952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15953#[cfg_attr(feature = "bindings", derive(TS))]
15954#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
15955pub enum VerticaHistoricalPoint {
15956    Latest,
15957    Epoch(Expression),
15958    Time(Expression),
15959}
15960
15961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15962#[cfg_attr(feature = "bindings", derive(TS))]
15963#[serde(tag = "kind", rename_all = "snake_case")]
15964pub enum VerticaDataType {
15965    Array {
15966        element_type: DataType,
15967        bound: Option<VerticaCollectionBound>,
15968    },
15969    Set {
15970        element_type: DataType,
15971        bound: Option<VerticaCollectionBound>,
15972    },
15973    Row {
15974        fields: Vec<StructField>,
15975    },
15976    LongVarBinary {
15977        length: Option<u32>,
15978    },
15979    Interval {
15980        precision: Option<u32>,
15981        year_month: bool,
15982        unit: Option<String>,
15983        end_unit: Option<String>,
15984    },
15985}
15986
15987#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15988#[cfg_attr(feature = "bindings", derive(TS))]
15989#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
15990pub enum VerticaCollectionBound {
15991    Elements(u32),
15992    Bytes(u32),
15993}
15994
15995#[derive(
15996    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
15997)]
15998#[cfg_attr(feature = "bindings", derive(TS))]
15999pub struct VerticaSelectExtensions {
16000    pub timeseries: Option<VerticaTimeseries>,
16001    pub match_clause: Option<VerticaMatch>,
16002    pub limit_over: Option<Over>,
16003}
16004
16005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16006#[cfg_attr(feature = "bindings", derive(TS))]
16007pub struct VerticaTimeseries {
16008    pub alias: Identifier,
16009    pub interval: Expression,
16010    pub over: Over,
16011}
16012
16013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16014#[cfg_attr(feature = "bindings", derive(TS))]
16015pub struct VerticaMatch {
16016    pub partition_by: Vec<Expression>,
16017    pub order_by: Vec<Ordered>,
16018    pub definitions: Vec<VerticaParameter>,
16019    pub name: Identifier,
16020    pub pattern: VerticaPattern,
16021    /// None = default; true = FIRST EVENT; false = ALL EVENTS.
16022    pub first_event: Option<bool>,
16023}
16024
16025#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16026#[cfg_attr(feature = "bindings", derive(TS))]
16027#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
16028pub enum VerticaPattern {
16029    Event(Identifier),
16030    Sequence(Vec<VerticaPattern>),
16031    Alternative(Vec<VerticaPattern>),
16032    Group(Box<VerticaPattern>),
16033    Repeat {
16034        pattern: Box<VerticaPattern>,
16035        quantifier: String,
16036    },
16037}
16038
16039#[derive(
16040    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
16041)]
16042#[cfg_attr(feature = "bindings", derive(TS))]
16043pub struct VerticaPhysical {
16044    pub order_by: Vec<Ordered>,
16045    pub segmentation: Option<VerticaSegmentation>,
16046    pub ksafe: Option<VerticaKsafe>,
16047}
16048
16049#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16050#[cfg_attr(feature = "bindings", derive(TS))]
16051#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
16052pub enum VerticaKsafe {
16053    Default,
16054    Level(u32),
16055}
16056
16057#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16058#[cfg_attr(feature = "bindings", derive(TS))]
16059#[serde(tag = "kind", rename_all = "snake_case")]
16060pub enum VerticaSegmentation {
16061    Segmented {
16062        expression: Expression,
16063        offset: Option<u32>,
16064    },
16065    Unsegmented {
16066        node: Option<Identifier>,
16067    },
16068}
16069
16070#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16071#[cfg_attr(feature = "bindings", derive(TS))]
16072pub struct VerticaProjectionColumn {
16073    pub name: Identifier,
16074    pub encoding: Option<Identifier>,
16075}
16076
16077#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16078#[cfg_attr(feature = "bindings", derive(TS))]
16079pub struct VerticaParserCall {
16080    pub name: TableRef,
16081    pub parameters: Vec<VerticaParameter>,
16082}
16083
16084#[cfg(test)]
16085mod tests {
16086    use super::*;
16087
16088    #[test]
16089    fn test_source_spans_are_metadata_not_expression_identity() {
16090        let plain = Expression::column("customer_id");
16091        let mut positioned = plain.clone();
16092        if let Expression::Column(column) = &mut positioned {
16093            column.span = Some(Span::new(7, 18, 1, 19));
16094            column.name.span = column.span;
16095        }
16096        assert_eq!(plain, positioned);
16097        assert_ne!(
16098            serde_json::to_value(&plain).unwrap(),
16099            serde_json::to_value(&positioned).unwrap()
16100        );
16101        assert_eq!(
16102            Identifier::new("a"),
16103            Identifier::new("a").with_span(Span::new(3, 4, 1, 5))
16104        );
16105        assert_ne!(Identifier::new("a"), Identifier::quoted("a"));
16106        assert_ne!(plain, Expression::column("other"));
16107        let Expression::Column(column) = plain else {
16108            unreachable!()
16109        };
16110        assert!(column.span.is_none() && column.name.span.is_none());
16111    }
16112
16113    #[test]
16114    #[cfg(feature = "bindings")]
16115    fn export_typescript_types() {
16116        // This test exports TypeScript types to the generated directory
16117        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
16118        Expression::export_all(&ts_rs::Config::default())
16119            .expect("Failed to export Expression types");
16120
16121        let mut variant_names = String::from(
16122            "// This file was generated from the Rust Expression enum. Do not edit it manually.\n\n",
16123        );
16124        variant_names.push_str("export const EXPRESSION_VARIANT_NAMES = [\n");
16125        for name in Expression::SERIALIZED_VARIANT_NAMES {
16126            use std::fmt::Write;
16127            writeln!(variant_names, "  {name:?},").expect("writing to a String cannot fail");
16128        }
16129        variant_names.push_str("] as const;\n");
16130
16131        let output_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
16132            .join("bindings/ExpressionVariantNames.ts");
16133        std::fs::write(output_path, variant_names)
16134            .expect("Failed to export serialized Expression variant names");
16135    }
16136
16137    #[test]
16138    fn test_simple_select_builder() {
16139        let select = Select::new()
16140            .column(Expression::star())
16141            .from(Expression::Table(Box::new(TableRef::new("users"))));
16142
16143        assert_eq!(select.expressions.len(), 1);
16144        assert!(select.from.is_some());
16145    }
16146
16147    #[test]
16148    fn test_expression_alias() {
16149        let expr = Expression::column("id").alias("user_id");
16150
16151        match expr {
16152            Expression::Alias(a) => {
16153                assert_eq!(a.alias.name, "user_id");
16154            }
16155            _ => panic!("Expected Alias"),
16156        }
16157    }
16158
16159    #[test]
16160    fn test_literal_creation() {
16161        let num = Expression::number(42);
16162        let str = Expression::string("hello");
16163
16164        match num {
16165            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
16166                let Literal::Number(n) = lit.as_ref() else {
16167                    unreachable!()
16168                };
16169                assert_eq!(n, "42")
16170            }
16171            _ => panic!("Expected Number"),
16172        }
16173
16174        match str {
16175            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
16176                let Literal::String(s) = lit.as_ref() else {
16177                    unreachable!()
16178                };
16179                assert_eq!(s, "hello")
16180            }
16181            _ => panic!("Expected String"),
16182        }
16183    }
16184
16185    #[test]
16186    fn test_expression_sql() {
16187        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
16188        assert_eq!(expr.sql(), "SELECT 1 + 2");
16189    }
16190
16191    #[test]
16192    fn test_expression_sql_for() {
16193        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
16194        let sql = expr.sql_for(crate::DialectType::Generic);
16195        // Generic mode normalizes IF() to CASE WHEN
16196        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
16197    }
16198}