Skip to main content

sqlparser/ast/
spans.rs

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