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