Skip to main content

sqlparser/ast/
spans.rs

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