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