Skip to main content

sqlparser/ast/
spans.rs

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