Skip to main content

sqlparser/ast/
spans.rs

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