Skip to main content

sqlparser/ast/
spans.rs

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