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