sqltk_parser/ast/
spans.rs

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