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