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