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        }
650    }
651}
652
653impl Spanned for CreateIndex {
654    fn span(&self) -> Span {
655        let CreateIndex {
656            name,
657            table_name,
658            using: _,
659            columns,
660            unique: _,        // bool
661            concurrently: _,  // bool
662            if_not_exists: _, // bool
663            include,
664            nulls_distinct: _, // bool
665            with,
666            predicate,
667            index_options: _,
668            alter_options,
669        } = self;
670
671        union_spans(
672            name.iter()
673                .map(|i| i.span())
674                .chain(core::iter::once(table_name.span()))
675                .chain(columns.iter().map(|i| i.column.span()))
676                .chain(include.iter().map(|i| i.span))
677                .chain(with.iter().map(|i| i.span()))
678                .chain(predicate.iter().map(|i| i.span()))
679                .chain(alter_options.iter().map(|i| i.span())),
680        )
681    }
682}
683
684impl Spanned for IndexColumn {
685    fn span(&self) -> Span {
686        self.column.span()
687    }
688}
689
690impl Spanned for CaseStatement {
691    fn span(&self) -> Span {
692        let CaseStatement {
693            case_token: AttachedToken(start),
694            match_expr: _,
695            when_blocks: _,
696            else_block: _,
697            end_case_token: AttachedToken(end),
698        } = self;
699
700        union_spans([start.span, end.span].into_iter())
701    }
702}
703
704impl Spanned for IfStatement {
705    fn span(&self) -> Span {
706        let IfStatement {
707            if_block,
708            elseif_blocks,
709            else_block,
710            end_token,
711        } = self;
712
713        union_spans(
714            iter::once(if_block.span())
715                .chain(elseif_blocks.iter().map(|b| b.span()))
716                .chain(else_block.as_ref().map(|b| b.span()))
717                .chain(end_token.as_ref().map(|AttachedToken(t)| t.span)),
718        )
719    }
720}
721
722impl Spanned for WhileStatement {
723    fn span(&self) -> Span {
724        let WhileStatement { while_block } = self;
725
726        while_block.span()
727    }
728}
729
730impl Spanned for ConditionalStatements {
731    fn span(&self) -> Span {
732        match self {
733            ConditionalStatements::Sequence { statements } => {
734                union_spans(statements.iter().map(|s| s.span()))
735            }
736            ConditionalStatements::BeginEnd(bes) => bes.span(),
737        }
738    }
739}
740
741impl Spanned for ConditionalStatementBlock {
742    fn span(&self) -> Span {
743        let ConditionalStatementBlock {
744            start_token: AttachedToken(start_token),
745            condition,
746            then_token,
747            conditional_statements,
748        } = self;
749
750        union_spans(
751            iter::once(start_token.span)
752                .chain(condition.as_ref().map(|c| c.span()))
753                .chain(then_token.as_ref().map(|AttachedToken(t)| t.span))
754                .chain(iter::once(conditional_statements.span())),
755        )
756    }
757}
758
759impl Spanned for RaiseStatement {
760    fn span(&self) -> Span {
761        let RaiseStatement { value } = self;
762
763        union_spans(value.iter().map(|value| value.span()))
764    }
765}
766
767impl Spanned for RaiseStatementValue {
768    fn span(&self) -> Span {
769        match self {
770            RaiseStatementValue::UsingMessage(expr) => expr.span(),
771            RaiseStatementValue::Expr(expr) => expr.span(),
772        }
773    }
774}
775
776/// # partial span
777///
778/// Missing spans:
779/// - [ColumnOption::Null]
780/// - [ColumnOption::NotNull]
781/// - [ColumnOption::Comment]
782/// - [ColumnOption::PrimaryKey]
783/// - [ColumnOption::Unique]
784/// - [ColumnOption::DialectSpecific]
785/// - [ColumnOption::Generated]
786impl Spanned for ColumnOption {
787    fn span(&self) -> Span {
788        match self {
789            ColumnOption::Null => Span::empty(),
790            ColumnOption::NotNull => Span::empty(),
791            ColumnOption::Default(expr) => expr.span(),
792            ColumnOption::Materialized(expr) => expr.span(),
793            ColumnOption::Ephemeral(expr) => expr.as_ref().map_or(Span::empty(), |e| e.span()),
794            ColumnOption::Alias(expr) => expr.span(),
795            ColumnOption::PrimaryKey(constraint) => constraint.span(),
796            ColumnOption::Unique(constraint) => constraint.span(),
797            ColumnOption::Check(constraint) => constraint.span(),
798            ColumnOption::ForeignKey(constraint) => constraint.span(),
799            ColumnOption::DialectSpecific(_) => Span::empty(),
800            ColumnOption::CharacterSet(object_name) => object_name.span(),
801            ColumnOption::Collation(object_name) => object_name.span(),
802            ColumnOption::Comment(_) => Span::empty(),
803            ColumnOption::OnUpdate(expr) => expr.span(),
804            ColumnOption::Generated { .. } => Span::empty(),
805            ColumnOption::Options(vec) => union_spans(vec.iter().map(|i| i.span())),
806            ColumnOption::Identity(..) => Span::empty(),
807            ColumnOption::OnConflict(..) => Span::empty(),
808            ColumnOption::Policy(..) => Span::empty(),
809            ColumnOption::Tags(..) => Span::empty(),
810            ColumnOption::Srid(..) => Span::empty(),
811            ColumnOption::Invisible => Span::empty(),
812        }
813    }
814}
815
816/// # missing span
817impl Spanned for ReferentialAction {
818    fn span(&self) -> Span {
819        Span::empty()
820    }
821}
822
823/// # missing span
824impl Spanned for ConstraintCharacteristics {
825    fn span(&self) -> Span {
826        let ConstraintCharacteristics {
827            deferrable: _, // bool
828            initially: _,  // enum
829            enforced: _,   // bool
830        } = self;
831
832        Span::empty()
833    }
834}
835
836impl Spanned for Analyze {
837    fn span(&self) -> Span {
838        union_spans(
839            core::iter::once(self.table_name.span())
840                .chain(
841                    self.partitions
842                        .iter()
843                        .flat_map(|i| i.iter().map(|k| k.span())),
844                )
845                .chain(self.columns.iter().map(|i| i.span)),
846        )
847    }
848}
849
850/// # partial span
851///
852/// Missing spans:
853/// - [AlterColumnOperation::SetNotNull]
854/// - [AlterColumnOperation::DropNotNull]
855/// - [AlterColumnOperation::DropDefault]
856/// - [AlterColumnOperation::AddGenerated]
857impl Spanned for AlterColumnOperation {
858    fn span(&self) -> Span {
859        match self {
860            AlterColumnOperation::SetNotNull => Span::empty(),
861            AlterColumnOperation::DropNotNull => Span::empty(),
862            AlterColumnOperation::SetDefault { value } => value.span(),
863            AlterColumnOperation::DropDefault => Span::empty(),
864            AlterColumnOperation::SetDataType {
865                data_type: _,
866                using,
867                had_set: _,
868            } => using.as_ref().map_or(Span::empty(), |u| u.span()),
869            AlterColumnOperation::AddGenerated { .. } => Span::empty(),
870        }
871    }
872}
873
874impl Spanned for CopySource {
875    fn span(&self) -> Span {
876        match self {
877            CopySource::Table {
878                table_name,
879                columns,
880            } => union_spans(
881                core::iter::once(table_name.span()).chain(columns.iter().map(|i| i.span)),
882            ),
883            CopySource::Query(query) => query.span(),
884        }
885    }
886}
887
888impl Spanned for Delete {
889    fn span(&self) -> Span {
890        let Delete {
891            delete_token,
892            tables,
893            from,
894            using,
895            selection,
896            returning,
897            order_by,
898            limit,
899        } = self;
900
901        union_spans(
902            core::iter::once(delete_token.0.span).chain(
903                tables
904                    .iter()
905                    .map(|i| i.span())
906                    .chain(core::iter::once(from.span()))
907                    .chain(
908                        using
909                            .iter()
910                            .map(|u| union_spans(u.iter().map(|i| i.span()))),
911                    )
912                    .chain(selection.iter().map(|i| i.span()))
913                    .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span())))
914                    .chain(order_by.iter().map(|i| i.span()))
915                    .chain(limit.iter().map(|i| i.span())),
916            ),
917        )
918    }
919}
920
921impl Spanned for Update {
922    fn span(&self) -> Span {
923        let Update {
924            update_token,
925            table,
926            assignments,
927            from,
928            selection,
929            returning,
930            or: _,
931            limit,
932        } = self;
933
934        union_spans(
935            core::iter::once(table.span())
936                .chain(core::iter::once(update_token.0.span))
937                .chain(assignments.iter().map(|i| i.span()))
938                .chain(from.iter().map(|i| i.span()))
939                .chain(selection.iter().map(|i| i.span()))
940                .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span())))
941                .chain(limit.iter().map(|i| i.span())),
942        )
943    }
944}
945
946impl Spanned for Merge {
947    fn span(&self) -> Span {
948        union_spans(
949            [self.merge_token.0.span, self.on.span()]
950                .into_iter()
951                .chain(self.clauses.iter().map(Spanned::span))
952                .chain(self.output.iter().map(Spanned::span)),
953        )
954    }
955}
956
957impl Spanned for FromTable {
958    fn span(&self) -> Span {
959        match self {
960            FromTable::WithFromKeyword(vec) => union_spans(vec.iter().map(|i| i.span())),
961            FromTable::WithoutKeyword(vec) => union_spans(vec.iter().map(|i| i.span())),
962        }
963    }
964}
965
966impl Spanned for ViewColumnDef {
967    fn span(&self) -> Span {
968        let ViewColumnDef {
969            name,
970            data_type: _, // todo, DataType
971            options,
972        } = self;
973
974        name.span.union_opt(&options.as_ref().map(|o| o.span()))
975    }
976}
977
978impl Spanned for ColumnOptions {
979    fn span(&self) -> Span {
980        union_spans(self.as_slice().iter().map(|i| i.span()))
981    }
982}
983
984impl Spanned for SqlOption {
985    fn span(&self) -> Span {
986        match self {
987            SqlOption::Clustered(table_options_clustered) => table_options_clustered.span(),
988            SqlOption::Ident(ident) => ident.span,
989            SqlOption::KeyValue { key, value } => key.span.union(&value.span()),
990            SqlOption::Partition {
991                column_name,
992                range_direction: _,
993                for_values,
994            } => union_spans(
995                core::iter::once(column_name.span).chain(for_values.iter().map(|i| i.span())),
996            ),
997            SqlOption::TableSpace(_) => Span::empty(),
998            SqlOption::Comment(_) => Span::empty(),
999            SqlOption::NamedParenthesizedList(NamedParenthesizedList {
1000                key: name,
1001                name: value,
1002                values,
1003            }) => union_spans(core::iter::once(name.span).chain(values.iter().map(|i| i.span)))
1004                .union_opt(&value.as_ref().map(|i| i.span)),
1005        }
1006    }
1007}
1008
1009/// # partial span
1010///
1011/// Missing spans:
1012/// - [TableOptionsClustered::ColumnstoreIndex]
1013impl Spanned for TableOptionsClustered {
1014    fn span(&self) -> Span {
1015        match self {
1016            TableOptionsClustered::ColumnstoreIndex => Span::empty(),
1017            TableOptionsClustered::ColumnstoreIndexOrder(vec) => {
1018                union_spans(vec.iter().map(|i| i.span))
1019            }
1020            TableOptionsClustered::Index(vec) => union_spans(vec.iter().map(|i| i.span())),
1021        }
1022    }
1023}
1024
1025impl Spanned for ClusteredIndex {
1026    fn span(&self) -> Span {
1027        let ClusteredIndex {
1028            name,
1029            asc: _, // bool
1030        } = self;
1031
1032        name.span
1033    }
1034}
1035
1036impl Spanned for CreateTableOptions {
1037    fn span(&self) -> Span {
1038        match self {
1039            CreateTableOptions::None => Span::empty(),
1040            CreateTableOptions::With(vec) => union_spans(vec.iter().map(|i| i.span())),
1041            CreateTableOptions::Options(vec) => {
1042                union_spans(vec.as_slice().iter().map(|i| i.span()))
1043            }
1044            CreateTableOptions::Plain(vec) => union_spans(vec.iter().map(|i| i.span())),
1045            CreateTableOptions::TableProperties(vec) => union_spans(vec.iter().map(|i| i.span())),
1046        }
1047    }
1048}
1049
1050/// # partial span
1051///
1052/// Missing spans:
1053/// - [AlterTableOperation::OwnerTo]
1054impl Spanned for AlterTableOperation {
1055    fn span(&self) -> Span {
1056        match self {
1057            AlterTableOperation::AddConstraint {
1058                constraint,
1059                not_valid: _,
1060            } => constraint.span(),
1061            AlterTableOperation::AddColumn {
1062                column_keyword: _,
1063                if_not_exists: _,
1064                column_def,
1065                column_position: _,
1066            } => column_def.span(),
1067            AlterTableOperation::AddProjection {
1068                if_not_exists: _,
1069                name,
1070                select,
1071            } => name.span.union(&select.span()),
1072            AlterTableOperation::DropProjection { if_exists: _, name } => name.span,
1073            AlterTableOperation::MaterializeProjection {
1074                if_exists: _,
1075                name,
1076                partition,
1077            } => name.span.union_opt(&partition.as_ref().map(|i| i.span)),
1078            AlterTableOperation::ClearProjection {
1079                if_exists: _,
1080                name,
1081                partition,
1082            } => name.span.union_opt(&partition.as_ref().map(|i| i.span)),
1083            AlterTableOperation::DisableRowLevelSecurity => Span::empty(),
1084            AlterTableOperation::DisableRule { name } => name.span,
1085            AlterTableOperation::DisableTrigger { name } => name.span,
1086            AlterTableOperation::DropConstraint {
1087                if_exists: _,
1088                name,
1089                drop_behavior: _,
1090            } => name.span,
1091            AlterTableOperation::DropColumn {
1092                has_column_keyword: _,
1093                column_names,
1094                if_exists: _,
1095                drop_behavior: _,
1096            } => union_spans(column_names.iter().map(|i| i.span)),
1097            AlterTableOperation::AttachPartition { partition } => partition.span(),
1098            AlterTableOperation::DetachPartition { partition } => partition.span(),
1099            AlterTableOperation::FreezePartition {
1100                partition,
1101                with_name,
1102            } => partition
1103                .span()
1104                .union_opt(&with_name.as_ref().map(|n| n.span)),
1105            AlterTableOperation::UnfreezePartition {
1106                partition,
1107                with_name,
1108            } => partition
1109                .span()
1110                .union_opt(&with_name.as_ref().map(|n| n.span)),
1111            AlterTableOperation::DropPrimaryKey { .. } => Span::empty(),
1112            AlterTableOperation::DropForeignKey { name, .. } => name.span,
1113            AlterTableOperation::DropIndex { name } => name.span,
1114            AlterTableOperation::EnableAlwaysRule { name } => name.span,
1115            AlterTableOperation::EnableAlwaysTrigger { name } => name.span,
1116            AlterTableOperation::EnableReplicaRule { name } => name.span,
1117            AlterTableOperation::EnableReplicaTrigger { name } => name.span,
1118            AlterTableOperation::EnableRowLevelSecurity => Span::empty(),
1119            AlterTableOperation::EnableRule { name } => name.span,
1120            AlterTableOperation::EnableTrigger { name } => name.span,
1121            AlterTableOperation::RenamePartitions {
1122                old_partitions,
1123                new_partitions,
1124            } => union_spans(
1125                old_partitions
1126                    .iter()
1127                    .map(|i| i.span())
1128                    .chain(new_partitions.iter().map(|i| i.span())),
1129            ),
1130            AlterTableOperation::AddPartitions {
1131                if_not_exists: _,
1132                new_partitions,
1133            } => union_spans(new_partitions.iter().map(|i| i.span())),
1134            AlterTableOperation::DropPartitions {
1135                partitions,
1136                if_exists: _,
1137            } => union_spans(partitions.iter().map(|i| i.span())),
1138            AlterTableOperation::RenameColumn {
1139                old_column_name,
1140                new_column_name,
1141            } => old_column_name.span.union(&new_column_name.span),
1142            AlterTableOperation::RenameTable { table_name } => table_name.span(),
1143            AlterTableOperation::ChangeColumn {
1144                old_name,
1145                new_name,
1146                data_type: _,
1147                options,
1148                column_position: _,
1149            } => union_spans(
1150                core::iter::once(old_name.span)
1151                    .chain(core::iter::once(new_name.span))
1152                    .chain(options.iter().map(|i| i.span())),
1153            ),
1154            AlterTableOperation::ModifyColumn {
1155                col_name,
1156                data_type: _,
1157                options,
1158                column_position: _,
1159            } => {
1160                union_spans(core::iter::once(col_name.span).chain(options.iter().map(|i| i.span())))
1161            }
1162            AlterTableOperation::RenameConstraint { old_name, new_name } => {
1163                old_name.span.union(&new_name.span)
1164            }
1165            AlterTableOperation::AlterColumn { column_name, op } => {
1166                column_name.span.union(&op.span())
1167            }
1168            AlterTableOperation::SwapWith { table_name } => table_name.span(),
1169            AlterTableOperation::SetTblProperties { table_properties } => {
1170                union_spans(table_properties.iter().map(|i| i.span()))
1171            }
1172            AlterTableOperation::OwnerTo { .. } => Span::empty(),
1173            AlterTableOperation::ClusterBy { exprs } => union_spans(exprs.iter().map(|e| e.span())),
1174            AlterTableOperation::DropClusteringKey => Span::empty(),
1175            AlterTableOperation::SuspendRecluster => Span::empty(),
1176            AlterTableOperation::ResumeRecluster => Span::empty(),
1177            AlterTableOperation::Refresh => Span::empty(),
1178            AlterTableOperation::Suspend => Span::empty(),
1179            AlterTableOperation::Resume => Span::empty(),
1180            AlterTableOperation::Algorithm { .. } => Span::empty(),
1181            AlterTableOperation::AutoIncrement { value, .. } => value.span(),
1182            AlterTableOperation::Lock { .. } => Span::empty(),
1183            AlterTableOperation::ReplicaIdentity { .. } => Span::empty(),
1184            AlterTableOperation::ValidateConstraint { name } => name.span,
1185            AlterTableOperation::SetOptionsParens { options } => {
1186                union_spans(options.iter().map(|i| i.span()))
1187            }
1188        }
1189    }
1190}
1191
1192impl Spanned for Partition {
1193    fn span(&self) -> Span {
1194        match self {
1195            Partition::Identifier(ident) => ident.span,
1196            Partition::Expr(expr) => expr.span(),
1197            Partition::Part(expr) => expr.span(),
1198            Partition::Partitions(vec) => union_spans(vec.iter().map(|i| i.span())),
1199        }
1200    }
1201}
1202
1203impl Spanned for ProjectionSelect {
1204    fn span(&self) -> Span {
1205        let ProjectionSelect {
1206            projection,
1207            order_by,
1208            group_by,
1209        } = self;
1210
1211        union_spans(
1212            projection
1213                .iter()
1214                .map(|i| i.span())
1215                .chain(order_by.iter().map(|i| i.span()))
1216                .chain(group_by.iter().map(|i| i.span())),
1217        )
1218    }
1219}
1220
1221/// # partial span
1222///
1223/// Missing spans:
1224/// - [OrderByKind::All]
1225impl Spanned for OrderBy {
1226    fn span(&self) -> Span {
1227        match &self.kind {
1228            OrderByKind::All(_) => Span::empty(),
1229            OrderByKind::Expressions(exprs) => union_spans(
1230                exprs
1231                    .iter()
1232                    .map(|i| i.span())
1233                    .chain(self.interpolate.iter().map(|i| i.span())),
1234            ),
1235        }
1236    }
1237}
1238
1239/// # partial span
1240///
1241/// Missing spans:
1242/// - [GroupByExpr::All]
1243impl Spanned for GroupByExpr {
1244    fn span(&self) -> Span {
1245        match self {
1246            GroupByExpr::All(_) => Span::empty(),
1247            GroupByExpr::Expressions(exprs, _modifiers) => {
1248                union_spans(exprs.iter().map(|i| i.span()))
1249            }
1250        }
1251    }
1252}
1253
1254impl Spanned for Interpolate {
1255    fn span(&self) -> Span {
1256        let Interpolate { exprs } = self;
1257
1258        union_spans(exprs.iter().flat_map(|i| i.iter().map(|e| e.span())))
1259    }
1260}
1261
1262impl Spanned for InterpolateExpr {
1263    fn span(&self) -> Span {
1264        let InterpolateExpr { column, expr } = self;
1265
1266        column.span.union_opt(&expr.as_ref().map(|e| e.span()))
1267    }
1268}
1269
1270impl Spanned for AlterIndexOperation {
1271    fn span(&self) -> Span {
1272        match self {
1273            AlterIndexOperation::RenameIndex { index_name } => index_name.span(),
1274        }
1275    }
1276}
1277
1278/// # partial span
1279///
1280/// Missing spans:ever
1281/// - [Insert::insert_alias]
1282impl Spanned for Insert {
1283    fn span(&self) -> Span {
1284        let Insert {
1285            insert_token,
1286            or: _,     // enum, sqlite specific
1287            ignore: _, // bool
1288            into: _,   // bool
1289            table,
1290            table_alias,
1291            columns,
1292            overwrite: _, // bool
1293            source,
1294            partitioned,
1295            after_columns,
1296            has_table_keyword: _, // bool
1297            on,
1298            returning,
1299            replace_into: _, // bool
1300            priority: _,     // todo, mysql specific
1301            insert_alias: _, // todo, mysql specific
1302            assignments,
1303            settings: _,      // todo, clickhouse specific
1304            format_clause: _, // todo, clickhouse specific
1305        } = self;
1306
1307        union_spans(
1308            core::iter::once(insert_token.0.span)
1309                .chain(core::iter::once(table.span()))
1310                .chain(table_alias.as_ref().map(|i| i.span))
1311                .chain(columns.iter().map(|i| i.span))
1312                .chain(source.as_ref().map(|q| q.span()))
1313                .chain(assignments.iter().map(|i| i.span()))
1314                .chain(partitioned.iter().flat_map(|i| i.iter().map(|k| k.span())))
1315                .chain(after_columns.iter().map(|i| i.span))
1316                .chain(on.as_ref().map(|i| i.span()))
1317                .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1318        )
1319    }
1320}
1321
1322impl Spanned for OnInsert {
1323    fn span(&self) -> Span {
1324        match self {
1325            OnInsert::DuplicateKeyUpdate(vec) => union_spans(vec.iter().map(|i| i.span())),
1326            OnInsert::OnConflict(on_conflict) => on_conflict.span(),
1327        }
1328    }
1329}
1330
1331impl Spanned for OnConflict {
1332    fn span(&self) -> Span {
1333        let OnConflict {
1334            conflict_target,
1335            action,
1336        } = self;
1337
1338        action
1339            .span()
1340            .union_opt(&conflict_target.as_ref().map(|i| i.span()))
1341    }
1342}
1343
1344impl Spanned for ConflictTarget {
1345    fn span(&self) -> Span {
1346        match self {
1347            ConflictTarget::Columns(vec) => union_spans(vec.iter().map(|i| i.span)),
1348            ConflictTarget::OnConstraint(object_name) => object_name.span(),
1349        }
1350    }
1351}
1352
1353/// # partial span
1354///
1355/// Missing spans:
1356/// - [OnConflictAction::DoNothing]
1357impl Spanned for OnConflictAction {
1358    fn span(&self) -> Span {
1359        match self {
1360            OnConflictAction::DoNothing => Span::empty(),
1361            OnConflictAction::DoUpdate(do_update) => do_update.span(),
1362        }
1363    }
1364}
1365
1366impl Spanned for DoUpdate {
1367    fn span(&self) -> Span {
1368        let DoUpdate {
1369            assignments,
1370            selection,
1371        } = self;
1372
1373        union_spans(
1374            assignments
1375                .iter()
1376                .map(|i| i.span())
1377                .chain(selection.iter().map(|i| i.span())),
1378        )
1379    }
1380}
1381
1382impl Spanned for Assignment {
1383    fn span(&self) -> Span {
1384        let Assignment { target, value } = self;
1385
1386        target.span().union(&value.span())
1387    }
1388}
1389
1390impl Spanned for AssignmentTarget {
1391    fn span(&self) -> Span {
1392        match self {
1393            AssignmentTarget::ColumnName(object_name) => object_name.span(),
1394            AssignmentTarget::Tuple(vec) => union_spans(vec.iter().map(|i| i.span())),
1395        }
1396    }
1397}
1398
1399/// # partial span
1400///
1401/// Most expressions are missing keywords in their spans.
1402/// f.e. `IS NULL <expr>` reports as `<expr>::span`.
1403///
1404/// Missing spans:
1405/// - [Expr::MatchAgainst] # MySQL specific
1406/// - [Expr::RLike] # MySQL specific
1407/// - [Expr::Struct] # BigQuery specific
1408/// - [Expr::Named] # BigQuery specific
1409/// - [Expr::Dictionary] # DuckDB specific
1410/// - [Expr::Map] # DuckDB specific
1411/// - [Expr::Lambda]
1412impl Spanned for Expr {
1413    fn span(&self) -> Span {
1414        match self {
1415            Expr::Identifier(ident) => ident.span,
1416            Expr::CompoundIdentifier(vec) => union_spans(vec.iter().map(|i| i.span)),
1417            Expr::CompoundFieldAccess { root, access_chain } => {
1418                union_spans(iter::once(root.span()).chain(access_chain.iter().map(|i| i.span())))
1419            }
1420            Expr::IsFalse(expr) => expr.span(),
1421            Expr::IsNotFalse(expr) => expr.span(),
1422            Expr::IsTrue(expr) => expr.span(),
1423            Expr::IsNotTrue(expr) => expr.span(),
1424            Expr::IsNull(expr) => expr.span(),
1425            Expr::IsNotNull(expr) => expr.span(),
1426            Expr::IsUnknown(expr) => expr.span(),
1427            Expr::IsNotUnknown(expr) => expr.span(),
1428            Expr::IsDistinctFrom(lhs, rhs) => lhs.span().union(&rhs.span()),
1429            Expr::IsNotDistinctFrom(lhs, rhs) => lhs.span().union(&rhs.span()),
1430            Expr::InList {
1431                expr,
1432                list,
1433                negated: _,
1434            } => union_spans(
1435                core::iter::once(expr.span()).chain(list.iter().map(|item| item.span())),
1436            ),
1437            Expr::InSubquery {
1438                expr,
1439                subquery,
1440                negated: _,
1441            } => expr.span().union(&subquery.span()),
1442            Expr::InUnnest {
1443                expr,
1444                array_expr,
1445                negated: _,
1446            } => expr.span().union(&array_expr.span()),
1447            Expr::Between {
1448                expr,
1449                negated: _,
1450                low,
1451                high,
1452            } => expr.span().union(&low.span()).union(&high.span()),
1453
1454            Expr::BinaryOp { left, op: _, right } => left.span().union(&right.span()),
1455            Expr::Like {
1456                negated: _,
1457                expr,
1458                pattern,
1459                escape_char: _,
1460                any: _,
1461            } => expr.span().union(&pattern.span()),
1462            Expr::ILike {
1463                negated: _,
1464                expr,
1465                pattern,
1466                escape_char: _,
1467                any: _,
1468            } => expr.span().union(&pattern.span()),
1469            Expr::RLike { .. } => Span::empty(),
1470            Expr::IsNormalized {
1471                expr,
1472                form: _,
1473                negated: _,
1474            } => expr.span(),
1475            Expr::SimilarTo {
1476                negated: _,
1477                expr,
1478                pattern,
1479                escape_char: _,
1480            } => expr.span().union(&pattern.span()),
1481            Expr::Ceil { expr, field: _ } => expr.span(),
1482            Expr::Floor { expr, field: _ } => expr.span(),
1483            Expr::Position { expr, r#in } => expr.span().union(&r#in.span()),
1484            Expr::Overlay {
1485                expr,
1486                overlay_what,
1487                overlay_from,
1488                overlay_for,
1489            } => expr
1490                .span()
1491                .union(&overlay_what.span())
1492                .union(&overlay_from.span())
1493                .union_opt(&overlay_for.as_ref().map(|i| i.span())),
1494            Expr::Collate { expr, collation } => expr
1495                .span()
1496                .union(&union_spans(collation.0.iter().map(|i| i.span()))),
1497            Expr::Nested(expr) => expr.span(),
1498            Expr::Value(value) => value.span(),
1499            Expr::TypedString(TypedString { value, .. }) => value.span(),
1500            Expr::Function(function) => function.span(),
1501            Expr::GroupingSets(vec) => {
1502                union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span())))
1503            }
1504            Expr::Cube(vec) => union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1505            Expr::Rollup(vec) => union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1506            Expr::Tuple(vec) => union_spans(vec.iter().map(|i| i.span())),
1507            Expr::Array(array) => array.span(),
1508            Expr::MatchAgainst { .. } => Span::empty(),
1509            Expr::JsonAccess { value, path } => value.span().union(&path.span()),
1510            Expr::AnyOp {
1511                left,
1512                compare_op: _,
1513                right,
1514                is_some: _,
1515            } => left.span().union(&right.span()),
1516            Expr::AllOp {
1517                left,
1518                compare_op: _,
1519                right,
1520            } => left.span().union(&right.span()),
1521            Expr::UnaryOp { op: _, expr } => expr.span(),
1522            Expr::Convert {
1523                expr,
1524                data_type: _,
1525                charset,
1526                target_before_value: _,
1527                styles,
1528                is_try: _,
1529            } => union_spans(
1530                core::iter::once(expr.span())
1531                    .chain(charset.as_ref().map(|i| i.span()))
1532                    .chain(styles.iter().map(|i| i.span())),
1533            ),
1534            Expr::Cast {
1535                kind: _,
1536                expr,
1537                data_type: _,
1538                format: _,
1539            } => expr.span(),
1540            Expr::AtTimeZone {
1541                timestamp,
1542                time_zone,
1543            } => timestamp.span().union(&time_zone.span()),
1544            Expr::Extract {
1545                field: _,
1546                syntax: _,
1547                expr,
1548            } => expr.span(),
1549            Expr::Substring {
1550                expr,
1551                substring_from,
1552                substring_for,
1553                special: _,
1554                shorthand: _,
1555            } => union_spans(
1556                core::iter::once(expr.span())
1557                    .chain(substring_from.as_ref().map(|i| i.span()))
1558                    .chain(substring_for.as_ref().map(|i| i.span())),
1559            ),
1560            Expr::Trim {
1561                expr,
1562                trim_where: _,
1563                trim_what,
1564                trim_characters,
1565            } => union_spans(
1566                core::iter::once(expr.span())
1567                    .chain(trim_what.as_ref().map(|i| i.span()))
1568                    .chain(
1569                        trim_characters
1570                            .as_ref()
1571                            .map(|items| union_spans(items.iter().map(|i| i.span()))),
1572                    ),
1573            ),
1574            Expr::Prefixed { value, .. } => value.span(),
1575            Expr::Case {
1576                case_token,
1577                end_token,
1578                operand,
1579                conditions,
1580                else_result,
1581            } => union_spans(
1582                iter::once(case_token.0.span)
1583                    .chain(
1584                        operand
1585                            .as_ref()
1586                            .map(|i| i.span())
1587                            .into_iter()
1588                            .chain(conditions.iter().flat_map(|case_when| {
1589                                [case_when.condition.span(), case_when.result.span()]
1590                            }))
1591                            .chain(else_result.as_ref().map(|i| i.span())),
1592                    )
1593                    .chain(iter::once(end_token.0.span)),
1594            ),
1595            Expr::Exists { subquery, .. } => subquery.span(),
1596            Expr::Subquery(query) => query.span(),
1597            Expr::Struct { .. } => Span::empty(),
1598            Expr::Named { .. } => Span::empty(),
1599            Expr::Dictionary(_) => Span::empty(),
1600            Expr::Map(_) => Span::empty(),
1601            Expr::Interval(interval) => interval.value.span(),
1602            Expr::Wildcard(token) => token.0.span,
1603            Expr::QualifiedWildcard(object_name, token) => union_spans(
1604                object_name
1605                    .0
1606                    .iter()
1607                    .map(|i| i.span())
1608                    .chain(iter::once(token.0.span)),
1609            ),
1610            Expr::OuterJoin(expr) => expr.span(),
1611            Expr::Prior(expr) => expr.span(),
1612            Expr::Lambda(_) => Span::empty(),
1613            Expr::MemberOf(member_of) => member_of.value.span().union(&member_of.array.span()),
1614        }
1615    }
1616}
1617
1618impl Spanned for Subscript {
1619    fn span(&self) -> Span {
1620        match self {
1621            Subscript::Index { index } => index.span(),
1622            Subscript::Slice {
1623                lower_bound,
1624                upper_bound,
1625                stride,
1626            } => union_spans(
1627                [
1628                    lower_bound.as_ref().map(|i| i.span()),
1629                    upper_bound.as_ref().map(|i| i.span()),
1630                    stride.as_ref().map(|i| i.span()),
1631                ]
1632                .into_iter()
1633                .flatten(),
1634            ),
1635        }
1636    }
1637}
1638
1639impl Spanned for AccessExpr {
1640    fn span(&self) -> Span {
1641        match self {
1642            AccessExpr::Dot(ident) => ident.span(),
1643            AccessExpr::Subscript(subscript) => subscript.span(),
1644        }
1645    }
1646}
1647
1648impl Spanned for ObjectName {
1649    fn span(&self) -> Span {
1650        let ObjectName(segments) = self;
1651
1652        union_spans(segments.iter().map(|i| i.span()))
1653    }
1654}
1655
1656impl Spanned for ObjectNamePart {
1657    fn span(&self) -> Span {
1658        match self {
1659            ObjectNamePart::Identifier(ident) => ident.span,
1660            ObjectNamePart::Function(func) => func
1661                .name
1662                .span
1663                .union(&union_spans(func.args.iter().map(|i| i.span()))),
1664        }
1665    }
1666}
1667
1668impl Spanned for Array {
1669    fn span(&self) -> Span {
1670        let Array {
1671            elem,
1672            named: _, // bool
1673        } = self;
1674
1675        union_spans(elem.iter().map(|i| i.span()))
1676    }
1677}
1678
1679impl Spanned for Function {
1680    fn span(&self) -> Span {
1681        let Function {
1682            name,
1683            uses_odbc_syntax: _,
1684            parameters,
1685            args,
1686            filter,
1687            null_treatment: _, // enum
1688            over: _,           // todo
1689            within_group,
1690        } = self;
1691
1692        union_spans(
1693            name.0
1694                .iter()
1695                .map(|i| i.span())
1696                .chain(iter::once(args.span()))
1697                .chain(iter::once(parameters.span()))
1698                .chain(filter.iter().map(|i| i.span()))
1699                .chain(within_group.iter().map(|i| i.span())),
1700        )
1701    }
1702}
1703
1704/// # partial span
1705///
1706/// The span of [FunctionArguments::None] is empty.
1707impl Spanned for FunctionArguments {
1708    fn span(&self) -> Span {
1709        match self {
1710            FunctionArguments::None => Span::empty(),
1711            FunctionArguments::Subquery(query) => query.span(),
1712            FunctionArguments::List(list) => list.span(),
1713        }
1714    }
1715}
1716
1717impl Spanned for FunctionArgumentList {
1718    fn span(&self) -> Span {
1719        let FunctionArgumentList {
1720            duplicate_treatment: _, // enum
1721            args,
1722            clauses,
1723        } = self;
1724
1725        union_spans(
1726            // # todo: duplicate-treatment span
1727            args.iter()
1728                .map(|i| i.span())
1729                .chain(clauses.iter().map(|i| i.span())),
1730        )
1731    }
1732}
1733
1734impl Spanned for FunctionArgumentClause {
1735    fn span(&self) -> Span {
1736        match self {
1737            FunctionArgumentClause::IgnoreOrRespectNulls(_) => Span::empty(),
1738            FunctionArgumentClause::OrderBy(vec) => union_spans(vec.iter().map(|i| i.expr.span())),
1739            FunctionArgumentClause::Limit(expr) => expr.span(),
1740            FunctionArgumentClause::OnOverflow(_) => Span::empty(),
1741            FunctionArgumentClause::Having(HavingBound(_kind, expr)) => expr.span(),
1742            FunctionArgumentClause::Separator(value) => value.span(),
1743            FunctionArgumentClause::JsonNullClause(_) => Span::empty(),
1744            FunctionArgumentClause::JsonReturningClause(_) => Span::empty(),
1745        }
1746    }
1747}
1748
1749/// # partial span
1750///
1751/// see Spanned impl for JsonPathElem for more information
1752impl Spanned for JsonPath {
1753    fn span(&self) -> Span {
1754        let JsonPath { path } = self;
1755
1756        union_spans(path.iter().map(|i| i.span()))
1757    }
1758}
1759
1760/// # partial span
1761///
1762/// Missing spans:
1763/// - [JsonPathElem::Dot]
1764impl Spanned for JsonPathElem {
1765    fn span(&self) -> Span {
1766        match self {
1767            JsonPathElem::Dot { .. } => Span::empty(),
1768            JsonPathElem::Bracket { key } => key.span(),
1769        }
1770    }
1771}
1772
1773impl Spanned for SelectItemQualifiedWildcardKind {
1774    fn span(&self) -> Span {
1775        match self {
1776            SelectItemQualifiedWildcardKind::ObjectName(object_name) => object_name.span(),
1777            SelectItemQualifiedWildcardKind::Expr(expr) => expr.span(),
1778        }
1779    }
1780}
1781
1782impl Spanned for SelectItem {
1783    fn span(&self) -> Span {
1784        match self {
1785            SelectItem::UnnamedExpr(expr) => expr.span(),
1786            SelectItem::ExprWithAlias { expr, alias } => expr.span().union(&alias.span),
1787            SelectItem::QualifiedWildcard(kind, wildcard_additional_options) => union_spans(
1788                [kind.span()]
1789                    .into_iter()
1790                    .chain(iter::once(wildcard_additional_options.span())),
1791            ),
1792            SelectItem::Wildcard(wildcard_additional_options) => wildcard_additional_options.span(),
1793        }
1794    }
1795}
1796
1797impl Spanned for WildcardAdditionalOptions {
1798    fn span(&self) -> Span {
1799        let WildcardAdditionalOptions {
1800            wildcard_token,
1801            opt_ilike,
1802            opt_exclude,
1803            opt_except,
1804            opt_replace,
1805            opt_rename,
1806        } = self;
1807
1808        union_spans(
1809            core::iter::once(wildcard_token.0.span)
1810                .chain(opt_ilike.as_ref().map(|i| i.span()))
1811                .chain(opt_exclude.as_ref().map(|i| i.span()))
1812                .chain(opt_rename.as_ref().map(|i| i.span()))
1813                .chain(opt_replace.as_ref().map(|i| i.span()))
1814                .chain(opt_except.as_ref().map(|i| i.span())),
1815        )
1816    }
1817}
1818
1819/// # missing span
1820impl Spanned for IlikeSelectItem {
1821    fn span(&self) -> Span {
1822        Span::empty()
1823    }
1824}
1825
1826impl Spanned for ExcludeSelectItem {
1827    fn span(&self) -> Span {
1828        match self {
1829            ExcludeSelectItem::Single(ident) => ident.span,
1830            ExcludeSelectItem::Multiple(vec) => union_spans(vec.iter().map(|i| i.span)),
1831        }
1832    }
1833}
1834
1835impl Spanned for RenameSelectItem {
1836    fn span(&self) -> Span {
1837        match self {
1838            RenameSelectItem::Single(ident) => ident.ident.span.union(&ident.alias.span),
1839            RenameSelectItem::Multiple(vec) => {
1840                union_spans(vec.iter().map(|i| i.ident.span.union(&i.alias.span)))
1841            }
1842        }
1843    }
1844}
1845
1846impl Spanned for ExceptSelectItem {
1847    fn span(&self) -> Span {
1848        let ExceptSelectItem {
1849            first_element,
1850            additional_elements,
1851        } = self;
1852
1853        union_spans(
1854            iter::once(first_element.span).chain(additional_elements.iter().map(|i| i.span)),
1855        )
1856    }
1857}
1858
1859impl Spanned for ReplaceSelectItem {
1860    fn span(&self) -> Span {
1861        let ReplaceSelectItem { items } = self;
1862
1863        union_spans(items.iter().map(|i| i.span()))
1864    }
1865}
1866
1867impl Spanned for ReplaceSelectElement {
1868    fn span(&self) -> Span {
1869        let ReplaceSelectElement {
1870            expr,
1871            column_name,
1872            as_keyword: _, // bool
1873        } = self;
1874
1875        expr.span().union(&column_name.span)
1876    }
1877}
1878
1879/// # partial span
1880///
1881/// Missing spans:
1882/// - [TableFactor::JsonTable]
1883impl Spanned for TableFactor {
1884    fn span(&self) -> Span {
1885        match self {
1886            TableFactor::Table {
1887                name,
1888                alias,
1889                args: _,
1890                with_hints: _,
1891                version: _,
1892                with_ordinality: _,
1893                partitions: _,
1894                json_path: _,
1895                sample: _,
1896                index_hints: _,
1897            } => union_spans(
1898                name.0
1899                    .iter()
1900                    .map(|i| i.span())
1901                    .chain(alias.as_ref().map(|alias| {
1902                        union_spans(
1903                            iter::once(alias.name.span)
1904                                .chain(alias.columns.iter().map(|i| i.span())),
1905                        )
1906                    })),
1907            ),
1908            TableFactor::Derived {
1909                lateral: _,
1910                subquery,
1911                alias,
1912            } => subquery
1913                .span()
1914                .union_opt(&alias.as_ref().map(|alias| alias.span())),
1915            TableFactor::TableFunction { expr, alias } => expr
1916                .span()
1917                .union_opt(&alias.as_ref().map(|alias| alias.span())),
1918            TableFactor::UNNEST {
1919                alias,
1920                with_offset: _,
1921                with_offset_alias,
1922                array_exprs,
1923                with_ordinality: _,
1924            } => union_spans(
1925                alias
1926                    .iter()
1927                    .map(|i| i.span())
1928                    .chain(array_exprs.iter().map(|i| i.span()))
1929                    .chain(with_offset_alias.as_ref().map(|i| i.span)),
1930            ),
1931            TableFactor::NestedJoin {
1932                table_with_joins,
1933                alias,
1934            } => table_with_joins
1935                .span()
1936                .union_opt(&alias.as_ref().map(|alias| alias.span())),
1937            TableFactor::Function {
1938                lateral: _,
1939                name,
1940                args,
1941                alias,
1942            } => union_spans(
1943                name.0
1944                    .iter()
1945                    .map(|i| i.span())
1946                    .chain(args.iter().map(|i| i.span()))
1947                    .chain(alias.as_ref().map(|alias| alias.span())),
1948            ),
1949            TableFactor::JsonTable { .. } => Span::empty(),
1950            TableFactor::XmlTable { .. } => Span::empty(),
1951            TableFactor::Pivot {
1952                table,
1953                aggregate_functions,
1954                value_column,
1955                value_source,
1956                default_on_null,
1957                alias,
1958            } => union_spans(
1959                core::iter::once(table.span())
1960                    .chain(aggregate_functions.iter().map(|i| i.span()))
1961                    .chain(value_column.iter().map(|i| i.span()))
1962                    .chain(core::iter::once(value_source.span()))
1963                    .chain(default_on_null.as_ref().map(|i| i.span()))
1964                    .chain(alias.as_ref().map(|i| i.span())),
1965            ),
1966            TableFactor::Unpivot {
1967                table,
1968                value,
1969                null_inclusion: _,
1970                name,
1971                columns,
1972                alias,
1973            } => union_spans(
1974                core::iter::once(table.span())
1975                    .chain(core::iter::once(value.span()))
1976                    .chain(core::iter::once(name.span))
1977                    .chain(columns.iter().map(|ilist| ilist.span()))
1978                    .chain(alias.as_ref().map(|alias| alias.span())),
1979            ),
1980            TableFactor::MatchRecognize {
1981                table,
1982                partition_by,
1983                order_by,
1984                measures,
1985                rows_per_match: _,
1986                after_match_skip: _,
1987                pattern,
1988                symbols,
1989                alias,
1990            } => union_spans(
1991                core::iter::once(table.span())
1992                    .chain(partition_by.iter().map(|i| i.span()))
1993                    .chain(order_by.iter().map(|i| i.span()))
1994                    .chain(measures.iter().map(|i| i.span()))
1995                    .chain(core::iter::once(pattern.span()))
1996                    .chain(symbols.iter().map(|i| i.span()))
1997                    .chain(alias.as_ref().map(|i| i.span())),
1998            ),
1999            TableFactor::SemanticView {
2000                name,
2001                dimensions,
2002                metrics,
2003                facts,
2004                where_clause,
2005                alias,
2006            } => union_spans(
2007                name.0
2008                    .iter()
2009                    .map(|i| i.span())
2010                    .chain(dimensions.iter().map(|d| d.span()))
2011                    .chain(metrics.iter().map(|m| m.span()))
2012                    .chain(facts.iter().map(|f| f.span()))
2013                    .chain(where_clause.as_ref().map(|e| e.span()))
2014                    .chain(alias.as_ref().map(|a| a.span())),
2015            ),
2016            TableFactor::OpenJsonTable { .. } => Span::empty(),
2017        }
2018    }
2019}
2020
2021impl Spanned for PivotValueSource {
2022    fn span(&self) -> Span {
2023        match self {
2024            PivotValueSource::List(vec) => union_spans(vec.iter().map(|i| i.span())),
2025            PivotValueSource::Any(vec) => union_spans(vec.iter().map(|i| i.span())),
2026            PivotValueSource::Subquery(query) => query.span(),
2027        }
2028    }
2029}
2030
2031impl Spanned for ExprWithAlias {
2032    fn span(&self) -> Span {
2033        let ExprWithAlias { expr, alias } = self;
2034
2035        expr.span().union_opt(&alias.as_ref().map(|i| i.span))
2036    }
2037}
2038
2039/// # missing span
2040impl Spanned for MatchRecognizePattern {
2041    fn span(&self) -> Span {
2042        Span::empty()
2043    }
2044}
2045
2046impl Spanned for SymbolDefinition {
2047    fn span(&self) -> Span {
2048        let SymbolDefinition { symbol, definition } = self;
2049
2050        symbol.span.union(&definition.span())
2051    }
2052}
2053
2054impl Spanned for Measure {
2055    fn span(&self) -> Span {
2056        let Measure { expr, alias } = self;
2057
2058        expr.span().union(&alias.span)
2059    }
2060}
2061
2062impl Spanned for OrderByExpr {
2063    fn span(&self) -> Span {
2064        let OrderByExpr {
2065            expr,
2066            options: _,
2067            with_fill,
2068        } = self;
2069
2070        expr.span().union_opt(&with_fill.as_ref().map(|f| f.span()))
2071    }
2072}
2073
2074impl Spanned for WithFill {
2075    fn span(&self) -> Span {
2076        let WithFill { from, to, step } = self;
2077
2078        union_spans(
2079            from.iter()
2080                .map(|f| f.span())
2081                .chain(to.iter().map(|t| t.span()))
2082                .chain(step.iter().map(|s| s.span())),
2083        )
2084    }
2085}
2086
2087impl Spanned for FunctionArg {
2088    fn span(&self) -> Span {
2089        match self {
2090            FunctionArg::Named {
2091                name,
2092                arg,
2093                operator: _,
2094            } => name.span.union(&arg.span()),
2095            FunctionArg::Unnamed(arg) => arg.span(),
2096            FunctionArg::ExprNamed {
2097                name,
2098                arg,
2099                operator: _,
2100            } => name.span().union(&arg.span()),
2101        }
2102    }
2103}
2104
2105/// # partial span
2106///
2107/// Missing spans:
2108/// - [FunctionArgExpr::Wildcard]
2109impl Spanned for FunctionArgExpr {
2110    fn span(&self) -> Span {
2111        match self {
2112            FunctionArgExpr::Expr(expr) => expr.span(),
2113            FunctionArgExpr::QualifiedWildcard(object_name) => {
2114                union_spans(object_name.0.iter().map(|i| i.span()))
2115            }
2116            FunctionArgExpr::Wildcard => Span::empty(),
2117        }
2118    }
2119}
2120
2121impl Spanned for TableAlias {
2122    fn span(&self) -> Span {
2123        let TableAlias {
2124            explicit: _,
2125            name,
2126            columns,
2127        } = self;
2128        union_spans(core::iter::once(name.span).chain(columns.iter().map(Spanned::span)))
2129    }
2130}
2131
2132impl Spanned for TableAliasColumnDef {
2133    fn span(&self) -> Span {
2134        let TableAliasColumnDef { name, data_type: _ } = self;
2135
2136        name.span
2137    }
2138}
2139
2140impl Spanned for ValueWithSpan {
2141    fn span(&self) -> Span {
2142        self.span
2143    }
2144}
2145
2146/// The span is stored in the `ValueWrapper` struct
2147impl Spanned for Value {
2148    fn span(&self) -> Span {
2149        Span::empty() // # todo: Value needs to store spans before this is possible
2150    }
2151}
2152
2153impl Spanned for Join {
2154    fn span(&self) -> Span {
2155        let Join {
2156            relation,
2157            global: _, // bool
2158            join_operator,
2159        } = self;
2160
2161        relation.span().union(&join_operator.span())
2162    }
2163}
2164
2165/// # partial span
2166///
2167/// Missing spans:
2168/// - [JoinOperator::CrossJoin]
2169/// - [JoinOperator::CrossApply]
2170/// - [JoinOperator::OuterApply]
2171impl Spanned for JoinOperator {
2172    fn span(&self) -> Span {
2173        match self {
2174            JoinOperator::Join(join_constraint) => join_constraint.span(),
2175            JoinOperator::Inner(join_constraint) => join_constraint.span(),
2176            JoinOperator::Left(join_constraint) => join_constraint.span(),
2177            JoinOperator::LeftOuter(join_constraint) => join_constraint.span(),
2178            JoinOperator::Right(join_constraint) => join_constraint.span(),
2179            JoinOperator::RightOuter(join_constraint) => join_constraint.span(),
2180            JoinOperator::FullOuter(join_constraint) => join_constraint.span(),
2181            JoinOperator::CrossJoin(join_constraint) => join_constraint.span(),
2182            JoinOperator::LeftSemi(join_constraint) => join_constraint.span(),
2183            JoinOperator::RightSemi(join_constraint) => join_constraint.span(),
2184            JoinOperator::LeftAnti(join_constraint) => join_constraint.span(),
2185            JoinOperator::RightAnti(join_constraint) => join_constraint.span(),
2186            JoinOperator::CrossApply => Span::empty(),
2187            JoinOperator::OuterApply => Span::empty(),
2188            JoinOperator::AsOf {
2189                match_condition,
2190                constraint,
2191            } => match_condition.span().union(&constraint.span()),
2192            JoinOperator::Anti(join_constraint) => join_constraint.span(),
2193            JoinOperator::Semi(join_constraint) => join_constraint.span(),
2194            JoinOperator::StraightJoin(join_constraint) => join_constraint.span(),
2195        }
2196    }
2197}
2198
2199/// # partial span
2200///
2201/// Missing spans:
2202/// - [JoinConstraint::Natural]
2203/// - [JoinConstraint::None]
2204impl Spanned for JoinConstraint {
2205    fn span(&self) -> Span {
2206        match self {
2207            JoinConstraint::On(expr) => expr.span(),
2208            JoinConstraint::Using(vec) => union_spans(vec.iter().map(|i| i.span())),
2209            JoinConstraint::Natural => Span::empty(),
2210            JoinConstraint::None => Span::empty(),
2211        }
2212    }
2213}
2214
2215impl Spanned for TableWithJoins {
2216    fn span(&self) -> Span {
2217        let TableWithJoins { relation, joins } = self;
2218
2219        union_spans(core::iter::once(relation.span()).chain(joins.iter().map(|item| item.span())))
2220    }
2221}
2222
2223impl Spanned for Select {
2224    fn span(&self) -> Span {
2225        let Select {
2226            select_token,
2227            distinct: _, // todo
2228            top: _,      // todo, mysql specific
2229            projection,
2230            exclude: _,
2231            into,
2232            from,
2233            lateral_views,
2234            prewhere,
2235            selection,
2236            group_by,
2237            cluster_by,
2238            distribute_by,
2239            sort_by,
2240            having,
2241            named_window,
2242            qualify,
2243            window_before_qualify: _, // bool
2244            value_table_mode: _,      // todo, BigQuery specific
2245            connect_by,
2246            top_before_distinct: _,
2247            flavor: _,
2248        } = self;
2249
2250        union_spans(
2251            core::iter::once(select_token.0.span)
2252                .chain(projection.iter().map(|item| item.span()))
2253                .chain(into.iter().map(|item| item.span()))
2254                .chain(from.iter().map(|item| item.span()))
2255                .chain(lateral_views.iter().map(|item| item.span()))
2256                .chain(prewhere.iter().map(|item| item.span()))
2257                .chain(selection.iter().map(|item| item.span()))
2258                .chain(core::iter::once(group_by.span()))
2259                .chain(cluster_by.iter().map(|item| item.span()))
2260                .chain(distribute_by.iter().map(|item| item.span()))
2261                .chain(sort_by.iter().map(|item| item.span()))
2262                .chain(having.iter().map(|item| item.span()))
2263                .chain(named_window.iter().map(|item| item.span()))
2264                .chain(qualify.iter().map(|item| item.span()))
2265                .chain(connect_by.iter().map(|item| item.span())),
2266        )
2267    }
2268}
2269
2270impl Spanned for ConnectBy {
2271    fn span(&self) -> Span {
2272        let ConnectBy {
2273            condition,
2274            relationships,
2275        } = self;
2276
2277        union_spans(
2278            core::iter::once(condition.span()).chain(relationships.iter().map(|item| item.span())),
2279        )
2280    }
2281}
2282
2283impl Spanned for NamedWindowDefinition {
2284    fn span(&self) -> Span {
2285        let NamedWindowDefinition(
2286            ident,
2287            _, // todo: NamedWindowExpr
2288        ) = self;
2289
2290        ident.span
2291    }
2292}
2293
2294impl Spanned for LateralView {
2295    fn span(&self) -> Span {
2296        let LateralView {
2297            lateral_view,
2298            lateral_view_name,
2299            lateral_col_alias,
2300            outer: _, // bool
2301        } = self;
2302
2303        union_spans(
2304            core::iter::once(lateral_view.span())
2305                .chain(core::iter::once(lateral_view_name.span()))
2306                .chain(lateral_col_alias.iter().map(|i| i.span)),
2307        )
2308    }
2309}
2310
2311impl Spanned for SelectInto {
2312    fn span(&self) -> Span {
2313        let SelectInto {
2314            temporary: _, // bool
2315            unlogged: _,  // bool
2316            table: _,     // bool
2317            name,
2318        } = self;
2319
2320        name.span()
2321    }
2322}
2323
2324impl Spanned for UpdateTableFromKind {
2325    fn span(&self) -> Span {
2326        let from = match self {
2327            UpdateTableFromKind::BeforeSet(from) => from,
2328            UpdateTableFromKind::AfterSet(from) => from,
2329        };
2330        union_spans(from.iter().map(|t| t.span()))
2331    }
2332}
2333
2334impl Spanned for TableObject {
2335    fn span(&self) -> Span {
2336        match self {
2337            TableObject::TableName(ObjectName(segments)) => {
2338                union_spans(segments.iter().map(|i| i.span()))
2339            }
2340            TableObject::TableFunction(func) => func.span(),
2341        }
2342    }
2343}
2344
2345impl Spanned for BeginEndStatements {
2346    fn span(&self) -> Span {
2347        let BeginEndStatements {
2348            begin_token,
2349            statements,
2350            end_token,
2351        } = self;
2352        union_spans(
2353            core::iter::once(begin_token.0.span)
2354                .chain(statements.iter().map(|i| i.span()))
2355                .chain(core::iter::once(end_token.0.span)),
2356        )
2357    }
2358}
2359
2360impl Spanned for OpenStatement {
2361    fn span(&self) -> Span {
2362        let OpenStatement { cursor_name } = self;
2363        cursor_name.span
2364    }
2365}
2366
2367impl Spanned for AlterSchemaOperation {
2368    fn span(&self) -> Span {
2369        match self {
2370            AlterSchemaOperation::SetDefaultCollate { collate } => collate.span(),
2371            AlterSchemaOperation::AddReplica { replica, options } => union_spans(
2372                core::iter::once(replica.span)
2373                    .chain(options.iter().flat_map(|i| i.iter().map(|i| i.span()))),
2374            ),
2375            AlterSchemaOperation::DropReplica { replica } => replica.span,
2376            AlterSchemaOperation::SetOptionsParens { options } => {
2377                union_spans(options.iter().map(|i| i.span()))
2378            }
2379            AlterSchemaOperation::Rename { name } => name.span(),
2380            AlterSchemaOperation::OwnerTo { owner } => {
2381                if let Owner::Ident(ident) = owner {
2382                    ident.span
2383                } else {
2384                    Span::empty()
2385                }
2386            }
2387        }
2388    }
2389}
2390
2391impl Spanned for AlterSchema {
2392    fn span(&self) -> Span {
2393        union_spans(
2394            core::iter::once(self.name.span()).chain(self.operations.iter().map(|i| i.span())),
2395        )
2396    }
2397}
2398
2399impl Spanned for CreateView {
2400    fn span(&self) -> Span {
2401        union_spans(
2402            core::iter::once(self.name.span())
2403                .chain(self.columns.iter().map(|i| i.span()))
2404                .chain(core::iter::once(self.query.span()))
2405                .chain(core::iter::once(self.options.span()))
2406                .chain(self.cluster_by.iter().map(|i| i.span))
2407                .chain(self.to.iter().map(|i| i.span())),
2408        )
2409    }
2410}
2411
2412impl Spanned for AlterTable {
2413    fn span(&self) -> Span {
2414        union_spans(
2415            core::iter::once(self.name.span())
2416                .chain(self.operations.iter().map(|i| i.span()))
2417                .chain(self.on_cluster.iter().map(|i| i.span))
2418                .chain(core::iter::once(self.end_token.0.span)),
2419        )
2420    }
2421}
2422
2423impl Spanned for CreateOperator {
2424    fn span(&self) -> Span {
2425        Span::empty()
2426    }
2427}
2428
2429impl Spanned for CreateOperatorFamily {
2430    fn span(&self) -> Span {
2431        Span::empty()
2432    }
2433}
2434
2435impl Spanned for CreateOperatorClass {
2436    fn span(&self) -> Span {
2437        Span::empty()
2438    }
2439}
2440
2441impl Spanned for MergeClause {
2442    fn span(&self) -> Span {
2443        union_spans([self.when_token.0.span, self.action.span()].into_iter())
2444    }
2445}
2446
2447impl Spanned for MergeAction {
2448    fn span(&self) -> Span {
2449        match self {
2450            MergeAction::Insert(expr) => expr.span(),
2451            MergeAction::Update(expr) => expr.span(),
2452            MergeAction::Delete { delete_token } => delete_token.0.span,
2453        }
2454    }
2455}
2456
2457impl Spanned for MergeInsertExpr {
2458    fn span(&self) -> Span {
2459        union_spans(
2460            [
2461                self.insert_token.0.span,
2462                self.kind_token.0.span,
2463                match self.kind {
2464                    MergeInsertKind::Values(ref values) => values.span(),
2465                    MergeInsertKind::Row => Span::empty(), // ~ covered by `kind_token`
2466                },
2467            ]
2468            .into_iter()
2469            .chain(self.insert_predicate.iter().map(Spanned::span))
2470            .chain(self.columns.iter().map(|i| i.span())),
2471        )
2472    }
2473}
2474
2475impl Spanned for MergeUpdateExpr {
2476    fn span(&self) -> Span {
2477        union_spans(
2478            core::iter::once(self.update_token.0.span)
2479                .chain(self.assignments.iter().map(Spanned::span))
2480                .chain(self.update_predicate.iter().map(Spanned::span))
2481                .chain(self.delete_predicate.iter().map(Spanned::span)),
2482        )
2483    }
2484}
2485
2486impl Spanned for OutputClause {
2487    fn span(&self) -> Span {
2488        match self {
2489            OutputClause::Output {
2490                output_token,
2491                select_items,
2492                into_table,
2493            } => union_spans(
2494                core::iter::once(output_token.0.span)
2495                    .chain(into_table.iter().map(Spanned::span))
2496                    .chain(select_items.iter().map(Spanned::span)),
2497            ),
2498            OutputClause::Returning {
2499                returning_token,
2500                select_items,
2501            } => union_spans(
2502                core::iter::once(returning_token.0.span)
2503                    .chain(select_items.iter().map(Spanned::span)),
2504            ),
2505        }
2506    }
2507}
2508
2509#[cfg(test)]
2510pub mod tests {
2511    use crate::dialect::{Dialect, GenericDialect, SnowflakeDialect};
2512    use crate::parser::Parser;
2513    use crate::tokenizer::{Location, Span};
2514
2515    use super::*;
2516
2517    struct SpanTest<'a>(Parser<'a>, &'a str);
2518
2519    impl<'a> SpanTest<'a> {
2520        fn new(dialect: &'a dyn Dialect, sql: &'a str) -> Self {
2521            Self(Parser::new(dialect).try_with_sql(sql).unwrap(), sql)
2522        }
2523
2524        // get the subsection of the source string that corresponds to the span
2525        // only works on single-line strings
2526        fn get_source(&self, span: Span) -> &'a str {
2527            // lines in spans are 1-indexed
2528            &self.1[(span.start.column as usize - 1)..(span.end.column - 1) as usize]
2529        }
2530    }
2531
2532    #[test]
2533    fn test_join() {
2534        let dialect = &GenericDialect;
2535        let mut test = SpanTest::new(
2536            dialect,
2537            "SELECT id, name FROM users LEFT JOIN companies ON users.company_id = companies.id",
2538        );
2539
2540        let query = test.0.parse_select().unwrap();
2541        let select_span = query.span();
2542
2543        assert_eq!(
2544            test.get_source(select_span),
2545            "SELECT id, name FROM users LEFT JOIN companies ON users.company_id = companies.id"
2546        );
2547
2548        let join_span = query.from[0].joins[0].span();
2549
2550        // 'LEFT JOIN' missing
2551        assert_eq!(
2552            test.get_source(join_span),
2553            "companies ON users.company_id = companies.id"
2554        );
2555    }
2556
2557    #[test]
2558    pub fn test_union() {
2559        let dialect = &GenericDialect;
2560        let mut test = SpanTest::new(
2561            dialect,
2562            "SELECT a FROM postgres.public.source UNION SELECT a FROM postgres.public.source",
2563        );
2564
2565        let query = test.0.parse_query().unwrap();
2566        let select_span = query.span();
2567
2568        assert_eq!(
2569            test.get_source(select_span),
2570            "SELECT a FROM postgres.public.source UNION SELECT a FROM postgres.public.source"
2571        );
2572    }
2573
2574    #[test]
2575    pub fn test_subquery() {
2576        let dialect = &GenericDialect;
2577        let mut test = SpanTest::new(
2578            dialect,
2579            "SELECT a FROM (SELECT a FROM postgres.public.source) AS b",
2580        );
2581
2582        let query = test.0.parse_select().unwrap();
2583        let select_span = query.span();
2584
2585        assert_eq!(
2586            test.get_source(select_span),
2587            "SELECT a FROM (SELECT a FROM postgres.public.source) AS b"
2588        );
2589
2590        let subquery_span = query.from[0].span();
2591
2592        // left paren missing
2593        assert_eq!(
2594            test.get_source(subquery_span),
2595            "SELECT a FROM postgres.public.source) AS b"
2596        );
2597    }
2598
2599    #[test]
2600    pub fn test_cte() {
2601        let dialect = &GenericDialect;
2602        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");
2603
2604        let query = test.0.parse_query().unwrap();
2605
2606        let select_span = query.span();
2607
2608        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");
2609    }
2610
2611    #[test]
2612    pub fn test_snowflake_lateral_flatten() {
2613        let dialect = &SnowflakeDialect;
2614        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");
2615
2616        let query = test.0.parse_select().unwrap();
2617
2618        let select_span = query.span();
2619
2620        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");
2621    }
2622
2623    #[test]
2624    pub fn test_wildcard_from_cte() {
2625        let dialect = &GenericDialect;
2626        let mut test = SpanTest::new(
2627            dialect,
2628            "WITH cte AS (SELECT a FROM postgres.public.source) SELECT cte.* FROM cte",
2629        );
2630
2631        let query = test.0.parse_query().unwrap();
2632        let cte_span = query.clone().with.unwrap().cte_tables[0].span();
2633        let cte_query_span = query.clone().with.unwrap().cte_tables[0].query.span();
2634        let body_span = query.body.span();
2635
2636        // the WITH keyboard is part of the query
2637        assert_eq!(
2638            test.get_source(cte_span),
2639            "cte AS (SELECT a FROM postgres.public.source)"
2640        );
2641        assert_eq!(
2642            test.get_source(cte_query_span),
2643            "SELECT a FROM postgres.public.source"
2644        );
2645
2646        assert_eq!(test.get_source(body_span), "SELECT cte.* FROM cte");
2647    }
2648
2649    #[test]
2650    fn test_case_expr_span() {
2651        let dialect = &GenericDialect;
2652        let mut test = SpanTest::new(dialect, "CASE 1 WHEN 2 THEN 3 ELSE 4 END");
2653        let expr = test.0.parse_expr().unwrap();
2654        let expr_span = expr.span();
2655        assert_eq!(
2656            test.get_source(expr_span),
2657            "CASE 1 WHEN 2 THEN 3 ELSE 4 END"
2658        );
2659    }
2660
2661    #[test]
2662    fn test_placeholder_span() {
2663        let sql = "\nSELECT\n  :fooBar";
2664        let r = Parser::parse_sql(&GenericDialect, sql).unwrap();
2665        assert_eq!(1, r.len());
2666        match &r[0] {
2667            Statement::Query(q) => {
2668                let col = &q.body.as_select().unwrap().projection[0];
2669                match col {
2670                    SelectItem::UnnamedExpr(Expr::Value(ValueWithSpan {
2671                        value: Value::Placeholder(s),
2672                        span,
2673                    })) => {
2674                        assert_eq!(":fooBar", s);
2675                        assert_eq!(&Span::new((3, 3).into(), (3, 10).into()), span);
2676                    }
2677                    _ => panic!("expected unnamed expression; got {col:?}"),
2678                }
2679            }
2680            stmt => panic!("expected query; got {stmt:?}"),
2681        }
2682    }
2683
2684    #[test]
2685    fn test_alter_table_multiline_span() {
2686        let sql = r#"-- foo
2687ALTER TABLE users
2688  ADD COLUMN foo
2689  varchar; -- hi there"#;
2690
2691        let r = Parser::parse_sql(&crate::dialect::PostgreSqlDialect {}, sql).unwrap();
2692        assert_eq!(1, r.len());
2693
2694        let stmt_span = r[0].span();
2695
2696        assert_eq!(stmt_span.start, (2, 13).into());
2697        assert_eq!(stmt_span.end, (4, 11).into());
2698    }
2699
2700    #[test]
2701    fn test_update_statement_span() {
2702        let sql = r#"-- foo
2703      UPDATE foo
2704   /* bar */
2705   SET bar = 3
2706 WHERE quux > 42 ;
2707"#;
2708
2709        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2710        assert_eq!(1, r.len());
2711
2712        let stmt_span = r[0].span();
2713
2714        assert_eq!(stmt_span.start, (2, 7).into());
2715        assert_eq!(stmt_span.end, (5, 17).into());
2716    }
2717
2718    #[test]
2719    fn test_insert_statement_span() {
2720        let sql = r#"
2721/* foo */ INSERT  INTO  FOO  (X, Y, Z)
2722  SELECT 1, 2, 3
2723  FROM DUAL
2724;"#;
2725
2726        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2727        assert_eq!(1, r.len());
2728
2729        let stmt_span = r[0].span();
2730
2731        assert_eq!(stmt_span.start, (2, 11).into());
2732        assert_eq!(stmt_span.end, (4, 12).into());
2733    }
2734
2735    #[test]
2736    fn test_replace_statement_span() {
2737        let sql = r#"
2738/* foo */ REPLACE INTO
2739    cities(name,population)
2740SELECT
2741    name,
2742    population
2743FROM
2744   cities
2745WHERE id = 1
2746;"#;
2747
2748        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2749        assert_eq!(1, r.len());
2750
2751        dbg!(&r[0]);
2752
2753        let stmt_span = r[0].span();
2754
2755        assert_eq!(stmt_span.start, (2, 11).into());
2756        assert_eq!(stmt_span.end, (9, 13).into());
2757    }
2758
2759    #[test]
2760    fn test_delete_statement_span() {
2761        let sql = r#"-- foo
2762      DELETE /* quux */
2763        FROM foo
2764       WHERE foo.x = 42
2765;"#;
2766
2767        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2768        assert_eq!(1, r.len());
2769
2770        let stmt_span = r[0].span();
2771
2772        assert_eq!(stmt_span.start, (2, 7).into());
2773        assert_eq!(stmt_span.end, (4, 24).into());
2774    }
2775
2776    #[test]
2777    fn test_merge_statement_spans() {
2778        let sql = r#"
2779        -- plain merge statement; no RETURNING, no OUTPUT
2780
2781        MERGE INTO target_table USING source_table
2782                ON target_table.id = source_table.oooid
2783
2784        /* an inline comment */ WHEN NOT MATCHED THEN
2785            INSERT (ID, description)
2786               VALUES (source_table.id, source_table.description)
2787
2788            -- another one
2789                WHEN MATCHED AND target_table.x = 'X' THEN
2790            UPDATE SET target_table.description = source_table.description
2791
2792              WHEN MATCHED AND target_table.x != 'X' THEN   DELETE
2793        WHEN NOT MATCHED AND 1 THEN INSERT (product, quantity) ROW 
2794        "#;
2795
2796        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2797        assert_eq!(1, r.len());
2798
2799        // ~ assert the span of the whole statement
2800        let stmt_span = r[0].span();
2801        assert_eq!(stmt_span.start, (4, 9).into());
2802        assert_eq!(stmt_span.end, (16, 67).into());
2803
2804        // ~ individual tokens within the statement
2805        let Statement::Merge(Merge {
2806            merge_token,
2807            into: _,
2808            table: _,
2809            source: _,
2810            on: _,
2811            clauses,
2812            output,
2813        }) = &r[0]
2814        else {
2815            panic!("not a MERGE statement");
2816        };
2817        assert_eq!(
2818            merge_token.0.span,
2819            Span::new(Location::new(4, 9), Location::new(4, 14))
2820        );
2821        assert_eq!(clauses.len(), 4);
2822
2823        // ~ the INSERT clause's TOKENs
2824        assert_eq!(
2825            clauses[0].when_token.0.span,
2826            Span::new(Location::new(7, 33), Location::new(7, 37))
2827        );
2828        if let MergeAction::Insert(MergeInsertExpr {
2829            insert_token,
2830            kind_token,
2831            ..
2832        }) = &clauses[0].action
2833        {
2834            assert_eq!(
2835                insert_token.0.span,
2836                Span::new(Location::new(8, 13), Location::new(8, 19))
2837            );
2838            assert_eq!(
2839                kind_token.0.span,
2840                Span::new(Location::new(9, 16), Location::new(9, 22))
2841            );
2842        } else {
2843            panic!("not a MERGE INSERT clause");
2844        }
2845
2846        // ~ the UPDATE token(s)
2847        assert_eq!(
2848            clauses[1].when_token.0.span,
2849            Span::new(Location::new(12, 17), Location::new(12, 21))
2850        );
2851        if let MergeAction::Update(MergeUpdateExpr {
2852            update_token,
2853            assignments: _,
2854            update_predicate: _,
2855            delete_predicate: _,
2856        }) = &clauses[1].action
2857        {
2858            assert_eq!(
2859                update_token.0.span,
2860                Span::new(Location::new(13, 13), Location::new(13, 19))
2861            );
2862        } else {
2863            panic!("not a MERGE UPDATE clause");
2864        }
2865
2866        // the DELETE token(s)
2867        assert_eq!(
2868            clauses[2].when_token.0.span,
2869            Span::new(Location::new(15, 15), Location::new(15, 19))
2870        );
2871        if let MergeAction::Delete { delete_token } = &clauses[2].action {
2872            assert_eq!(
2873                delete_token.0.span,
2874                Span::new(Location::new(15, 61), Location::new(15, 67))
2875            );
2876        } else {
2877            panic!("not a MERGE DELETE clause");
2878        }
2879
2880        // ~ an INSERT clause's ROW token
2881        assert_eq!(
2882            clauses[3].when_token.0.span,
2883            Span::new(Location::new(16, 9), Location::new(16, 13))
2884        );
2885        if let MergeAction::Insert(MergeInsertExpr {
2886            insert_token,
2887            kind_token,
2888            ..
2889        }) = &clauses[3].action
2890        {
2891            assert_eq!(
2892                insert_token.0.span,
2893                Span::new(Location::new(16, 37), Location::new(16, 43))
2894            );
2895            assert_eq!(
2896                kind_token.0.span,
2897                Span::new(Location::new(16, 64), Location::new(16, 67))
2898            );
2899        } else {
2900            panic!("not a MERGE INSERT clause");
2901        }
2902
2903        assert!(output.is_none());
2904    }
2905
2906    #[test]
2907    fn test_merge_statement_spans_with_returning() {
2908        let sql = r#"
2909    MERGE INTO wines AS w
2910    USING wine_stock_changes AS s
2911        ON s.winename = w.winename
2912    WHEN NOT MATCHED AND s.stock_delta > 0 THEN INSERT VALUES (s.winename, s.stock_delta)
2913    WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN UPDATE SET stock = w.stock + s.stock_delta
2914    WHEN MATCHED THEN DELETE
2915    RETURNING merge_action(), w.*
2916        "#;
2917
2918        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2919        assert_eq!(1, r.len());
2920
2921        // ~ assert the span of the whole statement
2922        let stmt_span = r[0].span();
2923        assert_eq!(
2924            stmt_span,
2925            Span::new(Location::new(2, 5), Location::new(8, 34))
2926        );
2927
2928        // ~ individual tokens within the statement
2929        if let Statement::Merge(Merge { output, .. }) = &r[0] {
2930            if let Some(OutputClause::Returning {
2931                returning_token, ..
2932            }) = output
2933            {
2934                assert_eq!(
2935                    returning_token.0.span,
2936                    Span::new(Location::new(8, 5), Location::new(8, 14))
2937                );
2938            } else {
2939                panic!("unexpected MERGE output clause");
2940            }
2941        } else {
2942            panic!("not a MERGE statement");
2943        };
2944    }
2945
2946    #[test]
2947    fn test_merge_statement_spans_with_output() {
2948        let sql = r#"MERGE INTO a USING b ON a.id = b.id
2949        WHEN MATCHED THEN DELETE
2950              OUTPUT inserted.*"#;
2951
2952        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2953        assert_eq!(1, r.len());
2954
2955        // ~ assert the span of the whole statement
2956        let stmt_span = r[0].span();
2957        assert_eq!(
2958            stmt_span,
2959            Span::new(Location::new(1, 1), Location::new(3, 32))
2960        );
2961
2962        // ~ individual tokens within the statement
2963        if let Statement::Merge(Merge { output, .. }) = &r[0] {
2964            if let Some(OutputClause::Output { output_token, .. }) = output {
2965                assert_eq!(
2966                    output_token.0.span,
2967                    Span::new(Location::new(3, 15), Location::new(3, 21))
2968                );
2969            } else {
2970                panic!("unexpected MERGE output clause");
2971            }
2972        } else {
2973            panic!("not a MERGE statement");
2974        };
2975    }
2976
2977    #[test]
2978    fn test_merge_statement_spans_with_update_predicates() {
2979        let sql = r#"
2980       MERGE INTO a USING b ON a.id = b.id
2981        WHEN MATCHED THEN
2982              UPDATE set a.x = a.x + b.x
2983               WHERE b.x != 2
2984              DELETE WHERE a.x <> 3"#;
2985
2986        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2987        assert_eq!(1, r.len());
2988
2989        // ~ assert the span of the whole statement
2990        let stmt_span = r[0].span();
2991        assert_eq!(
2992            stmt_span,
2993            Span::new(Location::new(2, 8), Location::new(6, 36))
2994        );
2995    }
2996
2997    #[test]
2998    fn test_merge_statement_spans_with_insert_predicate() {
2999        let sql = r#"
3000       MERGE INTO a USING b ON a.id = b.id
3001        WHEN NOT MATCHED THEN
3002            INSERT VALUES (b.x, b.y) WHERE b.x != 2
3003-- qed
3004"#;
3005
3006        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
3007        assert_eq!(1, r.len());
3008
3009        // ~ assert the span of the whole statement
3010        let stmt_span = r[0].span();
3011        assert_eq!(
3012            stmt_span,
3013            Span::new(Location::new(2, 8), Location::new(4, 52))
3014        );
3015    }
3016}