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    /// LIMIT applied to entire UNION result
3939    pub limit: Option<Box<Expression>>,
3940    /// OFFSET applied to entire UNION result
3941    pub offset: Option<Box<Expression>>,
3942    /// DISTRIBUTE BY clause (Hive/Spark)
3943    #[serde(default, skip_serializing_if = "Option::is_none")]
3944    pub distribute_by: Option<DistributeBy>,
3945    /// SORT BY clause (Hive/Spark)
3946    #[serde(default, skip_serializing_if = "Option::is_none")]
3947    pub sort_by: Option<SortBy>,
3948    /// CLUSTER BY clause (Hive/Spark)
3949    #[serde(default, skip_serializing_if = "Option::is_none")]
3950    pub cluster_by: Option<ClusterBy>,
3951    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
3952    #[serde(default)]
3953    pub by_name: bool,
3954    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
3955    #[serde(default, skip_serializing_if = "Option::is_none")]
3956    pub side: Option<String>,
3957    /// BigQuery: Set operation kind (INNER)
3958    #[serde(default, skip_serializing_if = "Option::is_none")]
3959    pub kind: Option<String>,
3960    /// BigQuery: CORRESPONDING modifier
3961    #[serde(default)]
3962    pub corresponding: bool,
3963    /// BigQuery: STRICT modifier (before CORRESPONDING)
3964    #[serde(default)]
3965    pub strict: bool,
3966    /// BigQuery: BY (columns) after CORRESPONDING
3967    #[serde(default, skip_serializing_if = "Vec::is_empty")]
3968    pub on_columns: Vec<Expression>,
3969}
3970
3971/// Iteratively flatten the left-recursive chain to prevent stack overflow
3972/// when dropping deeply nested set operation trees (e.g., 1000+ UNION ALLs).
3973impl Drop for Union {
3974    fn drop(&mut self) {
3975        loop {
3976            if let Expression::Union(ref mut inner) = self.left {
3977                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
3978                let old_left = std::mem::replace(&mut self.left, next_left);
3979                drop(old_left);
3980            } else {
3981                break;
3982            }
3983        }
3984    }
3985}
3986
3987/// Represent an INTERSECT set operation between two query expressions.
3988///
3989/// Returns only rows that appear in both operands. When `all` is true,
3990/// duplicates are preserved according to their multiplicity.
3991#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
3992#[cfg_attr(feature = "bindings", derive(TS))]
3993pub struct Intersect {
3994    /// The left-hand query operand.
3995    pub left: Expression,
3996    /// The right-hand query operand.
3997    pub right: Expression,
3998    /// Whether INTERSECT ALL (true) or INTERSECT (false, which deduplicates).
3999    pub all: bool,
4000    /// Whether DISTINCT was explicitly specified
4001    #[serde(default)]
4002    pub distinct: bool,
4003    /// Optional WITH clause
4004    pub with: Option<With>,
4005    /// ORDER BY applied to entire INTERSECT result
4006    pub order_by: Option<OrderBy>,
4007    /// LIMIT applied to entire INTERSECT result
4008    pub limit: Option<Box<Expression>>,
4009    /// OFFSET applied to entire INTERSECT result
4010    pub offset: Option<Box<Expression>>,
4011    /// DISTRIBUTE BY clause (Hive/Spark)
4012    #[serde(default, skip_serializing_if = "Option::is_none")]
4013    pub distribute_by: Option<DistributeBy>,
4014    /// SORT BY clause (Hive/Spark)
4015    #[serde(default, skip_serializing_if = "Option::is_none")]
4016    pub sort_by: Option<SortBy>,
4017    /// CLUSTER BY clause (Hive/Spark)
4018    #[serde(default, skip_serializing_if = "Option::is_none")]
4019    pub cluster_by: Option<ClusterBy>,
4020    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4021    #[serde(default)]
4022    pub by_name: bool,
4023    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4024    #[serde(default, skip_serializing_if = "Option::is_none")]
4025    pub side: Option<String>,
4026    /// BigQuery: Set operation kind (INNER)
4027    #[serde(default, skip_serializing_if = "Option::is_none")]
4028    pub kind: Option<String>,
4029    /// BigQuery: CORRESPONDING modifier
4030    #[serde(default)]
4031    pub corresponding: bool,
4032    /// BigQuery: STRICT modifier (before CORRESPONDING)
4033    #[serde(default)]
4034    pub strict: bool,
4035    /// BigQuery: BY (columns) after CORRESPONDING
4036    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4037    pub on_columns: Vec<Expression>,
4038}
4039
4040impl Drop for Intersect {
4041    fn drop(&mut self) {
4042        loop {
4043            if let Expression::Intersect(ref mut inner) = self.left {
4044                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4045                let old_left = std::mem::replace(&mut self.left, next_left);
4046                drop(old_left);
4047            } else {
4048                break;
4049            }
4050        }
4051    }
4052}
4053
4054/// Represent an EXCEPT (MINUS) set operation between two query expressions.
4055///
4056/// Returns rows from the left operand that do not appear in the right operand.
4057/// When `all` is true, duplicates are subtracted according to their multiplicity.
4058#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4059#[cfg_attr(feature = "bindings", derive(TS))]
4060pub struct Except {
4061    /// The left-hand query operand.
4062    pub left: Expression,
4063    /// The right-hand query operand (rows to subtract).
4064    pub right: Expression,
4065    /// Whether EXCEPT ALL (true) or EXCEPT (false, which deduplicates).
4066    pub all: bool,
4067    /// Whether DISTINCT was explicitly specified
4068    #[serde(default)]
4069    pub distinct: bool,
4070    /// Optional WITH clause
4071    pub with: Option<With>,
4072    /// ORDER BY applied to entire EXCEPT result
4073    pub order_by: Option<OrderBy>,
4074    /// LIMIT applied to entire EXCEPT result
4075    pub limit: Option<Box<Expression>>,
4076    /// OFFSET applied to entire EXCEPT result
4077    pub offset: Option<Box<Expression>>,
4078    /// DISTRIBUTE BY clause (Hive/Spark)
4079    #[serde(default, skip_serializing_if = "Option::is_none")]
4080    pub distribute_by: Option<DistributeBy>,
4081    /// SORT BY clause (Hive/Spark)
4082    #[serde(default, skip_serializing_if = "Option::is_none")]
4083    pub sort_by: Option<SortBy>,
4084    /// CLUSTER BY clause (Hive/Spark)
4085    #[serde(default, skip_serializing_if = "Option::is_none")]
4086    pub cluster_by: Option<ClusterBy>,
4087    /// DuckDB, Snowflake, and BigQuery BY NAME modifier
4088    #[serde(default)]
4089    pub by_name: bool,
4090    /// BigQuery: Set operation side (LEFT, RIGHT, FULL)
4091    #[serde(default, skip_serializing_if = "Option::is_none")]
4092    pub side: Option<String>,
4093    /// BigQuery: Set operation kind (INNER)
4094    #[serde(default, skip_serializing_if = "Option::is_none")]
4095    pub kind: Option<String>,
4096    /// BigQuery: CORRESPONDING modifier
4097    #[serde(default)]
4098    pub corresponding: bool,
4099    /// BigQuery: STRICT modifier (before CORRESPONDING)
4100    #[serde(default)]
4101    pub strict: bool,
4102    /// BigQuery: BY (columns) after CORRESPONDING
4103    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4104    pub on_columns: Vec<Expression>,
4105}
4106
4107impl Drop for Except {
4108    fn drop(&mut self) {
4109        loop {
4110            if let Expression::Except(ref mut inner) = self.left {
4111                let next_left = std::mem::replace(&mut inner.left, Expression::Null(Null));
4112                let old_left = std::mem::replace(&mut self.left, next_left);
4113                drop(old_left);
4114            } else {
4115                break;
4116            }
4117        }
4118    }
4119}
4120
4121/// INTO clause for SELECT INTO statements
4122#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4123#[cfg_attr(feature = "bindings", derive(TS))]
4124pub struct SelectInto {
4125    /// Target table or variable (used when single target)
4126    pub this: Expression,
4127    /// Whether TEMPORARY keyword was used
4128    #[serde(default)]
4129    pub temporary: bool,
4130    /// Whether UNLOGGED keyword was used (PostgreSQL)
4131    #[serde(default)]
4132    pub unlogged: bool,
4133    /// Whether BULK COLLECT INTO was used (Oracle PL/SQL)
4134    #[serde(default)]
4135    pub bulk_collect: bool,
4136    /// Multiple target variables (Oracle PL/SQL: BULK COLLECT INTO v1, v2)
4137    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4138    pub expressions: Vec<Expression>,
4139}
4140
4141/// Represent a parenthesized subquery expression.
4142///
4143/// A subquery wraps an inner query (typically a SELECT, UNION, etc.) in
4144/// parentheses and optionally applies an alias, column aliases, ORDER BY,
4145/// LIMIT, and OFFSET. The `modifiers_inside` flag controls whether the
4146/// modifiers are rendered inside or outside the parentheses.
4147///
4148/// Subqueries appear in many SQL contexts: FROM clauses, WHERE IN/EXISTS,
4149/// scalar subqueries in select-lists, and derived tables.
4150#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4151#[cfg_attr(feature = "bindings", derive(TS))]
4152pub struct Subquery {
4153    /// The inner query expression.
4154    pub this: Expression,
4155    /// Optional alias for the derived table.
4156    pub alias: Option<Identifier>,
4157    /// Optional column aliases: AS t(c1, c2)
4158    pub column_aliases: Vec<Identifier>,
4159    /// Whether AS keyword was explicitly used for the alias.
4160    #[serde(default)]
4161    pub alias_explicit_as: bool,
4162    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4163    #[serde(skip_serializing_if = "Option::is_none", default)]
4164    pub alias_keyword: Option<String>,
4165    /// ORDER BY clause (for parenthesized queries)
4166    pub order_by: Option<OrderBy>,
4167    /// LIMIT clause
4168    pub limit: Option<Limit>,
4169    /// OFFSET clause
4170    pub offset: Option<Offset>,
4171    /// DISTRIBUTE BY clause (Hive/Spark)
4172    #[serde(default, skip_serializing_if = "Option::is_none")]
4173    pub distribute_by: Option<DistributeBy>,
4174    /// SORT BY clause (Hive/Spark)
4175    #[serde(default, skip_serializing_if = "Option::is_none")]
4176    pub sort_by: Option<SortBy>,
4177    /// CLUSTER BY clause (Hive/Spark)
4178    #[serde(default, skip_serializing_if = "Option::is_none")]
4179    pub cluster_by: Option<ClusterBy>,
4180    /// Whether this is a LATERAL subquery (can reference earlier tables in FROM)
4181    #[serde(default)]
4182    pub lateral: bool,
4183    /// Whether modifiers (ORDER BY, LIMIT, OFFSET) should be generated inside the parentheses
4184    /// true: (SELECT 1 LIMIT 1)  - modifiers inside
4185    /// false: (SELECT 1) LIMIT 1 - modifiers outside
4186    #[serde(default)]
4187    pub modifiers_inside: bool,
4188    /// Trailing comments after the closing paren
4189    #[serde(default)]
4190    pub trailing_comments: Vec<String>,
4191    /// Inferred data type from type annotation
4192    #[serde(default, skip_serializing_if = "Option::is_none")]
4193    #[ast(skip)]
4194    pub inferred_type: Option<DataType>,
4195}
4196
4197/// Pipe operator expression: query |> transform
4198///
4199/// Used in DataFusion and BigQuery pipe syntax:
4200///   FROM t |> WHERE x > 1 |> SELECT x, y |> ORDER BY x |> LIMIT 10
4201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4202#[cfg_attr(feature = "bindings", derive(TS))]
4203pub struct PipeOperator {
4204    /// The input query/expression (left side of |>)
4205    pub this: Expression,
4206    /// The piped operation (right side of |>)
4207    pub expression: Expression,
4208}
4209
4210/// VALUES table constructor: VALUES (1, 'a'), (2, 'b')
4211#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4212#[cfg_attr(feature = "bindings", derive(TS))]
4213pub struct Values {
4214    /// The rows of values
4215    pub expressions: Vec<Tuple>,
4216    /// Optional alias for the table
4217    pub alias: Option<Identifier>,
4218    /// Optional column aliases: AS t(c1, c2)
4219    pub column_aliases: Vec<Identifier>,
4220}
4221
4222/// PIVOT operation - supports both standard and DuckDB simplified syntax
4223///
4224/// Standard syntax (in FROM clause):
4225///   table PIVOT(agg_func [AS alias], ... FOR column IN (value [AS alias], ...))
4226///   table UNPIVOT(value_col FOR name_col IN (col1, col2, ...))
4227///
4228/// DuckDB simplified syntax (statement-level):
4229///   PIVOT table ON columns [IN (...)] USING agg_func [AS alias], ... [GROUP BY ...]
4230///   UNPIVOT table ON columns INTO NAME name_col VALUE val_col
4231#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4232#[cfg_attr(feature = "bindings", derive(TS))]
4233pub struct Pivot {
4234    /// Source table/expression
4235    pub this: Expression,
4236    /// For standard PIVOT: the aggregation function(s) (first is primary)
4237    /// For DuckDB simplified: unused (use `using` instead)
4238    #[serde(default)]
4239    pub expressions: Vec<Expression>,
4240    /// For standard PIVOT: the FOR...IN clause(s) as In expressions
4241    #[serde(default)]
4242    pub fields: Vec<Expression>,
4243    /// For standard: unused. For DuckDB simplified: the USING aggregation functions
4244    #[serde(default)]
4245    pub using: Vec<Expression>,
4246    /// GROUP BY clause (used in both standard inside-parens and DuckDB simplified)
4247    #[serde(default)]
4248    pub group: Option<Box<Expression>>,
4249    /// Whether this is an UNPIVOT (vs PIVOT)
4250    #[serde(default)]
4251    pub unpivot: bool,
4252    /// For DuckDB UNPIVOT: INTO NAME col VALUE col
4253    #[serde(default)]
4254    pub into: Option<Box<Expression>>,
4255    /// Optional alias
4256    #[serde(default)]
4257    pub alias: Option<Identifier>,
4258    /// Optional output column aliases from `PIVOT(...) AS alias(col1, col2, ...)`
4259    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4260    pub alias_columns: Vec<Identifier>,
4261    /// Include/exclude nulls (for UNPIVOT)
4262    #[serde(default)]
4263    pub include_nulls: Option<bool>,
4264    /// Default on null value (Snowflake)
4265    #[serde(default)]
4266    pub default_on_null: Option<Box<Expression>>,
4267    /// WITH clause (CTEs)
4268    #[serde(default, skip_serializing_if = "Option::is_none")]
4269    pub with: Option<With>,
4270}
4271
4272/// UNPIVOT operation
4273#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4274#[cfg_attr(feature = "bindings", derive(TS))]
4275pub struct Unpivot {
4276    pub this: Expression,
4277    pub value_column: Identifier,
4278    pub name_column: Identifier,
4279    pub columns: Vec<Expression>,
4280    pub alias: Option<Identifier>,
4281    /// Optional output column aliases from `UNPIVOT(...) AS alias(col1, col2, ...)`
4282    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4283    pub alias_columns: Vec<Identifier>,
4284    /// Whether the value_column was parenthesized in the original SQL
4285    #[serde(default)]
4286    pub value_column_parenthesized: bool,
4287    /// INCLUDE NULLS (true), EXCLUDE NULLS (false), or not specified (None)
4288    #[serde(default)]
4289    pub include_nulls: Option<bool>,
4290    /// Additional value columns when parenthesized (e.g., (first_half_sales, second_half_sales))
4291    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4292    pub extra_value_columns: Vec<Identifier>,
4293}
4294
4295/// PIVOT alias for aliasing pivot expressions
4296/// The alias can be an identifier or an expression (for Oracle/BigQuery string concatenation aliases)
4297#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4298#[cfg_attr(feature = "bindings", derive(TS))]
4299pub struct PivotAlias {
4300    pub this: Expression,
4301    pub alias: Expression,
4302}
4303
4304/// PREWHERE clause (ClickHouse) - early filtering before WHERE
4305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4306#[cfg_attr(feature = "bindings", derive(TS))]
4307pub struct PreWhere {
4308    pub this: Expression,
4309}
4310
4311/// STREAM definition (Snowflake) - for change data capture
4312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4313#[cfg_attr(feature = "bindings", derive(TS))]
4314pub struct Stream {
4315    pub this: Expression,
4316    #[serde(skip_serializing_if = "Option::is_none")]
4317    pub on: Option<Expression>,
4318    #[serde(skip_serializing_if = "Option::is_none")]
4319    pub show_initial_rows: Option<bool>,
4320}
4321
4322/// USING DATA clause for data import statements
4323#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4324#[cfg_attr(feature = "bindings", derive(TS))]
4325pub struct UsingData {
4326    pub this: Expression,
4327}
4328
4329/// XML Namespace declaration
4330#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4331#[cfg_attr(feature = "bindings", derive(TS))]
4332pub struct XmlNamespace {
4333    pub this: Expression,
4334    #[serde(skip_serializing_if = "Option::is_none")]
4335    pub alias: Option<Identifier>,
4336}
4337
4338/// ROW FORMAT clause for Hive/Spark
4339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4340#[cfg_attr(feature = "bindings", derive(TS))]
4341pub struct RowFormat {
4342    pub delimited: bool,
4343    pub fields_terminated_by: Option<String>,
4344    pub collection_items_terminated_by: Option<String>,
4345    pub map_keys_terminated_by: Option<String>,
4346    pub lines_terminated_by: Option<String>,
4347    pub null_defined_as: Option<String>,
4348}
4349
4350/// Directory insert for INSERT OVERWRITE DIRECTORY (Hive/Spark)
4351#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4352#[cfg_attr(feature = "bindings", derive(TS))]
4353pub struct DirectoryInsert {
4354    pub local: bool,
4355    pub path: String,
4356    pub row_format: Option<RowFormat>,
4357    /// STORED AS clause (e.g., TEXTFILE, ORC, PARQUET)
4358    #[serde(default)]
4359    pub stored_as: Option<String>,
4360}
4361
4362/// INSERT statement
4363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4364#[cfg_attr(feature = "bindings", derive(TS))]
4365pub struct Insert {
4366    pub table: TableRef,
4367    pub columns: Vec<Identifier>,
4368    pub values: Vec<Vec<Expression>>,
4369    pub query: Option<Expression>,
4370    /// INSERT OVERWRITE for Hive/Spark
4371    pub overwrite: bool,
4372    /// PARTITION clause for Hive/Spark
4373    pub partition: Vec<(Identifier, Option<Expression>)>,
4374    /// INSERT OVERWRITE DIRECTORY for Hive/Spark
4375    #[serde(default)]
4376    pub directory: Option<DirectoryInsert>,
4377    /// RETURNING clause (PostgreSQL, SQLite)
4378    #[serde(default)]
4379    pub returning: Vec<Expression>,
4380    /// OUTPUT clause (TSQL)
4381    #[serde(default)]
4382    pub output: Option<OutputClause>,
4383    /// ON CONFLICT clause (PostgreSQL, SQLite)
4384    #[serde(default)]
4385    pub on_conflict: Option<Box<Expression>>,
4386    /// Leading comments before the statement
4387    #[serde(default)]
4388    pub leading_comments: Vec<String>,
4389    /// IF EXISTS clause (Hive)
4390    #[serde(default)]
4391    pub if_exists: bool,
4392    /// WITH clause (CTEs)
4393    #[serde(default)]
4394    pub with: Option<With>,
4395    /// INSERT IGNORE (MySQL) - ignore duplicate key errors
4396    #[serde(default)]
4397    pub ignore: bool,
4398    /// Source alias for VALUES clause (MySQL): VALUES (1, 2) AS new_data
4399    #[serde(default)]
4400    pub source_alias: Option<Identifier>,
4401    /// Table alias (PostgreSQL): INSERT INTO table AS t(...)
4402    #[serde(default)]
4403    pub alias: Option<Identifier>,
4404    /// Whether the alias uses explicit AS keyword
4405    #[serde(default)]
4406    pub alias_explicit_as: bool,
4407    /// DEFAULT VALUES (PostgreSQL): INSERT INTO t DEFAULT VALUES
4408    #[serde(default)]
4409    pub default_values: bool,
4410    /// BY NAME modifier (DuckDB): INSERT INTO x BY NAME SELECT ...
4411    #[serde(default)]
4412    pub by_name: bool,
4413    /// SQLite conflict action: INSERT OR ABORT|FAIL|IGNORE|REPLACE|ROLLBACK INTO ...
4414    #[serde(default, skip_serializing_if = "Option::is_none")]
4415    pub conflict_action: Option<String>,
4416    /// MySQL/SQLite REPLACE INTO statement (treat like INSERT)
4417    #[serde(default)]
4418    pub is_replace: bool,
4419    /// Oracle-style hint: `INSERT <hint> INTO ...` (for example Oracle APPEND hints)
4420    #[serde(default, skip_serializing_if = "Option::is_none")]
4421    pub hint: Option<Hint>,
4422    /// REPLACE WHERE clause (Databricks): INSERT INTO a REPLACE WHERE cond VALUES ...
4423    #[serde(default)]
4424    pub replace_where: Option<Box<Expression>>,
4425    /// Source table (Hive/Spark): INSERT OVERWRITE TABLE target TABLE source
4426    #[serde(default)]
4427    pub source: Option<Box<Expression>>,
4428    /// ClickHouse: INSERT INTO FUNCTION func_name(...) - the function call
4429    #[serde(default, skip_serializing_if = "Option::is_none")]
4430    pub function_target: Option<Box<Expression>>,
4431    /// ClickHouse: PARTITION BY expr
4432    #[serde(default, skip_serializing_if = "Option::is_none")]
4433    pub partition_by: Option<Box<Expression>>,
4434    /// ClickHouse: SETTINGS key = val, ...
4435    #[serde(default, skip_serializing_if = "Vec::is_empty")]
4436    pub settings: Vec<Expression>,
4437}
4438
4439/// OUTPUT clause (TSQL) - used in INSERT, UPDATE, DELETE
4440#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4441#[cfg_attr(feature = "bindings", derive(TS))]
4442pub struct OutputClause {
4443    /// Columns/expressions to output
4444    pub columns: Vec<Expression>,
4445    /// Optional INTO target table or table variable
4446    #[serde(default)]
4447    pub into_table: Option<Expression>,
4448}
4449
4450/// UPDATE statement
4451#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4452#[cfg_attr(feature = "bindings", derive(TS))]
4453pub struct Update {
4454    pub table: TableRef,
4455    #[serde(default)]
4456    pub hint: Option<Hint>,
4457    /// Additional tables for multi-table UPDATE (MySQL syntax)
4458    #[serde(default)]
4459    pub extra_tables: Vec<TableRef>,
4460    /// JOINs attached to the table list (MySQL multi-table syntax)
4461    #[serde(default)]
4462    pub table_joins: Vec<Join>,
4463    pub set: Vec<(Identifier, Expression)>,
4464    pub from_clause: Option<From>,
4465    /// JOINs after FROM clause (PostgreSQL, Snowflake, SQL Server syntax)
4466    #[serde(default)]
4467    pub from_joins: Vec<Join>,
4468    pub where_clause: Option<Where>,
4469    /// RETURNING clause (PostgreSQL, SQLite)
4470    #[serde(default)]
4471    pub returning: Vec<Expression>,
4472    /// OUTPUT clause (TSQL)
4473    #[serde(default)]
4474    pub output: Option<OutputClause>,
4475    /// WITH clause (CTEs)
4476    #[serde(default)]
4477    pub with: Option<With>,
4478    /// Leading comments before the statement
4479    #[serde(default)]
4480    pub leading_comments: Vec<String>,
4481    /// LIMIT clause (MySQL)
4482    #[serde(default)]
4483    pub limit: Option<Expression>,
4484    /// ORDER BY clause (MySQL)
4485    #[serde(default)]
4486    pub order_by: Option<OrderBy>,
4487    /// Whether FROM clause appears before SET (Snowflake syntax)
4488    #[serde(default)]
4489    pub from_before_set: bool,
4490}
4491
4492/// DELETE statement
4493#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4494#[cfg_attr(feature = "bindings", derive(TS))]
4495pub struct Delete {
4496    pub table: TableRef,
4497    #[serde(default)]
4498    pub hint: Option<Hint>,
4499    /// ClickHouse: ON CLUSTER clause for distributed DDL
4500    #[serde(default, skip_serializing_if = "Option::is_none")]
4501    pub on_cluster: Option<OnCluster>,
4502    /// Optional alias for the table
4503    pub alias: Option<Identifier>,
4504    /// Whether the alias was declared with explicit AS keyword
4505    #[serde(default)]
4506    pub alias_explicit_as: bool,
4507    /// PostgreSQL/DuckDB USING clause - additional tables to join
4508    pub using: Vec<TableRef>,
4509    pub where_clause: Option<Where>,
4510    /// OUTPUT clause (TSQL)
4511    #[serde(default)]
4512    pub output: Option<OutputClause>,
4513    /// Leading comments before the statement
4514    #[serde(default)]
4515    pub leading_comments: Vec<String>,
4516    /// WITH clause (CTEs)
4517    #[serde(default)]
4518    pub with: Option<With>,
4519    /// LIMIT clause (MySQL)
4520    #[serde(default)]
4521    pub limit: Option<Expression>,
4522    /// ORDER BY clause (MySQL)
4523    #[serde(default)]
4524    pub order_by: Option<OrderBy>,
4525    /// RETURNING clause (PostgreSQL)
4526    #[serde(default)]
4527    pub returning: Vec<Expression>,
4528    /// MySQL multi-table DELETE: DELETE t1, t2 FROM ... or DELETE FROM t1, t2 USING ...
4529    /// These are the target tables to delete from
4530    #[serde(default)]
4531    pub tables: Vec<TableRef>,
4532    /// True if tables were after FROM keyword (DELETE FROM t1, t2 USING syntax)
4533    /// False if tables were before FROM keyword (DELETE t1, t2 FROM syntax)
4534    #[serde(default)]
4535    pub tables_from_using: bool,
4536    /// JOINs in MySQL multi-table DELETE: DELETE t1 FROM t1 LEFT JOIN t2 ...
4537    #[serde(default)]
4538    pub joins: Vec<Join>,
4539    /// FORCE INDEX hint (MySQL): DELETE FROM t FORCE INDEX (idx)
4540    #[serde(default)]
4541    pub force_index: Option<String>,
4542    /// BigQuery-style DELETE without FROM keyword: DELETE table WHERE ...
4543    #[serde(default)]
4544    pub no_from: bool,
4545}
4546
4547/// COPY statement (Snowflake, PostgreSQL, DuckDB, TSQL)
4548#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4549#[cfg_attr(feature = "bindings", derive(TS))]
4550pub struct CopyStmt {
4551    /// Target table or query
4552    pub this: Expression,
4553    /// True for FROM (loading into table), false for TO (exporting)
4554    pub kind: bool,
4555    /// Source/destination file(s) or stage
4556    pub files: Vec<Expression>,
4557    /// Copy parameters
4558    #[serde(default)]
4559    pub params: Vec<CopyParameter>,
4560    /// Credentials for external access
4561    #[serde(default)]
4562    pub credentials: Option<Box<Credentials>>,
4563    /// Whether the INTO keyword was used (COPY INTO vs COPY)
4564    #[serde(default)]
4565    pub is_into: bool,
4566    /// Whether parameters are wrapped in WITH (...) syntax
4567    #[serde(default)]
4568    pub with_wrapped: bool,
4569}
4570
4571/// COPY parameter (e.g., FILE_FORMAT = CSV or FORMAT PARQUET)
4572#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4573#[cfg_attr(feature = "bindings", derive(TS))]
4574pub struct CopyParameter {
4575    pub name: String,
4576    pub value: Option<Expression>,
4577    pub values: Vec<Expression>,
4578    /// Whether the parameter used = sign (TSQL: KEY = VALUE vs DuckDB: KEY VALUE)
4579    #[serde(default)]
4580    pub eq: bool,
4581}
4582
4583/// Credentials for external access (S3, Azure, etc.)
4584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4585#[cfg_attr(feature = "bindings", derive(TS))]
4586pub struct Credentials {
4587    pub credentials: Vec<(String, String)>,
4588    pub encryption: Option<String>,
4589    pub storage: Option<String>,
4590}
4591
4592/// PUT statement (Snowflake)
4593#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4594#[cfg_attr(feature = "bindings", derive(TS))]
4595pub struct PutStmt {
4596    /// Source file path
4597    pub source: String,
4598    /// Whether source was quoted in the original SQL
4599    #[serde(default)]
4600    pub source_quoted: bool,
4601    /// Target stage
4602    pub target: Expression,
4603    /// PUT parameters
4604    #[serde(default)]
4605    pub params: Vec<CopyParameter>,
4606}
4607
4608/// Stage reference (Snowflake) - @stage_name or @namespace.stage/path
4609#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4610#[cfg_attr(feature = "bindings", derive(TS))]
4611pub struct StageReference {
4612    /// Stage name including @ prefix (e.g., "@mystage", "@namespace.mystage")
4613    pub name: String,
4614    /// Optional path within the stage (e.g., "/path/to/file.csv")
4615    #[serde(default)]
4616    pub path: Option<String>,
4617    /// Optional FILE_FORMAT parameter
4618    #[serde(default)]
4619    pub file_format: Option<Expression>,
4620    /// Optional PATTERN parameter
4621    #[serde(default)]
4622    pub pattern: Option<String>,
4623    /// Whether the stage reference was originally quoted (e.g., '@mystage')
4624    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4625    pub quoted: bool,
4626}
4627
4628/// Historical data / Time travel (Snowflake) - BEFORE (STATEMENT => ...) or AT (TIMESTAMP => ...)
4629#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4630#[cfg_attr(feature = "bindings", derive(TS))]
4631pub struct HistoricalData {
4632    /// The time travel kind: "BEFORE", "AT", or "END" (as an Identifier expression)
4633    pub this: Box<Expression>,
4634    /// The time travel type: "STATEMENT", "TIMESTAMP", "OFFSET", "STREAM", or "VERSION"
4635    pub kind: String,
4636    /// The expression value (e.g., the statement ID or timestamp)
4637    pub expression: Box<Expression>,
4638}
4639
4640/// Represent an aliased expression (`expr AS name`).
4641///
4642/// Used for column aliases in select-lists, table aliases on subqueries,
4643/// and column alias lists on table-valued expressions (e.g. `AS t(c1, c2)`).
4644#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4645#[cfg_attr(feature = "bindings", derive(TS))]
4646pub struct Alias {
4647    /// The expression being aliased.
4648    pub this: Expression,
4649    /// The alias name (required for simple aliases, optional when only column aliases provided)
4650    pub alias: Identifier,
4651    /// Optional column aliases for table-valued functions: AS t(col1, col2) or AS (col1, col2)
4652    #[serde(default)]
4653    pub column_aliases: Vec<Identifier>,
4654    /// Whether AS keyword was explicitly used for the alias.
4655    #[serde(default)]
4656    pub alias_explicit_as: bool,
4657    /// Original alias keyword spelling, e.g. `AS` vs `as`.
4658    #[serde(skip_serializing_if = "Option::is_none", default)]
4659    pub alias_keyword: Option<String>,
4660    /// Comments that appeared between the expression and AS keyword
4661    #[serde(default)]
4662    pub pre_alias_comments: Vec<String>,
4663    /// Trailing comments that appeared after the alias
4664    #[serde(default)]
4665    pub trailing_comments: Vec<String>,
4666    /// Inferred data type from type annotation
4667    #[serde(default, skip_serializing_if = "Option::is_none")]
4668    #[ast(skip)]
4669    pub inferred_type: Option<DataType>,
4670}
4671
4672impl Alias {
4673    /// Create a simple alias
4674    pub fn new(this: Expression, alias: Identifier) -> Self {
4675        Self {
4676            this,
4677            alias,
4678            column_aliases: Vec::new(),
4679            alias_explicit_as: false,
4680            alias_keyword: None,
4681            pre_alias_comments: Vec::new(),
4682            trailing_comments: Vec::new(),
4683            inferred_type: None,
4684        }
4685    }
4686
4687    /// Create an alias with column aliases only (no table alias name)
4688    pub fn with_columns(this: Expression, column_aliases: Vec<Identifier>) -> Self {
4689        Self {
4690            this,
4691            alias: Identifier::empty(),
4692            column_aliases,
4693            alias_explicit_as: false,
4694            alias_keyword: None,
4695            pre_alias_comments: Vec::new(),
4696            trailing_comments: Vec::new(),
4697            inferred_type: None,
4698        }
4699    }
4700}
4701
4702/// Represent a type cast expression.
4703///
4704/// Covers both the standard `CAST(expr AS type)` syntax and the PostgreSQL
4705/// shorthand `expr::type`. Also used as the payload for `TryCast` and
4706/// `SafeCast` variants. Supports optional FORMAT (BigQuery) and DEFAULT ON
4707/// CONVERSION ERROR (Oracle) clauses.
4708#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4709#[cfg_attr(feature = "bindings", derive(TS))]
4710pub struct Cast {
4711    /// The expression being cast.
4712    pub this: Expression,
4713    /// The target data type.
4714    pub to: DataType,
4715    #[serde(default)]
4716    pub trailing_comments: Vec<String>,
4717    /// Whether PostgreSQL `::` syntax was used (true) vs CAST() function (false)
4718    #[serde(default)]
4719    pub double_colon_syntax: bool,
4720    /// FORMAT clause for BigQuery: CAST(x AS STRING FORMAT 'format_string')
4721    #[serde(skip_serializing_if = "Option::is_none", default)]
4722    pub format: Option<Box<Expression>>,
4723    /// DEFAULT value ON CONVERSION ERROR (Oracle): CAST(x AS type DEFAULT val ON CONVERSION ERROR)
4724    #[serde(skip_serializing_if = "Option::is_none", default)]
4725    pub default: Option<Box<Expression>>,
4726    /// Inferred data type from type annotation
4727    #[serde(default, skip_serializing_if = "Option::is_none")]
4728    #[ast(skip)]
4729    pub inferred_type: Option<DataType>,
4730}
4731
4732///// COLLATE expression: expr COLLATE 'collation_name' or expr COLLATE collation_name
4733#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4734#[cfg_attr(feature = "bindings", derive(TS))]
4735pub struct CollationExpr {
4736    pub this: Expression,
4737    pub collation: String,
4738    /// True if the collation was single-quoted in the original SQL (string literal)
4739    #[serde(default)]
4740    pub quoted: bool,
4741    /// True if the collation was double-quoted in the original SQL (identifier)
4742    #[serde(default)]
4743    pub double_quoted: bool,
4744}
4745
4746/// Represent a CASE expression (both simple and searched forms).
4747///
4748/// When `operand` is `Some`, this is a simple CASE (`CASE x WHEN 1 THEN ...`).
4749/// When `operand` is `None`, this is a searched CASE (`CASE WHEN x > 0 THEN ...`).
4750/// Each entry in `whens` is a `(condition, result)` pair.
4751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4752#[cfg_attr(feature = "bindings", derive(TS))]
4753pub struct Case {
4754    /// The operand for simple CASE, or `None` for searched CASE.
4755    pub operand: Option<Expression>,
4756    /// Pairs of (WHEN condition, THEN result).
4757    pub whens: Vec<(Expression, Expression)>,
4758    /// Optional ELSE result.
4759    pub else_: Option<Expression>,
4760    /// Comments from the CASE keyword (emitted after END)
4761    #[serde(default)]
4762    #[serde(skip_serializing_if = "Vec::is_empty")]
4763    pub comments: Vec<String>,
4764    /// Inferred data type from type annotation
4765    #[serde(default, skip_serializing_if = "Option::is_none")]
4766    #[ast(skip)]
4767    pub inferred_type: Option<DataType>,
4768}
4769
4770/// Represent a binary operation (two operands separated by an operator).
4771///
4772/// This is the shared payload struct for all binary operator variants in the
4773/// [`Expression`] enum: arithmetic (`Add`, `Sub`, `Mul`, `Div`, `Mod`),
4774/// comparison (`Eq`, `Neq`, `Lt`, `Gt`, etc.), logical (`And`, `Or`),
4775/// bitwise, and dialect-specific operators. Comment fields enable round-trip
4776/// preservation of inline comments around operators.
4777#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4778#[cfg_attr(feature = "bindings", derive(TS))]
4779pub struct BinaryOp {
4780    pub left: Expression,
4781    pub right: Expression,
4782    /// Comments after the left operand (before the operator)
4783    #[serde(default)]
4784    pub left_comments: Vec<String>,
4785    /// Comments after the operator (before the right operand)
4786    #[serde(default)]
4787    pub operator_comments: Vec<String>,
4788    /// Comments after the right operand
4789    #[serde(default)]
4790    pub trailing_comments: Vec<String>,
4791    /// Inferred data type from type annotation
4792    #[serde(default, skip_serializing_if = "Option::is_none")]
4793    #[ast(skip)]
4794    pub inferred_type: Option<DataType>,
4795}
4796
4797impl BinaryOp {
4798    pub fn new(left: Expression, right: Expression) -> Self {
4799        Self {
4800            left,
4801            right,
4802            left_comments: Vec::new(),
4803            operator_comments: Vec::new(),
4804            trailing_comments: Vec::new(),
4805            inferred_type: None,
4806        }
4807    }
4808}
4809
4810/// LIKE/ILIKE operation with optional ESCAPE clause and quantifier (ANY/ALL)
4811#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4812#[cfg_attr(feature = "bindings", derive(TS))]
4813pub struct LikeOp {
4814    pub left: Expression,
4815    pub right: Expression,
4816    /// ESCAPE character/expression
4817    #[serde(default)]
4818    pub escape: Option<Expression>,
4819    /// Quantifier: ANY, ALL, or SOME
4820    #[serde(default)]
4821    pub quantifier: Option<String>,
4822    /// Inferred data type from type annotation
4823    #[serde(default, skip_serializing_if = "Option::is_none")]
4824    #[ast(skip)]
4825    pub inferred_type: Option<DataType>,
4826}
4827
4828impl LikeOp {
4829    pub fn new(left: Expression, right: Expression) -> Self {
4830        Self {
4831            left,
4832            right,
4833            escape: None,
4834            quantifier: None,
4835            inferred_type: None,
4836        }
4837    }
4838
4839    pub fn with_escape(left: Expression, right: Expression, escape: Expression) -> Self {
4840        Self {
4841            left,
4842            right,
4843            escape: Some(escape),
4844            quantifier: None,
4845            inferred_type: None,
4846        }
4847    }
4848}
4849
4850/// Represent a unary operation (single operand with a prefix operator).
4851///
4852/// Shared payload for `Not`, `Neg`, and `BitwiseNot` variants.
4853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4854#[cfg_attr(feature = "bindings", derive(TS))]
4855pub struct UnaryOp {
4856    /// The operand expression.
4857    pub this: Expression,
4858    /// Inferred data type from type annotation
4859    #[serde(default, skip_serializing_if = "Option::is_none")]
4860    #[ast(skip)]
4861    pub inferred_type: Option<DataType>,
4862}
4863
4864impl UnaryOp {
4865    pub fn new(this: Expression) -> Self {
4866        Self {
4867            this,
4868            inferred_type: None,
4869        }
4870    }
4871}
4872
4873/// Represent an IN predicate (`x IN (1, 2, 3)` or `x IN (SELECT ...)`).
4874///
4875/// Either `expressions` (a value list) or `query` (a subquery) is populated,
4876/// but not both. When `not` is true, the predicate is `NOT IN`.
4877#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4878#[cfg_attr(feature = "bindings", derive(TS))]
4879pub struct In {
4880    /// The expression being tested.
4881    pub this: Expression,
4882    /// The value list (mutually exclusive with `query`).
4883    pub expressions: Vec<Expression>,
4884    /// A subquery (mutually exclusive with `expressions`).
4885    pub query: Option<Expression>,
4886    /// Whether this is NOT IN.
4887    pub not: bool,
4888    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4889    pub global: bool,
4890    /// BigQuery: IN UNNEST(expr)
4891    #[serde(default, skip_serializing_if = "Option::is_none")]
4892    pub unnest: Option<Box<Expression>>,
4893    /// Whether the right side is a bare field reference (no parentheses).
4894    /// Matches Python sqlglot's `field` attribute on `In` expression.
4895    /// e.g., `a IN subquery1` vs `a IN (subquery1)`
4896    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
4897    pub is_field: bool,
4898}
4899
4900/// Represent a BETWEEN predicate (`x BETWEEN low AND high`).
4901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4902#[cfg_attr(feature = "bindings", derive(TS))]
4903pub struct Between {
4904    /// The expression being tested.
4905    pub this: Expression,
4906    /// The lower bound.
4907    pub low: Expression,
4908    /// The upper bound.
4909    pub high: Expression,
4910    /// Whether this is NOT BETWEEN.
4911    pub not: bool,
4912    /// SYMMETRIC/ASYMMETRIC qualifier: None = regular, Some(true) = SYMMETRIC, Some(false) = ASYMMETRIC
4913    #[serde(default)]
4914    pub symmetric: Option<bool>,
4915}
4916
4917/// IS NULL predicate
4918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4919#[cfg_attr(feature = "bindings", derive(TS))]
4920pub struct IsNull {
4921    pub this: Expression,
4922    pub not: bool,
4923    /// Whether this was the postfix form (ISNULL/NOTNULL) vs standard (IS NULL/IS NOT NULL)
4924    #[serde(default)]
4925    pub postfix_form: bool,
4926}
4927
4928/// IS TRUE / IS FALSE predicate
4929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4930#[cfg_attr(feature = "bindings", derive(TS))]
4931pub struct IsTrueFalse {
4932    pub this: Expression,
4933    pub not: bool,
4934}
4935
4936/// IS JSON predicate (SQL standard)
4937/// Checks if a value is valid JSON
4938#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4939#[cfg_attr(feature = "bindings", derive(TS))]
4940pub struct IsJson {
4941    pub this: Expression,
4942    /// JSON type: VALUE, SCALAR, OBJECT, or ARRAY (None = just IS JSON)
4943    pub json_type: Option<String>,
4944    /// Key uniqueness constraint
4945    pub unique_keys: Option<JsonUniqueKeys>,
4946    /// Whether IS NOT JSON
4947    pub negated: bool,
4948}
4949
4950/// JSON unique keys constraint variants
4951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4952#[cfg_attr(feature = "bindings", derive(TS))]
4953pub enum JsonUniqueKeys {
4954    /// WITH UNIQUE KEYS
4955    With,
4956    /// WITHOUT UNIQUE KEYS
4957    Without,
4958    /// UNIQUE KEYS (shorthand for WITH UNIQUE KEYS)
4959    Shorthand,
4960}
4961
4962/// Represent an EXISTS predicate (`EXISTS (SELECT ...)` or `NOT EXISTS (...)`).
4963#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4964#[cfg_attr(feature = "bindings", derive(TS))]
4965pub struct Exists {
4966    /// The subquery expression.
4967    pub this: Expression,
4968    /// Whether this is NOT EXISTS.
4969    pub not: bool,
4970}
4971
4972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4973#[cfg_attr(feature = "bindings", derive(TS))]
4974pub struct Upsert {
4975    /// Retained source semantics; serialized independently of generator configuration.
4976    #[serde(default, skip_serializing_if = "Option::is_none")]
4977    #[ast(skip)]
4978    pub source_dialect: Option<crate::dialects::DialectType>,
4979
4980    pub table: TableRef,
4981    pub partition: Option<Expression>,
4982    pub columns: Vec<Identifier>,
4983    pub source: Expression,
4984    pub condition: Option<Expression>,
4985    pub primary_key: bool,
4986}
4987
4988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
4989#[cfg_attr(feature = "bindings", derive(TS))]
4990pub struct PartitionSpec {
4991    /// Retained source semantics; serialized independently of generator configuration.
4992    #[serde(default, skip_serializing_if = "Option::is_none")]
4993    #[ast(skip)]
4994    pub source_dialect: Option<crate::dialects::DialectType>,
4995
4996    pub method: String,
4997    pub columns: Vec<Expression>,
4998    pub partitions: Option<Expression>,
4999    pub ranges: Vec<PartitionRangeSpec>,
5000    pub primary_key_check: Option<bool>,
5001    pub properties: Vec<Expression>,
5002    pub subpartition: Option<Box<PartitionSpec>>,
5003}
5004
5005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5006#[cfg_attr(feature = "bindings", derive(TS))]
5007pub struct PartitionRangeSpec {
5008    pub name: Option<Identifier>,
5009    pub kind: String,
5010    pub values: Vec<Expression>,
5011    pub dynamic: bool,
5012    pub direction: Option<String>,
5013    pub threshold: Option<Expression>,
5014    pub interval: Option<(Expression, Option<String>)>,
5015    pub properties: Vec<Expression>,
5016}
5017
5018#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5019#[cfg_attr(feature = "bindings", derive(TS))]
5020pub struct StorageProperty {
5021    /// Retained source semantics; serialized independently of generator configuration.
5022    #[serde(default, skip_serializing_if = "Option::is_none")]
5023    #[ast(skip)]
5024    pub source_dialect: Option<crate::dialects::DialectType>,
5025
5026    pub name: String,
5027    pub values: Vec<Expression>,
5028}
5029
5030#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5031#[cfg_attr(feature = "bindings", derive(TS))]
5032pub struct Hierarchy {
5033    /// Retained source semantics; serialized independently of generator configuration.
5034    #[serde(default, skip_serializing_if = "Option::is_none")]
5035    #[ast(skip)]
5036    pub source_dialect: Option<crate::dialects::DialectType>,
5037
5038    pub name: String,
5039    pub source: Expression,
5040    pub start: Option<Expression>,
5041    pub siblings: Vec<Ordered>,
5042    pub depth: Option<Expression>,
5043    pub multiparent: Option<String>,
5044    pub orphan: Option<String>,
5045    pub cycle: Option<String>,
5046    pub cache: Option<String>,
5047}
5048
5049#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5050#[cfg_attr(feature = "bindings", derive(TS))]
5051pub struct ViewParameter {
5052    /// Retained source semantics; serialized independently of generator configuration.
5053    #[serde(default, skip_serializing_if = "Option::is_none")]
5054    #[ast(skip)]
5055    pub source_dialect: Option<crate::dialects::DialectType>,
5056
5057    pub name: Identifier,
5058    pub value: Expression,
5059}
5060
5061#[derive(
5062    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
5063)]
5064#[cfg_attr(feature = "bindings", derive(TS))]
5065pub struct JsonOptions {
5066    pub wrapper: Option<String>,
5067    pub on_empty: Option<SqlBehavior>,
5068    pub on_error: Option<SqlBehavior>,
5069}
5070
5071#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5072#[cfg_attr(feature = "bindings", derive(TS))]
5073pub struct SqlBehavior {
5074    /// ERROR, NULL, DEFAULT, EMPTY ARRAY, or EMPTY OBJECT.
5075    pub kind: String,
5076    pub value: Option<Expression>,
5077}
5078
5079/// Procedure invocation, including library member calls and asynchronous execution.
5080#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5081#[cfg_attr(feature = "bindings", derive(TS))]
5082pub struct Call {
5083    /// Retained source semantics; serialized independently of generator configuration.
5084    #[serde(default, skip_serializing_if = "Option::is_none")]
5085    #[ast(skip)]
5086    pub source_dialect: Option<crate::dialects::DialectType>,
5087
5088    pub name: Vec<Identifier>,
5089    pub member: Option<Identifier>,
5090    pub arguments: Vec<Expression>,
5091    pub asynchronous: bool,
5092    pub hints: Vec<Expression>,
5093}
5094
5095/// Regex search options shared by predicates, extraction, replacement, and position calls.
5096#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5097#[cfg_attr(feature = "bindings", derive(TS))]
5098pub struct RegexOptions {
5099    #[serde(default, skip_serializing_if = "Option::is_none")]
5100    #[ast(skip)]
5101    pub source_dialect: Option<crate::dialects::DialectType>,
5102    /// Original spelling when a dialect has more than one native alias.
5103    pub source_name: String,
5104    #[serde(default)]
5105    pub negated: bool,
5106    pub start: Option<Expression>,
5107    pub occurrence: Option<Expression>,
5108    pub flags: Option<Expression>,
5109    pub position_after: Option<bool>,
5110}
5111
5112/// Grouping-set selection and result-delivery options.
5113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5114#[cfg_attr(feature = "bindings", derive(TS))]
5115pub struct GroupingOptions {
5116    #[serde(default, skip_serializing_if = "Option::is_none")]
5117    #[ast(skip)]
5118    pub source_dialect: Option<crate::dialects::DialectType>,
5119    pub best: Option<Expression>,
5120    pub limit: Option<Expression>,
5121    pub offset: Option<Expression>,
5122    pub subtotal: bool,
5123    pub balance: bool,
5124    pub total: bool,
5125    pub structured: bool,
5126    pub overview: bool,
5127    pub prefix: Option<Expression>,
5128    pub multiple_resultsets: bool,
5129}
5130
5131#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5132#[cfg_attr(feature = "bindings", derive(TS))]
5133pub struct ResultSerialization {
5134    /// JSON or XML, validated by the HANA parser.
5135    pub format: String,
5136    pub options: Vec<(String, String)>,
5137    #[serde(default, skip_serializing_if = "Option::is_none")]
5138    pub returning: Option<DataType>,
5139}
5140
5141/// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`).
5142///
5143/// This is the generic function node. Well-known aggregates, window functions,
5144/// and built-in functions each have their own dedicated `Expression` variants
5145/// (e.g. `Count`, `Sum`, `WindowFunction`). Functions that the parser does
5146/// not recognize as built-ins are represented with this struct.
5147#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5148#[cfg_attr(feature = "bindings", derive(TS))]
5149pub struct Function {
5150    /// Qualified name components preserve quoting without changing the node kind.
5151    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5152    pub qualified_name: Vec<Identifier>,
5153    /// Optional DEFAULT/NULL/ERROR behavior after the arguments.
5154    #[serde(default, skip_serializing_if = "Option::is_none")]
5155    pub on_error: Option<Box<SqlBehavior>>,
5156    /// Dialect whose call semantics must be retained through independent generation.
5157    #[serde(default, skip_serializing_if = "Option::is_none")]
5158    #[ast(skip)]
5159    pub source_dialect: Option<crate::dialects::DialectType>,
5160
5161    /// The function name, as originally written (may be schema-qualified).
5162    pub name: String,
5163    /// Positional arguments to the function.
5164    pub args: Vec<Expression>,
5165    /// Whether DISTINCT was specified inside the call (e.g. `COUNT(DISTINCT x)`).
5166    pub distinct: bool,
5167    #[serde(default)]
5168    pub trailing_comments: Vec<String>,
5169    /// Whether this function uses bracket syntax (e.g., MAP[keys, values])
5170    #[serde(default)]
5171    pub use_bracket_syntax: bool,
5172    /// Whether this function was called without parentheses (e.g., CURRENT_TIMESTAMP vs CURRENT_TIMESTAMP())
5173    #[serde(default)]
5174    pub no_parens: bool,
5175    /// Whether the function name was quoted (e.g., `p.d.UdF` in BigQuery)
5176    #[serde(default)]
5177    pub quoted: bool,
5178    /// Source position span
5179    #[serde(default, skip_serializing_if = "Option::is_none")]
5180    pub span: Option<Span>,
5181    /// Inferred data type from type annotation
5182    #[serde(default, skip_serializing_if = "Option::is_none")]
5183    #[ast(skip)]
5184    pub inferred_type: Option<DataType>,
5185}
5186
5187impl Default for Function {
5188    fn default() -> Self {
5189        Self {
5190            source_dialect: None,
5191            qualified_name: Vec::new(),
5192            on_error: None,
5193            name: String::new(),
5194            args: Vec::new(),
5195            distinct: false,
5196            trailing_comments: Vec::new(),
5197            use_bracket_syntax: false,
5198            no_parens: false,
5199            quoted: false,
5200            span: None,
5201            inferred_type: None,
5202        }
5203    }
5204}
5205
5206impl Function {
5207    /// Construct a call with individually quoted qualified name components.
5208    pub fn qualified(name: Vec<Identifier>, args: Vec<Expression>) -> Self {
5209        Self {
5210            name: name
5211                .iter()
5212                .map(|part| part.name.as_str())
5213                .collect::<Vec<_>>()
5214                .join("."),
5215            qualified_name: name,
5216            args,
5217            ..Default::default()
5218        }
5219    }
5220    pub fn new(name: impl Into<String>, args: Vec<Expression>) -> Self {
5221        Self {
5222            source_dialect: None,
5223            qualified_name: Vec::new(),
5224            on_error: None,
5225            name: name.into(),
5226            args,
5227            distinct: false,
5228            trailing_comments: Vec::new(),
5229            use_bracket_syntax: false,
5230            no_parens: false,
5231            quoted: false,
5232            span: None,
5233            inferred_type: None,
5234        }
5235    }
5236}
5237
5238/// Represent a named aggregate function call with optional FILTER, ORDER BY, and LIMIT.
5239///
5240/// This struct is used for aggregate function calls that are not covered by
5241/// one of the dedicated typed variants (e.g. `Count`, `Sum`). It supports
5242/// SQL:2003 FILTER (WHERE ...) clauses, ordered-set aggregates, and
5243/// IGNORE NULLS / RESPECT NULLS modifiers.
5244#[derive(
5245    polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Default, Serialize, Deserialize,
5246)]
5247#[cfg_attr(feature = "bindings", derive(TS))]
5248pub struct AggregateFunction {
5249    /// Dialect whose call semantics must be retained through independent generation.
5250    #[serde(default, skip_serializing_if = "Option::is_none")]
5251    #[ast(skip)]
5252    pub source_dialect: Option<crate::dialects::DialectType>,
5253
5254    /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG").
5255    pub name: String,
5256    /// Positional arguments.
5257    pub args: Vec<Expression>,
5258    /// Whether DISTINCT was specified.
5259    pub distinct: bool,
5260    /// Optional FILTER (WHERE ...) clause applied to the aggregate.
5261    pub filter: Option<Expression>,
5262    /// ORDER BY inside aggregate (e.g., JSON_AGG(x ORDER BY y))
5263    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5264    pub order_by: Vec<Ordered>,
5265    /// LIMIT inside aggregate (e.g., ARRAY_CONCAT_AGG(x LIMIT 2))
5266    #[serde(default, skip_serializing_if = "Option::is_none")]
5267    pub limit: Option<Box<Expression>>,
5268    /// IGNORE NULLS / RESPECT NULLS
5269    #[serde(default, skip_serializing_if = "Option::is_none")]
5270    pub ignore_nulls: Option<bool>,
5271    /// Inferred data type from type annotation
5272    #[serde(default, skip_serializing_if = "Option::is_none")]
5273    #[ast(skip)]
5274    pub inferred_type: Option<DataType>,
5275}
5276
5277/// Represent a window function call with its OVER clause.
5278///
5279/// The inner `this` expression is typically a window-specific expression
5280/// (e.g. `RowNumber`, `Rank`, `Lead`) or an aggregate used as a window
5281/// function.  The `over` field carries the PARTITION BY, ORDER BY, and
5282/// frame specification.
5283#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5284#[cfg_attr(feature = "bindings", derive(TS))]
5285pub struct WindowFunction {
5286    /// The function expression (e.g. ROW_NUMBER(), SUM(amount)).
5287    pub this: Expression,
5288    /// The OVER clause defining the window partitioning, ordering, and frame.
5289    pub over: Over,
5290    /// Oracle KEEP clause: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...)
5291    #[serde(default, skip_serializing_if = "Option::is_none")]
5292    pub keep: Option<Keep>,
5293    /// Inferred data type from type annotation
5294    #[serde(default, skip_serializing_if = "Option::is_none")]
5295    #[ast(skip)]
5296    pub inferred_type: Option<DataType>,
5297}
5298
5299/// Oracle KEEP clause for aggregate functions
5300/// Syntax: aggregate_function KEEP (DENSE_RANK FIRST|LAST ORDER BY column [ASC|DESC])
5301#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5302#[cfg_attr(feature = "bindings", derive(TS))]
5303pub struct Keep {
5304    /// true = FIRST, false = LAST
5305    pub first: bool,
5306    /// ORDER BY clause inside KEEP
5307    pub order_by: Vec<Ordered>,
5308}
5309
5310/// WITHIN GROUP clause (for ordered-set aggregate functions)
5311#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5312#[cfg_attr(feature = "bindings", derive(TS))]
5313pub struct WithinGroup {
5314    /// The aggregate function (LISTAGG, PERCENTILE_CONT, etc.)
5315    pub this: Expression,
5316    /// The ORDER BY clause within the group
5317    pub order_by: Vec<Ordered>,
5318}
5319
5320/// Represent the FROM clause of a SELECT statement.
5321///
5322/// Contains one or more table sources (tables, subqueries, table-valued
5323/// functions, etc.). Multiple entries represent comma-separated implicit joins.
5324#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5325#[cfg_attr(feature = "bindings", derive(TS))]
5326pub struct From {
5327    /// The table source expressions.
5328    pub expressions: Vec<Expression>,
5329}
5330
5331/// Represent a JOIN clause between two table sources.
5332///
5333/// The join condition can be specified via `on` (ON predicate) or `using`
5334/// (USING column list), but not both. The `kind` field determines the join
5335/// type (INNER, LEFT, CROSS, etc.).
5336#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5337#[cfg_attr(feature = "bindings", derive(TS))]
5338pub struct Join {
5339    /// The right-hand table expression being joined.
5340    pub this: Expression,
5341    /// The ON condition (mutually exclusive with `using`).
5342    pub on: Option<Expression>,
5343    /// The USING column list (mutually exclusive with `on`).
5344    pub using: Vec<Identifier>,
5345    /// The join type (INNER, LEFT, RIGHT, FULL, CROSS, etc.).
5346    pub kind: JoinKind,
5347    /// Whether INNER keyword was explicitly used (INNER JOIN vs JOIN)
5348    pub use_inner_keyword: bool,
5349    /// Whether OUTER keyword was explicitly used (LEFT OUTER JOIN vs LEFT JOIN)
5350    pub use_outer_keyword: bool,
5351    /// Whether the ON/USING condition was deferred (assigned right-to-left for chained JOINs)
5352    pub deferred_condition: bool,
5353    /// TSQL join hint: LOOP, HASH, MERGE (e.g., INNER LOOP JOIN)
5354    #[serde(default, skip_serializing_if = "Option::is_none")]
5355    pub join_hint: Option<String>,
5356    /// Snowflake ASOF JOIN match condition (MATCH_CONDITION clause)
5357    #[serde(default, skip_serializing_if = "Option::is_none")]
5358    pub match_condition: Option<Expression>,
5359    /// PIVOT/UNPIVOT operations that follow this join (Oracle/TSQL syntax)
5360    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5361    pub pivots: Vec<Expression>,
5362    /// Comments collected between join-kind keywords (for example `INNER <comment> JOIN`)
5363    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5364    pub comments: Vec<String>,
5365    /// Nesting group identifier for nested join pretty-printing.
5366    /// Joins in the same group were parsed together; group boundaries come from
5367    /// deferred condition resolution phases.
5368    #[serde(default)]
5369    pub nesting_group: usize,
5370    /// Snowflake: DIRECTED keyword in JOIN (e.g., CROSS DIRECTED JOIN)
5371    #[serde(default)]
5372    pub directed: bool,
5373}
5374
5375/// Enumerate all supported SQL join types.
5376///
5377/// Covers the standard join types (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL)
5378/// as well as dialect-specific variants: SEMI/ANTI joins, LATERAL joins,
5379/// CROSS/OUTER APPLY (TSQL), ASOF joins (DuckDB/Snowflake), ARRAY joins
5380/// (ClickHouse), STRAIGHT_JOIN (MySQL), and implicit comma-joins.
5381#[derive(
5382    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5383)]
5384#[cfg_attr(feature = "bindings", derive(TS))]
5385pub enum JoinKind {
5386    Inner,
5387    Left,
5388    Right,
5389    Full,
5390    Outer, // Standalone OUTER JOIN (without LEFT/RIGHT/FULL)
5391    Cross,
5392    Natural,
5393    NaturalLeft,
5394    NaturalRight,
5395    NaturalFull,
5396    Semi,
5397    Anti,
5398    // Directional SEMI/ANTI joins
5399    LeftSemi,
5400    LeftAnti,
5401    RightSemi,
5402    RightAnti,
5403    // SQL Server specific
5404    CrossApply,
5405    OuterApply,
5406    // Time-series specific
5407    AsOf,
5408    AsOfLeft,
5409    AsOfRight,
5410    // Lateral join
5411    Lateral,
5412    LeftLateral,
5413    // MySQL specific
5414    Straight,
5415    // Implicit join (comma-separated tables: FROM a, b)
5416    Implicit,
5417    // ClickHouse ARRAY JOIN
5418    Array,
5419    LeftArray,
5420    // ClickHouse PASTE JOIN (positional join)
5421    Paste,
5422    // DuckDB POSITIONAL JOIN
5423    Positional,
5424}
5425
5426impl Default for JoinKind {
5427    fn default() -> Self {
5428        JoinKind::Inner
5429    }
5430}
5431
5432/// Parenthesized table expression with joins
5433/// Represents: (tbl1 CROSS JOIN tbl2) or ((SELECT 1) CROSS JOIN (SELECT 2))
5434#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5435#[cfg_attr(feature = "bindings", derive(TS))]
5436pub struct JoinedTable {
5437    /// The left-hand side table expression
5438    pub left: Expression,
5439    /// The joins applied to the left table
5440    pub joins: Vec<Join>,
5441    /// LATERAL VIEW clauses (Hive/Spark)
5442    pub lateral_views: Vec<LateralView>,
5443    /// Optional alias for the joined table expression
5444    pub alias: Option<Identifier>,
5445}
5446
5447/// Represent a WHERE clause containing a boolean filter predicate.
5448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5449#[cfg_attr(feature = "bindings", derive(TS))]
5450pub struct Where {
5451    /// The filter predicate expression.
5452    pub this: Expression,
5453}
5454
5455/// Represent a GROUP BY clause with optional ALL/DISTINCT and WITH TOTALS modifiers.
5456///
5457/// The `expressions` list may contain plain columns, ordinal positions,
5458/// ROLLUP/CUBE/GROUPING SETS expressions, or the special empty-set `()`.
5459#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5460#[cfg_attr(feature = "bindings", derive(TS))]
5461pub struct GroupBy {
5462    /// The grouping expressions.
5463    pub expressions: Vec<Expression>,
5464    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
5465    #[serde(default)]
5466    pub all: Option<bool>,
5467    /// ClickHouse: WITH TOTALS modifier
5468    #[serde(default)]
5469    pub totals: bool,
5470    /// Leading comments that appeared before the GROUP BY keyword
5471    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5472    pub comments: Vec<String>,
5473}
5474
5475/// Represent a HAVING clause containing a predicate over aggregate results.
5476#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5477#[cfg_attr(feature = "bindings", derive(TS))]
5478pub struct Having {
5479    /// The filter predicate, typically involving aggregate functions.
5480    pub this: Expression,
5481    /// Leading comments that appeared before the HAVING keyword
5482    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5483    pub comments: Vec<String>,
5484}
5485
5486/// Represent an ORDER BY clause containing one or more sort specifications.
5487#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5488#[cfg_attr(feature = "bindings", derive(TS))]
5489pub struct OrderBy {
5490    /// The sort specifications, each with direction and null ordering.
5491    pub expressions: Vec<Ordered>,
5492    /// Whether this is ORDER SIBLINGS BY (Oracle hierarchical queries)
5493    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5494    pub siblings: bool,
5495    /// Leading comments that appeared before the ORDER BY keyword
5496    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5497    pub comments: Vec<String>,
5498}
5499
5500/// Represent an expression with sort direction and null ordering.
5501///
5502/// Used inside ORDER BY clauses, window frame ORDER BY, and index definitions.
5503/// When `desc` is false the sort is ascending. The `nulls_first` field
5504/// controls the NULLS FIRST / NULLS LAST modifier; `None` means unspecified
5505/// (database default).
5506#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5507#[cfg_attr(feature = "bindings", derive(TS))]
5508pub struct Ordered {
5509    /// Vertica lets the engine select null placement for aggregate/window ordering.
5510    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5511    pub nulls_auto: bool,
5512    /// The expression to sort by.
5513    pub this: Expression,
5514    /// Whether the sort direction is descending (true) or ascending (false).
5515    pub desc: bool,
5516    /// `Some(true)` = NULLS FIRST, `Some(false)` = NULLS LAST, `None` = unspecified.
5517    pub nulls_first: Option<bool>,
5518    /// Whether ASC was explicitly written (not just implied)
5519    #[serde(default)]
5520    pub explicit_asc: bool,
5521    /// ClickHouse WITH FILL clause
5522    #[serde(default, skip_serializing_if = "Option::is_none")]
5523    pub with_fill: Option<Box<WithFill>>,
5524}
5525
5526impl Ordered {
5527    pub fn asc(expr: Expression) -> Self {
5528        Self {
5529            nulls_auto: false,
5530            this: expr,
5531            desc: false,
5532            nulls_first: None,
5533            explicit_asc: false,
5534            with_fill: None,
5535        }
5536    }
5537
5538    pub fn desc(expr: Expression) -> Self {
5539        Self {
5540            nulls_auto: false,
5541            this: expr,
5542            desc: true,
5543            nulls_first: None,
5544            explicit_asc: false,
5545            with_fill: None,
5546        }
5547    }
5548}
5549
5550/// DISTRIBUTE BY clause (Hive/Spark)
5551/// Controls how rows are distributed across reducers
5552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5553#[cfg_attr(feature = "bindings", derive(TS))]
5554#[cfg_attr(feature = "bindings", ts(export))]
5555pub struct DistributeBy {
5556    pub expressions: Vec<Expression>,
5557}
5558
5559/// CLUSTER BY clause (Hive/Spark)
5560/// Combines DISTRIBUTE BY and SORT BY on the same columns
5561#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5562#[cfg_attr(feature = "bindings", derive(TS))]
5563#[cfg_attr(feature = "bindings", ts(export))]
5564pub struct ClusterBy {
5565    pub expressions: Vec<Ordered>,
5566}
5567
5568/// SORT BY clause (Hive/Spark)
5569/// Sorts data within each reducer (local sort, not global)
5570#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5571#[cfg_attr(feature = "bindings", derive(TS))]
5572#[cfg_attr(feature = "bindings", ts(export))]
5573pub struct SortBy {
5574    pub expressions: Vec<Ordered>,
5575}
5576
5577/// LATERAL VIEW clause (Hive/Spark)
5578/// Used for unnesting arrays/maps with EXPLODE, POSEXPLODE, etc.
5579#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5580#[cfg_attr(feature = "bindings", derive(TS))]
5581#[cfg_attr(feature = "bindings", ts(export))]
5582pub struct LateralView {
5583    /// The table-generating function (EXPLODE, POSEXPLODE, etc.)
5584    pub this: Expression,
5585    /// Table alias for the generated table
5586    pub table_alias: Option<Identifier>,
5587    /// Column aliases for the generated columns
5588    pub column_aliases: Vec<Identifier>,
5589    /// OUTER keyword - preserve nulls when input is empty/null
5590    pub outer: bool,
5591}
5592
5593/// Query hint
5594#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5595#[cfg_attr(feature = "bindings", derive(TS))]
5596#[cfg_attr(feature = "bindings", ts(export))]
5597pub struct Hint {
5598    #[serde(default, skip_serializing_if = "Option::is_none")]
5599    #[ast(skip)]
5600    pub source_dialect: Option<crate::dialects::DialectType>,
5601    pub expressions: Vec<HintExpression>,
5602}
5603
5604/// Individual hint expression
5605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5606#[cfg_attr(feature = "bindings", derive(TS))]
5607#[cfg_attr(feature = "bindings", ts(export))]
5608pub enum HintExpression {
5609    /// A structured hint directive with optional execution scope modifiers.
5610    Directive {
5611        name: Identifier,
5612        arguments: Option<Vec<Expression>>,
5613        remote: bool,
5614        cascade: bool,
5615    },
5616    /// Function-style hint: USE_HASH(table)
5617    Function { name: String, args: Vec<Expression> },
5618    /// Simple identifier hint: PARALLEL
5619    Identifier(String),
5620    /// Raw hint text (unparsed)
5621    Raw(String),
5622}
5623
5624/// Pseudocolumn type
5625#[derive(
5626    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5627)]
5628#[cfg_attr(feature = "bindings", derive(TS))]
5629#[cfg_attr(feature = "bindings", ts(export))]
5630pub enum PseudocolumnType {
5631    Rownum,      // Oracle ROWNUM
5632    Rowid,       // Oracle ROWID
5633    Level,       // Oracle LEVEL (for CONNECT BY)
5634    Sysdate,     // Oracle SYSDATE
5635    ObjectId,    // Oracle OBJECT_ID
5636    ObjectValue, // Oracle OBJECT_VALUE
5637}
5638
5639impl PseudocolumnType {
5640    pub fn as_str(&self) -> &'static str {
5641        match self {
5642            PseudocolumnType::Rownum => "ROWNUM",
5643            PseudocolumnType::Rowid => "ROWID",
5644            PseudocolumnType::Level => "LEVEL",
5645            PseudocolumnType::Sysdate => "SYSDATE",
5646            PseudocolumnType::ObjectId => "OBJECT_ID",
5647            PseudocolumnType::ObjectValue => "OBJECT_VALUE",
5648        }
5649    }
5650
5651    pub fn from_str(s: &str) -> Option<Self> {
5652        match s.to_uppercase().as_str() {
5653            "ROWNUM" => Some(PseudocolumnType::Rownum),
5654            "ROWID" => Some(PseudocolumnType::Rowid),
5655            "LEVEL" => Some(PseudocolumnType::Level),
5656            "SYSDATE" => Some(PseudocolumnType::Sysdate),
5657            "OBJECT_ID" => Some(PseudocolumnType::ObjectId),
5658            "OBJECT_VALUE" => Some(PseudocolumnType::ObjectValue),
5659            _ => None,
5660        }
5661    }
5662}
5663
5664/// Pseudocolumn expression (Oracle ROWNUM, ROWID, LEVEL, etc.)
5665/// These are special identifiers that should not be quoted
5666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5667#[cfg_attr(feature = "bindings", derive(TS))]
5668#[cfg_attr(feature = "bindings", ts(export))]
5669pub struct Pseudocolumn {
5670    pub kind: PseudocolumnType,
5671}
5672
5673impl Pseudocolumn {
5674    pub fn rownum() -> Self {
5675        Self {
5676            kind: PseudocolumnType::Rownum,
5677        }
5678    }
5679
5680    pub fn rowid() -> Self {
5681        Self {
5682            kind: PseudocolumnType::Rowid,
5683        }
5684    }
5685
5686    pub fn level() -> Self {
5687        Self {
5688            kind: PseudocolumnType::Level,
5689        }
5690    }
5691}
5692
5693/// Oracle CONNECT BY clause for hierarchical queries
5694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5695#[cfg_attr(feature = "bindings", derive(TS))]
5696#[cfg_attr(feature = "bindings", ts(export))]
5697pub struct Connect {
5698    /// START WITH condition (optional, can come before or after CONNECT BY)
5699    pub start: Option<Expression>,
5700    /// CONNECT BY condition (required, contains PRIOR references)
5701    pub connect: Expression,
5702    /// NOCYCLE keyword to prevent infinite loops
5703    pub nocycle: bool,
5704}
5705
5706/// Oracle PRIOR expression - references parent row's value in CONNECT BY
5707#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5708#[cfg_attr(feature = "bindings", derive(TS))]
5709#[cfg_attr(feature = "bindings", ts(export))]
5710pub struct Prior {
5711    pub this: Expression,
5712}
5713
5714/// Oracle CONNECT_BY_ROOT function - returns root row's column value
5715#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5716#[cfg_attr(feature = "bindings", derive(TS))]
5717#[cfg_attr(feature = "bindings", ts(export))]
5718pub struct ConnectByRoot {
5719    pub this: Expression,
5720}
5721
5722/// MATCH_RECOGNIZE clause for row pattern matching (Oracle/Snowflake/Presto/Trino)
5723#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5724#[cfg_attr(feature = "bindings", derive(TS))]
5725#[cfg_attr(feature = "bindings", ts(export))]
5726pub struct MatchRecognize {
5727    /// Source table/expression
5728    pub this: Option<Box<Expression>>,
5729    /// PARTITION BY expressions
5730    pub partition_by: Option<Vec<Expression>>,
5731    /// ORDER BY expressions
5732    pub order_by: Option<Vec<Ordered>>,
5733    /// MEASURES definitions
5734    pub measures: Option<Vec<MatchRecognizeMeasure>>,
5735    /// Row semantics (ONE ROW PER MATCH, ALL ROWS PER MATCH, etc.)
5736    pub rows: Option<MatchRecognizeRows>,
5737    /// AFTER MATCH SKIP behavior
5738    pub after: Option<MatchRecognizeAfter>,
5739    /// PATTERN definition (stored as raw string for complex regex patterns)
5740    pub pattern: Option<String>,
5741    /// DEFINE clauses (pattern variable definitions)
5742    pub define: Option<Vec<(Identifier, Expression)>>,
5743    /// Optional alias for the result
5744    pub alias: Option<Identifier>,
5745    /// Whether AS keyword was explicitly present before alias
5746    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5747    pub alias_explicit_as: bool,
5748}
5749
5750/// MEASURES expression with optional RUNNING/FINAL semantics
5751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5752#[cfg_attr(feature = "bindings", derive(TS))]
5753#[cfg_attr(feature = "bindings", ts(export))]
5754pub struct MatchRecognizeMeasure {
5755    /// The measure expression
5756    pub this: Expression,
5757    /// RUNNING or FINAL semantics (Snowflake-specific)
5758    pub window_frame: Option<MatchRecognizeSemantics>,
5759}
5760
5761/// Semantics for MEASURES in MATCH_RECOGNIZE
5762#[derive(
5763    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5764)]
5765#[cfg_attr(feature = "bindings", derive(TS))]
5766#[cfg_attr(feature = "bindings", ts(export))]
5767pub enum MatchRecognizeSemantics {
5768    Running,
5769    Final,
5770}
5771
5772/// Row output semantics for MATCH_RECOGNIZE
5773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5774#[cfg_attr(feature = "bindings", derive(TS))]
5775#[cfg_attr(feature = "bindings", ts(export))]
5776pub enum MatchRecognizeRows {
5777    OneRowPerMatch,
5778    AllRowsPerMatch,
5779    AllRowsPerMatchShowEmptyMatches,
5780    AllRowsPerMatchOmitEmptyMatches,
5781    AllRowsPerMatchWithUnmatchedRows,
5782}
5783
5784/// AFTER MATCH SKIP behavior
5785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5786#[cfg_attr(feature = "bindings", derive(TS))]
5787#[cfg_attr(feature = "bindings", ts(export))]
5788pub enum MatchRecognizeAfter {
5789    PastLastRow,
5790    ToNextRow,
5791    ToFirst(Identifier),
5792    ToLast(Identifier),
5793}
5794
5795/// Represent a LIMIT clause that restricts the number of returned rows.
5796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5797#[cfg_attr(feature = "bindings", derive(TS))]
5798pub struct Limit {
5799    /// The limit count expression.
5800    pub this: Expression,
5801    /// Whether PERCENT modifier is present (DuckDB: LIMIT 10 PERCENT)
5802    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
5803    pub percent: bool,
5804    /// Comments from before the LIMIT keyword (emitted after the limit value)
5805    #[serde(default)]
5806    #[serde(skip_serializing_if = "Vec::is_empty")]
5807    pub comments: Vec<String>,
5808}
5809
5810/// OFFSET clause
5811#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5812#[cfg_attr(feature = "bindings", derive(TS))]
5813pub struct Offset {
5814    pub this: Expression,
5815    /// Whether ROW/ROWS keyword was used (SQL standard syntax)
5816    #[serde(skip_serializing_if = "Option::is_none", default)]
5817    pub rows: Option<bool>,
5818}
5819
5820/// TOP clause (SQL Server)
5821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5822#[cfg_attr(feature = "bindings", derive(TS))]
5823pub struct Top {
5824    pub this: Expression,
5825    pub percent: bool,
5826    pub with_ties: bool,
5827    /// Whether the expression was parenthesized: TOP (10) vs TOP 10
5828    #[serde(default)]
5829    pub parenthesized: bool,
5830}
5831
5832/// FETCH FIRST/NEXT clause (SQL standard)
5833#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5834#[cfg_attr(feature = "bindings", derive(TS))]
5835pub struct Fetch {
5836    /// FIRST or NEXT
5837    pub direction: String,
5838    /// Count expression (optional)
5839    pub count: Option<Expression>,
5840    /// PERCENT modifier
5841    pub percent: bool,
5842    /// ROWS or ROW keyword present
5843    pub rows: bool,
5844    /// WITH TIES modifier
5845    pub with_ties: bool,
5846}
5847
5848/// Represent a QUALIFY clause for filtering on window function results.
5849///
5850/// Supported by Snowflake, BigQuery, DuckDB, and Databricks. The predicate
5851/// typically references a window function (e.g.
5852/// `QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY ts DESC) = 1`).
5853#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5854#[cfg_attr(feature = "bindings", derive(TS))]
5855pub struct Qualify {
5856    /// The filter predicate over window function results.
5857    pub this: Expression,
5858}
5859
5860/// SAMPLE / TABLESAMPLE clause
5861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5862#[cfg_attr(feature = "bindings", derive(TS))]
5863pub struct Sample {
5864    pub method: SampleMethod,
5865    pub size: Expression,
5866    pub seed: Option<Expression>,
5867    /// ClickHouse OFFSET expression after SAMPLE size
5868    #[serde(default)]
5869    pub offset: Option<Expression>,
5870    /// Whether the unit comes after the size (e.g., "100 ROWS" vs "ROW 100")
5871    pub unit_after_size: bool,
5872    /// Whether the keyword was SAMPLE (true) or TABLESAMPLE (false)
5873    #[serde(default)]
5874    pub use_sample_keyword: bool,
5875    /// Whether the method was explicitly specified (BERNOULLI, SYSTEM, etc.)
5876    #[serde(default)]
5877    pub explicit_method: bool,
5878    /// Whether the method keyword appeared before the size (TABLESAMPLE BERNOULLI (10))
5879    #[serde(default)]
5880    pub method_before_size: bool,
5881    /// Whether SEED keyword was used (true) or REPEATABLE (false)
5882    #[serde(default)]
5883    pub use_seed_keyword: bool,
5884    /// BUCKET numerator for Hive bucket sampling (BUCKET 1 OUT OF 5)
5885    pub bucket_numerator: Option<Box<Expression>>,
5886    /// BUCKET denominator (the 5 in BUCKET 1 OUT OF 5)
5887    pub bucket_denominator: Option<Box<Expression>>,
5888    /// BUCKET field for ON clause (BUCKET 1 OUT OF 5 ON x)
5889    pub bucket_field: Option<Box<Expression>>,
5890    /// Whether this is a DuckDB USING SAMPLE clause (vs SAMPLE/TABLESAMPLE)
5891    #[serde(default)]
5892    pub is_using_sample: bool,
5893    /// Whether the unit was explicitly PERCENT (vs ROWS)
5894    #[serde(default)]
5895    pub is_percent: bool,
5896    /// Whether to suppress method output (for cross-dialect transpilation)
5897    #[serde(default)]
5898    pub suppress_method_output: bool,
5899}
5900
5901/// Sample method
5902#[derive(
5903    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
5904)]
5905#[cfg_attr(feature = "bindings", derive(TS))]
5906pub enum SampleMethod {
5907    Bernoulli,
5908    System,
5909    Block,
5910    Row,
5911    Percent,
5912    /// Hive bucket sampling
5913    Bucket,
5914    /// DuckDB reservoir sampling
5915    Reservoir,
5916}
5917
5918/// Named window definition (WINDOW w AS (...))
5919#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5920#[cfg_attr(feature = "bindings", derive(TS))]
5921pub struct NamedWindow {
5922    pub name: Identifier,
5923    pub spec: Over,
5924}
5925
5926/// Represent a WITH clause containing one or more Common Table Expressions (CTEs).
5927///
5928/// When `recursive` is true, the clause is `WITH RECURSIVE`, enabling CTEs
5929/// that reference themselves. Each CTE is defined in the `ctes` vector and
5930/// can be referenced by name in subsequent CTEs and in the main query body.
5931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5932#[cfg_attr(feature = "bindings", derive(TS))]
5933pub struct With {
5934    /// The list of CTE definitions, in order.
5935    pub ctes: Vec<Cte>,
5936    /// Whether the WITH RECURSIVE keyword was used.
5937    pub recursive: bool,
5938    /// Leading comments before the statement
5939    #[serde(default)]
5940    pub leading_comments: Vec<String>,
5941    /// SEARCH/CYCLE clause for recursive CTEs (PostgreSQL)
5942    #[serde(default, skip_serializing_if = "Option::is_none")]
5943    pub search: Option<Box<Expression>>,
5944}
5945
5946/// Represent a single Common Table Expression definition.
5947///
5948/// A CTE has a name (`alias`), an optional column list, and a body query.
5949/// The `materialized` field maps to PostgreSQL's `MATERIALIZED` /
5950/// `NOT MATERIALIZED` hints. ClickHouse supports an inverted syntax where
5951/// the expression comes before the alias (`alias_first`).
5952#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5953#[cfg_attr(feature = "bindings", derive(TS))]
5954pub struct Cte {
5955    /// The CTE name.
5956    pub alias: Identifier,
5957    /// The CTE body (typically a SELECT, UNION, etc.).
5958    pub this: Expression,
5959    /// Optional column alias list: `cte_name(c1, c2) AS (...)`.
5960    pub columns: Vec<Identifier>,
5961    /// `Some(true)` = MATERIALIZED, `Some(false)` = NOT MATERIALIZED, `None` = unspecified.
5962    pub materialized: Option<bool>,
5963    /// USING KEY (columns) for DuckDB recursive CTEs
5964    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5965    pub key_expressions: Vec<Identifier>,
5966    /// ClickHouse supports expression-first WITH items: WITH <expr> AS <alias>
5967    #[serde(default)]
5968    pub alias_first: bool,
5969    /// Comments associated with this CTE (placed after alias name, before AS)
5970    #[serde(default, skip_serializing_if = "Vec::is_empty")]
5971    pub comments: Vec<String>,
5972}
5973
5974/// Window specification
5975#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5976#[cfg_attr(feature = "bindings", derive(TS))]
5977pub struct WindowSpec {
5978    pub partition_by: Vec<Expression>,
5979    pub order_by: Vec<Ordered>,
5980    pub frame: Option<WindowFrame>,
5981}
5982
5983/// OVER clause
5984#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5985#[cfg_attr(feature = "bindings", derive(TS))]
5986pub struct Over {
5987    /// Named window reference (e.g., OVER w or OVER (w ORDER BY x))
5988    pub window_name: Option<Identifier>,
5989    pub partition_by: Vec<Expression>,
5990    pub order_by: Vec<Ordered>,
5991    pub frame: Option<WindowFrame>,
5992    pub alias: Option<Identifier>,
5993}
5994
5995/// Window frame
5996#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
5997#[cfg_attr(feature = "bindings", derive(TS))]
5998pub struct WindowFrame {
5999    pub kind: WindowFrameKind,
6000    pub start: WindowFrameBound,
6001    pub end: Option<WindowFrameBound>,
6002    pub exclude: Option<WindowFrameExclude>,
6003    /// Original text of the frame kind keyword (preserves input case, e.g. "range")
6004    #[serde(default, skip_serializing_if = "Option::is_none")]
6005    pub kind_text: Option<String>,
6006    /// Original text of the start bound side keyword (e.g. "preceding")
6007    #[serde(default, skip_serializing_if = "Option::is_none")]
6008    pub start_side_text: Option<String>,
6009    /// Original text of the end bound side keyword
6010    #[serde(default, skip_serializing_if = "Option::is_none")]
6011    pub end_side_text: Option<String>,
6012}
6013
6014#[derive(
6015    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6016)]
6017#[cfg_attr(feature = "bindings", derive(TS))]
6018pub enum WindowFrameKind {
6019    Rows,
6020    Range,
6021    Groups,
6022}
6023
6024/// EXCLUDE clause for window frames
6025#[derive(
6026    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6027)]
6028#[cfg_attr(feature = "bindings", derive(TS))]
6029pub enum WindowFrameExclude {
6030    CurrentRow,
6031    Group,
6032    Ties,
6033    NoOthers,
6034}
6035
6036#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6037#[cfg_attr(feature = "bindings", derive(TS))]
6038pub enum WindowFrameBound {
6039    CurrentRow,
6040    UnboundedPreceding,
6041    UnboundedFollowing,
6042    Preceding(Box<Expression>),
6043    Following(Box<Expression>),
6044    /// Bare PRECEDING without value (inverted syntax: just "PRECEDING")
6045    BarePreceding,
6046    /// Bare FOLLOWING without value (inverted syntax: just "FOLLOWING")
6047    BareFollowing,
6048    /// Bare numeric bound without PRECEDING/FOLLOWING (e.g., RANGE BETWEEN 1 AND 3)
6049    Value(Box<Expression>),
6050}
6051
6052/// Struct field with optional OPTIONS clause (BigQuery) and COMMENT (Spark/Databricks)
6053#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6054#[cfg_attr(feature = "bindings", derive(TS))]
6055pub struct StructField {
6056    /// A raw field name, or a delimited identifier for compatibility with parsed ASTs.
6057    /// Parsed quoted names use double quotes with doubled internal quotes. An empty
6058    /// string denotes an anonymous field. Generation selects the target dialect's quotes.
6059    pub name: String,
6060    pub data_type: DataType,
6061    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6062    pub options: Vec<Expression>,
6063    #[serde(default, skip_serializing_if = "Option::is_none")]
6064    pub comment: Option<String>,
6065}
6066
6067impl StructField {
6068    /// Create a new struct field without options
6069    pub fn new(name: String, data_type: DataType) -> Self {
6070        Self {
6071            name,
6072            data_type,
6073            options: Vec::new(),
6074            comment: None,
6075        }
6076    }
6077
6078    /// Create a new struct field with options
6079    pub fn with_options(name: String, data_type: DataType, options: Vec<Expression>) -> Self {
6080        Self {
6081            name,
6082            data_type,
6083            options,
6084            comment: None,
6085        }
6086    }
6087
6088    /// Create a new struct field with options and comment
6089    pub fn with_options_and_comment(
6090        name: String,
6091        data_type: DataType,
6092        options: Vec<Expression>,
6093        comment: Option<String>,
6094    ) -> Self {
6095        Self {
6096            name,
6097            data_type,
6098            options,
6099            comment,
6100        }
6101    }
6102}
6103
6104/// Oracle-specific data types whose semantics cannot be represented losslessly by the
6105/// generic [`DataType`] variants.
6106///
6107/// Keeping these types structured allows the Oracle parser to retain details such as a
6108/// negative `NUMBER` scale, `BYTE`/`CHAR` length semantics, interval precisions, and
6109/// `TIMESTAMP WITH LOCAL TIME ZONE` until the target dialect is known.
6110#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6111#[cfg_attr(feature = "bindings", derive(TS))]
6112#[serde(tag = "oracle_data_type", rename_all = "snake_case")]
6113pub enum OracleDataType {
6114    Number {
6115        precision: Option<u32>,
6116        scale: Option<i32>,
6117    },
6118    BinaryFloat,
6119    BinaryDouble,
6120    Float {
6121        precision: Option<u32>,
6122    },
6123    Character {
6124        kind: OracleCharacterKind,
6125        length: Option<u32>,
6126        semantics: Option<OracleCharacterLengthSemantics>,
6127    },
6128    Date,
6129    Timestamp {
6130        precision: Option<u32>,
6131        timezone: OracleTimestampTimeZone,
6132    },
6133    IntervalYearToMonth {
6134        year_precision: Option<u32>,
6135    },
6136    IntervalDayToSecond {
6137        day_precision: Option<u32>,
6138        fractional_seconds_precision: Option<u32>,
6139    },
6140    Clob {
6141        national: bool,
6142    },
6143    Blob,
6144    Raw {
6145        length: Option<u32>,
6146    },
6147    Long {
6148        raw: bool,
6149    },
6150    RowId,
6151}
6152
6153#[derive(
6154    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6155)]
6156#[cfg_attr(feature = "bindings", derive(TS))]
6157#[serde(rename_all = "snake_case")]
6158pub enum OracleCharacterKind {
6159    Char,
6160    VarChar,
6161    NChar,
6162    NVarChar,
6163}
6164
6165#[derive(
6166    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6167)]
6168#[cfg_attr(feature = "bindings", derive(TS))]
6169#[serde(rename_all = "snake_case")]
6170pub enum OracleCharacterLengthSemantics {
6171    Byte,
6172    Char,
6173}
6174
6175#[derive(
6176    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6177)]
6178#[cfg_attr(feature = "bindings", derive(TS))]
6179#[serde(rename_all = "snake_case")]
6180pub enum OracleTimestampTimeZone {
6181    None,
6182    WithTimeZone,
6183    WithLocalTimeZone,
6184}
6185
6186/// Enumerate all SQL data types recognized by the parser.
6187///
6188/// Covers standard SQL types (BOOLEAN, INT, VARCHAR, TIMESTAMP, etc.) as well
6189/// as dialect-specific types (JSONB, VECTOR, OBJECT, etc.). Parametric types
6190/// like ARRAY, MAP, and STRUCT are represented with nested [`DataType`] fields.
6191///
6192/// This enum is used in CAST expressions, column definitions, function return
6193/// types, and anywhere a data type specification appears in SQL.
6194///
6195/// Types that do not match any known variant fall through to `Custom { name }`,
6196/// preserving the original type name for round-trip fidelity.
6197#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6198#[cfg_attr(feature = "bindings", derive(TS))]
6199#[serde(tag = "data_type", rename_all = "snake_case")]
6200pub enum DataType {
6201    Vertica {
6202        vertica_type: Box<VerticaDataType>,
6203    },
6204    // Numeric
6205    Boolean,
6206    TinyInt {
6207        length: Option<u32>,
6208    },
6209    SmallInt {
6210        length: Option<u32>,
6211    },
6212    /// Int type with optional length. `integer_spelling` indicates whether the original
6213    /// type was spelled as `INTEGER` (true) vs `INT` (false), used for certain dialects
6214    /// like Databricks that preserve the original spelling in specific contexts (e.g., ?:: syntax).
6215    Int {
6216        length: Option<u32>,
6217        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6218        integer_spelling: bool,
6219    },
6220    BigInt {
6221        length: Option<u32>,
6222    },
6223    /// Signed 128-bit integer (DuckDB HUGEINT, ClickHouse Int128, StarRocks LARGEINT).
6224    Int128,
6225    /// Unsigned 8-bit integer (DuckDB UTINYINT, ClickHouse UInt8).
6226    #[serde(rename = "uint8")]
6227    UInt8,
6228    /// Unsigned 16-bit integer (DuckDB USMALLINT, ClickHouse UInt16).
6229    #[serde(rename = "uint16")]
6230    UInt16,
6231    /// Unsigned 32-bit integer (DuckDB UINTEGER, ClickHouse UInt32).
6232    #[serde(rename = "uint32")]
6233    UInt32,
6234    /// Unsigned 64-bit integer (DuckDB UBIGINT, ClickHouse UInt64).
6235    #[serde(rename = "uint64")]
6236    UInt64,
6237    /// Unsigned 128-bit integer (DuckDB UHUGEINT, ClickHouse UInt128).
6238    #[serde(rename = "uint128")]
6239    UInt128,
6240    /// Float type with optional precision and scale. `real_spelling` indicates whether the original
6241    /// type was spelled as `REAL` (true) vs `FLOAT` (false), used for dialects like Redshift that
6242    /// preserve the original spelling.
6243    Float {
6244        precision: Option<u32>,
6245        scale: Option<u32>,
6246        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6247        real_spelling: bool,
6248    },
6249    Double {
6250        precision: Option<u32>,
6251        scale: Option<u32>,
6252    },
6253    Decimal {
6254        precision: Option<u32>,
6255        scale: Option<u32>,
6256    },
6257    /// Structured Oracle data type retained until the target dialect is known.
6258    Oracle {
6259        oracle_type: OracleDataType,
6260    },
6261
6262    /// A HANA type whose domain or syntax is not represented by a common type.
6263    Hana {
6264        hana_type: HanaDataType,
6265    },
6266
6267    // String
6268    Char {
6269        length: Option<u32>,
6270    },
6271    /// VarChar type with optional length. `parenthesized_length` indicates whether the length
6272    /// was wrapped in extra parentheses (Hive: `VARCHAR((50))` inside STRUCT definitions).
6273    VarChar {
6274        length: Option<u32>,
6275        #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6276        parenthesized_length: bool,
6277    },
6278    /// String type with optional max length (BigQuery STRING(n))
6279    String {
6280        length: Option<u32>,
6281    },
6282    Text,
6283    /// TEXT with optional length: TEXT(n) - used by MySQL, SQLite, DuckDB, etc.
6284    TextWithLength {
6285        length: u32,
6286    },
6287
6288    // Binary
6289    Binary {
6290        length: Option<u32>,
6291    },
6292    VarBinary {
6293        length: Option<u32>,
6294    },
6295    Blob,
6296
6297    // Bit
6298    Bit {
6299        length: Option<u32>,
6300    },
6301    VarBit {
6302        length: Option<u32>,
6303    },
6304
6305    // Date/Time
6306    Date,
6307    Time {
6308        precision: Option<u32>,
6309        #[serde(default)]
6310        timezone: bool,
6311    },
6312    Timestamp {
6313        precision: Option<u32>,
6314        timezone: bool,
6315    },
6316    Interval {
6317        unit: Option<String>,
6318        /// For range intervals like INTERVAL DAY TO HOUR
6319        #[serde(default, skip_serializing_if = "Option::is_none")]
6320        to: Option<String>,
6321    },
6322
6323    // JSON
6324    Json,
6325    JsonB,
6326
6327    // UUID
6328    Uuid,
6329
6330    // Array
6331    Array {
6332        element_type: Box<DataType>,
6333        /// Optional dimension size for PostgreSQL (e.g., [3] in INT[3])
6334        #[serde(default, skip_serializing_if = "Option::is_none")]
6335        dimension: Option<u32>,
6336    },
6337
6338    /// List type (Materialize): INT LIST, TEXT LIST LIST
6339    /// Uses postfix LIST syntax instead of ARRAY<T>
6340    List {
6341        element_type: Box<DataType>,
6342    },
6343
6344    // Struct/Map
6345    // nested: true means parenthesized syntax STRUCT(name TYPE, ...) (DuckDB/Presto/ROW)
6346    // nested: false means angle-bracket syntax STRUCT<name TYPE, ...> (BigQuery)
6347    Struct {
6348        fields: Vec<StructField>,
6349        nested: bool,
6350    },
6351    Map {
6352        key_type: Box<DataType>,
6353        value_type: Box<DataType>,
6354    },
6355
6356    // Enum type (DuckDB): ENUM('RED', 'GREEN', 'BLUE')
6357    Enum {
6358        values: Vec<String>,
6359        #[serde(default, skip_serializing_if = "Vec::is_empty")]
6360        assignments: Vec<Option<String>>,
6361    },
6362
6363    // Set type (MySQL): SET('a', 'b', 'c')
6364    Set {
6365        values: Vec<String>,
6366    },
6367
6368    // Union type (DuckDB): UNION(num INT, str TEXT)
6369    Union {
6370        fields: Vec<(String, DataType)>,
6371    },
6372
6373    // Vector (Snowflake / SingleStore)
6374    Vector {
6375        #[serde(default)]
6376        element_type: Option<Box<DataType>>,
6377        dimension: Option<u32>,
6378    },
6379
6380    // Object (Snowflake structured type)
6381    // fields: Vec of (field_name, field_type, not_null)
6382    Object {
6383        fields: Vec<(String, DataType, bool)>,
6384        modifier: Option<String>,
6385    },
6386
6387    // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
6388    Nullable {
6389        inner: Box<DataType>,
6390    },
6391
6392    // Custom/User-defined
6393    Custom {
6394        name: String,
6395    },
6396
6397    // Spatial types
6398    Geometry {
6399        subtype: Option<String>,
6400        srid: Option<u32>,
6401    },
6402    Geography {
6403        subtype: Option<String>,
6404        srid: Option<u32>,
6405    },
6406
6407    // Character Set (for CONVERT USING in MySQL)
6408    // Renders as CHAR CHARACTER SET {name} in cast target
6409    CharacterSet {
6410        name: String,
6411    },
6412
6413    // Unknown
6414    Unknown,
6415}
6416
6417/// Source-specific HANA type, retained until a target is selected.
6418#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6419#[cfg_attr(feature = "bindings", derive(TS))]
6420pub struct HanaDataType {
6421    pub name: String,
6422    pub parameters: Vec<u32>,
6423}
6424
6425impl DataType {
6426    /// Canonical unsigned names and their bit-width aliases. Parser entry points
6427    /// and legacy Custom-type normalization share this mapping.
6428    pub(crate) fn from_unsigned_name(name: &str) -> Option<Self> {
6429        match name.to_ascii_uppercase().as_str() {
6430            "UTINYINT" | "UINT8" => Some(Self::UInt8),
6431            "USMALLINT" | "UINT16" => Some(Self::UInt16),
6432            "UINTEGER" | "UINT32" => Some(Self::UInt32),
6433            "UBIGINT" | "UINT64" => Some(Self::UInt64),
6434            "UHUGEINT" | "UINT128" => Some(Self::UInt128),
6435            _ => None,
6436        }
6437    }
6438}
6439
6440/// Array expression
6441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6442#[cfg_attr(feature = "bindings", derive(TS))]
6443#[cfg_attr(feature = "bindings", ts(rename = "SqlArray"))]
6444pub struct Array {
6445    pub expressions: Vec<Expression>,
6446    /// Inferred array data type from type annotation
6447    #[serde(default, skip_serializing_if = "Option::is_none")]
6448    #[ast(skip)]
6449    pub inferred_type: Option<DataType>,
6450}
6451
6452/// Struct expression
6453#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6454#[cfg_attr(feature = "bindings", derive(TS))]
6455pub struct Struct {
6456    pub fields: Vec<(Option<String>, Expression)>,
6457}
6458
6459/// Tuple expression
6460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6461#[cfg_attr(feature = "bindings", derive(TS))]
6462pub struct Tuple {
6463    pub expressions: Vec<Expression>,
6464}
6465
6466/// Interval expression
6467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6468#[cfg_attr(feature = "bindings", derive(TS))]
6469pub struct Interval {
6470    /// The value expression (e.g., '1', 5, column_ref)
6471    pub this: Option<Expression>,
6472    /// The unit specification (optional - can be None, a simple unit, a span, or an expression)
6473    pub unit: Option<IntervalUnitSpec>,
6474}
6475
6476/// Specification for interval unit - can be a simple unit, a span (HOUR TO SECOND), or an expression
6477#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6478#[cfg_attr(feature = "bindings", derive(TS))]
6479#[serde(tag = "type", rename_all = "snake_case")]
6480pub enum IntervalUnitSpec {
6481    /// Simple interval unit (YEAR, MONTH, DAY, etc.)
6482    Simple {
6483        unit: IntervalUnit,
6484        /// Whether to use plural form (e.g., DAYS vs DAY)
6485        use_plural: bool,
6486    },
6487    /// Interval span (e.g., HOUR TO SECOND)
6488    Span(IntervalSpan),
6489    /// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6490    /// The start and end can be expressions like function calls with precision
6491    ExprSpan(IntervalSpanExpr),
6492    /// Expression as unit (e.g., CURRENT_DATE, CAST(GETDATE() AS DATE))
6493    Expr(Box<Expression>),
6494}
6495
6496/// Interval span for ranges like HOUR TO SECOND
6497#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6498#[cfg_attr(feature = "bindings", derive(TS))]
6499pub struct IntervalSpan {
6500    /// Start unit (e.g., HOUR)
6501    pub this: IntervalUnit,
6502    /// End unit (e.g., SECOND)
6503    pub expression: IntervalUnit,
6504}
6505
6506/// Expression-based interval span for Oracle (e.g., DAY(9) TO SECOND(3))
6507/// Unlike IntervalSpan, this uses expressions to represent units with optional precision
6508#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6509#[cfg_attr(feature = "bindings", derive(TS))]
6510pub struct IntervalSpanExpr {
6511    /// Start unit expression (e.g., Var("DAY") or Anonymous("DAY", [9]))
6512    pub this: Box<Expression>,
6513    /// End unit expression (e.g., Var("SECOND") or Anonymous("SECOND", [3]))
6514    pub expression: Box<Expression>,
6515}
6516
6517#[derive(
6518    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6519)]
6520#[cfg_attr(feature = "bindings", derive(TS))]
6521pub enum IntervalUnit {
6522    Year,
6523    Quarter,
6524    Month,
6525    Week,
6526    Day,
6527    Hour,
6528    Minute,
6529    Second,
6530    Millisecond,
6531    Microsecond,
6532    Nanosecond,
6533}
6534
6535/// SQL Command (COMMIT, ROLLBACK, BEGIN, etc.)
6536#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6537#[cfg_attr(feature = "bindings", derive(TS))]
6538pub struct Command {
6539    /// The command text (e.g., "ROLLBACK", "COMMIT", "BEGIN")
6540    pub this: String,
6541}
6542
6543/// PREPARE statement (PostgreSQL/generic prepared statement definition)
6544/// Syntax: PREPARE name [(type, ...)] AS statement
6545#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6546#[cfg_attr(feature = "bindings", derive(TS))]
6547pub struct PrepareStatement {
6548    /// The prepared statement name.
6549    pub name: Identifier,
6550    /// Optional PostgreSQL parameter type list.
6551    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6552    pub parameter_types: Vec<DataType>,
6553    /// The statement to execute when the prepared statement is invoked.
6554    pub statement: Expression,
6555}
6556
6557/// T-SQL TRY/CATCH block.
6558#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6559#[cfg_attr(feature = "bindings", derive(TS))]
6560pub struct TryCatch {
6561    /// Statements inside BEGIN TRY ... END TRY.
6562    #[serde(default)]
6563    pub try_body: Vec<Expression>,
6564    /// Statements inside BEGIN CATCH ... END CATCH, when present.
6565    #[serde(default, skip_serializing_if = "Option::is_none")]
6566    pub catch_body: Option<Vec<Expression>>,
6567}
6568
6569/// EXEC/EXECUTE statement (TSQL stored procedure call)
6570/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6572#[cfg_attr(feature = "bindings", derive(TS))]
6573pub struct ExecuteStatement {
6574    /// The procedure name (can be qualified: schema.proc_name)
6575    pub this: Expression,
6576    /// Optional T-SQL return-status variable (`EXECUTE @status = procedure`).
6577    #[serde(default, skip_serializing_if = "Option::is_none")]
6578    pub return_status: Option<String>,
6579    /// Named parameters: @param=value pairs
6580    #[serde(default)]
6581    pub parameters: Vec<ExecuteParameter>,
6582    /// Positional prepared statement arguments, used by PostgreSQL EXECUTE name(...).
6583    #[serde(default, skip_serializing_if = "Vec::is_empty")]
6584    pub arguments: Vec<Expression>,
6585    /// Whether this statement represents PostgreSQL-style prepared statement execution.
6586    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6587    pub prepared: bool,
6588    /// Trailing clause text (e.g. WITH RESULT SETS ((...)))
6589    #[serde(default, skip_serializing_if = "Option::is_none")]
6590    pub suffix: Option<String>,
6591}
6592
6593/// Named parameter in EXEC statement: @name=value
6594#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6595#[cfg_attr(feature = "bindings", derive(TS))]
6596pub struct ExecuteParameter {
6597    /// Parameter name (including @)
6598    pub name: String,
6599    /// Parameter value
6600    pub value: Expression,
6601    /// Whether this is a positional parameter (no = sign)
6602    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6603    pub positional: bool,
6604    /// TSQL OUTPUT modifier on parameter
6605    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
6606    pub output: bool,
6607}
6608
6609/// KILL statement (MySQL/MariaDB)
6610/// KILL [CONNECTION | QUERY] <id>
6611#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6612#[cfg_attr(feature = "bindings", derive(TS))]
6613pub struct Kill {
6614    /// The target (process ID or connection ID)
6615    pub this: Expression,
6616    /// Optional kind: "CONNECTION" or "QUERY"
6617    pub kind: Option<String>,
6618}
6619
6620/// Snowflake CREATE TASK statement
6621#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6622#[cfg_attr(feature = "bindings", derive(TS))]
6623pub struct CreateTask {
6624    pub or_replace: bool,
6625    pub if_not_exists: bool,
6626    /// Task name (possibly qualified: db.schema.task)
6627    pub name: String,
6628    /// Raw text of properties between name and AS (WAREHOUSE, SCHEDULE, etc.)
6629    pub properties: String,
6630    /// The SQL statement body after AS
6631    pub body: Expression,
6632}
6633
6634/// Raw/unparsed SQL
6635#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6636#[cfg_attr(feature = "bindings", derive(TS))]
6637pub struct Raw {
6638    pub sql: String,
6639}
6640
6641// ============================================================================
6642// Function expression types
6643// ============================================================================
6644
6645/// Generic unary function (takes a single argument)
6646#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6647#[cfg_attr(feature = "bindings", derive(TS))]
6648pub struct UnaryFunc {
6649    pub this: Expression,
6650    /// Original function name for round-trip preservation (e.g., CHAR_LENGTH vs LENGTH)
6651    #[serde(skip_serializing_if = "Option::is_none", default)]
6652    pub original_name: Option<String>,
6653    /// Inferred data type from type annotation
6654    #[serde(default, skip_serializing_if = "Option::is_none")]
6655    #[ast(skip)]
6656    pub inferred_type: Option<DataType>,
6657}
6658
6659impl UnaryFunc {
6660    /// Create a new UnaryFunc with no original_name
6661    pub fn new(this: Expression) -> Self {
6662        Self {
6663            this,
6664            original_name: None,
6665            inferred_type: None,
6666        }
6667    }
6668
6669    /// Create a new UnaryFunc with an original name for round-trip preservation
6670    pub fn with_name(this: Expression, name: String) -> Self {
6671        Self {
6672            this,
6673            original_name: Some(name),
6674            inferred_type: None,
6675        }
6676    }
6677}
6678
6679/// CHAR/CHR function with multiple args and optional USING charset
6680/// e.g., CHAR(77, 77.3, '77.3' USING utf8mb4)
6681/// e.g., CHR(187 USING NCHAR_CS) -- Oracle
6682#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6683#[cfg_attr(feature = "bindings", derive(TS))]
6684pub struct CharFunc {
6685    pub args: Vec<Expression>,
6686    #[serde(skip_serializing_if = "Option::is_none", default)]
6687    pub charset: Option<String>,
6688    /// Original function name (CHAR or CHR), defaults to CHAR
6689    #[serde(skip_serializing_if = "Option::is_none", default)]
6690    pub name: Option<String>,
6691}
6692
6693/// Generic binary function (takes two arguments)
6694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6695#[cfg_attr(feature = "bindings", derive(TS))]
6696pub struct BinaryFunc {
6697    pub this: Expression,
6698    pub expression: Expression,
6699    /// Original function name for round-trip preservation (e.g., NVL vs IFNULL)
6700    #[serde(skip_serializing_if = "Option::is_none", default)]
6701    pub original_name: Option<String>,
6702    /// Inferred data type from type annotation
6703    #[serde(default, skip_serializing_if = "Option::is_none")]
6704    #[ast(skip)]
6705    pub inferred_type: Option<DataType>,
6706}
6707
6708/// Variable argument function
6709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6710#[cfg_attr(feature = "bindings", derive(TS))]
6711pub struct VarArgFunc {
6712    pub expressions: Vec<Expression>,
6713    /// Original function name for round-trip preservation (e.g., COALESCE vs IFNULL)
6714    #[serde(skip_serializing_if = "Option::is_none", default)]
6715    pub original_name: Option<String>,
6716    /// Inferred data type from type annotation
6717    #[serde(default, skip_serializing_if = "Option::is_none")]
6718    #[ast(skip)]
6719    pub inferred_type: Option<DataType>,
6720}
6721
6722/// CONCAT_WS function
6723#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6724#[cfg_attr(feature = "bindings", derive(TS))]
6725pub struct ConcatWs {
6726    pub separator: Expression,
6727    pub expressions: Vec<Expression>,
6728}
6729
6730/// SUBSTRING function
6731#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6732#[cfg_attr(feature = "bindings", derive(TS))]
6733pub struct SubstringFunc {
6734    pub this: Expression,
6735    pub start: Expression,
6736    pub length: Option<Expression>,
6737    /// Whether SQL standard FROM/FOR syntax was used (true) vs comma-separated (false)
6738    #[serde(default)]
6739    pub from_for_syntax: bool,
6740}
6741
6742/// OVERLAY function - OVERLAY(string PLACING replacement FROM position [FOR length])
6743#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6744#[cfg_attr(feature = "bindings", derive(TS))]
6745pub struct OverlayFunc {
6746    pub this: Expression,
6747    pub replacement: Expression,
6748    pub from: Expression,
6749    pub length: Option<Expression>,
6750}
6751
6752/// TRIM function
6753#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6754#[cfg_attr(feature = "bindings", derive(TS))]
6755pub struct TrimFunc {
6756    pub this: Expression,
6757    pub characters: Option<Expression>,
6758    pub position: TrimPosition,
6759    /// Whether SQL standard syntax was used (TRIM(BOTH chars FROM str)) vs function syntax (TRIM(str))
6760    #[serde(default)]
6761    pub sql_standard_syntax: bool,
6762    /// Whether the position was explicitly specified (BOTH/LEADING/TRAILING) vs defaulted
6763    #[serde(default)]
6764    pub position_explicit: bool,
6765    /// Inferred data type from type annotation
6766    #[serde(default, skip_serializing_if = "Option::is_none")]
6767    #[ast(skip)]
6768    pub inferred_type: Option<DataType>,
6769}
6770
6771#[derive(
6772    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
6773)]
6774#[cfg_attr(feature = "bindings", derive(TS))]
6775pub enum TrimPosition {
6776    Both,
6777    Leading,
6778    Trailing,
6779}
6780
6781/// REPLACE function
6782#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6783#[cfg_attr(feature = "bindings", derive(TS))]
6784pub struct ReplaceFunc {
6785    pub this: Expression,
6786    pub old: Expression,
6787    pub new: Expression,
6788}
6789
6790/// LEFT/RIGHT function
6791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6792#[cfg_attr(feature = "bindings", derive(TS))]
6793pub struct LeftRightFunc {
6794    pub this: Expression,
6795    pub length: Expression,
6796}
6797
6798/// REPEAT function
6799#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6800#[cfg_attr(feature = "bindings", derive(TS))]
6801pub struct RepeatFunc {
6802    pub this: Expression,
6803    pub times: Expression,
6804}
6805
6806/// LPAD/RPAD function
6807#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6808#[cfg_attr(feature = "bindings", derive(TS))]
6809pub struct PadFunc {
6810    pub this: Expression,
6811    pub length: Expression,
6812    pub fill: Option<Expression>,
6813}
6814
6815/// SPLIT function
6816#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6817#[cfg_attr(feature = "bindings", derive(TS))]
6818pub struct SplitFunc {
6819    pub this: Expression,
6820    pub delimiter: Expression,
6821}
6822
6823/// REGEXP_LIKE function
6824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6825#[cfg_attr(feature = "bindings", derive(TS))]
6826pub struct RegexpFunc {
6827    /// Additional search boundaries and retained source semantics.
6828    #[serde(default, skip_serializing_if = "Option::is_none")]
6829    pub options: Option<RegexOptions>,
6830    pub this: Expression,
6831    pub pattern: Expression,
6832    pub flags: Option<Expression>,
6833}
6834
6835/// REGEXP_REPLACE function
6836#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6837#[cfg_attr(feature = "bindings", derive(TS))]
6838pub struct RegexpReplaceFunc {
6839    /// Additional search boundaries and retained source semantics.
6840    #[serde(default, skip_serializing_if = "Option::is_none")]
6841    pub options: Option<RegexOptions>,
6842    pub this: Expression,
6843    pub pattern: Expression,
6844    pub replacement: Expression,
6845    pub flags: Option<Expression>,
6846}
6847
6848/// REGEXP_EXTRACT function
6849#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6850#[cfg_attr(feature = "bindings", derive(TS))]
6851pub struct RegexpExtractFunc {
6852    /// Additional search boundaries and retained source semantics.
6853    #[serde(default, skip_serializing_if = "Option::is_none")]
6854    pub options: Option<RegexOptions>,
6855    pub this: Expression,
6856    pub pattern: Expression,
6857    pub group: Option<Expression>,
6858}
6859
6860/// ROUND function
6861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6862#[cfg_attr(feature = "bindings", derive(TS))]
6863pub struct RoundFunc {
6864    pub this: Expression,
6865    pub decimals: Option<Expression>,
6866}
6867
6868/// FLOOR function with optional scale and time unit (Druid: FLOOR(time TO unit))
6869#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6870#[cfg_attr(feature = "bindings", derive(TS))]
6871pub struct FloorFunc {
6872    pub this: Expression,
6873    pub scale: Option<Expression>,
6874    /// Time unit for Druid-style FLOOR(time TO unit) syntax
6875    #[serde(skip_serializing_if = "Option::is_none", default)]
6876    pub to: Option<Expression>,
6877}
6878
6879/// CEIL function with optional decimals and time unit (Druid: CEIL(time TO unit))
6880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6881#[cfg_attr(feature = "bindings", derive(TS))]
6882pub struct CeilFunc {
6883    pub this: Expression,
6884    #[serde(skip_serializing_if = "Option::is_none", default)]
6885    pub decimals: Option<Expression>,
6886    /// Time unit for Druid-style CEIL(time TO unit) syntax
6887    #[serde(skip_serializing_if = "Option::is_none", default)]
6888    pub to: Option<Expression>,
6889}
6890
6891/// LOG function
6892#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6893#[cfg_attr(feature = "bindings", derive(TS))]
6894pub struct LogFunc {
6895    pub this: Expression,
6896    pub base: Option<Expression>,
6897}
6898
6899/// CURRENT_DATE (no arguments)
6900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6901#[cfg_attr(feature = "bindings", derive(TS))]
6902pub struct CurrentDate;
6903
6904/// CURRENT_TIME
6905#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6906#[cfg_attr(feature = "bindings", derive(TS))]
6907pub struct CurrentTime {
6908    pub precision: Option<u32>,
6909}
6910
6911/// CURRENT_TIMESTAMP
6912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6913#[cfg_attr(feature = "bindings", derive(TS))]
6914pub struct CurrentTimestamp {
6915    pub precision: Option<u32>,
6916    /// If true, generate SYSDATE instead of CURRENT_TIMESTAMP (Oracle-specific)
6917    #[serde(default)]
6918    pub sysdate: bool,
6919}
6920
6921/// CURRENT_TIMESTAMP_LTZ - Snowflake local timezone timestamp
6922#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6923#[cfg_attr(feature = "bindings", derive(TS))]
6924pub struct CurrentTimestampLTZ {
6925    pub precision: Option<u32>,
6926}
6927
6928/// AT TIME ZONE expression for timezone conversion
6929#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6930#[cfg_attr(feature = "bindings", derive(TS))]
6931pub struct AtTimeZone {
6932    /// The expression to convert
6933    pub this: Expression,
6934    /// The target timezone
6935    pub zone: Expression,
6936}
6937
6938/// DATE_ADD / DATE_SUB function
6939#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6940#[cfg_attr(feature = "bindings", derive(TS))]
6941pub struct DateAddFunc {
6942    pub this: Expression,
6943    pub interval: Expression,
6944    pub unit: IntervalUnit,
6945}
6946
6947/// DATEDIFF function
6948#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6949#[cfg_attr(feature = "bindings", derive(TS))]
6950pub struct DateDiffFunc {
6951    pub this: Expression,
6952    pub expression: Expression,
6953    pub unit: Option<IntervalUnit>,
6954}
6955
6956/// DATE_TRUNC function
6957#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6958#[cfg_attr(feature = "bindings", derive(TS))]
6959pub struct DateTruncFunc {
6960    pub this: Expression,
6961    pub unit: DateTimeField,
6962}
6963
6964/// EXTRACT function
6965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
6966#[cfg_attr(feature = "bindings", derive(TS))]
6967pub struct ExtractFunc {
6968    pub this: Expression,
6969    pub field: DateTimeField,
6970}
6971
6972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6973#[cfg_attr(feature = "bindings", derive(TS))]
6974pub enum DateTimeField {
6975    Year,
6976    Month,
6977    Day,
6978    Hour,
6979    Minute,
6980    Second,
6981    Millisecond,
6982    Microsecond,
6983    DayOfWeek,
6984    DayOfYear,
6985    Week,
6986    /// Week with a modifier like WEEK(monday), WEEK(sunday)
6987    WeekWithModifier(String),
6988    Quarter,
6989    Epoch,
6990    Timezone,
6991    TimezoneHour,
6992    TimezoneMinute,
6993    Date,
6994    Time,
6995    /// Custom datetime field for dialect-specific or arbitrary fields
6996    Custom(String),
6997}
6998
6999/// TO_DATE function
7000#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7001#[cfg_attr(feature = "bindings", derive(TS))]
7002pub struct ToDateFunc {
7003    pub this: Expression,
7004    pub format: Option<Expression>,
7005}
7006
7007/// TO_TIMESTAMP function
7008#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7009#[cfg_attr(feature = "bindings", derive(TS))]
7010pub struct ToTimestampFunc {
7011    pub this: Expression,
7012    pub format: Option<Expression>,
7013}
7014
7015/// IF function
7016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7017#[cfg_attr(feature = "bindings", derive(TS))]
7018pub struct IfFunc {
7019    pub condition: Expression,
7020    pub true_value: Expression,
7021    pub false_value: Option<Expression>,
7022    /// Original function name (IF, IFF, IIF) for round-trip preservation
7023    #[serde(skip_serializing_if = "Option::is_none", default)]
7024    pub original_name: Option<String>,
7025    /// Inferred data type from type annotation
7026    #[serde(default, skip_serializing_if = "Option::is_none")]
7027    #[ast(skip)]
7028    pub inferred_type: Option<DataType>,
7029}
7030
7031/// NVL2 function
7032#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7033#[cfg_attr(feature = "bindings", derive(TS))]
7034pub struct Nvl2Func {
7035    pub this: Expression,
7036    pub true_value: Expression,
7037    pub false_value: Expression,
7038    /// Inferred data type from type annotation
7039    #[serde(default, skip_serializing_if = "Option::is_none")]
7040    #[ast(skip)]
7041    pub inferred_type: Option<DataType>,
7042}
7043
7044// ============================================================================
7045// Typed Aggregate Function types
7046// ============================================================================
7047
7048/// Generic aggregate function base type
7049#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7050#[cfg_attr(feature = "bindings", derive(TS))]
7051pub struct AggFunc {
7052    pub this: Expression,
7053    pub distinct: bool,
7054    pub filter: Option<Expression>,
7055    pub order_by: Vec<Ordered>,
7056    /// Original function name (case-preserving) when parsed from SQL
7057    #[serde(skip_serializing_if = "Option::is_none", default)]
7058    pub name: Option<String>,
7059    /// IGNORE NULLS (true) or RESPECT NULLS (false), None if not specified
7060    #[serde(skip_serializing_if = "Option::is_none", default)]
7061    pub ignore_nulls: Option<bool>,
7062    /// HAVING MAX/MIN expr inside aggregate (BigQuery syntax)
7063    /// e.g., ANY_VALUE(fruit HAVING MAX sold) - (expression, is_max: true for MAX, false for MIN)
7064    #[serde(skip_serializing_if = "Option::is_none", default)]
7065    pub having_max: Option<(Box<Expression>, bool)>,
7066    /// LIMIT inside aggregate (e.g., ARRAY_AGG(x ORDER BY y LIMIT 2))
7067    #[serde(skip_serializing_if = "Option::is_none", default)]
7068    pub limit: Option<Box<Expression>>,
7069    /// Inferred data type from type annotation
7070    #[serde(default, skip_serializing_if = "Option::is_none")]
7071    #[ast(skip)]
7072    pub inferred_type: Option<DataType>,
7073}
7074
7075/// COUNT function with optional star
7076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7077#[cfg_attr(feature = "bindings", derive(TS))]
7078pub struct CountFunc {
7079    pub this: Option<Expression>,
7080    pub star: bool,
7081    pub distinct: bool,
7082    pub filter: Option<Expression>,
7083    /// IGNORE NULLS (true) or RESPECT NULLS (false)
7084    #[serde(default, skip_serializing_if = "Option::is_none")]
7085    pub ignore_nulls: Option<bool>,
7086    /// Original function name for case preservation (e.g., "count" or "COUNT")
7087    #[serde(default, skip_serializing_if = "Option::is_none")]
7088    pub original_name: Option<String>,
7089    /// Inferred data type from type annotation
7090    #[serde(default, skip_serializing_if = "Option::is_none")]
7091    #[ast(skip)]
7092    pub inferred_type: Option<DataType>,
7093}
7094
7095/// GROUP_CONCAT function (MySQL style)
7096#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7097#[cfg_attr(feature = "bindings", derive(TS))]
7098pub struct GroupConcatFunc {
7099    pub this: Expression,
7100    pub separator: Option<Expression>,
7101    pub order_by: Option<Vec<Ordered>>,
7102    pub distinct: bool,
7103    pub filter: Option<Expression>,
7104    /// MySQL 8.0.19+: LIMIT n inside GROUP_CONCAT
7105    #[serde(default, skip_serializing_if = "Option::is_none")]
7106    pub limit: Option<Box<Expression>>,
7107    /// Inferred data type from type annotation
7108    #[serde(default, skip_serializing_if = "Option::is_none")]
7109    #[ast(skip)]
7110    pub inferred_type: Option<DataType>,
7111}
7112
7113/// STRING_AGG function (PostgreSQL/Standard SQL)
7114#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7115#[cfg_attr(feature = "bindings", derive(TS))]
7116pub struct StringAggFunc {
7117    pub this: Expression,
7118    #[serde(default)]
7119    pub separator: Option<Expression>,
7120    #[serde(default)]
7121    pub order_by: Option<Vec<Ordered>>,
7122    #[serde(default)]
7123    pub distinct: bool,
7124    #[serde(default)]
7125    pub filter: Option<Expression>,
7126    /// BigQuery LIMIT inside STRING_AGG
7127    #[serde(default, skip_serializing_if = "Option::is_none")]
7128    pub limit: Option<Box<Expression>>,
7129    /// Inferred data type from type annotation
7130    #[serde(default, skip_serializing_if = "Option::is_none")]
7131    #[ast(skip)]
7132    pub inferred_type: Option<DataType>,
7133}
7134
7135/// LISTAGG function (Oracle style)
7136#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7137#[cfg_attr(feature = "bindings", derive(TS))]
7138pub struct ListAggFunc {
7139    /// Retain source byte-limit and overflow semantics through AST generation.
7140    #[serde(default, skip_serializing_if = "Option::is_none")]
7141    #[ast(skip)]
7142    pub source_dialect: Option<crate::dialects::DialectType>,
7143    pub this: Expression,
7144    pub separator: Option<Expression>,
7145    pub on_overflow: Option<ListAggOverflow>,
7146    /// Vertica `USING PARAMETERS max_length = n`
7147    #[serde(default, skip_serializing_if = "Option::is_none")]
7148    pub max_length: Option<Box<Expression>>,
7149    pub order_by: Option<Vec<Ordered>>,
7150    pub distinct: bool,
7151    pub filter: Option<Expression>,
7152    /// Inferred data type from type annotation
7153    #[serde(default, skip_serializing_if = "Option::is_none")]
7154    #[ast(skip)]
7155    pub inferred_type: Option<DataType>,
7156}
7157
7158/// LISTAGG ON OVERFLOW behavior
7159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7160#[cfg_attr(feature = "bindings", derive(TS))]
7161pub enum ListAggOverflow {
7162    Error,
7163    Truncate {
7164        filler: Option<Expression>,
7165        with_count: bool,
7166    },
7167}
7168
7169/// SUM_IF / COUNT_IF function
7170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7171#[cfg_attr(feature = "bindings", derive(TS))]
7172pub struct SumIfFunc {
7173    pub this: Expression,
7174    pub condition: Expression,
7175    pub filter: Option<Expression>,
7176    /// Inferred data type from type annotation
7177    #[serde(default, skip_serializing_if = "Option::is_none")]
7178    #[ast(skip)]
7179    pub inferred_type: Option<DataType>,
7180}
7181
7182/// APPROX_PERCENTILE function
7183#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7184#[cfg_attr(feature = "bindings", derive(TS))]
7185pub struct ApproxPercentileFunc {
7186    pub this: Expression,
7187    pub percentile: Expression,
7188    pub accuracy: Option<Expression>,
7189    pub filter: Option<Expression>,
7190}
7191
7192/// PERCENTILE_CONT / PERCENTILE_DISC function
7193#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7194#[cfg_attr(feature = "bindings", derive(TS))]
7195pub struct PercentileFunc {
7196    pub this: Expression,
7197    pub percentile: Expression,
7198    pub order_by: Option<Vec<Ordered>>,
7199    pub filter: Option<Expression>,
7200}
7201
7202// ============================================================================
7203// Typed Window Function types
7204// ============================================================================
7205
7206/// ROW_NUMBER function (no arguments)
7207#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7208#[cfg_attr(feature = "bindings", derive(TS))]
7209pub struct RowNumber;
7210
7211/// RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7212#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7213#[cfg_attr(feature = "bindings", derive(TS))]
7214pub struct Rank {
7215    /// DuckDB: RANK(ORDER BY col) - order by inside function
7216    #[serde(default, skip_serializing_if = "Option::is_none")]
7217    pub order_by: Option<Vec<Ordered>>,
7218    /// Oracle hypothetical rank: RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7219    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7220    pub args: Vec<Expression>,
7221}
7222
7223/// DENSE_RANK function (Oracle allows hypothetical args with WITHIN GROUP)
7224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7225#[cfg_attr(feature = "bindings", derive(TS))]
7226pub struct DenseRank {
7227    /// Oracle hypothetical rank: DENSE_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7228    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7229    pub args: Vec<Expression>,
7230}
7231
7232/// NTILE function (DuckDB allows ORDER BY inside)
7233#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7234#[cfg_attr(feature = "bindings", derive(TS))]
7235pub struct NTileFunc {
7236    /// num_buckets is optional to support Databricks NTILE() without arguments
7237    #[serde(default, skip_serializing_if = "Option::is_none")]
7238    pub num_buckets: Option<Expression>,
7239    /// DuckDB: NTILE(n ORDER BY col) - order by inside function
7240    #[serde(default, skip_serializing_if = "Option::is_none")]
7241    pub order_by: Option<Vec<Ordered>>,
7242}
7243
7244/// LEAD / LAG function
7245#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7246#[cfg_attr(feature = "bindings", derive(TS))]
7247pub struct LeadLagFunc {
7248    pub this: Expression,
7249    pub offset: Option<Expression>,
7250    pub default: Option<Expression>,
7251    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7252    #[serde(default, skip_serializing_if = "Option::is_none")]
7253    pub ignore_nulls: Option<bool>,
7254}
7255
7256/// FIRST_VALUE / LAST_VALUE function
7257#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7258#[cfg_attr(feature = "bindings", derive(TS))]
7259pub struct ValueFunc {
7260    pub this: Expression,
7261    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7262    #[serde(default, skip_serializing_if = "Option::is_none")]
7263    pub ignore_nulls: Option<bool>,
7264    /// ORDER BY inside the function parens (e.g., DuckDB: LAST_VALUE(x ORDER BY x))
7265    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7266    pub order_by: Vec<Ordered>,
7267}
7268
7269/// NTH_VALUE function
7270#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7271#[cfg_attr(feature = "bindings", derive(TS))]
7272pub struct NthValueFunc {
7273    pub this: Expression,
7274    pub offset: Expression,
7275    /// None = not specified, Some(true) = IGNORE NULLS, Some(false) = RESPECT NULLS
7276    #[serde(default, skip_serializing_if = "Option::is_none")]
7277    pub ignore_nulls: Option<bool>,
7278    /// Snowflake FROM FIRST / FROM LAST clause
7279    /// None = not specified, Some(true) = FROM FIRST, Some(false) = FROM LAST
7280    #[serde(default, skip_serializing_if = "Option::is_none")]
7281    pub from_first: Option<bool>,
7282}
7283
7284/// PERCENT_RANK function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7285#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7286#[cfg_attr(feature = "bindings", derive(TS))]
7287pub struct PercentRank {
7288    /// DuckDB: PERCENT_RANK(ORDER BY col) - order by inside function
7289    #[serde(default, skip_serializing_if = "Option::is_none")]
7290    pub order_by: Option<Vec<Ordered>>,
7291    /// Oracle hypothetical rank: PERCENT_RANK(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7292    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7293    pub args: Vec<Expression>,
7294}
7295
7296/// CUME_DIST function (DuckDB allows ORDER BY inside, Oracle allows hypothetical args with WITHIN GROUP)
7297#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7298#[cfg_attr(feature = "bindings", derive(TS))]
7299pub struct CumeDist {
7300    /// DuckDB: CUME_DIST(ORDER BY col) - order by inside function
7301    #[serde(default, skip_serializing_if = "Option::is_none")]
7302    pub order_by: Option<Vec<Ordered>>,
7303    /// Oracle hypothetical rank: CUME_DIST(val1, val2, ...) WITHIN GROUP (ORDER BY ...)
7304    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7305    pub args: Vec<Expression>,
7306}
7307
7308// ============================================================================
7309// Additional String Function types
7310// ============================================================================
7311
7312/// POSITION/INSTR function
7313#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7314#[cfg_attr(feature = "bindings", derive(TS))]
7315pub struct PositionFunc {
7316    pub substring: Expression,
7317    pub string: Expression,
7318    pub start: Option<Expression>,
7319}
7320
7321// ============================================================================
7322// Additional Math Function types
7323// ============================================================================
7324
7325/// RANDOM function (no arguments)
7326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7327#[cfg_attr(feature = "bindings", derive(TS))]
7328pub struct Random;
7329
7330/// RAND function (optional seed, or Teradata RANDOM(lower, upper))
7331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7332#[cfg_attr(feature = "bindings", derive(TS))]
7333pub struct Rand {
7334    pub seed: Option<Box<Expression>>,
7335    /// Teradata RANDOM lower bound
7336    #[serde(default)]
7337    pub lower: Option<Box<Expression>>,
7338    /// Teradata RANDOM upper bound
7339    #[serde(default)]
7340    pub upper: Option<Box<Expression>>,
7341}
7342
7343/// TRUNCATE / TRUNC function
7344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7345#[cfg_attr(feature = "bindings", derive(TS))]
7346pub struct TruncateFunc {
7347    pub this: Expression,
7348    pub decimals: Option<Expression>,
7349}
7350
7351/// PI function (no arguments)
7352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7353#[cfg_attr(feature = "bindings", derive(TS))]
7354pub struct Pi;
7355
7356// ============================================================================
7357// Control Flow Function types
7358// ============================================================================
7359
7360/// DECODE function (Oracle style)
7361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7362#[cfg_attr(feature = "bindings", derive(TS))]
7363pub struct DecodeFunc {
7364    pub this: Expression,
7365    pub search_results: Vec<(Expression, Expression)>,
7366    pub default: Option<Expression>,
7367}
7368
7369// ============================================================================
7370// Additional Date/Time Function types
7371// ============================================================================
7372
7373/// DATE_FORMAT / FORMAT_DATE function
7374#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7375#[cfg_attr(feature = "bindings", derive(TS))]
7376pub struct DateFormatFunc {
7377    pub this: Expression,
7378    pub format: Expression,
7379}
7380
7381/// FROM_UNIXTIME function
7382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7383#[cfg_attr(feature = "bindings", derive(TS))]
7384pub struct FromUnixtimeFunc {
7385    pub this: Expression,
7386    pub format: Option<Expression>,
7387}
7388
7389/// UNIX_TIMESTAMP function
7390#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7391#[cfg_attr(feature = "bindings", derive(TS))]
7392pub struct UnixTimestampFunc {
7393    pub this: Option<Expression>,
7394    pub format: Option<Expression>,
7395}
7396
7397/// MAKE_DATE function
7398#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7399#[cfg_attr(feature = "bindings", derive(TS))]
7400pub struct MakeDateFunc {
7401    pub year: Expression,
7402    pub month: Expression,
7403    pub day: Expression,
7404}
7405
7406/// MAKE_TIMESTAMP function
7407#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7408#[cfg_attr(feature = "bindings", derive(TS))]
7409pub struct MakeTimestampFunc {
7410    pub year: Expression,
7411    pub month: Expression,
7412    pub day: Expression,
7413    pub hour: Expression,
7414    pub minute: Expression,
7415    pub second: Expression,
7416    pub timezone: Option<Expression>,
7417}
7418
7419/// LAST_DAY function with optional date part (for BigQuery granularity like WEEK(SUNDAY))
7420#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7421#[cfg_attr(feature = "bindings", derive(TS))]
7422pub struct LastDayFunc {
7423    pub this: Expression,
7424    /// Optional date part for granularity (e.g., MONTH, YEAR, WEEK(SUNDAY))
7425    #[serde(skip_serializing_if = "Option::is_none", default)]
7426    pub unit: Option<DateTimeField>,
7427}
7428
7429// ============================================================================
7430// Array Function types
7431// ============================================================================
7432
7433/// ARRAY constructor
7434#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7435#[cfg_attr(feature = "bindings", derive(TS))]
7436pub struct ArrayConstructor {
7437    pub expressions: Vec<Expression>,
7438    pub bracket_notation: bool,
7439    /// True if LIST keyword was used instead of ARRAY (DuckDB)
7440    pub use_list_keyword: bool,
7441    /// Inferred array data type from type annotation
7442    #[serde(default, skip_serializing_if = "Option::is_none")]
7443    #[ast(skip)]
7444    pub inferred_type: Option<DataType>,
7445}
7446
7447/// ARRAY_SORT function
7448#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7449#[cfg_attr(feature = "bindings", derive(TS))]
7450pub struct ArraySortFunc {
7451    pub this: Expression,
7452    pub comparator: Option<Expression>,
7453    pub desc: bool,
7454    pub nulls_first: Option<bool>,
7455}
7456
7457/// ARRAY_JOIN / ARRAY_TO_STRING function
7458#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7459#[cfg_attr(feature = "bindings", derive(TS))]
7460pub struct ArrayJoinFunc {
7461    pub this: Expression,
7462    pub separator: Expression,
7463    pub null_replacement: Option<Expression>,
7464}
7465
7466/// UNNEST function
7467#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7468#[cfg_attr(feature = "bindings", derive(TS))]
7469pub struct UnnestFunc {
7470    pub this: Expression,
7471    /// Additional arguments for multi-argument UNNEST (e.g., UNNEST(arr1, arr2))
7472    #[serde(default, skip_serializing_if = "Vec::is_empty")]
7473    pub expressions: Vec<Expression>,
7474    pub with_ordinality: bool,
7475    pub alias: Option<Identifier>,
7476    /// BigQuery: offset alias for WITH OFFSET AS <name>
7477    #[serde(default, skip_serializing_if = "Option::is_none")]
7478    pub offset_alias: Option<Identifier>,
7479    /// Inferred type of the first UNNEST output column.
7480    #[serde(default, skip_serializing_if = "Option::is_none")]
7481    #[ast(skip)]
7482    pub inferred_type: Option<DataType>,
7483}
7484
7485/// ARRAY_FILTER function (with lambda)
7486#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7487#[cfg_attr(feature = "bindings", derive(TS))]
7488pub struct ArrayFilterFunc {
7489    pub this: Expression,
7490    pub filter: Expression,
7491}
7492
7493/// ARRAY_TRANSFORM / TRANSFORM function (with lambda)
7494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7495#[cfg_attr(feature = "bindings", derive(TS))]
7496pub struct ArrayTransformFunc {
7497    pub this: Expression,
7498    pub transform: Expression,
7499}
7500
7501/// SEQUENCE / GENERATE_SERIES function
7502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7503#[cfg_attr(feature = "bindings", derive(TS))]
7504pub struct SequenceFunc {
7505    pub start: Expression,
7506    pub stop: Expression,
7507    pub step: Option<Expression>,
7508}
7509
7510// ============================================================================
7511// Struct Function types
7512// ============================================================================
7513
7514/// STRUCT constructor
7515#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7516#[cfg_attr(feature = "bindings", derive(TS))]
7517pub struct StructConstructor {
7518    pub fields: Vec<(Option<Identifier>, Expression)>,
7519}
7520
7521/// STRUCT_EXTRACT function
7522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7523#[cfg_attr(feature = "bindings", derive(TS))]
7524pub struct StructExtractFunc {
7525    pub this: Expression,
7526    pub field: Identifier,
7527}
7528
7529/// NAMED_STRUCT function
7530#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7531#[cfg_attr(feature = "bindings", derive(TS))]
7532pub struct NamedStructFunc {
7533    pub pairs: Vec<(Expression, Expression)>,
7534}
7535
7536// ============================================================================
7537// Map Function types
7538// ============================================================================
7539
7540/// MAP constructor
7541#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7542#[cfg_attr(feature = "bindings", derive(TS))]
7543pub struct MapConstructor {
7544    pub keys: Vec<Expression>,
7545    pub values: Vec<Expression>,
7546    /// Whether curly brace syntax was used (`{'a': 1}`) vs MAP function (`MAP(...)`)
7547    #[serde(default)]
7548    pub curly_brace_syntax: bool,
7549    /// Whether MAP keyword was present (`MAP {'a': 1}`) vs bare curly braces (`{'a': 1}`)
7550    #[serde(default)]
7551    pub with_map_keyword: bool,
7552}
7553
7554/// TRANSFORM_KEYS / TRANSFORM_VALUES function
7555#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7556#[cfg_attr(feature = "bindings", derive(TS))]
7557pub struct TransformFunc {
7558    pub this: Expression,
7559    pub transform: Expression,
7560}
7561
7562/// Function call with EMITS clause (Exasol)
7563/// Used for JSON_EXTRACT(...) EMITS (col1 TYPE1, col2 TYPE2)
7564#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7565#[cfg_attr(feature = "bindings", derive(TS))]
7566pub struct FunctionEmits {
7567    /// The function call expression
7568    pub this: Expression,
7569    /// The EMITS schema definition
7570    pub emits: Expression,
7571}
7572
7573// ============================================================================
7574// JSON Function types
7575// ============================================================================
7576
7577/// JSON_EXTRACT / JSON_EXTRACT_SCALAR function
7578#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7579#[cfg_attr(feature = "bindings", derive(TS))]
7580pub struct JsonExtractFunc {
7581    #[serde(default, skip_serializing_if = "Option::is_none")]
7582    #[ast(skip)]
7583    pub source_dialect: Option<crate::dialects::DialectType>,
7584    /// Structured SQL/JSON wrapper and error/empty behavior.
7585    #[serde(default, skip_serializing_if = "Option::is_none")]
7586    pub options: Option<JsonOptions>,
7587
7588    pub this: Expression,
7589    pub path: Expression,
7590    pub returning: Option<DataType>,
7591    /// True if parsed from -> or ->> operator syntax
7592    #[serde(default)]
7593    pub arrow_syntax: bool,
7594    /// True if parsed from #>> operator syntax (PostgreSQL JSONB path text extraction)
7595    #[serde(default)]
7596    pub hash_arrow_syntax: bool,
7597    /// Wrapper option: WITH/WITHOUT [CONDITIONAL|UNCONDITIONAL] [ARRAY] WRAPPER
7598    #[serde(default)]
7599    pub wrapper_option: Option<String>,
7600    /// Quotes handling: KEEP QUOTES or OMIT QUOTES
7601    #[serde(default)]
7602    pub quotes_option: Option<String>,
7603    /// ON SCALAR STRING flag
7604    #[serde(default)]
7605    pub on_scalar_string: bool,
7606    /// Error handling: NULL ON ERROR, ERROR ON ERROR, etc.
7607    #[serde(default)]
7608    pub on_error: Option<String>,
7609}
7610
7611/// JSON path extraction
7612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7613#[cfg_attr(feature = "bindings", derive(TS))]
7614pub struct JsonPathFunc {
7615    pub this: Expression,
7616    pub paths: Vec<Expression>,
7617}
7618
7619/// JSON_OBJECT function
7620#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7621#[cfg_attr(feature = "bindings", derive(TS))]
7622pub struct JsonObjectFunc {
7623    pub pairs: Vec<(Expression, Expression)>,
7624    pub null_handling: Option<JsonNullHandling>,
7625    #[serde(default)]
7626    pub with_unique_keys: bool,
7627    #[serde(default)]
7628    pub returning_type: Option<DataType>,
7629    #[serde(default)]
7630    pub format_json: bool,
7631    #[serde(default)]
7632    pub encoding: Option<String>,
7633    /// For JSON_OBJECT(*) syntax
7634    #[serde(default)]
7635    pub star: bool,
7636}
7637
7638/// JSON null handling options
7639#[derive(
7640    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7641)]
7642#[cfg_attr(feature = "bindings", derive(TS))]
7643pub enum JsonNullHandling {
7644    NullOnNull,
7645    AbsentOnNull,
7646}
7647
7648/// JSON_SET / JSON_INSERT function
7649#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7650#[cfg_attr(feature = "bindings", derive(TS))]
7651pub struct JsonModifyFunc {
7652    pub this: Expression,
7653    pub path_values: Vec<(Expression, Expression)>,
7654}
7655
7656/// JSON_ARRAYAGG function
7657#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7658#[cfg_attr(feature = "bindings", derive(TS))]
7659pub struct JsonArrayAggFunc {
7660    pub this: Expression,
7661    pub order_by: Option<Vec<Ordered>>,
7662    pub null_handling: Option<JsonNullHandling>,
7663    pub filter: Option<Expression>,
7664}
7665
7666/// JSON_OBJECTAGG function
7667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7668#[cfg_attr(feature = "bindings", derive(TS))]
7669pub struct JsonObjectAggFunc {
7670    pub key: Expression,
7671    pub value: Expression,
7672    pub null_handling: Option<JsonNullHandling>,
7673    pub filter: Option<Expression>,
7674}
7675
7676// ============================================================================
7677// Type Casting Function types
7678// ============================================================================
7679
7680/// CONVERT function (SQL Server style)
7681#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7682#[cfg_attr(feature = "bindings", derive(TS))]
7683pub struct ConvertFunc {
7684    pub this: Expression,
7685    pub to: DataType,
7686    pub style: Option<Expression>,
7687}
7688
7689// ============================================================================
7690// Additional Expression types
7691// ============================================================================
7692
7693/// Lambda expression
7694#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7695#[cfg_attr(feature = "bindings", derive(TS))]
7696pub struct LambdaExpr {
7697    pub parameters: Vec<Identifier>,
7698    pub body: Expression,
7699    /// True if using DuckDB's LAMBDA x : expr syntax (vs x -> expr)
7700    #[serde(default)]
7701    pub colon: bool,
7702    /// Optional type annotations for parameters (Snowflake: a int -> a + 1)
7703    /// Maps parameter index to data type
7704    #[serde(default)]
7705    pub parameter_types: Vec<Option<DataType>>,
7706}
7707
7708/// Parameter (parameterized queries)
7709#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7710#[cfg_attr(feature = "bindings", derive(TS))]
7711pub struct Parameter {
7712    pub name: Option<String>,
7713    pub index: Option<u32>,
7714    pub style: ParameterStyle,
7715    /// Whether the name was quoted (e.g., @"x" vs @x)
7716    #[serde(default)]
7717    pub quoted: bool,
7718    /// Whether the name was string-quoted with single quotes (e.g., @'foo')
7719    #[serde(default)]
7720    pub string_quoted: bool,
7721    /// Optional secondary expression for ${kind:name} syntax (Hive hiveconf variables)
7722    #[serde(default)]
7723    pub expression: Option<String>,
7724}
7725
7726/// Parameter placeholder styles
7727#[derive(
7728    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7729)]
7730#[cfg_attr(feature = "bindings", derive(TS))]
7731pub enum ParameterStyle {
7732    Question,     // ?
7733    Dollar,       // $1, $2
7734    DollarBrace,  // ${name} (Databricks, Hive template variables)
7735    Brace,        // {name} (Spark/Databricks widget/template variables)
7736    Colon,        // :name
7737    At,           // @name
7738    DoubleAt,     // @@name (system variables in MySQL/SQL Server)
7739    DoubleDollar, // $$name
7740    Percent,      // %s, %(name)s (PostgreSQL psycopg2 style)
7741}
7742
7743/// Placeholder expression
7744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7745#[cfg_attr(feature = "bindings", derive(TS))]
7746pub struct Placeholder {
7747    pub index: Option<u32>,
7748}
7749
7750/// Named argument in function call: name => value or name := value
7751#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7752#[cfg_attr(feature = "bindings", derive(TS))]
7753pub struct NamedArgument {
7754    pub name: Identifier,
7755    pub value: Expression,
7756    /// The separator used: `=>`, `:=`, or `=`
7757    pub separator: NamedArgSeparator,
7758}
7759
7760/// Separator style for named arguments
7761#[derive(
7762    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
7763)]
7764#[cfg_attr(feature = "bindings", derive(TS))]
7765pub enum NamedArgSeparator {
7766    /// `=>` (standard SQL, Snowflake, BigQuery)
7767    DArrow,
7768    /// `:=` (Oracle, MySQL)
7769    ColonEq,
7770    /// `=` (simple equals, some dialects)
7771    Eq,
7772}
7773
7774/// TABLE ref or MODEL ref used as a function argument (BigQuery)
7775/// e.g., GAP_FILL(TABLE device_data, ...) or ML.PREDICT(MODEL mydataset.mymodel, ...)
7776#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7777#[cfg_attr(feature = "bindings", derive(TS))]
7778pub struct TableArgument {
7779    /// The keyword prefix: "TABLE" or "MODEL"
7780    pub prefix: String,
7781    /// The table/model reference expression
7782    pub this: Expression,
7783}
7784
7785/// SQL Comment preservation
7786#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7787#[cfg_attr(feature = "bindings", derive(TS))]
7788pub struct SqlComment {
7789    pub text: String,
7790    pub is_block: bool,
7791}
7792
7793// ============================================================================
7794// Additional Predicate types
7795// ============================================================================
7796
7797/// SIMILAR TO expression
7798#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7799#[cfg_attr(feature = "bindings", derive(TS))]
7800pub struct SimilarToExpr {
7801    pub this: Expression,
7802    pub pattern: Expression,
7803    pub escape: Option<Expression>,
7804    pub not: bool,
7805}
7806
7807/// ANY / ALL quantified expression
7808#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7809#[cfg_attr(feature = "bindings", derive(TS))]
7810pub struct QuantifiedExpr {
7811    pub this: Expression,
7812    pub subquery: Expression,
7813    pub op: Option<QuantifiedOp>,
7814}
7815
7816/// Comparison operator for quantified expressions
7817#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7818#[cfg_attr(feature = "bindings", derive(TS))]
7819pub enum QuantifiedOp {
7820    Eq,
7821    Neq,
7822    Lt,
7823    Lte,
7824    Gt,
7825    Gte,
7826}
7827
7828/// OVERLAPS expression
7829/// Supports two forms:
7830/// 1. Simple binary: a OVERLAPS b (this, expression are set)
7831/// 2. Full ANSI: (a, b) OVERLAPS (c, d) (left_start, left_end, right_start, right_end are set)
7832#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7833#[cfg_attr(feature = "bindings", derive(TS))]
7834pub struct OverlapsExpr {
7835    /// Left operand for simple binary form
7836    #[serde(skip_serializing_if = "Option::is_none")]
7837    pub this: Option<Expression>,
7838    /// Right operand for simple binary form
7839    #[serde(skip_serializing_if = "Option::is_none")]
7840    pub expression: Option<Expression>,
7841    /// Left range start for full ANSI form
7842    #[serde(skip_serializing_if = "Option::is_none")]
7843    pub left_start: Option<Expression>,
7844    /// Left range end for full ANSI form
7845    #[serde(skip_serializing_if = "Option::is_none")]
7846    pub left_end: Option<Expression>,
7847    /// Right range start for full ANSI form
7848    #[serde(skip_serializing_if = "Option::is_none")]
7849    pub right_start: Option<Expression>,
7850    /// Right range end for full ANSI form
7851    #[serde(skip_serializing_if = "Option::is_none")]
7852    pub right_end: Option<Expression>,
7853}
7854
7855// ============================================================================
7856// Array/Struct/Map access
7857// ============================================================================
7858
7859/// Subscript access (array[index] or map[key])
7860#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7861#[cfg_attr(feature = "bindings", derive(TS))]
7862pub struct Subscript {
7863    pub this: Expression,
7864    pub index: Expression,
7865}
7866
7867/// Dot access (struct.field)
7868#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7869#[cfg_attr(feature = "bindings", derive(TS))]
7870pub struct DotAccess {
7871    pub this: Expression,
7872    pub field: Identifier,
7873    #[serde(default, skip_serializing_if = "Option::is_none")]
7874    pub inferred_type: Option<DataType>,
7875}
7876
7877/// Method call (expr.method(args))
7878#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7879#[cfg_attr(feature = "bindings", derive(TS))]
7880pub struct MethodCall {
7881    pub this: Expression,
7882    pub method: Identifier,
7883    pub args: Vec<Expression>,
7884}
7885
7886/// Array slice (array[start:end])
7887#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7888#[cfg_attr(feature = "bindings", derive(TS))]
7889pub struct ArraySlice {
7890    pub this: Expression,
7891    pub start: Option<Expression>,
7892    pub end: Option<Expression>,
7893}
7894
7895// ============================================================================
7896// DDL (Data Definition Language) Statements
7897// ============================================================================
7898
7899/// ON COMMIT behavior for temporary tables
7900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7901#[cfg_attr(feature = "bindings", derive(TS))]
7902pub enum OnCommit {
7903    /// ON COMMIT PRESERVE ROWS
7904    PreserveRows,
7905    /// ON COMMIT DELETE ROWS
7906    DeleteRows,
7907}
7908
7909/// TiDB `AUTO_RANDOM[(shard_bits[, range_bits])]` column attribute.
7910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7911#[cfg_attr(feature = "bindings", derive(TS))]
7912pub struct TiDBAutoRandom {
7913    #[serde(default, skip_serializing_if = "Option::is_none")]
7914    pub shard_bits: Option<u64>,
7915    #[serde(default, skip_serializing_if = "Option::is_none")]
7916    pub range_bits: Option<u64>,
7917    /// Whether the attribute was wrapped in a TiDB executable comment.
7918    #[serde(default)]
7919    pub executable_comment: bool,
7920}
7921
7922/// A TiDB-specific table option and its source syntax.
7923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7924#[cfg_attr(feature = "bindings", derive(TS))]
7925pub struct TiDBTableOption {
7926    pub kind: TiDBTableOptionKind,
7927    /// Whether the option was wrapped in a TiDB executable comment.
7928    #[serde(default)]
7929    pub executable_comment: bool,
7930}
7931
7932/// TiDB table options supported by `CREATE TABLE` and applicable `ALTER TABLE` forms.
7933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7934#[cfg_attr(feature = "bindings", derive(TS))]
7935#[serde(tag = "type", rename_all = "snake_case")]
7936pub enum TiDBTableOptionKind {
7937    ShardRowIdBits {
7938        bits: u64,
7939    },
7940    PreSplitRegions {
7941        regions: u64,
7942    },
7943    AutoRandomBase {
7944        value: u64,
7945    },
7946    /// `None` represents `PLACEMENT POLICY = DEFAULT`.
7947    PlacementPolicy {
7948        policy: Option<Identifier>,
7949    },
7950    Ttl {
7951        column: Identifier,
7952        interval: Interval,
7953        #[serde(default, skip_serializing_if = "Option::is_none")]
7954        enabled: Option<bool>,
7955    },
7956    TtlEnable {
7957        enabled: bool,
7958    },
7959    TtlJobInterval {
7960        interval: String,
7961    },
7962}
7963
7964/// CREATE TABLE statement
7965#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
7966#[cfg_attr(feature = "bindings", derive(TS))]
7967pub struct CreateTable {
7968    pub name: TableRef,
7969    /// ClickHouse: ON CLUSTER clause for distributed DDL
7970    #[serde(default, skip_serializing_if = "Option::is_none")]
7971    pub on_cluster: Option<OnCluster>,
7972    pub columns: Vec<ColumnDef>,
7973    pub constraints: Vec<TableConstraint>,
7974    pub if_not_exists: bool,
7975    pub temporary: bool,
7976    pub or_replace: bool,
7977    /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake)
7978    #[serde(default, skip_serializing_if = "Option::is_none")]
7979    pub table_modifier: Option<String>,
7980    /// Dialect whose call semantics must be retained through independent generation.
7981    #[serde(default, skip_serializing_if = "Option::is_none")]
7982    #[ast(skip)]
7983    pub source_dialect: Option<crate::dialects::DialectType>,
7984
7985    pub as_select: Option<Expression>,
7986    /// Whether the AS SELECT was wrapped in parentheses
7987    #[serde(default)]
7988    pub as_select_parenthesized: bool,
7989    /// ON COMMIT behavior for temporary tables
7990    #[serde(default)]
7991    pub on_commit: Option<OnCommit>,
7992    /// Clone source table (e.g., CREATE TABLE t CLONE source_table)
7993    #[serde(default)]
7994    pub clone_source: Option<TableRef>,
7995    /// Time travel AT/BEFORE clause for CLONE (e.g., AT(TIMESTAMP => '...'))
7996    #[serde(default, skip_serializing_if = "Option::is_none")]
7997    pub clone_at_clause: Option<Expression>,
7998    /// Whether this is a COPY operation (BigQuery) vs CLONE (Snowflake/Databricks)
7999    #[serde(default)]
8000    pub is_copy: bool,
8001    /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
8002    #[serde(default)]
8003    pub shallow_clone: bool,
8004    /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
8005    #[serde(default)]
8006    pub deep_clone: bool,
8007    /// Leading comments before the statement
8008    #[serde(default)]
8009    pub leading_comments: Vec<String>,
8010    /// WITH properties (e.g., WITH (FORMAT='parquet'))
8011    #[serde(default)]
8012    pub with_properties: Vec<(String, String)>,
8013    /// Teradata: table options after name before columns (comma-separated)
8014    #[serde(default)]
8015    pub teradata_post_name_options: Vec<String>,
8016    /// Teradata: WITH DATA (true) or WITH NO DATA (false) after AS SELECT
8017    #[serde(default)]
8018    pub with_data: Option<bool>,
8019    /// Teradata: AND STATISTICS (true) or AND NO STATISTICS (false)
8020    #[serde(default)]
8021    pub with_statistics: Option<bool>,
8022    /// Teradata: Index specifications (NO PRIMARY INDEX, UNIQUE PRIMARY INDEX, etc.)
8023    #[serde(default)]
8024    pub teradata_indexes: Vec<TeradataIndex>,
8025    /// WITH clause (CTEs) - for CREATE TABLE ... AS WITH ... SELECT ...
8026    #[serde(default)]
8027    pub with_cte: Option<With>,
8028    /// Table properties like DEFAULT COLLATE (BigQuery)
8029    #[serde(default)]
8030    pub properties: Vec<Expression>,
8031    /// PostgreSQL PARTITION OF property (e.g., CREATE TABLE t PARTITION OF parent ...)
8032    #[serde(default, skip_serializing_if = "Option::is_none")]
8033    pub partition_of: Option<Expression>,
8034    /// TSQL: WITH(SYSTEM_VERSIONING=ON(...)) after column definitions
8035    #[serde(default)]
8036    pub post_table_properties: Vec<Expression>,
8037    /// MySQL table options after column definitions (ENGINE=val, AUTO_INCREMENT=val, etc.)
8038    #[serde(default)]
8039    pub mysql_table_options: Vec<(String, String)>,
8040    /// TiDB-specific table options after column definitions.
8041    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8042    pub tidb_table_options: Vec<TiDBTableOption>,
8043    /// PostgreSQL INHERITS clause: INHERITS (parent1, parent2, ...)
8044    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8045    pub inherits: Vec<TableRef>,
8046    /// TSQL ON filegroup or ON filegroup (partition_column) clause
8047    #[serde(default, skip_serializing_if = "Option::is_none")]
8048    pub on_property: Option<OnProperty>,
8049    /// Snowflake: COPY GRANTS clause to copy privileges from replaced table
8050    #[serde(default)]
8051    pub copy_grants: bool,
8052    /// Snowflake: USING TEMPLATE expression for schema inference
8053    #[serde(default, skip_serializing_if = "Option::is_none")]
8054    pub using_template: Option<Box<Expression>>,
8055    /// StarRocks: ROLLUP (r1(col1, col2), r2(col1))
8056    #[serde(default, skip_serializing_if = "Option::is_none")]
8057    pub rollup: Option<RollupProperty>,
8058    /// ClickHouse: UUID 'xxx' clause after table name
8059    #[serde(default, skip_serializing_if = "Option::is_none")]
8060    pub uuid: Option<String>,
8061    /// WITH PARTITION COLUMNS (col_name col_type, ...) — currently used by BigQuery
8062    /// for hive-partitioned external tables. Not dialect-prefixed since the syntax
8063    /// could appear in other engines.
8064    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8065    pub with_partition_columns: Vec<ColumnDef>,
8066    /// WITH CONNECTION `project.region.connection` — currently used by BigQuery
8067    /// for external tables that reference a Cloud Resource connection.
8068    #[serde(default, skip_serializing_if = "Option::is_none")]
8069    pub with_connection: Option<TableRef>,
8070}
8071
8072/// Teradata index specification for CREATE TABLE
8073#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8074#[cfg_attr(feature = "bindings", derive(TS))]
8075pub struct TeradataIndex {
8076    /// Index kind: NoPrimary, Primary, PrimaryAmp, Unique, UniquePrimary
8077    pub kind: TeradataIndexKind,
8078    /// Optional index name
8079    pub name: Option<String>,
8080    /// Optional column list
8081    pub columns: Vec<String>,
8082}
8083
8084/// Kind of Teradata index
8085#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8086#[cfg_attr(feature = "bindings", derive(TS))]
8087pub enum TeradataIndexKind {
8088    /// NO PRIMARY INDEX
8089    NoPrimary,
8090    /// PRIMARY INDEX
8091    Primary,
8092    /// PRIMARY AMP INDEX
8093    PrimaryAmp,
8094    /// UNIQUE INDEX
8095    Unique,
8096    /// UNIQUE PRIMARY INDEX
8097    UniquePrimary,
8098    /// INDEX (secondary, non-primary)
8099    Secondary,
8100}
8101
8102impl CreateTable {
8103    pub fn new(name: impl Into<String>) -> Self {
8104        Self {
8105            name: TableRef::new(name),
8106            on_cluster: None,
8107            columns: Vec::new(),
8108            constraints: Vec::new(),
8109            if_not_exists: false,
8110            temporary: false,
8111            or_replace: false,
8112            table_modifier: None,
8113            source_dialect: None,
8114            as_select: None,
8115            as_select_parenthesized: false,
8116            on_commit: None,
8117            clone_source: None,
8118            clone_at_clause: None,
8119            shallow_clone: false,
8120            deep_clone: false,
8121            is_copy: false,
8122            leading_comments: Vec::new(),
8123            with_properties: Vec::new(),
8124            teradata_post_name_options: Vec::new(),
8125            with_data: None,
8126            with_statistics: None,
8127            teradata_indexes: Vec::new(),
8128            with_cte: None,
8129            properties: Vec::new(),
8130            partition_of: None,
8131            post_table_properties: Vec::new(),
8132            mysql_table_options: Vec::new(),
8133            tidb_table_options: Vec::new(),
8134            inherits: Vec::new(),
8135            on_property: None,
8136            copy_grants: false,
8137            using_template: None,
8138            rollup: None,
8139            uuid: None,
8140            with_partition_columns: Vec::new(),
8141            with_connection: None,
8142        }
8143    }
8144}
8145
8146/// Sort order for PRIMARY KEY ASC/DESC
8147#[derive(
8148    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Serialize, Deserialize,
8149)]
8150#[cfg_attr(feature = "bindings", derive(TS))]
8151pub enum SortOrder {
8152    Asc,
8153    Desc,
8154}
8155
8156/// Type of column constraint for tracking order
8157#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8158#[cfg_attr(feature = "bindings", derive(TS))]
8159pub enum ConstraintType {
8160    NotNull,
8161    Null,
8162    PrimaryKey,
8163    Unique,
8164    Default,
8165    AutoIncrement,
8166    AutoRandom,
8167    Collate,
8168    Comment,
8169    References,
8170    Check,
8171    GeneratedAsIdentity,
8172    /// Snowflake: TAG (key='value', ...)
8173    Tags,
8174    /// Computed/generated column
8175    ComputedColumn,
8176    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END
8177    GeneratedAsRow,
8178    /// MySQL: ON UPDATE expression
8179    OnUpdate,
8180    /// PATH constraint for XMLTABLE/JSON_TABLE columns
8181    Path,
8182    /// Redshift: ENCODE encoding_type
8183    Encode,
8184}
8185
8186/// Column definition in CREATE TABLE
8187#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8188#[cfg_attr(feature = "bindings", derive(TS))]
8189pub struct ColumnDef {
8190    pub name: Identifier,
8191    pub data_type: DataType,
8192    pub nullable: Option<bool>,
8193    pub default: Option<Expression>,
8194    pub primary_key: bool,
8195    /// Sort order for PRIMARY KEY (ASC/DESC)
8196    #[serde(default)]
8197    pub primary_key_order: Option<SortOrder>,
8198    pub unique: bool,
8199    /// PostgreSQL 15+: UNIQUE NULLS NOT DISTINCT
8200    #[serde(default)]
8201    pub unique_nulls_not_distinct: bool,
8202    pub auto_increment: bool,
8203    /// TiDB distributed primary-key allocation attribute.
8204    #[serde(default, skip_serializing_if = "Option::is_none")]
8205    pub auto_random: Option<TiDBAutoRandom>,
8206    pub comment: Option<String>,
8207    pub constraints: Vec<ColumnConstraint>,
8208    /// Track original order of constraints for accurate regeneration
8209    #[serde(default)]
8210    pub constraint_order: Vec<ConstraintType>,
8211    /// Teradata: FORMAT 'pattern'
8212    #[serde(default)]
8213    pub format: Option<String>,
8214    /// Teradata: TITLE 'title'
8215    #[serde(default)]
8216    pub title: Option<String>,
8217    /// Teradata: INLINE LENGTH n
8218    #[serde(default)]
8219    pub inline_length: Option<u64>,
8220    /// Teradata: COMPRESS or COMPRESS (values) or COMPRESS 'value'
8221    #[serde(default)]
8222    pub compress: Option<Vec<Expression>>,
8223    /// Teradata: CHARACTER SET name
8224    #[serde(default)]
8225    pub character_set: Option<String>,
8226    /// Teradata: UPPERCASE
8227    #[serde(default)]
8228    pub uppercase: bool,
8229    /// Teradata: CASESPECIFIC / NOT CASESPECIFIC (None = not specified, Some(true) = CASESPECIFIC, Some(false) = NOT CASESPECIFIC)
8230    #[serde(default)]
8231    pub casespecific: Option<bool>,
8232    /// Snowflake: AUTOINCREMENT START value
8233    #[serde(default)]
8234    pub auto_increment_start: Option<Box<Expression>>,
8235    /// Snowflake: AUTOINCREMENT INCREMENT value
8236    #[serde(default)]
8237    pub auto_increment_increment: Option<Box<Expression>>,
8238    /// Snowflake: AUTOINCREMENT ORDER/NOORDER (true = ORDER, false = NOORDER, None = not specified)
8239    #[serde(default)]
8240    pub auto_increment_order: Option<bool>,
8241    /// MySQL: UNSIGNED modifier
8242    #[serde(default)]
8243    pub unsigned: bool,
8244    /// MySQL: ZEROFILL modifier
8245    #[serde(default)]
8246    pub zerofill: bool,
8247    /// MySQL: ON UPDATE expression (e.g., ON UPDATE CURRENT_TIMESTAMP)
8248    #[serde(default, skip_serializing_if = "Option::is_none")]
8249    pub on_update: Option<Expression>,
8250    /// MySQL: column VISIBLE/INVISIBLE modifier.
8251    #[serde(default, skip_serializing_if = "Option::is_none")]
8252    pub visible: Option<bool>,
8253    /// Named constraint for UNIQUE (e.g., CONSTRAINT must_be_different UNIQUE)
8254    #[serde(default, skip_serializing_if = "Option::is_none")]
8255    pub unique_constraint_name: Option<String>,
8256    /// Named constraint for NOT NULL (e.g., CONSTRAINT present NOT NULL)
8257    #[serde(default, skip_serializing_if = "Option::is_none")]
8258    pub not_null_constraint_name: Option<String>,
8259    /// Named constraint for PRIMARY KEY (e.g., CONSTRAINT pk_name PRIMARY KEY)
8260    #[serde(default, skip_serializing_if = "Option::is_none")]
8261    pub primary_key_constraint_name: Option<String>,
8262    /// Named constraint for CHECK (e.g., CONSTRAINT chk_name CHECK(...))
8263    #[serde(default, skip_serializing_if = "Option::is_none")]
8264    pub check_constraint_name: Option<String>,
8265    /// BigQuery: OPTIONS (key=value, ...) on column
8266    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8267    pub options: Vec<Expression>,
8268    /// SQLite: Column definition without explicit type
8269    #[serde(default)]
8270    pub no_type: bool,
8271    /// Redshift: ENCODE encoding_type (e.g., ZSTD, DELTA, LZO, etc.)
8272    #[serde(default, skip_serializing_if = "Option::is_none")]
8273    pub encoding: Option<String>,
8274    /// ClickHouse: CODEC(LZ4HC(9), ZSTD, DELTA)
8275    #[serde(default, skip_serializing_if = "Option::is_none")]
8276    pub codec: Option<String>,
8277    /// ClickHouse: EPHEMERAL [expr] modifier
8278    #[serde(default, skip_serializing_if = "Option::is_none")]
8279    pub ephemeral: Option<Option<Box<Expression>>>,
8280    /// ClickHouse: MATERIALIZED expr modifier
8281    #[serde(default, skip_serializing_if = "Option::is_none")]
8282    pub materialized_expr: Option<Box<Expression>>,
8283    /// ClickHouse: ALIAS expr modifier
8284    #[serde(default, skip_serializing_if = "Option::is_none")]
8285    pub alias_expr: Option<Box<Expression>>,
8286    /// ClickHouse: TTL expr modifier on columns
8287    #[serde(default, skip_serializing_if = "Option::is_none")]
8288    pub ttl_expr: Option<Box<Expression>>,
8289    /// TSQL: NOT FOR REPLICATION
8290    #[serde(default)]
8291    pub not_for_replication: bool,
8292}
8293
8294impl ColumnDef {
8295    pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
8296        Self {
8297            name: Identifier::new(name),
8298            data_type,
8299            nullable: None,
8300            default: None,
8301            primary_key: false,
8302            primary_key_order: None,
8303            unique: false,
8304            unique_nulls_not_distinct: false,
8305            auto_increment: false,
8306            auto_random: None,
8307            comment: None,
8308            constraints: Vec::new(),
8309            constraint_order: Vec::new(),
8310            format: None,
8311            title: None,
8312            inline_length: None,
8313            compress: None,
8314            character_set: None,
8315            uppercase: false,
8316            casespecific: None,
8317            auto_increment_start: None,
8318            auto_increment_increment: None,
8319            auto_increment_order: None,
8320            unsigned: false,
8321            zerofill: false,
8322            on_update: None,
8323            visible: None,
8324            unique_constraint_name: None,
8325            not_null_constraint_name: None,
8326            primary_key_constraint_name: None,
8327            check_constraint_name: None,
8328            options: Vec::new(),
8329            no_type: false,
8330            encoding: None,
8331            codec: None,
8332            ephemeral: None,
8333            materialized_expr: None,
8334            alias_expr: None,
8335            ttl_expr: None,
8336            not_for_replication: false,
8337        }
8338    }
8339}
8340
8341/// Column-level constraint
8342#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8343#[cfg_attr(feature = "bindings", derive(TS))]
8344pub enum ColumnConstraint {
8345    NotNull,
8346    Null,
8347    Unique,
8348    PrimaryKey,
8349    Default(Expression),
8350    Check(Expression),
8351    References(ForeignKeyRef),
8352    GeneratedAsIdentity(GeneratedAsIdentity),
8353    Collate(Identifier),
8354    Comment(String),
8355    /// Snowflake: TAG (key='value', ...)
8356    Tags(Tags),
8357    /// Computed/generated column: GENERATED ALWAYS AS (expr) STORED|VIRTUAL (MySQL/PostgreSQL)
8358    /// or AS (expr) PERSISTED [NOT NULL] (TSQL)
8359    ComputedColumn(ComputedColumn),
8360    /// TSQL temporal: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8361    GeneratedAsRow(GeneratedAsRow),
8362    /// PATH constraint for XMLTABLE/JSON_TABLE columns: PATH 'xpath'
8363    Path(Expression),
8364}
8365
8366/// Computed/generated column constraint
8367#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8368#[cfg_attr(feature = "bindings", derive(TS))]
8369pub struct ComputedColumn {
8370    /// The expression that computes the column value
8371    pub expression: Box<Expression>,
8372    /// PERSISTED (TSQL) or STORED (MySQL/PostgreSQL) = true; VIRTUAL = false; None = not specified
8373    #[serde(default)]
8374    pub persisted: bool,
8375    /// NOT NULL (TSQL computed columns)
8376    #[serde(default)]
8377    pub not_null: bool,
8378    /// The persistence keyword used: "STORED", "VIRTUAL", or "PERSISTED"
8379    /// When None, defaults to dialect-appropriate output
8380    #[serde(default)]
8381    pub persistence_kind: Option<String>,
8382    /// Optional data type for SingleStore: AS (expr) PERSISTED TYPE NOT NULL
8383    #[serde(default, skip_serializing_if = "Option::is_none")]
8384    pub data_type: Option<DataType>,
8385}
8386
8387/// TSQL temporal column constraint: GENERATED ALWAYS AS ROW START|END [HIDDEN]
8388#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8389#[cfg_attr(feature = "bindings", derive(TS))]
8390pub struct GeneratedAsRow {
8391    /// true = ROW START, false = ROW END
8392    pub start: bool,
8393    /// HIDDEN modifier
8394    #[serde(default)]
8395    pub hidden: bool,
8396}
8397
8398/// Generated identity column constraint
8399#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8400#[cfg_attr(feature = "bindings", derive(TS))]
8401pub struct GeneratedAsIdentity {
8402    /// True for ALWAYS, False for BY DEFAULT
8403    pub always: bool,
8404    /// ON NULL (only valid with BY DEFAULT)
8405    pub on_null: bool,
8406    /// START WITH value
8407    pub start: Option<Box<Expression>>,
8408    /// INCREMENT BY value
8409    pub increment: Option<Box<Expression>>,
8410    /// MINVALUE
8411    pub minvalue: Option<Box<Expression>>,
8412    /// MAXVALUE
8413    pub maxvalue: Option<Box<Expression>>,
8414    /// CYCLE option - Some(true) = CYCLE, Some(false) = NO CYCLE, None = not specified
8415    pub cycle: Option<bool>,
8416}
8417
8418/// Constraint modifiers (shared between table-level constraints)
8419#[derive(
8420    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
8421)]
8422#[cfg_attr(feature = "bindings", derive(TS))]
8423pub struct ConstraintModifiers {
8424    /// ENFORCED / NOT ENFORCED
8425    pub enforced: Option<bool>,
8426    /// DEFERRABLE / NOT DEFERRABLE
8427    pub deferrable: Option<bool>,
8428    /// INITIALLY DEFERRED / INITIALLY IMMEDIATE
8429    pub initially_deferred: Option<bool>,
8430    /// NORELY (Oracle)
8431    pub norely: bool,
8432    /// RELY (Oracle)
8433    pub rely: bool,
8434    /// USING index type (MySQL): BTREE or HASH
8435    #[serde(default)]
8436    pub using: Option<String>,
8437    /// True if USING appeared before columns (MySQL: INDEX USING BTREE (col) vs INDEX (col) USING BTREE)
8438    #[serde(default)]
8439    pub using_before_columns: bool,
8440    /// MySQL index COMMENT 'text'
8441    #[serde(default, skip_serializing_if = "Option::is_none")]
8442    pub comment: Option<String>,
8443    /// MySQL index VISIBLE/INVISIBLE
8444    #[serde(default, skip_serializing_if = "Option::is_none")]
8445    pub visible: Option<bool>,
8446    /// MySQL ENGINE_ATTRIBUTE = 'value'
8447    #[serde(default, skip_serializing_if = "Option::is_none")]
8448    pub engine_attribute: Option<String>,
8449    /// MySQL WITH PARSER name
8450    #[serde(default, skip_serializing_if = "Option::is_none")]
8451    pub with_parser: Option<String>,
8452    /// PostgreSQL NOT VALID (constraint is not validated against existing data)
8453    #[serde(default)]
8454    pub not_valid: bool,
8455    /// TSQL CLUSTERED/NONCLUSTERED modifier
8456    #[serde(default, skip_serializing_if = "Option::is_none")]
8457    pub clustered: Option<String>,
8458    /// SQLite ON CONFLICT clause: ROLLBACK, ABORT, FAIL, IGNORE, or REPLACE
8459    #[serde(default, skip_serializing_if = "Option::is_none")]
8460    pub on_conflict: Option<String>,
8461    /// TSQL WITH options (e.g., PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF)
8462    #[serde(default, skip_serializing_if = "Vec::is_empty")]
8463    pub with_options: Vec<(String, String)>,
8464    /// TSQL ON filegroup (e.g., ON [INDEX], ON [PRIMARY])
8465    #[serde(default, skip_serializing_if = "Option::is_none")]
8466    pub on_filegroup: Option<Identifier>,
8467}
8468
8469/// Table-level constraint
8470#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8471#[cfg_attr(feature = "bindings", derive(TS))]
8472pub enum TableConstraint {
8473    PrimaryKey {
8474        name: Option<Identifier>,
8475        columns: Vec<Identifier>,
8476        /// Databricks primary-key columns marked with the TIMESERIES attribute.
8477        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8478        timeseries_columns: Vec<Identifier>,
8479        /// INCLUDE (columns) - non-key columns included in the index (PostgreSQL)
8480        #[serde(default)]
8481        include_columns: Vec<Identifier>,
8482        #[serde(default)]
8483        modifiers: ConstraintModifiers,
8484        /// Whether the CONSTRAINT keyword was used (vs MySQL's `PRIMARY KEY name (cols)` syntax)
8485        #[serde(default)]
8486        has_constraint_keyword: bool,
8487    },
8488    Unique {
8489        name: Option<Identifier>,
8490        columns: Vec<Identifier>,
8491        /// Whether columns are parenthesized (false for UNIQUE idx_name without parens)
8492        #[serde(default)]
8493        columns_parenthesized: bool,
8494        #[serde(default)]
8495        modifiers: ConstraintModifiers,
8496        /// Whether the CONSTRAINT keyword was used (vs MySQL's `UNIQUE name (cols)` syntax)
8497        #[serde(default)]
8498        has_constraint_keyword: bool,
8499        /// PostgreSQL 15+: NULLS NOT DISTINCT
8500        #[serde(default)]
8501        nulls_not_distinct: bool,
8502    },
8503    ForeignKey {
8504        name: Option<Identifier>,
8505        columns: Vec<Identifier>,
8506        #[serde(default)]
8507        references: Option<ForeignKeyRef>,
8508        /// ON DELETE action when REFERENCES is absent
8509        #[serde(default)]
8510        on_delete: Option<ReferentialAction>,
8511        /// ON UPDATE action when REFERENCES is absent
8512        #[serde(default)]
8513        on_update: Option<ReferentialAction>,
8514        #[serde(default)]
8515        modifiers: ConstraintModifiers,
8516    },
8517    Check {
8518        name: Option<Identifier>,
8519        expression: Expression,
8520        #[serde(default)]
8521        modifiers: ConstraintModifiers,
8522    },
8523    /// ClickHouse ASSUME constraint (query optimization assumption)
8524    Assume {
8525        name: Option<Identifier>,
8526        expression: Expression,
8527    },
8528    /// TSQL named DEFAULT constraint: CONSTRAINT name DEFAULT value FOR column
8529    Default {
8530        name: Option<Identifier>,
8531        expression: Expression,
8532        column: Identifier,
8533    },
8534    /// INDEX / KEY constraint (MySQL)
8535    Index {
8536        name: Option<Identifier>,
8537        columns: Vec<Identifier>,
8538        /// Expression-capable index key parts. This is used when an index contains
8539        /// functional key parts that cannot be represented by `columns`.
8540        #[serde(default, skip_serializing_if = "Vec::is_empty")]
8541        key_parts: Vec<IndexKeyPart>,
8542        /// Index kind: UNIQUE, FULLTEXT, SPATIAL, etc.
8543        #[serde(default)]
8544        kind: Option<String>,
8545        #[serde(default)]
8546        modifiers: ConstraintModifiers,
8547        /// True if KEY keyword was used instead of INDEX
8548        #[serde(default)]
8549        use_key_keyword: bool,
8550        /// ClickHouse: indexed expression (instead of columns)
8551        #[serde(default, skip_serializing_if = "Option::is_none")]
8552        expression: Option<Box<Expression>>,
8553        /// ClickHouse: TYPE type_func(args)
8554        #[serde(default, skip_serializing_if = "Option::is_none")]
8555        index_type: Option<Box<Expression>>,
8556        /// ClickHouse: GRANULARITY n
8557        #[serde(default, skip_serializing_if = "Option::is_none")]
8558        granularity: Option<Box<Expression>>,
8559    },
8560    /// ClickHouse PROJECTION definition
8561    Projection {
8562        name: Identifier,
8563        expression: Expression,
8564    },
8565    /// PostgreSQL LIKE clause: LIKE source_table [INCLUDING|EXCLUDING options]
8566    Like {
8567        source: TableRef,
8568        /// Options as (INCLUDING|EXCLUDING, property) pairs
8569        options: Vec<(LikeOptionAction, String)>,
8570    },
8571    /// TSQL PERIOD FOR SYSTEM_TIME (start_col, end_col)
8572    PeriodForSystemTime {
8573        start_col: Identifier,
8574        end_col: Identifier,
8575    },
8576    /// PostgreSQL EXCLUDE constraint
8577    /// EXCLUDE [USING method] (element WITH operator, ...) [INCLUDE (cols)] [WHERE (expr)] [WITH (params)]
8578    Exclude {
8579        name: Option<Identifier>,
8580        /// Index access method (gist, btree, etc.)
8581        #[serde(default)]
8582        using: Option<String>,
8583        /// Elements: (expression, operator) pairs
8584        elements: Vec<ExcludeElement>,
8585        /// INCLUDE columns
8586        #[serde(default)]
8587        include_columns: Vec<Identifier>,
8588        /// WHERE predicate
8589        #[serde(default)]
8590        where_clause: Option<Box<Expression>>,
8591        /// WITH (storage_parameters)
8592        #[serde(default)]
8593        with_params: Vec<(String, String)>,
8594        /// USING INDEX TABLESPACE tablespace_name
8595        #[serde(default)]
8596        using_index_tablespace: Option<String>,
8597        #[serde(default)]
8598        modifiers: ConstraintModifiers,
8599    },
8600    /// Snowflake TAG clause: TAG (key='value', key2='value2')
8601    Tags(Tags),
8602    /// PostgreSQL table-level INITIALLY DEFERRED/INITIALLY IMMEDIATE
8603    /// This is a standalone clause at the end of the CREATE TABLE that sets the default
8604    /// for all deferrable constraints in the table
8605    InitiallyDeferred {
8606        /// true = INITIALLY DEFERRED, false = INITIALLY IMMEDIATE
8607        deferred: bool,
8608    },
8609}
8610
8611/// Element in an EXCLUDE constraint: expression WITH operator
8612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8613#[cfg_attr(feature = "bindings", derive(TS))]
8614pub struct ExcludeElement {
8615    /// The column expression (may include operator class, ordering, nulls)
8616    pub expression: String,
8617    /// The operator (e.g., &&, =)
8618    pub operator: String,
8619}
8620
8621/// Action for LIKE clause options
8622#[derive(
8623    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8624)]
8625#[cfg_attr(feature = "bindings", derive(TS))]
8626pub enum LikeOptionAction {
8627    Including,
8628    Excluding,
8629}
8630
8631/// MATCH type for foreign keys
8632#[derive(
8633    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8634)]
8635#[cfg_attr(feature = "bindings", derive(TS))]
8636pub enum MatchType {
8637    Full,
8638    Partial,
8639    Simple,
8640}
8641
8642/// Foreign key reference
8643#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8644#[cfg_attr(feature = "bindings", derive(TS))]
8645pub struct ForeignKeyRef {
8646    pub table: TableRef,
8647    pub columns: Vec<Identifier>,
8648    pub on_delete: Option<ReferentialAction>,
8649    pub on_update: Option<ReferentialAction>,
8650    /// True if ON UPDATE appears before ON DELETE in the original SQL
8651    #[serde(default)]
8652    pub on_update_first: bool,
8653    /// MATCH clause (FULL, PARTIAL, SIMPLE)
8654    #[serde(default)]
8655    pub match_type: Option<MatchType>,
8656    /// True if MATCH appears after ON DELETE/ON UPDATE clauses
8657    #[serde(default)]
8658    pub match_after_actions: bool,
8659    /// CONSTRAINT name (e.g., CONSTRAINT fk_name REFERENCES ...)
8660    #[serde(default)]
8661    pub constraint_name: Option<String>,
8662    /// DEFERRABLE / NOT DEFERRABLE
8663    #[serde(default)]
8664    pub deferrable: Option<bool>,
8665    /// Snowflake: FOREIGN KEY REFERENCES (includes FOREIGN KEY keywords before REFERENCES)
8666    #[serde(default)]
8667    pub has_foreign_key_keywords: bool,
8668}
8669
8670/// Referential action for foreign keys
8671#[derive(
8672    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
8673)]
8674#[cfg_attr(feature = "bindings", derive(TS))]
8675pub enum ReferentialAction {
8676    Cascade,
8677    SetNull,
8678    SetDefault,
8679    Restrict,
8680    NoAction,
8681}
8682
8683/// DROP TABLE statement
8684#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8685#[cfg_attr(feature = "bindings", derive(TS))]
8686pub struct DropTable {
8687    pub names: Vec<TableRef>,
8688    pub if_exists: bool,
8689    pub cascade: bool,
8690    /// Oracle: CASCADE CONSTRAINTS
8691    #[serde(default)]
8692    pub cascade_constraints: bool,
8693    /// Oracle: PURGE
8694    #[serde(default)]
8695    pub purge: bool,
8696    /// Comments that appear before the DROP keyword (e.g., leading line comments)
8697    #[serde(default)]
8698    pub leading_comments: Vec<String>,
8699    /// TSQL: OBJECT_ID arguments for reconstructing IF OBJECT_ID(...) IS NOT NULL pattern
8700    /// When set, TSQL generator outputs IF NOT OBJECT_ID(...) IS NULL BEGIN DROP TABLE ...; END
8701    #[serde(default, skip_serializing_if = "Option::is_none")]
8702    pub object_id_args: Option<String>,
8703    /// ClickHouse: SYNC modifier
8704    #[serde(default)]
8705    pub sync: bool,
8706    /// Snowflake: DROP ICEBERG TABLE
8707    #[serde(default)]
8708    pub iceberg: bool,
8709    /// RESTRICT modifier (opposite of CASCADE)
8710    #[serde(default)]
8711    pub restrict: bool,
8712}
8713
8714impl DropTable {
8715    pub fn new(name: impl Into<String>) -> Self {
8716        Self {
8717            names: vec![TableRef::new(name)],
8718            if_exists: false,
8719            cascade: false,
8720            cascade_constraints: false,
8721            purge: false,
8722            leading_comments: Vec::new(),
8723            object_id_args: None,
8724            sync: false,
8725            iceberg: false,
8726            restrict: false,
8727        }
8728    }
8729}
8730
8731/// UNDROP object statement (Snowflake, ClickHouse)
8732#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8733#[cfg_attr(feature = "bindings", derive(TS))]
8734pub struct Undrop {
8735    /// The object kind, e.g. "TABLE", "SCHEMA", "DATABASE", "DYNAMIC TABLE"
8736    pub kind: String,
8737    /// The object name
8738    pub name: TableRef,
8739    /// IF EXISTS clause
8740    #[serde(default)]
8741    pub if_exists: bool,
8742    /// Snowflake: optional RENAME TO target
8743    #[serde(default, skip_serializing_if = "Option::is_none")]
8744    pub rename_to: Option<TableRef>,
8745}
8746
8747/// Partition scope for a TiDB `SPLIT TABLE` statement.
8748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8749#[cfg_attr(feature = "bindings", derive(TS))]
8750#[serde(tag = "type", rename_all = "snake_case")]
8751pub enum SplitTablePartitionScope {
8752    Table,
8753    AllPartitions,
8754    Partitions { names: Vec<Identifier> },
8755}
8756
8757/// Split-point specification for a TiDB `SPLIT TABLE` statement.
8758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8759#[cfg_attr(feature = "bindings", derive(TS))]
8760#[serde(tag = "type", rename_all = "snake_case")]
8761pub enum SplitTableMode {
8762    Between {
8763        lower: Vec<Expression>,
8764        upper: Vec<Expression>,
8765        regions: u64,
8766    },
8767    By {
8768        points: Vec<Vec<Expression>>,
8769    },
8770}
8771
8772/// TiDB `SPLIT [PARTITION] TABLE` statement.
8773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8774#[cfg_attr(feature = "bindings", derive(TS))]
8775pub struct SplitTable {
8776    pub table: TableRef,
8777    pub partition_scope: SplitTablePartitionScope,
8778    #[serde(default, skip_serializing_if = "Option::is_none")]
8779    pub index: Option<Identifier>,
8780    pub mode: SplitTableMode,
8781}
8782
8783/// TiDB `FLASHBACK TABLE table [TO new_name]` statement.
8784#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8785#[cfg_attr(feature = "bindings", derive(TS))]
8786pub struct FlashbackTable {
8787    pub table: TableRef,
8788    #[serde(default, skip_serializing_if = "Option::is_none")]
8789    pub rename_to: Option<Identifier>,
8790}
8791
8792/// ALTER TABLE statement
8793#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8794#[cfg_attr(feature = "bindings", derive(TS))]
8795pub struct AlterTable {
8796    pub name: TableRef,
8797    pub actions: Vec<AlterTableAction>,
8798    /// IF EXISTS clause
8799    #[serde(default)]
8800    pub if_exists: bool,
8801    /// MySQL: ALGORITHM=INPLACE|COPY|DEFAULT|INSTANT
8802    #[serde(default, skip_serializing_if = "Option::is_none")]
8803    pub algorithm: Option<String>,
8804    /// MySQL: LOCK=NONE|SHARED|DEFAULT|EXCLUSIVE
8805    #[serde(default, skip_serializing_if = "Option::is_none")]
8806    pub lock: Option<String>,
8807    /// TSQL: WITH CHECK / WITH NOCHECK modifier before ADD CONSTRAINT
8808    #[serde(default, skip_serializing_if = "Option::is_none")]
8809    pub with_check: Option<String>,
8810    /// Hive: PARTITION clause before actions (e.g., ALTER TABLE x PARTITION(y=z) ADD COLUMN ...)
8811    #[serde(default, skip_serializing_if = "Option::is_none")]
8812    pub partition: Option<Vec<(Identifier, Expression)>>,
8813    /// ClickHouse: ON CLUSTER clause for distributed DDL
8814    #[serde(default, skip_serializing_if = "Option::is_none")]
8815    pub on_cluster: Option<OnCluster>,
8816    /// Snowflake: ALTER ICEBERG TABLE
8817    #[serde(default, skip_serializing_if = "Option::is_none")]
8818    pub table_modifier: Option<String>,
8819}
8820
8821impl AlterTable {
8822    pub fn new(name: impl Into<String>) -> Self {
8823        Self {
8824            name: TableRef::new(name),
8825            actions: Vec::new(),
8826            if_exists: false,
8827            algorithm: None,
8828            lock: None,
8829            with_check: None,
8830            partition: None,
8831            on_cluster: None,
8832            table_modifier: None,
8833        }
8834    }
8835}
8836
8837/// Column position for ADD COLUMN (MySQL/MariaDB)
8838#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8839#[cfg_attr(feature = "bindings", derive(TS))]
8840pub enum ColumnPosition {
8841    First,
8842    After(Identifier),
8843}
8844
8845/// Actions for ALTER TABLE
8846#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
8847#[cfg_attr(feature = "bindings", derive(TS))]
8848pub enum AlterTableAction {
8849    AddColumn {
8850        column: ColumnDef,
8851        if_not_exists: bool,
8852        position: Option<ColumnPosition>,
8853    },
8854    DropColumn {
8855        name: Identifier,
8856        if_exists: bool,
8857        cascade: bool,
8858    },
8859    RenameColumn {
8860        old_name: Identifier,
8861        new_name: Identifier,
8862        if_exists: bool,
8863    },
8864    AlterColumn {
8865        name: Identifier,
8866        action: AlterColumnAction,
8867        /// Whether this was parsed from MODIFY COLUMN syntax (MySQL)
8868        #[serde(default)]
8869        use_modify_keyword: bool,
8870    },
8871    /// MySQL/TiDB `MODIFY [COLUMN]` with a complete replacement column definition.
8872    ModifyColumn {
8873        column: ColumnDef,
8874        if_exists: bool,
8875        position: Option<ColumnPosition>,
8876    },
8877    RenameTable(TableRef),
8878    AddConstraint(TableConstraint),
8879    DropConstraint {
8880        name: Identifier,
8881        if_exists: bool,
8882    },
8883    /// DROP FOREIGN KEY action (Oracle/MySQL): ALTER TABLE t DROP FOREIGN KEY fk_name
8884    DropForeignKey {
8885        name: Identifier,
8886    },
8887    /// DROP PARTITION action (Hive/BigQuery)
8888    DropPartition {
8889        /// List of partitions to drop (each partition is a list of key=value pairs)
8890        partitions: Vec<Vec<(Identifier, Expression)>>,
8891        if_exists: bool,
8892    },
8893    /// ADD PARTITION action (Hive/Spark)
8894    AddPartition {
8895        /// The partition expression
8896        partition: Expression,
8897        if_not_exists: bool,
8898        location: Option<Expression>,
8899    },
8900    /// DELETE action (BigQuery): ALTER TABLE t DELETE WHERE condition
8901    Delete {
8902        where_clause: Expression,
8903    },
8904    /// SWAP WITH action (Snowflake): ALTER TABLE a SWAP WITH b
8905    SwapWith(TableRef),
8906    /// SET property action (Snowflake): ALTER TABLE t SET property=value
8907    SetProperty {
8908        properties: Vec<(String, Expression)>,
8909    },
8910    /// UNSET property action (Snowflake): ALTER TABLE t UNSET property
8911    UnsetProperty {
8912        properties: Vec<String>,
8913    },
8914    /// CLUSTER BY action (Snowflake): ALTER TABLE t CLUSTER BY (col1, col2)
8915    ClusterBy {
8916        expressions: Vec<Expression>,
8917    },
8918    /// SET TAG action (Snowflake): ALTER TABLE t SET TAG key='value'
8919    SetTag {
8920        expressions: Vec<(String, Expression)>,
8921    },
8922    /// UNSET TAG action (Snowflake): ALTER TABLE t UNSET TAG key1, key2
8923    UnsetTag {
8924        names: Vec<String>,
8925    },
8926    /// SET with parenthesized options (TSQL): ALTER TABLE t SET (SYSTEM_VERSIONING=ON, ...)
8927    SetOptions {
8928        expressions: Vec<Expression>,
8929    },
8930    /// ALTER INDEX action (MySQL): ALTER TABLE t ALTER INDEX i VISIBLE/INVISIBLE
8931    AlterIndex {
8932        name: Identifier,
8933        visible: bool,
8934    },
8935    /// PostgreSQL: ALTER TABLE t SET LOGGED/UNLOGGED/WITHOUT CLUSTER/WITHOUT OIDS/ACCESS METHOD/TABLESPACE
8936    SetAttribute {
8937        attribute: String,
8938    },
8939    /// Snowflake: ALTER TABLE t SET STAGE_FILE_FORMAT = (options)
8940    SetStageFileFormat {
8941        options: Option<Expression>,
8942    },
8943    /// Snowflake: ALTER TABLE t SET STAGE_COPY_OPTIONS = (options)
8944    SetStageCopyOptions {
8945        options: Option<Expression>,
8946    },
8947    /// Hive/Spark: ADD COLUMNS (col1 TYPE, col2 TYPE) [CASCADE]
8948    AddColumns {
8949        columns: Vec<ColumnDef>,
8950        cascade: bool,
8951    },
8952    /// Spark/Databricks: DROP COLUMNS (col1, col2, ...)
8953    DropColumns {
8954        names: Vec<Identifier>,
8955    },
8956    /// Hive/MySQL/SingleStore: CHANGE [COLUMN] old_name new_name [data_type] [COMMENT 'comment']
8957    /// In SingleStore, data_type can be omitted for simple column renames
8958    ChangeColumn {
8959        old_name: Identifier,
8960        new_name: Identifier,
8961        #[serde(default, skip_serializing_if = "Option::is_none")]
8962        data_type: Option<DataType>,
8963        comment: Option<String>,
8964        #[serde(default)]
8965        cascade: bool,
8966    },
8967    /// Redshift: ALTER TABLE t ALTER SORTKEY AUTO|NONE|(col1, col2)
8968    /// Also: ALTER TABLE t ALTER COMPOUND SORTKEY (col1, col2)
8969    AlterSortKey {
8970        /// AUTO or NONE keyword
8971        this: Option<String>,
8972        /// Column list for (col1, col2) syntax
8973        expressions: Vec<Expression>,
8974        /// Whether COMPOUND keyword was present
8975        compound: bool,
8976    },
8977    /// Redshift: ALTER TABLE t ALTER DISTSTYLE ALL|EVEN|AUTO|KEY
8978    /// Also: ALTER TABLE t ALTER DISTSTYLE KEY DISTKEY col
8979    /// Also: ALTER TABLE t ALTER DISTKEY col (shorthand for DISTSTYLE KEY DISTKEY col)
8980    AlterDistStyle {
8981        /// Distribution style: ALL, EVEN, AUTO, or KEY
8982        style: String,
8983        /// DISTKEY column (only when style is KEY)
8984        distkey: Option<Identifier>,
8985    },
8986    /// Redshift: ALTER TABLE t SET TABLE PROPERTIES ('a' = '5', 'b' = 'c')
8987    SetTableProperties {
8988        properties: Vec<(Expression, Expression)>,
8989    },
8990    /// Redshift: ALTER TABLE t SET LOCATION 's3://bucket/folder/'
8991    SetLocation {
8992        location: String,
8993    },
8994    /// Redshift: ALTER TABLE t SET FILE FORMAT AVRO
8995    SetFileFormat {
8996        format: String,
8997    },
8998    /// ClickHouse: ALTER TABLE t REPLACE PARTITION expr FROM source_table
8999    ReplacePartition {
9000        partition: Expression,
9001        source: Option<Box<Expression>>,
9002    },
9003    /// Set a TiDB-specific table option. `force` is valid for `AUTO_RANDOM_BASE`.
9004    SetTiDBTableOption {
9005        option: TiDBTableOption,
9006        #[serde(default)]
9007        force: bool,
9008    },
9009    /// TiDB `REMOVE TTL`.
9010    RemoveTiDBTtl {
9011        #[serde(default)]
9012        executable_comment: bool,
9013    },
9014    /// Raw SQL for dialect-specific ALTER TABLE actions (e.g., ClickHouse UPDATE/DELETE/DETACH/etc.)
9015    Raw {
9016        sql: String,
9017    },
9018}
9019
9020/// Actions for ALTER COLUMN
9021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9022#[cfg_attr(feature = "bindings", derive(TS))]
9023pub enum AlterColumnAction {
9024    SetDataType {
9025        data_type: DataType,
9026        /// USING expression for type conversion (PostgreSQL)
9027        using: Option<Expression>,
9028        /// COLLATE clause (TSQL: ALTER COLUMN col TYPE COLLATE collation_name)
9029        #[serde(default, skip_serializing_if = "Option::is_none")]
9030        collate: Option<String>,
9031    },
9032    SetDefault(Expression),
9033    DropDefault,
9034    SetNotNull,
9035    DropNotNull,
9036    /// Set column comment
9037    Comment(String),
9038    /// MySQL: SET VISIBLE
9039    SetVisible,
9040    /// MySQL: SET INVISIBLE
9041    SetInvisible,
9042}
9043
9044/// CREATE INDEX statement
9045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9046#[cfg_attr(feature = "bindings", derive(TS))]
9047pub struct CreateIndex {
9048    pub name: Identifier,
9049    pub table: TableRef,
9050    pub columns: Vec<IndexColumn>,
9051    /// Expression-capable index key parts. This is used when an index contains
9052    /// functional key parts that cannot be represented by `columns`.
9053    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9054    pub key_parts: Vec<IndexKeyPart>,
9055    pub unique: bool,
9056    pub if_not_exists: bool,
9057    pub using: Option<String>,
9058    /// TSQL CLUSTERED/NONCLUSTERED modifier
9059    #[serde(default)]
9060    pub clustered: Option<String>,
9061    /// PostgreSQL CONCURRENTLY modifier
9062    #[serde(default)]
9063    pub concurrently: bool,
9064    /// PostgreSQL WHERE clause for partial indexes
9065    #[serde(default)]
9066    pub where_clause: Option<Box<Expression>>,
9067    /// PostgreSQL INCLUDE columns
9068    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9069    pub include_columns: Vec<Identifier>,
9070    /// TSQL WITH options (e.g., allow_page_locks=on)
9071    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9072    pub with_options: Vec<(String, String)>,
9073    /// TSQL ON filegroup or partition scheme (e.g., ON PRIMARY, ON X([y]))
9074    #[serde(default)]
9075    pub on_filegroup: Option<String>,
9076}
9077
9078impl CreateIndex {
9079    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
9080        Self {
9081            name: Identifier::new(name),
9082            table: TableRef::new(table),
9083            columns: Vec::new(),
9084            key_parts: Vec::new(),
9085            unique: false,
9086            if_not_exists: false,
9087            using: None,
9088            clustered: None,
9089            concurrently: false,
9090            where_clause: None,
9091            include_columns: Vec::new(),
9092            with_options: Vec::new(),
9093            on_filegroup: None,
9094        }
9095    }
9096}
9097
9098/// Index column specification
9099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9100#[cfg_attr(feature = "bindings", derive(TS))]
9101pub struct IndexColumn {
9102    pub column: Identifier,
9103    pub desc: bool,
9104    /// Explicit ASC keyword was present
9105    #[serde(default)]
9106    pub asc: bool,
9107    pub nulls_first: Option<bool>,
9108    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops)
9109    #[serde(default, skip_serializing_if = "Option::is_none")]
9110    pub opclass: Option<String>,
9111}
9112
9113/// An expression-capable index key part.
9114#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9115#[cfg_attr(feature = "bindings", derive(TS))]
9116pub struct IndexKeyPart {
9117    pub expression: Box<Expression>,
9118    /// MySQL column prefix length, for example the `16` in `name(16)`.
9119    #[serde(default, skip_serializing_if = "Option::is_none")]
9120    pub prefix_length: Option<String>,
9121    pub desc: bool,
9122    /// Explicit ASC keyword was present.
9123    #[serde(default)]
9124    pub asc: bool,
9125    pub nulls_first: Option<bool>,
9126    /// PostgreSQL operator class (e.g., varchar_pattern_ops, public.gin_trgm_ops).
9127    #[serde(default, skip_serializing_if = "Option::is_none")]
9128    pub opclass: Option<String>,
9129}
9130
9131/// DROP INDEX statement
9132#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9133#[cfg_attr(feature = "bindings", derive(TS))]
9134pub struct DropIndex {
9135    pub name: TableRef,
9136    pub table: Option<TableRef>,
9137    pub if_exists: bool,
9138    /// PostgreSQL CONCURRENTLY modifier
9139    #[serde(default)]
9140    pub concurrently: bool,
9141}
9142
9143impl DropIndex {
9144    pub fn new(name: impl Into<String>) -> Self {
9145        Self {
9146            name: TableRef::new(name),
9147            table: None,
9148            if_exists: false,
9149            concurrently: false,
9150        }
9151    }
9152}
9153
9154/// View column definition with optional COMMENT and OPTIONS (BigQuery)
9155#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9156#[cfg_attr(feature = "bindings", derive(TS))]
9157pub struct ViewColumn {
9158    pub name: Identifier,
9159    pub comment: Option<String>,
9160    /// BigQuery: OPTIONS (key=value, ...) on column
9161    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9162    pub options: Vec<Expression>,
9163}
9164
9165impl ViewColumn {
9166    pub fn new(name: impl Into<String>) -> Self {
9167        Self {
9168            name: Identifier::new(name),
9169            comment: None,
9170            options: Vec::new(),
9171        }
9172    }
9173
9174    pub fn with_comment(name: impl Into<String>, comment: impl Into<String>) -> Self {
9175        Self {
9176            name: Identifier::new(name),
9177            comment: Some(comment.into()),
9178            options: Vec::new(),
9179        }
9180    }
9181}
9182
9183/// CREATE VIEW statement
9184#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9185#[cfg_attr(feature = "bindings", derive(TS))]
9186pub struct CreateView {
9187    pub name: TableRef,
9188    pub columns: Vec<ViewColumn>,
9189    pub query: Expression,
9190    pub or_replace: bool,
9191    /// TSQL: CREATE OR ALTER
9192    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9193    pub or_alter: bool,
9194    pub if_not_exists: bool,
9195    pub materialized: bool,
9196    pub temporary: bool,
9197    /// Snowflake: SECURE VIEW
9198    #[serde(default)]
9199    pub secure: bool,
9200    /// MySQL: ALGORITHM=UNDEFINED/MERGE/TEMPTABLE
9201    #[serde(skip_serializing_if = "Option::is_none")]
9202    pub algorithm: Option<String>,
9203    /// MySQL: DEFINER=user@host
9204    #[serde(skip_serializing_if = "Option::is_none")]
9205    pub definer: Option<String>,
9206    /// MySQL: SQL SECURITY DEFINER/INVOKER; Presto: SECURITY DEFINER/INVOKER
9207    #[serde(skip_serializing_if = "Option::is_none")]
9208    pub security: Option<FunctionSecurity>,
9209    /// True for MySQL-style "SQL SECURITY", false for Presto-style "SECURITY"
9210    #[serde(default = "default_true")]
9211    pub security_sql_style: bool,
9212    /// True when SQL SECURITY appears after the view name (not before VIEW keyword)
9213    #[serde(default)]
9214    pub security_after_name: bool,
9215    /// Whether the query was parenthesized: AS (SELECT ...)
9216    #[serde(default)]
9217    pub query_parenthesized: bool,
9218    /// Teradata: LOCKING mode (ROW, TABLE, DATABASE)
9219    #[serde(skip_serializing_if = "Option::is_none")]
9220    pub locking_mode: Option<String>,
9221    /// Teradata: LOCKING access type (ACCESS, READ, WRITE)
9222    #[serde(skip_serializing_if = "Option::is_none")]
9223    pub locking_access: Option<String>,
9224    /// Snowflake: COPY GRANTS
9225    #[serde(default)]
9226    pub copy_grants: bool,
9227    /// Snowflake: COMMENT = 'text'
9228    #[serde(skip_serializing_if = "Option::is_none", default)]
9229    pub comment: Option<String>,
9230    /// Snowflake: WITH ROW ACCESS POLICY ... clause
9231    #[serde(skip_serializing_if = "Option::is_none", default)]
9232    pub row_access_policy: Option<String>,
9233    /// Snowflake: TAG (name='value', ...)
9234    #[serde(default)]
9235    pub tags: Vec<(String, String)>,
9236    /// BigQuery: OPTIONS (key=value, ...)
9237    #[serde(default)]
9238    pub options: Vec<Expression>,
9239    /// Doris: BUILD IMMEDIATE/DEFERRED for materialized views
9240    #[serde(skip_serializing_if = "Option::is_none", default)]
9241    pub build: Option<String>,
9242    /// Doris: REFRESH property for materialized views
9243    #[serde(skip_serializing_if = "Option::is_none", default)]
9244    pub refresh: Option<Box<RefreshTriggerProperty>>,
9245    /// Doris: Schema with typed column definitions for materialized views
9246    /// This is used instead of `columns` when the view has typed column definitions
9247    #[serde(skip_serializing_if = "Option::is_none", default)]
9248    pub schema: Option<Box<Schema>>,
9249    /// Doris: KEY (columns) for materialized views
9250    #[serde(skip_serializing_if = "Option::is_none", default)]
9251    pub unique_key: Option<Box<UniqueKeyProperty>>,
9252    /// Redshift: WITH NO SCHEMA BINDING
9253    #[serde(default)]
9254    pub no_schema_binding: bool,
9255    /// Redshift: AUTO REFRESH YES|NO for materialized views
9256    #[serde(skip_serializing_if = "Option::is_none", default)]
9257    pub auto_refresh: Option<bool>,
9258    /// ClickHouse: POPULATE / EMPTY before AS in materialized views
9259    #[serde(skip_serializing_if = "Option::is_none", default)]
9260    pub clickhouse_population: Option<String>,
9261    /// ClickHouse: ON CLUSTER clause
9262    #[serde(default, skip_serializing_if = "Option::is_none")]
9263    pub on_cluster: Option<OnCluster>,
9264    /// ClickHouse: TO destination_table
9265    #[serde(default, skip_serializing_if = "Option::is_none")]
9266    pub to_table: Option<TableRef>,
9267    /// ClickHouse: Table properties (ENGINE, ORDER BY, SAMPLE, SETTINGS, TTL, etc.) for materialized views
9268    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9269    pub table_properties: Vec<Expression>,
9270}
9271
9272impl CreateView {
9273    pub fn new(name: impl Into<String>, query: Expression) -> Self {
9274        Self {
9275            name: TableRef::new(name),
9276            columns: Vec::new(),
9277            query,
9278            or_replace: false,
9279            or_alter: false,
9280            if_not_exists: false,
9281            materialized: false,
9282            temporary: false,
9283            secure: false,
9284            algorithm: None,
9285            definer: None,
9286            security: None,
9287            security_sql_style: true,
9288            security_after_name: false,
9289            query_parenthesized: false,
9290            locking_mode: None,
9291            locking_access: None,
9292            copy_grants: false,
9293            comment: None,
9294            row_access_policy: None,
9295            tags: Vec::new(),
9296            options: Vec::new(),
9297            build: None,
9298            refresh: None,
9299            schema: None,
9300            unique_key: None,
9301            no_schema_binding: false,
9302            auto_refresh: None,
9303            clickhouse_population: None,
9304            on_cluster: None,
9305            to_table: None,
9306            table_properties: Vec::new(),
9307        }
9308    }
9309}
9310
9311/// DROP VIEW statement
9312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9313#[cfg_attr(feature = "bindings", derive(TS))]
9314pub struct DropView {
9315    pub name: TableRef,
9316    pub if_exists: bool,
9317    pub materialized: bool,
9318}
9319
9320impl DropView {
9321    pub fn new(name: impl Into<String>) -> Self {
9322        Self {
9323            name: TableRef::new(name),
9324            if_exists: false,
9325            materialized: false,
9326        }
9327    }
9328}
9329
9330/// TRUNCATE TABLE statement
9331#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9332#[cfg_attr(feature = "bindings", derive(TS))]
9333pub struct Truncate {
9334    /// Target of TRUNCATE (TABLE vs DATABASE)
9335    #[serde(default)]
9336    pub target: TruncateTarget,
9337    /// IF EXISTS clause
9338    #[serde(default)]
9339    pub if_exists: bool,
9340    pub table: TableRef,
9341    /// ClickHouse: ON CLUSTER clause for distributed DDL
9342    #[serde(default, skip_serializing_if = "Option::is_none")]
9343    pub on_cluster: Option<OnCluster>,
9344    pub cascade: bool,
9345    /// Additional tables for multi-table TRUNCATE
9346    #[serde(default)]
9347    pub extra_tables: Vec<TruncateTableEntry>,
9348    /// RESTART IDENTITY or CONTINUE IDENTITY
9349    #[serde(default)]
9350    pub identity: Option<TruncateIdentity>,
9351    /// RESTRICT option (alternative to CASCADE)
9352    #[serde(default)]
9353    pub restrict: bool,
9354    /// Hive PARTITION clause: PARTITION(key=value, ...)
9355    #[serde(default, skip_serializing_if = "Option::is_none")]
9356    pub partition: Option<Box<Expression>>,
9357}
9358
9359/// A table entry in a TRUNCATE statement, with optional ONLY modifier and * suffix
9360#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9361#[cfg_attr(feature = "bindings", derive(TS))]
9362pub struct TruncateTableEntry {
9363    pub table: TableRef,
9364    /// Whether the table has a * suffix (inherit children)
9365    #[serde(default)]
9366    pub star: bool,
9367}
9368
9369/// TRUNCATE target type
9370#[derive(
9371    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9372)]
9373#[cfg_attr(feature = "bindings", derive(TS))]
9374pub enum TruncateTarget {
9375    Table,
9376    Database,
9377}
9378
9379impl Default for TruncateTarget {
9380    fn default() -> Self {
9381        TruncateTarget::Table
9382    }
9383}
9384
9385/// TRUNCATE identity option
9386#[derive(
9387    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9388)]
9389#[cfg_attr(feature = "bindings", derive(TS))]
9390pub enum TruncateIdentity {
9391    Restart,
9392    Continue,
9393}
9394
9395impl Truncate {
9396    pub fn new(table: impl Into<String>) -> Self {
9397        Self {
9398            target: TruncateTarget::Table,
9399            if_exists: false,
9400            table: TableRef::new(table),
9401            on_cluster: None,
9402            cascade: false,
9403            extra_tables: Vec::new(),
9404            identity: None,
9405            restrict: false,
9406            partition: None,
9407        }
9408    }
9409}
9410
9411/// USE statement (USE database, USE ROLE, USE WAREHOUSE, USE CATALOG, USE SCHEMA)
9412#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9413#[cfg_attr(feature = "bindings", derive(TS))]
9414pub struct Use {
9415    /// The kind of object (DATABASE, SCHEMA, ROLE, WAREHOUSE, CATALOG, or None for default)
9416    pub kind: Option<UseKind>,
9417    /// The name of the object
9418    pub this: Identifier,
9419}
9420
9421/// Kind of USE statement
9422#[derive(
9423    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9424)]
9425#[cfg_attr(feature = "bindings", derive(TS))]
9426pub enum UseKind {
9427    Database,
9428    Schema,
9429    Role,
9430    Warehouse,
9431    Catalog,
9432    /// Snowflake: USE SECONDARY ROLES ALL|NONE
9433    SecondaryRoles,
9434}
9435
9436/// SET variable statement
9437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9438#[cfg_attr(feature = "bindings", derive(TS))]
9439pub struct SetStatement {
9440    /// The items being set
9441    pub items: Vec<SetItem>,
9442}
9443
9444/// A single SET item (variable assignment)
9445#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9446#[cfg_attr(feature = "bindings", derive(TS))]
9447pub struct SetItem {
9448    /// The variable name
9449    pub name: Expression,
9450    /// The value to set
9451    pub value: Expression,
9452    /// Kind: None for plain SET, Some("GLOBAL") for SET GLOBAL, etc.
9453    pub kind: Option<String>,
9454    /// Whether the SET item was parsed without an = sign (TSQL: SET KEY VALUE)
9455    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9456    pub no_equals: bool,
9457}
9458
9459/// CACHE TABLE statement (Spark)
9460#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9461#[cfg_attr(feature = "bindings", derive(TS))]
9462pub struct Cache {
9463    /// The table to cache
9464    pub table: Identifier,
9465    /// LAZY keyword - defer caching until first use
9466    pub lazy: bool,
9467    /// Optional OPTIONS clause (key-value pairs)
9468    pub options: Vec<(Expression, Expression)>,
9469    /// Optional AS clause with query
9470    pub query: Option<Expression>,
9471}
9472
9473/// UNCACHE TABLE statement (Spark)
9474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9475#[cfg_attr(feature = "bindings", derive(TS))]
9476pub struct Uncache {
9477    /// The table to uncache
9478    pub table: Identifier,
9479    /// IF EXISTS clause
9480    pub if_exists: bool,
9481}
9482
9483/// LOAD DATA statement (Hive)
9484#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9485#[cfg_attr(feature = "bindings", derive(TS))]
9486pub struct LoadData {
9487    /// LOCAL keyword - load from local filesystem
9488    pub local: bool,
9489    /// The path to load data from (INPATH value)
9490    pub inpath: String,
9491    /// Whether to overwrite existing data
9492    pub overwrite: bool,
9493    /// The target table
9494    pub table: Expression,
9495    /// Optional PARTITION clause with key-value pairs
9496    pub partition: Vec<(Identifier, Expression)>,
9497    /// Optional INPUTFORMAT clause
9498    pub input_format: Option<String>,
9499    /// Optional SERDE clause
9500    pub serde: Option<String>,
9501}
9502
9503/// PRAGMA statement (SQLite)
9504#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9505#[cfg_attr(feature = "bindings", derive(TS))]
9506pub struct Pragma {
9507    /// Optional schema prefix (e.g., "schema" in "schema.pragma_name")
9508    pub schema: Option<Identifier>,
9509    /// The pragma name
9510    pub name: Identifier,
9511    /// Optional value for assignment (PRAGMA name = value)
9512    pub value: Option<Expression>,
9513    /// Optional arguments for function-style pragmas (PRAGMA name(arg))
9514    pub args: Vec<Expression>,
9515    /// Whether this pragma should be generated using assignment syntax.
9516    #[serde(default)]
9517    pub use_assignment_syntax: bool,
9518}
9519
9520/// A privilege with optional column list for GRANT/REVOKE
9521/// Examples: SELECT, UPDATE(col1, col2), ALL(col1, col2, col3)
9522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9523#[cfg_attr(feature = "bindings", derive(TS))]
9524pub struct Privilege {
9525    /// The privilege name (e.g., SELECT, INSERT, UPDATE, ALL)
9526    pub name: String,
9527    /// Optional column list for column-level privileges (e.g., UPDATE(col1, col2))
9528    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9529    pub columns: Vec<String>,
9530}
9531
9532/// Principal in GRANT/REVOKE (user, role, etc.)
9533#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9534#[cfg_attr(feature = "bindings", derive(TS))]
9535pub struct GrantPrincipal {
9536    /// The name of the principal
9537    pub name: Identifier,
9538    /// Whether prefixed with ROLE keyword
9539    pub is_role: bool,
9540    /// Whether prefixed with GROUP keyword (Redshift)
9541    #[serde(default)]
9542    pub is_group: bool,
9543    /// Whether prefixed with SHARE keyword (Snowflake)
9544    #[serde(default)]
9545    pub is_share: bool,
9546}
9547
9548/// GRANT statement
9549#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9550#[cfg_attr(feature = "bindings", derive(TS))]
9551pub struct Grant {
9552    /// Privileges to grant (e.g., SELECT, INSERT, UPDATE(col1, col2))
9553    pub privileges: Vec<Privilege>,
9554    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9555    pub kind: Option<String>,
9556    /// The object to grant on
9557    pub securable: Identifier,
9558    /// Function parameter types (for FUNCTION kind)
9559    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9560    pub function_params: Vec<String>,
9561    /// The grantees
9562    pub principals: Vec<GrantPrincipal>,
9563    /// WITH GRANT OPTION
9564    pub grant_option: bool,
9565    /// TSQL: AS principal (the grantor role)
9566    #[serde(default, skip_serializing_if = "Option::is_none")]
9567    pub as_principal: Option<Identifier>,
9568}
9569
9570/// REVOKE statement
9571#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9572#[cfg_attr(feature = "bindings", derive(TS))]
9573pub struct Revoke {
9574    /// Privileges to revoke (e.g., SELECT, INSERT, UPDATE(col1, col2))
9575    pub privileges: Vec<Privilege>,
9576    /// Object kind (TABLE, SCHEMA, FUNCTION, etc.)
9577    pub kind: Option<String>,
9578    /// The object to revoke from
9579    pub securable: Identifier,
9580    /// Function parameter types (for FUNCTION kind)
9581    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9582    pub function_params: Vec<String>,
9583    /// The grantees
9584    pub principals: Vec<GrantPrincipal>,
9585    /// GRANT OPTION FOR
9586    pub grant_option: bool,
9587    /// CASCADE
9588    pub cascade: bool,
9589    /// RESTRICT
9590    #[serde(default)]
9591    pub restrict: bool,
9592}
9593
9594/// COMMENT ON statement
9595#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9596#[cfg_attr(feature = "bindings", derive(TS))]
9597pub struct Comment {
9598    /// The object being commented on
9599    pub this: Expression,
9600    /// The object kind (COLUMN, TABLE, DATABASE, etc.)
9601    pub kind: String,
9602    /// The comment text expression
9603    pub expression: Expression,
9604    /// IF EXISTS clause
9605    pub exists: bool,
9606    /// MATERIALIZED keyword
9607    pub materialized: bool,
9608}
9609
9610// ============================================================================
9611// Phase 4: Additional DDL Statements
9612// ============================================================================
9613
9614/// ALTER VIEW statement
9615#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9616#[cfg_attr(feature = "bindings", derive(TS))]
9617pub struct AlterView {
9618    pub name: TableRef,
9619    pub actions: Vec<AlterViewAction>,
9620    /// MySQL: ALGORITHM = MERGE|TEMPTABLE|UNDEFINED
9621    #[serde(default, skip_serializing_if = "Option::is_none")]
9622    pub algorithm: Option<String>,
9623    /// MySQL: DEFINER = 'user'@'host'
9624    #[serde(default, skip_serializing_if = "Option::is_none")]
9625    pub definer: Option<String>,
9626    /// MySQL: SQL SECURITY = DEFINER|INVOKER
9627    #[serde(default, skip_serializing_if = "Option::is_none")]
9628    pub sql_security: Option<String>,
9629    /// TSQL: WITH option (SCHEMABINDING, ENCRYPTION, VIEW_METADATA)
9630    #[serde(default, skip_serializing_if = "Option::is_none")]
9631    pub with_option: Option<String>,
9632    /// Hive: Column aliases with optional comments: (c1 COMMENT 'text', c2)
9633    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9634    pub columns: Vec<ViewColumn>,
9635}
9636
9637/// Actions for ALTER VIEW
9638#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9639#[cfg_attr(feature = "bindings", derive(TS))]
9640pub enum AlterViewAction {
9641    /// Rename the view
9642    Rename(TableRef),
9643    /// Change owner
9644    OwnerTo(Identifier),
9645    /// Set schema
9646    SetSchema(Identifier),
9647    /// Set authorization (Trino/Presto)
9648    SetAuthorization(String),
9649    /// Alter column
9650    AlterColumn {
9651        name: Identifier,
9652        action: AlterColumnAction,
9653    },
9654    /// Redefine view as query (SELECT, UNION, etc.)
9655    AsSelect(Box<Expression>),
9656    /// Hive: SET TBLPROPERTIES ('key'='value', ...)
9657    SetTblproperties(Vec<(String, String)>),
9658    /// Hive: UNSET TBLPROPERTIES ('key1', 'key2', ...)
9659    UnsetTblproperties(Vec<String>),
9660}
9661
9662impl AlterView {
9663    pub fn new(name: impl Into<String>) -> Self {
9664        Self {
9665            name: TableRef::new(name),
9666            actions: Vec::new(),
9667            algorithm: None,
9668            definer: None,
9669            sql_security: None,
9670            with_option: None,
9671            columns: Vec::new(),
9672        }
9673    }
9674}
9675
9676/// ALTER INDEX statement
9677#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9678#[cfg_attr(feature = "bindings", derive(TS))]
9679pub struct AlterIndex {
9680    pub name: Identifier,
9681    pub table: Option<TableRef>,
9682    pub actions: Vec<AlterIndexAction>,
9683}
9684
9685/// Actions for ALTER INDEX
9686#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9687#[cfg_attr(feature = "bindings", derive(TS))]
9688pub enum AlterIndexAction {
9689    /// Rename the index
9690    Rename(Identifier),
9691    /// Set tablespace
9692    SetTablespace(Identifier),
9693    /// Set visibility (MySQL)
9694    Visible(bool),
9695}
9696
9697impl AlterIndex {
9698    pub fn new(name: impl Into<String>) -> Self {
9699        Self {
9700            name: Identifier::new(name),
9701            table: None,
9702            actions: Vec::new(),
9703        }
9704    }
9705}
9706
9707/// CREATE SCHEMA statement
9708#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9709#[cfg_attr(feature = "bindings", derive(TS))]
9710pub struct CreateSchema {
9711    /// Schema name parts, possibly dot-qualified (e.g. [mydb, hr] for "mydb.hr")
9712    pub name: Vec<Identifier>,
9713    pub if_not_exists: bool,
9714    pub authorization: Option<Identifier>,
9715    /// CLONE source parts, possibly dot-qualified
9716    #[serde(default)]
9717    pub clone_from: Option<Vec<Identifier>>,
9718    /// AT/BEFORE clause for time travel (Snowflake)
9719    #[serde(default)]
9720    pub at_clause: Option<Expression>,
9721    /// Schema properties like DEFAULT COLLATE
9722    #[serde(default)]
9723    pub properties: Vec<Expression>,
9724    /// Leading comments before the statement
9725    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9726    pub leading_comments: Vec<String>,
9727}
9728
9729impl CreateSchema {
9730    pub fn new(name: impl Into<String>) -> Self {
9731        Self {
9732            name: vec![Identifier::new(name)],
9733            if_not_exists: false,
9734            authorization: None,
9735            clone_from: None,
9736            at_clause: None,
9737            properties: Vec::new(),
9738            leading_comments: Vec::new(),
9739        }
9740    }
9741}
9742
9743/// DROP SCHEMA statement
9744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9745#[cfg_attr(feature = "bindings", derive(TS))]
9746pub struct DropSchema {
9747    pub name: Identifier,
9748    pub if_exists: bool,
9749    pub cascade: bool,
9750}
9751
9752impl DropSchema {
9753    pub fn new(name: impl Into<String>) -> Self {
9754        Self {
9755            name: Identifier::new(name),
9756            if_exists: false,
9757            cascade: false,
9758        }
9759    }
9760}
9761
9762/// DROP NAMESPACE statement (Spark/Databricks - alias for DROP SCHEMA)
9763#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9764#[cfg_attr(feature = "bindings", derive(TS))]
9765pub struct DropNamespace {
9766    pub name: Identifier,
9767    pub if_exists: bool,
9768    pub cascade: bool,
9769}
9770
9771impl DropNamespace {
9772    pub fn new(name: impl Into<String>) -> Self {
9773        Self {
9774            name: Identifier::new(name),
9775            if_exists: false,
9776            cascade: false,
9777        }
9778    }
9779}
9780
9781/// CREATE DATABASE statement
9782#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9783#[cfg_attr(feature = "bindings", derive(TS))]
9784pub struct CreateDatabase {
9785    pub name: Identifier,
9786    pub if_not_exists: bool,
9787    pub options: Vec<DatabaseOption>,
9788    /// Snowflake CLONE source
9789    #[serde(default)]
9790    pub clone_from: Option<Identifier>,
9791    /// AT/BEFORE clause for time travel (Snowflake)
9792    #[serde(default)]
9793    pub at_clause: Option<Expression>,
9794}
9795
9796/// Database option
9797#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9798#[cfg_attr(feature = "bindings", derive(TS))]
9799pub enum DatabaseOption {
9800    CharacterSet(String),
9801    Collate(String),
9802    Owner(Identifier),
9803    Template(Identifier),
9804    Encoding(String),
9805    Location(String),
9806}
9807
9808impl CreateDatabase {
9809    pub fn new(name: impl Into<String>) -> Self {
9810        Self {
9811            name: Identifier::new(name),
9812            if_not_exists: false,
9813            options: Vec::new(),
9814            clone_from: None,
9815            at_clause: None,
9816        }
9817    }
9818}
9819
9820/// DROP DATABASE statement
9821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9822#[cfg_attr(feature = "bindings", derive(TS))]
9823pub struct DropDatabase {
9824    pub name: Identifier,
9825    pub if_exists: bool,
9826    /// ClickHouse: SYNC modifier
9827    #[serde(default)]
9828    pub sync: bool,
9829}
9830
9831impl DropDatabase {
9832    pub fn new(name: impl Into<String>) -> Self {
9833        Self {
9834            name: Identifier::new(name),
9835            if_exists: false,
9836            sync: false,
9837        }
9838    }
9839}
9840
9841/// CREATE FUNCTION statement
9842#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9843#[cfg_attr(feature = "bindings", derive(TS))]
9844pub struct CreateFunction {
9845    pub name: TableRef,
9846    pub parameters: Vec<FunctionParameter>,
9847    pub return_type: Option<DataType>,
9848    pub body: Option<FunctionBody>,
9849    pub or_replace: bool,
9850    /// TSQL: CREATE OR ALTER
9851    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9852    pub or_alter: bool,
9853    pub if_not_exists: bool,
9854    pub temporary: bool,
9855    pub language: Option<String>,
9856    pub deterministic: Option<bool>,
9857    pub returns_null_on_null_input: Option<bool>,
9858    pub security: Option<FunctionSecurity>,
9859    /// Whether parentheses were present in the original syntax
9860    #[serde(default = "default_true")]
9861    pub has_parens: bool,
9862    /// SQL data access characteristic (CONTAINS SQL, READS SQL DATA, etc.)
9863    #[serde(default)]
9864    pub sql_data_access: Option<SqlDataAccess>,
9865    /// TSQL: RETURNS @var TABLE (col_defs) - stores the variable name and column definitions as raw string
9866    #[serde(default, skip_serializing_if = "Option::is_none")]
9867    pub returns_table_body: Option<String>,
9868    /// True if LANGUAGE clause appears before RETURNS clause
9869    #[serde(default)]
9870    pub language_first: bool,
9871    /// PostgreSQL SET options: SET key = value, SET key FROM CURRENT
9872    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9873    pub set_options: Vec<FunctionSetOption>,
9874    /// True if STRICT was used instead of RETURNS NULL ON NULL INPUT
9875    #[serde(default)]
9876    pub strict: bool,
9877    /// BigQuery: OPTIONS (key=value, ...)
9878    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9879    pub options: Vec<Expression>,
9880    /// BigQuery: True if this is a TABLE FUNCTION (CREATE TABLE FUNCTION)
9881    #[serde(default)]
9882    pub is_table_function: bool,
9883    /// Original order of function properties (SET, AS, LANGUAGE, etc.)
9884    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9885    pub property_order: Vec<FunctionPropertyKind>,
9886    /// Hive: USING JAR|FILE|ARCHIVE '...'
9887    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9888    pub using_resources: Vec<FunctionUsingResource>,
9889    /// Databricks: ENVIRONMENT (dependencies = '...', environment_version = '...')
9890    #[serde(default, skip_serializing_if = "Vec::is_empty")]
9891    pub environment: Vec<Expression>,
9892    /// HANDLER 'handler_function' clause (Databricks)
9893    #[serde(default, skip_serializing_if = "Option::is_none")]
9894    pub handler: Option<String>,
9895    /// True when the HANDLER clause used Snowflake-style `HANDLER = 'fn'`
9896    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
9897    pub handler_uses_eq: bool,
9898    /// Snowflake: RUNTIME_VERSION='3.11'
9899    #[serde(default, skip_serializing_if = "Option::is_none")]
9900    pub runtime_version: Option<String>,
9901    /// Snowflake: PACKAGES=('pkg1', 'pkg2')
9902    #[serde(default, skip_serializing_if = "Option::is_none")]
9903    pub packages: Option<Vec<String>>,
9904    /// PARAMETER STYLE clause (e.g., PANDAS for Databricks)
9905    #[serde(default, skip_serializing_if = "Option::is_none")]
9906    pub parameter_style: Option<String>,
9907}
9908
9909/// A SET option in CREATE FUNCTION (PostgreSQL)
9910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9911#[cfg_attr(feature = "bindings", derive(TS))]
9912pub struct FunctionSetOption {
9913    pub name: String,
9914    pub value: FunctionSetValue,
9915}
9916
9917/// The value of a SET option
9918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9919#[cfg_attr(feature = "bindings", derive(TS))]
9920pub enum FunctionSetValue {
9921    /// SET key = value (use_to = false) or SET key TO value (use_to = true)
9922    Value { value: String, use_to: bool },
9923    /// SET key FROM CURRENT
9924    FromCurrent,
9925}
9926
9927/// SQL data access characteristics for functions
9928#[derive(
9929    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9930)]
9931#[cfg_attr(feature = "bindings", derive(TS))]
9932pub enum SqlDataAccess {
9933    /// NO SQL
9934    NoSql,
9935    /// CONTAINS SQL
9936    ContainsSql,
9937    /// READS SQL DATA
9938    ReadsSqlData,
9939    /// MODIFIES SQL DATA
9940    ModifiesSqlData,
9941}
9942
9943/// Types of properties in CREATE FUNCTION for tracking their original order
9944#[derive(
9945    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
9946)]
9947#[cfg_attr(feature = "bindings", derive(TS))]
9948pub enum FunctionPropertyKind {
9949    /// SET option
9950    Set,
9951    /// AS body
9952    As,
9953    /// Hive: USING JAR|FILE|ARCHIVE ...
9954    Using,
9955    /// LANGUAGE clause
9956    Language,
9957    /// IMMUTABLE/VOLATILE/STABLE (determinism)
9958    Determinism,
9959    /// CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT / STRICT
9960    NullInput,
9961    /// SECURITY DEFINER/INVOKER
9962    Security,
9963    /// SQL data access (CONTAINS SQL, READS SQL DATA, etc.)
9964    SqlDataAccess,
9965    /// OPTIONS clause (BigQuery)
9966    Options,
9967    /// ENVIRONMENT clause (Databricks)
9968    Environment,
9969    /// HANDLER clause (Databricks)
9970    Handler,
9971    /// Snowflake: RUNTIME_VERSION='...'
9972    RuntimeVersion,
9973    /// Snowflake: PACKAGES=(...)
9974    Packages,
9975    /// PARAMETER STYLE clause (Databricks)
9976    ParameterStyle,
9977}
9978
9979/// Hive CREATE FUNCTION resource in a USING clause
9980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9981#[cfg_attr(feature = "bindings", derive(TS))]
9982pub struct FunctionUsingResource {
9983    pub kind: String,
9984    pub uri: String,
9985}
9986
9987/// Function parameter
9988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
9989#[cfg_attr(feature = "bindings", derive(TS))]
9990pub struct FunctionParameter {
9991    pub name: Option<Identifier>,
9992    pub data_type: DataType,
9993    pub mode: Option<ParameterMode>,
9994    pub default: Option<Expression>,
9995    /// Original text of the mode keyword for case-preserving output (e.g., "inout", "VARIADIC")
9996    #[serde(default, skip_serializing_if = "Option::is_none")]
9997    pub mode_text: Option<String>,
9998}
9999
10000/// Parameter mode (IN, OUT, INOUT, VARIADIC)
10001#[derive(
10002    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10003)]
10004#[cfg_attr(feature = "bindings", derive(TS))]
10005pub enum ParameterMode {
10006    In,
10007    Out,
10008    InOut,
10009    Variadic,
10010}
10011
10012/// Function body
10013#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10014#[cfg_attr(feature = "bindings", derive(TS))]
10015pub enum FunctionBody {
10016    /// AS $$ ... $$ (dollar-quoted)
10017    Block(String),
10018    /// AS 'string' (single-quoted string literal body)
10019    StringLiteral(String),
10020    /// AS 'expression'
10021    Expression(Expression),
10022    /// EXTERNAL NAME 'library'
10023    External(String),
10024    /// RETURN expression
10025    Return(Expression),
10026    /// BEGIN ... END block with parsed statements
10027    Statements(Vec<Expression>),
10028    /// AS $$...$$ or $tag$...$tag$ (dollar-quoted with optional tag)
10029    /// Stores (content, optional_tag)
10030    DollarQuoted {
10031        content: String,
10032        tag: Option<String>,
10033    },
10034    /// BEGIN ... END block preserved as raw text (MySQL procedural bodies)
10035    RawBlock(String),
10036}
10037
10038/// Function security (DEFINER, INVOKER, or NONE)
10039#[derive(
10040    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10041)]
10042#[cfg_attr(feature = "bindings", derive(TS))]
10043pub enum FunctionSecurity {
10044    Definer,
10045    Invoker,
10046    /// StarRocks/MySQL: SECURITY NONE
10047    None,
10048}
10049
10050impl CreateFunction {
10051    pub fn new(name: impl Into<String>) -> Self {
10052        Self {
10053            name: TableRef::new(name),
10054            parameters: Vec::new(),
10055            return_type: None,
10056            body: None,
10057            or_replace: false,
10058            or_alter: false,
10059            if_not_exists: false,
10060            temporary: false,
10061            language: None,
10062            deterministic: None,
10063            returns_null_on_null_input: None,
10064            security: None,
10065            has_parens: true,
10066            sql_data_access: None,
10067            returns_table_body: None,
10068            language_first: false,
10069            set_options: Vec::new(),
10070            strict: false,
10071            options: Vec::new(),
10072            is_table_function: false,
10073            property_order: Vec::new(),
10074            using_resources: Vec::new(),
10075            environment: Vec::new(),
10076            handler: None,
10077            handler_uses_eq: false,
10078            runtime_version: None,
10079            packages: None,
10080            parameter_style: None,
10081        }
10082    }
10083}
10084
10085/// DROP FUNCTION statement
10086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10087#[cfg_attr(feature = "bindings", derive(TS))]
10088pub struct DropFunction {
10089    pub name: TableRef,
10090    pub parameters: Option<Vec<DataType>>,
10091    pub if_exists: bool,
10092    pub cascade: bool,
10093}
10094
10095impl DropFunction {
10096    pub fn new(name: impl Into<String>) -> Self {
10097        Self {
10098            name: TableRef::new(name),
10099            parameters: None,
10100            if_exists: false,
10101            cascade: false,
10102        }
10103    }
10104}
10105
10106/// CREATE PROCEDURE statement
10107#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10108#[cfg_attr(feature = "bindings", derive(TS))]
10109pub struct CreateProcedure {
10110    pub name: TableRef,
10111    pub parameters: Vec<FunctionParameter>,
10112    pub body: Option<FunctionBody>,
10113    pub or_replace: bool,
10114    /// TSQL: CREATE OR ALTER
10115    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10116    pub or_alter: bool,
10117    pub if_not_exists: bool,
10118    pub language: Option<String>,
10119    pub security: Option<FunctionSecurity>,
10120    /// Return type (Snowflake: RETURNS OBJECT, RETURNS VARCHAR, etc.)
10121    #[serde(default)]
10122    pub return_type: Option<DataType>,
10123    /// Execution context (EXECUTE AS CALLER, EXECUTE AS OWNER)
10124    #[serde(default)]
10125    pub execute_as: Option<String>,
10126    /// TSQL WITH options (ENCRYPTION, RECOMPILE, SCHEMABINDING, etc.)
10127    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10128    pub with_options: Vec<String>,
10129    /// Whether the parameter list had parentheses (false for TSQL procedures without parens)
10130    #[serde(default = "default_true", skip_serializing_if = "is_true")]
10131    pub has_parens: bool,
10132    /// Whether the short form PROC was used (instead of PROCEDURE)
10133    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10134    pub use_proc_keyword: bool,
10135}
10136
10137impl CreateProcedure {
10138    pub fn new(name: impl Into<String>) -> Self {
10139        Self {
10140            name: TableRef::new(name),
10141            parameters: Vec::new(),
10142            body: None,
10143            or_replace: false,
10144            or_alter: false,
10145            if_not_exists: false,
10146            language: None,
10147            security: None,
10148            return_type: None,
10149            execute_as: None,
10150            with_options: Vec::new(),
10151            has_parens: true,
10152            use_proc_keyword: false,
10153        }
10154    }
10155}
10156
10157/// DROP PROCEDURE statement
10158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10159#[cfg_attr(feature = "bindings", derive(TS))]
10160pub struct DropProcedure {
10161    pub name: TableRef,
10162    pub parameters: Option<Vec<DataType>>,
10163    pub if_exists: bool,
10164    pub cascade: bool,
10165}
10166
10167impl DropProcedure {
10168    pub fn new(name: impl Into<String>) -> Self {
10169        Self {
10170            name: TableRef::new(name),
10171            parameters: None,
10172            if_exists: false,
10173            cascade: false,
10174        }
10175    }
10176}
10177
10178/// Sequence property tag for ordering
10179#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10180#[cfg_attr(feature = "bindings", derive(TS))]
10181pub enum SeqPropKind {
10182    Start,
10183    Increment,
10184    Minvalue,
10185    Maxvalue,
10186    Cache,
10187    NoCache,
10188    Cycle,
10189    NoCycle,
10190    OwnedBy,
10191    Order,
10192    NoOrder,
10193    Comment,
10194    /// SHARING=<value> (Oracle)
10195    Sharing,
10196    /// KEEP (Oracle)
10197    Keep,
10198    /// NOKEEP (Oracle)
10199    NoKeep,
10200    /// SCALE [EXTEND|NOEXTEND] (Oracle)
10201    Scale,
10202    /// NOSCALE (Oracle)
10203    NoScale,
10204    /// SHARD [EXTEND|NOEXTEND] (Oracle)
10205    Shard,
10206    /// NOSHARD (Oracle)
10207    NoShard,
10208    /// SESSION (Oracle)
10209    Session,
10210    /// GLOBAL (Oracle)
10211    Global,
10212    /// NOCACHE (single word, Oracle)
10213    NoCacheWord,
10214    /// NOCYCLE (single word, Oracle)
10215    NoCycleWord,
10216    /// NOMINVALUE (single word, Oracle)
10217    NoMinvalueWord,
10218    /// NOMAXVALUE (single word, Oracle)
10219    NoMaxvalueWord,
10220}
10221
10222/// CREATE SYNONYM statement (TSQL)
10223#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10224#[cfg_attr(feature = "bindings", derive(TS))]
10225pub struct CreateSynonym {
10226    /// The synonym name (can be qualified: schema.synonym_name)
10227    pub name: TableRef,
10228    /// The target object the synonym refers to
10229    pub target: TableRef,
10230}
10231
10232/// CREATE SEQUENCE statement
10233#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10234#[cfg_attr(feature = "bindings", derive(TS))]
10235pub struct CreateSequence {
10236    pub name: TableRef,
10237    pub if_not_exists: bool,
10238    pub temporary: bool,
10239    #[serde(default)]
10240    pub or_replace: bool,
10241    /// AS <type> clause (e.g., AS SMALLINT, AS BIGINT)
10242    #[serde(default, skip_serializing_if = "Option::is_none")]
10243    pub as_type: Option<DataType>,
10244    pub increment: Option<i64>,
10245    pub minvalue: Option<SequenceBound>,
10246    pub maxvalue: Option<SequenceBound>,
10247    pub start: Option<i64>,
10248    pub cache: Option<i64>,
10249    pub cycle: bool,
10250    pub owned_by: Option<TableRef>,
10251    /// Whether OWNED BY NONE was specified
10252    #[serde(default)]
10253    pub owned_by_none: bool,
10254    /// Snowflake: ORDER or NOORDER (true = ORDER, false = NOORDER, None = not specified)
10255    #[serde(default)]
10256    pub order: Option<bool>,
10257    /// Snowflake: COMMENT = 'value'
10258    #[serde(default)]
10259    pub comment: Option<String>,
10260    /// SHARING=<value> (Oracle)
10261    #[serde(default, skip_serializing_if = "Option::is_none")]
10262    pub sharing: Option<String>,
10263    /// SCALE modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SCALE
10264    #[serde(default, skip_serializing_if = "Option::is_none")]
10265    pub scale_modifier: Option<String>,
10266    /// SHARD modifier: Some("EXTEND"), Some("NOEXTEND"), Some("") for plain SHARD
10267    #[serde(default, skip_serializing_if = "Option::is_none")]
10268    pub shard_modifier: Option<String>,
10269    /// Tracks the order in which properties appeared in the source
10270    #[serde(default)]
10271    pub property_order: Vec<SeqPropKind>,
10272}
10273
10274/// Sequence bound (value or NO MINVALUE/NO MAXVALUE)
10275#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10276#[cfg_attr(feature = "bindings", derive(TS))]
10277pub enum SequenceBound {
10278    Value(i64),
10279    None,
10280}
10281
10282impl CreateSequence {
10283    pub fn new(name: impl Into<String>) -> Self {
10284        Self {
10285            name: TableRef::new(name),
10286            if_not_exists: false,
10287            temporary: false,
10288            or_replace: false,
10289            as_type: None,
10290            increment: None,
10291            minvalue: None,
10292            maxvalue: None,
10293            start: None,
10294            cache: None,
10295            cycle: false,
10296            owned_by: None,
10297            owned_by_none: false,
10298            order: None,
10299            comment: None,
10300            sharing: None,
10301            scale_modifier: None,
10302            shard_modifier: None,
10303            property_order: Vec::new(),
10304        }
10305    }
10306}
10307
10308/// DROP SEQUENCE statement
10309#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10310#[cfg_attr(feature = "bindings", derive(TS))]
10311pub struct DropSequence {
10312    pub name: TableRef,
10313    pub if_exists: bool,
10314    pub cascade: bool,
10315}
10316
10317impl DropSequence {
10318    pub fn new(name: impl Into<String>) -> Self {
10319        Self {
10320            name: TableRef::new(name),
10321            if_exists: false,
10322            cascade: false,
10323        }
10324    }
10325}
10326
10327/// ALTER SEQUENCE statement
10328#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10329#[cfg_attr(feature = "bindings", derive(TS))]
10330pub struct AlterSequence {
10331    pub name: TableRef,
10332    pub if_exists: bool,
10333    pub increment: Option<i64>,
10334    pub minvalue: Option<SequenceBound>,
10335    pub maxvalue: Option<SequenceBound>,
10336    pub start: Option<i64>,
10337    pub restart: Option<Option<i64>>,
10338    pub cache: Option<i64>,
10339    pub cycle: Option<bool>,
10340    pub owned_by: Option<Option<TableRef>>,
10341}
10342
10343impl AlterSequence {
10344    pub fn new(name: impl Into<String>) -> Self {
10345        Self {
10346            name: TableRef::new(name),
10347            if_exists: false,
10348            increment: None,
10349            minvalue: None,
10350            maxvalue: None,
10351            start: None,
10352            restart: None,
10353            cache: None,
10354            cycle: None,
10355            owned_by: None,
10356        }
10357    }
10358}
10359
10360/// CREATE TRIGGER statement
10361#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10362#[cfg_attr(feature = "bindings", derive(TS))]
10363pub struct CreateTrigger {
10364    pub name: Identifier,
10365    pub table: TableRef,
10366    pub timing: TriggerTiming,
10367    pub events: Vec<TriggerEvent>,
10368    #[serde(default, skip_serializing_if = "Option::is_none")]
10369    pub for_each: Option<TriggerForEach>,
10370    pub when: Option<Expression>,
10371    /// Whether the WHEN clause was parenthesized in the original SQL
10372    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10373    pub when_paren: bool,
10374    pub body: TriggerBody,
10375    pub or_replace: bool,
10376    /// TSQL: CREATE OR ALTER
10377    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
10378    pub or_alter: bool,
10379    pub constraint: bool,
10380    pub deferrable: Option<bool>,
10381    pub initially_deferred: Option<bool>,
10382    pub referencing: Option<TriggerReferencing>,
10383}
10384
10385/// Trigger timing (BEFORE, AFTER, INSTEAD OF)
10386#[derive(
10387    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10388)]
10389#[cfg_attr(feature = "bindings", derive(TS))]
10390pub enum TriggerTiming {
10391    Before,
10392    After,
10393    InsteadOf,
10394}
10395
10396/// Trigger event (INSERT, UPDATE, DELETE, TRUNCATE)
10397#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10398#[cfg_attr(feature = "bindings", derive(TS))]
10399pub enum TriggerEvent {
10400    Insert,
10401    Update(Option<Vec<Identifier>>),
10402    Delete,
10403    Truncate,
10404}
10405
10406/// Trigger FOR EACH clause
10407#[derive(
10408    polyglot_sql_ast_derive::AstNode, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize,
10409)]
10410#[cfg_attr(feature = "bindings", derive(TS))]
10411pub enum TriggerForEach {
10412    Row,
10413    Statement,
10414}
10415
10416/// Trigger body
10417#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10418#[cfg_attr(feature = "bindings", derive(TS))]
10419pub enum TriggerBody {
10420    /// EXECUTE FUNCTION/PROCEDURE name(args)
10421    Execute {
10422        function: TableRef,
10423        args: Vec<Expression>,
10424    },
10425    /// BEGIN ... END block
10426    Block(String),
10427}
10428
10429/// Trigger REFERENCING clause
10430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10431#[cfg_attr(feature = "bindings", derive(TS))]
10432pub struct TriggerReferencing {
10433    pub old_table: Option<Identifier>,
10434    pub new_table: Option<Identifier>,
10435    pub old_row: Option<Identifier>,
10436    pub new_row: Option<Identifier>,
10437}
10438
10439impl CreateTrigger {
10440    pub fn new(name: impl Into<String>, table: impl Into<String>) -> Self {
10441        Self {
10442            name: Identifier::new(name),
10443            table: TableRef::new(table),
10444            timing: TriggerTiming::Before,
10445            events: Vec::new(),
10446            for_each: Some(TriggerForEach::Row),
10447            when: None,
10448            when_paren: false,
10449            body: TriggerBody::Execute {
10450                function: TableRef::new(""),
10451                args: Vec::new(),
10452            },
10453            or_replace: false,
10454            or_alter: false,
10455            constraint: false,
10456            deferrable: None,
10457            initially_deferred: None,
10458            referencing: None,
10459        }
10460    }
10461}
10462
10463/// DROP TRIGGER statement
10464#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10465#[cfg_attr(feature = "bindings", derive(TS))]
10466pub struct DropTrigger {
10467    pub name: Identifier,
10468    pub table: Option<TableRef>,
10469    pub if_exists: bool,
10470    pub cascade: bool,
10471}
10472
10473impl DropTrigger {
10474    pub fn new(name: impl Into<String>) -> Self {
10475        Self {
10476            name: Identifier::new(name),
10477            table: None,
10478            if_exists: false,
10479            cascade: false,
10480        }
10481    }
10482}
10483
10484/// CREATE TYPE statement
10485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10486#[cfg_attr(feature = "bindings", derive(TS))]
10487pub struct CreateType {
10488    pub name: TableRef,
10489    pub definition: TypeDefinition,
10490    pub if_not_exists: bool,
10491}
10492
10493/// Type definition
10494#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10495#[cfg_attr(feature = "bindings", derive(TS))]
10496pub enum TypeDefinition {
10497    /// ENUM type: CREATE TYPE name AS ENUM ('val1', 'val2', ...)
10498    Enum(Vec<String>),
10499    /// Composite type: CREATE TYPE name AS (field1 type1, field2 type2, ...)
10500    Composite(Vec<TypeAttribute>),
10501    /// Range type: CREATE TYPE name AS RANGE (SUBTYPE = type, ...)
10502    Range {
10503        subtype: DataType,
10504        subtype_diff: Option<String>,
10505        canonical: Option<String>,
10506    },
10507    /// Base type (for advanced usage)
10508    Base {
10509        input: String,
10510        output: String,
10511        internallength: Option<i32>,
10512    },
10513    /// Domain type
10514    Domain {
10515        base_type: DataType,
10516        default: Option<Expression>,
10517        constraints: Vec<DomainConstraint>,
10518    },
10519}
10520
10521/// Type attribute for composite types
10522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10523#[cfg_attr(feature = "bindings", derive(TS))]
10524pub struct TypeAttribute {
10525    pub name: Identifier,
10526    pub data_type: DataType,
10527    pub collate: Option<Identifier>,
10528}
10529
10530/// Domain constraint
10531#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10532#[cfg_attr(feature = "bindings", derive(TS))]
10533pub struct DomainConstraint {
10534    pub name: Option<Identifier>,
10535    pub check: Expression,
10536}
10537
10538impl CreateType {
10539    pub fn new_enum(name: impl Into<String>, values: Vec<String>) -> Self {
10540        Self {
10541            name: TableRef::new(name),
10542            definition: TypeDefinition::Enum(values),
10543            if_not_exists: false,
10544        }
10545    }
10546
10547    pub fn new_composite(name: impl Into<String>, attributes: Vec<TypeAttribute>) -> Self {
10548        Self {
10549            name: TableRef::new(name),
10550            definition: TypeDefinition::Composite(attributes),
10551            if_not_exists: false,
10552        }
10553    }
10554}
10555
10556/// DROP TYPE statement
10557#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10558#[cfg_attr(feature = "bindings", derive(TS))]
10559pub struct DropType {
10560    pub name: TableRef,
10561    pub if_exists: bool,
10562    pub cascade: bool,
10563}
10564
10565impl DropType {
10566    pub fn new(name: impl Into<String>) -> Self {
10567        Self {
10568            name: TableRef::new(name),
10569            if_exists: false,
10570            cascade: false,
10571        }
10572    }
10573}
10574
10575/// DESCRIBE statement - shows table structure or query plan
10576#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10577#[cfg_attr(feature = "bindings", derive(TS))]
10578pub struct Describe {
10579    /// The target to describe (table name or query)
10580    pub target: Expression,
10581    /// EXTENDED format
10582    pub extended: bool,
10583    /// FORMATTED format
10584    pub formatted: bool,
10585    /// Object kind (e.g., "SEMANTIC VIEW", "TABLE", etc.)
10586    #[serde(default)]
10587    pub kind: Option<String>,
10588    /// Properties like type=stage
10589    #[serde(default)]
10590    pub properties: Vec<(String, String)>,
10591    /// Style keyword (e.g., "ANALYZE", "HISTORY")
10592    #[serde(default, skip_serializing_if = "Option::is_none")]
10593    pub style: Option<String>,
10594    /// Partition specification for DESCRIBE PARTITION
10595    #[serde(default)]
10596    pub partition: Option<Box<Expression>>,
10597    /// Leading comments before the statement
10598    #[serde(default)]
10599    pub leading_comments: Vec<String>,
10600    /// AS JSON suffix (Databricks)
10601    #[serde(default)]
10602    pub as_json: bool,
10603    /// Parenthesized parameter types for DESCRIBE PROCEDURE/FUNCTION (e.g., INT, VARCHAR)
10604    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10605    pub params: Vec<String>,
10606}
10607
10608impl Describe {
10609    pub fn new(target: Expression) -> Self {
10610        Self {
10611            target,
10612            extended: false,
10613            formatted: false,
10614            kind: None,
10615            properties: Vec::new(),
10616            style: None,
10617            partition: None,
10618            leading_comments: Vec::new(),
10619            as_json: false,
10620            params: Vec::new(),
10621        }
10622    }
10623}
10624
10625/// SHOW statement - displays database objects
10626#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10627#[cfg_attr(feature = "bindings", derive(TS))]
10628pub struct Show {
10629    /// The thing to show (DATABASES, TABLES, SCHEMAS, etc.)
10630    pub this: String,
10631    /// Whether TERSE was specified
10632    #[serde(default)]
10633    pub terse: bool,
10634    /// Whether HISTORY was specified
10635    #[serde(default)]
10636    pub history: bool,
10637    /// LIKE pattern
10638    pub like: Option<Expression>,
10639    /// IN scope kind (ACCOUNT, DATABASE, SCHEMA, TABLE)
10640    pub scope_kind: Option<String>,
10641    /// IN scope object
10642    pub scope: Option<Expression>,
10643    /// STARTS WITH pattern
10644    pub starts_with: Option<Expression>,
10645    /// LIMIT clause
10646    pub limit: Option<Box<Limit>>,
10647    /// FROM clause (for specific object)
10648    pub from: Option<Expression>,
10649    /// WHERE clause (MySQL: SHOW STATUS WHERE ...)
10650    #[serde(default, skip_serializing_if = "Option::is_none")]
10651    pub where_clause: Option<Expression>,
10652    /// FOR target (MySQL: SHOW GRANTS FOR user, SHOW PROFILE ... FOR QUERY n)
10653    #[serde(default, skip_serializing_if = "Option::is_none")]
10654    pub for_target: Option<Expression>,
10655    /// Second FROM clause (MySQL: SHOW COLUMNS FROM tbl FROM db)
10656    #[serde(default, skip_serializing_if = "Option::is_none")]
10657    pub db: Option<Expression>,
10658    /// Target identifier (MySQL: engine name in SHOW ENGINE, table in SHOW COLUMNS FROM)
10659    #[serde(default, skip_serializing_if = "Option::is_none")]
10660    pub target: Option<Expression>,
10661    /// MUTEX flag for SHOW ENGINE (true=MUTEX, false=STATUS, None=neither)
10662    #[serde(default, skip_serializing_if = "Option::is_none")]
10663    pub mutex: Option<bool>,
10664    /// WITH PRIVILEGES clause (Snowflake: SHOW ... WITH PRIVILEGES USAGE, MODIFY)
10665    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10666    pub privileges: Vec<String>,
10667}
10668
10669impl Show {
10670    pub fn new(this: impl Into<String>) -> Self {
10671        Self {
10672            this: this.into(),
10673            terse: false,
10674            history: false,
10675            like: None,
10676            scope_kind: None,
10677            scope: None,
10678            starts_with: None,
10679            limit: None,
10680            from: None,
10681            where_clause: None,
10682            for_target: None,
10683            db: None,
10684            target: None,
10685            mutex: None,
10686            privileges: Vec::new(),
10687        }
10688    }
10689}
10690
10691/// Represent an explicit parenthesized expression for grouping precedence.
10692///
10693/// Preserves user-written parentheses so that `(a + b) * c` round-trips
10694/// correctly instead of being flattened to `a + b * c`.
10695#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10696#[cfg_attr(feature = "bindings", derive(TS))]
10697pub struct Paren {
10698    /// The inner expression wrapped by parentheses.
10699    pub this: Expression,
10700    #[serde(default)]
10701    pub trailing_comments: Vec<String>,
10702}
10703
10704/// Expression annotated with trailing comments (for round-trip preservation)
10705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10706#[cfg_attr(feature = "bindings", derive(TS))]
10707pub struct Annotated {
10708    pub this: Expression,
10709    pub trailing_comments: Vec<String>,
10710}
10711
10712// === BATCH GENERATED STRUCT DEFINITIONS ===
10713// Generated from Python sqlglot expressions.py
10714
10715/// Refresh
10716#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10717#[cfg_attr(feature = "bindings", derive(TS))]
10718pub struct Refresh {
10719    pub this: Box<Expression>,
10720    pub kind: String,
10721}
10722
10723/// LockingStatement
10724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10725#[cfg_attr(feature = "bindings", derive(TS))]
10726pub struct LockingStatement {
10727    pub this: Box<Expression>,
10728    pub expression: Box<Expression>,
10729}
10730
10731/// SequenceProperties
10732#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10733#[cfg_attr(feature = "bindings", derive(TS))]
10734pub struct SequenceProperties {
10735    #[serde(default)]
10736    pub increment: Option<Box<Expression>>,
10737    #[serde(default)]
10738    pub minvalue: Option<Box<Expression>>,
10739    #[serde(default)]
10740    pub maxvalue: Option<Box<Expression>>,
10741    #[serde(default)]
10742    pub cache: Option<Box<Expression>>,
10743    #[serde(default)]
10744    pub start: Option<Box<Expression>>,
10745    #[serde(default)]
10746    pub owned: Option<Box<Expression>>,
10747    #[serde(default)]
10748    pub options: Vec<Expression>,
10749}
10750
10751/// TruncateTable
10752#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10753#[cfg_attr(feature = "bindings", derive(TS))]
10754pub struct TruncateTable {
10755    #[serde(default)]
10756    pub expressions: Vec<Expression>,
10757    #[serde(default)]
10758    pub is_database: Option<Box<Expression>>,
10759    #[serde(default)]
10760    pub exists: bool,
10761    #[serde(default)]
10762    pub only: Option<Box<Expression>>,
10763    #[serde(default)]
10764    pub cluster: Option<Box<Expression>>,
10765    #[serde(default)]
10766    pub identity: Option<Box<Expression>>,
10767    #[serde(default)]
10768    pub option: Option<Box<Expression>>,
10769    #[serde(default)]
10770    pub partition: Option<Box<Expression>>,
10771}
10772
10773/// Clone
10774#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10775#[cfg_attr(feature = "bindings", derive(TS))]
10776pub struct Clone {
10777    pub this: Box<Expression>,
10778    #[serde(default)]
10779    pub shallow: Option<Box<Expression>>,
10780    #[serde(default)]
10781    pub copy: Option<Box<Expression>>,
10782}
10783
10784/// Attach
10785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10786#[cfg_attr(feature = "bindings", derive(TS))]
10787pub struct Attach {
10788    pub this: Box<Expression>,
10789    #[serde(default)]
10790    pub exists: bool,
10791    #[serde(default)]
10792    pub expressions: Vec<Expression>,
10793}
10794
10795/// Detach
10796#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10797#[cfg_attr(feature = "bindings", derive(TS))]
10798pub struct Detach {
10799    pub this: Box<Expression>,
10800    #[serde(default)]
10801    pub exists: bool,
10802}
10803
10804/// Install
10805#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10806#[cfg_attr(feature = "bindings", derive(TS))]
10807pub struct Install {
10808    pub this: Box<Expression>,
10809    #[serde(default)]
10810    pub from_: Option<Box<Expression>>,
10811    #[serde(default)]
10812    pub force: Option<Box<Expression>>,
10813}
10814
10815/// Summarize
10816#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10817#[cfg_attr(feature = "bindings", derive(TS))]
10818pub struct Summarize {
10819    pub this: Box<Expression>,
10820    #[serde(default)]
10821    pub table: Option<Box<Expression>>,
10822}
10823
10824/// Declare
10825#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10826#[cfg_attr(feature = "bindings", derive(TS))]
10827pub struct Declare {
10828    #[serde(default)]
10829    pub expressions: Vec<Expression>,
10830    #[serde(default)]
10831    pub replace: bool,
10832}
10833
10834/// DeclareItem
10835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10836#[cfg_attr(feature = "bindings", derive(TS))]
10837pub struct DeclareItem {
10838    pub this: Box<Expression>,
10839    #[serde(default)]
10840    pub kind: Option<String>,
10841    #[serde(default)]
10842    pub default: Option<Box<Expression>>,
10843    #[serde(default)]
10844    pub has_as: bool,
10845    /// BigQuery: additional variable names in multi-variable DECLARE (DECLARE X, Y, Z INT64)
10846    #[serde(default, skip_serializing_if = "Vec::is_empty")]
10847    pub additional_names: Vec<Expression>,
10848}
10849
10850/// Set
10851#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10852#[cfg_attr(feature = "bindings", derive(TS))]
10853pub struct Set {
10854    #[serde(default)]
10855    pub expressions: Vec<Expression>,
10856    #[serde(default)]
10857    pub unset: Option<Box<Expression>>,
10858    #[serde(default)]
10859    pub tag: Option<Box<Expression>>,
10860}
10861
10862/// Heredoc
10863#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10864#[cfg_attr(feature = "bindings", derive(TS))]
10865pub struct Heredoc {
10866    pub this: Box<Expression>,
10867    #[serde(default)]
10868    pub tag: Option<Box<Expression>>,
10869}
10870
10871/// QueryBand
10872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10873#[cfg_attr(feature = "bindings", derive(TS))]
10874pub struct QueryBand {
10875    pub this: Box<Expression>,
10876    #[serde(default)]
10877    pub scope: Option<Box<Expression>>,
10878    #[serde(default)]
10879    pub update: Option<Box<Expression>>,
10880}
10881
10882/// UserDefinedFunction
10883#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10884#[cfg_attr(feature = "bindings", derive(TS))]
10885pub struct UserDefinedFunction {
10886    pub this: Box<Expression>,
10887    #[serde(default)]
10888    pub expressions: Vec<Expression>,
10889    #[serde(default)]
10890    pub wrapped: Option<Box<Expression>>,
10891}
10892
10893/// RecursiveWithSearch
10894#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10895#[cfg_attr(feature = "bindings", derive(TS))]
10896pub struct RecursiveWithSearch {
10897    pub kind: String,
10898    pub this: Box<Expression>,
10899    pub expression: Box<Expression>,
10900    #[serde(default)]
10901    pub using: Option<Box<Expression>>,
10902}
10903
10904/// ProjectionDef
10905#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10906#[cfg_attr(feature = "bindings", derive(TS))]
10907pub struct ProjectionDef {
10908    pub this: Box<Expression>,
10909    pub expression: Box<Expression>,
10910}
10911
10912/// TableAlias
10913#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10914#[cfg_attr(feature = "bindings", derive(TS))]
10915pub struct TableAlias {
10916    #[serde(default)]
10917    pub this: Option<Box<Expression>>,
10918    #[serde(default)]
10919    pub columns: Vec<Expression>,
10920}
10921
10922/// ByteString
10923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10924#[cfg_attr(feature = "bindings", derive(TS))]
10925pub struct ByteString {
10926    pub this: Box<Expression>,
10927    #[serde(default)]
10928    pub is_bytes: Option<Box<Expression>>,
10929}
10930
10931/// HexStringExpr - Hex string expression (not literal)
10932/// BigQuery: converts to FROM_HEX(this)
10933#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10934#[cfg_attr(feature = "bindings", derive(TS))]
10935pub struct HexStringExpr {
10936    pub this: Box<Expression>,
10937    #[serde(default)]
10938    pub is_integer: Option<bool>,
10939}
10940
10941/// UnicodeString
10942#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10943#[cfg_attr(feature = "bindings", derive(TS))]
10944pub struct UnicodeString {
10945    pub this: Box<Expression>,
10946    #[serde(default)]
10947    pub escape: Option<Box<Expression>>,
10948}
10949
10950/// AlterColumn
10951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10952#[cfg_attr(feature = "bindings", derive(TS))]
10953pub struct AlterColumn {
10954    pub this: Box<Expression>,
10955    #[serde(default)]
10956    pub dtype: Option<Box<Expression>>,
10957    #[serde(default)]
10958    pub collate: Option<Box<Expression>>,
10959    #[serde(default)]
10960    pub using: Option<Box<Expression>>,
10961    #[serde(default)]
10962    pub default: Option<Box<Expression>>,
10963    #[serde(default)]
10964    pub drop: Option<Box<Expression>>,
10965    #[serde(default)]
10966    pub comment: Option<Box<Expression>>,
10967    #[serde(default)]
10968    pub allow_null: Option<Box<Expression>>,
10969    #[serde(default)]
10970    pub visible: Option<Box<Expression>>,
10971    #[serde(default)]
10972    pub rename_to: Option<Box<Expression>>,
10973}
10974
10975/// AlterSortKey
10976#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10977#[cfg_attr(feature = "bindings", derive(TS))]
10978pub struct AlterSortKey {
10979    #[serde(default)]
10980    pub this: Option<Box<Expression>>,
10981    #[serde(default)]
10982    pub expressions: Vec<Expression>,
10983    #[serde(default)]
10984    pub compound: Option<Box<Expression>>,
10985}
10986
10987/// AlterSet
10988#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
10989#[cfg_attr(feature = "bindings", derive(TS))]
10990pub struct AlterSet {
10991    #[serde(default)]
10992    pub expressions: Vec<Expression>,
10993    #[serde(default)]
10994    pub option: Option<Box<Expression>>,
10995    #[serde(default)]
10996    pub tablespace: Option<Box<Expression>>,
10997    #[serde(default)]
10998    pub access_method: Option<Box<Expression>>,
10999    #[serde(default)]
11000    pub file_format: Option<Box<Expression>>,
11001    #[serde(default)]
11002    pub copy_options: Option<Box<Expression>>,
11003    #[serde(default)]
11004    pub tag: Option<Box<Expression>>,
11005    #[serde(default)]
11006    pub location: Option<Box<Expression>>,
11007    #[serde(default)]
11008    pub serde: Option<Box<Expression>>,
11009}
11010
11011/// RenameColumn
11012#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11013#[cfg_attr(feature = "bindings", derive(TS))]
11014pub struct RenameColumn {
11015    pub this: Box<Expression>,
11016    #[serde(default)]
11017    pub to: Option<Box<Expression>>,
11018    #[serde(default)]
11019    pub exists: bool,
11020}
11021
11022/// Comprehension
11023#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11024#[cfg_attr(feature = "bindings", derive(TS))]
11025pub struct Comprehension {
11026    pub this: Box<Expression>,
11027    pub expression: Box<Expression>,
11028    #[serde(default)]
11029    pub position: Option<Box<Expression>>,
11030    #[serde(default)]
11031    pub iterator: Option<Box<Expression>>,
11032    #[serde(default)]
11033    pub condition: Option<Box<Expression>>,
11034}
11035
11036/// MergeTreeTTLAction
11037#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11038#[cfg_attr(feature = "bindings", derive(TS))]
11039pub struct MergeTreeTTLAction {
11040    pub this: Box<Expression>,
11041    #[serde(default)]
11042    pub delete: Option<Box<Expression>>,
11043    #[serde(default)]
11044    pub recompress: Option<Box<Expression>>,
11045    #[serde(default)]
11046    pub to_disk: Option<Box<Expression>>,
11047    #[serde(default)]
11048    pub to_volume: Option<Box<Expression>>,
11049}
11050
11051/// MergeTreeTTL
11052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11053#[cfg_attr(feature = "bindings", derive(TS))]
11054pub struct MergeTreeTTL {
11055    #[serde(default)]
11056    pub expressions: Vec<Expression>,
11057    #[serde(default)]
11058    pub where_: Option<Box<Expression>>,
11059    #[serde(default)]
11060    pub group: Option<Box<Expression>>,
11061    #[serde(default)]
11062    pub aggregates: Option<Box<Expression>>,
11063}
11064
11065/// IndexConstraintOption
11066#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11067#[cfg_attr(feature = "bindings", derive(TS))]
11068pub struct IndexConstraintOption {
11069    #[serde(default)]
11070    pub key_block_size: Option<Box<Expression>>,
11071    #[serde(default)]
11072    pub using: Option<Box<Expression>>,
11073    #[serde(default)]
11074    pub parser: Option<Box<Expression>>,
11075    #[serde(default)]
11076    pub comment: Option<Box<Expression>>,
11077    #[serde(default)]
11078    pub visible: Option<Box<Expression>>,
11079    #[serde(default)]
11080    pub engine_attr: Option<Box<Expression>>,
11081    #[serde(default)]
11082    pub secondary_engine_attr: Option<Box<Expression>>,
11083}
11084
11085/// PeriodForSystemTimeConstraint
11086#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11087#[cfg_attr(feature = "bindings", derive(TS))]
11088pub struct PeriodForSystemTimeConstraint {
11089    pub this: Box<Expression>,
11090    pub expression: Box<Expression>,
11091}
11092
11093/// CaseSpecificColumnConstraint
11094#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11095#[cfg_attr(feature = "bindings", derive(TS))]
11096pub struct CaseSpecificColumnConstraint {
11097    #[serde(default)]
11098    pub not_: Option<Box<Expression>>,
11099}
11100
11101/// CharacterSetColumnConstraint
11102#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11103#[cfg_attr(feature = "bindings", derive(TS))]
11104pub struct CharacterSetColumnConstraint {
11105    pub this: Box<Expression>,
11106}
11107
11108/// CheckColumnConstraint
11109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11110#[cfg_attr(feature = "bindings", derive(TS))]
11111pub struct CheckColumnConstraint {
11112    pub this: Box<Expression>,
11113    #[serde(default)]
11114    pub enforced: Option<Box<Expression>>,
11115}
11116
11117/// AssumeColumnConstraint (ClickHouse ASSUME constraint)
11118#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11119#[cfg_attr(feature = "bindings", derive(TS))]
11120pub struct AssumeColumnConstraint {
11121    pub this: Box<Expression>,
11122}
11123
11124/// CompressColumnConstraint
11125#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11126#[cfg_attr(feature = "bindings", derive(TS))]
11127pub struct CompressColumnConstraint {
11128    #[serde(default)]
11129    pub this: Option<Box<Expression>>,
11130}
11131
11132/// DateFormatColumnConstraint
11133#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11134#[cfg_attr(feature = "bindings", derive(TS))]
11135pub struct DateFormatColumnConstraint {
11136    pub this: Box<Expression>,
11137}
11138
11139/// EphemeralColumnConstraint
11140#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11141#[cfg_attr(feature = "bindings", derive(TS))]
11142pub struct EphemeralColumnConstraint {
11143    #[serde(default)]
11144    pub this: Option<Box<Expression>>,
11145}
11146
11147/// WithOperator
11148#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11149#[cfg_attr(feature = "bindings", derive(TS))]
11150pub struct WithOperator {
11151    pub this: Box<Expression>,
11152    pub op: String,
11153}
11154
11155/// GeneratedAsIdentityColumnConstraint
11156#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11157#[cfg_attr(feature = "bindings", derive(TS))]
11158pub struct GeneratedAsIdentityColumnConstraint {
11159    #[serde(default)]
11160    pub this: Option<Box<Expression>>,
11161    #[serde(default)]
11162    pub expression: Option<Box<Expression>>,
11163    #[serde(default)]
11164    pub on_null: Option<Box<Expression>>,
11165    #[serde(default)]
11166    pub start: Option<Box<Expression>>,
11167    #[serde(default)]
11168    pub increment: Option<Box<Expression>>,
11169    #[serde(default)]
11170    pub minvalue: Option<Box<Expression>>,
11171    #[serde(default)]
11172    pub maxvalue: Option<Box<Expression>>,
11173    #[serde(default)]
11174    pub cycle: Option<Box<Expression>>,
11175    #[serde(default)]
11176    pub order: Option<Box<Expression>>,
11177}
11178
11179/// AutoIncrementColumnConstraint - MySQL/TSQL auto-increment marker
11180/// TSQL: outputs "IDENTITY"
11181#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11182#[cfg_attr(feature = "bindings", derive(TS))]
11183pub struct AutoIncrementColumnConstraint;
11184
11185/// CommentColumnConstraint - Column comment marker
11186#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11187#[cfg_attr(feature = "bindings", derive(TS))]
11188pub struct CommentColumnConstraint;
11189
11190/// GeneratedAsRowColumnConstraint
11191#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11192#[cfg_attr(feature = "bindings", derive(TS))]
11193pub struct GeneratedAsRowColumnConstraint {
11194    #[serde(default)]
11195    pub start: Option<Box<Expression>>,
11196    #[serde(default)]
11197    pub hidden: Option<Box<Expression>>,
11198}
11199
11200/// IndexColumnConstraint
11201#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11202#[cfg_attr(feature = "bindings", derive(TS))]
11203pub struct IndexColumnConstraint {
11204    #[serde(default)]
11205    pub this: Option<Box<Expression>>,
11206    #[serde(default)]
11207    pub expressions: Vec<Expression>,
11208    #[serde(default)]
11209    pub kind: Option<String>,
11210    #[serde(default)]
11211    pub index_type: Option<Box<Expression>>,
11212    #[serde(default)]
11213    pub options: Vec<Expression>,
11214    #[serde(default)]
11215    pub expression: Option<Box<Expression>>,
11216    #[serde(default)]
11217    pub granularity: Option<Box<Expression>>,
11218}
11219
11220/// MaskingPolicyColumnConstraint
11221#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11222#[cfg_attr(feature = "bindings", derive(TS))]
11223pub struct MaskingPolicyColumnConstraint {
11224    pub this: Box<Expression>,
11225    #[serde(default)]
11226    pub expressions: Vec<Expression>,
11227}
11228
11229/// NotNullColumnConstraint
11230#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11231#[cfg_attr(feature = "bindings", derive(TS))]
11232pub struct NotNullColumnConstraint {
11233    #[serde(default)]
11234    pub allow_null: Option<Box<Expression>>,
11235}
11236
11237/// DefaultColumnConstraint - DEFAULT value for a column
11238#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11239#[cfg_attr(feature = "bindings", derive(TS))]
11240pub struct DefaultColumnConstraint {
11241    pub this: Box<Expression>,
11242    /// TSQL: DEFAULT value FOR column (table-level default constraint)
11243    #[serde(default, skip_serializing_if = "Option::is_none")]
11244    pub for_column: Option<Identifier>,
11245}
11246
11247/// PrimaryKeyColumnConstraint
11248#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11249#[cfg_attr(feature = "bindings", derive(TS))]
11250pub struct PrimaryKeyColumnConstraint {
11251    #[serde(default)]
11252    pub desc: Option<Box<Expression>>,
11253    #[serde(default)]
11254    pub options: Vec<Expression>,
11255}
11256
11257/// UniqueColumnConstraint
11258#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11259#[cfg_attr(feature = "bindings", derive(TS))]
11260pub struct UniqueColumnConstraint {
11261    #[serde(default)]
11262    pub this: Option<Box<Expression>>,
11263    #[serde(default)]
11264    pub index_type: Option<Box<Expression>>,
11265    #[serde(default)]
11266    pub on_conflict: Option<Box<Expression>>,
11267    #[serde(default)]
11268    pub nulls: Option<Box<Expression>>,
11269    #[serde(default)]
11270    pub options: Vec<Expression>,
11271}
11272
11273/// WatermarkColumnConstraint
11274#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11275#[cfg_attr(feature = "bindings", derive(TS))]
11276pub struct WatermarkColumnConstraint {
11277    pub this: Box<Expression>,
11278    pub expression: Box<Expression>,
11279}
11280
11281/// ComputedColumnConstraint
11282#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11283#[cfg_attr(feature = "bindings", derive(TS))]
11284pub struct ComputedColumnConstraint {
11285    pub this: Box<Expression>,
11286    #[serde(default)]
11287    pub persisted: Option<Box<Expression>>,
11288    #[serde(default)]
11289    pub not_null: Option<Box<Expression>>,
11290    #[serde(default)]
11291    pub data_type: Option<Box<Expression>>,
11292}
11293
11294/// InOutColumnConstraint
11295#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11296#[cfg_attr(feature = "bindings", derive(TS))]
11297pub struct InOutColumnConstraint {
11298    #[serde(default)]
11299    pub input_: Option<Box<Expression>>,
11300    #[serde(default)]
11301    pub output: Option<Box<Expression>>,
11302}
11303
11304/// PathColumnConstraint - PATH 'xpath' for XMLTABLE/JSON_TABLE columns
11305#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11306#[cfg_attr(feature = "bindings", derive(TS))]
11307pub struct PathColumnConstraint {
11308    pub this: Box<Expression>,
11309}
11310
11311/// Constraint
11312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11313#[cfg_attr(feature = "bindings", derive(TS))]
11314pub struct Constraint {
11315    pub this: Box<Expression>,
11316    #[serde(default)]
11317    pub expressions: Vec<Expression>,
11318}
11319
11320/// Export
11321#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11322#[cfg_attr(feature = "bindings", derive(TS))]
11323pub struct Export {
11324    pub this: Box<Expression>,
11325    #[serde(default)]
11326    pub connection: Option<Box<Expression>>,
11327    #[serde(default)]
11328    pub options: Vec<Expression>,
11329}
11330
11331/// Filter
11332#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11333#[cfg_attr(feature = "bindings", derive(TS))]
11334pub struct Filter {
11335    pub this: Box<Expression>,
11336    pub expression: Box<Expression>,
11337}
11338
11339/// Changes
11340#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11341#[cfg_attr(feature = "bindings", derive(TS))]
11342pub struct Changes {
11343    #[serde(default)]
11344    pub information: Option<Box<Expression>>,
11345    #[serde(default)]
11346    pub at_before: Option<Box<Expression>>,
11347    #[serde(default)]
11348    pub end: Option<Box<Expression>>,
11349}
11350
11351/// Directory
11352#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11353#[cfg_attr(feature = "bindings", derive(TS))]
11354pub struct Directory {
11355    pub this: Box<Expression>,
11356    #[serde(default)]
11357    pub local: Option<Box<Expression>>,
11358    #[serde(default)]
11359    pub row_format: Option<Box<Expression>>,
11360}
11361
11362/// ForeignKey
11363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11364#[cfg_attr(feature = "bindings", derive(TS))]
11365pub struct ForeignKey {
11366    #[serde(default)]
11367    pub expressions: Vec<Expression>,
11368    #[serde(default)]
11369    pub reference: Option<Box<Expression>>,
11370    #[serde(default)]
11371    pub delete: Option<Box<Expression>>,
11372    #[serde(default)]
11373    pub update: Option<Box<Expression>>,
11374    #[serde(default)]
11375    pub options: Vec<Expression>,
11376}
11377
11378/// ColumnPrefix
11379#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11380#[cfg_attr(feature = "bindings", derive(TS))]
11381pub struct ColumnPrefix {
11382    pub this: Box<Expression>,
11383    pub expression: Box<Expression>,
11384}
11385
11386/// PrimaryKey
11387#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11388#[cfg_attr(feature = "bindings", derive(TS))]
11389pub struct PrimaryKey {
11390    #[serde(default)]
11391    pub this: Option<Box<Expression>>,
11392    #[serde(default)]
11393    pub expressions: Vec<Expression>,
11394    #[serde(default)]
11395    pub options: Vec<Expression>,
11396    #[serde(default)]
11397    pub include: Option<Box<Expression>>,
11398}
11399
11400/// Into
11401#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11402#[cfg_attr(feature = "bindings", derive(TS))]
11403pub struct IntoClause {
11404    #[serde(default)]
11405    pub this: Option<Box<Expression>>,
11406    #[serde(default)]
11407    pub temporary: bool,
11408    #[serde(default)]
11409    pub unlogged: Option<Box<Expression>>,
11410    #[serde(default)]
11411    pub bulk_collect: Option<Box<Expression>>,
11412    #[serde(default)]
11413    pub expressions: Vec<Expression>,
11414}
11415
11416/// JoinHint
11417#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11418#[cfg_attr(feature = "bindings", derive(TS))]
11419pub struct JoinHint {
11420    pub this: Box<Expression>,
11421    #[serde(default)]
11422    pub expressions: Vec<Expression>,
11423}
11424
11425/// Opclass
11426#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11427#[cfg_attr(feature = "bindings", derive(TS))]
11428pub struct Opclass {
11429    pub this: Box<Expression>,
11430    pub expression: Box<Expression>,
11431}
11432
11433/// Index
11434#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11435#[cfg_attr(feature = "bindings", derive(TS))]
11436pub struct Index {
11437    #[serde(default)]
11438    pub this: Option<Box<Expression>>,
11439    #[serde(default)]
11440    pub table: Option<Box<Expression>>,
11441    #[serde(default)]
11442    pub unique: bool,
11443    #[serde(default)]
11444    pub primary: Option<Box<Expression>>,
11445    #[serde(default)]
11446    pub amp: Option<Box<Expression>>,
11447    #[serde(default)]
11448    pub params: Vec<Expression>,
11449}
11450
11451/// IndexParameters
11452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11453#[cfg_attr(feature = "bindings", derive(TS))]
11454pub struct IndexParameters {
11455    #[serde(default)]
11456    pub using: Option<Box<Expression>>,
11457    #[serde(default)]
11458    pub include: Option<Box<Expression>>,
11459    #[serde(default)]
11460    pub columns: Vec<Expression>,
11461    #[serde(default)]
11462    pub with_storage: Option<Box<Expression>>,
11463    #[serde(default)]
11464    pub partition_by: Option<Box<Expression>>,
11465    #[serde(default)]
11466    pub tablespace: Option<Box<Expression>>,
11467    #[serde(default)]
11468    pub where_: Option<Box<Expression>>,
11469    #[serde(default)]
11470    pub on: Option<Box<Expression>>,
11471}
11472
11473/// ConditionalInsert
11474#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11475#[cfg_attr(feature = "bindings", derive(TS))]
11476pub struct ConditionalInsert {
11477    pub this: Box<Expression>,
11478    #[serde(default)]
11479    pub expression: Option<Box<Expression>>,
11480    #[serde(default)]
11481    pub else_: Option<Box<Expression>>,
11482}
11483
11484/// MultitableInserts
11485#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11486#[cfg_attr(feature = "bindings", derive(TS))]
11487pub struct MultitableInserts {
11488    #[serde(default)]
11489    pub expressions: Vec<Expression>,
11490    pub kind: String,
11491    #[serde(default)]
11492    pub source: Option<Box<Expression>>,
11493    /// Leading comments before the statement
11494    #[serde(default)]
11495    pub leading_comments: Vec<String>,
11496    /// OVERWRITE modifier (Snowflake: INSERT OVERWRITE ALL)
11497    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11498    pub overwrite: bool,
11499}
11500
11501/// OnConflict
11502#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11503#[cfg_attr(feature = "bindings", derive(TS))]
11504pub struct OnConflict {
11505    #[serde(default)]
11506    pub duplicate: Option<Box<Expression>>,
11507    #[serde(default)]
11508    pub expressions: Vec<Expression>,
11509    #[serde(default)]
11510    pub action: Option<Box<Expression>>,
11511    #[serde(default)]
11512    pub conflict_keys: Option<Box<Expression>>,
11513    #[serde(default)]
11514    pub index_predicate: Option<Box<Expression>>,
11515    #[serde(default)]
11516    pub constraint: Option<Box<Expression>>,
11517    #[serde(default)]
11518    pub where_: Option<Box<Expression>>,
11519}
11520
11521/// OnCondition
11522#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11523#[cfg_attr(feature = "bindings", derive(TS))]
11524pub struct OnCondition {
11525    #[serde(default)]
11526    pub error: Option<Box<Expression>>,
11527    #[serde(default)]
11528    pub empty: Option<Box<Expression>>,
11529    #[serde(default)]
11530    pub null: Option<Box<Expression>>,
11531}
11532
11533/// Returning
11534#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11535#[cfg_attr(feature = "bindings", derive(TS))]
11536pub struct Returning {
11537    #[serde(default)]
11538    pub expressions: Vec<Expression>,
11539    #[serde(default)]
11540    pub into: Option<Box<Expression>>,
11541}
11542
11543/// Introducer
11544#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11545#[cfg_attr(feature = "bindings", derive(TS))]
11546pub struct Introducer {
11547    pub this: Box<Expression>,
11548    pub expression: Box<Expression>,
11549}
11550
11551/// PartitionRange
11552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11553#[cfg_attr(feature = "bindings", derive(TS))]
11554pub struct PartitionRange {
11555    pub this: Box<Expression>,
11556    #[serde(default)]
11557    pub expression: Option<Box<Expression>>,
11558    #[serde(default)]
11559    pub expressions: Vec<Expression>,
11560}
11561
11562/// Group
11563#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11564#[cfg_attr(feature = "bindings", derive(TS))]
11565pub struct Group {
11566    #[serde(default)]
11567    pub expressions: Vec<Expression>,
11568    #[serde(default)]
11569    pub grouping_sets: Option<Box<Expression>>,
11570    #[serde(default)]
11571    pub cube: Option<Box<Expression>>,
11572    #[serde(default)]
11573    pub rollup: Option<Box<Expression>>,
11574    #[serde(default)]
11575    pub totals: Option<Box<Expression>>,
11576    /// GROUP BY modifier: Some(true) = ALL, Some(false) = DISTINCT, None = no modifier
11577    #[serde(default)]
11578    pub all: Option<bool>,
11579}
11580
11581/// Cube
11582#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11583#[cfg_attr(feature = "bindings", derive(TS))]
11584pub struct Cube {
11585    /// Selection, subtotal, and result-delivery options for this grouping operation.
11586    #[serde(default, skip_serializing_if = "Option::is_none")]
11587    pub options: Option<GroupingOptions>,
11588    #[serde(default)]
11589    pub expressions: Vec<Expression>,
11590}
11591
11592/// Rollup
11593#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11594#[cfg_attr(feature = "bindings", derive(TS))]
11595pub struct Rollup {
11596    /// Selection, subtotal, and result-delivery options for this grouping operation.
11597    #[serde(default, skip_serializing_if = "Option::is_none")]
11598    pub options: Option<GroupingOptions>,
11599    #[serde(default)]
11600    pub expressions: Vec<Expression>,
11601}
11602
11603/// GroupingSets
11604#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11605#[cfg_attr(feature = "bindings", derive(TS))]
11606pub struct GroupingSets {
11607    /// Selection, subtotal, and result-delivery options for this grouping operation.
11608    #[serde(default, skip_serializing_if = "Option::is_none")]
11609    pub options: Option<GroupingOptions>,
11610    #[serde(default)]
11611    pub expressions: Vec<Expression>,
11612}
11613
11614/// LimitOptions
11615#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11616#[cfg_attr(feature = "bindings", derive(TS))]
11617pub struct LimitOptions {
11618    #[serde(default)]
11619    pub percent: Option<Box<Expression>>,
11620    #[serde(default)]
11621    pub rows: Option<Box<Expression>>,
11622    #[serde(default)]
11623    pub with_ties: Option<Box<Expression>>,
11624}
11625
11626/// Lateral
11627#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11628#[cfg_attr(feature = "bindings", derive(TS))]
11629pub struct Lateral {
11630    pub this: Box<Expression>,
11631    #[serde(default)]
11632    pub view: Option<Box<Expression>>,
11633    #[serde(default)]
11634    pub outer: Option<Box<Expression>>,
11635    #[serde(default)]
11636    pub alias: Option<String>,
11637    /// Whether the alias was originally quoted (backtick/double-quote)
11638    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
11639    pub alias_quoted: bool,
11640    #[serde(default)]
11641    pub cross_apply: Option<Box<Expression>>,
11642    #[serde(default)]
11643    pub ordinality: Option<Box<Expression>>,
11644    /// Column aliases for the lateral expression (e.g., LATERAL func() AS alias(col1, col2))
11645    #[serde(default, skip_serializing_if = "Vec::is_empty")]
11646    pub column_aliases: Vec<String>,
11647}
11648
11649/// TableFromRows
11650#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11651#[cfg_attr(feature = "bindings", derive(TS))]
11652pub struct TableFromRows {
11653    pub this: Box<Expression>,
11654    #[serde(default)]
11655    pub alias: Option<String>,
11656    #[serde(default)]
11657    pub joins: Vec<Expression>,
11658    #[serde(default)]
11659    pub pivots: Option<Box<Expression>>,
11660    #[serde(default)]
11661    pub sample: Option<Box<Expression>>,
11662}
11663
11664/// RowsFrom - PostgreSQL ROWS FROM (func1(args) AS alias1(...), func2(args) AS alias2(...)) syntax
11665/// Used for set-returning functions with typed column definitions
11666#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11667#[cfg_attr(feature = "bindings", derive(TS))]
11668pub struct RowsFrom {
11669    /// List of function expressions, each potentially with an alias and typed columns
11670    pub expressions: Vec<Expression>,
11671    /// WITH ORDINALITY modifier
11672    #[serde(default)]
11673    pub ordinality: bool,
11674    /// Optional outer alias: ROWS FROM (...) AS alias(col1 type1, col2 type2)
11675    #[serde(default)]
11676    pub alias: Option<Box<Expression>>,
11677}
11678
11679/// WithFill
11680#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11681#[cfg_attr(feature = "bindings", derive(TS))]
11682pub struct WithFill {
11683    #[serde(default)]
11684    pub from_: Option<Box<Expression>>,
11685    #[serde(default)]
11686    pub to: Option<Box<Expression>>,
11687    #[serde(default)]
11688    pub step: Option<Box<Expression>>,
11689    #[serde(default)]
11690    pub staleness: Option<Box<Expression>>,
11691    #[serde(default)]
11692    pub interpolate: Option<Box<Expression>>,
11693}
11694
11695/// Property
11696#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11697#[cfg_attr(feature = "bindings", derive(TS))]
11698pub struct Property {
11699    pub this: Box<Expression>,
11700    #[serde(default)]
11701    pub value: Option<Box<Expression>>,
11702}
11703
11704/// GrantPrivilege
11705#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11706#[cfg_attr(feature = "bindings", derive(TS))]
11707pub struct GrantPrivilege {
11708    pub this: Box<Expression>,
11709    #[serde(default)]
11710    pub expressions: Vec<Expression>,
11711}
11712
11713/// AllowedValuesProperty
11714#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11715#[cfg_attr(feature = "bindings", derive(TS))]
11716pub struct AllowedValuesProperty {
11717    #[serde(default)]
11718    pub expressions: Vec<Expression>,
11719}
11720
11721/// AlgorithmProperty
11722#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11723#[cfg_attr(feature = "bindings", derive(TS))]
11724pub struct AlgorithmProperty {
11725    pub this: Box<Expression>,
11726}
11727
11728/// AutoIncrementProperty
11729#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11730#[cfg_attr(feature = "bindings", derive(TS))]
11731pub struct AutoIncrementProperty {
11732    pub this: Box<Expression>,
11733}
11734
11735/// AutoRefreshProperty
11736#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11737#[cfg_attr(feature = "bindings", derive(TS))]
11738pub struct AutoRefreshProperty {
11739    pub this: Box<Expression>,
11740}
11741
11742/// BackupProperty
11743#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11744#[cfg_attr(feature = "bindings", derive(TS))]
11745pub struct BackupProperty {
11746    pub this: Box<Expression>,
11747}
11748
11749/// BuildProperty
11750#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11751#[cfg_attr(feature = "bindings", derive(TS))]
11752pub struct BuildProperty {
11753    pub this: Box<Expression>,
11754}
11755
11756/// BlockCompressionProperty
11757#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11758#[cfg_attr(feature = "bindings", derive(TS))]
11759pub struct BlockCompressionProperty {
11760    #[serde(default)]
11761    pub autotemp: Option<Box<Expression>>,
11762    #[serde(default)]
11763    pub always: Option<Box<Expression>>,
11764    #[serde(default)]
11765    pub default: Option<Box<Expression>>,
11766    #[serde(default)]
11767    pub manual: Option<Box<Expression>>,
11768    #[serde(default)]
11769    pub never: Option<Box<Expression>>,
11770}
11771
11772/// CharacterSetProperty
11773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11774#[cfg_attr(feature = "bindings", derive(TS))]
11775pub struct CharacterSetProperty {
11776    pub this: Box<Expression>,
11777    #[serde(default)]
11778    pub default: Option<Box<Expression>>,
11779}
11780
11781/// ChecksumProperty
11782#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11783#[cfg_attr(feature = "bindings", derive(TS))]
11784pub struct ChecksumProperty {
11785    #[serde(default)]
11786    pub on: Option<Box<Expression>>,
11787    #[serde(default)]
11788    pub default: Option<Box<Expression>>,
11789}
11790
11791/// CollateProperty
11792#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11793#[cfg_attr(feature = "bindings", derive(TS))]
11794pub struct CollateProperty {
11795    pub this: Box<Expression>,
11796    #[serde(default)]
11797    pub default: Option<Box<Expression>>,
11798}
11799
11800/// DataBlocksizeProperty
11801#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11802#[cfg_attr(feature = "bindings", derive(TS))]
11803pub struct DataBlocksizeProperty {
11804    #[serde(default)]
11805    pub size: Option<i64>,
11806    #[serde(default)]
11807    pub units: Option<Box<Expression>>,
11808    #[serde(default)]
11809    pub minimum: Option<Box<Expression>>,
11810    #[serde(default)]
11811    pub maximum: Option<Box<Expression>>,
11812    #[serde(default)]
11813    pub default: Option<Box<Expression>>,
11814}
11815
11816/// DataDeletionProperty
11817#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11818#[cfg_attr(feature = "bindings", derive(TS))]
11819pub struct DataDeletionProperty {
11820    /// Syntax marker for the ON/OFF keyword, not a transformable boolean expression.
11821    #[ast(skip)]
11822    pub on: Box<Expression>,
11823    #[serde(default)]
11824    pub filter_column: Option<Box<Expression>>,
11825    #[serde(default)]
11826    pub retention_period: Option<Box<Expression>>,
11827}
11828
11829/// DefinerProperty
11830#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11831#[cfg_attr(feature = "bindings", derive(TS))]
11832pub struct DefinerProperty {
11833    pub this: Box<Expression>,
11834}
11835
11836/// DistKeyProperty
11837#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11838#[cfg_attr(feature = "bindings", derive(TS))]
11839pub struct DistKeyProperty {
11840    pub this: Box<Expression>,
11841}
11842
11843/// DistributedByProperty
11844#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11845#[cfg_attr(feature = "bindings", derive(TS))]
11846pub struct DistributedByProperty {
11847    #[serde(default)]
11848    pub expressions: Vec<Expression>,
11849    pub kind: String,
11850    #[serde(default)]
11851    pub buckets: Option<Box<Expression>>,
11852    #[serde(default)]
11853    pub order: Option<Box<Expression>>,
11854}
11855
11856/// DistStyleProperty
11857#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11858#[cfg_attr(feature = "bindings", derive(TS))]
11859pub struct DistStyleProperty {
11860    pub this: Box<Expression>,
11861}
11862
11863/// DuplicateKeyProperty
11864#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11865#[cfg_attr(feature = "bindings", derive(TS))]
11866pub struct DuplicateKeyProperty {
11867    #[serde(default)]
11868    pub expressions: Vec<Expression>,
11869}
11870
11871/// EngineProperty
11872#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11873#[cfg_attr(feature = "bindings", derive(TS))]
11874pub struct EngineProperty {
11875    pub this: Box<Expression>,
11876}
11877
11878/// ToTableProperty
11879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11880#[cfg_attr(feature = "bindings", derive(TS))]
11881pub struct ToTableProperty {
11882    pub this: Box<Expression>,
11883}
11884
11885/// ExecuteAsProperty
11886#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11887#[cfg_attr(feature = "bindings", derive(TS))]
11888pub struct ExecuteAsProperty {
11889    pub this: Box<Expression>,
11890}
11891
11892/// ExternalProperty
11893#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11894#[cfg_attr(feature = "bindings", derive(TS))]
11895pub struct ExternalProperty {
11896    #[serde(default)]
11897    pub this: Option<Box<Expression>>,
11898}
11899
11900/// FallbackProperty
11901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11902#[cfg_attr(feature = "bindings", derive(TS))]
11903pub struct FallbackProperty {
11904    #[serde(default)]
11905    pub no: Option<Box<Expression>>,
11906    #[serde(default)]
11907    pub protection: Option<Box<Expression>>,
11908}
11909
11910/// FileFormatProperty
11911#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11912#[cfg_attr(feature = "bindings", derive(TS))]
11913pub struct FileFormatProperty {
11914    #[serde(default)]
11915    pub this: Option<Box<Expression>>,
11916    #[serde(default)]
11917    pub expressions: Vec<Expression>,
11918    #[serde(default)]
11919    pub hive_format: Option<Box<Expression>>,
11920}
11921
11922/// CredentialsProperty
11923#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11924#[cfg_attr(feature = "bindings", derive(TS))]
11925pub struct CredentialsProperty {
11926    #[serde(default)]
11927    pub expressions: Vec<Expression>,
11928}
11929
11930/// FreespaceProperty
11931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11932#[cfg_attr(feature = "bindings", derive(TS))]
11933pub struct FreespaceProperty {
11934    pub this: Box<Expression>,
11935    #[serde(default)]
11936    pub percent: Option<Box<Expression>>,
11937}
11938
11939/// InheritsProperty
11940#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11941#[cfg_attr(feature = "bindings", derive(TS))]
11942pub struct InheritsProperty {
11943    #[serde(default)]
11944    pub expressions: Vec<Expression>,
11945}
11946
11947/// InputModelProperty
11948#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11949#[cfg_attr(feature = "bindings", derive(TS))]
11950pub struct InputModelProperty {
11951    pub this: Box<Expression>,
11952}
11953
11954/// OutputModelProperty
11955#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11956#[cfg_attr(feature = "bindings", derive(TS))]
11957pub struct OutputModelProperty {
11958    pub this: Box<Expression>,
11959}
11960
11961/// IsolatedLoadingProperty
11962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11963#[cfg_attr(feature = "bindings", derive(TS))]
11964pub struct IsolatedLoadingProperty {
11965    #[serde(default)]
11966    pub no: Option<Box<Expression>>,
11967    #[serde(default)]
11968    pub concurrent: Option<Box<Expression>>,
11969    #[serde(default)]
11970    pub target: Option<Box<Expression>>,
11971}
11972
11973/// JournalProperty
11974#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11975#[cfg_attr(feature = "bindings", derive(TS))]
11976pub struct JournalProperty {
11977    #[serde(default)]
11978    pub no: Option<Box<Expression>>,
11979    #[serde(default)]
11980    pub dual: Option<Box<Expression>>,
11981    #[serde(default)]
11982    pub before: Option<Box<Expression>>,
11983    #[serde(default)]
11984    pub local: Option<Box<Expression>>,
11985    #[serde(default)]
11986    pub after: Option<Box<Expression>>,
11987}
11988
11989/// LanguageProperty
11990#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11991#[cfg_attr(feature = "bindings", derive(TS))]
11992pub struct LanguageProperty {
11993    pub this: Box<Expression>,
11994}
11995
11996/// EnviromentProperty
11997#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
11998#[cfg_attr(feature = "bindings", derive(TS))]
11999pub struct EnviromentProperty {
12000    #[serde(default)]
12001    pub expressions: Vec<Expression>,
12002}
12003
12004/// ClusteredByProperty
12005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12006#[cfg_attr(feature = "bindings", derive(TS))]
12007pub struct ClusteredByProperty {
12008    #[serde(default)]
12009    pub expressions: Vec<Expression>,
12010    #[serde(default)]
12011    pub sorted_by: Option<Box<Expression>>,
12012    #[serde(default)]
12013    pub buckets: Option<Box<Expression>>,
12014}
12015
12016/// DictProperty
12017#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12018#[cfg_attr(feature = "bindings", derive(TS))]
12019pub struct DictProperty {
12020    pub this: Box<Expression>,
12021    pub kind: String,
12022    #[serde(default)]
12023    pub settings: Option<Box<Expression>>,
12024}
12025
12026/// DictRange
12027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12028#[cfg_attr(feature = "bindings", derive(TS))]
12029pub struct DictRange {
12030    pub this: Box<Expression>,
12031    #[serde(default)]
12032    pub min: Option<Box<Expression>>,
12033    #[serde(default)]
12034    pub max: Option<Box<Expression>>,
12035}
12036
12037/// OnCluster
12038#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12039#[cfg_attr(feature = "bindings", derive(TS))]
12040pub struct OnCluster {
12041    pub this: Box<Expression>,
12042}
12043
12044/// LikeProperty
12045#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12046#[cfg_attr(feature = "bindings", derive(TS))]
12047pub struct LikeProperty {
12048    pub this: Box<Expression>,
12049    #[serde(default)]
12050    pub expressions: Vec<Expression>,
12051}
12052
12053/// LocationProperty
12054#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12055#[cfg_attr(feature = "bindings", derive(TS))]
12056pub struct LocationProperty {
12057    pub this: Box<Expression>,
12058}
12059
12060/// LockProperty
12061#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12062#[cfg_attr(feature = "bindings", derive(TS))]
12063pub struct LockProperty {
12064    pub this: Box<Expression>,
12065}
12066
12067/// LockingProperty
12068#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12069#[cfg_attr(feature = "bindings", derive(TS))]
12070pub struct LockingProperty {
12071    #[serde(default)]
12072    pub this: Option<Box<Expression>>,
12073    pub kind: String,
12074    #[serde(default)]
12075    pub for_or_in: Option<Box<Expression>>,
12076    #[serde(default)]
12077    pub lock_type: Option<Box<Expression>>,
12078    #[serde(default)]
12079    pub override_: Option<Box<Expression>>,
12080}
12081
12082/// LogProperty
12083#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12084#[cfg_attr(feature = "bindings", derive(TS))]
12085pub struct LogProperty {
12086    #[serde(default)]
12087    pub no: Option<Box<Expression>>,
12088}
12089
12090/// MaterializedProperty
12091#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12092#[cfg_attr(feature = "bindings", derive(TS))]
12093pub struct MaterializedProperty {
12094    #[serde(default)]
12095    pub this: Option<Box<Expression>>,
12096}
12097
12098/// MergeBlockRatioProperty
12099#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12100#[cfg_attr(feature = "bindings", derive(TS))]
12101pub struct MergeBlockRatioProperty {
12102    #[serde(default)]
12103    pub this: Option<Box<Expression>>,
12104    #[serde(default)]
12105    pub no: Option<Box<Expression>>,
12106    #[serde(default)]
12107    pub default: Option<Box<Expression>>,
12108    #[serde(default)]
12109    pub percent: Option<Box<Expression>>,
12110}
12111
12112/// OnProperty
12113#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12114#[cfg_attr(feature = "bindings", derive(TS))]
12115pub struct OnProperty {
12116    pub this: Box<Expression>,
12117}
12118
12119/// OnCommitProperty
12120#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12121#[cfg_attr(feature = "bindings", derive(TS))]
12122pub struct OnCommitProperty {
12123    #[serde(default)]
12124    pub delete: Option<Box<Expression>>,
12125}
12126
12127/// PartitionedByProperty
12128#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12129#[cfg_attr(feature = "bindings", derive(TS))]
12130pub struct PartitionedByProperty {
12131    pub this: Box<Expression>,
12132}
12133
12134/// BigQuery PARTITION BY property in CREATE TABLE statements.
12135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12136#[cfg_attr(feature = "bindings", derive(TS))]
12137pub struct PartitionByProperty {
12138    /// Structured partition scheme when the dialect supports methods and ranges.
12139    #[serde(default, skip_serializing_if = "Option::is_none")]
12140    pub specification: Option<PartitionSpec>,
12141    #[serde(default)]
12142    pub expressions: Vec<Expression>,
12143}
12144
12145/// PartitionedByBucket
12146#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12147#[cfg_attr(feature = "bindings", derive(TS))]
12148pub struct PartitionedByBucket {
12149    pub this: Box<Expression>,
12150    pub expression: Box<Expression>,
12151}
12152
12153/// BigQuery CLUSTER BY property in CREATE TABLE statements.
12154#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12155#[cfg_attr(feature = "bindings", derive(TS))]
12156pub struct ClusterByColumnsProperty {
12157    #[serde(default)]
12158    pub columns: Vec<Identifier>,
12159}
12160
12161/// PartitionByTruncate
12162#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12163#[cfg_attr(feature = "bindings", derive(TS))]
12164pub struct PartitionByTruncate {
12165    pub this: Box<Expression>,
12166    pub expression: Box<Expression>,
12167}
12168
12169/// PartitionByRangeProperty
12170#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12171#[cfg_attr(feature = "bindings", derive(TS))]
12172pub struct PartitionByRangeProperty {
12173    #[serde(default)]
12174    pub partition_expressions: Option<Box<Expression>>,
12175    #[serde(default)]
12176    pub create_expressions: Option<Box<Expression>>,
12177}
12178
12179/// PartitionByRangePropertyDynamic
12180#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12181#[cfg_attr(feature = "bindings", derive(TS))]
12182pub struct PartitionByRangePropertyDynamic {
12183    #[serde(default)]
12184    pub this: Option<Box<Expression>>,
12185    #[serde(default)]
12186    pub start: Option<Box<Expression>>,
12187    /// Use START/END/EVERY keywords (StarRocks) instead of FROM/TO/INTERVAL (Doris)
12188    #[serde(default)]
12189    pub use_start_end: bool,
12190    #[serde(default)]
12191    pub end: Option<Box<Expression>>,
12192    #[serde(default)]
12193    pub every: Option<Box<Expression>>,
12194}
12195
12196/// PartitionByListProperty
12197#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12198#[cfg_attr(feature = "bindings", derive(TS))]
12199pub struct PartitionByListProperty {
12200    #[serde(default)]
12201    pub partition_expressions: Option<Box<Expression>>,
12202    #[serde(default)]
12203    pub create_expressions: Option<Box<Expression>>,
12204}
12205
12206/// PartitionList
12207#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12208#[cfg_attr(feature = "bindings", derive(TS))]
12209pub struct PartitionList {
12210    pub this: Box<Expression>,
12211    #[serde(default)]
12212    pub expressions: Vec<Expression>,
12213}
12214
12215/// Partition - represents PARTITION/SUBPARTITION clause
12216#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12217#[cfg_attr(feature = "bindings", derive(TS))]
12218pub struct Partition {
12219    pub expressions: Vec<Expression>,
12220    #[serde(default)]
12221    pub subpartition: bool,
12222}
12223
12224/// RefreshTriggerProperty - Doris REFRESH clause for materialized views
12225/// e.g., REFRESH COMPLETE ON MANUAL, REFRESH AUTO ON SCHEDULE EVERY 5 MINUTE
12226#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12227#[cfg_attr(feature = "bindings", derive(TS))]
12228pub struct RefreshTriggerProperty {
12229    /// Method: COMPLETE or AUTO
12230    pub method: String,
12231    /// Trigger kind: MANUAL, COMMIT, or SCHEDULE
12232    #[serde(default)]
12233    pub kind: Option<String>,
12234    /// For SCHEDULE: EVERY n (the number)
12235    #[serde(default)]
12236    pub every: Option<Box<Expression>>,
12237    /// For SCHEDULE: the time unit (MINUTE, HOUR, DAY, etc.)
12238    #[serde(default)]
12239    pub unit: Option<String>,
12240    /// For SCHEDULE: STARTS 'datetime'
12241    #[serde(default)]
12242    pub starts: Option<Box<Expression>>,
12243}
12244
12245/// UniqueKeyProperty
12246#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12247#[cfg_attr(feature = "bindings", derive(TS))]
12248pub struct UniqueKeyProperty {
12249    #[serde(default)]
12250    pub expressions: Vec<Expression>,
12251}
12252
12253/// RollupProperty - StarRocks ROLLUP (index_name(col1, col2), ...)
12254#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12255#[cfg_attr(feature = "bindings", derive(TS))]
12256pub struct RollupProperty {
12257    pub expressions: Vec<RollupIndex>,
12258}
12259
12260/// RollupIndex - A single rollup index: name(col1, col2)
12261#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12262#[cfg_attr(feature = "bindings", derive(TS))]
12263pub struct RollupIndex {
12264    pub name: Identifier,
12265    pub expressions: Vec<Identifier>,
12266}
12267
12268/// PartitionBoundSpec
12269#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12270#[cfg_attr(feature = "bindings", derive(TS))]
12271pub struct PartitionBoundSpec {
12272    #[serde(default)]
12273    pub this: Option<Box<Expression>>,
12274    #[serde(default)]
12275    pub expression: Option<Box<Expression>>,
12276    #[serde(default)]
12277    pub from_expressions: Option<Box<Expression>>,
12278    #[serde(default)]
12279    pub to_expressions: Option<Box<Expression>>,
12280}
12281
12282/// PartitionedOfProperty
12283#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12284#[cfg_attr(feature = "bindings", derive(TS))]
12285pub struct PartitionedOfProperty {
12286    pub this: Box<Expression>,
12287    pub expression: Box<Expression>,
12288}
12289
12290/// RemoteWithConnectionModelProperty
12291#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12292#[cfg_attr(feature = "bindings", derive(TS))]
12293pub struct RemoteWithConnectionModelProperty {
12294    pub this: Box<Expression>,
12295}
12296
12297/// ReturnsProperty
12298#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12299#[cfg_attr(feature = "bindings", derive(TS))]
12300pub struct ReturnsProperty {
12301    #[serde(default)]
12302    pub this: Option<Box<Expression>>,
12303    #[serde(default)]
12304    pub is_table: Option<Box<Expression>>,
12305    #[serde(default)]
12306    pub table: Option<Box<Expression>>,
12307    #[serde(default)]
12308    pub null: Option<Box<Expression>>,
12309}
12310
12311/// RowFormatProperty
12312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12313#[cfg_attr(feature = "bindings", derive(TS))]
12314pub struct RowFormatProperty {
12315    pub this: Box<Expression>,
12316}
12317
12318/// RowFormatDelimitedProperty
12319#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12320#[cfg_attr(feature = "bindings", derive(TS))]
12321pub struct RowFormatDelimitedProperty {
12322    #[serde(default)]
12323    pub fields: Option<Box<Expression>>,
12324    #[serde(default)]
12325    pub escaped: Option<Box<Expression>>,
12326    #[serde(default)]
12327    pub collection_items: Option<Box<Expression>>,
12328    #[serde(default)]
12329    pub map_keys: Option<Box<Expression>>,
12330    #[serde(default)]
12331    pub lines: Option<Box<Expression>>,
12332    #[serde(default)]
12333    pub null: Option<Box<Expression>>,
12334    #[serde(default)]
12335    pub serde: Option<Box<Expression>>,
12336}
12337
12338/// RowFormatSerdeProperty
12339#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12340#[cfg_attr(feature = "bindings", derive(TS))]
12341pub struct RowFormatSerdeProperty {
12342    pub this: Box<Expression>,
12343    #[serde(default)]
12344    pub serde_properties: Option<Box<Expression>>,
12345}
12346
12347/// QueryTransform
12348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12349#[cfg_attr(feature = "bindings", derive(TS))]
12350pub struct QueryTransform {
12351    #[serde(default)]
12352    pub expressions: Vec<Expression>,
12353    #[serde(default)]
12354    pub command_script: Option<Box<Expression>>,
12355    #[serde(default)]
12356    pub schema: Option<Box<Expression>>,
12357    #[serde(default)]
12358    pub row_format_before: Option<Box<Expression>>,
12359    #[serde(default)]
12360    pub record_writer: Option<Box<Expression>>,
12361    #[serde(default)]
12362    pub row_format_after: Option<Box<Expression>>,
12363    #[serde(default)]
12364    pub record_reader: Option<Box<Expression>>,
12365}
12366
12367/// SampleProperty
12368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12369#[cfg_attr(feature = "bindings", derive(TS))]
12370pub struct SampleProperty {
12371    pub this: Box<Expression>,
12372}
12373
12374/// SecurityProperty
12375#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12376#[cfg_attr(feature = "bindings", derive(TS))]
12377pub struct SecurityProperty {
12378    pub this: Box<Expression>,
12379}
12380
12381/// SchemaCommentProperty
12382#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12383#[cfg_attr(feature = "bindings", derive(TS))]
12384pub struct SchemaCommentProperty {
12385    pub this: Box<Expression>,
12386}
12387
12388/// SemanticView
12389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12390#[cfg_attr(feature = "bindings", derive(TS))]
12391pub struct SemanticView {
12392    pub this: Box<Expression>,
12393    #[serde(default)]
12394    pub metrics: Option<Box<Expression>>,
12395    #[serde(default)]
12396    pub dimensions: Option<Box<Expression>>,
12397    #[serde(default)]
12398    pub facts: Option<Box<Expression>>,
12399    #[serde(default)]
12400    pub where_: Option<Box<Expression>>,
12401}
12402
12403/// SerdeProperties
12404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12405#[cfg_attr(feature = "bindings", derive(TS))]
12406pub struct SerdeProperties {
12407    #[serde(default)]
12408    pub expressions: Vec<Expression>,
12409    #[serde(default)]
12410    pub with_: Option<Box<Expression>>,
12411}
12412
12413/// SetProperty
12414#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12415#[cfg_attr(feature = "bindings", derive(TS))]
12416pub struct SetProperty {
12417    #[serde(default)]
12418    pub multi: Option<Box<Expression>>,
12419}
12420
12421/// SharingProperty
12422#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12423#[cfg_attr(feature = "bindings", derive(TS))]
12424pub struct SharingProperty {
12425    #[serde(default)]
12426    pub this: Option<Box<Expression>>,
12427}
12428
12429/// SetConfigProperty
12430#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12431#[cfg_attr(feature = "bindings", derive(TS))]
12432pub struct SetConfigProperty {
12433    pub this: Box<Expression>,
12434}
12435
12436/// SettingsProperty
12437#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12438#[cfg_attr(feature = "bindings", derive(TS))]
12439pub struct SettingsProperty {
12440    #[serde(default)]
12441    pub expressions: Vec<Expression>,
12442}
12443
12444/// SortKeyProperty
12445#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12446#[cfg_attr(feature = "bindings", derive(TS))]
12447pub struct SortKeyProperty {
12448    pub this: Box<Expression>,
12449    #[serde(default)]
12450    pub compound: Option<Box<Expression>>,
12451}
12452
12453/// SqlReadWriteProperty
12454#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12455#[cfg_attr(feature = "bindings", derive(TS))]
12456pub struct SqlReadWriteProperty {
12457    pub this: Box<Expression>,
12458}
12459
12460/// SqlSecurityProperty
12461#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12462#[cfg_attr(feature = "bindings", derive(TS))]
12463pub struct SqlSecurityProperty {
12464    pub this: Box<Expression>,
12465}
12466
12467/// StabilityProperty
12468#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12469#[cfg_attr(feature = "bindings", derive(TS))]
12470pub struct StabilityProperty {
12471    pub this: Box<Expression>,
12472}
12473
12474/// StorageHandlerProperty
12475#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12476#[cfg_attr(feature = "bindings", derive(TS))]
12477pub struct StorageHandlerProperty {
12478    pub this: Box<Expression>,
12479}
12480
12481/// TemporaryProperty
12482#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12483#[cfg_attr(feature = "bindings", derive(TS))]
12484pub struct TemporaryProperty {
12485    #[serde(default)]
12486    pub this: Option<Box<Expression>>,
12487}
12488
12489/// Tags
12490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12491#[cfg_attr(feature = "bindings", derive(TS))]
12492pub struct Tags {
12493    #[serde(default)]
12494    pub expressions: Vec<Expression>,
12495}
12496
12497/// TransformModelProperty
12498#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12499#[cfg_attr(feature = "bindings", derive(TS))]
12500pub struct TransformModelProperty {
12501    #[serde(default)]
12502    pub expressions: Vec<Expression>,
12503}
12504
12505/// TransientProperty
12506#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12507#[cfg_attr(feature = "bindings", derive(TS))]
12508pub struct TransientProperty {
12509    #[serde(default)]
12510    pub this: Option<Box<Expression>>,
12511}
12512
12513/// UsingTemplateProperty
12514#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12515#[cfg_attr(feature = "bindings", derive(TS))]
12516pub struct UsingTemplateProperty {
12517    pub this: Box<Expression>,
12518}
12519
12520/// ViewAttributeProperty
12521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12522#[cfg_attr(feature = "bindings", derive(TS))]
12523pub struct ViewAttributeProperty {
12524    pub this: Box<Expression>,
12525}
12526
12527/// VolatileProperty
12528#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12529#[cfg_attr(feature = "bindings", derive(TS))]
12530pub struct VolatileProperty {
12531    #[serde(default)]
12532    pub this: Option<Box<Expression>>,
12533}
12534
12535/// WithDataProperty
12536#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12537#[cfg_attr(feature = "bindings", derive(TS))]
12538pub struct WithDataProperty {
12539    #[serde(default)]
12540    pub no: Option<Box<Expression>>,
12541    #[serde(default)]
12542    pub statistics: Option<Box<Expression>>,
12543}
12544
12545/// WithJournalTableProperty
12546#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12547#[cfg_attr(feature = "bindings", derive(TS))]
12548pub struct WithJournalTableProperty {
12549    pub this: Box<Expression>,
12550}
12551
12552/// WithSchemaBindingProperty
12553#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12554#[cfg_attr(feature = "bindings", derive(TS))]
12555pub struct WithSchemaBindingProperty {
12556    pub this: Box<Expression>,
12557}
12558
12559/// WithSystemVersioningProperty
12560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12561#[cfg_attr(feature = "bindings", derive(TS))]
12562pub struct WithSystemVersioningProperty {
12563    #[serde(default)]
12564    pub on: Option<Box<Expression>>,
12565    #[serde(default)]
12566    pub this: Option<Box<Expression>>,
12567    #[serde(default)]
12568    pub data_consistency: Option<Box<Expression>>,
12569    #[serde(default)]
12570    pub retention_period: Option<Box<Expression>>,
12571    #[serde(default)]
12572    pub with_: Option<Box<Expression>>,
12573}
12574
12575/// WithProcedureOptions
12576#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12577#[cfg_attr(feature = "bindings", derive(TS))]
12578pub struct WithProcedureOptions {
12579    #[serde(default)]
12580    pub expressions: Vec<Expression>,
12581}
12582
12583/// EncodeProperty
12584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12585#[cfg_attr(feature = "bindings", derive(TS))]
12586pub struct EncodeProperty {
12587    pub this: Box<Expression>,
12588    #[serde(default)]
12589    pub properties: Vec<Expression>,
12590    #[serde(default)]
12591    pub key: Option<Box<Expression>>,
12592}
12593
12594/// IncludeProperty
12595#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12596#[cfg_attr(feature = "bindings", derive(TS))]
12597pub struct IncludeProperty {
12598    pub this: Box<Expression>,
12599    #[serde(default)]
12600    pub alias: Option<String>,
12601    #[serde(default)]
12602    pub column_def: Option<Box<Expression>>,
12603}
12604
12605/// Properties
12606#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12607#[cfg_attr(feature = "bindings", derive(TS))]
12608pub struct Properties {
12609    #[serde(default)]
12610    pub expressions: Vec<Expression>,
12611}
12612
12613/// Key/value pair in a BigQuery OPTIONS (...) clause.
12614#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12615#[cfg_attr(feature = "bindings", derive(TS))]
12616pub struct OptionEntry {
12617    pub key: Identifier,
12618    pub value: Expression,
12619}
12620
12621/// Typed BigQuery OPTIONS (...) property for CREATE TABLE and related DDL.
12622#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12623#[cfg_attr(feature = "bindings", derive(TS))]
12624pub struct OptionsProperty {
12625    #[serde(default)]
12626    pub entries: Vec<OptionEntry>,
12627}
12628
12629/// InputOutputFormat
12630#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12631#[cfg_attr(feature = "bindings", derive(TS))]
12632pub struct InputOutputFormat {
12633    #[serde(default)]
12634    pub input_format: Option<Box<Expression>>,
12635    #[serde(default)]
12636    pub output_format: Option<Box<Expression>>,
12637}
12638
12639/// Reference
12640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12641#[cfg_attr(feature = "bindings", derive(TS))]
12642pub struct Reference {
12643    pub this: Box<Expression>,
12644    #[serde(default)]
12645    pub expressions: Vec<Expression>,
12646    #[serde(default)]
12647    pub options: Vec<Expression>,
12648}
12649
12650/// QueryOption
12651#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12652#[cfg_attr(feature = "bindings", derive(TS))]
12653pub struct QueryOption {
12654    pub this: Box<Expression>,
12655    #[serde(default)]
12656    pub expression: Option<Box<Expression>>,
12657}
12658
12659/// WithTableHint
12660#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12661#[cfg_attr(feature = "bindings", derive(TS))]
12662pub struct WithTableHint {
12663    #[serde(default)]
12664    pub expressions: Vec<Expression>,
12665}
12666
12667/// IndexTableHint
12668#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12669#[cfg_attr(feature = "bindings", derive(TS))]
12670pub struct IndexTableHint {
12671    pub this: Box<Expression>,
12672    #[serde(default)]
12673    pub expressions: Vec<Expression>,
12674    #[serde(default)]
12675    pub target: Option<Box<Expression>>,
12676}
12677
12678/// Get
12679#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12680#[cfg_attr(feature = "bindings", derive(TS))]
12681pub struct Get {
12682    pub this: Box<Expression>,
12683    #[serde(default)]
12684    pub target: Option<Box<Expression>>,
12685    #[serde(default)]
12686    pub properties: Vec<Expression>,
12687}
12688
12689/// SetOperation
12690#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12691#[cfg_attr(feature = "bindings", derive(TS))]
12692pub struct SetOperation {
12693    #[serde(default)]
12694    pub with_: Option<Box<Expression>>,
12695    pub this: Box<Expression>,
12696    pub expression: Box<Expression>,
12697    #[serde(default)]
12698    pub distinct: bool,
12699    #[serde(default)]
12700    pub by_name: Option<Box<Expression>>,
12701    #[serde(default)]
12702    pub side: Option<Box<Expression>>,
12703    #[serde(default)]
12704    pub kind: Option<String>,
12705    #[serde(default)]
12706    pub on: Option<Box<Expression>>,
12707}
12708
12709/// Var - Simple variable reference (for SQL variables, keywords as values)
12710#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12711#[cfg_attr(feature = "bindings", derive(TS))]
12712pub struct Var {
12713    pub this: String,
12714}
12715
12716/// Variadic - represents VARIADIC prefix on function arguments (PostgreSQL)
12717#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12718#[cfg_attr(feature = "bindings", derive(TS))]
12719pub struct Variadic {
12720    pub this: Box<Expression>,
12721}
12722
12723/// Version
12724#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12725#[cfg_attr(feature = "bindings", derive(TS))]
12726pub struct Version {
12727    pub this: Box<Expression>,
12728    pub kind: String,
12729    #[serde(default)]
12730    pub expression: Option<Box<Expression>>,
12731}
12732
12733/// Schema
12734#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12735#[cfg_attr(feature = "bindings", derive(TS))]
12736pub struct Schema {
12737    #[serde(default)]
12738    pub this: Option<Box<Expression>>,
12739    #[serde(default)]
12740    pub expressions: Vec<Expression>,
12741}
12742
12743/// Lock
12744#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12745#[cfg_attr(feature = "bindings", derive(TS))]
12746pub struct Lock {
12747    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
12748    pub ignore_locked: bool,
12749    #[serde(default)]
12750    pub update: Option<Box<Expression>>,
12751    #[serde(default)]
12752    pub expressions: Vec<Expression>,
12753    #[serde(default)]
12754    pub wait: Option<Box<Expression>>,
12755    #[serde(default)]
12756    pub key: Option<Box<Expression>>,
12757}
12758
12759/// TableSample - wraps an expression with a TABLESAMPLE clause
12760/// Used when TABLESAMPLE follows a non-Table expression (subquery, function, etc.)
12761#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12762#[cfg_attr(feature = "bindings", derive(TS))]
12763pub struct TableSample {
12764    /// The expression being sampled (subquery, function, etc.)
12765    #[serde(default, skip_serializing_if = "Option::is_none")]
12766    pub this: Option<Box<Expression>>,
12767    /// The sample specification
12768    #[serde(default, skip_serializing_if = "Option::is_none")]
12769    pub sample: Option<Box<Sample>>,
12770    #[serde(default)]
12771    pub expressions: Vec<Expression>,
12772    #[serde(default)]
12773    pub method: Option<String>,
12774    #[serde(default)]
12775    pub bucket_numerator: Option<Box<Expression>>,
12776    #[serde(default)]
12777    pub bucket_denominator: Option<Box<Expression>>,
12778    #[serde(default)]
12779    pub bucket_field: Option<Box<Expression>>,
12780    #[serde(default)]
12781    pub percent: Option<Box<Expression>>,
12782    #[serde(default)]
12783    pub rows: Option<Box<Expression>>,
12784    #[serde(default)]
12785    pub size: Option<i64>,
12786    #[serde(default)]
12787    pub seed: Option<Box<Expression>>,
12788}
12789
12790/// Tags are used for generating arbitrary sql like SELECT <span>x</span>.
12791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12792#[cfg_attr(feature = "bindings", derive(TS))]
12793pub struct Tag {
12794    #[serde(default)]
12795    pub this: Option<Box<Expression>>,
12796    #[serde(default)]
12797    pub prefix: Option<Box<Expression>>,
12798    #[serde(default)]
12799    pub postfix: Option<Box<Expression>>,
12800}
12801
12802/// UnpivotColumns
12803#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12804#[cfg_attr(feature = "bindings", derive(TS))]
12805pub struct UnpivotColumns {
12806    pub this: Box<Expression>,
12807    #[serde(default)]
12808    pub expressions: Vec<Expression>,
12809}
12810
12811/// SessionParameter
12812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12813#[cfg_attr(feature = "bindings", derive(TS))]
12814pub struct SessionParameter {
12815    pub this: Box<Expression>,
12816    #[serde(default)]
12817    pub kind: Option<String>,
12818}
12819
12820/// PseudoType
12821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12822#[cfg_attr(feature = "bindings", derive(TS))]
12823pub struct PseudoType {
12824    pub this: Box<Expression>,
12825}
12826
12827/// ObjectIdentifier
12828#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12829#[cfg_attr(feature = "bindings", derive(TS))]
12830pub struct ObjectIdentifier {
12831    pub this: Box<Expression>,
12832}
12833
12834/// Transaction
12835#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12836#[cfg_attr(feature = "bindings", derive(TS))]
12837pub struct Transaction {
12838    #[serde(default)]
12839    pub this: Option<Box<Expression>>,
12840    #[serde(default)]
12841    pub modes: Option<Box<Expression>>,
12842    #[serde(default)]
12843    pub mark: Option<Box<Expression>>,
12844}
12845
12846/// Commit
12847#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12848#[cfg_attr(feature = "bindings", derive(TS))]
12849pub struct Commit {
12850    #[serde(default)]
12851    pub chain: Option<Box<Expression>>,
12852    #[serde(default)]
12853    pub this: Option<Box<Expression>>,
12854    #[serde(default)]
12855    pub durability: Option<Box<Expression>>,
12856}
12857
12858/// Rollback
12859#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12860#[cfg_attr(feature = "bindings", derive(TS))]
12861pub struct Rollback {
12862    #[serde(default)]
12863    pub savepoint: Option<Box<Expression>>,
12864    #[serde(default)]
12865    pub this: Option<Box<Expression>>,
12866}
12867
12868/// AlterSession
12869#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12870#[cfg_attr(feature = "bindings", derive(TS))]
12871pub struct AlterSession {
12872    #[serde(default)]
12873    pub expressions: Vec<Expression>,
12874    #[serde(default)]
12875    pub unset: Option<Box<Expression>>,
12876}
12877
12878/// Analyze
12879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12880#[cfg_attr(feature = "bindings", derive(TS))]
12881pub struct Analyze {
12882    #[serde(default)]
12883    pub kind: Option<String>,
12884    #[serde(default)]
12885    pub this: Option<Box<Expression>>,
12886    #[serde(default)]
12887    pub options: Vec<Expression>,
12888    #[serde(default)]
12889    pub mode: Option<Box<Expression>>,
12890    #[serde(default)]
12891    pub partition: Option<Box<Expression>>,
12892    #[serde(default)]
12893    pub expression: Option<Box<Expression>>,
12894    #[serde(default)]
12895    pub properties: Vec<Expression>,
12896    /// Column list for ANALYZE tbl(col1, col2) syntax (PostgreSQL)
12897    #[serde(default, skip_serializing_if = "Vec::is_empty")]
12898    pub columns: Vec<String>,
12899}
12900
12901/// AnalyzeStatistics
12902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12903#[cfg_attr(feature = "bindings", derive(TS))]
12904pub struct AnalyzeStatistics {
12905    pub kind: String,
12906    #[serde(default)]
12907    pub option: Option<Box<Expression>>,
12908    #[serde(default)]
12909    pub this: Option<Box<Expression>>,
12910    #[serde(default)]
12911    pub expressions: Vec<Expression>,
12912}
12913
12914/// AnalyzeHistogram
12915#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12916#[cfg_attr(feature = "bindings", derive(TS))]
12917pub struct AnalyzeHistogram {
12918    pub this: Box<Expression>,
12919    #[serde(default)]
12920    pub expressions: Vec<Expression>,
12921    #[serde(default)]
12922    pub expression: Option<Box<Expression>>,
12923    #[serde(default)]
12924    pub update_options: Option<Box<Expression>>,
12925}
12926
12927/// AnalyzeSample
12928#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12929#[cfg_attr(feature = "bindings", derive(TS))]
12930pub struct AnalyzeSample {
12931    pub kind: String,
12932    #[serde(default)]
12933    pub sample: Option<Box<Expression>>,
12934}
12935
12936/// AnalyzeListChainedRows
12937#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12938#[cfg_attr(feature = "bindings", derive(TS))]
12939pub struct AnalyzeListChainedRows {
12940    #[serde(default)]
12941    pub expression: Option<Box<Expression>>,
12942}
12943
12944/// AnalyzeDelete
12945#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12946#[cfg_attr(feature = "bindings", derive(TS))]
12947pub struct AnalyzeDelete {
12948    #[serde(default)]
12949    pub kind: Option<String>,
12950}
12951
12952/// AnalyzeWith
12953#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12954#[cfg_attr(feature = "bindings", derive(TS))]
12955pub struct AnalyzeWith {
12956    #[serde(default)]
12957    pub expressions: Vec<Expression>,
12958}
12959
12960/// AnalyzeValidate
12961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12962#[cfg_attr(feature = "bindings", derive(TS))]
12963pub struct AnalyzeValidate {
12964    pub kind: String,
12965    #[serde(default)]
12966    pub this: Option<Box<Expression>>,
12967    #[serde(default)]
12968    pub expression: Option<Box<Expression>>,
12969}
12970
12971/// AddPartition
12972#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12973#[cfg_attr(feature = "bindings", derive(TS))]
12974pub struct AddPartition {
12975    pub this: Box<Expression>,
12976    #[serde(default)]
12977    pub exists: bool,
12978    #[serde(default)]
12979    pub location: Option<Box<Expression>>,
12980}
12981
12982/// AttachOption
12983#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12984#[cfg_attr(feature = "bindings", derive(TS))]
12985pub struct AttachOption {
12986    pub this: Box<Expression>,
12987    #[serde(default)]
12988    pub expression: Option<Box<Expression>>,
12989}
12990
12991/// DropPartition
12992#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
12993#[cfg_attr(feature = "bindings", derive(TS))]
12994pub struct DropPartition {
12995    #[serde(default)]
12996    pub expressions: Vec<Expression>,
12997    #[serde(default)]
12998    pub exists: bool,
12999}
13000
13001/// ReplacePartition
13002#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13003#[cfg_attr(feature = "bindings", derive(TS))]
13004pub struct ReplacePartition {
13005    pub expression: Box<Expression>,
13006    #[serde(default)]
13007    pub source: Option<Box<Expression>>,
13008}
13009
13010/// DPipe
13011#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13012#[cfg_attr(feature = "bindings", derive(TS))]
13013pub struct DPipe {
13014    pub this: Box<Expression>,
13015    pub expression: Box<Expression>,
13016    #[serde(default)]
13017    pub safe: Option<Box<Expression>>,
13018}
13019
13020/// Operator
13021#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13022#[cfg_attr(feature = "bindings", derive(TS))]
13023pub struct Operator {
13024    pub this: Box<Expression>,
13025    #[serde(default)]
13026    pub operator: Option<Box<Expression>>,
13027    pub expression: Box<Expression>,
13028    /// Comments between OPERATOR() and the RHS expression
13029    #[serde(default, skip_serializing_if = "Vec::is_empty")]
13030    pub comments: Vec<String>,
13031}
13032
13033/// PivotAny
13034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13035#[cfg_attr(feature = "bindings", derive(TS))]
13036pub struct PivotAny {
13037    #[serde(default)]
13038    pub this: Option<Box<Expression>>,
13039}
13040
13041/// Aliases
13042#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13043#[cfg_attr(feature = "bindings", derive(TS))]
13044pub struct Aliases {
13045    pub this: Box<Expression>,
13046    #[serde(default)]
13047    pub expressions: Vec<Expression>,
13048}
13049
13050/// AtIndex
13051#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13052#[cfg_attr(feature = "bindings", derive(TS))]
13053pub struct AtIndex {
13054    pub this: Box<Expression>,
13055    pub expression: Box<Expression>,
13056}
13057
13058/// FromTimeZone
13059#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13060#[cfg_attr(feature = "bindings", derive(TS))]
13061pub struct FromTimeZone {
13062    pub this: Box<Expression>,
13063    #[serde(default)]
13064    pub zone: Option<Box<Expression>>,
13065}
13066
13067/// Format override for a column in Teradata
13068#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13069#[cfg_attr(feature = "bindings", derive(TS))]
13070pub struct FormatPhrase {
13071    pub this: Box<Expression>,
13072    pub format: String,
13073}
13074
13075/// ForIn
13076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13077#[cfg_attr(feature = "bindings", derive(TS))]
13078pub struct ForIn {
13079    pub this: Box<Expression>,
13080    pub expression: Box<Expression>,
13081}
13082
13083/// Automatically converts unit arg into a var.
13084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13085#[cfg_attr(feature = "bindings", derive(TS))]
13086pub struct TimeUnit {
13087    #[serde(default)]
13088    pub unit: Option<String>,
13089}
13090
13091/// IntervalOp
13092#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13093#[cfg_attr(feature = "bindings", derive(TS))]
13094pub struct IntervalOp {
13095    #[serde(default)]
13096    pub unit: Option<String>,
13097    pub expression: Box<Expression>,
13098}
13099
13100/// HavingMax
13101#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13102#[cfg_attr(feature = "bindings", derive(TS))]
13103pub struct HavingMax {
13104    pub this: Box<Expression>,
13105    pub expression: Box<Expression>,
13106    #[serde(default)]
13107    pub max: Option<Box<Expression>>,
13108}
13109
13110/// CosineDistance
13111#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13112#[cfg_attr(feature = "bindings", derive(TS))]
13113pub struct CosineDistance {
13114    pub this: Box<Expression>,
13115    pub expression: Box<Expression>,
13116}
13117
13118/// DotProduct
13119#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13120#[cfg_attr(feature = "bindings", derive(TS))]
13121pub struct DotProduct {
13122    pub this: Box<Expression>,
13123    pub expression: Box<Expression>,
13124}
13125
13126/// EuclideanDistance
13127#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13128#[cfg_attr(feature = "bindings", derive(TS))]
13129pub struct EuclideanDistance {
13130    pub this: Box<Expression>,
13131    pub expression: Box<Expression>,
13132}
13133
13134/// ManhattanDistance
13135#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13136#[cfg_attr(feature = "bindings", derive(TS))]
13137pub struct ManhattanDistance {
13138    pub this: Box<Expression>,
13139    pub expression: Box<Expression>,
13140}
13141
13142/// JarowinklerSimilarity
13143#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13144#[cfg_attr(feature = "bindings", derive(TS))]
13145pub struct JarowinklerSimilarity {
13146    pub this: Box<Expression>,
13147    pub expression: Box<Expression>,
13148}
13149
13150/// Booland
13151#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13152#[cfg_attr(feature = "bindings", derive(TS))]
13153pub struct Booland {
13154    pub this: Box<Expression>,
13155    pub expression: Box<Expression>,
13156}
13157
13158/// Boolor
13159#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13160#[cfg_attr(feature = "bindings", derive(TS))]
13161pub struct Boolor {
13162    pub this: Box<Expression>,
13163    pub expression: Box<Expression>,
13164}
13165
13166/// ParameterizedAgg
13167#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13168#[cfg_attr(feature = "bindings", derive(TS))]
13169pub struct ParameterizedAgg {
13170    pub this: Box<Expression>,
13171    #[serde(default)]
13172    pub expressions: Vec<Expression>,
13173    #[serde(default)]
13174    pub params: Vec<Expression>,
13175}
13176
13177/// ArgMax
13178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13179#[cfg_attr(feature = "bindings", derive(TS))]
13180pub struct ArgMax {
13181    pub this: Box<Expression>,
13182    pub expression: Box<Expression>,
13183    #[serde(default)]
13184    pub count: Option<Box<Expression>>,
13185}
13186
13187/// ArgMin
13188#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13189#[cfg_attr(feature = "bindings", derive(TS))]
13190pub struct ArgMin {
13191    pub this: Box<Expression>,
13192    pub expression: Box<Expression>,
13193    #[serde(default)]
13194    pub count: Option<Box<Expression>>,
13195}
13196
13197/// ApproxTopK
13198#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13199#[cfg_attr(feature = "bindings", derive(TS))]
13200pub struct ApproxTopK {
13201    pub this: Box<Expression>,
13202    #[serde(default)]
13203    pub expression: Option<Box<Expression>>,
13204    #[serde(default)]
13205    pub counters: Option<Box<Expression>>,
13206}
13207
13208/// ApproxTopKAccumulate
13209#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13210#[cfg_attr(feature = "bindings", derive(TS))]
13211pub struct ApproxTopKAccumulate {
13212    pub this: Box<Expression>,
13213    #[serde(default)]
13214    pub expression: Option<Box<Expression>>,
13215}
13216
13217/// ApproxTopKCombine
13218#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13219#[cfg_attr(feature = "bindings", derive(TS))]
13220pub struct ApproxTopKCombine {
13221    pub this: Box<Expression>,
13222    #[serde(default)]
13223    pub expression: Option<Box<Expression>>,
13224}
13225
13226/// ApproxTopKEstimate
13227#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13228#[cfg_attr(feature = "bindings", derive(TS))]
13229pub struct ApproxTopKEstimate {
13230    pub this: Box<Expression>,
13231    #[serde(default)]
13232    pub expression: Option<Box<Expression>>,
13233}
13234
13235/// ApproxTopSum
13236#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13237#[cfg_attr(feature = "bindings", derive(TS))]
13238pub struct ApproxTopSum {
13239    pub this: Box<Expression>,
13240    pub expression: Box<Expression>,
13241    #[serde(default)]
13242    pub count: Option<Box<Expression>>,
13243}
13244
13245/// ApproxQuantiles
13246#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13247#[cfg_attr(feature = "bindings", derive(TS))]
13248pub struct ApproxQuantiles {
13249    pub this: Box<Expression>,
13250    #[serde(default)]
13251    pub expression: Option<Box<Expression>>,
13252}
13253
13254/// Minhash
13255#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13256#[cfg_attr(feature = "bindings", derive(TS))]
13257pub struct Minhash {
13258    pub this: Box<Expression>,
13259    #[serde(default)]
13260    pub expressions: Vec<Expression>,
13261}
13262
13263/// FarmFingerprint
13264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13265#[cfg_attr(feature = "bindings", derive(TS))]
13266pub struct FarmFingerprint {
13267    #[serde(default)]
13268    pub expressions: Vec<Expression>,
13269}
13270
13271/// Float64
13272#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13273#[cfg_attr(feature = "bindings", derive(TS))]
13274pub struct Float64 {
13275    pub this: Box<Expression>,
13276    #[serde(default)]
13277    pub expression: Option<Box<Expression>>,
13278}
13279
13280/// Transform
13281#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13282#[cfg_attr(feature = "bindings", derive(TS))]
13283pub struct Transform {
13284    pub this: Box<Expression>,
13285    pub expression: Box<Expression>,
13286}
13287
13288/// Translate
13289#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13290#[cfg_attr(feature = "bindings", derive(TS))]
13291pub struct Translate {
13292    pub this: Box<Expression>,
13293    #[serde(default)]
13294    pub from_: Option<Box<Expression>>,
13295    #[serde(default)]
13296    pub to: Option<Box<Expression>>,
13297}
13298
13299/// Grouping
13300#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13301#[cfg_attr(feature = "bindings", derive(TS))]
13302pub struct Grouping {
13303    #[serde(default)]
13304    pub expressions: Vec<Expression>,
13305}
13306
13307/// GroupingId
13308#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13309#[cfg_attr(feature = "bindings", derive(TS))]
13310pub struct GroupingId {
13311    #[serde(default)]
13312    pub expressions: Vec<Expression>,
13313}
13314
13315/// Anonymous
13316#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13317#[cfg_attr(feature = "bindings", derive(TS))]
13318pub struct Anonymous {
13319    pub this: Box<Expression>,
13320    #[serde(default)]
13321    pub expressions: Vec<Expression>,
13322}
13323
13324/// AnonymousAggFunc
13325#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13326#[cfg_attr(feature = "bindings", derive(TS))]
13327pub struct AnonymousAggFunc {
13328    pub this: Box<Expression>,
13329    #[serde(default)]
13330    pub expressions: Vec<Expression>,
13331}
13332
13333/// CombinedAggFunc
13334#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13335#[cfg_attr(feature = "bindings", derive(TS))]
13336pub struct CombinedAggFunc {
13337    pub this: Box<Expression>,
13338    #[serde(default)]
13339    pub expressions: Vec<Expression>,
13340}
13341
13342/// CombinedParameterizedAgg
13343#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13344#[cfg_attr(feature = "bindings", derive(TS))]
13345pub struct CombinedParameterizedAgg {
13346    pub this: Box<Expression>,
13347    #[serde(default)]
13348    pub expressions: Vec<Expression>,
13349    #[serde(default)]
13350    pub params: Vec<Expression>,
13351}
13352
13353/// HashAgg
13354#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13355#[cfg_attr(feature = "bindings", derive(TS))]
13356pub struct HashAgg {
13357    pub this: Box<Expression>,
13358    #[serde(default)]
13359    pub expressions: Vec<Expression>,
13360}
13361
13362/// Hll
13363#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13364#[cfg_attr(feature = "bindings", derive(TS))]
13365pub struct Hll {
13366    pub this: Box<Expression>,
13367    #[serde(default)]
13368    pub expressions: Vec<Expression>,
13369}
13370
13371/// Apply
13372#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13373#[cfg_attr(feature = "bindings", derive(TS))]
13374pub struct Apply {
13375    pub this: Box<Expression>,
13376    pub expression: Box<Expression>,
13377}
13378
13379/// ToBoolean
13380#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13381#[cfg_attr(feature = "bindings", derive(TS))]
13382pub struct ToBoolean {
13383    pub this: Box<Expression>,
13384    #[serde(default)]
13385    pub safe: Option<Box<Expression>>,
13386}
13387
13388/// List
13389#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13390#[cfg_attr(feature = "bindings", derive(TS))]
13391pub struct List {
13392    #[serde(default)]
13393    pub expressions: Vec<Expression>,
13394}
13395
13396/// ToMap - Materialize-style map constructor
13397/// Can hold either:
13398/// - A SELECT subquery (MAP(SELECT 'a', 1))
13399/// - A struct with key=>value entries (MAP['a' => 1, 'b' => 2])
13400#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13401#[cfg_attr(feature = "bindings", derive(TS))]
13402pub struct ToMap {
13403    /// Either a Select subquery or a Struct containing PropertyEQ entries
13404    pub this: Box<Expression>,
13405}
13406
13407/// Pad
13408#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13409#[cfg_attr(feature = "bindings", derive(TS))]
13410pub struct Pad {
13411    pub this: Box<Expression>,
13412    pub expression: Box<Expression>,
13413    #[serde(default)]
13414    pub fill_pattern: Option<Box<Expression>>,
13415    #[serde(default)]
13416    pub is_left: Option<Box<Expression>>,
13417}
13418
13419/// ToChar
13420#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13421#[cfg_attr(feature = "bindings", derive(TS))]
13422pub struct ToChar {
13423    pub this: Box<Expression>,
13424    #[serde(default)]
13425    pub format: Option<String>,
13426    #[serde(default)]
13427    pub nlsparam: Option<Box<Expression>>,
13428    #[serde(default)]
13429    pub is_numeric: Option<Box<Expression>>,
13430}
13431
13432/// StringFunc - String type conversion function (BigQuery STRING)
13433#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13434#[cfg_attr(feature = "bindings", derive(TS))]
13435pub struct StringFunc {
13436    pub this: Box<Expression>,
13437    #[serde(default)]
13438    pub zone: Option<Box<Expression>>,
13439}
13440
13441/// ToNumber
13442#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13443#[cfg_attr(feature = "bindings", derive(TS))]
13444pub struct ToNumber {
13445    pub this: Box<Expression>,
13446    #[serde(default)]
13447    pub format: Option<Box<Expression>>,
13448    #[serde(default)]
13449    pub nlsparam: Option<Box<Expression>>,
13450    #[serde(default)]
13451    pub precision: Option<Box<Expression>>,
13452    #[serde(default)]
13453    pub scale: Option<Box<Expression>>,
13454    #[serde(default)]
13455    pub safe: Option<Box<Expression>>,
13456    #[serde(default)]
13457    pub safe_name: Option<Box<Expression>>,
13458}
13459
13460/// ToDouble
13461#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13462#[cfg_attr(feature = "bindings", derive(TS))]
13463pub struct ToDouble {
13464    pub this: Box<Expression>,
13465    #[serde(default)]
13466    pub format: Option<String>,
13467    #[serde(default)]
13468    pub safe: Option<Box<Expression>>,
13469}
13470
13471/// ToDecfloat
13472#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13473#[cfg_attr(feature = "bindings", derive(TS))]
13474pub struct ToDecfloat {
13475    pub this: Box<Expression>,
13476    #[serde(default)]
13477    pub format: Option<String>,
13478}
13479
13480/// TryToDecfloat
13481#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13482#[cfg_attr(feature = "bindings", derive(TS))]
13483pub struct TryToDecfloat {
13484    pub this: Box<Expression>,
13485    #[serde(default)]
13486    pub format: Option<String>,
13487}
13488
13489/// ToFile
13490#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13491#[cfg_attr(feature = "bindings", derive(TS))]
13492pub struct ToFile {
13493    pub this: Box<Expression>,
13494    #[serde(default)]
13495    pub path: Option<Box<Expression>>,
13496    #[serde(default)]
13497    pub safe: Option<Box<Expression>>,
13498}
13499
13500/// Columns
13501#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13502#[cfg_attr(feature = "bindings", derive(TS))]
13503pub struct Columns {
13504    pub this: Box<Expression>,
13505    #[serde(default)]
13506    pub unpack: Option<Box<Expression>>,
13507}
13508
13509/// ConvertToCharset
13510#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13511#[cfg_attr(feature = "bindings", derive(TS))]
13512pub struct ConvertToCharset {
13513    pub this: Box<Expression>,
13514    #[serde(default)]
13515    pub dest: Option<Box<Expression>>,
13516    #[serde(default)]
13517    pub source: Option<Box<Expression>>,
13518}
13519
13520/// ConvertTimezone
13521#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13522#[cfg_attr(feature = "bindings", derive(TS))]
13523pub struct ConvertTimezone {
13524    #[serde(default)]
13525    pub source_tz: Option<Box<Expression>>,
13526    #[serde(default)]
13527    pub target_tz: Option<Box<Expression>>,
13528    #[serde(default)]
13529    pub timestamp: Option<Box<Expression>>,
13530    #[serde(default)]
13531    pub options: Vec<Expression>,
13532}
13533
13534/// GenerateSeries
13535#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13536#[cfg_attr(feature = "bindings", derive(TS))]
13537pub struct GenerateSeries {
13538    #[serde(default)]
13539    pub start: Option<Box<Expression>>,
13540    #[serde(default)]
13541    pub end: Option<Box<Expression>>,
13542    #[serde(default)]
13543    pub step: Option<Box<Expression>>,
13544    #[serde(default)]
13545    pub is_end_exclusive: Option<Box<Expression>>,
13546}
13547
13548/// AIAgg
13549#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13550#[cfg_attr(feature = "bindings", derive(TS))]
13551pub struct AIAgg {
13552    pub this: Box<Expression>,
13553    pub expression: Box<Expression>,
13554}
13555
13556/// AIClassify
13557#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13558#[cfg_attr(feature = "bindings", derive(TS))]
13559pub struct AIClassify {
13560    pub this: Box<Expression>,
13561    #[serde(default)]
13562    pub categories: Option<Box<Expression>>,
13563    #[serde(default)]
13564    pub config: Option<Box<Expression>>,
13565}
13566
13567/// ArrayAll
13568#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13569#[cfg_attr(feature = "bindings", derive(TS))]
13570pub struct ArrayAll {
13571    pub this: Box<Expression>,
13572    pub expression: Box<Expression>,
13573}
13574
13575/// ArrayAny
13576#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13577#[cfg_attr(feature = "bindings", derive(TS))]
13578pub struct ArrayAny {
13579    pub this: Box<Expression>,
13580    pub expression: Box<Expression>,
13581}
13582
13583/// ArrayConstructCompact
13584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13585#[cfg_attr(feature = "bindings", derive(TS))]
13586pub struct ArrayConstructCompact {
13587    #[serde(default)]
13588    pub expressions: Vec<Expression>,
13589}
13590
13591/// StPoint
13592#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13593#[cfg_attr(feature = "bindings", derive(TS))]
13594pub struct StPoint {
13595    pub this: Box<Expression>,
13596    pub expression: Box<Expression>,
13597    #[serde(default)]
13598    pub null: Option<Box<Expression>>,
13599}
13600
13601/// StDistance
13602#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13603#[cfg_attr(feature = "bindings", derive(TS))]
13604pub struct StDistance {
13605    pub this: Box<Expression>,
13606    pub expression: Box<Expression>,
13607    #[serde(default)]
13608    pub use_spheroid: Option<Box<Expression>>,
13609}
13610
13611/// StringToArray
13612#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13613#[cfg_attr(feature = "bindings", derive(TS))]
13614pub struct StringToArray {
13615    pub this: Box<Expression>,
13616    #[serde(default)]
13617    pub expression: Option<Box<Expression>>,
13618    #[serde(default)]
13619    pub null: Option<Box<Expression>>,
13620}
13621
13622/// ArraySum
13623#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13624#[cfg_attr(feature = "bindings", derive(TS))]
13625pub struct ArraySum {
13626    pub this: Box<Expression>,
13627    #[serde(default)]
13628    pub expression: Option<Box<Expression>>,
13629}
13630
13631/// ObjectAgg
13632#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13633#[cfg_attr(feature = "bindings", derive(TS))]
13634pub struct ObjectAgg {
13635    pub this: Box<Expression>,
13636    pub expression: Box<Expression>,
13637}
13638
13639/// CastToStrType
13640#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13641#[cfg_attr(feature = "bindings", derive(TS))]
13642pub struct CastToStrType {
13643    pub this: Box<Expression>,
13644    #[serde(default)]
13645    pub to: Option<Box<Expression>>,
13646}
13647
13648/// CheckJson
13649#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13650#[cfg_attr(feature = "bindings", derive(TS))]
13651pub struct CheckJson {
13652    pub this: Box<Expression>,
13653}
13654
13655/// CheckXml
13656#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13657#[cfg_attr(feature = "bindings", derive(TS))]
13658pub struct CheckXml {
13659    pub this: Box<Expression>,
13660    #[serde(default)]
13661    pub disable_auto_convert: Option<Box<Expression>>,
13662}
13663
13664/// TranslateCharacters
13665#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13666#[cfg_attr(feature = "bindings", derive(TS))]
13667pub struct TranslateCharacters {
13668    pub this: Box<Expression>,
13669    pub expression: Box<Expression>,
13670    #[serde(default)]
13671    pub with_error: Option<Box<Expression>>,
13672}
13673
13674/// CurrentSchemas
13675#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13676#[cfg_attr(feature = "bindings", derive(TS))]
13677pub struct CurrentSchemas {
13678    #[serde(default)]
13679    pub this: Option<Box<Expression>>,
13680}
13681
13682/// CurrentDatetime
13683#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13684#[cfg_attr(feature = "bindings", derive(TS))]
13685pub struct CurrentDatetime {
13686    #[serde(default)]
13687    pub this: Option<Box<Expression>>,
13688}
13689
13690/// Localtime
13691#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13692#[cfg_attr(feature = "bindings", derive(TS))]
13693pub struct Localtime {
13694    #[serde(default)]
13695    pub this: Option<Box<Expression>>,
13696}
13697
13698/// Localtimestamp
13699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13700#[cfg_attr(feature = "bindings", derive(TS))]
13701pub struct Localtimestamp {
13702    #[serde(default)]
13703    pub this: Option<Box<Expression>>,
13704}
13705
13706/// Systimestamp
13707#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13708#[cfg_attr(feature = "bindings", derive(TS))]
13709pub struct Systimestamp {
13710    #[serde(default)]
13711    pub this: Option<Box<Expression>>,
13712}
13713
13714/// CurrentSchema
13715#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13716#[cfg_attr(feature = "bindings", derive(TS))]
13717pub struct CurrentSchema {
13718    #[serde(default)]
13719    pub this: Option<Box<Expression>>,
13720}
13721
13722/// CurrentUser
13723#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13724#[cfg_attr(feature = "bindings", derive(TS))]
13725pub struct CurrentUser {
13726    #[serde(default)]
13727    pub this: Option<Box<Expression>>,
13728}
13729
13730/// SessionUser - MySQL/PostgreSQL SESSION_USER function
13731#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13732#[cfg_attr(feature = "bindings", derive(TS))]
13733pub struct SessionUser;
13734
13735/// JSONPathRoot - Represents $ in JSON path expressions
13736#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13737#[cfg_attr(feature = "bindings", derive(TS))]
13738pub struct JSONPathRoot;
13739
13740/// UtcTime
13741#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13742#[cfg_attr(feature = "bindings", derive(TS))]
13743pub struct UtcTime {
13744    #[serde(default)]
13745    pub this: Option<Box<Expression>>,
13746}
13747
13748/// UtcTimestamp
13749#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13750#[cfg_attr(feature = "bindings", derive(TS))]
13751pub struct UtcTimestamp {
13752    #[serde(default)]
13753    pub this: Option<Box<Expression>>,
13754}
13755
13756/// TimestampFunc - TIMESTAMP constructor function
13757#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13758#[cfg_attr(feature = "bindings", derive(TS))]
13759pub struct TimestampFunc {
13760    #[serde(default)]
13761    pub this: Option<Box<Expression>>,
13762    #[serde(default)]
13763    pub zone: Option<Box<Expression>>,
13764    #[serde(default)]
13765    pub with_tz: Option<bool>,
13766    #[serde(default)]
13767    pub safe: Option<bool>,
13768}
13769
13770/// DateBin
13771#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13772#[cfg_attr(feature = "bindings", derive(TS))]
13773pub struct DateBin {
13774    pub this: Box<Expression>,
13775    pub expression: Box<Expression>,
13776    #[serde(default)]
13777    pub unit: Option<String>,
13778    #[serde(default)]
13779    pub zone: Option<Box<Expression>>,
13780    #[serde(default)]
13781    pub origin: Option<Box<Expression>>,
13782}
13783
13784/// Datetime
13785#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13786#[cfg_attr(feature = "bindings", derive(TS))]
13787pub struct Datetime {
13788    pub this: Box<Expression>,
13789    #[serde(default)]
13790    pub expression: Option<Box<Expression>>,
13791}
13792
13793/// DatetimeAdd
13794#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13795#[cfg_attr(feature = "bindings", derive(TS))]
13796pub struct DatetimeAdd {
13797    pub this: Box<Expression>,
13798    pub expression: Box<Expression>,
13799    #[serde(default)]
13800    pub unit: Option<String>,
13801}
13802
13803/// DatetimeSub
13804#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13805#[cfg_attr(feature = "bindings", derive(TS))]
13806pub struct DatetimeSub {
13807    pub this: Box<Expression>,
13808    pub expression: Box<Expression>,
13809    #[serde(default)]
13810    pub unit: Option<String>,
13811}
13812
13813/// DatetimeDiff
13814#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13815#[cfg_attr(feature = "bindings", derive(TS))]
13816pub struct DatetimeDiff {
13817    pub this: Box<Expression>,
13818    pub expression: Box<Expression>,
13819    #[serde(default)]
13820    pub unit: Option<String>,
13821}
13822
13823/// DatetimeTrunc
13824#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13825#[cfg_attr(feature = "bindings", derive(TS))]
13826pub struct DatetimeTrunc {
13827    pub this: Box<Expression>,
13828    pub unit: String,
13829    #[serde(default)]
13830    pub zone: Option<Box<Expression>>,
13831}
13832
13833/// Dayname
13834#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13835#[cfg_attr(feature = "bindings", derive(TS))]
13836pub struct Dayname {
13837    pub this: Box<Expression>,
13838    #[serde(default)]
13839    pub abbreviated: Option<Box<Expression>>,
13840}
13841
13842/// MakeInterval
13843#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13844#[cfg_attr(feature = "bindings", derive(TS))]
13845pub struct MakeInterval {
13846    #[serde(default)]
13847    pub year: Option<Box<Expression>>,
13848    #[serde(default)]
13849    pub month: Option<Box<Expression>>,
13850    #[serde(default)]
13851    pub week: Option<Box<Expression>>,
13852    #[serde(default)]
13853    pub day: Option<Box<Expression>>,
13854    #[serde(default)]
13855    pub hour: Option<Box<Expression>>,
13856    #[serde(default)]
13857    pub minute: Option<Box<Expression>>,
13858    #[serde(default)]
13859    pub second: Option<Box<Expression>>,
13860}
13861
13862/// PreviousDay
13863#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13864#[cfg_attr(feature = "bindings", derive(TS))]
13865pub struct PreviousDay {
13866    pub this: Box<Expression>,
13867    pub expression: Box<Expression>,
13868}
13869
13870/// Elt
13871#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13872#[cfg_attr(feature = "bindings", derive(TS))]
13873pub struct Elt {
13874    pub this: Box<Expression>,
13875    #[serde(default)]
13876    pub expressions: Vec<Expression>,
13877}
13878
13879/// TimestampAdd
13880#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13881#[cfg_attr(feature = "bindings", derive(TS))]
13882pub struct TimestampAdd {
13883    pub this: Box<Expression>,
13884    pub expression: Box<Expression>,
13885    #[serde(default)]
13886    pub unit: Option<String>,
13887}
13888
13889/// TimestampSub
13890#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13891#[cfg_attr(feature = "bindings", derive(TS))]
13892pub struct TimestampSub {
13893    pub this: Box<Expression>,
13894    pub expression: Box<Expression>,
13895    #[serde(default)]
13896    pub unit: Option<String>,
13897}
13898
13899/// TimestampDiff
13900#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13901#[cfg_attr(feature = "bindings", derive(TS))]
13902pub struct TimestampDiff {
13903    pub this: Box<Expression>,
13904    pub expression: Box<Expression>,
13905    #[serde(default)]
13906    pub unit: Option<String>,
13907}
13908
13909/// TimeSlice
13910#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13911#[cfg_attr(feature = "bindings", derive(TS))]
13912pub struct TimeSlice {
13913    pub this: Box<Expression>,
13914    pub expression: Box<Expression>,
13915    pub unit: String,
13916    #[serde(default)]
13917    pub kind: Option<String>,
13918}
13919
13920/// TimeAdd
13921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13922#[cfg_attr(feature = "bindings", derive(TS))]
13923pub struct TimeAdd {
13924    pub this: Box<Expression>,
13925    pub expression: Box<Expression>,
13926    #[serde(default)]
13927    pub unit: Option<String>,
13928}
13929
13930/// TimeSub
13931#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13932#[cfg_attr(feature = "bindings", derive(TS))]
13933pub struct TimeSub {
13934    pub this: Box<Expression>,
13935    pub expression: Box<Expression>,
13936    #[serde(default)]
13937    pub unit: Option<String>,
13938}
13939
13940/// TimeDiff
13941#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13942#[cfg_attr(feature = "bindings", derive(TS))]
13943pub struct TimeDiff {
13944    pub this: Box<Expression>,
13945    pub expression: Box<Expression>,
13946    #[serde(default)]
13947    pub unit: Option<String>,
13948}
13949
13950/// TimeTrunc
13951#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13952#[cfg_attr(feature = "bindings", derive(TS))]
13953pub struct TimeTrunc {
13954    pub this: Box<Expression>,
13955    pub unit: String,
13956    #[serde(default)]
13957    pub zone: Option<Box<Expression>>,
13958}
13959
13960/// DateFromParts
13961#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13962#[cfg_attr(feature = "bindings", derive(TS))]
13963pub struct DateFromParts {
13964    #[serde(default)]
13965    pub year: Option<Box<Expression>>,
13966    #[serde(default)]
13967    pub month: Option<Box<Expression>>,
13968    #[serde(default)]
13969    pub day: Option<Box<Expression>>,
13970    #[serde(default)]
13971    pub allow_overflow: Option<Box<Expression>>,
13972}
13973
13974/// TimeFromParts
13975#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13976#[cfg_attr(feature = "bindings", derive(TS))]
13977pub struct TimeFromParts {
13978    #[serde(default)]
13979    pub hour: Option<Box<Expression>>,
13980    #[serde(default)]
13981    pub min: Option<Box<Expression>>,
13982    #[serde(default)]
13983    pub sec: Option<Box<Expression>>,
13984    #[serde(default)]
13985    pub nano: Option<Box<Expression>>,
13986    #[serde(default)]
13987    pub fractions: Option<Box<Expression>>,
13988    #[serde(default)]
13989    pub precision: Option<i64>,
13990}
13991
13992/// DecodeCase
13993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
13994#[cfg_attr(feature = "bindings", derive(TS))]
13995pub struct DecodeCase {
13996    #[serde(default)]
13997    pub expressions: Vec<Expression>,
13998}
13999
14000/// Decrypt
14001#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14002#[cfg_attr(feature = "bindings", derive(TS))]
14003pub struct Decrypt {
14004    pub this: Box<Expression>,
14005    #[serde(default)]
14006    pub passphrase: Option<Box<Expression>>,
14007    #[serde(default)]
14008    pub aad: Option<Box<Expression>>,
14009    #[serde(default)]
14010    pub encryption_method: Option<Box<Expression>>,
14011    #[serde(default)]
14012    pub safe: Option<Box<Expression>>,
14013}
14014
14015/// DecryptRaw
14016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14017#[cfg_attr(feature = "bindings", derive(TS))]
14018pub struct DecryptRaw {
14019    pub this: Box<Expression>,
14020    #[serde(default)]
14021    pub key: Option<Box<Expression>>,
14022    #[serde(default)]
14023    pub iv: Option<Box<Expression>>,
14024    #[serde(default)]
14025    pub aad: Option<Box<Expression>>,
14026    #[serde(default)]
14027    pub encryption_method: Option<Box<Expression>>,
14028    #[serde(default)]
14029    pub aead: Option<Box<Expression>>,
14030    #[serde(default)]
14031    pub safe: Option<Box<Expression>>,
14032}
14033
14034/// Encode
14035#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14036#[cfg_attr(feature = "bindings", derive(TS))]
14037pub struct Encode {
14038    pub this: Box<Expression>,
14039    #[serde(default)]
14040    pub charset: Option<Box<Expression>>,
14041}
14042
14043/// Encrypt
14044#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14045#[cfg_attr(feature = "bindings", derive(TS))]
14046pub struct Encrypt {
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}
14055
14056/// EncryptRaw
14057#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14058#[cfg_attr(feature = "bindings", derive(TS))]
14059pub struct EncryptRaw {
14060    pub this: Box<Expression>,
14061    #[serde(default)]
14062    pub key: Option<Box<Expression>>,
14063    #[serde(default)]
14064    pub iv: Option<Box<Expression>>,
14065    #[serde(default)]
14066    pub aad: Option<Box<Expression>>,
14067    #[serde(default)]
14068    pub encryption_method: Option<Box<Expression>>,
14069}
14070
14071/// EqualNull
14072#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14073#[cfg_attr(feature = "bindings", derive(TS))]
14074pub struct EqualNull {
14075    pub this: Box<Expression>,
14076    pub expression: Box<Expression>,
14077}
14078
14079/// ToBinary
14080#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14081#[cfg_attr(feature = "bindings", derive(TS))]
14082pub struct ToBinary {
14083    pub this: Box<Expression>,
14084    #[serde(default)]
14085    pub format: Option<String>,
14086    #[serde(default)]
14087    pub safe: Option<Box<Expression>>,
14088}
14089
14090/// Base64DecodeBinary
14091#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14092#[cfg_attr(feature = "bindings", derive(TS))]
14093pub struct Base64DecodeBinary {
14094    pub this: Box<Expression>,
14095    #[serde(default)]
14096    pub alphabet: Option<Box<Expression>>,
14097}
14098
14099/// Base64DecodeString
14100#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14101#[cfg_attr(feature = "bindings", derive(TS))]
14102pub struct Base64DecodeString {
14103    pub this: Box<Expression>,
14104    #[serde(default)]
14105    pub alphabet: Option<Box<Expression>>,
14106}
14107
14108/// Base64Encode
14109#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14110#[cfg_attr(feature = "bindings", derive(TS))]
14111pub struct Base64Encode {
14112    pub this: Box<Expression>,
14113    #[serde(default)]
14114    pub max_line_length: Option<Box<Expression>>,
14115    #[serde(default)]
14116    pub alphabet: Option<Box<Expression>>,
14117}
14118
14119/// TryBase64DecodeBinary
14120#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14121#[cfg_attr(feature = "bindings", derive(TS))]
14122pub struct TryBase64DecodeBinary {
14123    pub this: Box<Expression>,
14124    #[serde(default)]
14125    pub alphabet: Option<Box<Expression>>,
14126}
14127
14128/// TryBase64DecodeString
14129#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14130#[cfg_attr(feature = "bindings", derive(TS))]
14131pub struct TryBase64DecodeString {
14132    pub this: Box<Expression>,
14133    #[serde(default)]
14134    pub alphabet: Option<Box<Expression>>,
14135}
14136
14137/// GapFill
14138#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14139#[cfg_attr(feature = "bindings", derive(TS))]
14140pub struct GapFill {
14141    pub this: Box<Expression>,
14142    #[serde(default)]
14143    pub ts_column: Option<Box<Expression>>,
14144    #[serde(default)]
14145    pub bucket_width: Option<Box<Expression>>,
14146    #[serde(default)]
14147    pub partitioning_columns: Option<Box<Expression>>,
14148    #[serde(default)]
14149    pub value_columns: Option<Box<Expression>>,
14150    #[serde(default)]
14151    pub origin: Option<Box<Expression>>,
14152    #[serde(default)]
14153    pub ignore_nulls: Option<Box<Expression>>,
14154}
14155
14156/// GenerateDateArray
14157#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14158#[cfg_attr(feature = "bindings", derive(TS))]
14159pub struct GenerateDateArray {
14160    #[serde(default)]
14161    pub start: Option<Box<Expression>>,
14162    #[serde(default)]
14163    pub end: Option<Box<Expression>>,
14164    #[serde(default)]
14165    pub step: Option<Box<Expression>>,
14166}
14167
14168/// GenerateTimestampArray
14169#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14170#[cfg_attr(feature = "bindings", derive(TS))]
14171pub struct GenerateTimestampArray {
14172    #[serde(default)]
14173    pub start: Option<Box<Expression>>,
14174    #[serde(default)]
14175    pub end: Option<Box<Expression>>,
14176    #[serde(default)]
14177    pub step: Option<Box<Expression>>,
14178}
14179
14180/// GetExtract
14181#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14182#[cfg_attr(feature = "bindings", derive(TS))]
14183pub struct GetExtract {
14184    pub this: Box<Expression>,
14185    pub expression: Box<Expression>,
14186}
14187
14188/// Getbit
14189#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14190#[cfg_attr(feature = "bindings", derive(TS))]
14191pub struct Getbit {
14192    pub this: Box<Expression>,
14193    pub expression: Box<Expression>,
14194    #[serde(default)]
14195    pub zero_is_msb: Option<Box<Expression>>,
14196}
14197
14198/// OverflowTruncateBehavior
14199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14200#[cfg_attr(feature = "bindings", derive(TS))]
14201pub struct OverflowTruncateBehavior {
14202    #[serde(default)]
14203    pub this: Option<Box<Expression>>,
14204    #[serde(default)]
14205    pub with_count: Option<Box<Expression>>,
14206}
14207
14208/// HexEncode
14209#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14210#[cfg_attr(feature = "bindings", derive(TS))]
14211pub struct HexEncode {
14212    pub this: Box<Expression>,
14213    #[serde(default)]
14214    pub case: Option<Box<Expression>>,
14215}
14216
14217/// Compress
14218#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14219#[cfg_attr(feature = "bindings", derive(TS))]
14220pub struct Compress {
14221    pub this: Box<Expression>,
14222    #[serde(default)]
14223    pub method: Option<String>,
14224}
14225
14226/// DecompressBinary
14227#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14228#[cfg_attr(feature = "bindings", derive(TS))]
14229pub struct DecompressBinary {
14230    pub this: Box<Expression>,
14231    pub method: String,
14232}
14233
14234/// DecompressString
14235#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14236#[cfg_attr(feature = "bindings", derive(TS))]
14237pub struct DecompressString {
14238    pub this: Box<Expression>,
14239    pub method: String,
14240}
14241
14242/// Xor
14243#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14244#[cfg_attr(feature = "bindings", derive(TS))]
14245pub struct Xor {
14246    #[serde(default)]
14247    pub this: Option<Box<Expression>>,
14248    #[serde(default)]
14249    pub expression: Option<Box<Expression>>,
14250    #[serde(default)]
14251    pub expressions: Vec<Expression>,
14252}
14253
14254/// Nullif
14255#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14256#[cfg_attr(feature = "bindings", derive(TS))]
14257pub struct Nullif {
14258    pub this: Box<Expression>,
14259    pub expression: Box<Expression>,
14260}
14261
14262/// JSON
14263#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14264#[cfg_attr(feature = "bindings", derive(TS))]
14265pub struct JSON {
14266    #[serde(default)]
14267    pub this: Option<Box<Expression>>,
14268    #[serde(default)]
14269    pub with_: Option<Box<Expression>>,
14270    #[serde(default)]
14271    pub unique: bool,
14272}
14273
14274/// JSONPath
14275#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14276#[cfg_attr(feature = "bindings", derive(TS))]
14277pub struct JSONPath {
14278    #[serde(default)]
14279    pub expressions: Vec<Expression>,
14280    #[serde(default)]
14281    pub escape: Option<Box<Expression>>,
14282}
14283
14284/// JSONPathFilter
14285#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14286#[cfg_attr(feature = "bindings", derive(TS))]
14287pub struct JSONPathFilter {
14288    pub this: Box<Expression>,
14289}
14290
14291/// JSONPathKey
14292#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14293#[cfg_attr(feature = "bindings", derive(TS))]
14294pub struct JSONPathKey {
14295    pub this: Box<Expression>,
14296}
14297
14298/// JSONPathRecursive
14299#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14300#[cfg_attr(feature = "bindings", derive(TS))]
14301pub struct JSONPathRecursive {
14302    #[serde(default)]
14303    pub this: Option<Box<Expression>>,
14304}
14305
14306/// JSONPathScript
14307#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14308#[cfg_attr(feature = "bindings", derive(TS))]
14309pub struct JSONPathScript {
14310    pub this: Box<Expression>,
14311}
14312
14313/// JSONPathSlice
14314#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14315#[cfg_attr(feature = "bindings", derive(TS))]
14316pub struct JSONPathSlice {
14317    #[serde(default)]
14318    pub start: Option<Box<Expression>>,
14319    #[serde(default)]
14320    pub end: Option<Box<Expression>>,
14321    #[serde(default)]
14322    pub step: Option<Box<Expression>>,
14323}
14324
14325/// JSONPathSelector
14326#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14327#[cfg_attr(feature = "bindings", derive(TS))]
14328pub struct JSONPathSelector {
14329    pub this: Box<Expression>,
14330}
14331
14332/// JSONPathSubscript
14333#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14334#[cfg_attr(feature = "bindings", derive(TS))]
14335pub struct JSONPathSubscript {
14336    pub this: Box<Expression>,
14337}
14338
14339/// JSONPathUnion
14340#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14341#[cfg_attr(feature = "bindings", derive(TS))]
14342pub struct JSONPathUnion {
14343    #[serde(default)]
14344    pub expressions: Vec<Expression>,
14345}
14346
14347/// Format
14348#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14349#[cfg_attr(feature = "bindings", derive(TS))]
14350pub struct Format {
14351    pub this: Box<Expression>,
14352    #[serde(default)]
14353    pub expressions: Vec<Expression>,
14354}
14355
14356/// JSONKeys
14357#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14358#[cfg_attr(feature = "bindings", derive(TS))]
14359pub struct JSONKeys {
14360    pub this: Box<Expression>,
14361    #[serde(default)]
14362    pub expression: Option<Box<Expression>>,
14363    #[serde(default)]
14364    pub expressions: Vec<Expression>,
14365}
14366
14367/// JSONKeyValue
14368#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14369#[cfg_attr(feature = "bindings", derive(TS))]
14370pub struct JSONKeyValue {
14371    pub this: Box<Expression>,
14372    pub expression: Box<Expression>,
14373}
14374
14375/// JSONKeysAtDepth
14376#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14377#[cfg_attr(feature = "bindings", derive(TS))]
14378pub struct JSONKeysAtDepth {
14379    pub this: Box<Expression>,
14380    #[serde(default)]
14381    pub expression: Option<Box<Expression>>,
14382    #[serde(default)]
14383    pub mode: Option<Box<Expression>>,
14384}
14385
14386/// JSONObject
14387#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14388#[cfg_attr(feature = "bindings", derive(TS))]
14389pub struct JSONObject {
14390    #[serde(default)]
14391    pub expressions: Vec<Expression>,
14392    #[serde(default)]
14393    pub null_handling: Option<Box<Expression>>,
14394    #[serde(default)]
14395    pub unique_keys: Option<Box<Expression>>,
14396    #[serde(default)]
14397    pub return_type: Option<Box<Expression>>,
14398    #[serde(default)]
14399    pub encoding: Option<Box<Expression>>,
14400}
14401
14402/// JSONObjectAgg
14403#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14404#[cfg_attr(feature = "bindings", derive(TS))]
14405pub struct JSONObjectAgg {
14406    #[serde(default)]
14407    pub expressions: Vec<Expression>,
14408    #[serde(default)]
14409    pub null_handling: Option<Box<Expression>>,
14410    #[serde(default)]
14411    pub unique_keys: Option<Box<Expression>>,
14412    #[serde(default)]
14413    pub return_type: Option<Box<Expression>>,
14414    #[serde(default)]
14415    pub encoding: Option<Box<Expression>>,
14416}
14417
14418/// JSONBObjectAgg
14419#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14420#[cfg_attr(feature = "bindings", derive(TS))]
14421pub struct JSONBObjectAgg {
14422    pub this: Box<Expression>,
14423    pub expression: Box<Expression>,
14424}
14425
14426/// JSONArray
14427#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14428#[cfg_attr(feature = "bindings", derive(TS))]
14429pub struct JSONArray {
14430    #[serde(default)]
14431    pub expressions: Vec<Expression>,
14432    #[serde(default)]
14433    pub null_handling: Option<Box<Expression>>,
14434    #[serde(default)]
14435    pub return_type: Option<Box<Expression>>,
14436    #[serde(default)]
14437    pub strict: Option<Box<Expression>>,
14438}
14439
14440/// JSONArrayAgg
14441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14442#[cfg_attr(feature = "bindings", derive(TS))]
14443pub struct JSONArrayAgg {
14444    pub this: Box<Expression>,
14445    #[serde(default)]
14446    pub order: Option<Box<Expression>>,
14447    #[serde(default)]
14448    pub null_handling: Option<Box<Expression>>,
14449    #[serde(default)]
14450    pub return_type: Option<Box<Expression>>,
14451    #[serde(default)]
14452    pub strict: Option<Box<Expression>>,
14453}
14454
14455/// JSONExists
14456#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14457#[cfg_attr(feature = "bindings", derive(TS))]
14458pub struct JSONExists {
14459    pub this: Box<Expression>,
14460    #[serde(default)]
14461    pub path: Option<Box<Expression>>,
14462    #[serde(default)]
14463    pub passing: Option<Box<Expression>>,
14464    #[serde(default)]
14465    pub on_condition: Option<Box<Expression>>,
14466    #[serde(default)]
14467    pub from_dcolonqmark: Option<Box<Expression>>,
14468}
14469
14470/// JSONColumnDef
14471#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14472#[cfg_attr(feature = "bindings", derive(TS))]
14473pub struct JSONColumnDef {
14474    /// Typed column definition; legacy dialects may use the textual kind field.
14475    #[serde(default, skip_serializing_if = "Option::is_none")]
14476    pub data_type: Option<DataType>,
14477    #[serde(default, skip_serializing_if = "Option::is_none")]
14478    pub encoding: Option<String>,
14479    #[serde(default, skip_serializing_if = "Option::is_none")]
14480    #[ast(skip)]
14481    pub source_dialect: Option<crate::dialects::DialectType>,
14482    /// Structured SQL/JSON wrapper and error/empty behavior.
14483    #[serde(default, skip_serializing_if = "Option::is_none")]
14484    pub options: Option<JsonOptions>,
14485
14486    #[serde(default)]
14487    pub this: Option<Box<Expression>>,
14488    #[serde(default)]
14489    pub kind: Option<String>,
14490    #[serde(default)]
14491    pub format_json: bool,
14492    #[serde(default)]
14493    pub path: Option<Box<Expression>>,
14494    #[serde(default)]
14495    pub nested_schema: Option<Box<Expression>>,
14496    #[serde(default)]
14497    pub ordinality: Option<Box<Expression>>,
14498}
14499
14500/// JSONSchema
14501#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14502#[cfg_attr(feature = "bindings", derive(TS))]
14503pub struct JSONSchema {
14504    #[serde(default)]
14505    pub expressions: Vec<Expression>,
14506}
14507
14508/// JSONSet
14509#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14510#[cfg_attr(feature = "bindings", derive(TS))]
14511pub struct JSONSet {
14512    pub this: Box<Expression>,
14513    #[serde(default)]
14514    pub expressions: Vec<Expression>,
14515}
14516
14517/// JSONStripNulls
14518#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14519#[cfg_attr(feature = "bindings", derive(TS))]
14520pub struct JSONStripNulls {
14521    pub this: Box<Expression>,
14522    #[serde(default)]
14523    pub expression: Option<Box<Expression>>,
14524    #[serde(default)]
14525    pub include_arrays: Option<Box<Expression>>,
14526    #[serde(default)]
14527    pub remove_empty: Option<Box<Expression>>,
14528}
14529
14530/// JSONValue
14531#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14532#[cfg_attr(feature = "bindings", derive(TS))]
14533pub struct JSONValue {
14534    #[serde(default, skip_serializing_if = "Option::is_none")]
14535    #[ast(skip)]
14536    pub source_dialect: Option<crate::dialects::DialectType>,
14537    /// Structured SQL/JSON wrapper and error/empty behavior.
14538    #[serde(default, skip_serializing_if = "Option::is_none")]
14539    pub options: Option<JsonOptions>,
14540
14541    pub this: Box<Expression>,
14542    #[serde(default)]
14543    pub path: Option<Box<Expression>>,
14544    #[serde(default)]
14545    pub returning: Option<Box<Expression>>,
14546    #[serde(default)]
14547    pub on_condition: Option<Box<Expression>>,
14548}
14549
14550/// JSONValueArray
14551#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14552#[cfg_attr(feature = "bindings", derive(TS))]
14553pub struct JSONValueArray {
14554    pub this: Box<Expression>,
14555    #[serde(default)]
14556    pub expression: Option<Box<Expression>>,
14557}
14558
14559/// JSONRemove
14560#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14561#[cfg_attr(feature = "bindings", derive(TS))]
14562pub struct JSONRemove {
14563    pub this: Box<Expression>,
14564    #[serde(default)]
14565    pub expressions: Vec<Expression>,
14566}
14567
14568/// JSONTable
14569#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14570#[cfg_attr(feature = "bindings", derive(TS))]
14571pub struct JSONTable {
14572    #[serde(default, skip_serializing_if = "Option::is_none")]
14573    #[ast(skip)]
14574    pub source_dialect: Option<crate::dialects::DialectType>,
14575    /// Structured SQL/JSON wrapper and error/empty behavior.
14576    #[serde(default, skip_serializing_if = "Option::is_none")]
14577    pub options: Option<JsonOptions>,
14578
14579    pub this: Box<Expression>,
14580    #[serde(default)]
14581    pub schema: Option<Box<Expression>>,
14582    #[serde(default)]
14583    pub path: Option<Box<Expression>>,
14584    #[serde(default)]
14585    pub error_handling: Option<Box<Expression>>,
14586    #[serde(default)]
14587    pub empty_handling: Option<Box<Expression>>,
14588}
14589
14590/// JSONType
14591#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14592#[cfg_attr(feature = "bindings", derive(TS))]
14593pub struct JSONType {
14594    pub this: Box<Expression>,
14595    #[serde(default)]
14596    pub expression: Option<Box<Expression>>,
14597}
14598
14599/// ObjectInsert
14600#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14601#[cfg_attr(feature = "bindings", derive(TS))]
14602pub struct ObjectInsert {
14603    pub this: Box<Expression>,
14604    #[serde(default)]
14605    pub key: Option<Box<Expression>>,
14606    #[serde(default)]
14607    pub value: Option<Box<Expression>>,
14608    #[serde(default)]
14609    pub update_flag: Option<Box<Expression>>,
14610}
14611
14612/// OpenJSONColumnDef
14613#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14614#[cfg_attr(feature = "bindings", derive(TS))]
14615pub struct OpenJSONColumnDef {
14616    pub this: Box<Expression>,
14617    pub kind: String,
14618    #[serde(default)]
14619    pub path: Option<Box<Expression>>,
14620    #[serde(default)]
14621    pub as_json: Option<Box<Expression>>,
14622    /// The parsed data type for proper generation
14623    #[serde(default, skip_serializing_if = "Option::is_none")]
14624    pub data_type: Option<DataType>,
14625}
14626
14627/// OpenJSON
14628#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14629#[cfg_attr(feature = "bindings", derive(TS))]
14630pub struct OpenJSON {
14631    pub this: Box<Expression>,
14632    #[serde(default)]
14633    pub path: Option<Box<Expression>>,
14634    #[serde(default)]
14635    pub expressions: Vec<Expression>,
14636}
14637
14638/// JSONBExists
14639#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14640#[cfg_attr(feature = "bindings", derive(TS))]
14641pub struct JSONBExists {
14642    pub this: Box<Expression>,
14643    #[serde(default)]
14644    pub path: Option<Box<Expression>>,
14645}
14646
14647/// JSONCast
14648#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14649#[cfg_attr(feature = "bindings", derive(TS))]
14650pub struct JSONCast {
14651    pub this: Box<Expression>,
14652    pub to: DataType,
14653}
14654
14655/// JSONExtract
14656#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14657#[cfg_attr(feature = "bindings", derive(TS))]
14658pub struct JSONExtract {
14659    pub this: Box<Expression>,
14660    pub expression: Box<Expression>,
14661    #[serde(default)]
14662    pub only_json_types: Option<Box<Expression>>,
14663    #[serde(default)]
14664    pub expressions: Vec<Expression>,
14665    #[serde(default)]
14666    pub variant_extract: Option<Box<Expression>>,
14667    #[serde(default)]
14668    pub json_query: Option<Box<Expression>>,
14669    #[serde(default)]
14670    pub option: Option<Box<Expression>>,
14671    #[serde(default)]
14672    pub quote: Option<Box<Expression>>,
14673    #[serde(default)]
14674    pub on_condition: Option<Box<Expression>>,
14675    #[serde(default)]
14676    pub requires_json: Option<Box<Expression>>,
14677}
14678
14679/// JSONExtractQuote
14680#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14681#[cfg_attr(feature = "bindings", derive(TS))]
14682pub struct JSONExtractQuote {
14683    #[serde(default)]
14684    pub option: Option<Box<Expression>>,
14685    #[serde(default)]
14686    pub scalar: Option<Box<Expression>>,
14687}
14688
14689/// JSONExtractArray
14690#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14691#[cfg_attr(feature = "bindings", derive(TS))]
14692pub struct JSONExtractArray {
14693    pub this: Box<Expression>,
14694    #[serde(default)]
14695    pub expression: Option<Box<Expression>>,
14696}
14697
14698/// JSONExtractScalar
14699#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14700#[cfg_attr(feature = "bindings", derive(TS))]
14701pub struct JSONExtractScalar {
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 json_type: Option<Box<Expression>>,
14710    #[serde(default)]
14711    pub scalar_only: Option<Box<Expression>>,
14712}
14713
14714/// JSONBExtractScalar
14715#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14716#[cfg_attr(feature = "bindings", derive(TS))]
14717pub struct JSONBExtractScalar {
14718    pub this: Box<Expression>,
14719    pub expression: Box<Expression>,
14720    #[serde(default)]
14721    pub json_type: Option<Box<Expression>>,
14722}
14723
14724/// JSONFormat
14725#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14726#[cfg_attr(feature = "bindings", derive(TS))]
14727pub struct JSONFormat {
14728    #[serde(default)]
14729    pub this: Option<Box<Expression>>,
14730    #[serde(default)]
14731    pub options: Vec<Expression>,
14732    #[serde(default)]
14733    pub is_json: Option<Box<Expression>>,
14734    #[serde(default)]
14735    pub to_json: Option<Box<Expression>>,
14736}
14737
14738/// JSONArrayAppend
14739#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14740#[cfg_attr(feature = "bindings", derive(TS))]
14741pub struct JSONArrayAppend {
14742    pub this: Box<Expression>,
14743    #[serde(default)]
14744    pub expressions: Vec<Expression>,
14745}
14746
14747/// JSONArrayContains
14748#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14749#[cfg_attr(feature = "bindings", derive(TS))]
14750pub struct JSONArrayContains {
14751    pub this: Box<Expression>,
14752    pub expression: Box<Expression>,
14753    #[serde(default)]
14754    pub json_type: Option<Box<Expression>>,
14755}
14756
14757/// JSONArrayInsert
14758#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14759#[cfg_attr(feature = "bindings", derive(TS))]
14760pub struct JSONArrayInsert {
14761    pub this: Box<Expression>,
14762    #[serde(default)]
14763    pub expressions: Vec<Expression>,
14764}
14765
14766/// ParseJSON
14767#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14768#[cfg_attr(feature = "bindings", derive(TS))]
14769pub struct ParseJSON {
14770    pub this: Box<Expression>,
14771    #[serde(default)]
14772    pub expression: Option<Box<Expression>>,
14773    #[serde(default)]
14774    pub safe: Option<Box<Expression>>,
14775}
14776
14777/// ParseUrl
14778#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14779#[cfg_attr(feature = "bindings", derive(TS))]
14780pub struct ParseUrl {
14781    pub this: Box<Expression>,
14782    #[serde(default)]
14783    pub part_to_extract: Option<Box<Expression>>,
14784    #[serde(default)]
14785    pub key: Option<Box<Expression>>,
14786    #[serde(default)]
14787    pub permissive: Option<Box<Expression>>,
14788}
14789
14790/// ParseIp
14791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14792#[cfg_attr(feature = "bindings", derive(TS))]
14793pub struct ParseIp {
14794    pub this: Box<Expression>,
14795    #[serde(default)]
14796    pub type_: Option<Box<Expression>>,
14797    #[serde(default)]
14798    pub permissive: Option<Box<Expression>>,
14799}
14800
14801/// ParseTime
14802#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14803#[cfg_attr(feature = "bindings", derive(TS))]
14804pub struct ParseTime {
14805    pub this: Box<Expression>,
14806    pub format: String,
14807}
14808
14809/// ParseDatetime
14810#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14811#[cfg_attr(feature = "bindings", derive(TS))]
14812pub struct ParseDatetime {
14813    pub this: Box<Expression>,
14814    #[serde(default)]
14815    pub format: Option<String>,
14816    #[serde(default)]
14817    pub zone: Option<Box<Expression>>,
14818}
14819
14820/// Map
14821#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14822#[cfg_attr(feature = "bindings", derive(TS))]
14823pub struct Map {
14824    #[serde(default)]
14825    pub keys: Vec<Expression>,
14826    #[serde(default)]
14827    pub values: Vec<Expression>,
14828}
14829
14830/// MapCat
14831#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14832#[cfg_attr(feature = "bindings", derive(TS))]
14833pub struct MapCat {
14834    pub this: Box<Expression>,
14835    pub expression: Box<Expression>,
14836}
14837
14838/// MapDelete
14839#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14840#[cfg_attr(feature = "bindings", derive(TS))]
14841pub struct MapDelete {
14842    pub this: Box<Expression>,
14843    #[serde(default)]
14844    pub expressions: Vec<Expression>,
14845}
14846
14847/// MapInsert
14848#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14849#[cfg_attr(feature = "bindings", derive(TS))]
14850pub struct MapInsert {
14851    pub this: Box<Expression>,
14852    #[serde(default)]
14853    pub key: Option<Box<Expression>>,
14854    #[serde(default)]
14855    pub value: Option<Box<Expression>>,
14856    #[serde(default)]
14857    pub update_flag: Option<Box<Expression>>,
14858}
14859
14860/// MapPick
14861#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14862#[cfg_attr(feature = "bindings", derive(TS))]
14863pub struct MapPick {
14864    pub this: Box<Expression>,
14865    #[serde(default)]
14866    pub expressions: Vec<Expression>,
14867}
14868
14869/// ScopeResolution
14870#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14871#[cfg_attr(feature = "bindings", derive(TS))]
14872pub struct ScopeResolution {
14873    #[serde(default)]
14874    pub this: Option<Box<Expression>>,
14875    pub expression: Box<Expression>,
14876}
14877
14878/// Slice
14879#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14880#[cfg_attr(feature = "bindings", derive(TS))]
14881pub struct Slice {
14882    #[serde(default)]
14883    pub this: Option<Box<Expression>>,
14884    #[serde(default)]
14885    pub expression: Option<Box<Expression>>,
14886    #[serde(default)]
14887    pub step: Option<Box<Expression>>,
14888}
14889
14890/// VarMap
14891#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14892#[cfg_attr(feature = "bindings", derive(TS))]
14893pub struct VarMap {
14894    #[serde(default)]
14895    pub keys: Vec<Expression>,
14896    #[serde(default)]
14897    pub values: Vec<Expression>,
14898}
14899
14900/// MatchAgainst
14901#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14902#[cfg_attr(feature = "bindings", derive(TS))]
14903pub struct MatchAgainst {
14904    pub this: Box<Expression>,
14905    #[serde(default)]
14906    pub expressions: Vec<Expression>,
14907    #[serde(default)]
14908    pub modifier: Option<Box<Expression>>,
14909}
14910
14911/// MD5Digest
14912#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14913#[cfg_attr(feature = "bindings", derive(TS))]
14914pub struct MD5Digest {
14915    pub this: Box<Expression>,
14916    #[serde(default)]
14917    pub expressions: Vec<Expression>,
14918}
14919
14920/// Monthname
14921#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14922#[cfg_attr(feature = "bindings", derive(TS))]
14923pub struct Monthname {
14924    pub this: Box<Expression>,
14925    #[serde(default)]
14926    pub abbreviated: Option<Box<Expression>>,
14927}
14928
14929/// Ntile
14930#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14931#[cfg_attr(feature = "bindings", derive(TS))]
14932pub struct Ntile {
14933    #[serde(default)]
14934    pub this: Option<Box<Expression>>,
14935}
14936
14937/// Normalize
14938#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14939#[cfg_attr(feature = "bindings", derive(TS))]
14940pub struct Normalize {
14941    pub this: Box<Expression>,
14942    #[serde(default)]
14943    pub form: Option<Box<Expression>>,
14944    #[serde(default)]
14945    pub is_casefold: Option<Box<Expression>>,
14946}
14947
14948/// Normal
14949#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14950#[cfg_attr(feature = "bindings", derive(TS))]
14951pub struct Normal {
14952    pub this: Box<Expression>,
14953    #[serde(default)]
14954    pub stddev: Option<Box<Expression>>,
14955    #[serde(default)]
14956    pub gen: Option<Box<Expression>>,
14957}
14958
14959/// Predict
14960#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14961#[cfg_attr(feature = "bindings", derive(TS))]
14962pub struct Predict {
14963    pub this: Box<Expression>,
14964    pub expression: Box<Expression>,
14965    #[serde(default)]
14966    pub params_struct: Option<Box<Expression>>,
14967}
14968
14969/// MLTranslate
14970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14971#[cfg_attr(feature = "bindings", derive(TS))]
14972pub struct MLTranslate {
14973    pub this: Box<Expression>,
14974    pub expression: Box<Expression>,
14975    #[serde(default)]
14976    pub params_struct: Option<Box<Expression>>,
14977}
14978
14979/// FeaturesAtTime
14980#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14981#[cfg_attr(feature = "bindings", derive(TS))]
14982pub struct FeaturesAtTime {
14983    pub this: Box<Expression>,
14984    #[serde(default)]
14985    pub time: Option<Box<Expression>>,
14986    #[serde(default)]
14987    pub num_rows: Option<Box<Expression>>,
14988    #[serde(default)]
14989    pub ignore_feature_nulls: Option<Box<Expression>>,
14990}
14991
14992/// GenerateEmbedding
14993#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
14994#[cfg_attr(feature = "bindings", derive(TS))]
14995pub struct GenerateEmbedding {
14996    pub this: Box<Expression>,
14997    pub expression: Box<Expression>,
14998    #[serde(default)]
14999    pub params_struct: Option<Box<Expression>>,
15000    #[serde(default)]
15001    pub is_text: Option<Box<Expression>>,
15002}
15003
15004/// MLForecast
15005#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15006#[cfg_attr(feature = "bindings", derive(TS))]
15007pub struct MLForecast {
15008    pub this: Box<Expression>,
15009    #[serde(default)]
15010    pub expression: Option<Box<Expression>>,
15011    #[serde(default)]
15012    pub params_struct: Option<Box<Expression>>,
15013}
15014
15015/// ModelAttribute
15016#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15017#[cfg_attr(feature = "bindings", derive(TS))]
15018pub struct ModelAttribute {
15019    pub this: Box<Expression>,
15020    pub expression: Box<Expression>,
15021}
15022
15023/// VectorSearch
15024#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15025#[cfg_attr(feature = "bindings", derive(TS))]
15026pub struct VectorSearch {
15027    pub this: Box<Expression>,
15028    #[serde(default)]
15029    pub column_to_search: Option<Box<Expression>>,
15030    #[serde(default)]
15031    pub query_table: Option<Box<Expression>>,
15032    #[serde(default)]
15033    pub query_column_to_search: Option<Box<Expression>>,
15034    #[serde(default)]
15035    pub top_k: Option<Box<Expression>>,
15036    #[serde(default)]
15037    pub distance_type: Option<Box<Expression>>,
15038    #[serde(default)]
15039    pub options: Vec<Expression>,
15040}
15041
15042/// Quantile
15043#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15044#[cfg_attr(feature = "bindings", derive(TS))]
15045pub struct Quantile {
15046    pub this: Box<Expression>,
15047    #[serde(default)]
15048    pub quantile: Option<Box<Expression>>,
15049}
15050
15051/// ApproxQuantile
15052#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15053#[cfg_attr(feature = "bindings", derive(TS))]
15054pub struct ApproxQuantile {
15055    pub this: Box<Expression>,
15056    #[serde(default)]
15057    pub quantile: Option<Box<Expression>>,
15058    #[serde(default)]
15059    pub accuracy: Option<Box<Expression>>,
15060    #[serde(default)]
15061    pub weight: Option<Box<Expression>>,
15062    #[serde(default)]
15063    pub error_tolerance: Option<Box<Expression>>,
15064}
15065
15066/// ApproxPercentileEstimate
15067#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15068#[cfg_attr(feature = "bindings", derive(TS))]
15069pub struct ApproxPercentileEstimate {
15070    pub this: Box<Expression>,
15071    #[serde(default)]
15072    pub percentile: Option<Box<Expression>>,
15073}
15074
15075/// Randn
15076#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15077#[cfg_attr(feature = "bindings", derive(TS))]
15078pub struct Randn {
15079    #[serde(default)]
15080    pub this: Option<Box<Expression>>,
15081}
15082
15083/// Randstr
15084#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15085#[cfg_attr(feature = "bindings", derive(TS))]
15086pub struct Randstr {
15087    pub this: Box<Expression>,
15088    #[serde(default)]
15089    pub generator: Option<Box<Expression>>,
15090}
15091
15092/// RangeN
15093#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15094#[cfg_attr(feature = "bindings", derive(TS))]
15095pub struct RangeN {
15096    pub this: Box<Expression>,
15097    #[serde(default)]
15098    pub expressions: Vec<Expression>,
15099    #[serde(default)]
15100    pub each: Option<Box<Expression>>,
15101}
15102
15103/// RangeBucket
15104#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15105#[cfg_attr(feature = "bindings", derive(TS))]
15106pub struct RangeBucket {
15107    pub this: Box<Expression>,
15108    pub expression: Box<Expression>,
15109}
15110
15111/// ReadCSV
15112#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15113#[cfg_attr(feature = "bindings", derive(TS))]
15114pub struct ReadCSV {
15115    pub this: Box<Expression>,
15116    #[serde(default)]
15117    pub expressions: Vec<Expression>,
15118}
15119
15120/// ReadParquet
15121#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15122#[cfg_attr(feature = "bindings", derive(TS))]
15123pub struct ReadParquet {
15124    #[serde(default)]
15125    pub expressions: Vec<Expression>,
15126}
15127
15128/// Reduce
15129#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15130#[cfg_attr(feature = "bindings", derive(TS))]
15131pub struct Reduce {
15132    pub this: Box<Expression>,
15133    #[serde(default)]
15134    pub initial: Option<Box<Expression>>,
15135    #[serde(default)]
15136    pub merge: Option<Box<Expression>>,
15137    #[serde(default)]
15138    pub finish: Option<Box<Expression>>,
15139}
15140
15141/// RegexpExtractAll
15142#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15143#[cfg_attr(feature = "bindings", derive(TS))]
15144pub struct RegexpExtractAll {
15145    pub this: Box<Expression>,
15146    pub expression: Box<Expression>,
15147    #[serde(default)]
15148    pub group: Option<Box<Expression>>,
15149    #[serde(default)]
15150    pub parameters: Option<Box<Expression>>,
15151    #[serde(default)]
15152    pub position: Option<Box<Expression>>,
15153    #[serde(default)]
15154    pub occurrence: Option<Box<Expression>>,
15155}
15156
15157/// RegexpILike
15158#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15159#[cfg_attr(feature = "bindings", derive(TS))]
15160pub struct RegexpILike {
15161    pub this: Box<Expression>,
15162    pub expression: Box<Expression>,
15163    #[serde(default)]
15164    pub flag: Option<Box<Expression>>,
15165}
15166
15167/// RegexpFullMatch
15168#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15169#[cfg_attr(feature = "bindings", derive(TS))]
15170pub struct RegexpFullMatch {
15171    pub this: Box<Expression>,
15172    pub expression: Box<Expression>,
15173    #[serde(default)]
15174    pub options: Vec<Expression>,
15175}
15176
15177/// RegexpInstr
15178#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15179#[cfg_attr(feature = "bindings", derive(TS))]
15180pub struct RegexpInstr {
15181    /// Additional search boundaries and retained source semantics.
15182    #[serde(default, skip_serializing_if = "Option::is_none")]
15183    pub options: Option<RegexOptions>,
15184    pub this: Box<Expression>,
15185    pub expression: Box<Expression>,
15186    #[serde(default)]
15187    pub position: Option<Box<Expression>>,
15188    #[serde(default)]
15189    pub occurrence: Option<Box<Expression>>,
15190    #[serde(default)]
15191    pub option: Option<Box<Expression>>,
15192    #[serde(default)]
15193    pub parameters: Option<Box<Expression>>,
15194    #[serde(default)]
15195    pub group: Option<Box<Expression>>,
15196}
15197
15198/// RegexpSplit
15199#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15200#[cfg_attr(feature = "bindings", derive(TS))]
15201pub struct RegexpSplit {
15202    pub this: Box<Expression>,
15203    pub expression: Box<Expression>,
15204    #[serde(default)]
15205    pub limit: Option<Box<Expression>>,
15206}
15207
15208/// RegexpCount
15209#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15210#[cfg_attr(feature = "bindings", derive(TS))]
15211pub struct RegexpCount {
15212    /// Additional search boundaries and retained source semantics.
15213    #[serde(default, skip_serializing_if = "Option::is_none")]
15214    pub options: Option<RegexOptions>,
15215    pub this: Box<Expression>,
15216    pub expression: Box<Expression>,
15217    #[serde(default)]
15218    pub position: Option<Box<Expression>>,
15219    #[serde(default)]
15220    pub parameters: Option<Box<Expression>>,
15221}
15222
15223/// RegrValx
15224#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15225#[cfg_attr(feature = "bindings", derive(TS))]
15226pub struct RegrValx {
15227    pub this: Box<Expression>,
15228    pub expression: Box<Expression>,
15229}
15230
15231/// RegrValy
15232#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15233#[cfg_attr(feature = "bindings", derive(TS))]
15234pub struct RegrValy {
15235    pub this: Box<Expression>,
15236    pub expression: Box<Expression>,
15237}
15238
15239/// RegrAvgy
15240#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15241#[cfg_attr(feature = "bindings", derive(TS))]
15242pub struct RegrAvgy {
15243    pub this: Box<Expression>,
15244    pub expression: Box<Expression>,
15245}
15246
15247/// RegrAvgx
15248#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15249#[cfg_attr(feature = "bindings", derive(TS))]
15250pub struct RegrAvgx {
15251    pub this: Box<Expression>,
15252    pub expression: Box<Expression>,
15253}
15254
15255/// RegrCount
15256#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15257#[cfg_attr(feature = "bindings", derive(TS))]
15258pub struct RegrCount {
15259    pub this: Box<Expression>,
15260    pub expression: Box<Expression>,
15261}
15262
15263/// RegrIntercept
15264#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15265#[cfg_attr(feature = "bindings", derive(TS))]
15266pub struct RegrIntercept {
15267    pub this: Box<Expression>,
15268    pub expression: Box<Expression>,
15269}
15270
15271/// RegrR2
15272#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15273#[cfg_attr(feature = "bindings", derive(TS))]
15274pub struct RegrR2 {
15275    pub this: Box<Expression>,
15276    pub expression: Box<Expression>,
15277}
15278
15279/// RegrSxx
15280#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15281#[cfg_attr(feature = "bindings", derive(TS))]
15282pub struct RegrSxx {
15283    pub this: Box<Expression>,
15284    pub expression: Box<Expression>,
15285}
15286
15287/// RegrSxy
15288#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15289#[cfg_attr(feature = "bindings", derive(TS))]
15290pub struct RegrSxy {
15291    pub this: Box<Expression>,
15292    pub expression: Box<Expression>,
15293}
15294
15295/// RegrSyy
15296#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15297#[cfg_attr(feature = "bindings", derive(TS))]
15298pub struct RegrSyy {
15299    pub this: Box<Expression>,
15300    pub expression: Box<Expression>,
15301}
15302
15303/// RegrSlope
15304#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15305#[cfg_attr(feature = "bindings", derive(TS))]
15306pub struct RegrSlope {
15307    pub this: Box<Expression>,
15308    pub expression: Box<Expression>,
15309}
15310
15311/// SafeAdd
15312#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15313#[cfg_attr(feature = "bindings", derive(TS))]
15314pub struct SafeAdd {
15315    pub this: Box<Expression>,
15316    pub expression: Box<Expression>,
15317}
15318
15319/// SafeDivide
15320#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15321#[cfg_attr(feature = "bindings", derive(TS))]
15322pub struct SafeDivide {
15323    pub this: Box<Expression>,
15324    pub expression: Box<Expression>,
15325}
15326
15327/// SafeMultiply
15328#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15329#[cfg_attr(feature = "bindings", derive(TS))]
15330pub struct SafeMultiply {
15331    pub this: Box<Expression>,
15332    pub expression: Box<Expression>,
15333}
15334
15335/// SafeSubtract
15336#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15337#[cfg_attr(feature = "bindings", derive(TS))]
15338pub struct SafeSubtract {
15339    pub this: Box<Expression>,
15340    pub expression: Box<Expression>,
15341}
15342
15343/// SHA2
15344#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15345#[cfg_attr(feature = "bindings", derive(TS))]
15346pub struct SHA2 {
15347    pub this: Box<Expression>,
15348    #[serde(default)]
15349    pub length: Option<i64>,
15350}
15351
15352/// SHA2Digest
15353#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15354#[cfg_attr(feature = "bindings", derive(TS))]
15355pub struct SHA2Digest {
15356    pub this: Box<Expression>,
15357    #[serde(default)]
15358    pub length: Option<i64>,
15359}
15360
15361/// SortArray
15362#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15363#[cfg_attr(feature = "bindings", derive(TS))]
15364pub struct SortArray {
15365    pub this: Box<Expression>,
15366    #[serde(default)]
15367    pub asc: Option<Box<Expression>>,
15368    #[serde(default)]
15369    pub nulls_first: Option<Box<Expression>>,
15370}
15371
15372/// SplitPart
15373#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15374#[cfg_attr(feature = "bindings", derive(TS))]
15375pub struct SplitPart {
15376    pub this: Box<Expression>,
15377    #[serde(default)]
15378    pub delimiter: Option<Box<Expression>>,
15379    #[serde(default)]
15380    pub part_index: Option<Box<Expression>>,
15381}
15382
15383/// SUBSTRING_INDEX(str, delim, count)
15384#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15385#[cfg_attr(feature = "bindings", derive(TS))]
15386pub struct SubstringIndex {
15387    pub this: Box<Expression>,
15388    #[serde(default)]
15389    pub delimiter: Option<Box<Expression>>,
15390    #[serde(default)]
15391    pub count: Option<Box<Expression>>,
15392}
15393
15394/// StandardHash
15395#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15396#[cfg_attr(feature = "bindings", derive(TS))]
15397pub struct StandardHash {
15398    pub this: Box<Expression>,
15399    #[serde(default)]
15400    pub expression: Option<Box<Expression>>,
15401}
15402
15403/// StrPosition
15404#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15405#[cfg_attr(feature = "bindings", derive(TS))]
15406pub struct StrPosition {
15407    pub this: Box<Expression>,
15408    #[serde(default)]
15409    pub substr: Option<Box<Expression>>,
15410    #[serde(default)]
15411    pub position: Option<Box<Expression>>,
15412    #[serde(default)]
15413    pub occurrence: Option<Box<Expression>>,
15414}
15415
15416/// Search
15417#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15418#[cfg_attr(feature = "bindings", derive(TS))]
15419pub struct Search {
15420    pub this: Box<Expression>,
15421    pub expression: Box<Expression>,
15422    #[serde(default)]
15423    pub json_scope: Option<Box<Expression>>,
15424    #[serde(default)]
15425    pub analyzer: Option<Box<Expression>>,
15426    #[serde(default)]
15427    pub analyzer_options: Option<Box<Expression>>,
15428    #[serde(default)]
15429    pub search_mode: Option<Box<Expression>>,
15430}
15431
15432/// SearchIp
15433#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15434#[cfg_attr(feature = "bindings", derive(TS))]
15435pub struct SearchIp {
15436    pub this: Box<Expression>,
15437    pub expression: Box<Expression>,
15438}
15439
15440/// StrToDate
15441#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15442#[cfg_attr(feature = "bindings", derive(TS))]
15443pub struct StrToDate {
15444    pub this: Box<Expression>,
15445    #[serde(default)]
15446    pub format: Option<String>,
15447    #[serde(default)]
15448    pub safe: Option<Box<Expression>>,
15449}
15450
15451/// StrToTime
15452#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15453#[cfg_attr(feature = "bindings", derive(TS))]
15454pub struct StrToTime {
15455    pub this: Box<Expression>,
15456    pub format: String,
15457    #[serde(default)]
15458    pub zone: Option<Box<Expression>>,
15459    #[serde(default)]
15460    pub safe: Option<Box<Expression>>,
15461    #[serde(default)]
15462    pub target_type: Option<Box<Expression>>,
15463}
15464
15465/// StrToUnix
15466#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15467#[cfg_attr(feature = "bindings", derive(TS))]
15468pub struct StrToUnix {
15469    #[serde(default)]
15470    pub this: Option<Box<Expression>>,
15471    #[serde(default)]
15472    pub format: Option<String>,
15473}
15474
15475/// StrToMap
15476#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15477#[cfg_attr(feature = "bindings", derive(TS))]
15478pub struct StrToMap {
15479    pub this: Box<Expression>,
15480    #[serde(default)]
15481    pub pair_delim: Option<Box<Expression>>,
15482    #[serde(default)]
15483    pub key_value_delim: Option<Box<Expression>>,
15484    #[serde(default)]
15485    pub duplicate_resolution_callback: Option<Box<Expression>>,
15486}
15487
15488/// NumberToStr
15489#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15490#[cfg_attr(feature = "bindings", derive(TS))]
15491pub struct NumberToStr {
15492    pub this: Box<Expression>,
15493    pub format: String,
15494    #[serde(default)]
15495    pub culture: Option<Box<Expression>>,
15496}
15497
15498/// FromBase
15499#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15500#[cfg_attr(feature = "bindings", derive(TS))]
15501pub struct FromBase {
15502    pub this: Box<Expression>,
15503    pub expression: Box<Expression>,
15504}
15505
15506/// Stuff
15507#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15508#[cfg_attr(feature = "bindings", derive(TS))]
15509pub struct Stuff {
15510    pub this: Box<Expression>,
15511    #[serde(default)]
15512    pub start: Option<Box<Expression>>,
15513    #[serde(default)]
15514    pub length: Option<i64>,
15515    pub expression: Box<Expression>,
15516}
15517
15518/// TimeToStr
15519#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15520#[cfg_attr(feature = "bindings", derive(TS))]
15521pub struct TimeToStr {
15522    pub this: Box<Expression>,
15523    pub format: String,
15524    #[serde(default)]
15525    pub culture: Option<Box<Expression>>,
15526    #[serde(default)]
15527    pub zone: Option<Box<Expression>>,
15528}
15529
15530/// TimeStrToTime
15531#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15532#[cfg_attr(feature = "bindings", derive(TS))]
15533pub struct TimeStrToTime {
15534    pub this: Box<Expression>,
15535    #[serde(default)]
15536    pub zone: Option<Box<Expression>>,
15537}
15538
15539/// TsOrDsAdd
15540#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15541#[cfg_attr(feature = "bindings", derive(TS))]
15542pub struct TsOrDsAdd {
15543    pub this: Box<Expression>,
15544    pub expression: Box<Expression>,
15545    #[serde(default)]
15546    pub unit: Option<String>,
15547    #[serde(default)]
15548    pub return_type: Option<Box<Expression>>,
15549}
15550
15551/// TsOrDsDiff
15552#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15553#[cfg_attr(feature = "bindings", derive(TS))]
15554pub struct TsOrDsDiff {
15555    pub this: Box<Expression>,
15556    pub expression: Box<Expression>,
15557    #[serde(default)]
15558    pub unit: Option<String>,
15559}
15560
15561/// TsOrDsToDate
15562#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15563#[cfg_attr(feature = "bindings", derive(TS))]
15564pub struct TsOrDsToDate {
15565    pub this: Box<Expression>,
15566    #[serde(default)]
15567    pub format: Option<String>,
15568    #[serde(default)]
15569    pub safe: Option<Box<Expression>>,
15570}
15571
15572/// TsOrDsToTime
15573#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15574#[cfg_attr(feature = "bindings", derive(TS))]
15575pub struct TsOrDsToTime {
15576    pub this: Box<Expression>,
15577    #[serde(default)]
15578    pub format: Option<String>,
15579    #[serde(default)]
15580    pub safe: Option<Box<Expression>>,
15581}
15582
15583/// Unhex
15584#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15585#[cfg_attr(feature = "bindings", derive(TS))]
15586pub struct Unhex {
15587    pub this: Box<Expression>,
15588    #[serde(default)]
15589    pub expression: Option<Box<Expression>>,
15590}
15591
15592/// Uniform
15593#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15594#[cfg_attr(feature = "bindings", derive(TS))]
15595pub struct Uniform {
15596    pub this: Box<Expression>,
15597    pub expression: Box<Expression>,
15598    #[serde(default)]
15599    pub gen: Option<Box<Expression>>,
15600    #[serde(default)]
15601    pub seed: Option<Box<Expression>>,
15602}
15603
15604/// UnixToStr
15605#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15606#[cfg_attr(feature = "bindings", derive(TS))]
15607pub struct UnixToStr {
15608    pub this: Box<Expression>,
15609    #[serde(default)]
15610    pub format: Option<String>,
15611}
15612
15613/// UnixToTime
15614#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15615#[cfg_attr(feature = "bindings", derive(TS))]
15616pub struct UnixToTime {
15617    pub this: Box<Expression>,
15618    #[serde(default)]
15619    pub scale: Option<i64>,
15620    #[serde(default)]
15621    pub zone: Option<Box<Expression>>,
15622    #[serde(default)]
15623    pub hours: Option<Box<Expression>>,
15624    #[serde(default)]
15625    pub minutes: Option<Box<Expression>>,
15626    #[serde(default)]
15627    pub format: Option<String>,
15628    #[serde(default)]
15629    pub target_type: Option<Box<Expression>>,
15630}
15631
15632/// Uuid
15633#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15634#[cfg_attr(feature = "bindings", derive(TS))]
15635pub struct Uuid {
15636    #[serde(default)]
15637    pub this: Option<Box<Expression>>,
15638    #[serde(default)]
15639    pub name: Option<String>,
15640    #[serde(default)]
15641    pub is_string: Option<Box<Expression>>,
15642}
15643
15644/// TimestampFromParts
15645#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15646#[cfg_attr(feature = "bindings", derive(TS))]
15647pub struct TimestampFromParts {
15648    #[serde(default)]
15649    pub zone: Option<Box<Expression>>,
15650    #[serde(default)]
15651    pub milli: Option<Box<Expression>>,
15652    #[serde(default)]
15653    pub this: Option<Box<Expression>>,
15654    #[serde(default)]
15655    pub expression: Option<Box<Expression>>,
15656}
15657
15658/// TimestampTzFromParts
15659#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15660#[cfg_attr(feature = "bindings", derive(TS))]
15661pub struct TimestampTzFromParts {
15662    #[serde(default)]
15663    pub zone: Option<Box<Expression>>,
15664}
15665
15666/// Corr
15667#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15668#[cfg_attr(feature = "bindings", derive(TS))]
15669pub struct Corr {
15670    pub this: Box<Expression>,
15671    pub expression: Box<Expression>,
15672    #[serde(default)]
15673    pub null_on_zero_variance: Option<Box<Expression>>,
15674}
15675
15676/// WidthBucket
15677#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15678#[cfg_attr(feature = "bindings", derive(TS))]
15679pub struct WidthBucket {
15680    pub this: Box<Expression>,
15681    #[serde(default)]
15682    pub min_value: Option<Box<Expression>>,
15683    #[serde(default)]
15684    pub max_value: Option<Box<Expression>>,
15685    #[serde(default)]
15686    pub num_buckets: Option<Box<Expression>>,
15687    #[serde(default)]
15688    pub threshold: Option<Box<Expression>>,
15689}
15690
15691/// CovarSamp
15692#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15693#[cfg_attr(feature = "bindings", derive(TS))]
15694pub struct CovarSamp {
15695    pub this: Box<Expression>,
15696    pub expression: Box<Expression>,
15697}
15698
15699/// CovarPop
15700#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15701#[cfg_attr(feature = "bindings", derive(TS))]
15702pub struct CovarPop {
15703    pub this: Box<Expression>,
15704    pub expression: Box<Expression>,
15705}
15706
15707/// Week
15708#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15709#[cfg_attr(feature = "bindings", derive(TS))]
15710pub struct Week {
15711    pub this: Box<Expression>,
15712    #[serde(default)]
15713    pub mode: Option<Box<Expression>>,
15714}
15715
15716/// XMLElement
15717#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15718#[cfg_attr(feature = "bindings", derive(TS))]
15719pub struct XMLElement {
15720    pub this: Box<Expression>,
15721    #[serde(default)]
15722    pub expressions: Vec<Expression>,
15723    #[serde(default)]
15724    pub evalname: Option<Box<Expression>>,
15725}
15726
15727/// XMLGet
15728#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15729#[cfg_attr(feature = "bindings", derive(TS))]
15730pub struct XMLGet {
15731    pub this: Box<Expression>,
15732    pub expression: Box<Expression>,
15733    #[serde(default)]
15734    pub instance: Option<Box<Expression>>,
15735}
15736
15737/// XMLTable
15738#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15739#[cfg_attr(feature = "bindings", derive(TS))]
15740pub struct XMLTable {
15741    pub this: Box<Expression>,
15742    #[serde(default)]
15743    pub namespaces: Option<Box<Expression>>,
15744    #[serde(default)]
15745    pub passing: Option<Box<Expression>>,
15746    #[serde(default)]
15747    pub columns: Vec<Expression>,
15748    #[serde(default)]
15749    pub by_ref: Option<Box<Expression>>,
15750}
15751
15752/// XMLKeyValueOption
15753#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15754#[cfg_attr(feature = "bindings", derive(TS))]
15755pub struct XMLKeyValueOption {
15756    pub this: Box<Expression>,
15757    #[serde(default)]
15758    pub expression: Option<Box<Expression>>,
15759}
15760
15761/// Zipf
15762#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15763#[cfg_attr(feature = "bindings", derive(TS))]
15764pub struct Zipf {
15765    pub this: Box<Expression>,
15766    #[serde(default)]
15767    pub elementcount: Option<Box<Expression>>,
15768    #[serde(default)]
15769    pub gen: Option<Box<Expression>>,
15770}
15771
15772/// Merge
15773#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15774#[cfg_attr(feature = "bindings", derive(TS))]
15775pub struct Merge {
15776    pub this: Box<Expression>,
15777    pub using: Box<Expression>,
15778    #[serde(default)]
15779    pub on: Option<Box<Expression>>,
15780    #[serde(default)]
15781    pub using_cond: Option<Box<Expression>>,
15782    #[serde(default)]
15783    pub whens: Option<Box<Expression>>,
15784    #[serde(default)]
15785    pub with_: Option<Box<Expression>>,
15786    #[serde(default)]
15787    pub returning: Option<Box<Expression>>,
15788}
15789
15790/// When
15791#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15792#[cfg_attr(feature = "bindings", derive(TS))]
15793pub struct When {
15794    #[serde(default)]
15795    pub matched: Option<Box<Expression>>,
15796    #[serde(default)]
15797    pub source: Option<Box<Expression>>,
15798    #[serde(default)]
15799    pub condition: Option<Box<Expression>>,
15800    pub then: Box<Expression>,
15801}
15802
15803/// Wraps around one or more WHEN [NOT] MATCHED [...] clauses.
15804#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15805#[cfg_attr(feature = "bindings", derive(TS))]
15806pub struct Whens {
15807    #[serde(default)]
15808    pub expressions: Vec<Expression>,
15809}
15810
15811/// NextValueFor
15812#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15813#[cfg_attr(feature = "bindings", derive(TS))]
15814pub struct NextValueFor {
15815    pub this: Box<Expression>,
15816    #[serde(default)]
15817    pub order: Option<Box<Expression>>,
15818}
15819
15820// Vertica dialect support.
15821/// Native Vertica syntax, retaining semantics through serialization and traversal.
15822#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15823#[cfg_attr(feature = "bindings", derive(TS))]
15824#[serde(tag = "kind", rename_all = "snake_case")]
15825pub enum VerticaExpression {
15826    PhysicalTable {
15827        this: Expression,
15828        physical: VerticaPhysical,
15829    },
15830    FlexTable {
15831        this: Expression,
15832        physical: VerticaPhysical,
15833    },
15834    Projection {
15835        name: TableRef,
15836        columns: Vec<VerticaProjectionColumn>,
15837        query: Expression,
15838        physical: VerticaPhysical,
15839    },
15840    Copy {
15841        table: TableRef,
15842        columns: Vec<Identifier>,
15843        local: bool,
15844        sources: Vec<Expression>,
15845        parser: Option<VerticaParserCall>,
15846        options: Vec<VerticaParameter>,
15847    },
15848    ExportParquet {
15849        options: Vec<VerticaParameter>,
15850        over: Option<Over>,
15851        query: Expression,
15852    },
15853    Interpolate {
15854        left: Expression,
15855        right: Expression,
15856        previous: bool,
15857    },
15858    /// Zero-based array access retains source bounds semantics from parsing.
15859    ArrayAccess {
15860        this: Expression,
15861        indices: Vec<Expression>,
15862    },
15863    ArraySlice {
15864        this: Expression,
15865        start: Option<Expression>,
15866        end: Option<Expression>,
15867    },
15868    BoundaryDateDiff {
15869        start: Expression,
15870        end: Expression,
15871        unit: IntervalUnit,
15872    },
15873    UsingParameters {
15874        this: Expression,
15875        parameters: Vec<VerticaParameter>,
15876    },
15877    SafeCast {
15878        this: Expression,
15879        to: DataType,
15880    },
15881    Set {
15882        values: Vec<Expression>,
15883    },
15884    Interval {
15885        value: Expression,
15886        precision: Option<u32>,
15887        year_month: bool,
15888        unit: Option<String>,
15889        end_unit: Option<String>,
15890    },
15891    /// Hexadecimal byte value, distinct from PostgreSQL's bit strings.
15892    Binary {
15893        hex: String,
15894    },
15895    Historical {
15896        query: Expression,
15897        point: VerticaHistoricalPoint,
15898    },
15899    PartitionBest,
15900}
15901
15902#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15903#[cfg_attr(feature = "bindings", derive(TS))]
15904pub struct VerticaParameter {
15905    pub name: Identifier,
15906    pub value: Expression,
15907}
15908
15909#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15910#[cfg_attr(feature = "bindings", derive(TS))]
15911#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
15912pub enum VerticaHistoricalPoint {
15913    Latest,
15914    Epoch(Expression),
15915    Time(Expression),
15916}
15917
15918#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15919#[cfg_attr(feature = "bindings", derive(TS))]
15920#[serde(tag = "kind", rename_all = "snake_case")]
15921pub enum VerticaDataType {
15922    Array {
15923        element_type: DataType,
15924        bound: Option<VerticaCollectionBound>,
15925    },
15926    Set {
15927        element_type: DataType,
15928        bound: Option<VerticaCollectionBound>,
15929    },
15930    Row {
15931        fields: Vec<StructField>,
15932    },
15933    LongVarBinary {
15934        length: Option<u32>,
15935    },
15936    Interval {
15937        precision: Option<u32>,
15938        year_month: bool,
15939        unit: Option<String>,
15940        end_unit: Option<String>,
15941    },
15942}
15943
15944#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15945#[cfg_attr(feature = "bindings", derive(TS))]
15946#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
15947pub enum VerticaCollectionBound {
15948    Elements(u32),
15949    Bytes(u32),
15950}
15951
15952#[derive(
15953    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
15954)]
15955#[cfg_attr(feature = "bindings", derive(TS))]
15956pub struct VerticaSelectExtensions {
15957    pub timeseries: Option<VerticaTimeseries>,
15958    pub match_clause: Option<VerticaMatch>,
15959    pub limit_over: Option<Over>,
15960}
15961
15962#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15963#[cfg_attr(feature = "bindings", derive(TS))]
15964pub struct VerticaTimeseries {
15965    pub alias: Identifier,
15966    pub interval: Expression,
15967    pub over: Over,
15968}
15969
15970#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15971#[cfg_attr(feature = "bindings", derive(TS))]
15972pub struct VerticaMatch {
15973    pub partition_by: Vec<Expression>,
15974    pub order_by: Vec<Ordered>,
15975    pub definitions: Vec<VerticaParameter>,
15976    pub name: Identifier,
15977    pub pattern: VerticaPattern,
15978    /// None = default; true = FIRST EVENT; false = ALL EVENTS.
15979    pub first_event: Option<bool>,
15980}
15981
15982#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
15983#[cfg_attr(feature = "bindings", derive(TS))]
15984#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
15985pub enum VerticaPattern {
15986    Event(Identifier),
15987    Sequence(Vec<VerticaPattern>),
15988    Alternative(Vec<VerticaPattern>),
15989    Group(Box<VerticaPattern>),
15990    Repeat {
15991        pattern: Box<VerticaPattern>,
15992        quantifier: String,
15993    },
15994}
15995
15996#[derive(
15997    polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize,
15998)]
15999#[cfg_attr(feature = "bindings", derive(TS))]
16000pub struct VerticaPhysical {
16001    pub order_by: Vec<Ordered>,
16002    pub segmentation: Option<VerticaSegmentation>,
16003    pub ksafe: Option<VerticaKsafe>,
16004}
16005
16006#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16007#[cfg_attr(feature = "bindings", derive(TS))]
16008#[serde(tag = "kind", content = "value", rename_all = "snake_case")]
16009pub enum VerticaKsafe {
16010    Default,
16011    Level(u32),
16012}
16013
16014#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16015#[cfg_attr(feature = "bindings", derive(TS))]
16016#[serde(tag = "kind", rename_all = "snake_case")]
16017pub enum VerticaSegmentation {
16018    Segmented {
16019        expression: Expression,
16020        offset: Option<u32>,
16021    },
16022    Unsegmented {
16023        node: Option<Identifier>,
16024    },
16025}
16026
16027#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16028#[cfg_attr(feature = "bindings", derive(TS))]
16029pub struct VerticaProjectionColumn {
16030    pub name: Identifier,
16031    pub encoding: Option<Identifier>,
16032}
16033
16034#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)]
16035#[cfg_attr(feature = "bindings", derive(TS))]
16036pub struct VerticaParserCall {
16037    pub name: TableRef,
16038    pub parameters: Vec<VerticaParameter>,
16039}
16040
16041#[cfg(test)]
16042mod tests {
16043    use super::*;
16044
16045    #[test]
16046    fn test_source_spans_are_metadata_not_expression_identity() {
16047        let plain = Expression::column("customer_id");
16048        let mut positioned = plain.clone();
16049        if let Expression::Column(column) = &mut positioned {
16050            column.span = Some(Span::new(7, 18, 1, 19));
16051            column.name.span = column.span;
16052        }
16053        assert_eq!(plain, positioned);
16054        assert_ne!(
16055            serde_json::to_value(&plain).unwrap(),
16056            serde_json::to_value(&positioned).unwrap()
16057        );
16058        assert_eq!(
16059            Identifier::new("a"),
16060            Identifier::new("a").with_span(Span::new(3, 4, 1, 5))
16061        );
16062        assert_ne!(Identifier::new("a"), Identifier::quoted("a"));
16063        assert_ne!(plain, Expression::column("other"));
16064        let Expression::Column(column) = plain else {
16065            unreachable!()
16066        };
16067        assert!(column.span.is_none() && column.name.span.is_none());
16068    }
16069
16070    #[test]
16071    #[cfg(feature = "bindings")]
16072    fn export_typescript_types() {
16073        // This test exports TypeScript types to the generated directory
16074        // Run with: cargo test -p polyglot-sql --features bindings export_typescript_types
16075        Expression::export_all(&ts_rs::Config::default())
16076            .expect("Failed to export Expression types");
16077
16078        let mut variant_names = String::from(
16079            "// This file was generated from the Rust Expression enum. Do not edit it manually.\n\n",
16080        );
16081        variant_names.push_str("export const EXPRESSION_VARIANT_NAMES = [\n");
16082        for name in Expression::SERIALIZED_VARIANT_NAMES {
16083            use std::fmt::Write;
16084            writeln!(variant_names, "  {name:?},").expect("writing to a String cannot fail");
16085        }
16086        variant_names.push_str("] as const;\n");
16087
16088        let output_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
16089            .join("bindings/ExpressionVariantNames.ts");
16090        std::fs::write(output_path, variant_names)
16091            .expect("Failed to export serialized Expression variant names");
16092    }
16093
16094    #[test]
16095    fn test_simple_select_builder() {
16096        let select = Select::new()
16097            .column(Expression::star())
16098            .from(Expression::Table(Box::new(TableRef::new("users"))));
16099
16100        assert_eq!(select.expressions.len(), 1);
16101        assert!(select.from.is_some());
16102    }
16103
16104    #[test]
16105    fn test_expression_alias() {
16106        let expr = Expression::column("id").alias("user_id");
16107
16108        match expr {
16109            Expression::Alias(a) => {
16110                assert_eq!(a.alias.name, "user_id");
16111            }
16112            _ => panic!("Expected Alias"),
16113        }
16114    }
16115
16116    #[test]
16117    fn test_literal_creation() {
16118        let num = Expression::number(42);
16119        let str = Expression::string("hello");
16120
16121        match num {
16122            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)) => {
16123                let Literal::Number(n) = lit.as_ref() else {
16124                    unreachable!()
16125                };
16126                assert_eq!(n, "42")
16127            }
16128            _ => panic!("Expected Number"),
16129        }
16130
16131        match str {
16132            Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
16133                let Literal::String(s) = lit.as_ref() else {
16134                    unreachable!()
16135                };
16136                assert_eq!(s, "hello")
16137            }
16138            _ => panic!("Expected String"),
16139        }
16140    }
16141
16142    #[test]
16143    fn test_expression_sql() {
16144        let expr = crate::parse_one("SELECT 1 + 2", crate::DialectType::Generic).unwrap();
16145        assert_eq!(expr.sql(), "SELECT 1 + 2");
16146    }
16147
16148    #[test]
16149    fn test_expression_sql_for() {
16150        let expr = crate::parse_one("SELECT IF(x > 0, 1, 0)", crate::DialectType::Generic).unwrap();
16151        let sql = expr.sql_for(crate::DialectType::Generic);
16152        // Generic mode normalizes IF() to CASE WHEN
16153        assert!(sql.contains("CASE WHEN"), "Expected CASE WHEN in: {}", sql);
16154    }
16155}