sqlparser/ast/
spans.rs

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