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