Skip to main content

sqlparser/ast/
spans.rs

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