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::ast::query::SelectItemQualifiedWildcardKind;
19use core::iter;
20
21use crate::tokenizer::Span;
22
23use super::{
24    dcl::SecondaryRoles, value::ValueWithSpan, AccessExpr, AlterColumnOperation,
25    AlterIndexOperation, AlterTableOperation, Array, Assignment, AssignmentTarget, AttachedToken,
26    BeginEndStatements, CaseStatement, CloseCursor, ClusteredIndex, ColumnDef, ColumnOption,
27    ColumnOptionDef, ConditionalStatementBlock, ConditionalStatements, ConflictTarget, ConnectBy,
28    ConstraintCharacteristics, CopySource, CreateIndex, CreateTable, CreateTableOptions, Cte,
29    Delete, DoUpdate, ExceptSelectItem, ExcludeSelectItem, Expr, ExprWithAlias, Fetch, FromTable,
30    Function, FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList,
31    FunctionArguments, GroupByExpr, HavingBound, IfStatement, IlikeSelectItem, Insert, Interpolate,
32    InterpolateExpr, Join, JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView,
33    LimitClause, MatchRecognizePattern, Measure, NamedWindowDefinition, ObjectName, ObjectNamePart,
34    Offset, OnConflict, OnConflictAction, OnInsert, OrderBy, OrderByExpr, OrderByKind, Partition,
35    PivotValueSource, ProjectionSelect, Query, RaiseStatement, RaiseStatementValue,
36    ReferentialAction, RenameSelectItem, ReplaceSelectElement, ReplaceSelectItem, Select,
37    SelectInto, SelectItem, SetExpr, SqlOption, Statement, Subscript, SymbolDefinition, TableAlias,
38    TableAliasColumnDef, TableConstraint, TableFactor, TableObject, TableOptionsClustered,
39    TableWithJoins, UpdateTableFromKind, Use, Value, Values, ViewColumnDef,
40    WildcardAdditionalOptions, With, WithFill,
41};
42
43/// Given an iterator of spans, return the [Span::union] of all spans.
44fn union_spans<I: Iterator<Item = Span>>(iter: I) -> Span {
45    Span::union_iter(iter)
46}
47
48/// Trait for AST nodes that have a source location information.
49///
50/// # Notes:
51///
52/// Source [`Span`] are not yet complete. They may be missing:
53///
54/// 1. keywords or other tokens
55/// 2. span information entirely, in which case they return [`Span::empty()`].
56///
57/// Note Some impl blocks (rendered below) are annotated with which nodes are
58/// missing spans. See [this ticket] for additional information and status.
59///
60/// [this ticket]: https://github.com/apache/datafusion-sqlparser-rs/issues/1548
61///
62/// # Example
63/// ```
64/// # use sqlparser::parser::{Parser, ParserError};
65/// # use sqlparser::ast::Spanned;
66/// # use sqlparser::dialect::GenericDialect;
67/// # use sqlparser::tokenizer::Location;
68/// # fn main() -> Result<(), ParserError> {
69/// let dialect = GenericDialect {};
70/// let sql = r#"SELECT *
71///   FROM table_1"#;
72/// let statements = Parser::new(&dialect)
73///   .try_with_sql(sql)?
74///   .parse_statements()?;
75/// // Get the span of the first statement (SELECT)
76/// let span = statements[0].span();
77/// // statement starts at line 1, column 1 (1 based, not 0 based)
78/// assert_eq!(span.start, Location::new(1, 1));
79/// // statement ends on line 2, column 15
80/// assert_eq!(span.end, Location::new(2, 15));
81/// # Ok(())
82/// # }
83/// ```
84///
85pub trait Spanned {
86    /// Return the [`Span`] (the minimum and maximum [`Location`]) for this AST
87    /// node, by recursively combining the spans of its children.
88    ///
89    /// [`Location`]: crate::tokenizer::Location
90    fn span(&self) -> Span;
91}
92
93impl Spanned for Query {
94    fn span(&self) -> Span {
95        let Query {
96            with,
97            body,
98            order_by,
99            limit_clause,
100            fetch,
101            locks: _,         // todo
102            for_clause: _,    // todo, mssql specific
103            settings: _,      // todo, clickhouse specific
104            format_clause: _, // todo, clickhouse specific
105        } = self;
106
107        union_spans(
108            with.iter()
109                .map(|i| i.span())
110                .chain(core::iter::once(body.span()))
111                .chain(order_by.as_ref().map(|i| i.span()))
112                .chain(limit_clause.as_ref().map(|i| i.span()))
113                .chain(fetch.as_ref().map(|i| i.span())),
114        )
115    }
116}
117
118impl Spanned for LimitClause {
119    fn span(&self) -> Span {
120        match self {
121            LimitClause::LimitOffset {
122                limit,
123                offset,
124                limit_by,
125            } => union_spans(
126                limit
127                    .iter()
128                    .map(|i| i.span())
129                    .chain(offset.as_ref().map(|i| i.span()))
130                    .chain(limit_by.iter().map(|i| i.span())),
131            ),
132            LimitClause::OffsetCommaLimit { offset, limit } => offset.span().union(&limit.span()),
133        }
134    }
135}
136
137impl Spanned for Offset {
138    fn span(&self) -> Span {
139        let Offset {
140            value,
141            rows: _, // enum
142        } = self;
143
144        value.span()
145    }
146}
147
148impl Spanned for Fetch {
149    fn span(&self) -> Span {
150        let Fetch {
151            with_ties: _, // bool
152            percent: _,   // bool
153            quantity,
154        } = self;
155
156        quantity.as_ref().map_or(Span::empty(), |i| i.span())
157    }
158}
159
160impl Spanned for With {
161    fn span(&self) -> Span {
162        let With {
163            with_token,
164            recursive: _, // bool
165            cte_tables,
166        } = self;
167
168        union_spans(
169            core::iter::once(with_token.0.span).chain(cte_tables.iter().map(|item| item.span())),
170        )
171    }
172}
173
174impl Spanned for Cte {
175    fn span(&self) -> Span {
176        let Cte {
177            alias,
178            query,
179            from,
180            materialized: _, // enum
181            closing_paren_token,
182        } = self;
183
184        union_spans(
185            core::iter::once(alias.span())
186                .chain(core::iter::once(query.span()))
187                .chain(from.iter().map(|item| item.span))
188                .chain(core::iter::once(closing_paren_token.0.span)),
189        )
190    }
191}
192
193/// # partial span
194///
195/// [SetExpr::Table] is not implemented.
196impl Spanned for SetExpr {
197    fn span(&self) -> Span {
198        match self {
199            SetExpr::Select(select) => select.span(),
200            SetExpr::Query(query) => query.span(),
201            SetExpr::SetOperation {
202                op: _,
203                set_quantifier: _,
204                left,
205                right,
206            } => left.span().union(&right.span()),
207            SetExpr::Values(values) => values.span(),
208            SetExpr::Insert(statement) => statement.span(),
209            SetExpr::Table(_) => Span::empty(),
210            SetExpr::Update(statement) => statement.span(),
211            SetExpr::Delete(statement) => statement.span(),
212        }
213    }
214}
215
216impl Spanned for Values {
217    fn span(&self) -> Span {
218        let Values {
219            explicit_row: _, // bool,
220            rows,
221        } = self;
222
223        union_spans(
224            rows.iter()
225                .map(|row| union_spans(row.iter().map(|expr| expr.span()))),
226        )
227    }
228}
229
230/// # partial span
231///
232/// Missing spans:
233/// - [Statement::CopyIntoSnowflake]
234/// - [Statement::CreateSecret]
235/// - [Statement::CreateRole]
236/// - [Statement::AlterType]
237/// - [Statement::AlterRole]
238/// - [Statement::AttachDatabase]
239/// - [Statement::AttachDuckDBDatabase]
240/// - [Statement::DetachDuckDBDatabase]
241/// - [Statement::Drop]
242/// - [Statement::DropFunction]
243/// - [Statement::DropProcedure]
244/// - [Statement::DropSecret]
245/// - [Statement::Declare]
246/// - [Statement::CreateExtension]
247/// - [Statement::Fetch]
248/// - [Statement::Flush]
249/// - [Statement::Discard]
250/// - [Statement::Set]
251/// - [Statement::ShowFunctions]
252/// - [Statement::ShowVariable]
253/// - [Statement::ShowStatus]
254/// - [Statement::ShowVariables]
255/// - [Statement::ShowCreate]
256/// - [Statement::ShowColumns]
257/// - [Statement::ShowTables]
258/// - [Statement::ShowCollation]
259/// - [Statement::StartTransaction]
260/// - [Statement::Comment]
261/// - [Statement::Commit]
262/// - [Statement::Rollback]
263/// - [Statement::CreateSchema]
264/// - [Statement::CreateDatabase]
265/// - [Statement::CreateFunction]
266/// - [Statement::CreateTrigger]
267/// - [Statement::DropTrigger]
268/// - [Statement::CreateProcedure]
269/// - [Statement::CreateMacro]
270/// - [Statement::CreateStage]
271/// - [Statement::Assert]
272/// - [Statement::Grant]
273/// - [Statement::Revoke]
274/// - [Statement::Deallocate]
275/// - [Statement::Execute]
276/// - [Statement::Prepare]
277/// - [Statement::Kill]
278/// - [Statement::ExplainTable]
279/// - [Statement::Explain]
280/// - [Statement::Savepoint]
281/// - [Statement::ReleaseSavepoint]
282/// - [Statement::Merge]
283/// - [Statement::Cache]
284/// - [Statement::UNCache]
285/// - [Statement::CreateSequence]
286/// - [Statement::CreateType]
287/// - [Statement::Pragma]
288/// - [Statement::LockTables]
289/// - [Statement::UnlockTables]
290/// - [Statement::Unload]
291/// - [Statement::OptimizeTable]
292impl Spanned for Statement {
293    fn span(&self) -> Span {
294        match self {
295            Statement::Analyze {
296                table_name,
297                partitions,
298                for_columns: _,
299                columns,
300                cache_metadata: _,
301                noscan: _,
302                compute_statistics: _,
303                has_table_keyword: _,
304            } => union_spans(
305                core::iter::once(table_name.span())
306                    .chain(partitions.iter().flat_map(|i| i.iter().map(|k| k.span())))
307                    .chain(columns.iter().map(|i| i.span)),
308            ),
309            Statement::Truncate {
310                table_names,
311                partitions,
312                table: _,
313                only: _,
314                identity: _,
315                cascade: _,
316                on_cluster: _,
317            } => union_spans(
318                table_names
319                    .iter()
320                    .map(|i| i.name.span())
321                    .chain(partitions.iter().flat_map(|i| i.iter().map(|k| k.span()))),
322            ),
323            Statement::Msck {
324                table_name,
325                repair: _,
326                partition_action: _,
327            } => table_name.span(),
328            Statement::Query(query) => query.span(),
329            Statement::Insert(insert) => insert.span(),
330            Statement::Install { extension_name } => extension_name.span,
331            Statement::Load { extension_name } => extension_name.span,
332            Statement::Directory {
333                overwrite: _,
334                local: _,
335                path: _,
336                file_format: _,
337                source,
338            } => source.span(),
339            Statement::Case(stmt) => stmt.span(),
340            Statement::If(stmt) => stmt.span(),
341            Statement::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::Close { cursor } => match cursor {
368                CloseCursor::All => Span::empty(),
369                CloseCursor::Specific { name } => name.span,
370            },
371            Statement::Update {
372                table,
373                assignments,
374                from,
375                selection,
376                returning,
377                or: _,
378            } => union_spans(
379                core::iter::once(table.span())
380                    .chain(assignments.iter().map(|i| i.span()))
381                    .chain(from.iter().map(|i| i.span()))
382                    .chain(selection.iter().map(|i| i.span()))
383                    .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span()))),
384            ),
385            Statement::Delete(delete) => delete.span(),
386            Statement::CreateView {
387                or_alter: _,
388                or_replace: _,
389                materialized: _,
390                name,
391                columns,
392                query,
393                options,
394                cluster_by,
395                comment: _,
396                with_no_schema_binding: _,
397                if_not_exists: _,
398                temporary: _,
399                to,
400                params: _,
401            } => union_spans(
402                core::iter::once(name.span())
403                    .chain(columns.iter().map(|i| i.span()))
404                    .chain(core::iter::once(query.span()))
405                    .chain(core::iter::once(options.span()))
406                    .chain(cluster_by.iter().map(|i| i.span))
407                    .chain(to.iter().map(|i| i.span())),
408            ),
409            Statement::CreateTable(create_table) => create_table.span(),
410            Statement::CreateVirtualTable {
411                name,
412                if_not_exists: _,
413                module_name,
414                module_args,
415            } => union_spans(
416                core::iter::once(name.span())
417                    .chain(core::iter::once(module_name.span))
418                    .chain(module_args.iter().map(|i| i.span)),
419            ),
420            Statement::CreateIndex(create_index) => create_index.span(),
421            Statement::CreateRole { .. } => Span::empty(),
422            Statement::CreateSecret { .. } => Span::empty(),
423            Statement::CreateConnector { .. } => Span::empty(),
424            Statement::AlterTable {
425                name,
426                if_exists: _,
427                only: _,
428                operations,
429                location: _,
430                on_cluster,
431            } => union_spans(
432                core::iter::once(name.span())
433                    .chain(operations.iter().map(|i| i.span()))
434                    .chain(on_cluster.iter().map(|i| i.span)),
435            ),
436            Statement::AlterIndex { name, operation } => name.span().union(&operation.span()),
437            Statement::AlterView {
438                name,
439                columns,
440                query,
441                with_options,
442            } => union_spans(
443                core::iter::once(name.span())
444                    .chain(columns.iter().map(|i| i.span))
445                    .chain(core::iter::once(query.span()))
446                    .chain(with_options.iter().map(|i| i.span())),
447            ),
448            // These statements need to be implemented
449            Statement::AlterType { .. } => Span::empty(),
450            Statement::AlterRole { .. } => Span::empty(),
451            Statement::AlterSession { .. } => Span::empty(),
452            Statement::AttachDatabase { .. } => Span::empty(),
453            Statement::AttachDuckDBDatabase { .. } => Span::empty(),
454            Statement::DetachDuckDBDatabase { .. } => Span::empty(),
455            Statement::Drop { .. } => Span::empty(),
456            Statement::DropFunction { .. } => Span::empty(),
457            Statement::DropProcedure { .. } => Span::empty(),
458            Statement::DropSecret { .. } => Span::empty(),
459            Statement::Declare { .. } => Span::empty(),
460            Statement::CreateExtension { .. } => Span::empty(),
461            Statement::DropExtension { .. } => Span::empty(),
462            Statement::Fetch { .. } => Span::empty(),
463            Statement::Flush { .. } => Span::empty(),
464            Statement::Discard { .. } => Span::empty(),
465            Statement::Set(_) => Span::empty(),
466            Statement::ShowFunctions { .. } => Span::empty(),
467            Statement::ShowVariable { .. } => Span::empty(),
468            Statement::ShowStatus { .. } => Span::empty(),
469            Statement::ShowVariables { .. } => Span::empty(),
470            Statement::ShowCreate { .. } => Span::empty(),
471            Statement::ShowColumns { .. } => Span::empty(),
472            Statement::ShowTables { .. } => Span::empty(),
473            Statement::ShowCollation { .. } => Span::empty(),
474            Statement::Use(u) => u.span(),
475            Statement::StartTransaction { .. } => Span::empty(),
476            Statement::Comment { .. } => Span::empty(),
477            Statement::Commit { .. } => Span::empty(),
478            Statement::Rollback { .. } => Span::empty(),
479            Statement::CreateSchema { .. } => Span::empty(),
480            Statement::CreateDatabase { .. } => Span::empty(),
481            Statement::CreateFunction { .. } => Span::empty(),
482            Statement::CreateTrigger { .. } => Span::empty(),
483            Statement::DropTrigger { .. } => Span::empty(),
484            Statement::CreateProcedure { .. } => Span::empty(),
485            Statement::CreateMacro { .. } => Span::empty(),
486            Statement::CreateStage { .. } => Span::empty(),
487            Statement::Assert { .. } => Span::empty(),
488            Statement::Grant { .. } => Span::empty(),
489            Statement::Revoke { .. } => Span::empty(),
490            Statement::Deallocate { .. } => Span::empty(),
491            Statement::Execute { .. } => Span::empty(),
492            Statement::Prepare { .. } => Span::empty(),
493            Statement::Kill { .. } => Span::empty(),
494            Statement::ExplainTable { .. } => Span::empty(),
495            Statement::Explain { .. } => Span::empty(),
496            Statement::Savepoint { .. } => Span::empty(),
497            Statement::ReleaseSavepoint { .. } => Span::empty(),
498            Statement::Merge { .. } => Span::empty(),
499            Statement::Cache { .. } => Span::empty(),
500            Statement::UNCache { .. } => Span::empty(),
501            Statement::CreateSequence { .. } => Span::empty(),
502            Statement::CreateType { .. } => Span::empty(),
503            Statement::Pragma { .. } => Span::empty(),
504            Statement::LockTables { .. } => Span::empty(),
505            Statement::UnlockTables => Span::empty(),
506            Statement::Unload { .. } => Span::empty(),
507            Statement::OptimizeTable { .. } => Span::empty(),
508            Statement::CreatePolicy { .. } => Span::empty(),
509            Statement::AlterPolicy { .. } => Span::empty(),
510            Statement::AlterConnector { .. } => Span::empty(),
511            Statement::DropPolicy { .. } => Span::empty(),
512            Statement::DropConnector { .. } => Span::empty(),
513            Statement::ShowDatabases { .. } => Span::empty(),
514            Statement::ShowSchemas { .. } => Span::empty(),
515            Statement::ShowObjects { .. } => Span::empty(),
516            Statement::ShowViews { .. } => Span::empty(),
517            Statement::LISTEN { .. } => Span::empty(),
518            Statement::NOTIFY { .. } => Span::empty(),
519            Statement::LoadData { .. } => Span::empty(),
520            Statement::UNLISTEN { .. } => Span::empty(),
521            Statement::RenameTable { .. } => Span::empty(),
522            Statement::RaisError { .. } => Span::empty(),
523            Statement::Print { .. } => Span::empty(),
524            Statement::Return { .. } => Span::empty(),
525            Statement::List(..) | Statement::Remove(..) => Span::empty(),
526        }
527    }
528}
529
530impl Spanned for Use {
531    fn span(&self) -> Span {
532        match self {
533            Use::Catalog(object_name) => object_name.span(),
534            Use::Schema(object_name) => object_name.span(),
535            Use::Database(object_name) => object_name.span(),
536            Use::Warehouse(object_name) => object_name.span(),
537            Use::Role(object_name) => object_name.span(),
538            Use::SecondaryRoles(secondary_roles) => {
539                if let SecondaryRoles::List(roles) = secondary_roles {
540                    return union_spans(roles.iter().map(|i| i.span));
541                }
542                Span::empty()
543            }
544            Use::Object(object_name) => object_name.span(),
545            Use::Default => Span::empty(),
546        }
547    }
548}
549
550impl Spanned for CreateTable {
551    fn span(&self) -> Span {
552        let CreateTable {
553            or_replace: _,    // bool
554            temporary: _,     // bool
555            external: _,      // bool
556            global: _,        // bool
557            if_not_exists: _, // bool
558            transient: _,     // bool
559            volatile: _,      // bool
560            iceberg: _,       // bool, Snowflake specific
561            name,
562            columns,
563            constraints,
564            hive_distribution: _, // hive specific
565            hive_formats: _,      // hive specific
566            table_properties,
567            with_options,
568            file_format: _, // enum
569            location: _,    // string, no span
570            query,
571            without_rowid: _, // bool
572            like,
573            clone,
574            engine: _,                          // todo
575            comment: _,                         // todo, no span
576            auto_increment_offset: _,           // u32, no span
577            default_charset: _,                 // string, no span
578            collation: _,                       // string, no span
579            on_commit: _,                       // enum
580            on_cluster: _,                      // todo, clickhouse specific
581            primary_key: _,                     // todo, clickhouse specific
582            order_by: _,                        // todo, clickhouse specific
583            partition_by: _,                    // todo, BigQuery specific
584            cluster_by: _,                      // todo, BigQuery specific
585            clustered_by: _,                    // todo, Hive specific
586            options: _,                         // todo, BigQuery specific
587            inherits: _,                        // todo, PostgreSQL specific
588            strict: _,                          // bool
589            copy_grants: _,                     // bool
590            enable_schema_evolution: _,         // bool
591            change_tracking: _,                 // bool
592            data_retention_time_in_days: _,     // u64, no span
593            max_data_extension_time_in_days: _, // u64, no span
594            default_ddl_collation: _,           // string, no span
595            with_aggregation_policy: _,         // todo, Snowflake specific
596            with_row_access_policy: _,          // todo, Snowflake specific
597            with_tags: _,                       // todo, Snowflake specific
598            external_volume: _,                 // todo, Snowflake specific
599            base_location: _,                   // todo, Snowflake specific
600            catalog: _,                         // todo, Snowflake specific
601            catalog_sync: _,                    // todo, Snowflake specific
602            storage_serialization_policy: _,    // todo, Snowflake specific
603        } = self;
604
605        union_spans(
606            core::iter::once(name.span())
607                .chain(columns.iter().map(|i| i.span()))
608                .chain(constraints.iter().map(|i| i.span()))
609                .chain(table_properties.iter().map(|i| i.span()))
610                .chain(with_options.iter().map(|i| i.span()))
611                .chain(query.iter().map(|i| i.span()))
612                .chain(like.iter().map(|i| i.span()))
613                .chain(clone.iter().map(|i| i.span())),
614        )
615    }
616}
617
618impl Spanned for ColumnDef {
619    fn span(&self) -> Span {
620        let ColumnDef {
621            name,
622            data_type: _, // enum
623            options,
624        } = self;
625
626        union_spans(core::iter::once(name.span).chain(options.iter().map(|i| i.span())))
627    }
628}
629
630impl Spanned for ColumnOptionDef {
631    fn span(&self) -> Span {
632        let ColumnOptionDef { name, option } = self;
633
634        option.span().union_opt(&name.as_ref().map(|i| i.span))
635    }
636}
637
638impl Spanned for TableConstraint {
639    fn span(&self) -> Span {
640        match self {
641            TableConstraint::Unique {
642                name,
643                index_name,
644                index_type_display: _,
645                index_type: _,
646                columns,
647                index_options: _,
648                characteristics,
649                nulls_distinct: _,
650            } => union_spans(
651                name.iter()
652                    .map(|i| i.span)
653                    .chain(index_name.iter().map(|i| i.span))
654                    .chain(columns.iter().map(|i| i.span))
655                    .chain(characteristics.iter().map(|i| i.span())),
656            ),
657            TableConstraint::PrimaryKey {
658                name,
659                index_name,
660                index_type: _,
661                columns,
662                index_options: _,
663                characteristics,
664            } => union_spans(
665                name.iter()
666                    .map(|i| i.span)
667                    .chain(index_name.iter().map(|i| i.span))
668                    .chain(columns.iter().map(|i| i.span))
669                    .chain(characteristics.iter().map(|i| i.span())),
670            ),
671            TableConstraint::ForeignKey {
672                name,
673                columns,
674                foreign_table,
675                referred_columns,
676                on_delete,
677                on_update,
678                characteristics,
679            } => union_spans(
680                name.iter()
681                    .map(|i| i.span)
682                    .chain(columns.iter().map(|i| i.span))
683                    .chain(core::iter::once(foreign_table.span()))
684                    .chain(referred_columns.iter().map(|i| i.span))
685                    .chain(on_delete.iter().map(|i| i.span()))
686                    .chain(on_update.iter().map(|i| i.span()))
687                    .chain(characteristics.iter().map(|i| i.span())),
688            ),
689            TableConstraint::Check { name, expr } => {
690                expr.span().union_opt(&name.as_ref().map(|i| i.span))
691            }
692            TableConstraint::Index {
693                display_as_key: _,
694                name,
695                index_type: _,
696                columns,
697            } => union_spans(
698                name.iter()
699                    .map(|i| i.span)
700                    .chain(columns.iter().map(|i| i.span)),
701            ),
702            TableConstraint::FulltextOrSpatial {
703                fulltext: _,
704                index_type_display: _,
705                opt_index_name,
706                columns,
707            } => union_spans(
708                opt_index_name
709                    .iter()
710                    .map(|i| i.span)
711                    .chain(columns.iter().map(|i| i.span)),
712            ),
713        }
714    }
715}
716
717impl Spanned for CreateIndex {
718    fn span(&self) -> Span {
719        let CreateIndex {
720            name,
721            table_name,
722            using: _,
723            columns,
724            unique: _,        // bool
725            concurrently: _,  // bool
726            if_not_exists: _, // bool
727            include,
728            nulls_distinct: _, // bool
729            with,
730            predicate,
731        } = self;
732
733        union_spans(
734            name.iter()
735                .map(|i| i.span())
736                .chain(core::iter::once(table_name.span()))
737                .chain(columns.iter().map(|i| i.column.span()))
738                .chain(include.iter().map(|i| i.span))
739                .chain(with.iter().map(|i| i.span()))
740                .chain(predicate.iter().map(|i| i.span())),
741        )
742    }
743}
744
745impl Spanned for CaseStatement {
746    fn span(&self) -> Span {
747        let CaseStatement {
748            case_token: AttachedToken(start),
749            match_expr: _,
750            when_blocks: _,
751            else_block: _,
752            end_case_token: AttachedToken(end),
753        } = self;
754
755        union_spans([start.span, end.span].into_iter())
756    }
757}
758
759impl Spanned for IfStatement {
760    fn span(&self) -> Span {
761        let IfStatement {
762            if_block,
763            elseif_blocks,
764            else_block,
765            end_token,
766        } = self;
767
768        union_spans(
769            iter::once(if_block.span())
770                .chain(elseif_blocks.iter().map(|b| b.span()))
771                .chain(else_block.as_ref().map(|b| b.span()))
772                .chain(end_token.as_ref().map(|AttachedToken(t)| t.span)),
773        )
774    }
775}
776
777impl Spanned for ConditionalStatements {
778    fn span(&self) -> Span {
779        match self {
780            ConditionalStatements::Sequence { statements } => {
781                union_spans(statements.iter().map(|s| s.span()))
782            }
783            ConditionalStatements::BeginEnd(bes) => bes.span(),
784        }
785    }
786}
787
788impl Spanned for ConditionalStatementBlock {
789    fn span(&self) -> Span {
790        let ConditionalStatementBlock {
791            start_token: AttachedToken(start_token),
792            condition,
793            then_token,
794            conditional_statements,
795        } = self;
796
797        union_spans(
798            iter::once(start_token.span)
799                .chain(condition.as_ref().map(|c| c.span()))
800                .chain(then_token.as_ref().map(|AttachedToken(t)| t.span))
801                .chain(iter::once(conditional_statements.span())),
802        )
803    }
804}
805
806impl Spanned for RaiseStatement {
807    fn span(&self) -> Span {
808        let RaiseStatement { value } = self;
809
810        union_spans(value.iter().map(|value| value.span()))
811    }
812}
813
814impl Spanned for RaiseStatementValue {
815    fn span(&self) -> Span {
816        match self {
817            RaiseStatementValue::UsingMessage(expr) => expr.span(),
818            RaiseStatementValue::Expr(expr) => expr.span(),
819        }
820    }
821}
822
823/// # partial span
824///
825/// Missing spans:
826/// - [ColumnOption::Null]
827/// - [ColumnOption::NotNull]
828/// - [ColumnOption::Comment]
829/// - [ColumnOption::Unique]¨
830/// - [ColumnOption::DialectSpecific]
831/// - [ColumnOption::Generated]
832impl Spanned for ColumnOption {
833    fn span(&self) -> Span {
834        match self {
835            ColumnOption::Null => Span::empty(),
836            ColumnOption::NotNull => Span::empty(),
837            ColumnOption::Default(expr) => expr.span(),
838            ColumnOption::Materialized(expr) => expr.span(),
839            ColumnOption::Ephemeral(expr) => expr.as_ref().map_or(Span::empty(), |e| e.span()),
840            ColumnOption::Alias(expr) => expr.span(),
841            ColumnOption::Unique { .. } => Span::empty(),
842            ColumnOption::ForeignKey {
843                foreign_table,
844                referred_columns,
845                on_delete,
846                on_update,
847                characteristics,
848            } => union_spans(
849                core::iter::once(foreign_table.span())
850                    .chain(referred_columns.iter().map(|i| i.span))
851                    .chain(on_delete.iter().map(|i| i.span()))
852                    .chain(on_update.iter().map(|i| i.span()))
853                    .chain(characteristics.iter().map(|i| i.span())),
854            ),
855            ColumnOption::Check(expr) => expr.span(),
856            ColumnOption::DialectSpecific(_) => Span::empty(),
857            ColumnOption::CharacterSet(object_name) => object_name.span(),
858            ColumnOption::Collation(object_name) => object_name.span(),
859            ColumnOption::Comment(_) => Span::empty(),
860            ColumnOption::OnUpdate(expr) => expr.span(),
861            ColumnOption::Generated { .. } => Span::empty(),
862            ColumnOption::Options(vec) => union_spans(vec.iter().map(|i| i.span())),
863            ColumnOption::Identity(..) => Span::empty(),
864            ColumnOption::OnConflict(..) => Span::empty(),
865            ColumnOption::Policy(..) => Span::empty(),
866            ColumnOption::Tags(..) => Span::empty(),
867        }
868    }
869}
870
871/// # missing span
872impl Spanned for ReferentialAction {
873    fn span(&self) -> Span {
874        Span::empty()
875    }
876}
877
878/// # missing span
879impl Spanned for ConstraintCharacteristics {
880    fn span(&self) -> Span {
881        let ConstraintCharacteristics {
882            deferrable: _, // bool
883            initially: _,  // enum
884            enforced: _,   // bool
885        } = self;
886
887        Span::empty()
888    }
889}
890
891/// # partial span
892///
893/// Missing spans:
894/// - [AlterColumnOperation::SetNotNull]
895/// - [AlterColumnOperation::DropNotNull]
896/// - [AlterColumnOperation::DropDefault]
897/// - [AlterColumnOperation::AddGenerated]
898impl Spanned for AlterColumnOperation {
899    fn span(&self) -> Span {
900        match self {
901            AlterColumnOperation::SetNotNull => Span::empty(),
902            AlterColumnOperation::DropNotNull => Span::empty(),
903            AlterColumnOperation::SetDefault { value } => value.span(),
904            AlterColumnOperation::DropDefault => Span::empty(),
905            AlterColumnOperation::SetDataType {
906                data_type: _,
907                using,
908            } => using.as_ref().map_or(Span::empty(), |u| u.span()),
909            AlterColumnOperation::AddGenerated { .. } => Span::empty(),
910        }
911    }
912}
913
914impl Spanned for CopySource {
915    fn span(&self) -> Span {
916        match self {
917            CopySource::Table {
918                table_name,
919                columns,
920            } => union_spans(
921                core::iter::once(table_name.span()).chain(columns.iter().map(|i| i.span)),
922            ),
923            CopySource::Query(query) => query.span(),
924        }
925    }
926}
927
928impl Spanned for Delete {
929    fn span(&self) -> Span {
930        let Delete {
931            tables,
932            from,
933            using,
934            selection,
935            returning,
936            order_by,
937            limit,
938        } = self;
939
940        union_spans(
941            tables
942                .iter()
943                .map(|i| i.span())
944                .chain(core::iter::once(from.span()))
945                .chain(
946                    using
947                        .iter()
948                        .map(|u| union_spans(u.iter().map(|i| i.span()))),
949                )
950                .chain(selection.iter().map(|i| i.span()))
951                .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span())))
952                .chain(order_by.iter().map(|i| i.span()))
953                .chain(limit.iter().map(|i| i.span())),
954        )
955    }
956}
957
958impl Spanned for FromTable {
959    fn span(&self) -> Span {
960        match self {
961            FromTable::WithFromKeyword(vec) => union_spans(vec.iter().map(|i| i.span())),
962            FromTable::WithoutKeyword(vec) => union_spans(vec.iter().map(|i| i.span())),
963        }
964    }
965}
966
967impl Spanned for ViewColumnDef {
968    fn span(&self) -> Span {
969        let ViewColumnDef {
970            name,
971            data_type: _, // todo, DataType
972            options,
973        } = self;
974
975        union_spans(
976            core::iter::once(name.span)
977                .chain(options.iter().flat_map(|i| i.iter().map(|k| k.span()))),
978        )
979    }
980}
981
982impl Spanned for SqlOption {
983    fn span(&self) -> Span {
984        match self {
985            SqlOption::Clustered(table_options_clustered) => table_options_clustered.span(),
986            SqlOption::Ident(ident) => ident.span,
987            SqlOption::KeyValue { key, value } => key.span.union(&value.span()),
988            SqlOption::Partition {
989                column_name,
990                range_direction: _,
991                for_values,
992            } => union_spans(
993                core::iter::once(column_name.span).chain(for_values.iter().map(|i| i.span())),
994            ),
995        }
996    }
997}
998
999/// # partial span
1000///
1001/// Missing spans:
1002/// - [TableOptionsClustered::ColumnstoreIndex]
1003impl Spanned for TableOptionsClustered {
1004    fn span(&self) -> Span {
1005        match self {
1006            TableOptionsClustered::ColumnstoreIndex => Span::empty(),
1007            TableOptionsClustered::ColumnstoreIndexOrder(vec) => {
1008                union_spans(vec.iter().map(|i| i.span))
1009            }
1010            TableOptionsClustered::Index(vec) => union_spans(vec.iter().map(|i| i.span())),
1011        }
1012    }
1013}
1014
1015impl Spanned for ClusteredIndex {
1016    fn span(&self) -> Span {
1017        let ClusteredIndex {
1018            name,
1019            asc: _, // bool
1020        } = self;
1021
1022        name.span
1023    }
1024}
1025
1026impl Spanned for CreateTableOptions {
1027    fn span(&self) -> Span {
1028        match self {
1029            CreateTableOptions::None => Span::empty(),
1030            CreateTableOptions::With(vec) => union_spans(vec.iter().map(|i| i.span())),
1031            CreateTableOptions::Options(vec) => union_spans(vec.iter().map(|i| i.span())),
1032        }
1033    }
1034}
1035
1036/// # partial span
1037///
1038/// Missing spans:
1039/// - [AlterTableOperation::OwnerTo]
1040impl Spanned for AlterTableOperation {
1041    fn span(&self) -> Span {
1042        match self {
1043            AlterTableOperation::AddConstraint(table_constraint) => table_constraint.span(),
1044            AlterTableOperation::AddColumn {
1045                column_keyword: _,
1046                if_not_exists: _,
1047                column_def,
1048                column_position: _,
1049            } => column_def.span(),
1050            AlterTableOperation::AddProjection {
1051                if_not_exists: _,
1052                name,
1053                select,
1054            } => name.span.union(&select.span()),
1055            AlterTableOperation::DropProjection { if_exists: _, name } => name.span,
1056            AlterTableOperation::MaterializeProjection {
1057                if_exists: _,
1058                name,
1059                partition,
1060            } => name.span.union_opt(&partition.as_ref().map(|i| i.span)),
1061            AlterTableOperation::ClearProjection {
1062                if_exists: _,
1063                name,
1064                partition,
1065            } => name.span.union_opt(&partition.as_ref().map(|i| i.span)),
1066            AlterTableOperation::DisableRowLevelSecurity => Span::empty(),
1067            AlterTableOperation::DisableRule { name } => name.span,
1068            AlterTableOperation::DisableTrigger { name } => name.span,
1069            AlterTableOperation::DropConstraint {
1070                if_exists: _,
1071                name,
1072                drop_behavior: _,
1073            } => name.span,
1074            AlterTableOperation::DropColumn {
1075                column_name,
1076                if_exists: _,
1077                drop_behavior: _,
1078            } => column_name.span,
1079            AlterTableOperation::AttachPartition { partition } => partition.span(),
1080            AlterTableOperation::DetachPartition { partition } => partition.span(),
1081            AlterTableOperation::FreezePartition {
1082                partition,
1083                with_name,
1084            } => partition
1085                .span()
1086                .union_opt(&with_name.as_ref().map(|n| n.span)),
1087            AlterTableOperation::UnfreezePartition {
1088                partition,
1089                with_name,
1090            } => partition
1091                .span()
1092                .union_opt(&with_name.as_ref().map(|n| n.span)),
1093            AlterTableOperation::DropPrimaryKey => Span::empty(),
1094            AlterTableOperation::DropForeignKey { name } => name.span,
1095            AlterTableOperation::EnableAlwaysRule { name } => name.span,
1096            AlterTableOperation::EnableAlwaysTrigger { name } => name.span,
1097            AlterTableOperation::EnableReplicaRule { name } => name.span,
1098            AlterTableOperation::EnableReplicaTrigger { name } => name.span,
1099            AlterTableOperation::EnableRowLevelSecurity => Span::empty(),
1100            AlterTableOperation::EnableRule { name } => name.span,
1101            AlterTableOperation::EnableTrigger { name } => name.span,
1102            AlterTableOperation::RenamePartitions {
1103                old_partitions,
1104                new_partitions,
1105            } => union_spans(
1106                old_partitions
1107                    .iter()
1108                    .map(|i| i.span())
1109                    .chain(new_partitions.iter().map(|i| i.span())),
1110            ),
1111            AlterTableOperation::AddPartitions {
1112                if_not_exists: _,
1113                new_partitions,
1114            } => union_spans(new_partitions.iter().map(|i| i.span())),
1115            AlterTableOperation::DropPartitions {
1116                partitions,
1117                if_exists: _,
1118            } => union_spans(partitions.iter().map(|i| i.span())),
1119            AlterTableOperation::RenameColumn {
1120                old_column_name,
1121                new_column_name,
1122            } => old_column_name.span.union(&new_column_name.span),
1123            AlterTableOperation::RenameTable { table_name } => table_name.span(),
1124            AlterTableOperation::ChangeColumn {
1125                old_name,
1126                new_name,
1127                data_type: _,
1128                options,
1129                column_position: _,
1130            } => union_spans(
1131                core::iter::once(old_name.span)
1132                    .chain(core::iter::once(new_name.span))
1133                    .chain(options.iter().map(|i| i.span())),
1134            ),
1135            AlterTableOperation::ModifyColumn {
1136                col_name,
1137                data_type: _,
1138                options,
1139                column_position: _,
1140            } => {
1141                union_spans(core::iter::once(col_name.span).chain(options.iter().map(|i| i.span())))
1142            }
1143            AlterTableOperation::RenameConstraint { old_name, new_name } => {
1144                old_name.span.union(&new_name.span)
1145            }
1146            AlterTableOperation::AlterColumn { column_name, op } => {
1147                column_name.span.union(&op.span())
1148            }
1149            AlterTableOperation::SwapWith { table_name } => table_name.span(),
1150            AlterTableOperation::SetTblProperties { table_properties } => {
1151                union_spans(table_properties.iter().map(|i| i.span()))
1152            }
1153            AlterTableOperation::OwnerTo { .. } => Span::empty(),
1154            AlterTableOperation::ClusterBy { exprs } => union_spans(exprs.iter().map(|e| e.span())),
1155            AlterTableOperation::DropClusteringKey => Span::empty(),
1156            AlterTableOperation::SuspendRecluster => Span::empty(),
1157            AlterTableOperation::ResumeRecluster => Span::empty(),
1158            AlterTableOperation::Algorithm { .. } => Span::empty(),
1159            AlterTableOperation::AutoIncrement { value, .. } => value.span(),
1160            AlterTableOperation::Lock { .. } => Span::empty(),
1161        }
1162    }
1163}
1164
1165impl Spanned for Partition {
1166    fn span(&self) -> Span {
1167        match self {
1168            Partition::Identifier(ident) => ident.span,
1169            Partition::Expr(expr) => expr.span(),
1170            Partition::Part(expr) => expr.span(),
1171            Partition::Partitions(vec) => union_spans(vec.iter().map(|i| i.span())),
1172        }
1173    }
1174}
1175
1176impl Spanned for ProjectionSelect {
1177    fn span(&self) -> Span {
1178        let ProjectionSelect {
1179            projection,
1180            order_by,
1181            group_by,
1182        } = self;
1183
1184        union_spans(
1185            projection
1186                .iter()
1187                .map(|i| i.span())
1188                .chain(order_by.iter().map(|i| i.span()))
1189                .chain(group_by.iter().map(|i| i.span())),
1190        )
1191    }
1192}
1193
1194/// # partial span
1195///
1196/// Missing spans:
1197/// - [OrderByKind::All]
1198impl Spanned for OrderBy {
1199    fn span(&self) -> Span {
1200        match &self.kind {
1201            OrderByKind::All(_) => Span::empty(),
1202            OrderByKind::Expressions(exprs) => union_spans(
1203                exprs
1204                    .iter()
1205                    .map(|i| i.span())
1206                    .chain(self.interpolate.iter().map(|i| i.span())),
1207            ),
1208        }
1209    }
1210}
1211
1212/// # partial span
1213///
1214/// Missing spans:
1215/// - [GroupByExpr::All]
1216impl Spanned for GroupByExpr {
1217    fn span(&self) -> Span {
1218        match self {
1219            GroupByExpr::All(_) => Span::empty(),
1220            GroupByExpr::Expressions(exprs, _modifiers) => {
1221                union_spans(exprs.iter().map(|i| i.span()))
1222            }
1223        }
1224    }
1225}
1226
1227impl Spanned for Interpolate {
1228    fn span(&self) -> Span {
1229        let Interpolate { exprs } = self;
1230
1231        union_spans(exprs.iter().flat_map(|i| i.iter().map(|e| e.span())))
1232    }
1233}
1234
1235impl Spanned for InterpolateExpr {
1236    fn span(&self) -> Span {
1237        let InterpolateExpr { column, expr } = self;
1238
1239        column.span.union_opt(&expr.as_ref().map(|e| e.span()))
1240    }
1241}
1242
1243impl Spanned for AlterIndexOperation {
1244    fn span(&self) -> Span {
1245        match self {
1246            AlterIndexOperation::RenameIndex { index_name } => index_name.span(),
1247        }
1248    }
1249}
1250
1251/// # partial span
1252///
1253/// Missing spans:ever
1254/// - [Insert::insert_alias]
1255impl Spanned for Insert {
1256    fn span(&self) -> Span {
1257        let Insert {
1258            or: _,     // enum, sqlite specific
1259            ignore: _, // bool
1260            into: _,   // bool
1261            table,
1262            table_alias,
1263            columns,
1264            overwrite: _, // bool
1265            source,
1266            partitioned,
1267            after_columns,
1268            has_table_keyword: _, // bool
1269            on,
1270            returning,
1271            replace_into: _, // bool
1272            priority: _,     // todo, mysql specific
1273            insert_alias: _, // todo, mysql specific
1274            assignments,
1275            settings: _,      // todo, clickhouse specific
1276            format_clause: _, // todo, clickhouse specific
1277        } = self;
1278
1279        union_spans(
1280            core::iter::once(table.span())
1281                .chain(table_alias.as_ref().map(|i| i.span))
1282                .chain(columns.iter().map(|i| i.span))
1283                .chain(source.as_ref().map(|q| q.span()))
1284                .chain(assignments.iter().map(|i| i.span()))
1285                .chain(partitioned.iter().flat_map(|i| i.iter().map(|k| k.span())))
1286                .chain(after_columns.iter().map(|i| i.span))
1287                .chain(on.as_ref().map(|i| i.span()))
1288                .chain(returning.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1289        )
1290    }
1291}
1292
1293impl Spanned for OnInsert {
1294    fn span(&self) -> Span {
1295        match self {
1296            OnInsert::DuplicateKeyUpdate(vec) => union_spans(vec.iter().map(|i| i.span())),
1297            OnInsert::OnConflict(on_conflict) => on_conflict.span(),
1298        }
1299    }
1300}
1301
1302impl Spanned for OnConflict {
1303    fn span(&self) -> Span {
1304        let OnConflict {
1305            conflict_target,
1306            action,
1307        } = self;
1308
1309        action
1310            .span()
1311            .union_opt(&conflict_target.as_ref().map(|i| i.span()))
1312    }
1313}
1314
1315impl Spanned for ConflictTarget {
1316    fn span(&self) -> Span {
1317        match self {
1318            ConflictTarget::Columns(vec) => union_spans(vec.iter().map(|i| i.span)),
1319            ConflictTarget::OnConstraint(object_name) => object_name.span(),
1320        }
1321    }
1322}
1323
1324/// # partial span
1325///
1326/// Missing spans:
1327/// - [OnConflictAction::DoNothing]
1328impl Spanned for OnConflictAction {
1329    fn span(&self) -> Span {
1330        match self {
1331            OnConflictAction::DoNothing => Span::empty(),
1332            OnConflictAction::DoUpdate(do_update) => do_update.span(),
1333        }
1334    }
1335}
1336
1337impl Spanned for DoUpdate {
1338    fn span(&self) -> Span {
1339        let DoUpdate {
1340            assignments,
1341            selection,
1342        } = self;
1343
1344        union_spans(
1345            assignments
1346                .iter()
1347                .map(|i| i.span())
1348                .chain(selection.iter().map(|i| i.span())),
1349        )
1350    }
1351}
1352
1353impl Spanned for Assignment {
1354    fn span(&self) -> Span {
1355        let Assignment { target, value } = self;
1356
1357        target.span().union(&value.span())
1358    }
1359}
1360
1361impl Spanned for AssignmentTarget {
1362    fn span(&self) -> Span {
1363        match self {
1364            AssignmentTarget::ColumnName(object_name) => object_name.span(),
1365            AssignmentTarget::Tuple(vec) => union_spans(vec.iter().map(|i| i.span())),
1366        }
1367    }
1368}
1369
1370/// # partial span
1371///
1372/// Most expressions are missing keywords in their spans.
1373/// f.e. `IS NULL <expr>` reports as `<expr>::span`.
1374///
1375/// Missing spans:
1376/// - [Expr::TypedString] # missing span for data_type
1377/// - [Expr::MatchAgainst] # MySQL specific
1378/// - [Expr::RLike] # MySQL specific
1379/// - [Expr::Struct] # BigQuery specific
1380/// - [Expr::Named] # BigQuery specific
1381/// - [Expr::Dictionary] # DuckDB specific
1382/// - [Expr::Map] # DuckDB specific
1383/// - [Expr::Lambda]
1384impl Spanned for Expr {
1385    fn span(&self) -> Span {
1386        match self {
1387            Expr::Identifier(ident) => ident.span,
1388            Expr::CompoundIdentifier(vec) => union_spans(vec.iter().map(|i| i.span)),
1389            Expr::CompoundFieldAccess { root, access_chain } => {
1390                union_spans(iter::once(root.span()).chain(access_chain.iter().map(|i| i.span())))
1391            }
1392            Expr::IsFalse(expr) => expr.span(),
1393            Expr::IsNotFalse(expr) => expr.span(),
1394            Expr::IsTrue(expr) => expr.span(),
1395            Expr::IsNotTrue(expr) => expr.span(),
1396            Expr::IsNull(expr) => expr.span(),
1397            Expr::IsNotNull(expr) => expr.span(),
1398            Expr::IsUnknown(expr) => expr.span(),
1399            Expr::IsNotUnknown(expr) => expr.span(),
1400            Expr::IsDistinctFrom(lhs, rhs) => lhs.span().union(&rhs.span()),
1401            Expr::IsNotDistinctFrom(lhs, rhs) => lhs.span().union(&rhs.span()),
1402            Expr::InList {
1403                expr,
1404                list,
1405                negated: _,
1406            } => union_spans(
1407                core::iter::once(expr.span()).chain(list.iter().map(|item| item.span())),
1408            ),
1409            Expr::InSubquery {
1410                expr,
1411                subquery,
1412                negated: _,
1413            } => expr.span().union(&subquery.span()),
1414            Expr::InUnnest {
1415                expr,
1416                array_expr,
1417                negated: _,
1418            } => expr.span().union(&array_expr.span()),
1419            Expr::Between {
1420                expr,
1421                negated: _,
1422                low,
1423                high,
1424            } => expr.span().union(&low.span()).union(&high.span()),
1425
1426            Expr::BinaryOp { left, op: _, right } => left.span().union(&right.span()),
1427            Expr::Like {
1428                negated: _,
1429                expr,
1430                pattern,
1431                escape_char: _,
1432                any: _,
1433            } => expr.span().union(&pattern.span()),
1434            Expr::ILike {
1435                negated: _,
1436                expr,
1437                pattern,
1438                escape_char: _,
1439                any: _,
1440            } => expr.span().union(&pattern.span()),
1441            Expr::RLike { .. } => Span::empty(),
1442            Expr::IsNormalized {
1443                expr,
1444                form: _,
1445                negated: _,
1446            } => expr.span(),
1447            Expr::SimilarTo {
1448                negated: _,
1449                expr,
1450                pattern,
1451                escape_char: _,
1452            } => expr.span().union(&pattern.span()),
1453            Expr::Ceil { expr, field: _ } => expr.span(),
1454            Expr::Floor { expr, field: _ } => expr.span(),
1455            Expr::Position { expr, r#in } => expr.span().union(&r#in.span()),
1456            Expr::Overlay {
1457                expr,
1458                overlay_what,
1459                overlay_from,
1460                overlay_for,
1461            } => expr
1462                .span()
1463                .union(&overlay_what.span())
1464                .union(&overlay_from.span())
1465                .union_opt(&overlay_for.as_ref().map(|i| i.span())),
1466            Expr::Collate { expr, collation } => expr
1467                .span()
1468                .union(&union_spans(collation.0.iter().map(|i| i.span()))),
1469            Expr::Nested(expr) => expr.span(),
1470            Expr::Value(value) => value.span(),
1471            Expr::TypedString { value, .. } => value.span(),
1472            Expr::Function(function) => function.span(),
1473            Expr::GroupingSets(vec) => {
1474                union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span())))
1475            }
1476            Expr::Cube(vec) => union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1477            Expr::Rollup(vec) => union_spans(vec.iter().flat_map(|i| i.iter().map(|k| k.span()))),
1478            Expr::Tuple(vec) => union_spans(vec.iter().map(|i| i.span())),
1479            Expr::Array(array) => array.span(),
1480            Expr::MatchAgainst { .. } => Span::empty(),
1481            Expr::JsonAccess { value, path } => value.span().union(&path.span()),
1482            Expr::AnyOp {
1483                left,
1484                compare_op: _,
1485                right,
1486                is_some: _,
1487            } => left.span().union(&right.span()),
1488            Expr::AllOp {
1489                left,
1490                compare_op: _,
1491                right,
1492            } => left.span().union(&right.span()),
1493            Expr::UnaryOp { op: _, expr } => expr.span(),
1494            Expr::Convert {
1495                expr,
1496                data_type: _,
1497                charset,
1498                target_before_value: _,
1499                styles,
1500                is_try: _,
1501            } => union_spans(
1502                core::iter::once(expr.span())
1503                    .chain(charset.as_ref().map(|i| i.span()))
1504                    .chain(styles.iter().map(|i| i.span())),
1505            ),
1506            Expr::Cast {
1507                kind: _,
1508                expr,
1509                data_type: _,
1510                format: _,
1511            } => expr.span(),
1512            Expr::AtTimeZone {
1513                timestamp,
1514                time_zone,
1515            } => timestamp.span().union(&time_zone.span()),
1516            Expr::Extract {
1517                field: _,
1518                syntax: _,
1519                expr,
1520            } => expr.span(),
1521            Expr::Substring {
1522                expr,
1523                substring_from,
1524                substring_for,
1525                special: _,
1526                shorthand: _,
1527            } => union_spans(
1528                core::iter::once(expr.span())
1529                    .chain(substring_from.as_ref().map(|i| i.span()))
1530                    .chain(substring_for.as_ref().map(|i| i.span())),
1531            ),
1532            Expr::Trim {
1533                expr,
1534                trim_where: _,
1535                trim_what,
1536                trim_characters,
1537            } => union_spans(
1538                core::iter::once(expr.span())
1539                    .chain(trim_what.as_ref().map(|i| i.span()))
1540                    .chain(
1541                        trim_characters
1542                            .as_ref()
1543                            .map(|items| union_spans(items.iter().map(|i| i.span()))),
1544                    ),
1545            ),
1546            Expr::Prefixed { value, .. } => value.span(),
1547            Expr::Case {
1548                operand,
1549                conditions,
1550                else_result,
1551            } => union_spans(
1552                operand
1553                    .as_ref()
1554                    .map(|i| i.span())
1555                    .into_iter()
1556                    .chain(conditions.iter().flat_map(|case_when| {
1557                        [case_when.condition.span(), case_when.result.span()]
1558                    }))
1559                    .chain(else_result.as_ref().map(|i| i.span())),
1560            ),
1561            Expr::Exists { subquery, .. } => subquery.span(),
1562            Expr::Subquery(query) => query.span(),
1563            Expr::Struct { .. } => Span::empty(),
1564            Expr::Named { .. } => Span::empty(),
1565            Expr::Dictionary(_) => Span::empty(),
1566            Expr::Map(_) => Span::empty(),
1567            Expr::Interval(interval) => interval.value.span(),
1568            Expr::Wildcard(token) => token.0.span,
1569            Expr::QualifiedWildcard(object_name, token) => union_spans(
1570                object_name
1571                    .0
1572                    .iter()
1573                    .map(|i| i.span())
1574                    .chain(iter::once(token.0.span)),
1575            ),
1576            Expr::OuterJoin(expr) => expr.span(),
1577            Expr::Prior(expr) => expr.span(),
1578            Expr::Lambda(_) => Span::empty(),
1579        }
1580    }
1581}
1582
1583impl Spanned for Subscript {
1584    fn span(&self) -> Span {
1585        match self {
1586            Subscript::Index { index } => index.span(),
1587            Subscript::Slice {
1588                lower_bound,
1589                upper_bound,
1590                stride,
1591            } => union_spans(
1592                [
1593                    lower_bound.as_ref().map(|i| i.span()),
1594                    upper_bound.as_ref().map(|i| i.span()),
1595                    stride.as_ref().map(|i| i.span()),
1596                ]
1597                .into_iter()
1598                .flatten(),
1599            ),
1600        }
1601    }
1602}
1603
1604impl Spanned for AccessExpr {
1605    fn span(&self) -> Span {
1606        match self {
1607            AccessExpr::Dot(ident) => ident.span(),
1608            AccessExpr::Subscript(subscript) => subscript.span(),
1609        }
1610    }
1611}
1612
1613impl Spanned for ObjectName {
1614    fn span(&self) -> Span {
1615        let ObjectName(segments) = self;
1616
1617        union_spans(segments.iter().map(|i| i.span()))
1618    }
1619}
1620
1621impl Spanned for ObjectNamePart {
1622    fn span(&self) -> Span {
1623        match self {
1624            ObjectNamePart::Identifier(ident) => ident.span,
1625        }
1626    }
1627}
1628
1629impl Spanned for Array {
1630    fn span(&self) -> Span {
1631        let Array {
1632            elem,
1633            named: _, // bool
1634        } = self;
1635
1636        union_spans(elem.iter().map(|i| i.span()))
1637    }
1638}
1639
1640impl Spanned for Function {
1641    fn span(&self) -> Span {
1642        let Function {
1643            name,
1644            uses_odbc_syntax: _,
1645            parameters,
1646            args,
1647            filter,
1648            null_treatment: _, // enum
1649            over: _,           // todo
1650            within_group,
1651        } = self;
1652
1653        union_spans(
1654            name.0
1655                .iter()
1656                .map(|i| i.span())
1657                .chain(iter::once(args.span()))
1658                .chain(iter::once(parameters.span()))
1659                .chain(filter.iter().map(|i| i.span()))
1660                .chain(within_group.iter().map(|i| i.span())),
1661        )
1662    }
1663}
1664
1665/// # partial span
1666///
1667/// The span of [FunctionArguments::None] is empty.
1668impl Spanned for FunctionArguments {
1669    fn span(&self) -> Span {
1670        match self {
1671            FunctionArguments::None => Span::empty(),
1672            FunctionArguments::Subquery(query) => query.span(),
1673            FunctionArguments::List(list) => list.span(),
1674        }
1675    }
1676}
1677
1678impl Spanned for FunctionArgumentList {
1679    fn span(&self) -> Span {
1680        let FunctionArgumentList {
1681            duplicate_treatment: _, // enum
1682            args,
1683            clauses,
1684        } = self;
1685
1686        union_spans(
1687            // # todo: duplicate-treatment span
1688            args.iter()
1689                .map(|i| i.span())
1690                .chain(clauses.iter().map(|i| i.span())),
1691        )
1692    }
1693}
1694
1695impl Spanned for FunctionArgumentClause {
1696    fn span(&self) -> Span {
1697        match self {
1698            FunctionArgumentClause::IgnoreOrRespectNulls(_) => Span::empty(),
1699            FunctionArgumentClause::OrderBy(vec) => union_spans(vec.iter().map(|i| i.expr.span())),
1700            FunctionArgumentClause::Limit(expr) => expr.span(),
1701            FunctionArgumentClause::OnOverflow(_) => Span::empty(),
1702            FunctionArgumentClause::Having(HavingBound(_kind, expr)) => expr.span(),
1703            FunctionArgumentClause::Separator(value) => value.span(),
1704            FunctionArgumentClause::JsonNullClause(_) => Span::empty(),
1705        }
1706    }
1707}
1708
1709/// # partial span
1710///
1711/// see Spanned impl for JsonPathElem for more information
1712impl Spanned for JsonPath {
1713    fn span(&self) -> Span {
1714        let JsonPath { path } = self;
1715
1716        union_spans(path.iter().map(|i| i.span()))
1717    }
1718}
1719
1720/// # partial span
1721///
1722/// Missing spans:
1723/// - [JsonPathElem::Dot]
1724impl Spanned for JsonPathElem {
1725    fn span(&self) -> Span {
1726        match self {
1727            JsonPathElem::Dot { .. } => Span::empty(),
1728            JsonPathElem::Bracket { key } => key.span(),
1729        }
1730    }
1731}
1732
1733impl Spanned for SelectItemQualifiedWildcardKind {
1734    fn span(&self) -> Span {
1735        match self {
1736            SelectItemQualifiedWildcardKind::ObjectName(object_name) => object_name.span(),
1737            SelectItemQualifiedWildcardKind::Expr(expr) => expr.span(),
1738        }
1739    }
1740}
1741
1742impl Spanned for SelectItem {
1743    fn span(&self) -> Span {
1744        match self {
1745            SelectItem::UnnamedExpr(expr) => expr.span(),
1746            SelectItem::ExprWithAlias { expr, alias } => expr.span().union(&alias.span),
1747            SelectItem::QualifiedWildcard(kind, wildcard_additional_options) => union_spans(
1748                [kind.span()]
1749                    .into_iter()
1750                    .chain(iter::once(wildcard_additional_options.span())),
1751            ),
1752            SelectItem::Wildcard(wildcard_additional_options) => wildcard_additional_options.span(),
1753        }
1754    }
1755}
1756
1757impl Spanned for WildcardAdditionalOptions {
1758    fn span(&self) -> Span {
1759        let WildcardAdditionalOptions {
1760            wildcard_token,
1761            opt_ilike,
1762            opt_exclude,
1763            opt_except,
1764            opt_replace,
1765            opt_rename,
1766        } = self;
1767
1768        union_spans(
1769            core::iter::once(wildcard_token.0.span)
1770                .chain(opt_ilike.as_ref().map(|i| i.span()))
1771                .chain(opt_exclude.as_ref().map(|i| i.span()))
1772                .chain(opt_rename.as_ref().map(|i| i.span()))
1773                .chain(opt_replace.as_ref().map(|i| i.span()))
1774                .chain(opt_except.as_ref().map(|i| i.span())),
1775        )
1776    }
1777}
1778
1779/// # missing span
1780impl Spanned for IlikeSelectItem {
1781    fn span(&self) -> Span {
1782        Span::empty()
1783    }
1784}
1785
1786impl Spanned for ExcludeSelectItem {
1787    fn span(&self) -> Span {
1788        match self {
1789            ExcludeSelectItem::Single(ident) => ident.span,
1790            ExcludeSelectItem::Multiple(vec) => union_spans(vec.iter().map(|i| i.span)),
1791        }
1792    }
1793}
1794
1795impl Spanned for RenameSelectItem {
1796    fn span(&self) -> Span {
1797        match self {
1798            RenameSelectItem::Single(ident) => ident.ident.span.union(&ident.alias.span),
1799            RenameSelectItem::Multiple(vec) => {
1800                union_spans(vec.iter().map(|i| i.ident.span.union(&i.alias.span)))
1801            }
1802        }
1803    }
1804}
1805
1806impl Spanned for ExceptSelectItem {
1807    fn span(&self) -> Span {
1808        let ExceptSelectItem {
1809            first_element,
1810            additional_elements,
1811        } = self;
1812
1813        union_spans(
1814            iter::once(first_element.span).chain(additional_elements.iter().map(|i| i.span)),
1815        )
1816    }
1817}
1818
1819impl Spanned for ReplaceSelectItem {
1820    fn span(&self) -> Span {
1821        let ReplaceSelectItem { items } = self;
1822
1823        union_spans(items.iter().map(|i| i.span()))
1824    }
1825}
1826
1827impl Spanned for ReplaceSelectElement {
1828    fn span(&self) -> Span {
1829        let ReplaceSelectElement {
1830            expr,
1831            column_name,
1832            as_keyword: _, // bool
1833        } = self;
1834
1835        expr.span().union(&column_name.span)
1836    }
1837}
1838
1839/// # partial span
1840///
1841/// Missing spans:
1842/// - [TableFactor::JsonTable]
1843impl Spanned for TableFactor {
1844    fn span(&self) -> Span {
1845        match self {
1846            TableFactor::Table {
1847                name,
1848                alias,
1849                args: _,
1850                with_hints: _,
1851                version: _,
1852                with_ordinality: _,
1853                partitions: _,
1854                json_path: _,
1855                sample: _,
1856                index_hints: _,
1857            } => union_spans(
1858                name.0
1859                    .iter()
1860                    .map(|i| i.span())
1861                    .chain(alias.as_ref().map(|alias| {
1862                        union_spans(
1863                            iter::once(alias.name.span)
1864                                .chain(alias.columns.iter().map(|i| i.span())),
1865                        )
1866                    })),
1867            ),
1868            TableFactor::Derived {
1869                lateral: _,
1870                subquery,
1871                alias,
1872            } => subquery
1873                .span()
1874                .union_opt(&alias.as_ref().map(|alias| alias.span())),
1875            TableFactor::TableFunction { expr, alias } => expr
1876                .span()
1877                .union_opt(&alias.as_ref().map(|alias| alias.span())),
1878            TableFactor::UNNEST {
1879                alias,
1880                with_offset: _,
1881                with_offset_alias,
1882                array_exprs,
1883                with_ordinality: _,
1884            } => union_spans(
1885                alias
1886                    .iter()
1887                    .map(|i| i.span())
1888                    .chain(array_exprs.iter().map(|i| i.span()))
1889                    .chain(with_offset_alias.as_ref().map(|i| i.span)),
1890            ),
1891            TableFactor::NestedJoin {
1892                table_with_joins,
1893                alias,
1894            } => table_with_joins
1895                .span()
1896                .union_opt(&alias.as_ref().map(|alias| alias.span())),
1897            TableFactor::Function {
1898                lateral: _,
1899                name,
1900                args,
1901                alias,
1902            } => union_spans(
1903                name.0
1904                    .iter()
1905                    .map(|i| i.span())
1906                    .chain(args.iter().map(|i| i.span()))
1907                    .chain(alias.as_ref().map(|alias| alias.span())),
1908            ),
1909            TableFactor::JsonTable { .. } => Span::empty(),
1910            TableFactor::XmlTable { .. } => Span::empty(),
1911            TableFactor::Pivot {
1912                table,
1913                aggregate_functions,
1914                value_column,
1915                value_source,
1916                default_on_null,
1917                alias,
1918            } => union_spans(
1919                core::iter::once(table.span())
1920                    .chain(aggregate_functions.iter().map(|i| i.span()))
1921                    .chain(value_column.iter().map(|i| i.span))
1922                    .chain(core::iter::once(value_source.span()))
1923                    .chain(default_on_null.as_ref().map(|i| i.span()))
1924                    .chain(alias.as_ref().map(|i| i.span())),
1925            ),
1926            TableFactor::Unpivot {
1927                table,
1928                value,
1929                name,
1930                columns,
1931                alias,
1932            } => union_spans(
1933                core::iter::once(table.span())
1934                    .chain(core::iter::once(value.span))
1935                    .chain(core::iter::once(name.span))
1936                    .chain(columns.iter().map(|i| i.span))
1937                    .chain(alias.as_ref().map(|alias| alias.span())),
1938            ),
1939            TableFactor::MatchRecognize {
1940                table,
1941                partition_by,
1942                order_by,
1943                measures,
1944                rows_per_match: _,
1945                after_match_skip: _,
1946                pattern,
1947                symbols,
1948                alias,
1949            } => union_spans(
1950                core::iter::once(table.span())
1951                    .chain(partition_by.iter().map(|i| i.span()))
1952                    .chain(order_by.iter().map(|i| i.span()))
1953                    .chain(measures.iter().map(|i| i.span()))
1954                    .chain(core::iter::once(pattern.span()))
1955                    .chain(symbols.iter().map(|i| i.span()))
1956                    .chain(alias.as_ref().map(|i| i.span())),
1957            ),
1958            TableFactor::OpenJsonTable { .. } => Span::empty(),
1959        }
1960    }
1961}
1962
1963impl Spanned for PivotValueSource {
1964    fn span(&self) -> Span {
1965        match self {
1966            PivotValueSource::List(vec) => union_spans(vec.iter().map(|i| i.span())),
1967            PivotValueSource::Any(vec) => union_spans(vec.iter().map(|i| i.span())),
1968            PivotValueSource::Subquery(query) => query.span(),
1969        }
1970    }
1971}
1972
1973impl Spanned for ExprWithAlias {
1974    fn span(&self) -> Span {
1975        let ExprWithAlias { expr, alias } = self;
1976
1977        expr.span().union_opt(&alias.as_ref().map(|i| i.span))
1978    }
1979}
1980
1981/// # missing span
1982impl Spanned for MatchRecognizePattern {
1983    fn span(&self) -> Span {
1984        Span::empty()
1985    }
1986}
1987
1988impl Spanned for SymbolDefinition {
1989    fn span(&self) -> Span {
1990        let SymbolDefinition { symbol, definition } = self;
1991
1992        symbol.span.union(&definition.span())
1993    }
1994}
1995
1996impl Spanned for Measure {
1997    fn span(&self) -> Span {
1998        let Measure { expr, alias } = self;
1999
2000        expr.span().union(&alias.span)
2001    }
2002}
2003
2004impl Spanned for OrderByExpr {
2005    fn span(&self) -> Span {
2006        let OrderByExpr {
2007            expr,
2008            options: _,
2009            with_fill,
2010        } = self;
2011
2012        expr.span().union_opt(&with_fill.as_ref().map(|f| f.span()))
2013    }
2014}
2015
2016impl Spanned for WithFill {
2017    fn span(&self) -> Span {
2018        let WithFill { from, to, step } = self;
2019
2020        union_spans(
2021            from.iter()
2022                .map(|f| f.span())
2023                .chain(to.iter().map(|t| t.span()))
2024                .chain(step.iter().map(|s| s.span())),
2025        )
2026    }
2027}
2028
2029impl Spanned for FunctionArg {
2030    fn span(&self) -> Span {
2031        match self {
2032            FunctionArg::Named {
2033                name,
2034                arg,
2035                operator: _,
2036            } => name.span.union(&arg.span()),
2037            FunctionArg::Unnamed(arg) => arg.span(),
2038            FunctionArg::ExprNamed {
2039                name,
2040                arg,
2041                operator: _,
2042            } => name.span().union(&arg.span()),
2043        }
2044    }
2045}
2046
2047/// # partial span
2048///
2049/// Missing spans:
2050/// - [FunctionArgExpr::Wildcard]
2051impl Spanned for FunctionArgExpr {
2052    fn span(&self) -> Span {
2053        match self {
2054            FunctionArgExpr::Expr(expr) => expr.span(),
2055            FunctionArgExpr::QualifiedWildcard(object_name) => {
2056                union_spans(object_name.0.iter().map(|i| i.span()))
2057            }
2058            FunctionArgExpr::Wildcard => Span::empty(),
2059        }
2060    }
2061}
2062
2063impl Spanned for TableAlias {
2064    fn span(&self) -> Span {
2065        let TableAlias { name, columns } = self;
2066
2067        union_spans(iter::once(name.span).chain(columns.iter().map(|i| i.span())))
2068    }
2069}
2070
2071impl Spanned for TableAliasColumnDef {
2072    fn span(&self) -> Span {
2073        let TableAliasColumnDef { name, data_type: _ } = self;
2074
2075        name.span
2076    }
2077}
2078
2079impl Spanned for ValueWithSpan {
2080    fn span(&self) -> Span {
2081        self.span
2082    }
2083}
2084
2085/// The span is stored in the `ValueWrapper` struct
2086impl Spanned for Value {
2087    fn span(&self) -> Span {
2088        Span::empty() // # todo: Value needs to store spans before this is possible
2089    }
2090}
2091
2092impl Spanned for Join {
2093    fn span(&self) -> Span {
2094        let Join {
2095            relation,
2096            global: _, // bool
2097            join_operator,
2098        } = self;
2099
2100        relation.span().union(&join_operator.span())
2101    }
2102}
2103
2104/// # partial span
2105///
2106/// Missing spans:
2107/// - [JoinOperator::CrossJoin]
2108/// - [JoinOperator::CrossApply]
2109/// - [JoinOperator::OuterApply]
2110impl Spanned for JoinOperator {
2111    fn span(&self) -> Span {
2112        match self {
2113            JoinOperator::Join(join_constraint) => join_constraint.span(),
2114            JoinOperator::Inner(join_constraint) => join_constraint.span(),
2115            JoinOperator::Left(join_constraint) => join_constraint.span(),
2116            JoinOperator::LeftOuter(join_constraint) => join_constraint.span(),
2117            JoinOperator::Right(join_constraint) => join_constraint.span(),
2118            JoinOperator::RightOuter(join_constraint) => join_constraint.span(),
2119            JoinOperator::FullOuter(join_constraint) => join_constraint.span(),
2120            JoinOperator::CrossJoin => Span::empty(),
2121            JoinOperator::LeftSemi(join_constraint) => join_constraint.span(),
2122            JoinOperator::RightSemi(join_constraint) => join_constraint.span(),
2123            JoinOperator::LeftAnti(join_constraint) => join_constraint.span(),
2124            JoinOperator::RightAnti(join_constraint) => join_constraint.span(),
2125            JoinOperator::CrossApply => Span::empty(),
2126            JoinOperator::OuterApply => Span::empty(),
2127            JoinOperator::AsOf {
2128                match_condition,
2129                constraint,
2130            } => match_condition.span().union(&constraint.span()),
2131            JoinOperator::Anti(join_constraint) => join_constraint.span(),
2132            JoinOperator::Semi(join_constraint) => join_constraint.span(),
2133            JoinOperator::StraightJoin(join_constraint) => join_constraint.span(),
2134        }
2135    }
2136}
2137
2138/// # partial span
2139///
2140/// Missing spans:
2141/// - [JoinConstraint::Natural]
2142/// - [JoinConstraint::None]
2143impl Spanned for JoinConstraint {
2144    fn span(&self) -> Span {
2145        match self {
2146            JoinConstraint::On(expr) => expr.span(),
2147            JoinConstraint::Using(vec) => union_spans(vec.iter().map(|i| i.span())),
2148            JoinConstraint::Natural => Span::empty(),
2149            JoinConstraint::None => Span::empty(),
2150        }
2151    }
2152}
2153
2154impl Spanned for TableWithJoins {
2155    fn span(&self) -> Span {
2156        let TableWithJoins { relation, joins } = self;
2157
2158        union_spans(core::iter::once(relation.span()).chain(joins.iter().map(|item| item.span())))
2159    }
2160}
2161
2162impl Spanned for Select {
2163    fn span(&self) -> Span {
2164        let Select {
2165            select_token,
2166            distinct: _, // todo
2167            top: _,      // todo, mysql specific
2168            projection,
2169            into,
2170            from,
2171            lateral_views,
2172            prewhere,
2173            selection,
2174            group_by,
2175            cluster_by,
2176            distribute_by,
2177            sort_by,
2178            having,
2179            named_window,
2180            qualify,
2181            window_before_qualify: _, // bool
2182            value_table_mode: _,      // todo, BigQuery specific
2183            connect_by,
2184            top_before_distinct: _,
2185            flavor: _,
2186        } = self;
2187
2188        union_spans(
2189            core::iter::once(select_token.0.span)
2190                .chain(projection.iter().map(|item| item.span()))
2191                .chain(into.iter().map(|item| item.span()))
2192                .chain(from.iter().map(|item| item.span()))
2193                .chain(lateral_views.iter().map(|item| item.span()))
2194                .chain(prewhere.iter().map(|item| item.span()))
2195                .chain(selection.iter().map(|item| item.span()))
2196                .chain(core::iter::once(group_by.span()))
2197                .chain(cluster_by.iter().map(|item| item.span()))
2198                .chain(distribute_by.iter().map(|item| item.span()))
2199                .chain(sort_by.iter().map(|item| item.span()))
2200                .chain(having.iter().map(|item| item.span()))
2201                .chain(named_window.iter().map(|item| item.span()))
2202                .chain(qualify.iter().map(|item| item.span()))
2203                .chain(connect_by.iter().map(|item| item.span())),
2204        )
2205    }
2206}
2207
2208impl Spanned for ConnectBy {
2209    fn span(&self) -> Span {
2210        let ConnectBy {
2211            condition,
2212            relationships,
2213        } = self;
2214
2215        union_spans(
2216            core::iter::once(condition.span()).chain(relationships.iter().map(|item| item.span())),
2217        )
2218    }
2219}
2220
2221impl Spanned for NamedWindowDefinition {
2222    fn span(&self) -> Span {
2223        let NamedWindowDefinition(
2224            ident,
2225            _, // todo: NamedWindowExpr
2226        ) = self;
2227
2228        ident.span
2229    }
2230}
2231
2232impl Spanned for LateralView {
2233    fn span(&self) -> Span {
2234        let LateralView {
2235            lateral_view,
2236            lateral_view_name,
2237            lateral_col_alias,
2238            outer: _, // bool
2239        } = self;
2240
2241        union_spans(
2242            core::iter::once(lateral_view.span())
2243                .chain(core::iter::once(lateral_view_name.span()))
2244                .chain(lateral_col_alias.iter().map(|i| i.span)),
2245        )
2246    }
2247}
2248
2249impl Spanned for SelectInto {
2250    fn span(&self) -> Span {
2251        let SelectInto {
2252            temporary: _, // bool
2253            unlogged: _,  // bool
2254            table: _,     // bool
2255            name,
2256        } = self;
2257
2258        name.span()
2259    }
2260}
2261
2262impl Spanned for UpdateTableFromKind {
2263    fn span(&self) -> Span {
2264        let from = match self {
2265            UpdateTableFromKind::BeforeSet(from) => from,
2266            UpdateTableFromKind::AfterSet(from) => from,
2267        };
2268        union_spans(from.iter().map(|t| t.span()))
2269    }
2270}
2271
2272impl Spanned for TableObject {
2273    fn span(&self) -> Span {
2274        match self {
2275            TableObject::TableName(ObjectName(segments)) => {
2276                union_spans(segments.iter().map(|i| i.span()))
2277            }
2278            TableObject::TableFunction(func) => func.span(),
2279        }
2280    }
2281}
2282
2283impl Spanned for BeginEndStatements {
2284    fn span(&self) -> Span {
2285        let BeginEndStatements {
2286            begin_token,
2287            statements,
2288            end_token,
2289        } = self;
2290        union_spans(
2291            core::iter::once(begin_token.0.span)
2292                .chain(statements.iter().map(|i| i.span()))
2293                .chain(core::iter::once(end_token.0.span)),
2294        )
2295    }
2296}
2297
2298#[cfg(test)]
2299pub mod tests {
2300    use crate::dialect::{Dialect, GenericDialect, SnowflakeDialect};
2301    use crate::parser::Parser;
2302    use crate::tokenizer::Span;
2303
2304    use super::*;
2305
2306    struct SpanTest<'a>(Parser<'a>, &'a str);
2307
2308    impl<'a> SpanTest<'a> {
2309        fn new(dialect: &'a dyn Dialect, sql: &'a str) -> Self {
2310            Self(Parser::new(dialect).try_with_sql(sql).unwrap(), sql)
2311        }
2312
2313        // get the subsection of the source string that corresponds to the span
2314        // only works on single-line strings
2315        fn get_source(&self, span: Span) -> &'a str {
2316            // lines in spans are 1-indexed
2317            &self.1[(span.start.column as usize - 1)..(span.end.column - 1) as usize]
2318        }
2319    }
2320
2321    #[test]
2322    fn test_join() {
2323        let dialect = &GenericDialect;
2324        let mut test = SpanTest::new(
2325            dialect,
2326            "SELECT id, name FROM users LEFT JOIN companies ON users.company_id = companies.id",
2327        );
2328
2329        let query = test.0.parse_select().unwrap();
2330        let select_span = query.span();
2331
2332        assert_eq!(
2333            test.get_source(select_span),
2334            "SELECT id, name FROM users LEFT JOIN companies ON users.company_id = companies.id"
2335        );
2336
2337        let join_span = query.from[0].joins[0].span();
2338
2339        // 'LEFT JOIN' missing
2340        assert_eq!(
2341            test.get_source(join_span),
2342            "companies ON users.company_id = companies.id"
2343        );
2344    }
2345
2346    #[test]
2347    pub fn test_union() {
2348        let dialect = &GenericDialect;
2349        let mut test = SpanTest::new(
2350            dialect,
2351            "SELECT a FROM postgres.public.source UNION SELECT a FROM postgres.public.source",
2352        );
2353
2354        let query = test.0.parse_query().unwrap();
2355        let select_span = query.span();
2356
2357        assert_eq!(
2358            test.get_source(select_span),
2359            "SELECT a FROM postgres.public.source UNION SELECT a FROM postgres.public.source"
2360        );
2361    }
2362
2363    #[test]
2364    pub fn test_subquery() {
2365        let dialect = &GenericDialect;
2366        let mut test = SpanTest::new(
2367            dialect,
2368            "SELECT a FROM (SELECT a FROM postgres.public.source) AS b",
2369        );
2370
2371        let query = test.0.parse_select().unwrap();
2372        let select_span = query.span();
2373
2374        assert_eq!(
2375            test.get_source(select_span),
2376            "SELECT a FROM (SELECT a FROM postgres.public.source) AS b"
2377        );
2378
2379        let subquery_span = query.from[0].span();
2380
2381        // left paren missing
2382        assert_eq!(
2383            test.get_source(subquery_span),
2384            "SELECT a FROM postgres.public.source) AS b"
2385        );
2386    }
2387
2388    #[test]
2389    pub fn test_cte() {
2390        let dialect = &GenericDialect;
2391        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");
2392
2393        let query = test.0.parse_query().unwrap();
2394
2395        let select_span = query.span();
2396
2397        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");
2398    }
2399
2400    #[test]
2401    pub fn test_snowflake_lateral_flatten() {
2402        let dialect = &SnowflakeDialect;
2403        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");
2404
2405        let query = test.0.parse_select().unwrap();
2406
2407        let select_span = query.span();
2408
2409        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");
2410    }
2411
2412    #[test]
2413    pub fn test_wildcard_from_cte() {
2414        let dialect = &GenericDialect;
2415        let mut test = SpanTest::new(
2416            dialect,
2417            "WITH cte AS (SELECT a FROM postgres.public.source) SELECT cte.* FROM cte",
2418        );
2419
2420        let query = test.0.parse_query().unwrap();
2421        let cte_span = query.clone().with.unwrap().cte_tables[0].span();
2422        let cte_query_span = query.clone().with.unwrap().cte_tables[0].query.span();
2423        let body_span = query.body.span();
2424
2425        // the WITH keyboard is part of the query
2426        assert_eq!(
2427            test.get_source(cte_span),
2428            "cte AS (SELECT a FROM postgres.public.source)"
2429        );
2430        assert_eq!(
2431            test.get_source(cte_query_span),
2432            "SELECT a FROM postgres.public.source"
2433        );
2434
2435        assert_eq!(test.get_source(body_span), "SELECT cte.* FROM cte");
2436    }
2437}