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