sqltk_parser/ast/
spans.rs

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