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