Skip to main content

sqlparser/ast/
spans.rs

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