Skip to main content

sqlparser/ast/
spans.rs

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