[Go to site: main page, start]

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