Skip to main content

sqlparser/ast/
spans.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::{
19    ast::{
20        ddl::AlterSchema, query::SelectItemQualifiedWildcardKind, AlterSchemaOperation, AlterTable,
21        ColumnOptions, CreateOperator, CreateOperatorClass, CreateOperatorFamily, CreateView,
22        ExportData, Owner, TypedString,
23    },
24    tokenizer::TokenWithSpan,
25};
26use core::iter;
27
28use crate::tokenizer::Span;
29
30use super::{
31    comments, dcl::SecondaryRoles, value::ValueWithSpan, AccessExpr, AlterColumnOperation,
32    AlterIndexOperation, AlterTableOperation, Analyze, Array, Assignment, AssignmentTarget,
33    AttachedToken, BeginEndStatements, CaseStatement, CloseCursor, ClusteredIndex, ColumnDef,
34    ColumnOption, ColumnOptionDef, ConditionalStatementBlock, ConditionalStatements,
35    ConflictTarget, ConnectByKind, ConstraintCharacteristics, CopySource, CreateIndex, CreateTable,
36    CreateTableOptions, Cte, Delete, DoUpdate, ExceptSelectItem, ExcludeSelectItem, Expr,
37    ExprWithAlias, Fetch, ForValues, FromTable, Function, FunctionArg, FunctionArgExpr,
38    FunctionArgumentClause, FunctionArgumentList, FunctionArguments, GroupByExpr, HavingBound,
39    IfStatement, IlikeSelectItem, IndexColumn, Insert, Interpolate, InterpolateExpr, Join,
40    JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, LimitClause,
41    MatchRecognizePattern, Measure, Merge, MergeAction, MergeClause, MergeInsertExpr,
42    MergeInsertKind, MergeUpdateExpr, MergeUpdateKind, NamedParenthesizedList,
43    NamedWindowDefinition, ObjectName, ObjectNamePart, Offset, OnConflict, OnConflictAction,
44    OnInsert, OpenStatement, OrderBy, OrderByExpr, OrderByKind, OutputClause, Parens, Partition,
45    PartitionBoundValue, PivotValueSource, ProjectionSelect, Query, RaiseStatement,
46    RaiseStatementValue, ReferentialAction, RenameSelectItem, ReplaceSelectElement,
47    ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SqlOption, Statement, Subscript,
48    SymbolDefinition, TableAlias, TableAliasColumnDef, TableConstraint, TableFactor, TableObject,
49    TableOptionsClustered, TableWithJoins, Update, UpdateTableFromKind, Use, Values, ViewColumnDef,
50    WhileStatement, WildcardAdditionalOptions, With, WithFill,
51};
52
53/// Given an iterator of spans, return the [Span::union] of all spans.
54fn union_spans<I: Iterator<Item = Span>>(iter: I) -> Span {
55    Span::union_iter(iter)
56}
57
58/// Trait for AST nodes that have a source location information.
59///
60/// # Notes:
61///
62/// Source [`Span`] are not yet complete. They may be missing:
63///
64/// 1. keywords or other tokens
65/// 2. span information entirely, in which case they return [`Span::empty()`].
66///
67/// Note Some impl blocks (rendered below) are annotated with which nodes are
68/// missing spans. See [this ticket] for additional information and status.
69///
70/// [this ticket]: https://github.com/apache/datafusion-sqlparser-rs/issues/1548
71///
72/// # Example
73/// ```
74/// # use sqlparser::parser::{Parser, ParserError};
75/// # use sqlparser::ast::Spanned;
76/// # use sqlparser::dialect::GenericDialect;
77/// # use sqlparser::tokenizer::Location;
78/// # fn main() -> Result<(), ParserError> {
79/// let dialect = GenericDialect {};
80/// let sql = r#"SELECT *
81///   FROM table_1"#;
82/// let statements = Parser::new(&dialect)
83///   .try_with_sql(sql)?
84///   .parse_statements()?;
85/// // Get the span of the first statement (SELECT)
86/// let span = statements[0].span();
87/// // statement starts at line 1, column 1 (1 based, not 0 based)
88/// assert_eq!(span.start, Location::new(1, 1));
89/// // statement ends on line 2, column 15
90/// assert_eq!(span.end, Location::new(2, 15));
91/// # Ok(())
92/// # }
93/// ```
94///
95pub trait Spanned {
96    /// Return the [`Span`] (the minimum and maximum [`Location`]) for this AST
97    /// node, by recursively combining the spans of its children.
98    ///
99    /// [`Location`]: crate::tokenizer::Location
100    fn span(&self) -> Span;
101}
102
103impl Spanned for TokenWithSpan {
104    fn span(&self) -> Span {
105        self.span
106    }
107}
108
109impl<T> Spanned for Parens<T> {
110    fn span(&self) -> Span {
111        self.opening_token.0.span.union(&self.closing_token.0.span)
112    }
113}
114
115impl Spanned for Query {
116    fn span(&self) -> Span {
117        let Query {
118            with,
119            body,
120            order_by,
121            limit_clause,
122            fetch,
123            locks: _,          // todo
124            for_clause: _,     // todo, mssql specific
125            settings: _,       // todo, clickhouse specific
126            format_clause: _,  // todo, clickhouse specific
127            pipe_operators: _, // todo bigquery specific
128        } = self;
129
130        union_spans(
131            with.iter()
132                .map(|i| i.span())
133                .chain(core::iter::once(body.span()))
134                .chain(order_by.as_ref().map(|i| i.span()))
135                .chain(limit_clause.as_ref().map(|i| i.span()))
136                .chain(fetch.as_ref().map(|i| i.span())),
137        )
138    }
139}
140
141impl Spanned for LimitClause {
142    fn span(&self) -> Span {
143        match self {
144            LimitClause::LimitOffset {
145                limit,
146                offset,
147                limit_by,
148            } => union_spans(
149                limit
150                    .iter()
151                    .map(|i| i.span())
152                    .chain(offset.as_ref().map(|i| i.span()))
153                    .chain(limit_by.iter().map(|i| i.span())),
154            ),
155            LimitClause::OffsetCommaLimit { offset, limit } => offset.span().union(&limit.span()),
156        }
157    }
158}
159
160impl Spanned for Offset {
161    fn span(&self) -> Span {
162        let Offset {
163            value,
164            rows: _, // enum
165        } = self;
166
167        value.span()
168    }
169}
170
171impl Spanned for Fetch {
172    fn span(&self) -> Span {
173        let Fetch {
174            with_ties: _, // bool
175            percent: _,   // bool
176            quantity,
177        } = self;
178
179        quantity.as_ref().map_or(Span::empty(), |i| i.span())
180    }
181}
182
183impl Spanned for With {
184    fn span(&self) -> Span {
185        let With {
186            with_token,
187            recursive: _, // bool
188            cte_tables,
189        } = self;
190
191        union_spans(
192            core::iter::once(with_token.0.span).chain(cte_tables.iter().map(|item| item.span())),
193        )
194    }
195}
196
197impl Spanned for Cte {
198    fn span(&self) -> Span {
199        let Cte {
200            alias,
201            query,
202            from,
203            materialized: _, // enum
204            closing_paren_token,
205        } = self;
206
207        union_spans(
208            core::iter::once(alias.span())
209                .chain(core::iter::once(query.span()))
210                .chain(from.iter().map(|item| item.span))
211                .chain(core::iter::once(closing_paren_token.0.span)),
212        )
213    }
214}
215
216/// # partial span
217///
218/// [SetExpr::Table] is not implemented.
219impl Spanned for SetExpr {
220    fn span(&self) -> Span {
221        match self {
222            SetExpr::Select(select) => select.span(),
223            SetExpr::Query(query) => query.span(),
224            SetExpr::SetOperation {
225                op: _,
226                set_quantifier: _,
227                left,
228                right,
229            } => left.span().union(&right.span()),
230            SetExpr::Values(values) => values.span(),
231            SetExpr::Insert(statement) => statement.span(),
232            SetExpr::Table(_) => Span::empty(),
233            SetExpr::Update(statement) => statement.span(),
234            SetExpr::Delete(statement) => statement.span(),
235            SetExpr::Merge(statement) => statement.span(),
236        }
237    }
238}
239
240impl Spanned for Values {
241    fn span(&self) -> Span {
242        let Values {
243            explicit_row: _, // bool,
244            value_keyword: _,
245            rows,
246        } = self;
247
248        match &rows[..] {
249            [] => Span::empty(),
250            [f] => f.span(),
251            [f, .., l] => f.span().union(&l.span()),
252        }
253    }
254}
255
256/// # partial span
257///
258/// Missing spans:
259/// - [Statement::CopyIntoSnowflake]
260/// - [Statement::CreateSecret]
261/// - [Statement::CreateRole]
262/// - [Statement::AlterType]
263/// - [Statement::AlterOperator]
264/// - [Statement::AlterRole]
265/// - [Statement::AttachDatabase]
266/// - [Statement::AttachDuckDBDatabase]
267/// - [Statement::DetachDuckDBDatabase]
268/// - [Statement::Drop]
269/// - [Statement::DropFunction]
270/// - [Statement::DropProcedure]
271/// - [Statement::DropSecret]
272/// - [Statement::Declare]
273/// - [Statement::CreateExtension]
274/// - [Statement::CreateCollation]
275/// - [Statement::AlterCollation]
276/// - [Statement::Fetch]
277/// - [Statement::Flush]
278/// - [Statement::Discard]
279/// - [Statement::Set]
280/// - [Statement::ShowFunctions]
281/// - [Statement::ShowVariable]
282/// - [Statement::ShowStatus]
283/// - [Statement::ShowVariables]
284/// - [Statement::ShowCreate]
285/// - [Statement::ShowColumns]
286/// - [Statement::ShowTables]
287/// - [Statement::ShowCollation]
288/// - [Statement::StartTransaction]
289/// - [Statement::Comment]
290/// - [Statement::Commit]
291/// - [Statement::Rollback]
292/// - [Statement::CreateSchema]
293/// - [Statement::CreateDatabase]
294/// - [Statement::CreateFunction]
295/// - [Statement::CreateTrigger]
296/// - [Statement::DropTrigger]
297/// - [Statement::CreateProcedure]
298/// - [Statement::CreateMacro]
299/// - [Statement::CreateStage]
300/// - [Statement::Assert]
301/// - [Statement::Grant]
302/// - [Statement::Revoke]
303/// - [Statement::Deallocate]
304/// - [Statement::Execute]
305/// - [Statement::Prepare]
306/// - [Statement::Kill]
307/// - [Statement::ExplainTable]
308/// - [Statement::Explain]
309/// - [Statement::Savepoint]
310/// - [Statement::ReleaseSavepoint]
311/// - [Statement::Cache]
312/// - [Statement::UNCache]
313/// - [Statement::CreateSequence]
314/// - [Statement::CreateType]
315/// - [Statement::Pragma]
316/// - [Statement::Lock]
317/// - [Statement::LockTables]
318/// - [Statement::UnlockTables]
319/// - [Statement::Unload]
320/// - [Statement::OptimizeTable]
321impl Spanned for Statement {
322    fn span(&self) -> Span {
323        match self {
324            Statement::Analyze(analyze) => analyze.span(),
325            Statement::Truncate(truncate) => truncate.span(),
326            Statement::Msck(msck) => msck.span(),
327            Statement::Query(query) => query.span(),
328            Statement::Insert(insert) => insert.span(),
329            Statement::Install { extension_name } => extension_name.span,
330            Statement::Load { extension_name } => extension_name.span,
331            Statement::Directory {
332                overwrite: _,
333                local: _,
334                path: _,
335                file_format: _,
336                source,
337            } => source.span(),
338            Statement::Case(stmt) => stmt.span(),
339            Statement::If(stmt) => stmt.span(),
340            Statement::While(stmt) => stmt.span(),
341            Statement::Raise(stmt) => stmt.span(),
342            Statement::Call(function) => function.span(),
343            Statement::Copy {
344                source,
345                to: _,
346                target: _,
347                options: _,
348                legacy_options: _,
349                values: _,
350            } => source.span(),
351            Statement::CopyIntoSnowflake {
352                into: _,
353                into_columns: _,
354                from_obj: _,
355                from_obj_alias: _,
356                stage_params: _,
357                from_transformations: _,
358                files: _,
359                pattern: _,
360                file_format: _,
361                copy_options: _,
362                validation_mode: _,
363                kind: _,
364                from_query: _,
365                partition: _,
366            } => Span::empty(),
367            Statement::Open(open) => open.span(),
368            Statement::Close { cursor } => match cursor {
369                CloseCursor::All => Span::empty(),
370                CloseCursor::Specific { name } => name.span,
371            },
372            Statement::Update(update) => update.span(),
373            Statement::Delete(delete) => delete.span(),
374            Statement::CreateView(create_view) => create_view.span(),
375            Statement::CreateTable(create_table) => create_table.span(),
376            Statement::CreateVirtualTable {
377                name,
378                if_not_exists: _,
379                module_name,
380                module_args,
381            } => union_spans(
382                core::iter::once(name.span())
383                    .chain(core::iter::once(module_name.span))
384                    .chain(module_args.iter().map(|i| i.span)),
385            ),
386            Statement::CreateIndex(create_index) => create_index.span(),
387            Statement::CreateRole(create_role) => create_role.span(),
388            Statement::CreateExtension(create_extension) => create_extension.span(),
389            Statement::CreateCollation(create_collation) => create_collation.span(),
390            Statement::DropExtension(drop_extension) => drop_extension.span(),
391            Statement::DropOperator(drop_operator) => drop_operator.span(),
392            Statement::DropOperatorFamily(drop_operator_family) => drop_operator_family.span(),
393            Statement::DropOperatorClass(drop_operator_class) => drop_operator_class.span(),
394            Statement::CreateSecret { .. } => Span::empty(),
395            Statement::CreateServer { .. } => Span::empty(),
396            Statement::CreateConnector { .. } => Span::empty(),
397            Statement::CreateOperator(create_operator) => create_operator.span(),
398            Statement::CreateOperatorFamily(create_operator_family) => {
399                create_operator_family.span()
400            }
401            Statement::CreateOperatorClass(create_operator_class) => create_operator_class.span(),
402            Statement::AlterTable(alter_table) => alter_table.span(),
403            Statement::AlterIndex { name, operation } => name.span().union(&operation.span()),
404            Statement::AlterView {
405                name,
406                columns,
407                query,
408                with_options,
409            } => union_spans(
410                core::iter::once(name.span())
411                    .chain(columns.iter().map(|i| i.span))
412                    .chain(core::iter::once(query.span()))
413                    .chain(with_options.iter().map(|i| i.span())),
414            ),
415            // These statements need to be implemented
416            Statement::AlterFunction { .. } => Span::empty(),
417            Statement::AlterType { .. } => Span::empty(),
418            Statement::AlterCollation { .. } => Span::empty(),
419            Statement::AlterOperator { .. } => Span::empty(),
420            Statement::AlterOperatorFamily { .. } => Span::empty(),
421            Statement::AlterOperatorClass { .. } => Span::empty(),
422            Statement::AlterRole { .. } => Span::empty(),
423            Statement::AlterSession { .. } => Span::empty(),
424            Statement::AttachDatabase { .. } => Span::empty(),
425            Statement::AttachDuckDBDatabase { .. } => Span::empty(),
426            Statement::DetachDuckDBDatabase { .. } => Span::empty(),
427            Statement::Drop { .. } => Span::empty(),
428            Statement::DropFunction(drop_function) => drop_function.span(),
429            Statement::DropDomain { .. } => Span::empty(),
430            Statement::DropProcedure { .. } => Span::empty(),
431            Statement::DropSecret { .. } => Span::empty(),
432            Statement::Declare { .. } => Span::empty(),
433            Statement::Fetch { .. } => Span::empty(),
434            Statement::Flush { .. } => Span::empty(),
435            Statement::Discard { .. } => Span::empty(),
436            Statement::Set(_) => Span::empty(),
437            Statement::ShowFunctions { .. } => Span::empty(),
438            Statement::ShowVariable { .. } => Span::empty(),
439            Statement::ShowStatus { .. } => Span::empty(),
440            Statement::ShowVariables { .. } => Span::empty(),
441            Statement::ShowCreate { .. } => Span::empty(),
442            Statement::ShowColumns { .. } => Span::empty(),
443            Statement::ShowTables { .. } => Span::empty(),
444            Statement::ShowCollation { .. } => Span::empty(),
445            Statement::ShowCharset { .. } => Span::empty(),
446            Statement::Use(u) => u.span(),
447            Statement::StartTransaction { .. } => Span::empty(),
448            Statement::Comment { .. } => Span::empty(),
449            Statement::Commit { .. } => Span::empty(),
450            Statement::Rollback { .. } => Span::empty(),
451            Statement::CreateSchema { .. } => Span::empty(),
452            Statement::CreateDatabase { .. } => Span::empty(),
453            Statement::CreateFunction { .. } => Span::empty(),
454            Statement::CreateDomain { .. } => Span::empty(),
455            Statement::CreateTrigger { .. } => Span::empty(),
456            Statement::DropTrigger { .. } => Span::empty(),
457            Statement::CreateProcedure { .. } => Span::empty(),
458            Statement::CreateMacro { .. } => Span::empty(),
459            Statement::CreateStage { .. } => Span::empty(),
460            Statement::Assert { .. } => Span::empty(),
461            Statement::Grant { .. } => Span::empty(),
462            Statement::Deny { .. } => Span::empty(),
463            Statement::Revoke { .. } => Span::empty(),
464            Statement::Deallocate { .. } => Span::empty(),
465            Statement::Execute { .. } => Span::empty(),
466            Statement::Prepare { .. } => Span::empty(),
467            Statement::Kill { .. } => Span::empty(),
468            Statement::ExplainTable { .. } => Span::empty(),
469            Statement::Explain { .. } => Span::empty(),
470            Statement::Savepoint { .. } => Span::empty(),
471            Statement::ReleaseSavepoint { .. } => Span::empty(),
472            Statement::Merge(merge) => merge.span(),
473            Statement::Cache { .. } => Span::empty(),
474            Statement::UNCache { .. } => Span::empty(),
475            Statement::CreateSequence { .. } => Span::empty(),
476            Statement::CreateType { .. } => Span::empty(),
477            Statement::Pragma { .. } => Span::empty(),
478            Statement::Lock(_) => Span::empty(),
479            Statement::LockTables { .. } => Span::empty(),
480            Statement::UnlockTables => Span::empty(),
481            Statement::Unload { .. } => Span::empty(),
482            Statement::OptimizeTable { .. } => Span::empty(),
483            Statement::CreatePolicy { .. } => Span::empty(),
484            Statement::AlterPolicy { .. } => Span::empty(),
485            Statement::AlterConnector { .. } => Span::empty(),
486            Statement::DropPolicy { .. } => Span::empty(),
487            Statement::DropConnector { .. } => Span::empty(),
488            Statement::ShowCatalogs { .. } => Span::empty(),
489            Statement::ShowDatabases { .. } => Span::empty(),
490            Statement::ShowProcessList { .. } => Span::empty(),
491            Statement::ShowSchemas { .. } => Span::empty(),
492            Statement::ShowObjects { .. } => Span::empty(),
493            Statement::ShowViews { .. } => Span::empty(),
494            Statement::LISTEN { .. } => Span::empty(),
495            Statement::NOTIFY { .. } => Span::empty(),
496            Statement::LoadData { .. } => Span::empty(),
497            Statement::UNLISTEN { .. } => Span::empty(),
498            Statement::RenameTable { .. } => Span::empty(),
499            Statement::RaisError { .. } => Span::empty(),
500            Statement::Throw(_) => Span::empty(),
501            Statement::Print { .. } => Span::empty(),
502            Statement::WaitFor(_) => Span::empty(),
503            Statement::Return { .. } => Span::empty(),
504            Statement::List(..) | Statement::Remove(..) => Span::empty(),
505            Statement::ExportData(ExportData {
506                options,
507                query,
508                connection,
509            }) => union_spans(
510                options
511                    .iter()
512                    .map(|i| i.span())
513                    .chain(core::iter::once(query.span()))
514                    .chain(connection.iter().map(|i| i.span())),
515            ),
516            Statement::CreateUser(..) => Span::empty(),
517            Statement::AlterSchema(s) => s.span(),
518            Statement::Vacuum(..) => Span::empty(),
519            Statement::AlterUser(..) => Span::empty(),
520            Statement::Reset(..) => Span::empty(),
521        }
522    }
523}
524
525impl Spanned for Use {
526    fn span(&self) -> Span {
527        match self {
528            Use::Catalog(object_name) => object_name.span(),
529            Use::Schema(object_name) => object_name.span(),
530            Use::Database(object_name) => object_name.span(),
531            Use::Warehouse(object_name) => object_name.span(),
532            Use::Role(object_name) => object_name.span(),
533            Use::SecondaryRoles(secondary_roles) => {
534                if let SecondaryRoles::List(roles) = secondary_roles {
535                    return union_spans(roles.iter().map(|i| i.span));
536                }
537                Span::empty()
538            }
539            Use::Object(object_name) => object_name.span(),
540            Use::Default => Span::empty(),
541        }
542    }
543}
544
545impl Spanned for CreateTable {
546    fn span(&self) -> Span {
547        let CreateTable {
548            or_replace: _,    // bool
549            temporary: _,     // bool
550            external: _,      // bool
551            global: _,        // bool
552            dynamic: _,       // bool
553            if_not_exists: _, // bool
554            transient: _,     // bool
555            volatile: _,      // bool
556            iceberg: _,       // bool, Snowflake specific
557            snapshot: _,      // bool, BigQuery specific
558            name,
559            columns,
560            constraints,
561            hive_distribution: _, // hive specific
562            hive_formats: _,      // hive specific
563            file_format: _,       // enum
564            location: _,          // string, no span
565            query,
566            without_rowid: _, // bool
567            like: _,
568            clone,
569            comment: _, // todo, no span
570            on_commit: _,
571            on_cluster: _,   // todo, clickhouse specific
572            primary_key: _,  // todo, clickhouse specific
573            order_by: _,     // todo, clickhouse specific
574            partition_by: _, // todo, BigQuery specific
575            cluster_by: _,   // todo, BigQuery specific
576            clustered_by: _, // todo, Hive specific
577            inherits: _,     // todo, PostgreSQL specific
578            partition_of,
579            for_values,
580            strict: _,                          // bool
581            copy_grants: _,                     // bool
582            enable_schema_evolution: _,         // bool
583            change_tracking: _,                 // bool
584            data_retention_time_in_days: _,     // u64, no span
585            max_data_extension_time_in_days: _, // u64, no span
586            default_ddl_collation: _,           // string, no span
587            with_aggregation_policy: _,         // todo, Snowflake specific
588            with_row_access_policy: _,          // todo, Snowflake specific
589            with_storage_lifecycle_policy: _,   // todo, Snowflake specific
590            with_tags: _,                       // todo, Snowflake specific
591            external_volume: _,                 // todo, Snowflake specific
592            with_connection: _,                 // todo, BigQuery external table connection
593            base_location: _,                   // todo, Snowflake specific
594            catalog: _,                         // todo, Snowflake specific
595            catalog_sync: _,                    // todo, Snowflake specific
596            storage_serialization_policy: _,
597            table_options,
598            target_lag: _,
599            warehouse: _,
600            version: _,
601            refresh_mode: _,
602            initialize: _,
603            require_user: _,
604            diststyle: _,
605            distkey: _,
606            sortkey: _,
607            backup: _,
608            multiset: _,
609            fallback: _,
610            with_data: _,
611        } = self;
612
613        union_spans(
614            core::iter::once(name.span())
615                .chain(core::iter::once(table_options.span()))
616                .chain(columns.iter().map(|i| i.span()))
617                .chain(constraints.iter().map(|i| i.span()))
618                .chain(query.iter().map(|i| i.span()))
619                .chain(clone.iter().map(|i| i.span()))
620                .chain(partition_of.iter().map(|i| i.span()))
621                .chain(for_values.iter().map(|i| i.span())),
622        )
623    }
624}
625
626impl Spanned for ColumnDef {
627    fn span(&self) -> Span {
628        let ColumnDef {
629            name,
630            data_type: _, // enum
631            options,
632        } = self;
633
634        union_spans(core::iter::once(name.span).chain(options.iter().map(|i| i.span())))
635    }
636}
637
638impl Spanned for ColumnOptionDef {
639    fn span(&self) -> Span {
640        let ColumnOptionDef { name, option } = self;
641
642        option.span().union_opt(&name.as_ref().map(|i| i.span))
643    }
644}
645
646impl Spanned for TableConstraint {
647    fn span(&self) -> Span {
648        match self {
649            TableConstraint::Unique(constraint) => constraint.span(),
650            TableConstraint::PrimaryKey(constraint) => constraint.span(),
651            TableConstraint::ForeignKey(constraint) => constraint.span(),
652            TableConstraint::Check(constraint) => constraint.span(),
653            TableConstraint::Index(constraint) => constraint.span(),
654            TableConstraint::FulltextOrSpatial(constraint) => constraint.span(),
655            TableConstraint::PrimaryKeyUsingIndex(constraint)
656            | TableConstraint::UniqueUsingIndex(constraint) => constraint.span(),
657        }
658    }
659}
660
661impl Spanned for PartitionBoundValue {
662    fn span(&self) -> Span {
663        match self {
664            PartitionBoundValue::Expr(expr) => expr.span(),
665            // MINVALUE and MAXVALUE are keywords without tracked spans
666            PartitionBoundValue::MinValue => Span::empty(),
667            PartitionBoundValue::MaxValue => Span::empty(),
668        }
669    }
670}
671
672impl Spanned for ForValues {
673    fn span(&self) -> Span {
674        match self {
675            ForValues::In(exprs) => union_spans(exprs.iter().map(|e| e.span())),
676            ForValues::From { from, to } => union_spans(
677                from.iter()
678                    .map(|v| v.span())
679                    .chain(to.iter().map(|v| v.span())),
680            ),
681            // WITH (MODULUS n, REMAINDER r) - u64 values have no spans
682            ForValues::With { .. } => Span::empty(),
683            ForValues::Default => Span::empty(),
684        }
685    }
686}
687
688impl Spanned for CreateIndex {
689    fn span(&self) -> Span {
690        let CreateIndex {
691            name,
692            table_name,
693            using: _,
694            columns,
695            unique: _,        // bool
696            concurrently: _,  // bool
697            r#async: _,       // bool
698            if_not_exists: _, // bool
699            include,
700            nulls_distinct: _, // bool
701            with,
702            predicate,
703            index_options: _,
704            alter_options,
705        } = self;
706
707        union_spans(
708            name.iter()
709                .map(|i| i.span())
710                .chain(core::iter::once(table_name.span()))
711                .chain(columns.iter().map(|i| i.column.span()))
712                .chain(include.iter().map(|i| i.span))
713                .chain(with.iter().map(|i| i.span()))
714                .chain(predicate.iter().map(|i| i.span()))
715                .chain(alter_options.iter().map(|i| i.span())),
716        )
717    }
718}
719
720impl Spanned for IndexColumn {
721    fn span(&self) -> Span {
722        self.column.span()
723    }
724}
725
726impl Spanned for CaseStatement {
727    fn span(&self) -> Span {
728        let CaseStatement {
729            case_token: AttachedToken(start),
730            match_expr: _,
731            when_blocks: _,
732            else_block: _,
733            end_case_token: AttachedToken(end),
734        } = self;
735
736        union_spans([start.span, end.span].into_iter())
737    }
738}
739
740impl Spanned for IfStatement {
741    fn span(&self) -> Span {
742        let IfStatement {
743            if_block,
744            elseif_blocks,
745            else_block,
746            end_token,
747        } = self;
748
749        union_spans(
750            iter::once(if_block.span())
751                .chain(elseif_blocks.iter().map(|b| b.span()))
752                .chain(else_block.as_ref().map(|b| b.span()))
753                .chain(end_token.as_ref().map(|AttachedToken(t)| t.span)),
754        )
755    }
756}
757
758impl Spanned for WhileStatement {
759    fn span(&self) -> Span {
760        let WhileStatement { while_block } = self;
761
762        while_block.span()
763    }
764}
765
766impl Spanned for ConditionalStatements {
767    fn span(&self) -> Span {
768        match self {
769            ConditionalStatements::Sequence { statements } => {
770                union_spans(statements.iter().map(|s| s.span()))
771            }
772            ConditionalStatements::BeginEnd(bes) => bes.span(),
773        }
774    }
775}
776
777impl Spanned for ConditionalStatementBlock {
778    fn span(&self) -> Span {
779        let ConditionalStatementBlock {
780            start_token: AttachedToken(start_token),
781            condition,
782            then_token,
783            conditional_statements,
784        } = self;
785
786        union_spans(
787            iter::once(start_token.span)
788                .chain(condition.as_ref().map(|c| c.span()))
789                .chain(then_token.as_ref().map(|AttachedToken(t)| t.span))
790                .chain(iter::once(conditional_statements.span())),
791        )
792    }
793}
794
795impl Spanned for RaiseStatement {
796    fn span(&self) -> Span {
797        let RaiseStatement { value } = self;
798
799        union_spans(value.iter().map(|value| value.span()))
800    }
801}
802
803impl Spanned for RaiseStatementValue {
804    fn span(&self) -> Span {
805        match self {
806            RaiseStatementValue::UsingMessage(expr) => expr.span(),
807            RaiseStatementValue::Expr(expr) => expr.span(),
808        }
809    }
810}
811
812/// # partial span
813///
814/// Missing spans:
815/// - [ColumnOption::Null]
816/// - [ColumnOption::NotNull]
817/// - [ColumnOption::Comment]
818/// - [ColumnOption::PrimaryKey]
819/// - [ColumnOption::Unique]
820/// - [ColumnOption::DialectSpecific]
821/// - [ColumnOption::Generated]
822impl Spanned for ColumnOption {
823    fn span(&self) -> Span {
824        match self {
825            ColumnOption::Null => Span::empty(),
826            ColumnOption::NotNull => Span::empty(),
827            ColumnOption::Default(expr) => expr.span(),
828            ColumnOption::Materialized(expr) => expr.span(),
829            ColumnOption::Ephemeral(expr) => expr.as_ref().map_or(Span::empty(), |e| e.span()),
830            ColumnOption::Alias(expr) => expr.span(),
831            ColumnOption::PrimaryKey(constraint) => constraint.span(),
832            ColumnOption::Unique(constraint) => constraint.span(),
833            ColumnOption::Check(constraint) => constraint.span(),
834            ColumnOption::ForeignKey(constraint) => constraint.span(),
835            ColumnOption::DialectSpecific(_) => Span::empty(),
836            ColumnOption::CharacterSet(object_name) => object_name.span(),
837            ColumnOption::Collation(object_name) => object_name.span(),
838            ColumnOption::Comment(_) => Span::empty(),
839            ColumnOption::OnUpdate(expr) => expr.span(),
840            ColumnOption::Generated { .. } => Span::empty(),
841            ColumnOption::Options(vec) => union_spans(vec.iter().map(|i| i.span())),
842            ColumnOption::Identity(..) => Span::empty(),
843            ColumnOption::OnConflict(..) => Span::empty(),
844            ColumnOption::Policy(..) => Span::empty(),
845            ColumnOption::Tags(..) => Span::empty(),
846            ColumnOption::Srid(..) => Span::empty(),
847            ColumnOption::Invisible => Span::empty(),
848        }
849    }
850}
851
852/// # missing span
853impl Spanned for ReferentialAction {
854    fn span(&self) -> Span {
855        Span::empty()
856    }
857}
858
859/// # missing span
860impl Spanned for ConstraintCharacteristics {
861    fn span(&self) -> Span {
862        let ConstraintCharacteristics {
863            deferrable: _, // bool
864            initially: _,  // enum
865            enforced: _,   // bool
866        } = self;
867
868        Span::empty()
869    }
870}
871
872impl Spanned for Analyze {
873    fn span(&self) -> Span {
874        union_spans(
875            self.table_name
876                .iter()
877                .map(|t| t.span())
878                .chain(
879                    self.partitions
880                        .iter()
881                        .flat_map(|i| i.iter().map(|k| k.span())),
882                )
883                .chain(self.columns.iter().map(|i| i.span)),
884        )
885    }
886}
887
888/// # partial span
889///
890/// Missing spans:
891/// - [AlterColumnOperation::SetNotNull]
892/// - [AlterColumnOperation::DropNotNull]
893/// - [AlterColumnOperation::DropDefault]
894/// - [AlterColumnOperation::SetStorage]
895/// - [AlterColumnOperation::AddGenerated]
896impl Spanned for AlterColumnOperation {
897    fn span(&self) -> Span {
898        match self {
899            AlterColumnOperation::SetNotNull => Span::empty(),
900            AlterColumnOperation::DropNotNull => Span::empty(),
901            AlterColumnOperation::SetDefault { value } => value.span(),
902            AlterColumnOperation::DropDefault => Span::empty(),
903            AlterColumnOperation::SetStorage { .. } => Span::empty(),
904            AlterColumnOperation::SetDataType {
905                data_type: _,
906                using,
907                had_set: _,
908            } => using.as_ref().map_or(Span::empty(), |u| u.span()),
909            AlterColumnOperation::AddGenerated { .. } => Span::empty(),
910        }
911    }
912}
913
914impl Spanned for CopySource {
915    fn span(&self) -> Span {
916        match self {
917            CopySource::Table {
918                table_name,
919                columns,
920            } => union_spans(
921                core::iter::once(table_name.span()).chain(columns.iter().map(|i| i.span)),
922            ),
923            CopySource::Query(query) => query.span(),
924        }
925    }
926}
927
928impl Spanned for Delete {
929    fn span(&self) -> Span {
930        let Delete {
931            delete_token,
932            optimizer_hints: _,
933            tables,
934            from,
935            using,
936            selection,
937            returning,
938            output,
939            order_by,
940            limit,
941        } = self;
942
943        union_spans(
944            core::iter::once(delete_token.0.span).chain(
945                tables
946                    .iter()
947                    .map(|i| i.span())
948                    .chain(core::iter::once(from.span()))
949                    .chain(
950                        using
951                            .iter()
952                            .map(|u| union_spans(u.iter().map(|i| i.span()))),
953                    )
954                    .chain(selection.iter().map(|i| i.span()))
955                    .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span())))
956                    .chain(output.iter().map(|i| i.span()))
957                    .chain(order_by.iter().map(|i| i.span()))
958                    .chain(limit.iter().map(|i| i.span())),
959            ),
960        )
961    }
962}
963
964impl Spanned for Update {
965    fn span(&self) -> Span {
966        let Update {
967            update_token,
968            optimizer_hints: _,
969            table,
970            assignments,
971            from,
972            selection,
973            returning,
974            output,
975            or: _,
976            order_by,
977            limit,
978        } = self;
979
980        union_spans(
981            core::iter::once(table.span())
982                .chain(core::iter::once(update_token.0.span))
983                .chain(assignments.iter().map(|i| i.span()))
984                .chain(from.iter().map(|i| i.span()))
985                .chain(selection.iter().map(|i| i.span()))
986                .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span())))
987                .chain(output.iter().map(|i| i.span()))
988                .chain(order_by.iter().map(|i| i.span()))
989                .chain(limit.iter().map(|i| i.span())),
990        )
991    }
992}
993
994impl Spanned for Merge {
995    fn span(&self) -> Span {
996        union_spans(
997            [self.merge_token.0.span, self.on.span()]
998                .into_iter()
999                .chain(self.clauses.iter().map(Spanned::span))
1000                .chain(self.output.iter().map(Spanned::span)),
1001        )
1002    }
1003}
1004
1005impl Spanned for FromTable {
1006    fn span(&self) -> Span {
1007        match self {
1008            FromTable::WithFromKeyword(vec) => union_spans(vec.iter().map(|i| i.span())),
1009            FromTable::WithoutKeyword(vec) => union_spans(vec.iter().map(|i| i.span())),
1010        }
1011    }
1012}
1013
1014impl Spanned for ViewColumnDef {
1015    fn span(&self) -> Span {
1016        let ViewColumnDef {
1017            name,
1018            data_type: _, // todo, DataType
1019            options,
1020        } = self;
1021
1022        name.span.union_opt(&options.as_ref().map(|o| o.span()))
1023    }
1024}
1025
1026impl Spanned for ColumnOptions {
1027    fn span(&self) -> Span {
1028        union_spans(self.as_slice().iter().map(|i| i.span()))
1029    }
1030}
1031
1032impl Spanned for SqlOption {
1033    fn span(&self) -> Span {
1034        match self {
1035            SqlOption::Clustered(table_options_clustered) => table_options_clustered.span(),
1036            SqlOption::Ident(ident) => ident.span,
1037            SqlOption::KeyValue { key, value } => key.span.union(&value.span()),
1038            SqlOption::Partition {
1039                column_name,
1040                range_direction: _,
1041                for_values,
1042            } => union_spans(
1043                core::iter::once(column_name.span).chain(for_values.iter().map(|i| i.span())),
1044            ),
1045            SqlOption::TableSpace(_) => Span::empty(),
1046            SqlOption::Comment(_) => Span::empty(),
1047            SqlOption::NamedParenthesizedList(NamedParenthesizedList {
1048                key: name,
1049                name: value,
1050                values,
1051            }) => union_spans(core::iter::once(name.span).chain(values.iter().map(|i| i.span)))
1052                .union_opt(&value.as_ref().map(|i| i.span)),
1053        }
1054    }
1055}
1056
1057/// # partial span
1058///
1059/// Missing spans:
1060/// - [TableOptionsClustered::ColumnstoreIndex]
1061impl Spanned for TableOptionsClustered {
1062    fn span(&self) -> Span {
1063        match self {
1064            TableOptionsClustered::ColumnstoreIndex => Span::empty(),
1065            TableOptionsClustered::ColumnstoreIndexOrder(vec) => {
1066                union_spans(vec.iter().map(|i| i.span))
1067            }
1068            TableOptionsClustered::Index(vec) => union_spans(vec.iter().map(|i| i.span())),
1069        }
1070    }
1071}
1072
1073impl Spanned for ClusteredIndex {
1074    fn span(&self) -> Span {
1075        let ClusteredIndex {
1076            name,
1077            asc: _, // bool
1078        } = self;
1079
1080        name.span
1081    }
1082}
1083
1084impl Spanned for CreateTableOptions {
1085    fn span(&self) -> Span {
1086        match self {
1087            CreateTableOptions::None => Span::empty(),
1088            CreateTableOptions::With(vec) => union_spans(vec.iter().map(|i| i.span())),
1089            CreateTableOptions::Options(vec) => {
1090                union_spans(vec.as_slice().iter().map(|i| i.span()))
1091            }
1092            CreateTableOptions::Plain(vec) => union_spans(vec.iter().map(|i| i.span())),
1093            CreateTableOptions::TableProperties(vec) => union_spans(vec.iter().map(|i| i.span())),
1094        }
1095    }
1096}
1097
1098/// # partial span
1099///
1100/// Missing spans:
1101/// - [AlterTableOperation::OwnerTo]
1102impl Spanned for AlterTableOperation {
1103    fn span(&self) -> Span {
1104        match self {
1105            AlterTableOperation::AddConstraint {
1106                constraint,
1107                not_valid: _,
1108            } => constraint.span(),
1109            AlterTableOperation::AddColumn {
1110                column_keyword: _,
1111                if_not_exists: _,
1112                column_def,
1113                column_position: _,
1114            } => column_def.span(),
1115            AlterTableOperation::AddProjection {
1116                if_not_exists: _,
1117                name,
1118                select,
1119            } => name.span.union(&select.span()),
1120            AlterTableOperation::DropProjection { if_exists: _, name } => name.span,
1121            AlterTableOperation::MaterializeProjection {
1122                if_exists: _,
1123                name,
1124                partition,
1125            } => name.span.union_opt(&partition.as_ref().map(|i| i.span)),
1126            AlterTableOperation::ClearProjection {
1127                if_exists: _,
1128                name,
1129                partition,
1130            } => name.span.union_opt(&partition.as_ref().map(|i| i.span)),
1131            AlterTableOperation::DisableRowLevelSecurity => Span::empty(),
1132            AlterTableOperation::DisableRule { name } => name.span,
1133            AlterTableOperation::DisableTrigger { name } => name.span,
1134            AlterTableOperation::DropConstraint {
1135                if_exists: _,
1136                name,
1137                drop_behavior: _,
1138            } => name.span,
1139            AlterTableOperation::DropColumn {
1140                has_column_keyword: _,
1141                column_names,
1142                if_exists: _,
1143                drop_behavior: _,
1144            } => union_spans(column_names.iter().map(|i| i.span)),
1145            AlterTableOperation::AttachPartition { partition } => partition.span(),
1146            AlterTableOperation::DetachPartition { partition } => partition.span(),
1147            AlterTableOperation::FreezePartition {
1148                partition,
1149                with_name,
1150            } => partition
1151                .span()
1152                .union_opt(&with_name.as_ref().map(|n| n.span)),
1153            AlterTableOperation::UnfreezePartition {
1154                partition,
1155                with_name,
1156            } => partition
1157                .span()
1158                .union_opt(&with_name.as_ref().map(|n| n.span)),
1159            AlterTableOperation::DropPrimaryKey { .. } => Span::empty(),
1160            AlterTableOperation::DropForeignKey { name, .. } => name.span,
1161            AlterTableOperation::DropIndex { name } => name.span,
1162            AlterTableOperation::EnableAlwaysRule { name } => name.span,
1163            AlterTableOperation::EnableAlwaysTrigger { name } => name.span,
1164            AlterTableOperation::EnableReplicaRule { name } => name.span,
1165            AlterTableOperation::EnableReplicaTrigger { name } => name.span,
1166            AlterTableOperation::EnableRowLevelSecurity => Span::empty(),
1167            AlterTableOperation::ForceRowLevelSecurity => Span::empty(),
1168            AlterTableOperation::NoForceRowLevelSecurity => Span::empty(),
1169            AlterTableOperation::EnableRule { name } => name.span,
1170            AlterTableOperation::EnableTrigger { name } => name.span,
1171            AlterTableOperation::RenamePartitions {
1172                old_partitions,
1173                new_partitions,
1174            } => union_spans(
1175                old_partitions
1176                    .iter()
1177                    .map(|i| i.span())
1178                    .chain(new_partitions.iter().map(|i| i.span())),
1179            ),
1180            AlterTableOperation::AddPartitions {
1181                if_not_exists: _,
1182                new_partitions,
1183            } => union_spans(new_partitions.iter().map(|i| i.span())),
1184            AlterTableOperation::DropPartitions {
1185                partitions,
1186                if_exists: _,
1187            } => union_spans(partitions.iter().map(|i| i.span())),
1188            AlterTableOperation::RenameColumn {
1189                old_column_name,
1190                new_column_name,
1191            } => old_column_name.span.union(&new_column_name.span),
1192            AlterTableOperation::RenameTable { table_name } => table_name.span(),
1193            AlterTableOperation::ChangeColumn {
1194                old_name,
1195                new_name,
1196                data_type: _,
1197                options,
1198                column_position: _,
1199            } => union_spans(
1200                core::iter::once(old_name.span)
1201                    .chain(core::iter::once(new_name.span))
1202                    .chain(options.iter().map(|i| i.span())),
1203            ),
1204            AlterTableOperation::ModifyColumn {
1205                col_name,
1206                data_type: _,
1207                options,
1208                column_position: _,
1209            } => {
1210                union_spans(core::iter::once(col_name.span).chain(options.iter().map(|i| i.span())))
1211            }
1212            AlterTableOperation::RenameConstraint { old_name, new_name } => {
1213                old_name.span.union(&new_name.span)
1214            }
1215            AlterTableOperation::AlterColumn { column_name, op } => {
1216                column_name.span.union(&op.span())
1217            }
1218            AlterTableOperation::SwapWith { table_name } => table_name.span(),
1219            AlterTableOperation::SetTblProperties { table_properties } => {
1220                union_spans(table_properties.iter().map(|i| i.span()))
1221            }
1222            AlterTableOperation::OwnerTo { .. } => Span::empty(),
1223            AlterTableOperation::ClusterBy { exprs } => union_spans(exprs.iter().map(|e| e.span())),
1224            AlterTableOperation::DropClusteringKey => Span::empty(),
1225            AlterTableOperation::AlterSortKey { .. } => Span::empty(),
1226            AlterTableOperation::SuspendRecluster => Span::empty(),
1227            AlterTableOperation::ResumeRecluster => Span::empty(),
1228            AlterTableOperation::Refresh { .. } => Span::empty(),
1229            AlterTableOperation::Suspend => Span::empty(),
1230            AlterTableOperation::Resume => Span::empty(),
1231            AlterTableOperation::Algorithm { .. } => Span::empty(),
1232            AlterTableOperation::AutoIncrement { value, .. } => value.span(),
1233            AlterTableOperation::Lock { .. } => Span::empty(),
1234            AlterTableOperation::ReplicaIdentity { .. } => Span::empty(),
1235            AlterTableOperation::ValidateConstraint { name } => name.span,
1236            AlterTableOperation::SetOptionsParens { options } => {
1237                union_spans(options.iter().map(|i| i.span()))
1238            }
1239        }
1240    }
1241}
1242
1243impl Spanned for Partition {
1244    fn span(&self) -> Span {
1245        match self {
1246            Partition::Identifier(ident) => ident.span,
1247            Partition::Expr(expr) => expr.span(),
1248            Partition::Part(expr) => expr.span(),
1249            Partition::Partitions(vec) => union_spans(vec.iter().map(|i| i.span())),
1250        }
1251    }
1252}
1253
1254impl Spanned for ProjectionSelect {
1255    fn span(&self) -> Span {
1256        let ProjectionSelect {
1257            projection,
1258            order_by,
1259            group_by,
1260        } = self;
1261
1262        union_spans(
1263            projection
1264                .iter()
1265                .map(|i| i.span())
1266                .chain(order_by.iter().map(|i| i.span()))
1267                .chain(group_by.iter().map(|i| i.span())),
1268        )
1269    }
1270}
1271
1272/// # partial span
1273///
1274/// Missing spans:
1275/// - [OrderByKind::All]
1276impl Spanned for OrderBy {
1277    fn span(&self) -> Span {
1278        match &self.kind {
1279            OrderByKind::All(_) => Span::empty(),
1280            OrderByKind::Expressions(exprs) => union_spans(
1281                exprs
1282                    .iter()
1283                    .map(|i| i.span())
1284                    .chain(self.interpolate.iter().map(|i| i.span())),
1285            ),
1286        }
1287    }
1288}
1289
1290/// # partial span
1291///
1292/// Missing spans:
1293/// - [GroupByExpr::All]
1294impl Spanned for GroupByExpr {
1295    fn span(&self) -> Span {
1296        match self {
1297            GroupByExpr::All(_) => Span::empty(),
1298            GroupByExpr::Expressions(exprs, _modifiers) => {
1299                union_spans(exprs.iter().map(|i| i.span()))
1300            }
1301        }
1302    }
1303}
1304
1305impl Spanned for Interpolate {
1306    fn span(&self) -> Span {
1307        let Interpolate { exprs } = self;
1308
1309        union_spans(exprs.iter().flat_map(|i| i.iter().map(|e| e.span())))
1310    }
1311}
1312
1313impl Spanned for InterpolateExpr {
1314    fn span(&self) -> Span {
1315        let InterpolateExpr { column, expr } = self;
1316
1317        column.span.union_opt(&expr.as_ref().map(|e| e.span()))
1318    }
1319}
1320
1321impl Spanned for AlterIndexOperation {
1322    fn span(&self) -> Span {
1323        match self {
1324            AlterIndexOperation::RenameIndex { index_name } => index_name.span(),
1325        }
1326    }
1327}
1328
1329/// # partial span
1330///
1331/// Missing spans:ever
1332/// - [Insert::insert_alias]
1333impl Spanned for Insert {
1334    fn span(&self) -> Span {
1335        let Insert {
1336            insert_token,
1337            optimizer_hints: _,
1338            or: _,     // enum, sqlite specific
1339            ignore: _, // bool
1340            into: _,   // bool
1341            table,
1342            table_alias,
1343            columns,
1344            overwrite: _, // bool
1345            source,
1346            partitioned,
1347            after_columns,
1348            has_table_keyword: _, // bool
1349            on,
1350            returning,
1351            output,
1352            replace_into: _, // bool
1353            priority: _,     // todo, mysql specific
1354            insert_alias: _, // todo, mysql specific
1355            assignments,
1356            settings: _,                 // todo, clickhouse specific
1357            format_clause: _,            // todo, clickhouse specific
1358            multi_table_insert_type: _,  // snowflake multi-table insert
1359            multi_table_into_clauses: _, // snowflake multi-table insert
1360            multi_table_when_clauses: _, // snowflake multi-table insert
1361            multi_table_else_clause: _,  // snowflake multi-table insert
1362        } = self;
1363
1364        union_spans(
1365            core::iter::once(insert_token.0.span)
1366                .chain(core::iter::once(table.span()))
1367                .chain(table_alias.iter().map(|k| k.alias.span))
1368                .chain(columns.iter().map(|i| i.span()))
1369                .chain(source.as_ref().map(|q| q.span()))
1370                .chain(assignments.iter().map(|i| i.span()))
1371                .chain(partitioned.iter().flat_map(|i| i.iter().map(|k| k.span())))
1372                .chain(after_columns.iter().map(|i| i.span))
1373                .chain(on.as_ref().map(|i| i.span()))
1374                .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span())))
1375                .chain(output.iter().map(|i| i.span())),
1376        )
1377    }
1378}
1379
1380impl Spanned for OnInsert {
1381    fn span(&self) -> Span {
1382        match self {
1383            OnInsert::DuplicateKeyUpdate(vec) => union_spans(vec.iter().map(|i| i.span())),
1384            OnInsert::OnConflict(on_conflict) => on_conflict.span(),
1385        }
1386    }
1387}
1388
1389impl Spanned for OnConflict {
1390    fn span(&self) -> Span {
1391        let OnConflict {
1392            conflict_target,
1393            action,
1394        } = self;
1395
1396        action
1397            .span()
1398            .union_opt(&conflict_target.as_ref().map(|i| i.span()))
1399    }
1400}
1401
1402impl Spanned for ConflictTarget {
1403    fn span(&self) -> Span {
1404        match self {
1405            ConflictTarget::Columns(vec) => union_spans(vec.iter().map(|i| i.span)),
1406            ConflictTarget::OnConstraint(object_name) => object_name.span(),
1407        }
1408    }
1409}
1410
1411/// # partial span
1412///
1413/// Missing spans:
1414/// - [OnConflictAction::DoNothing]
1415impl Spanned for OnConflictAction {
1416    fn span(&self) -> Span {
1417        match self {
1418            OnConflictAction::DoNothing => Span::empty(),
1419            OnConflictAction::DoUpdate(do_update) => do_update.span(),
1420        }
1421    }
1422}
1423
1424impl Spanned for DoUpdate {
1425    fn span(&self) -> Span {
1426        let DoUpdate {
1427            assignments,
1428            selection,
1429        } = self;
1430
1431        union_spans(
1432            assignments
1433                .iter()
1434                .map(|i| i.span())
1435                .chain(selection.iter().map(|i| i.span())),
1436        )
1437    }
1438}
1439
1440impl Spanned for Assignment {
1441    fn span(&self) -> Span {
1442        let Assignment { target, value } = self;
1443
1444        target.span().union(&value.span())
1445    }
1446}
1447
1448impl Spanned for AssignmentTarget {
1449    fn span(&self) -> Span {
1450        match self {
1451            AssignmentTarget::ColumnName(object_name) => object_name.span(),
1452            AssignmentTarget::Tuple(vec) => union_spans(vec.iter().map(|i| i.span())),
1453        }
1454    }
1455}
1456
1457/// # partial span
1458///
1459/// Most expressions are missing keywords in their spans.
1460/// f.e. `IS NULL <expr>` reports as `<expr>::span`.
1461///
1462/// Missing spans:
1463/// - [Expr::MatchAgainst] # MySQL specific
1464/// - [Expr::RLike] # MySQL specific
1465/// - [Expr::Struct] # BigQuery specific
1466/// - [Expr::Named] # BigQuery specific
1467/// - [Expr::Dictionary] # DuckDB specific
1468/// - [Expr::Map] # DuckDB specific
1469/// - [Expr::Lambda]
1470impl Spanned for Expr {
1471    fn span(&self) -> Span {
1472        match self {
1473            Expr::Identifier(ident) => ident.span,
1474            Expr::CompoundIdentifier(vec) => union_spans(vec.iter().map(|i| i.span)),
1475            Expr::CompoundFieldAccess { root, access_chain } => {
1476                union_spans(iter::once(root.span()).chain(access_chain.iter().map(|i| i.span())))
1477            }
1478            Expr::IsFalse(expr) => expr.span(),
1479            Expr::IsNotFalse(expr) => expr.span(),
1480            Expr::IsTrue(expr) => expr.span(),
1481            Expr::IsNotTrue(expr) => expr.span(),
1482            Expr::IsNull(expr) => expr.span(),
1483            Expr::IsNotNull(expr) => expr.span(),
1484            Expr::IsUnknown(expr) => expr.span(),
1485            Expr::IsNotUnknown(expr) => expr.span(),
1486            Expr::IsDistinctFrom(lhs, rhs) => lhs.span().union(&rhs.span()),
1487            Expr::IsNotDistinctFrom(lhs, rhs) => lhs.span().union(&rhs.span()),
1488            Expr::InList {
1489                expr,
1490                list,
1491                negated: _,
1492            } => union_spans(
1493                core::iter::once(expr.span()).chain(list.iter().map(|item| item.span())),
1494            ),
1495            Expr::InSubquery {
1496                expr,
1497                subquery,
1498                negated: _,
1499            } => expr.span().union(&subquery.span()),
1500            Expr::InUnnest {
1501                expr,
1502                array_expr,
1503                negated: _,
1504            } => expr.span().union(&array_expr.span()),
1505            Expr::Between {
1506                expr,
1507                negated: _,
1508                low,
1509                high,
1510            } => expr.span().union(&low.span()).union(&high.span()),
1511
1512            Expr::BinaryOp { left, op: _, right } => left.span().union(&right.span()),
1513            Expr::Like {
1514                negated: _,
1515                expr,
1516                pattern,
1517                escape_char: _,
1518                any: _,
1519            } => expr.span().union(&pattern.span()),
1520            Expr::ILike {
1521                negated: _,
1522                expr,
1523                pattern,
1524                escape_char: _,
1525                any: _,
1526            } => expr.span().union(&pattern.span()),
1527            Expr::RLike { .. } => Span::empty(),
1528            Expr::IsNormalized {
1529                expr,
1530                form: _,
1531                negated: _,
1532            } => expr.span(),
1533            Expr::SimilarTo {
1534                negated: _,
1535                expr,
1536                pattern,
1537                escape_char: _,
1538            } => expr.span().union(&pattern.span()),
1539            Expr::Ceil { expr, field: _ } => expr.span(),
1540            Expr::Floor { expr, field: _ } => expr.span(),
1541            Expr::Position { expr, r#in } => expr.span().union(&r#in.span()),
1542            Expr::Overlay {
1543                expr,
1544                overlay_what,
1545                overlay_from,
1546                overlay_for,
1547            } => expr
1548                .span()
1549                .union(&overlay_what.span())
1550                .union(&overlay_from.span())
1551                .union_opt(&overlay_for.as_ref().map(|i| i.span())),
1552            Expr::Collate { expr, collation } => expr
1553                .span()
1554                .union(&union_spans(collation.0.iter().map(|i| i.span()))),
1555            Expr::Nested(expr) => expr.span(),
1556            Expr::Value(value) => value.span(),
1557            Expr::TypedString(TypedString { value, .. }) => value.span(),
1558            Expr::Function(function) => function.span(),
1559            Expr::GroupingSets(vec) => {
1560                union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span())))
1561            }
1562            Expr::Cube(vec) => union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1563            Expr::Rollup(vec) => union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1564            Expr::Tuple(vec) => union_spans(vec.iter().map(|i| i.span())),
1565            Expr::Array(array) => array.span(),
1566            Expr::MatchAgainst { .. } => Span::empty(),
1567            Expr::JsonAccess { value, path } => value.span().union(&path.span()),
1568            Expr::AnyOp {
1569                left,
1570                compare_op: _,
1571                right,
1572                is_some: _,
1573            } => left.span().union(&right.span()),
1574            Expr::AllOp {
1575                left,
1576                compare_op: _,
1577                right,
1578            } => left.span().union(&right.span()),
1579            Expr::UnaryOp { op: _, expr } => expr.span(),
1580            Expr::Convert {
1581                expr,
1582                data_type: _,
1583                charset,
1584                target_before_value: _,
1585                styles,
1586                is_try: _,
1587            } => union_spans(
1588                core::iter::once(expr.span())
1589                    .chain(charset.as_ref().map(|i| i.span()))
1590                    .chain(styles.iter().map(|i| i.span())),
1591            ),
1592            Expr::Cast {
1593                kind: _,
1594                expr,
1595                data_type: _,
1596                array: _,
1597                format: _,
1598            } => expr.span(),
1599            Expr::AtTimeZone {
1600                timestamp,
1601                time_zone,
1602            } => timestamp.span().union(&time_zone.span()),
1603            Expr::Extract {
1604                field: _,
1605                syntax: _,
1606                expr,
1607            } => expr.span(),
1608            Expr::Substring {
1609                expr,
1610                substring_from,
1611                substring_for,
1612                special: _,
1613                shorthand: _,
1614            } => union_spans(
1615                core::iter::once(expr.span())
1616                    .chain(substring_from.as_ref().map(|i| i.span()))
1617                    .chain(substring_for.as_ref().map(|i| i.span())),
1618            ),
1619            Expr::Trim {
1620                expr,
1621                trim_where: _,
1622                trim_what,
1623                trim_characters,
1624            } => union_spans(
1625                core::iter::once(expr.span())
1626                    .chain(trim_what.as_ref().map(|i| i.span()))
1627                    .chain(
1628                        trim_characters
1629                            .as_ref()
1630                            .map(|items| union_spans(items.iter().map(|i| i.span()))),
1631                    ),
1632            ),
1633            Expr::Prefixed { value, .. } => value.span(),
1634            Expr::Case {
1635                case_token,
1636                end_token,
1637                operand,
1638                conditions,
1639                else_result,
1640            } => union_spans(
1641                iter::once(case_token.0.span)
1642                    .chain(
1643                        operand
1644                            .as_ref()
1645                            .map(|i| i.span())
1646                            .into_iter()
1647                            .chain(conditions.iter().flat_map(|case_when| {
1648                                [case_when.condition.span(), case_when.result.span()]
1649                            }))
1650                            .chain(else_result.as_ref().map(|i| i.span())),
1651                    )
1652                    .chain(iter::once(end_token.0.span)),
1653            ),
1654            Expr::Exists { subquery, .. } => subquery.span(),
1655            Expr::Subquery(query) => query.span(),
1656            Expr::Struct { .. } => Span::empty(),
1657            Expr::Named { .. } => Span::empty(),
1658            Expr::Dictionary(_) => Span::empty(),
1659            Expr::Map(_) => Span::empty(),
1660            Expr::Interval(interval) => interval.value.span(),
1661            Expr::Wildcard(token) => token.0.span,
1662            Expr::QualifiedWildcard(object_name, token) => union_spans(
1663                object_name
1664                    .0
1665                    .iter()
1666                    .map(|i| i.span())
1667                    .chain(iter::once(token.0.span)),
1668            ),
1669            Expr::OuterJoin(expr) => expr.span(),
1670            Expr::Prior(expr) => expr.span(),
1671            Expr::Lambda(_) => Span::empty(),
1672            Expr::MemberOf(member_of) => member_of.value.span().union(&member_of.array.span()),
1673        }
1674    }
1675}
1676
1677impl Spanned for Subscript {
1678    fn span(&self) -> Span {
1679        match self {
1680            Subscript::Index { index } => index.span(),
1681            Subscript::Slice {
1682                lower_bound,
1683                upper_bound,
1684                stride,
1685            } => union_spans(
1686                [
1687                    lower_bound.as_ref().map(|i| i.span()),
1688                    upper_bound.as_ref().map(|i| i.span()),
1689                    stride.as_ref().map(|i| i.span()),
1690                ]
1691                .into_iter()
1692                .flatten(),
1693            ),
1694        }
1695    }
1696}
1697
1698impl Spanned for AccessExpr {
1699    fn span(&self) -> Span {
1700        match self {
1701            AccessExpr::Dot(ident) => ident.span(),
1702            AccessExpr::Subscript(subscript) => subscript.span(),
1703        }
1704    }
1705}
1706
1707impl Spanned for ObjectName {
1708    fn span(&self) -> Span {
1709        let ObjectName(segments) = self;
1710
1711        union_spans(segments.iter().map(|i| i.span()))
1712    }
1713}
1714
1715impl Spanned for ObjectNamePart {
1716    fn span(&self) -> Span {
1717        match self {
1718            ObjectNamePart::Identifier(ident) => ident.span,
1719            ObjectNamePart::Function(func) => func
1720                .name
1721                .span
1722                .union(&union_spans(func.args.iter().map(|i| i.span()))),
1723        }
1724    }
1725}
1726
1727impl Spanned for Array {
1728    fn span(&self) -> Span {
1729        let Array {
1730            elem,
1731            named: _, // bool
1732        } = self;
1733
1734        union_spans(elem.iter().map(|i| i.span()))
1735    }
1736}
1737
1738impl Spanned for Function {
1739    fn span(&self) -> Span {
1740        let Function {
1741            name,
1742            uses_odbc_syntax: _,
1743            parameters,
1744            args,
1745            filter,
1746            null_treatment: _, // enum
1747            over: _,           // todo
1748            within_group,
1749        } = self;
1750
1751        union_spans(
1752            name.0
1753                .iter()
1754                .map(|i| i.span())
1755                .chain(iter::once(args.span()))
1756                .chain(iter::once(parameters.span()))
1757                .chain(filter.iter().map(|i| i.span()))
1758                .chain(within_group.iter().map(|i| i.span())),
1759        )
1760    }
1761}
1762
1763/// # partial span
1764///
1765/// The span of [FunctionArguments::None] is empty.
1766impl Spanned for FunctionArguments {
1767    fn span(&self) -> Span {
1768        match self {
1769            FunctionArguments::None => Span::empty(),
1770            FunctionArguments::Subquery(query) => query.span(),
1771            FunctionArguments::List(list) => list.span(),
1772        }
1773    }
1774}
1775
1776impl Spanned for FunctionArgumentList {
1777    fn span(&self) -> Span {
1778        let FunctionArgumentList {
1779            duplicate_treatment: _, // enum
1780            args,
1781            clauses,
1782        } = self;
1783
1784        union_spans(
1785            // # todo: duplicate-treatment span
1786            args.iter()
1787                .map(|i| i.span())
1788                .chain(clauses.iter().map(|i| i.span())),
1789        )
1790    }
1791}
1792
1793impl Spanned for FunctionArgumentClause {
1794    fn span(&self) -> Span {
1795        match self {
1796            FunctionArgumentClause::IgnoreOrRespectNulls(_) => Span::empty(),
1797            FunctionArgumentClause::OrderBy(vec) => union_spans(vec.iter().map(|i| i.expr.span())),
1798            FunctionArgumentClause::Limit(expr) => expr.span(),
1799            FunctionArgumentClause::OnOverflow(_) => Span::empty(),
1800            FunctionArgumentClause::Having(HavingBound(_kind, expr)) => expr.span(),
1801            FunctionArgumentClause::Separator(value) => value.span(),
1802            FunctionArgumentClause::JsonNullClause(_) => Span::empty(),
1803            FunctionArgumentClause::JsonReturningClause(_) => Span::empty(),
1804        }
1805    }
1806}
1807
1808/// # partial span
1809///
1810/// see Spanned impl for JsonPathElem for more information
1811impl Spanned for JsonPath {
1812    fn span(&self) -> Span {
1813        let JsonPath { path } = self;
1814
1815        union_spans(path.iter().map(|i| i.span()))
1816    }
1817}
1818
1819/// # partial span
1820///
1821/// Missing spans:
1822/// - [JsonPathElem::Dot]
1823impl Spanned for JsonPathElem {
1824    fn span(&self) -> Span {
1825        match self {
1826            JsonPathElem::Dot { .. } => Span::empty(),
1827            JsonPathElem::Bracket { key } => key.span(),
1828            JsonPathElem::ColonBracket { key } => key.span(),
1829        }
1830    }
1831}
1832
1833impl Spanned for SelectItemQualifiedWildcardKind {
1834    fn span(&self) -> Span {
1835        match self {
1836            SelectItemQualifiedWildcardKind::ObjectName(object_name) => object_name.span(),
1837            SelectItemQualifiedWildcardKind::Expr(expr) => expr.span(),
1838        }
1839    }
1840}
1841
1842impl Spanned for SelectItem {
1843    fn span(&self) -> Span {
1844        match self {
1845            SelectItem::UnnamedExpr(expr) => expr.span(),
1846            SelectItem::ExprWithAlias { expr, alias } => expr.span().union(&alias.span),
1847            SelectItem::ExprWithAliases { expr, aliases } => {
1848                union_spans(iter::once(expr.span()).chain(aliases.iter().map(|i| i.span)))
1849            }
1850            SelectItem::QualifiedWildcard(kind, wildcard_additional_options) => union_spans(
1851                [kind.span()]
1852                    .into_iter()
1853                    .chain(iter::once(wildcard_additional_options.span())),
1854            ),
1855            SelectItem::Wildcard(wildcard_additional_options) => wildcard_additional_options.span(),
1856        }
1857    }
1858}
1859
1860impl Spanned for WildcardAdditionalOptions {
1861    fn span(&self) -> Span {
1862        let WildcardAdditionalOptions {
1863            wildcard_token,
1864            opt_ilike,
1865            opt_exclude,
1866            opt_except,
1867            opt_replace,
1868            opt_rename,
1869            opt_alias,
1870        } = self;
1871
1872        union_spans(
1873            core::iter::once(wildcard_token.0.span)
1874                .chain(opt_ilike.as_ref().map(|i| i.span()))
1875                .chain(opt_exclude.as_ref().map(|i| i.span()))
1876                .chain(opt_rename.as_ref().map(|i| i.span()))
1877                .chain(opt_replace.as_ref().map(|i| i.span()))
1878                .chain(opt_except.as_ref().map(|i| i.span()))
1879                .chain(opt_alias.as_ref().map(|i| i.span)),
1880        )
1881    }
1882}
1883
1884/// # missing span
1885impl Spanned for IlikeSelectItem {
1886    fn span(&self) -> Span {
1887        Span::empty()
1888    }
1889}
1890
1891impl Spanned for ExcludeSelectItem {
1892    fn span(&self) -> Span {
1893        match self {
1894            ExcludeSelectItem::Single(name) => name.span(),
1895            ExcludeSelectItem::Multiple(vec) => union_spans(vec.iter().map(|i| i.span())),
1896        }
1897    }
1898}
1899
1900impl Spanned for RenameSelectItem {
1901    fn span(&self) -> Span {
1902        match self {
1903            RenameSelectItem::Single(ident) => ident.ident.span.union(&ident.alias.span),
1904            RenameSelectItem::Multiple(vec) => {
1905                union_spans(vec.iter().map(|i| i.ident.span.union(&i.alias.span)))
1906            }
1907        }
1908    }
1909}
1910
1911impl Spanned for ExceptSelectItem {
1912    fn span(&self) -> Span {
1913        let ExceptSelectItem {
1914            first_element,
1915            additional_elements,
1916        } = self;
1917
1918        union_spans(
1919            iter::once(first_element.span).chain(additional_elements.iter().map(|i| i.span)),
1920        )
1921    }
1922}
1923
1924impl Spanned for ReplaceSelectItem {
1925    fn span(&self) -> Span {
1926        let ReplaceSelectItem { items } = self;
1927
1928        union_spans(items.iter().map(|i| i.span()))
1929    }
1930}
1931
1932impl Spanned for ReplaceSelectElement {
1933    fn span(&self) -> Span {
1934        let ReplaceSelectElement {
1935            expr,
1936            column_name,
1937            as_keyword: _, // bool
1938        } = self;
1939
1940        expr.span().union(&column_name.span)
1941    }
1942}
1943
1944/// # partial span
1945///
1946/// Missing spans:
1947/// - [TableFactor::JsonTable]
1948impl Spanned for TableFactor {
1949    fn span(&self) -> Span {
1950        match self {
1951            TableFactor::Table {
1952                name,
1953                alias,
1954                args: _,
1955                with_hints: _,
1956                version: _,
1957                with_ordinality: _,
1958                partitions: _,
1959                json_path: _,
1960                sample: _,
1961                index_hints: _,
1962            } => union_spans(
1963                name.0
1964                    .iter()
1965                    .map(|i| i.span())
1966                    .chain(alias.as_ref().map(|alias| {
1967                        union_spans(
1968                            iter::once(alias.name.span)
1969                                .chain(alias.columns.iter().map(|i| i.span())),
1970                        )
1971                    })),
1972            ),
1973            TableFactor::Derived {
1974                lateral: _,
1975                subquery,
1976                alias,
1977                sample: _,
1978            } => subquery
1979                .span()
1980                .union_opt(&alias.as_ref().map(|alias| alias.span())),
1981            TableFactor::TableFunction { expr, alias } => expr
1982                .span()
1983                .union_opt(&alias.as_ref().map(|alias| alias.span())),
1984            TableFactor::UNNEST {
1985                alias,
1986                with_offset: _,
1987                with_offset_alias,
1988                array_exprs,
1989                with_ordinality: _,
1990            } => union_spans(
1991                alias
1992                    .iter()
1993                    .map(|i| i.span())
1994                    .chain(array_exprs.iter().map(|i| i.span()))
1995                    .chain(with_offset_alias.as_ref().map(|i| i.span)),
1996            ),
1997            TableFactor::NestedJoin {
1998                table_with_joins,
1999                alias,
2000            } => table_with_joins
2001                .span()
2002                .union_opt(&alias.as_ref().map(|alias| alias.span())),
2003            TableFactor::Function {
2004                lateral: _,
2005                name,
2006                args,
2007                with_ordinality: _,
2008                alias,
2009            } => union_spans(
2010                name.0
2011                    .iter()
2012                    .map(|i| i.span())
2013                    .chain(args.iter().map(|i| i.span()))
2014                    .chain(alias.as_ref().map(|alias| alias.span())),
2015            ),
2016            TableFactor::JsonTable { .. } => Span::empty(),
2017            TableFactor::XmlTable { .. } => Span::empty(),
2018            TableFactor::Pivot {
2019                table,
2020                aggregate_functions,
2021                value_column,
2022                value_source,
2023                default_on_null,
2024                alias,
2025            } => union_spans(
2026                core::iter::once(table.span())
2027                    .chain(aggregate_functions.iter().map(|i| i.span()))
2028                    .chain(value_column.iter().map(|i| i.span()))
2029                    .chain(core::iter::once(value_source.span()))
2030                    .chain(default_on_null.as_ref().map(|i| i.span()))
2031                    .chain(alias.as_ref().map(|i| i.span())),
2032            ),
2033            TableFactor::Unpivot {
2034                table,
2035                value,
2036                null_inclusion: _,
2037                name,
2038                columns,
2039                alias,
2040            } => union_spans(
2041                core::iter::once(table.span())
2042                    .chain(core::iter::once(value.span()))
2043                    .chain(core::iter::once(name.span))
2044                    .chain(columns.iter().map(|ilist| ilist.span()))
2045                    .chain(alias.as_ref().map(|alias| alias.span())),
2046            ),
2047            TableFactor::MatchRecognize {
2048                table,
2049                partition_by,
2050                order_by,
2051                measures,
2052                rows_per_match: _,
2053                after_match_skip: _,
2054                pattern,
2055                symbols,
2056                alias,
2057            } => union_spans(
2058                core::iter::once(table.span())
2059                    .chain(partition_by.iter().map(|i| i.span()))
2060                    .chain(order_by.iter().map(|i| i.span()))
2061                    .chain(measures.iter().map(|i| i.span()))
2062                    .chain(core::iter::once(pattern.span()))
2063                    .chain(symbols.iter().map(|i| i.span()))
2064                    .chain(alias.as_ref().map(|i| i.span())),
2065            ),
2066            TableFactor::SemanticView {
2067                name,
2068                dimensions,
2069                metrics,
2070                facts,
2071                where_clause,
2072                alias,
2073            } => union_spans(
2074                name.0
2075                    .iter()
2076                    .map(|i| i.span())
2077                    .chain(dimensions.iter().map(|d| d.span()))
2078                    .chain(metrics.iter().map(|m| m.span()))
2079                    .chain(facts.iter().map(|f| f.span()))
2080                    .chain(where_clause.as_ref().map(|e| e.span()))
2081                    .chain(alias.as_ref().map(|a| a.span())),
2082            ),
2083            TableFactor::OpenJsonTable { .. } => Span::empty(),
2084        }
2085    }
2086}
2087
2088impl Spanned for PivotValueSource {
2089    fn span(&self) -> Span {
2090        match self {
2091            PivotValueSource::List(vec) => union_spans(vec.iter().map(|i| i.span())),
2092            PivotValueSource::Any(vec) => union_spans(vec.iter().map(|i| i.span())),
2093            PivotValueSource::Subquery(query) => query.span(),
2094        }
2095    }
2096}
2097
2098impl Spanned for ExprWithAlias {
2099    fn span(&self) -> Span {
2100        let ExprWithAlias { expr, alias } = self;
2101
2102        expr.span().union_opt(&alias.as_ref().map(|i| i.span))
2103    }
2104}
2105
2106/// # missing span
2107impl Spanned for MatchRecognizePattern {
2108    fn span(&self) -> Span {
2109        Span::empty()
2110    }
2111}
2112
2113impl Spanned for SymbolDefinition {
2114    fn span(&self) -> Span {
2115        let SymbolDefinition { symbol, definition } = self;
2116
2117        symbol.span.union(&definition.span())
2118    }
2119}
2120
2121impl Spanned for Measure {
2122    fn span(&self) -> Span {
2123        let Measure { expr, alias } = self;
2124
2125        expr.span().union(&alias.span)
2126    }
2127}
2128
2129impl Spanned for OrderByExpr {
2130    fn span(&self) -> Span {
2131        let OrderByExpr {
2132            expr,
2133            options: _,
2134            with_fill,
2135        } = self;
2136
2137        expr.span().union_opt(&with_fill.as_ref().map(|f| f.span()))
2138    }
2139}
2140
2141impl Spanned for WithFill {
2142    fn span(&self) -> Span {
2143        let WithFill { from, to, step } = self;
2144
2145        union_spans(
2146            from.iter()
2147                .map(|f| f.span())
2148                .chain(to.iter().map(|t| t.span()))
2149                .chain(step.iter().map(|s| s.span())),
2150        )
2151    }
2152}
2153
2154impl Spanned for FunctionArg {
2155    fn span(&self) -> Span {
2156        match self {
2157            FunctionArg::Named {
2158                name,
2159                arg,
2160                operator: _,
2161            } => name.span.union(&arg.span()),
2162            FunctionArg::Unnamed(arg) => arg.span(),
2163            FunctionArg::ExprNamed {
2164                name,
2165                arg,
2166                operator: _,
2167            } => name.span().union(&arg.span()),
2168        }
2169    }
2170}
2171
2172/// # partial span
2173///
2174/// Missing spans:
2175/// - [FunctionArgExpr::Wildcard]
2176/// - [FunctionArgExpr::WildcardWithOptions]
2177impl Spanned for FunctionArgExpr {
2178    fn span(&self) -> Span {
2179        match self {
2180            FunctionArgExpr::Expr(expr) => expr.span(),
2181            FunctionArgExpr::QualifiedWildcard(object_name) => {
2182                union_spans(object_name.0.iter().map(|i| i.span()))
2183            }
2184            FunctionArgExpr::Wildcard => Span::empty(),
2185            FunctionArgExpr::WildcardWithOptions(_) => Span::empty(),
2186        }
2187    }
2188}
2189
2190impl Spanned for TableAlias {
2191    fn span(&self) -> Span {
2192        let TableAlias {
2193            explicit: _,
2194            name,
2195            columns,
2196            at,
2197        } = self;
2198        union_spans(
2199            core::iter::once(name.span)
2200                .chain(columns.iter().map(Spanned::span))
2201                .chain(at.iter().map(|at| at.span)),
2202        )
2203    }
2204}
2205
2206impl Spanned for TableAliasColumnDef {
2207    fn span(&self) -> Span {
2208        let TableAliasColumnDef { name, data_type: _ } = self;
2209
2210        name.span
2211    }
2212}
2213
2214impl Spanned for ValueWithSpan {
2215    fn span(&self) -> Span {
2216        self.span
2217    }
2218}
2219
2220impl Spanned for Join {
2221    fn span(&self) -> Span {
2222        let Join {
2223            relation,
2224            global: _, // bool
2225            join_operator,
2226        } = self;
2227
2228        relation.span().union(&join_operator.span())
2229    }
2230}
2231
2232/// # partial span
2233///
2234/// Missing spans:
2235/// - [JoinOperator::CrossJoin]
2236/// - [JoinOperator::CrossApply]
2237/// - [JoinOperator::OuterApply]
2238impl Spanned for JoinOperator {
2239    fn span(&self) -> Span {
2240        match self {
2241            JoinOperator::Join(join_constraint) => join_constraint.span(),
2242            JoinOperator::Inner(join_constraint) => join_constraint.span(),
2243            JoinOperator::Left(join_constraint) => join_constraint.span(),
2244            JoinOperator::LeftOuter(join_constraint) => join_constraint.span(),
2245            JoinOperator::Right(join_constraint) => join_constraint.span(),
2246            JoinOperator::RightOuter(join_constraint) => join_constraint.span(),
2247            JoinOperator::FullOuter(join_constraint) => join_constraint.span(),
2248            JoinOperator::CrossJoin(join_constraint) => join_constraint.span(),
2249            JoinOperator::LeftSemi(join_constraint) => join_constraint.span(),
2250            JoinOperator::RightSemi(join_constraint) => join_constraint.span(),
2251            JoinOperator::LeftAnti(join_constraint) => join_constraint.span(),
2252            JoinOperator::RightAnti(join_constraint) => join_constraint.span(),
2253            JoinOperator::CrossApply => Span::empty(),
2254            JoinOperator::OuterApply => Span::empty(),
2255            JoinOperator::AsOf {
2256                match_condition,
2257                constraint,
2258            } => match_condition.span().union(&constraint.span()),
2259            JoinOperator::Anti(join_constraint) => join_constraint.span(),
2260            JoinOperator::Semi(join_constraint) => join_constraint.span(),
2261            JoinOperator::StraightJoin(join_constraint) => join_constraint.span(),
2262            JoinOperator::ArrayJoin => Span::empty(),
2263            JoinOperator::LeftArrayJoin => Span::empty(),
2264            JoinOperator::InnerArrayJoin => Span::empty(),
2265        }
2266    }
2267}
2268
2269/// # partial span
2270///
2271/// Missing spans:
2272/// - [JoinConstraint::Natural]
2273/// - [JoinConstraint::None]
2274impl Spanned for JoinConstraint {
2275    fn span(&self) -> Span {
2276        match self {
2277            JoinConstraint::On(expr) => expr.span(),
2278            JoinConstraint::Using(vec) => union_spans(vec.iter().map(|i| i.span())),
2279            JoinConstraint::Natural => Span::empty(),
2280            JoinConstraint::None => Span::empty(),
2281        }
2282    }
2283}
2284
2285impl Spanned for TableWithJoins {
2286    fn span(&self) -> Span {
2287        let TableWithJoins { relation, joins } = self;
2288
2289        union_spans(core::iter::once(relation.span()).chain(joins.iter().map(|item| item.span())))
2290    }
2291}
2292
2293impl Spanned for Select {
2294    fn span(&self) -> Span {
2295        let Select {
2296            select_token,
2297            optimizer_hints: _,
2298            distinct: _, // todo
2299            select_modifiers: _,
2300            top: _, // todo, mysql specific
2301            projection,
2302            exclude: _,
2303            into,
2304            from,
2305            lateral_views,
2306            prewhere,
2307            selection,
2308            group_by,
2309            cluster_by,
2310            distribute_by,
2311            sort_by,
2312            having,
2313            named_window,
2314            qualify,
2315            window_before_qualify: _, // bool
2316            value_table_mode: _,      // todo, BigQuery specific
2317            connect_by,
2318            top_before_distinct: _,
2319            flavor: _,
2320        } = self;
2321
2322        union_spans(
2323            core::iter::once(select_token.0.span)
2324                .chain(projection.iter().map(|item| item.span()))
2325                .chain(into.iter().map(|item| item.span()))
2326                .chain(from.iter().map(|item| item.span()))
2327                .chain(lateral_views.iter().map(|item| item.span()))
2328                .chain(prewhere.iter().map(|item| item.span()))
2329                .chain(selection.iter().map(|item| item.span()))
2330                .chain(connect_by.iter().map(|item| item.span()))
2331                .chain(core::iter::once(group_by.span()))
2332                .chain(cluster_by.iter().map(|item| item.span()))
2333                .chain(distribute_by.iter().map(|item| item.span()))
2334                .chain(sort_by.iter().map(|item| item.span()))
2335                .chain(having.iter().map(|item| item.span()))
2336                .chain(named_window.iter().map(|item| item.span()))
2337                .chain(qualify.iter().map(|item| item.span())),
2338        )
2339    }
2340}
2341
2342impl Spanned for ConnectByKind {
2343    fn span(&self) -> Span {
2344        match self {
2345            ConnectByKind::ConnectBy {
2346                connect_token,
2347                nocycle: _,
2348                relationships,
2349            } => union_spans(
2350                core::iter::once(connect_token.0.span())
2351                    .chain(relationships.last().iter().map(|item| item.span())),
2352            ),
2353            ConnectByKind::StartWith {
2354                start_token,
2355                condition,
2356            } => union_spans([start_token.0.span(), condition.span()].into_iter()),
2357        }
2358    }
2359}
2360
2361impl Spanned for NamedWindowDefinition {
2362    fn span(&self) -> Span {
2363        let NamedWindowDefinition(
2364            ident,
2365            _, // todo: NamedWindowExpr
2366        ) = self;
2367
2368        ident.span
2369    }
2370}
2371
2372impl Spanned for LateralView {
2373    fn span(&self) -> Span {
2374        let LateralView {
2375            lateral_view,
2376            lateral_view_name,
2377            lateral_col_alias,
2378            outer: _, // bool
2379        } = self;
2380
2381        union_spans(
2382            core::iter::once(lateral_view.span())
2383                .chain(core::iter::once(lateral_view_name.span()))
2384                .chain(lateral_col_alias.iter().map(|i| i.span)),
2385        )
2386    }
2387}
2388
2389impl Spanned for SelectInto {
2390    fn span(&self) -> Span {
2391        let SelectInto {
2392            temporary: _, // bool
2393            unlogged: _,  // bool
2394            table: _,     // bool
2395            name,
2396        } = self;
2397
2398        name.span()
2399    }
2400}
2401
2402impl Spanned for UpdateTableFromKind {
2403    fn span(&self) -> Span {
2404        let from = match self {
2405            UpdateTableFromKind::BeforeSet(from) => from,
2406            UpdateTableFromKind::AfterSet(from) => from,
2407        };
2408        union_spans(from.iter().map(|t| t.span()))
2409    }
2410}
2411
2412impl Spanned for TableObject {
2413    fn span(&self) -> Span {
2414        match self {
2415            TableObject::TableName(ObjectName(segments)) => {
2416                union_spans(segments.iter().map(|i| i.span()))
2417            }
2418            TableObject::TableFunction(func) => func.span(),
2419            TableObject::TableQuery(query) => query.span(),
2420        }
2421    }
2422}
2423
2424impl Spanned for BeginEndStatements {
2425    fn span(&self) -> Span {
2426        let BeginEndStatements {
2427            begin_token,
2428            statements,
2429            end_token,
2430        } = self;
2431        union_spans(
2432            core::iter::once(begin_token.0.span)
2433                .chain(statements.iter().map(|i| i.span()))
2434                .chain(core::iter::once(end_token.0.span)),
2435        )
2436    }
2437}
2438
2439impl Spanned for OpenStatement {
2440    fn span(&self) -> Span {
2441        let OpenStatement { cursor_name } = self;
2442        cursor_name.span
2443    }
2444}
2445
2446impl Spanned for AlterSchemaOperation {
2447    fn span(&self) -> Span {
2448        match self {
2449            AlterSchemaOperation::SetDefaultCollate { collate } => collate.span(),
2450            AlterSchemaOperation::AddReplica { replica, options } => union_spans(
2451                core::iter::once(replica.span)
2452                    .chain(options.iter().flat_map(|i| i.iter().map(|i| i.span()))),
2453            ),
2454            AlterSchemaOperation::DropReplica { replica } => replica.span,
2455            AlterSchemaOperation::SetOptionsParens { options } => {
2456                union_spans(options.iter().map(|i| i.span()))
2457            }
2458            AlterSchemaOperation::Rename { name } => name.span(),
2459            AlterSchemaOperation::OwnerTo { owner } => {
2460                if let Owner::Ident(ident) = owner {
2461                    ident.span
2462                } else {
2463                    Span::empty()
2464                }
2465            }
2466        }
2467    }
2468}
2469
2470impl Spanned for AlterSchema {
2471    fn span(&self) -> Span {
2472        union_spans(
2473            core::iter::once(self.name.span()).chain(self.operations.iter().map(|i| i.span())),
2474        )
2475    }
2476}
2477
2478impl Spanned for CreateView {
2479    fn span(&self) -> Span {
2480        union_spans(
2481            core::iter::once(self.name.span())
2482                .chain(self.columns.iter().map(|i| i.span()))
2483                .chain(core::iter::once(self.query.span()))
2484                .chain(core::iter::once(self.options.span()))
2485                .chain(self.cluster_by.iter().map(|i| i.span))
2486                .chain(self.to.iter().map(|i| i.span())),
2487        )
2488    }
2489}
2490
2491impl Spanned for AlterTable {
2492    fn span(&self) -> Span {
2493        union_spans(
2494            core::iter::once(self.name.span())
2495                .chain(self.operations.iter().map(|i| i.span()))
2496                .chain(self.on_cluster.iter().map(|i| i.span))
2497                .chain(core::iter::once(self.end_token.0.span)),
2498        )
2499    }
2500}
2501
2502impl Spanned for CreateOperator {
2503    fn span(&self) -> Span {
2504        Span::empty()
2505    }
2506}
2507
2508impl Spanned for CreateOperatorFamily {
2509    fn span(&self) -> Span {
2510        Span::empty()
2511    }
2512}
2513
2514impl Spanned for CreateOperatorClass {
2515    fn span(&self) -> Span {
2516        Span::empty()
2517    }
2518}
2519
2520impl Spanned for MergeClause {
2521    fn span(&self) -> Span {
2522        union_spans([self.when_token.0.span, self.action.span()].into_iter())
2523    }
2524}
2525
2526impl Spanned for MergeAction {
2527    fn span(&self) -> Span {
2528        match self {
2529            MergeAction::Insert(expr) => expr.span(),
2530            MergeAction::Update(expr) => expr.span(),
2531            MergeAction::Delete { delete_token } => delete_token.0.span,
2532        }
2533    }
2534}
2535
2536impl Spanned for MergeInsertExpr {
2537    fn span(&self) -> Span {
2538        union_spans(
2539            [
2540                self.insert_token.0.span,
2541                self.kind_token.0.span,
2542                match self.kind {
2543                    MergeInsertKind::Values(ref values) => values.span(),
2544                    MergeInsertKind::Row | MergeInsertKind::Wildcard => Span::empty(),
2545                },
2546            ]
2547            .into_iter()
2548            .chain(self.insert_predicate.iter().map(Spanned::span))
2549            .chain(self.columns.iter().map(|i| i.span())),
2550        )
2551    }
2552}
2553
2554impl Spanned for MergeUpdateExpr {
2555    fn span(&self) -> Span {
2556        let kind_span = match &self.kind {
2557            MergeUpdateKind::Set(assignments) => union_spans(assignments.iter().map(Spanned::span)),
2558            MergeUpdateKind::Wildcard => Span::empty(),
2559        };
2560        union_spans(
2561            core::iter::once(self.update_token.0.span)
2562                .chain(core::iter::once(kind_span))
2563                .chain(self.update_predicate.iter().map(Spanned::span))
2564                .chain(self.delete_predicate.iter().map(Spanned::span)),
2565        )
2566    }
2567}
2568
2569impl Spanned for OutputClause {
2570    fn span(&self) -> Span {
2571        match self {
2572            OutputClause::Output {
2573                output_token,
2574                select_items,
2575                into_table,
2576            } => union_spans(
2577                core::iter::once(output_token.0.span)
2578                    .chain(into_table.iter().map(Spanned::span))
2579                    .chain(select_items.iter().map(Spanned::span)),
2580            ),
2581            OutputClause::Returning {
2582                returning_token,
2583                select_items,
2584            } => union_spans(
2585                core::iter::once(returning_token.0.span)
2586                    .chain(select_items.iter().map(Spanned::span)),
2587            ),
2588        }
2589    }
2590}
2591
2592impl Spanned for comments::CommentWithSpan {
2593    fn span(&self) -> Span {
2594        self.span
2595    }
2596}
2597
2598#[cfg(test)]
2599pub mod tests {
2600    use crate::ast::Value;
2601    use crate::dialect::{Dialect, GenericDialect, SnowflakeDialect};
2602    use crate::parser::Parser;
2603    use crate::tokenizer::{Location, Span};
2604
2605    use super::*;
2606
2607    struct SpanTest<'a>(Parser<'a>, &'a str);
2608
2609    impl<'a> SpanTest<'a> {
2610        fn new(dialect: &'a dyn Dialect, sql: &'a str) -> Self {
2611            Self(Parser::new(dialect).try_with_sql(sql).unwrap(), sql)
2612        }
2613
2614        // get the subsection of the source string that corresponds to the span
2615        // only works on single-line strings
2616        fn get_source(&self, span: Span) -> &'a str {
2617            // lines in spans are 1-indexed
2618            &self.1[(span.start.column as usize - 1)..(span.end.column - 1) as usize]
2619        }
2620    }
2621
2622    #[test]
2623    fn test_join() {
2624        let dialect = &GenericDialect;
2625        let mut test = SpanTest::new(
2626            dialect,
2627            "SELECT id, name FROM users LEFT JOIN companies ON users.company_id = companies.id",
2628        );
2629
2630        let query = test.0.parse_select().unwrap();
2631        let select_span = query.span();
2632
2633        assert_eq!(
2634            test.get_source(select_span),
2635            "SELECT id, name FROM users LEFT JOIN companies ON users.company_id = companies.id"
2636        );
2637
2638        let join_span = query.from[0].joins[0].span();
2639
2640        // 'LEFT JOIN' missing
2641        assert_eq!(
2642            test.get_source(join_span),
2643            "companies ON users.company_id = companies.id"
2644        );
2645    }
2646
2647    #[test]
2648    pub fn test_union() {
2649        let dialect = &GenericDialect;
2650        let mut test = SpanTest::new(
2651            dialect,
2652            "SELECT a FROM postgres.public.source UNION SELECT a FROM postgres.public.source",
2653        );
2654
2655        let query = test.0.parse_query().unwrap();
2656        let select_span = query.span();
2657
2658        assert_eq!(
2659            test.get_source(select_span),
2660            "SELECT a FROM postgres.public.source UNION SELECT a FROM postgres.public.source"
2661        );
2662    }
2663
2664    #[test]
2665    pub fn test_subquery() {
2666        let dialect = &GenericDialect;
2667        let mut test = SpanTest::new(
2668            dialect,
2669            "SELECT a FROM (SELECT a FROM postgres.public.source) AS b",
2670        );
2671
2672        let query = test.0.parse_select().unwrap();
2673        let select_span = query.span();
2674
2675        assert_eq!(
2676            test.get_source(select_span),
2677            "SELECT a FROM (SELECT a FROM postgres.public.source) AS b"
2678        );
2679
2680        let subquery_span = query.from[0].span();
2681
2682        // left paren missing
2683        assert_eq!(
2684            test.get_source(subquery_span),
2685            "SELECT a FROM postgres.public.source) AS b"
2686        );
2687    }
2688
2689    #[test]
2690    pub fn test_cte() {
2691        let dialect = &GenericDialect;
2692        let mut test = SpanTest::new(dialect, "WITH cte_outer AS (SELECT a FROM postgres.public.source), cte_ignored AS (SELECT a FROM cte_outer), cte_inner AS (SELECT a FROM cte_outer) SELECT a FROM cte_inner");
2693
2694        let query = test.0.parse_query().unwrap();
2695
2696        let select_span = query.span();
2697
2698        assert_eq!(test.get_source(select_span), "WITH cte_outer AS (SELECT a FROM postgres.public.source), cte_ignored AS (SELECT a FROM cte_outer), cte_inner AS (SELECT a FROM cte_outer) SELECT a FROM cte_inner");
2699    }
2700
2701    #[test]
2702    pub fn test_snowflake_lateral_flatten() {
2703        let dialect = &SnowflakeDialect;
2704        let mut test = SpanTest::new(dialect, "SELECT FLATTENED.VALUE:field::TEXT AS FIELD FROM SNOWFLAKE.SCHEMA.SOURCE AS S, LATERAL FLATTEN(INPUT => S.JSON_ARRAY) AS FLATTENED");
2705
2706        let query = test.0.parse_select().unwrap();
2707
2708        let select_span = query.span();
2709
2710        assert_eq!(test.get_source(select_span), "SELECT FLATTENED.VALUE:field::TEXT AS FIELD FROM SNOWFLAKE.SCHEMA.SOURCE AS S, LATERAL FLATTEN(INPUT => S.JSON_ARRAY) AS FLATTENED");
2711    }
2712
2713    #[test]
2714    pub fn test_wildcard_from_cte() {
2715        let dialect = &GenericDialect;
2716        let mut test = SpanTest::new(
2717            dialect,
2718            "WITH cte AS (SELECT a FROM postgres.public.source) SELECT cte.* FROM cte",
2719        );
2720
2721        let query = test.0.parse_query().unwrap();
2722        let cte_span = query.clone().with.unwrap().cte_tables[0].span();
2723        let cte_query_span = query.clone().with.unwrap().cte_tables[0].query.span();
2724        let body_span = query.body.span();
2725
2726        // the WITH keyboard is part of the query
2727        assert_eq!(
2728            test.get_source(cte_span),
2729            "cte AS (SELECT a FROM postgres.public.source)"
2730        );
2731        assert_eq!(
2732            test.get_source(cte_query_span),
2733            "SELECT a FROM postgres.public.source"
2734        );
2735
2736        assert_eq!(test.get_source(body_span), "SELECT cte.* FROM cte");
2737    }
2738
2739    #[test]
2740    fn test_case_expr_span() {
2741        let dialect = &GenericDialect;
2742        let mut test = SpanTest::new(dialect, "CASE 1 WHEN 2 THEN 3 ELSE 4 END");
2743        let expr = test.0.parse_expr().unwrap();
2744        let expr_span = expr.span();
2745        assert_eq!(
2746            test.get_source(expr_span),
2747            "CASE 1 WHEN 2 THEN 3 ELSE 4 END"
2748        );
2749    }
2750
2751    #[test]
2752    fn test_placeholder_span() {
2753        let sql = "\nSELECT\n  :fooBar";
2754        let r = Parser::parse_sql(&GenericDialect, sql).unwrap();
2755        assert_eq!(1, r.len());
2756        match &r[0] {
2757            Statement::Query(q) => {
2758                let col = &q.body.as_select().unwrap().projection[0];
2759                match col {
2760                    SelectItem::UnnamedExpr(Expr::Value(ValueWithSpan {
2761                        value: Value::Placeholder(s),
2762                        span,
2763                    })) => {
2764                        assert_eq!(":fooBar", s);
2765                        assert_eq!(&Span::new((3, 3).into(), (3, 10).into()), span);
2766                    }
2767                    _ => panic!("expected unnamed expression; got {col:?}"),
2768                }
2769            }
2770            stmt => panic!("expected query; got {stmt:?}"),
2771        }
2772    }
2773
2774    #[test]
2775    fn test_alter_table_multiline_span() {
2776        let sql = r#"-- foo
2777ALTER TABLE users
2778  ADD COLUMN foo
2779  varchar; -- hi there"#;
2780
2781        let r = Parser::parse_sql(&crate::dialect::PostgreSqlDialect {}, sql).unwrap();
2782        assert_eq!(1, r.len());
2783
2784        let stmt_span = r[0].span();
2785
2786        assert_eq!(stmt_span.start, (2, 13).into());
2787        assert_eq!(stmt_span.end, (4, 11).into());
2788    }
2789
2790    #[test]
2791    fn test_update_statement_span() {
2792        let sql = r#"-- foo
2793      UPDATE foo
2794   /* bar */
2795   SET bar = 3
2796 WHERE quux > 42 ;
2797"#;
2798
2799        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2800        assert_eq!(1, r.len());
2801
2802        let stmt_span = r[0].span();
2803
2804        assert_eq!(stmt_span.start, (2, 7).into());
2805        assert_eq!(stmt_span.end, (5, 17).into());
2806    }
2807
2808    #[test]
2809    fn test_insert_statement_span() {
2810        let sql = r#"
2811/* foo */ INSERT  INTO  FOO  (X, Y, Z)
2812  SELECT 1, 2, 3
2813  FROM DUAL
2814;"#;
2815
2816        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2817        assert_eq!(1, r.len());
2818
2819        let stmt_span = r[0].span();
2820
2821        assert_eq!(stmt_span.start, (2, 11).into());
2822        assert_eq!(stmt_span.end, (4, 12).into());
2823    }
2824
2825    #[test]
2826    fn test_replace_statement_span() {
2827        let sql = r#"
2828/* foo */ REPLACE INTO
2829    cities(name,population)
2830SELECT
2831    name,
2832    population
2833FROM
2834   cities
2835WHERE id = 1
2836;"#;
2837
2838        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2839        assert_eq!(1, r.len());
2840
2841        dbg!(&r[0]);
2842
2843        let stmt_span = r[0].span();
2844
2845        assert_eq!(stmt_span.start, (2, 11).into());
2846        assert_eq!(stmt_span.end, (9, 13).into());
2847    }
2848
2849    #[test]
2850    fn test_delete_statement_span() {
2851        let sql = r#"-- foo
2852      DELETE /* quux */
2853        FROM foo
2854       WHERE foo.x = 42
2855;"#;
2856
2857        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2858        assert_eq!(1, r.len());
2859
2860        let stmt_span = r[0].span();
2861
2862        assert_eq!(stmt_span.start, (2, 7).into());
2863        assert_eq!(stmt_span.end, (4, 24).into());
2864    }
2865
2866    #[test]
2867    fn test_merge_statement_spans() {
2868        let sql = r#"
2869        -- plain merge statement; no RETURNING, no OUTPUT
2870
2871        MERGE INTO target_table USING source_table
2872                ON target_table.id = source_table.oooid
2873
2874        /* an inline comment */ WHEN NOT MATCHED THEN
2875            INSERT (ID, description)
2876               VALUES (source_table.id, source_table.description)
2877
2878            -- another one
2879                WHEN MATCHED AND target_table.x = 'X' THEN
2880            UPDATE SET target_table.description = source_table.description
2881
2882              WHEN MATCHED AND target_table.x != 'X' THEN   DELETE
2883        WHEN NOT MATCHED AND 1 THEN INSERT (product, quantity) ROW
2884        "#;
2885
2886        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2887        assert_eq!(1, r.len());
2888
2889        // ~ assert the span of the whole statement
2890        let stmt_span = r[0].span();
2891        assert_eq!(stmt_span.start, (4, 9).into());
2892        assert_eq!(stmt_span.end, (16, 67).into());
2893
2894        // ~ individual tokens within the statement
2895        let Statement::Merge(Merge {
2896            merge_token,
2897            optimizer_hints: _,
2898            into: _,
2899            table: _,
2900            source: _,
2901            on: _,
2902            clauses,
2903            output,
2904        }) = &r[0]
2905        else {
2906            panic!("not a MERGE statement");
2907        };
2908        assert_eq!(
2909            merge_token.0.span,
2910            Span::new(Location::new(4, 9), Location::new(4, 14))
2911        );
2912        assert_eq!(clauses.len(), 4);
2913
2914        // ~ the INSERT clause's TOKENs
2915        assert_eq!(
2916            clauses[0].when_token.0.span,
2917            Span::new(Location::new(7, 33), Location::new(7, 37))
2918        );
2919        if let MergeAction::Insert(MergeInsertExpr {
2920            insert_token,
2921            kind_token,
2922            ..
2923        }) = &clauses[0].action
2924        {
2925            assert_eq!(
2926                insert_token.0.span,
2927                Span::new(Location::new(8, 13), Location::new(8, 19))
2928            );
2929            assert_eq!(
2930                kind_token.0.span,
2931                Span::new(Location::new(9, 16), Location::new(9, 22))
2932            );
2933        } else {
2934            panic!("not a MERGE INSERT clause");
2935        }
2936
2937        // ~ the UPDATE token(s)
2938        assert_eq!(
2939            clauses[1].when_token.0.span,
2940            Span::new(Location::new(12, 17), Location::new(12, 21))
2941        );
2942        if let MergeAction::Update(MergeUpdateExpr {
2943            update_token,
2944            kind: _,
2945            update_predicate: _,
2946            delete_predicate: _,
2947        }) = &clauses[1].action
2948        {
2949            assert_eq!(
2950                update_token.0.span,
2951                Span::new(Location::new(13, 13), Location::new(13, 19))
2952            );
2953        } else {
2954            panic!("not a MERGE UPDATE clause");
2955        }
2956
2957        // the DELETE token(s)
2958        assert_eq!(
2959            clauses[2].when_token.0.span,
2960            Span::new(Location::new(15, 15), Location::new(15, 19))
2961        );
2962        if let MergeAction::Delete { delete_token } = &clauses[2].action {
2963            assert_eq!(
2964                delete_token.0.span,
2965                Span::new(Location::new(15, 61), Location::new(15, 67))
2966            );
2967        } else {
2968            panic!("not a MERGE DELETE clause");
2969        }
2970
2971        // ~ an INSERT clause's ROW token
2972        assert_eq!(
2973            clauses[3].when_token.0.span,
2974            Span::new(Location::new(16, 9), Location::new(16, 13))
2975        );
2976        if let MergeAction::Insert(MergeInsertExpr {
2977            insert_token,
2978            kind_token,
2979            ..
2980        }) = &clauses[3].action
2981        {
2982            assert_eq!(
2983                insert_token.0.span,
2984                Span::new(Location::new(16, 37), Location::new(16, 43))
2985            );
2986            assert_eq!(
2987                kind_token.0.span,
2988                Span::new(Location::new(16, 64), Location::new(16, 67))
2989            );
2990        } else {
2991            panic!("not a MERGE INSERT clause");
2992        }
2993
2994        assert!(output.is_none());
2995    }
2996
2997    #[test]
2998    fn test_merge_statement_spans_with_returning() {
2999        let sql = r#"
3000    MERGE INTO wines AS w
3001    USING wine_stock_changes AS s
3002        ON s.winename = w.winename
3003    WHEN NOT MATCHED AND s.stock_delta > 0 THEN INSERT VALUES (s.winename, s.stock_delta)
3004    WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN UPDATE SET stock = w.stock + s.stock_delta
3005    WHEN MATCHED THEN DELETE
3006    RETURNING merge_action(), w.*
3007        "#;
3008
3009        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
3010        assert_eq!(1, r.len());
3011
3012        // ~ assert the span of the whole statement
3013        let stmt_span = r[0].span();
3014        assert_eq!(
3015            stmt_span,
3016            Span::new(Location::new(2, 5), Location::new(8, 34))
3017        );
3018
3019        // ~ individual tokens within the statement
3020        if let Statement::Merge(Merge { output, .. }) = &r[0] {
3021            if let Some(OutputClause::Returning {
3022                returning_token, ..
3023            }) = output
3024            {
3025                assert_eq!(
3026                    returning_token.0.span,
3027                    Span::new(Location::new(8, 5), Location::new(8, 14))
3028                );
3029            } else {
3030                panic!("unexpected MERGE output clause");
3031            }
3032        } else {
3033            panic!("not a MERGE statement");
3034        };
3035    }
3036
3037    #[test]
3038    fn test_merge_statement_spans_with_output() {
3039        let sql = r#"MERGE INTO a USING b ON a.id = b.id
3040        WHEN MATCHED THEN DELETE
3041              OUTPUT inserted.*"#;
3042
3043        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
3044        assert_eq!(1, r.len());
3045
3046        // ~ assert the span of the whole statement
3047        let stmt_span = r[0].span();
3048        assert_eq!(
3049            stmt_span,
3050            Span::new(Location::new(1, 1), Location::new(3, 32))
3051        );
3052
3053        // ~ individual tokens within the statement
3054        if let Statement::Merge(Merge { output, .. }) = &r[0] {
3055            if let Some(OutputClause::Output { output_token, .. }) = output {
3056                assert_eq!(
3057                    output_token.0.span,
3058                    Span::new(Location::new(3, 15), Location::new(3, 21))
3059                );
3060            } else {
3061                panic!("unexpected MERGE output clause");
3062            }
3063        } else {
3064            panic!("not a MERGE statement");
3065        };
3066    }
3067
3068    #[test]
3069    fn test_merge_statement_spans_with_update_predicates() {
3070        let sql = r#"
3071       MERGE INTO a USING b ON a.id = b.id
3072        WHEN MATCHED THEN
3073              UPDATE set a.x = a.x + b.x
3074               WHERE b.x != 2
3075              DELETE WHERE a.x <> 3"#;
3076
3077        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
3078        assert_eq!(1, r.len());
3079
3080        // ~ assert the span of the whole statement
3081        let stmt_span = r[0].span();
3082        assert_eq!(
3083            stmt_span,
3084            Span::new(Location::new(2, 8), Location::new(6, 36))
3085        );
3086    }
3087
3088    #[test]
3089    fn test_merge_statement_spans_with_insert_predicate() {
3090        let sql = r#"
3091       MERGE INTO a USING b ON a.id = b.id
3092        WHEN NOT MATCHED THEN
3093            INSERT VALUES (b.x, b.y) WHERE b.x != 2
3094-- qed
3095"#;
3096
3097        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
3098        assert_eq!(1, r.len());
3099
3100        // ~ assert the span of the whole statement
3101        let stmt_span = r[0].span();
3102        assert_eq!(
3103            stmt_span,
3104            Span::new(Location::new(2, 8), Location::new(4, 52))
3105        );
3106    }
3107}