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