Skip to main content

sqlparser/ast/
spans.rs

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