sqlparser/ast/
spans.rs

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