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::FreezePartition {
1162                partition,
1163                with_name,
1164            } => partition
1165                .span()
1166                .union_opt(&with_name.as_ref().map(|n| n.span)),
1167            AlterTableOperation::UnfreezePartition {
1168                partition,
1169                with_name,
1170            } => partition
1171                .span()
1172                .union_opt(&with_name.as_ref().map(|n| n.span)),
1173            AlterTableOperation::DropPrimaryKey { .. } => Span::empty(),
1174            AlterTableOperation::DropForeignKey { name, .. } => name.span,
1175            AlterTableOperation::DropIndex { name } => name.span,
1176            AlterTableOperation::EnableAlwaysRule { name } => name.span,
1177            AlterTableOperation::EnableAlwaysTrigger { name } => name.span,
1178            AlterTableOperation::EnableReplicaRule { name } => name.span,
1179            AlterTableOperation::EnableReplicaTrigger { name } => name.span,
1180            AlterTableOperation::EnableRowLevelSecurity => Span::empty(),
1181            AlterTableOperation::ForceRowLevelSecurity => Span::empty(),
1182            AlterTableOperation::NoForceRowLevelSecurity => Span::empty(),
1183            AlterTableOperation::EnableRule { name } => name.span,
1184            AlterTableOperation::EnableTrigger { name } => name.span,
1185            AlterTableOperation::RenamePartitions {
1186                old_partitions,
1187                new_partitions,
1188            } => union_spans(
1189                old_partitions
1190                    .iter()
1191                    .map(|i| i.span())
1192                    .chain(new_partitions.iter().map(|i| i.span())),
1193            ),
1194            AlterTableOperation::AddPartitions {
1195                if_not_exists: _,
1196                new_partitions,
1197            } => union_spans(new_partitions.iter().map(|i| i.span())),
1198            AlterTableOperation::DropPartitions {
1199                partitions,
1200                if_exists: _,
1201            } => union_spans(partitions.iter().map(|i| i.span())),
1202            AlterTableOperation::RenameColumn {
1203                old_column_name,
1204                new_column_name,
1205            } => old_column_name.span.union(&new_column_name.span),
1206            AlterTableOperation::RenameTable { table_name } => table_name.span(),
1207            AlterTableOperation::ChangeColumn {
1208                old_name,
1209                new_name,
1210                data_type: _,
1211                options,
1212                column_position: _,
1213            } => union_spans(
1214                core::iter::once(old_name.span)
1215                    .chain(core::iter::once(new_name.span))
1216                    .chain(options.iter().map(|i| i.span())),
1217            ),
1218            AlterTableOperation::ModifyColumn {
1219                col_name,
1220                data_type: _,
1221                options,
1222                column_position: _,
1223            } => {
1224                union_spans(core::iter::once(col_name.span).chain(options.iter().map(|i| i.span())))
1225            }
1226            AlterTableOperation::RenameConstraint { old_name, new_name } => {
1227                old_name.span.union(&new_name.span)
1228            }
1229            AlterTableOperation::AlterColumn { column_name, op } => {
1230                column_name.span.union(&op.span())
1231            }
1232            AlterTableOperation::SwapWith { table_name } => table_name.span(),
1233            AlterTableOperation::SetTblProperties { table_properties } => {
1234                union_spans(table_properties.iter().map(|i| i.span()))
1235            }
1236            AlterTableOperation::OwnerTo { .. } => Span::empty(),
1237            AlterTableOperation::ClusterBy { exprs } => union_spans(exprs.iter().map(|e| e.span())),
1238            AlterTableOperation::DropClusteringKey => Span::empty(),
1239            AlterTableOperation::AlterSortKey { .. } => Span::empty(),
1240            AlterTableOperation::SuspendRecluster => Span::empty(),
1241            AlterTableOperation::ResumeRecluster => Span::empty(),
1242            AlterTableOperation::Refresh { .. } => Span::empty(),
1243            AlterTableOperation::Suspend => Span::empty(),
1244            AlterTableOperation::Resume => Span::empty(),
1245            AlterTableOperation::Algorithm { .. } => Span::empty(),
1246            AlterTableOperation::AutoIncrement { value, .. } => value.span(),
1247            AlterTableOperation::Lock { .. } => Span::empty(),
1248            AlterTableOperation::ReplicaIdentity { .. } => Span::empty(),
1249            AlterTableOperation::ValidateConstraint { name } => name.span,
1250            AlterTableOperation::SetOptionsParens { options } => {
1251                union_spans(options.iter().map(|i| i.span()))
1252            }
1253            AlterTableOperation::SetTablespace { .. } => Span::empty(),
1254        }
1255    }
1256}
1257
1258impl Spanned for Partition {
1259    fn span(&self) -> Span {
1260        match self {
1261            Partition::Identifier(ident) => ident.span,
1262            Partition::Expr(expr) => expr.span(),
1263            Partition::Part(expr) => expr.span(),
1264            Partition::Partitions(vec) => union_spans(vec.iter().map(|i| i.span())),
1265        }
1266    }
1267}
1268
1269impl Spanned for ProjectionSelect {
1270    fn span(&self) -> Span {
1271        let ProjectionSelect {
1272            projection,
1273            order_by,
1274            group_by,
1275        } = self;
1276
1277        union_spans(
1278            projection
1279                .iter()
1280                .map(|i| i.span())
1281                .chain(order_by.iter().map(|i| i.span()))
1282                .chain(group_by.iter().map(|i| i.span())),
1283        )
1284    }
1285}
1286
1287/// # partial span
1288///
1289/// Missing spans:
1290/// - [OrderByKind::All]
1291impl Spanned for OrderBy {
1292    fn span(&self) -> Span {
1293        match &self.kind {
1294            OrderByKind::All(_) => Span::empty(),
1295            OrderByKind::Expressions(exprs) => union_spans(
1296                exprs
1297                    .iter()
1298                    .map(|i| i.span())
1299                    .chain(self.interpolate.iter().map(|i| i.span())),
1300            ),
1301        }
1302    }
1303}
1304
1305/// # partial span
1306///
1307/// Missing spans:
1308/// - [GroupByExpr::All]
1309impl Spanned for GroupByExpr {
1310    fn span(&self) -> Span {
1311        match self {
1312            GroupByExpr::All(_) => Span::empty(),
1313            GroupByExpr::Expressions(exprs, _modifiers) => {
1314                union_spans(exprs.iter().map(|i| i.span()))
1315            }
1316        }
1317    }
1318}
1319
1320impl Spanned for Interpolate {
1321    fn span(&self) -> Span {
1322        let Interpolate { exprs } = self;
1323
1324        union_spans(exprs.iter().flat_map(|i| i.iter().map(|e| e.span())))
1325    }
1326}
1327
1328impl Spanned for InterpolateExpr {
1329    fn span(&self) -> Span {
1330        let InterpolateExpr { column, expr } = self;
1331
1332        column.span.union_opt(&expr.as_ref().map(|e| e.span()))
1333    }
1334}
1335
1336impl Spanned for AlterIndexOperation {
1337    fn span(&self) -> Span {
1338        match self {
1339            AlterIndexOperation::RenameIndex { index_name } => index_name.span(),
1340            AlterIndexOperation::SetTablespace { .. } => Span::empty(),
1341        }
1342    }
1343}
1344
1345/// # partial span
1346///
1347/// Missing spans:ever
1348/// - [Insert::insert_alias]
1349impl Spanned for Insert {
1350    fn span(&self) -> Span {
1351        let Insert {
1352            insert_token,
1353            optimizer_hints: _,
1354            or: _,     // enum, sqlite specific
1355            ignore: _, // bool
1356            into: _,   // bool
1357            table,
1358            table_alias,
1359            columns,
1360            overwrite: _, // bool
1361            source,
1362            partitioned,
1363            after_columns,
1364            has_table_keyword: _, // bool
1365            on,
1366            returning,
1367            output,
1368            replace_into: _, // bool
1369            priority: _,     // todo, mysql specific
1370            insert_alias: _, // todo, mysql specific
1371            assignments,
1372            settings: _,                 // todo, clickhouse specific
1373            format_clause: _,            // todo, clickhouse specific
1374            multi_table_insert_type: _,  // snowflake multi-table insert
1375            multi_table_into_clauses: _, // snowflake multi-table insert
1376            multi_table_when_clauses: _, // snowflake multi-table insert
1377            multi_table_else_clause: _,  // snowflake multi-table insert
1378        } = self;
1379
1380        union_spans(
1381            core::iter::once(insert_token.0.span)
1382                .chain(core::iter::once(table.span()))
1383                .chain(table_alias.iter().map(|k| k.alias.span))
1384                .chain(columns.iter().map(|i| i.span()))
1385                .chain(source.as_ref().map(|q| q.span()))
1386                .chain(assignments.iter().map(|i| i.span()))
1387                .chain(partitioned.iter().flat_map(|i| i.iter().map(|k| k.span())))
1388                .chain(after_columns.iter().map(|i| i.span))
1389                .chain(on.as_ref().map(|i| i.span()))
1390                .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span())))
1391                .chain(output.iter().map(|i| i.span())),
1392        )
1393    }
1394}
1395
1396impl Spanned for OnInsert {
1397    fn span(&self) -> Span {
1398        match self {
1399            OnInsert::DuplicateKeyUpdate(vec) => union_spans(vec.iter().map(|i| i.span())),
1400            OnInsert::OnConflict(on_conflict) => on_conflict.span(),
1401        }
1402    }
1403}
1404
1405impl Spanned for OnConflict {
1406    fn span(&self) -> Span {
1407        let OnConflict {
1408            conflict_target,
1409            action,
1410        } = self;
1411
1412        action
1413            .span()
1414            .union_opt(&conflict_target.as_ref().map(|i| i.span()))
1415    }
1416}
1417
1418impl Spanned for ConflictTarget {
1419    fn span(&self) -> Span {
1420        match self {
1421            ConflictTarget::Columns(vec) => union_spans(vec.iter().map(|i| i.span)),
1422            ConflictTarget::OnConstraint(object_name) => object_name.span(),
1423        }
1424    }
1425}
1426
1427/// # partial span
1428///
1429/// Missing spans:
1430/// - [OnConflictAction::DoNothing]
1431impl Spanned for OnConflictAction {
1432    fn span(&self) -> Span {
1433        match self {
1434            OnConflictAction::DoNothing => Span::empty(),
1435            OnConflictAction::DoUpdate(do_update) => do_update.span(),
1436        }
1437    }
1438}
1439
1440impl Spanned for DoUpdate {
1441    fn span(&self) -> Span {
1442        let DoUpdate {
1443            assignments,
1444            selection,
1445        } = self;
1446
1447        union_spans(
1448            assignments
1449                .iter()
1450                .map(|i| i.span())
1451                .chain(selection.iter().map(|i| i.span())),
1452        )
1453    }
1454}
1455
1456impl Spanned for Assignment {
1457    fn span(&self) -> Span {
1458        let Assignment { target, value } = self;
1459
1460        target.span().union(&value.span())
1461    }
1462}
1463
1464impl Spanned for AssignmentTarget {
1465    fn span(&self) -> Span {
1466        match self {
1467            AssignmentTarget::ColumnName(object_name) => object_name.span(),
1468            AssignmentTarget::Tuple(vec) => union_spans(vec.iter().map(|i| i.span())),
1469        }
1470    }
1471}
1472
1473/// # partial span
1474///
1475/// Most expressions are missing keywords in their spans.
1476/// f.e. `IS NULL <expr>` reports as `<expr>::span`.
1477///
1478/// Missing spans:
1479/// - [Expr::MatchAgainst] # MySQL specific
1480/// - [Expr::RLike] # MySQL specific
1481/// - [Expr::Struct] # BigQuery specific
1482/// - [Expr::Named] # BigQuery specific
1483/// - [Expr::Dictionary] # DuckDB specific
1484/// - [Expr::Map] # DuckDB specific
1485/// - [Expr::Lambda]
1486impl Spanned for Expr {
1487    fn span(&self) -> Span {
1488        match self {
1489            Expr::Identifier(ident) => ident.span,
1490            Expr::CompoundIdentifier(vec) => union_spans(vec.iter().map(|i| i.span)),
1491            Expr::CompoundFieldAccess { root, access_chain } => {
1492                union_spans(iter::once(root.span()).chain(access_chain.iter().map(|i| i.span())))
1493            }
1494            Expr::IsFalse(expr) => expr.span(),
1495            Expr::IsNotFalse(expr) => expr.span(),
1496            Expr::IsTrue(expr) => expr.span(),
1497            Expr::IsNotTrue(expr) => expr.span(),
1498            Expr::IsNull(expr) => expr.span(),
1499            Expr::IsNotNull(expr) => expr.span(),
1500            Expr::IsUnknown(expr) => expr.span(),
1501            Expr::IsNotUnknown(expr) => expr.span(),
1502            Expr::IsDistinctFrom(lhs, rhs) => lhs.span().union(&rhs.span()),
1503            Expr::IsNotDistinctFrom(lhs, rhs) => lhs.span().union(&rhs.span()),
1504            Expr::InList {
1505                expr,
1506                list,
1507                negated: _,
1508            } => union_spans(
1509                core::iter::once(expr.span()).chain(list.iter().map(|item| item.span())),
1510            ),
1511            Expr::InSubquery {
1512                expr,
1513                subquery,
1514                negated: _,
1515            } => expr.span().union(&subquery.span()),
1516            Expr::InUnnest {
1517                expr,
1518                array_expr,
1519                negated: _,
1520            } => expr.span().union(&array_expr.span()),
1521            Expr::Between {
1522                expr,
1523                negated: _,
1524                low,
1525                high,
1526            } => expr.span().union(&low.span()).union(&high.span()),
1527
1528            Expr::BinaryOp { left, op: _, right } => left.span().union(&right.span()),
1529            Expr::Like {
1530                negated: _,
1531                expr,
1532                pattern,
1533                escape_char: _,
1534                any: _,
1535            } => expr.span().union(&pattern.span()),
1536            Expr::ILike {
1537                negated: _,
1538                expr,
1539                pattern,
1540                escape_char: _,
1541                any: _,
1542            } => expr.span().union(&pattern.span()),
1543            Expr::RLike { .. } => Span::empty(),
1544            Expr::IsNormalized {
1545                expr,
1546                form: _,
1547                negated: _,
1548            } => expr.span(),
1549            Expr::SimilarTo {
1550                negated: _,
1551                expr,
1552                pattern,
1553                escape_char: _,
1554            } => expr.span().union(&pattern.span()),
1555            Expr::Ceil { expr, field: _ } => expr.span(),
1556            Expr::Floor { expr, field: _ } => expr.span(),
1557            Expr::Position { expr, r#in } => expr.span().union(&r#in.span()),
1558            Expr::Overlay {
1559                expr,
1560                overlay_what,
1561                overlay_from,
1562                overlay_for,
1563            } => expr
1564                .span()
1565                .union(&overlay_what.span())
1566                .union(&overlay_from.span())
1567                .union_opt(&overlay_for.as_ref().map(|i| i.span())),
1568            Expr::Collate { expr, collation } => expr
1569                .span()
1570                .union(&union_spans(collation.0.iter().map(|i| i.span()))),
1571            Expr::Nested(expr) => expr.span(),
1572            Expr::Value(value) => value.span(),
1573            Expr::TypedString(TypedString { value, .. }) => value.span(),
1574            Expr::Function(function) => function.span(),
1575            Expr::GroupingSets(vec) => {
1576                union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span())))
1577            }
1578            Expr::Cube(vec) => union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1579            Expr::Rollup(vec) => union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1580            Expr::Tuple(vec) => union_spans(vec.iter().map(|i| i.span())),
1581            Expr::Array(array) => array.span(),
1582            Expr::MatchAgainst { .. } => Span::empty(),
1583            Expr::JsonAccess { value, path } => value.span().union(&path.span()),
1584            Expr::AnyOp {
1585                left,
1586                compare_op: _,
1587                right,
1588                is_some: _,
1589            } => left.span().union(&right.span()),
1590            Expr::AllOp {
1591                left,
1592                compare_op: _,
1593                right,
1594            } => left.span().union(&right.span()),
1595            Expr::UnaryOp { op: _, expr } => expr.span(),
1596            Expr::Convert {
1597                expr,
1598                data_type: _,
1599                charset,
1600                target_before_value: _,
1601                styles,
1602                is_try: _,
1603            } => union_spans(
1604                core::iter::once(expr.span())
1605                    .chain(charset.as_ref().map(|i| i.span()))
1606                    .chain(styles.iter().map(|i| i.span())),
1607            ),
1608            Expr::Cast {
1609                kind: _,
1610                expr,
1611                data_type: _,
1612                array: _,
1613                format: _,
1614            } => expr.span(),
1615            Expr::AtTimeZone {
1616                timestamp,
1617                time_zone,
1618            } => timestamp.span().union(&time_zone.span()),
1619            Expr::Extract {
1620                field: _,
1621                syntax: _,
1622                expr,
1623            } => expr.span(),
1624            Expr::Substring {
1625                expr,
1626                substring_from,
1627                substring_for,
1628                special: _,
1629                shorthand: _,
1630            } => union_spans(
1631                core::iter::once(expr.span())
1632                    .chain(substring_from.as_ref().map(|i| i.span()))
1633                    .chain(substring_for.as_ref().map(|i| i.span())),
1634            ),
1635            Expr::Trim {
1636                expr,
1637                trim_where: _,
1638                trim_what,
1639                trim_characters,
1640            } => union_spans(
1641                core::iter::once(expr.span())
1642                    .chain(trim_what.as_ref().map(|i| i.span()))
1643                    .chain(
1644                        trim_characters
1645                            .as_ref()
1646                            .map(|items| union_spans(items.iter().map(|i| i.span()))),
1647                    ),
1648            ),
1649            Expr::Prefixed { value, .. } => value.span(),
1650            Expr::Case {
1651                case_token,
1652                end_token,
1653                operand,
1654                conditions,
1655                else_result,
1656            } => union_spans(
1657                iter::once(case_token.0.span)
1658                    .chain(
1659                        operand
1660                            .as_ref()
1661                            .map(|i| i.span())
1662                            .into_iter()
1663                            .chain(conditions.iter().flat_map(|case_when| {
1664                                [case_when.condition.span(), case_when.result.span()]
1665                            }))
1666                            .chain(else_result.as_ref().map(|i| i.span())),
1667                    )
1668                    .chain(iter::once(end_token.0.span)),
1669            ),
1670            Expr::Exists { subquery, .. } => subquery.span(),
1671            Expr::Subquery(query) => query.span(),
1672            Expr::Struct { .. } => Span::empty(),
1673            Expr::Named { .. } => Span::empty(),
1674            Expr::Dictionary(_) => Span::empty(),
1675            Expr::Map(_) => Span::empty(),
1676            Expr::Interval(interval) => interval.value.span(),
1677            Expr::Wildcard(token) => token.0.span,
1678            Expr::QualifiedWildcard(object_name, token) => union_spans(
1679                object_name
1680                    .0
1681                    .iter()
1682                    .map(|i| i.span())
1683                    .chain(iter::once(token.0.span)),
1684            ),
1685            Expr::OuterJoin(expr) => expr.span(),
1686            Expr::Prior(expr) => expr.span(),
1687            Expr::Lambda(_) => Span::empty(),
1688            Expr::MemberOf(member_of) => member_of.value.span().union(&member_of.array.span()),
1689        }
1690    }
1691}
1692
1693impl Spanned for Subscript {
1694    fn span(&self) -> Span {
1695        match self {
1696            Subscript::Index { index } => index.span(),
1697            Subscript::Slice {
1698                lower_bound,
1699                upper_bound,
1700                stride,
1701            } => union_spans(
1702                [
1703                    lower_bound.as_ref().map(|i| i.span()),
1704                    upper_bound.as_ref().map(|i| i.span()),
1705                    stride.as_ref().map(|i| i.span()),
1706                ]
1707                .into_iter()
1708                .flatten(),
1709            ),
1710        }
1711    }
1712}
1713
1714impl Spanned for AccessExpr {
1715    fn span(&self) -> Span {
1716        match self {
1717            AccessExpr::Dot(ident) => ident.span(),
1718            AccessExpr::Subscript(subscript) => subscript.span(),
1719        }
1720    }
1721}
1722
1723impl Spanned for ObjectName {
1724    fn span(&self) -> Span {
1725        let ObjectName(segments) = self;
1726
1727        union_spans(segments.iter().map(|i| i.span()))
1728    }
1729}
1730
1731impl Spanned for ObjectNamePart {
1732    fn span(&self) -> Span {
1733        match self {
1734            ObjectNamePart::Identifier(ident) => ident.span,
1735            ObjectNamePart::Function(func) => func
1736                .name
1737                .span
1738                .union(&union_spans(func.args.iter().map(|i| i.span()))),
1739        }
1740    }
1741}
1742
1743impl Spanned for Array {
1744    fn span(&self) -> Span {
1745        let Array {
1746            elem,
1747            named: _, // bool
1748        } = self;
1749
1750        union_spans(elem.iter().map(|i| i.span()))
1751    }
1752}
1753
1754impl Spanned for Function {
1755    fn span(&self) -> Span {
1756        let Function {
1757            name,
1758            uses_odbc_syntax: _,
1759            parameters,
1760            args,
1761            filter,
1762            null_treatment: _, // enum
1763            over: _,           // todo
1764            within_group,
1765        } = self;
1766
1767        union_spans(
1768            name.0
1769                .iter()
1770                .map(|i| i.span())
1771                .chain(iter::once(args.span()))
1772                .chain(iter::once(parameters.span()))
1773                .chain(filter.iter().map(|i| i.span()))
1774                .chain(within_group.iter().map(|i| i.span())),
1775        )
1776    }
1777}
1778
1779/// # partial span
1780///
1781/// The span of [FunctionArguments::None] is empty.
1782impl Spanned for FunctionArguments {
1783    fn span(&self) -> Span {
1784        match self {
1785            FunctionArguments::None => Span::empty(),
1786            FunctionArguments::Subquery(query) => query.span(),
1787            FunctionArguments::List(list) => list.span(),
1788        }
1789    }
1790}
1791
1792impl Spanned for FunctionArgumentList {
1793    fn span(&self) -> Span {
1794        let FunctionArgumentList {
1795            duplicate_treatment: _, // enum
1796            args,
1797            clauses,
1798        } = self;
1799
1800        union_spans(
1801            // # todo: duplicate-treatment span
1802            args.iter()
1803                .map(|i| i.span())
1804                .chain(clauses.iter().map(|i| i.span())),
1805        )
1806    }
1807}
1808
1809impl Spanned for FunctionArgumentClause {
1810    fn span(&self) -> Span {
1811        match self {
1812            FunctionArgumentClause::IgnoreOrRespectNulls(_) => Span::empty(),
1813            FunctionArgumentClause::OrderBy(vec) => union_spans(vec.iter().map(|i| i.expr.span())),
1814            FunctionArgumentClause::Limit(expr) => expr.span(),
1815            FunctionArgumentClause::OnOverflow(_) => Span::empty(),
1816            FunctionArgumentClause::Having(HavingBound(_kind, expr)) => expr.span(),
1817            FunctionArgumentClause::Separator(value) => value.span(),
1818            FunctionArgumentClause::JsonNullClause(_) => Span::empty(),
1819            FunctionArgumentClause::JsonReturningClause(_) => Span::empty(),
1820        }
1821    }
1822}
1823
1824/// # partial span
1825///
1826/// see Spanned impl for JsonPathElem for more information
1827impl Spanned for JsonPath {
1828    fn span(&self) -> Span {
1829        let JsonPath { path } = self;
1830
1831        union_spans(path.iter().map(|i| i.span()))
1832    }
1833}
1834
1835/// # partial span
1836///
1837/// Missing spans:
1838/// - [JsonPathElem::Dot]
1839impl Spanned for JsonPathElem {
1840    fn span(&self) -> Span {
1841        match self {
1842            JsonPathElem::Dot { .. } => Span::empty(),
1843            JsonPathElem::Bracket { key } => key.span(),
1844            JsonPathElem::ColonBracket { key } => key.span(),
1845        }
1846    }
1847}
1848
1849impl Spanned for SelectItemQualifiedWildcardKind {
1850    fn span(&self) -> Span {
1851        match self {
1852            SelectItemQualifiedWildcardKind::ObjectName(object_name) => object_name.span(),
1853            SelectItemQualifiedWildcardKind::Expr(expr) => expr.span(),
1854        }
1855    }
1856}
1857
1858impl Spanned for SelectItem {
1859    fn span(&self) -> Span {
1860        match self {
1861            SelectItem::UnnamedExpr(expr) => expr.span(),
1862            SelectItem::ExprWithAlias { expr, alias } => expr.span().union(&alias.span),
1863            SelectItem::ExprWithAliases { expr, aliases } => {
1864                union_spans(iter::once(expr.span()).chain(aliases.iter().map(|i| i.span)))
1865            }
1866            SelectItem::QualifiedWildcard(kind, wildcard_additional_options) => union_spans(
1867                [kind.span()]
1868                    .into_iter()
1869                    .chain(iter::once(wildcard_additional_options.span())),
1870            ),
1871            SelectItem::Wildcard(wildcard_additional_options) => wildcard_additional_options.span(),
1872        }
1873    }
1874}
1875
1876impl Spanned for WildcardAdditionalOptions {
1877    fn span(&self) -> Span {
1878        let WildcardAdditionalOptions {
1879            wildcard_token,
1880            opt_ilike,
1881            opt_exclude,
1882            opt_except,
1883            opt_replace,
1884            opt_rename,
1885            opt_alias,
1886        } = self;
1887
1888        union_spans(
1889            core::iter::once(wildcard_token.0.span)
1890                .chain(opt_ilike.as_ref().map(|i| i.span()))
1891                .chain(opt_exclude.as_ref().map(|i| i.span()))
1892                .chain(opt_rename.as_ref().map(|i| i.span()))
1893                .chain(opt_replace.as_ref().map(|i| i.span()))
1894                .chain(opt_except.as_ref().map(|i| i.span()))
1895                .chain(opt_alias.as_ref().map(|i| i.span)),
1896        )
1897    }
1898}
1899
1900/// # missing span
1901impl Spanned for IlikeSelectItem {
1902    fn span(&self) -> Span {
1903        Span::empty()
1904    }
1905}
1906
1907impl Spanned for ExcludeSelectItem {
1908    fn span(&self) -> Span {
1909        match self {
1910            ExcludeSelectItem::Single(name) => name.span(),
1911            ExcludeSelectItem::Multiple(vec) => union_spans(vec.iter().map(|i| i.span())),
1912        }
1913    }
1914}
1915
1916impl Spanned for RenameSelectItem {
1917    fn span(&self) -> Span {
1918        match self {
1919            RenameSelectItem::Single(ident) => ident.ident.span.union(&ident.alias.span),
1920            RenameSelectItem::Multiple(vec) => {
1921                union_spans(vec.iter().map(|i| i.ident.span.union(&i.alias.span)))
1922            }
1923        }
1924    }
1925}
1926
1927impl Spanned for ExceptSelectItem {
1928    fn span(&self) -> Span {
1929        let ExceptSelectItem {
1930            first_element,
1931            additional_elements,
1932        } = self;
1933
1934        union_spans(
1935            iter::once(first_element.span).chain(additional_elements.iter().map(|i| i.span)),
1936        )
1937    }
1938}
1939
1940impl Spanned for ReplaceSelectItem {
1941    fn span(&self) -> Span {
1942        let ReplaceSelectItem { items } = self;
1943
1944        union_spans(items.iter().map(|i| i.span()))
1945    }
1946}
1947
1948impl Spanned for ReplaceSelectElement {
1949    fn span(&self) -> Span {
1950        let ReplaceSelectElement {
1951            expr,
1952            column_name,
1953            as_keyword: _, // bool
1954        } = self;
1955
1956        expr.span().union(&column_name.span)
1957    }
1958}
1959
1960/// # partial span
1961///
1962/// Missing spans:
1963/// - [TableFactor::JsonTable]
1964impl Spanned for TableFactor {
1965    fn span(&self) -> Span {
1966        match self {
1967            TableFactor::Table {
1968                name,
1969                alias,
1970                args: _,
1971                with_hints: _,
1972                version: _,
1973                with_ordinality: _,
1974                partitions: _,
1975                json_path: _,
1976                sample: _,
1977                index_hints: _,
1978            } => union_spans(
1979                name.0
1980                    .iter()
1981                    .map(|i| i.span())
1982                    .chain(alias.as_ref().map(|alias| {
1983                        union_spans(
1984                            iter::once(alias.name.span)
1985                                .chain(alias.columns.iter().map(|i| i.span())),
1986                        )
1987                    })),
1988            ),
1989            TableFactor::Derived {
1990                lateral: _,
1991                subquery,
1992                alias,
1993                sample: _,
1994            } => subquery
1995                .span()
1996                .union_opt(&alias.as_ref().map(|alias| alias.span())),
1997            TableFactor::TableFunction { expr, alias } => expr
1998                .span()
1999                .union_opt(&alias.as_ref().map(|alias| alias.span())),
2000            TableFactor::UNNEST {
2001                alias,
2002                with_offset: _,
2003                with_offset_alias,
2004                array_exprs,
2005                with_ordinality: _,
2006            } => union_spans(
2007                alias
2008                    .iter()
2009                    .map(|i| i.span())
2010                    .chain(array_exprs.iter().map(|i| i.span()))
2011                    .chain(with_offset_alias.as_ref().map(|i| i.span)),
2012            ),
2013            TableFactor::NestedJoin {
2014                table_with_joins,
2015                alias,
2016            } => table_with_joins
2017                .span()
2018                .union_opt(&alias.as_ref().map(|alias| alias.span())),
2019            TableFactor::Function {
2020                lateral: _,
2021                name,
2022                args,
2023                alias,
2024            } => union_spans(
2025                name.0
2026                    .iter()
2027                    .map(|i| i.span())
2028                    .chain(args.iter().map(|i| i.span()))
2029                    .chain(alias.as_ref().map(|alias| alias.span())),
2030            ),
2031            TableFactor::JsonTable { .. } => Span::empty(),
2032            TableFactor::XmlTable { .. } => Span::empty(),
2033            TableFactor::Pivot {
2034                table,
2035                aggregate_functions,
2036                value_column,
2037                value_source,
2038                default_on_null,
2039                alias,
2040            } => union_spans(
2041                core::iter::once(table.span())
2042                    .chain(aggregate_functions.iter().map(|i| i.span()))
2043                    .chain(value_column.iter().map(|i| i.span()))
2044                    .chain(core::iter::once(value_source.span()))
2045                    .chain(default_on_null.as_ref().map(|i| i.span()))
2046                    .chain(alias.as_ref().map(|i| i.span())),
2047            ),
2048            TableFactor::Unpivot {
2049                table,
2050                value,
2051                null_inclusion: _,
2052                name,
2053                columns,
2054                alias,
2055            } => union_spans(
2056                core::iter::once(table.span())
2057                    .chain(core::iter::once(value.span()))
2058                    .chain(core::iter::once(name.span))
2059                    .chain(columns.iter().map(|ilist| ilist.span()))
2060                    .chain(alias.as_ref().map(|alias| alias.span())),
2061            ),
2062            TableFactor::MatchRecognize {
2063                table,
2064                partition_by,
2065                order_by,
2066                measures,
2067                rows_per_match: _,
2068                after_match_skip: _,
2069                pattern,
2070                symbols,
2071                alias,
2072            } => union_spans(
2073                core::iter::once(table.span())
2074                    .chain(partition_by.iter().map(|i| i.span()))
2075                    .chain(order_by.iter().map(|i| i.span()))
2076                    .chain(measures.iter().map(|i| i.span()))
2077                    .chain(core::iter::once(pattern.span()))
2078                    .chain(symbols.iter().map(|i| i.span()))
2079                    .chain(alias.as_ref().map(|i| i.span())),
2080            ),
2081            TableFactor::SemanticView {
2082                name,
2083                dimensions,
2084                metrics,
2085                facts,
2086                where_clause,
2087                alias,
2088            } => union_spans(
2089                name.0
2090                    .iter()
2091                    .map(|i| i.span())
2092                    .chain(dimensions.iter().map(|d| d.span()))
2093                    .chain(metrics.iter().map(|m| m.span()))
2094                    .chain(facts.iter().map(|f| f.span()))
2095                    .chain(where_clause.as_ref().map(|e| e.span()))
2096                    .chain(alias.as_ref().map(|a| a.span())),
2097            ),
2098            TableFactor::OpenJsonTable { .. } => Span::empty(),
2099        }
2100    }
2101}
2102
2103impl Spanned for PivotValueSource {
2104    fn span(&self) -> Span {
2105        match self {
2106            PivotValueSource::List(vec) => union_spans(vec.iter().map(|i| i.span())),
2107            PivotValueSource::Any(vec) => union_spans(vec.iter().map(|i| i.span())),
2108            PivotValueSource::Subquery(query) => query.span(),
2109        }
2110    }
2111}
2112
2113impl Spanned for ExprWithAlias {
2114    fn span(&self) -> Span {
2115        let ExprWithAlias { expr, alias } = self;
2116
2117        expr.span().union_opt(&alias.as_ref().map(|i| i.span))
2118    }
2119}
2120
2121/// # missing span
2122impl Spanned for MatchRecognizePattern {
2123    fn span(&self) -> Span {
2124        Span::empty()
2125    }
2126}
2127
2128impl Spanned for SymbolDefinition {
2129    fn span(&self) -> Span {
2130        let SymbolDefinition { symbol, definition } = self;
2131
2132        symbol.span.union(&definition.span())
2133    }
2134}
2135
2136impl Spanned for Measure {
2137    fn span(&self) -> Span {
2138        let Measure { expr, alias } = self;
2139
2140        expr.span().union(&alias.span)
2141    }
2142}
2143
2144impl Spanned for OrderByExpr {
2145    fn span(&self) -> Span {
2146        let OrderByExpr {
2147            expr,
2148            options: _,
2149            with_fill,
2150        } = self;
2151
2152        expr.span().union_opt(&with_fill.as_ref().map(|f| f.span()))
2153    }
2154}
2155
2156impl Spanned for WithFill {
2157    fn span(&self) -> Span {
2158        let WithFill { from, to, step } = self;
2159
2160        union_spans(
2161            from.iter()
2162                .map(|f| f.span())
2163                .chain(to.iter().map(|t| t.span()))
2164                .chain(step.iter().map(|s| s.span())),
2165        )
2166    }
2167}
2168
2169impl Spanned for FunctionArg {
2170    fn span(&self) -> Span {
2171        match self {
2172            FunctionArg::Named {
2173                name,
2174                arg,
2175                operator: _,
2176            } => name.span.union(&arg.span()),
2177            FunctionArg::Unnamed(arg) => arg.span(),
2178            FunctionArg::ExprNamed {
2179                name,
2180                arg,
2181                operator: _,
2182            } => name.span().union(&arg.span()),
2183        }
2184    }
2185}
2186
2187/// # partial span
2188///
2189/// Missing spans:
2190/// - [FunctionArgExpr::Wildcard]
2191/// - [FunctionArgExpr::WildcardWithOptions]
2192impl Spanned for FunctionArgExpr {
2193    fn span(&self) -> Span {
2194        match self {
2195            FunctionArgExpr::Expr(expr) => expr.span(),
2196            FunctionArgExpr::QualifiedWildcard(object_name) => {
2197                union_spans(object_name.0.iter().map(|i| i.span()))
2198            }
2199            FunctionArgExpr::Wildcard => Span::empty(),
2200            FunctionArgExpr::WildcardWithOptions(_) => Span::empty(),
2201        }
2202    }
2203}
2204
2205impl Spanned for TableAlias {
2206    fn span(&self) -> Span {
2207        let TableAlias {
2208            explicit: _,
2209            name,
2210            columns,
2211        } = self;
2212        union_spans(core::iter::once(name.span).chain(columns.iter().map(Spanned::span)))
2213    }
2214}
2215
2216impl Spanned for TableAliasColumnDef {
2217    fn span(&self) -> Span {
2218        let TableAliasColumnDef { name, data_type: _ } = self;
2219
2220        name.span
2221    }
2222}
2223
2224impl Spanned for ValueWithSpan {
2225    fn span(&self) -> Span {
2226        self.span
2227    }
2228}
2229
2230impl Spanned for Join {
2231    fn span(&self) -> Span {
2232        let Join {
2233            relation,
2234            global: _, // bool
2235            join_operator,
2236        } = self;
2237
2238        relation.span().union(&join_operator.span())
2239    }
2240}
2241
2242/// # partial span
2243///
2244/// Missing spans:
2245/// - [JoinOperator::CrossJoin]
2246/// - [JoinOperator::CrossApply]
2247/// - [JoinOperator::OuterApply]
2248impl Spanned for JoinOperator {
2249    fn span(&self) -> Span {
2250        match self {
2251            JoinOperator::Join(join_constraint) => join_constraint.span(),
2252            JoinOperator::Inner(join_constraint) => join_constraint.span(),
2253            JoinOperator::Left(join_constraint) => join_constraint.span(),
2254            JoinOperator::LeftOuter(join_constraint) => join_constraint.span(),
2255            JoinOperator::Right(join_constraint) => join_constraint.span(),
2256            JoinOperator::RightOuter(join_constraint) => join_constraint.span(),
2257            JoinOperator::FullOuter(join_constraint) => join_constraint.span(),
2258            JoinOperator::CrossJoin(join_constraint) => join_constraint.span(),
2259            JoinOperator::LeftSemi(join_constraint) => join_constraint.span(),
2260            JoinOperator::RightSemi(join_constraint) => join_constraint.span(),
2261            JoinOperator::LeftAnti(join_constraint) => join_constraint.span(),
2262            JoinOperator::RightAnti(join_constraint) => join_constraint.span(),
2263            JoinOperator::CrossApply => Span::empty(),
2264            JoinOperator::OuterApply => Span::empty(),
2265            JoinOperator::AsOf {
2266                match_condition,
2267                constraint,
2268            } => match_condition.span().union(&constraint.span()),
2269            JoinOperator::Anti(join_constraint) => join_constraint.span(),
2270            JoinOperator::Semi(join_constraint) => join_constraint.span(),
2271            JoinOperator::StraightJoin(join_constraint) => join_constraint.span(),
2272        }
2273    }
2274}
2275
2276/// # partial span
2277///
2278/// Missing spans:
2279/// - [JoinConstraint::Natural]
2280/// - [JoinConstraint::None]
2281impl Spanned for JoinConstraint {
2282    fn span(&self) -> Span {
2283        match self {
2284            JoinConstraint::On(expr) => expr.span(),
2285            JoinConstraint::Using(vec) => union_spans(vec.iter().map(|i| i.span())),
2286            JoinConstraint::Natural => Span::empty(),
2287            JoinConstraint::None => Span::empty(),
2288        }
2289    }
2290}
2291
2292impl Spanned for TableWithJoins {
2293    fn span(&self) -> Span {
2294        let TableWithJoins { relation, joins } = self;
2295
2296        union_spans(core::iter::once(relation.span()).chain(joins.iter().map(|item| item.span())))
2297    }
2298}
2299
2300impl Spanned for Select {
2301    fn span(&self) -> Span {
2302        let Select {
2303            select_token,
2304            optimizer_hints: _,
2305            distinct: _, // todo
2306            select_modifiers: _,
2307            top: _, // todo, mysql specific
2308            projection,
2309            exclude: _,
2310            into,
2311            from,
2312            lateral_views,
2313            prewhere,
2314            selection,
2315            group_by,
2316            cluster_by,
2317            distribute_by,
2318            sort_by,
2319            having,
2320            named_window,
2321            qualify,
2322            window_before_qualify: _, // bool
2323            value_table_mode: _,      // todo, BigQuery specific
2324            connect_by,
2325            top_before_distinct: _,
2326            flavor: _,
2327        } = self;
2328
2329        union_spans(
2330            core::iter::once(select_token.0.span)
2331                .chain(projection.iter().map(|item| item.span()))
2332                .chain(into.iter().map(|item| item.span()))
2333                .chain(from.iter().map(|item| item.span()))
2334                .chain(lateral_views.iter().map(|item| item.span()))
2335                .chain(prewhere.iter().map(|item| item.span()))
2336                .chain(selection.iter().map(|item| item.span()))
2337                .chain(connect_by.iter().map(|item| item.span()))
2338                .chain(core::iter::once(group_by.span()))
2339                .chain(cluster_by.iter().map(|item| item.span()))
2340                .chain(distribute_by.iter().map(|item| item.span()))
2341                .chain(sort_by.iter().map(|item| item.span()))
2342                .chain(having.iter().map(|item| item.span()))
2343                .chain(named_window.iter().map(|item| item.span()))
2344                .chain(qualify.iter().map(|item| item.span())),
2345        )
2346    }
2347}
2348
2349impl Spanned for ConnectByKind {
2350    fn span(&self) -> Span {
2351        match self {
2352            ConnectByKind::ConnectBy {
2353                connect_token,
2354                nocycle: _,
2355                relationships,
2356            } => union_spans(
2357                core::iter::once(connect_token.0.span())
2358                    .chain(relationships.last().iter().map(|item| item.span())),
2359            ),
2360            ConnectByKind::StartWith {
2361                start_token,
2362                condition,
2363            } => union_spans([start_token.0.span(), condition.span()].into_iter()),
2364        }
2365    }
2366}
2367
2368impl Spanned for NamedWindowDefinition {
2369    fn span(&self) -> Span {
2370        let NamedWindowDefinition(
2371            ident,
2372            _, // todo: NamedWindowExpr
2373        ) = self;
2374
2375        ident.span
2376    }
2377}
2378
2379impl Spanned for LateralView {
2380    fn span(&self) -> Span {
2381        let LateralView {
2382            lateral_view,
2383            lateral_view_name,
2384            lateral_col_alias,
2385            outer: _, // bool
2386        } = self;
2387
2388        union_spans(
2389            core::iter::once(lateral_view.span())
2390                .chain(core::iter::once(lateral_view_name.span()))
2391                .chain(lateral_col_alias.iter().map(|i| i.span)),
2392        )
2393    }
2394}
2395
2396impl Spanned for SelectInto {
2397    fn span(&self) -> Span {
2398        let SelectInto {
2399            temporary: _, // bool
2400            unlogged: _,  // bool
2401            table: _,     // bool
2402            name,
2403        } = self;
2404
2405        name.span()
2406    }
2407}
2408
2409impl Spanned for UpdateTableFromKind {
2410    fn span(&self) -> Span {
2411        let from = match self {
2412            UpdateTableFromKind::BeforeSet(from) => from,
2413            UpdateTableFromKind::AfterSet(from) => from,
2414        };
2415        union_spans(from.iter().map(|t| t.span()))
2416    }
2417}
2418
2419impl Spanned for TableObject {
2420    fn span(&self) -> Span {
2421        match self {
2422            TableObject::TableName(ObjectName(segments)) => {
2423                union_spans(segments.iter().map(|i| i.span()))
2424            }
2425            TableObject::TableFunction(func) => func.span(),
2426            TableObject::TableQuery(query) => query.span(),
2427        }
2428    }
2429}
2430
2431impl Spanned for BeginEndStatements {
2432    fn span(&self) -> Span {
2433        let BeginEndStatements {
2434            begin_token,
2435            statements,
2436            end_token,
2437        } = self;
2438        union_spans(
2439            core::iter::once(begin_token.0.span)
2440                .chain(statements.iter().map(|i| i.span()))
2441                .chain(core::iter::once(end_token.0.span)),
2442        )
2443    }
2444}
2445
2446impl Spanned for OpenStatement {
2447    fn span(&self) -> Span {
2448        let OpenStatement { cursor_name } = self;
2449        cursor_name.span
2450    }
2451}
2452
2453impl Spanned for AlterSchemaOperation {
2454    fn span(&self) -> Span {
2455        match self {
2456            AlterSchemaOperation::SetDefaultCollate { collate } => collate.span(),
2457            AlterSchemaOperation::AddReplica { replica, options } => union_spans(
2458                core::iter::once(replica.span)
2459                    .chain(options.iter().flat_map(|i| i.iter().map(|i| i.span()))),
2460            ),
2461            AlterSchemaOperation::DropReplica { replica } => replica.span,
2462            AlterSchemaOperation::SetOptionsParens { options } => {
2463                union_spans(options.iter().map(|i| i.span()))
2464            }
2465            AlterSchemaOperation::Rename { name } => name.span(),
2466            AlterSchemaOperation::OwnerTo { owner } => {
2467                if let Owner::Ident(ident) = owner {
2468                    ident.span
2469                } else {
2470                    Span::empty()
2471                }
2472            }
2473        }
2474    }
2475}
2476
2477impl Spanned for AlterSchema {
2478    fn span(&self) -> Span {
2479        union_spans(
2480            core::iter::once(self.name.span()).chain(self.operations.iter().map(|i| i.span())),
2481        )
2482    }
2483}
2484
2485impl Spanned for CreateView {
2486    fn span(&self) -> Span {
2487        union_spans(
2488            core::iter::once(self.name.span())
2489                .chain(self.columns.iter().map(|i| i.span()))
2490                .chain(core::iter::once(self.query.span()))
2491                .chain(core::iter::once(self.options.span()))
2492                .chain(self.cluster_by.iter().map(|i| i.span))
2493                .chain(self.to.iter().map(|i| i.span())),
2494        )
2495    }
2496}
2497
2498impl Spanned for AlterTable {
2499    fn span(&self) -> Span {
2500        union_spans(
2501            core::iter::once(self.name.span())
2502                .chain(self.operations.iter().map(|i| i.span()))
2503                .chain(self.on_cluster.iter().map(|i| i.span))
2504                .chain(core::iter::once(self.end_token.0.span)),
2505        )
2506    }
2507}
2508
2509impl Spanned for CreateOperator {
2510    fn span(&self) -> Span {
2511        Span::empty()
2512    }
2513}
2514
2515impl Spanned for CreateOperatorFamily {
2516    fn span(&self) -> Span {
2517        Span::empty()
2518    }
2519}
2520
2521impl Spanned for CreateOperatorClass {
2522    fn span(&self) -> Span {
2523        Span::empty()
2524    }
2525}
2526
2527impl Spanned for MergeClause {
2528    fn span(&self) -> Span {
2529        union_spans([self.when_token.0.span, self.action.span()].into_iter())
2530    }
2531}
2532
2533impl Spanned for MergeAction {
2534    fn span(&self) -> Span {
2535        match self {
2536            MergeAction::Insert(expr) => expr.span(),
2537            MergeAction::Update(expr) => expr.span(),
2538            MergeAction::Delete { delete_token } => delete_token.0.span,
2539        }
2540    }
2541}
2542
2543impl Spanned for MergeInsertExpr {
2544    fn span(&self) -> Span {
2545        union_spans(
2546            [
2547                self.insert_token.0.span,
2548                self.kind_token.0.span,
2549                match self.kind {
2550                    MergeInsertKind::Values(ref values) => values.span(),
2551                    MergeInsertKind::Row => Span::empty(), // ~ covered by `kind_token`
2552                },
2553            ]
2554            .into_iter()
2555            .chain(self.insert_predicate.iter().map(Spanned::span))
2556            .chain(self.columns.iter().map(|i| i.span())),
2557        )
2558    }
2559}
2560
2561impl Spanned for MergeUpdateExpr {
2562    fn span(&self) -> Span {
2563        union_spans(
2564            core::iter::once(self.update_token.0.span)
2565                .chain(self.assignments.iter().map(Spanned::span))
2566                .chain(self.update_predicate.iter().map(Spanned::span))
2567                .chain(self.delete_predicate.iter().map(Spanned::span)),
2568        )
2569    }
2570}
2571
2572impl Spanned for OutputClause {
2573    fn span(&self) -> Span {
2574        match self {
2575            OutputClause::Output {
2576                output_token,
2577                select_items,
2578                into_table,
2579            } => union_spans(
2580                core::iter::once(output_token.0.span)
2581                    .chain(into_table.iter().map(Spanned::span))
2582                    .chain(select_items.iter().map(Spanned::span)),
2583            ),
2584            OutputClause::Returning {
2585                returning_token,
2586                select_items,
2587            } => union_spans(
2588                core::iter::once(returning_token.0.span)
2589                    .chain(select_items.iter().map(Spanned::span)),
2590            ),
2591        }
2592    }
2593}
2594
2595impl Spanned for comments::CommentWithSpan {
2596    fn span(&self) -> Span {
2597        self.span
2598    }
2599}
2600
2601#[cfg(test)]
2602pub mod tests {
2603    use crate::ast::Value;
2604    use crate::dialect::{Dialect, GenericDialect, SnowflakeDialect};
2605    use crate::parser::Parser;
2606    use crate::tokenizer::{Location, Span};
2607
2608    use super::*;
2609
2610    struct SpanTest<'a>(Parser<'a>, &'a str);
2611
2612    impl<'a> SpanTest<'a> {
2613        fn new(dialect: &'a dyn Dialect, sql: &'a str) -> Self {
2614            Self(Parser::new(dialect).try_with_sql(sql).unwrap(), sql)
2615        }
2616
2617        // get the subsection of the source string that corresponds to the span
2618        // only works on single-line strings
2619        fn get_source(&self, span: Span) -> &'a str {
2620            // lines in spans are 1-indexed
2621            &self.1[(span.start.column as usize - 1)..(span.end.column - 1) as usize]
2622        }
2623    }
2624
2625    #[test]
2626    fn test_join() {
2627        let dialect = &GenericDialect;
2628        let mut test = SpanTest::new(
2629            dialect,
2630            "SELECT id, name FROM users LEFT JOIN companies ON users.company_id = companies.id",
2631        );
2632
2633        let query = test.0.parse_select().unwrap();
2634        let select_span = query.span();
2635
2636        assert_eq!(
2637            test.get_source(select_span),
2638            "SELECT id, name FROM users LEFT JOIN companies ON users.company_id = companies.id"
2639        );
2640
2641        let join_span = query.from[0].joins[0].span();
2642
2643        // 'LEFT JOIN' missing
2644        assert_eq!(
2645            test.get_source(join_span),
2646            "companies ON users.company_id = companies.id"
2647        );
2648    }
2649
2650    #[test]
2651    pub fn test_union() {
2652        let dialect = &GenericDialect;
2653        let mut test = SpanTest::new(
2654            dialect,
2655            "SELECT a FROM postgres.public.source UNION SELECT a FROM postgres.public.source",
2656        );
2657
2658        let query = test.0.parse_query().unwrap();
2659        let select_span = query.span();
2660
2661        assert_eq!(
2662            test.get_source(select_span),
2663            "SELECT a FROM postgres.public.source UNION SELECT a FROM postgres.public.source"
2664        );
2665    }
2666
2667    #[test]
2668    pub fn test_subquery() {
2669        let dialect = &GenericDialect;
2670        let mut test = SpanTest::new(
2671            dialect,
2672            "SELECT a FROM (SELECT a FROM postgres.public.source) AS b",
2673        );
2674
2675        let query = test.0.parse_select().unwrap();
2676        let select_span = query.span();
2677
2678        assert_eq!(
2679            test.get_source(select_span),
2680            "SELECT a FROM (SELECT a FROM postgres.public.source) AS b"
2681        );
2682
2683        let subquery_span = query.from[0].span();
2684
2685        // left paren missing
2686        assert_eq!(
2687            test.get_source(subquery_span),
2688            "SELECT a FROM postgres.public.source) AS b"
2689        );
2690    }
2691
2692    #[test]
2693    pub fn test_cte() {
2694        let dialect = &GenericDialect;
2695        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");
2696
2697        let query = test.0.parse_query().unwrap();
2698
2699        let select_span = query.span();
2700
2701        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");
2702    }
2703
2704    #[test]
2705    pub fn test_snowflake_lateral_flatten() {
2706        let dialect = &SnowflakeDialect;
2707        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");
2708
2709        let query = test.0.parse_select().unwrap();
2710
2711        let select_span = query.span();
2712
2713        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");
2714    }
2715
2716    #[test]
2717    pub fn test_wildcard_from_cte() {
2718        let dialect = &GenericDialect;
2719        let mut test = SpanTest::new(
2720            dialect,
2721            "WITH cte AS (SELECT a FROM postgres.public.source) SELECT cte.* FROM cte",
2722        );
2723
2724        let query = test.0.parse_query().unwrap();
2725        let cte_span = query.clone().with.unwrap().cte_tables[0].span();
2726        let cte_query_span = query.clone().with.unwrap().cte_tables[0].query.span();
2727        let body_span = query.body.span();
2728
2729        // the WITH keyboard is part of the query
2730        assert_eq!(
2731            test.get_source(cte_span),
2732            "cte AS (SELECT a FROM postgres.public.source)"
2733        );
2734        assert_eq!(
2735            test.get_source(cte_query_span),
2736            "SELECT a FROM postgres.public.source"
2737        );
2738
2739        assert_eq!(test.get_source(body_span), "SELECT cte.* FROM cte");
2740    }
2741
2742    #[test]
2743    fn test_case_expr_span() {
2744        let dialect = &GenericDialect;
2745        let mut test = SpanTest::new(dialect, "CASE 1 WHEN 2 THEN 3 ELSE 4 END");
2746        let expr = test.0.parse_expr().unwrap();
2747        let expr_span = expr.span();
2748        assert_eq!(
2749            test.get_source(expr_span),
2750            "CASE 1 WHEN 2 THEN 3 ELSE 4 END"
2751        );
2752    }
2753
2754    #[test]
2755    fn test_placeholder_span() {
2756        let sql = "\nSELECT\n  :fooBar";
2757        let r = Parser::parse_sql(&GenericDialect, sql).unwrap();
2758        assert_eq!(1, r.len());
2759        match &r[0] {
2760            Statement::Query(q) => {
2761                let col = &q.body.as_select().unwrap().projection[0];
2762                match col {
2763                    SelectItem::UnnamedExpr(Expr::Value(ValueWithSpan {
2764                        value: Value::Placeholder(s),
2765                        span,
2766                    })) => {
2767                        assert_eq!(":fooBar", s);
2768                        assert_eq!(&Span::new((3, 3).into(), (3, 10).into()), span);
2769                    }
2770                    _ => panic!("expected unnamed expression; got {col:?}"),
2771                }
2772            }
2773            stmt => panic!("expected query; got {stmt:?}"),
2774        }
2775    }
2776
2777    #[test]
2778    fn test_alter_table_multiline_span() {
2779        let sql = r#"-- foo
2780ALTER TABLE users
2781  ADD COLUMN foo
2782  varchar; -- hi there"#;
2783
2784        let r = Parser::parse_sql(&crate::dialect::PostgreSqlDialect {}, sql).unwrap();
2785        assert_eq!(1, r.len());
2786
2787        let stmt_span = r[0].span();
2788
2789        assert_eq!(stmt_span.start, (2, 13).into());
2790        assert_eq!(stmt_span.end, (4, 11).into());
2791    }
2792
2793    #[test]
2794    fn test_update_statement_span() {
2795        let sql = r#"-- foo
2796      UPDATE foo
2797   /* bar */
2798   SET bar = 3
2799 WHERE quux > 42 ;
2800"#;
2801
2802        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2803        assert_eq!(1, r.len());
2804
2805        let stmt_span = r[0].span();
2806
2807        assert_eq!(stmt_span.start, (2, 7).into());
2808        assert_eq!(stmt_span.end, (5, 17).into());
2809    }
2810
2811    #[test]
2812    fn test_insert_statement_span() {
2813        let sql = r#"
2814/* foo */ INSERT  INTO  FOO  (X, Y, Z)
2815  SELECT 1, 2, 3
2816  FROM DUAL
2817;"#;
2818
2819        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2820        assert_eq!(1, r.len());
2821
2822        let stmt_span = r[0].span();
2823
2824        assert_eq!(stmt_span.start, (2, 11).into());
2825        assert_eq!(stmt_span.end, (4, 12).into());
2826    }
2827
2828    #[test]
2829    fn test_replace_statement_span() {
2830        let sql = r#"
2831/* foo */ REPLACE INTO
2832    cities(name,population)
2833SELECT
2834    name,
2835    population
2836FROM
2837   cities
2838WHERE id = 1
2839;"#;
2840
2841        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2842        assert_eq!(1, r.len());
2843
2844        dbg!(&r[0]);
2845
2846        let stmt_span = r[0].span();
2847
2848        assert_eq!(stmt_span.start, (2, 11).into());
2849        assert_eq!(stmt_span.end, (9, 13).into());
2850    }
2851
2852    #[test]
2853    fn test_delete_statement_span() {
2854        let sql = r#"-- foo
2855      DELETE /* quux */
2856        FROM foo
2857       WHERE foo.x = 42
2858;"#;
2859
2860        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2861        assert_eq!(1, r.len());
2862
2863        let stmt_span = r[0].span();
2864
2865        assert_eq!(stmt_span.start, (2, 7).into());
2866        assert_eq!(stmt_span.end, (4, 24).into());
2867    }
2868
2869    #[test]
2870    fn test_merge_statement_spans() {
2871        let sql = r#"
2872        -- plain merge statement; no RETURNING, no OUTPUT
2873
2874        MERGE INTO target_table USING source_table
2875                ON target_table.id = source_table.oooid
2876
2877        /* an inline comment */ WHEN NOT MATCHED THEN
2878            INSERT (ID, description)
2879               VALUES (source_table.id, source_table.description)
2880
2881            -- another one
2882                WHEN MATCHED AND target_table.x = 'X' THEN
2883            UPDATE SET target_table.description = source_table.description
2884
2885              WHEN MATCHED AND target_table.x != 'X' THEN   DELETE
2886        WHEN NOT MATCHED AND 1 THEN INSERT (product, quantity) ROW
2887        "#;
2888
2889        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
2890        assert_eq!(1, r.len());
2891
2892        // ~ assert the span of the whole statement
2893        let stmt_span = r[0].span();
2894        assert_eq!(stmt_span.start, (4, 9).into());
2895        assert_eq!(stmt_span.end, (16, 67).into());
2896
2897        // ~ individual tokens within the statement
2898        let Statement::Merge(Merge {
2899            merge_token,
2900            optimizer_hints: _,
2901            into: _,
2902            table: _,
2903            source: _,
2904            on: _,
2905            clauses,
2906            output,
2907        }) = &r[0]
2908        else {
2909            panic!("not a MERGE statement");
2910        };
2911        assert_eq!(
2912            merge_token.0.span,
2913            Span::new(Location::new(4, 9), Location::new(4, 14))
2914        );
2915        assert_eq!(clauses.len(), 4);
2916
2917        // ~ the INSERT clause's TOKENs
2918        assert_eq!(
2919            clauses[0].when_token.0.span,
2920            Span::new(Location::new(7, 33), Location::new(7, 37))
2921        );
2922        if let MergeAction::Insert(MergeInsertExpr {
2923            insert_token,
2924            kind_token,
2925            ..
2926        }) = &clauses[0].action
2927        {
2928            assert_eq!(
2929                insert_token.0.span,
2930                Span::new(Location::new(8, 13), Location::new(8, 19))
2931            );
2932            assert_eq!(
2933                kind_token.0.span,
2934                Span::new(Location::new(9, 16), Location::new(9, 22))
2935            );
2936        } else {
2937            panic!("not a MERGE INSERT clause");
2938        }
2939
2940        // ~ the UPDATE token(s)
2941        assert_eq!(
2942            clauses[1].when_token.0.span,
2943            Span::new(Location::new(12, 17), Location::new(12, 21))
2944        );
2945        if let MergeAction::Update(MergeUpdateExpr {
2946            update_token,
2947            assignments: _,
2948            update_predicate: _,
2949            delete_predicate: _,
2950        }) = &clauses[1].action
2951        {
2952            assert_eq!(
2953                update_token.0.span,
2954                Span::new(Location::new(13, 13), Location::new(13, 19))
2955            );
2956        } else {
2957            panic!("not a MERGE UPDATE clause");
2958        }
2959
2960        // the DELETE token(s)
2961        assert_eq!(
2962            clauses[2].when_token.0.span,
2963            Span::new(Location::new(15, 15), Location::new(15, 19))
2964        );
2965        if let MergeAction::Delete { delete_token } = &clauses[2].action {
2966            assert_eq!(
2967                delete_token.0.span,
2968                Span::new(Location::new(15, 61), Location::new(15, 67))
2969            );
2970        } else {
2971            panic!("not a MERGE DELETE clause");
2972        }
2973
2974        // ~ an INSERT clause's ROW token
2975        assert_eq!(
2976            clauses[3].when_token.0.span,
2977            Span::new(Location::new(16, 9), Location::new(16, 13))
2978        );
2979        if let MergeAction::Insert(MergeInsertExpr {
2980            insert_token,
2981            kind_token,
2982            ..
2983        }) = &clauses[3].action
2984        {
2985            assert_eq!(
2986                insert_token.0.span,
2987                Span::new(Location::new(16, 37), Location::new(16, 43))
2988            );
2989            assert_eq!(
2990                kind_token.0.span,
2991                Span::new(Location::new(16, 64), Location::new(16, 67))
2992            );
2993        } else {
2994            panic!("not a MERGE INSERT clause");
2995        }
2996
2997        assert!(output.is_none());
2998    }
2999
3000    #[test]
3001    fn test_merge_statement_spans_with_returning() {
3002        let sql = r#"
3003    MERGE INTO wines AS w
3004    USING wine_stock_changes AS s
3005        ON s.winename = w.winename
3006    WHEN NOT MATCHED AND s.stock_delta > 0 THEN INSERT VALUES (s.winename, s.stock_delta)
3007    WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN UPDATE SET stock = w.stock + s.stock_delta
3008    WHEN MATCHED THEN DELETE
3009    RETURNING merge_action(), w.*
3010        "#;
3011
3012        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
3013        assert_eq!(1, r.len());
3014
3015        // ~ assert the span of the whole statement
3016        let stmt_span = r[0].span();
3017        assert_eq!(
3018            stmt_span,
3019            Span::new(Location::new(2, 5), Location::new(8, 34))
3020        );
3021
3022        // ~ individual tokens within the statement
3023        if let Statement::Merge(Merge { output, .. }) = &r[0] {
3024            if let Some(OutputClause::Returning {
3025                returning_token, ..
3026            }) = output
3027            {
3028                assert_eq!(
3029                    returning_token.0.span,
3030                    Span::new(Location::new(8, 5), Location::new(8, 14))
3031                );
3032            } else {
3033                panic!("unexpected MERGE output clause");
3034            }
3035        } else {
3036            panic!("not a MERGE statement");
3037        };
3038    }
3039
3040    #[test]
3041    fn test_merge_statement_spans_with_output() {
3042        let sql = r#"MERGE INTO a USING b ON a.id = b.id
3043        WHEN MATCHED THEN DELETE
3044              OUTPUT inserted.*"#;
3045
3046        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
3047        assert_eq!(1, r.len());
3048
3049        // ~ assert the span of the whole statement
3050        let stmt_span = r[0].span();
3051        assert_eq!(
3052            stmt_span,
3053            Span::new(Location::new(1, 1), Location::new(3, 32))
3054        );
3055
3056        // ~ individual tokens within the statement
3057        if let Statement::Merge(Merge { output, .. }) = &r[0] {
3058            if let Some(OutputClause::Output { output_token, .. }) = output {
3059                assert_eq!(
3060                    output_token.0.span,
3061                    Span::new(Location::new(3, 15), Location::new(3, 21))
3062                );
3063            } else {
3064                panic!("unexpected MERGE output clause");
3065            }
3066        } else {
3067            panic!("not a MERGE statement");
3068        };
3069    }
3070
3071    #[test]
3072    fn test_merge_statement_spans_with_update_predicates() {
3073        let sql = r#"
3074       MERGE INTO a USING b ON a.id = b.id
3075        WHEN MATCHED THEN
3076              UPDATE set a.x = a.x + b.x
3077               WHERE b.x != 2
3078              DELETE WHERE a.x <> 3"#;
3079
3080        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
3081        assert_eq!(1, r.len());
3082
3083        // ~ assert the span of the whole statement
3084        let stmt_span = r[0].span();
3085        assert_eq!(
3086            stmt_span,
3087            Span::new(Location::new(2, 8), Location::new(6, 36))
3088        );
3089    }
3090
3091    #[test]
3092    fn test_merge_statement_spans_with_insert_predicate() {
3093        let sql = r#"
3094       MERGE INTO a USING b ON a.id = b.id
3095        WHEN NOT MATCHED THEN
3096            INSERT VALUES (b.x, b.y) WHERE b.x != 2
3097-- qed
3098"#;
3099
3100        let r = Parser::parse_sql(&crate::dialect::GenericDialect, sql).unwrap();
3101        assert_eq!(1, r.len());
3102
3103        // ~ assert the span of the whole statement
3104        let stmt_span = r[0].span();
3105        assert_eq!(
3106            stmt_span,
3107            Span::new(Location::new(2, 8), Location::new(4, 52))
3108        );
3109    }
3110}