STET

agent_patch

runs/2026-02-28__18-27-22__gpt-5-3-codex/flux-pr-1435/flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/agent-logs/agent.patch

82806 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/mod.rs b/app/src/ast/mod.rs
index 9185c9d..8588068 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/ast/mod.rs
+++ b/app/src/ast/mod.rs
@@ -33,6 +33,8 @@ use serde::{Deserialize, Serialize};
 #[cfg(feature = "visitor")]
 use sqlparser_derive::{Visit, VisitMut};
 
+use crate::tokenizer::Span;
+
 pub use self::data_type::{
     ArrayElemTypeDef, CharLengthUnits, CharacterLength, DataType, ExactNumberInfo,
     StructBracketKind, TimezoneInfo,
@@ -87,11 +89,13 @@ mod dml;
 pub mod helpers;
 mod operator;
 mod query;
+mod spans;
 mod trigger;
 mod value;
 
 #[cfg(feature = "visitor")]
 mod visitor;
+pub use spans::Spanned;
 
 pub struct DisplaySeparated<'a, T>
 where
@@ -131,7 +135,7 @@ where
 }
 
 /// An identifier, decomposed into its value or character data and the quote style.
-#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[derive(Debug, Clone)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub struct Ident {
@@ -140,6 +144,8 @@ pub struct Ident {
     /// The starting quote if any. Valid quote characters are the single quote,
     /// double quote, backtick, and opening square bracket.
     pub quote_style: Option<char>,
+    /// The location span of this identifier in the source SQL.
+    pub span: Span,
 }
 
 impl Ident {
@@ -151,6 +157,7 @@ impl Ident {
         Ident {
             value: value.into(),
             quote_style: None,
+            span: Span::empty(),
         }
     }
 
@@ -164,6 +171,32 @@ impl Ident {
         Ident {
             value: value.into(),
             quote_style: Some(quote),
+            span: Span::empty(),
+        }
+    }
+
+    /// Create a new identifier with a specific source span and no quotes.
+    pub fn with_span<S>(span: Span, value: S) -> Self
+    where
+        S: Into<String>,
+    {
+        Ident {
+            value: value.into(),
+            quote_style: None,
+            span,
+        }
+    }
+
+    /// Create a new quoted identifier with a specific source span.
+    pub fn with_quote_and_span<S>(quote: char, span: Span, value: S) -> Self
+    where
+        S: Into<String>,
+    {
+        assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
+        Ident {
+            value: value.into(),
+            quote_style: Some(quote),
+            span,
         }
     }
 }
@@ -173,6 +206,7 @@ impl From<&str> for Ident {
         Ident {
             value: value.to_string(),
             quote_style: None,
+            span: Span::empty(),
         }
     }
 }
@@ -191,6 +225,33 @@ impl fmt::Display for Ident {
     }
 }
 
+impl PartialEq for Ident {
+    fn eq(&self, other: &Self) -> bool {
+        self.value == other.value && self.quote_style == other.quote_style
+    }
+}
+
+impl Eq for Ident {}
+
+impl PartialOrd for Ident {
+    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Ident {
+    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
+        (&self.value, &self.quote_style).cmp(&(&other.value, &other.quote_style))
+    }
+}
+
+impl core::hash::Hash for Ident {
+    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
+        core::hash::Hash::hash(&self.value, state);
+        core::hash::Hash::hash(&self.quote_style, state);
+    }
+}
+
 /// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj
 #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
diff --git a/app/src/ast/spans.rs b/app/src/ast/spans.rs
new file mode 100644
index 0000000..24817ee
--- /dev/null
+++ b/app/src/ast/spans.rs
@@ -0,0 +1,562 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#[cfg(not(feature = "std"))]
+use alloc::vec::Vec;
+
+use crate::tokenizer::{Span, TokenWithLocation};
+
+use super::{
+    Cte, ExceptSelectItem, ExcludeSelectItem, Expr, Fetch, Function, FunctionArg, FunctionArgExpr,
+    FunctionArgumentList, FunctionArguments, GroupByExpr, Ident, Join, JoinConstraint,
+    JoinOperator, ObjectName, Offset, OrderBy, OrderByExpr, Query, RenameSelectItem,
+    ReplaceSelectElement, ReplaceSelectItem, Select, SelectItem, SetExpr, Statement, TableAlias,
+    TableFactor, TableWithJoins, Value, Values, WildcardAdditionalOptions, With, Subscript,
+};
+
+/// Trait for AST nodes that can return a source span.
+pub trait Spanned {
+    fn span(&self) -> Span;
+}
+
+fn union_spans<I: Iterator<Item = Span>>(iter: I) -> Span {
+    Span::union_iter(iter)
+}
+
+impl Spanned for Span {
+    fn span(&self) -> Span {
+        *self
+    }
+}
+
+impl<T: Spanned> Spanned for Option<T> {
+    fn span(&self) -> Span {
+        self.as_ref().map_or(Span::empty(), Spanned::span)
+    }
+}
+
+impl<T: Spanned> Spanned for Box<T> {
+    fn span(&self) -> Span {
+        self.as_ref().span()
+    }
+}
+
+impl<T: Spanned> Spanned for Vec<T> {
+    fn span(&self) -> Span {
+        Span::union_iter(self.iter().map(Spanned::span))
+    }
+}
+
+impl Spanned for TokenWithLocation {
+    fn span(&self) -> Span {
+        self.span
+    }
+}
+
+impl Spanned for Ident {
+    fn span(&self) -> Span {
+        self.span
+    }
+}
+
+impl Spanned for ObjectName {
+    fn span(&self) -> Span {
+        union_spans(self.0.iter().map(Spanned::span))
+    }
+}
+
+impl Spanned for TableAlias {
+    fn span(&self) -> Span {
+        union_spans(
+            core::iter::once(self.name.span()).chain(self.columns.iter().map(Spanned::span)),
+        )
+    }
+}
+
+impl Spanned for Statement {
+    fn span(&self) -> Span {
+        match self {
+            Statement::Query(query) => query.span(),
+            _ => Span::empty(),
+        }
+    }
+}
+
+impl Spanned for Query {
+    fn span(&self) -> Span {
+        union_spans(
+            self.with
+                .iter()
+                .map(Spanned::span)
+                .chain(core::iter::once(self.body.span()))
+                .chain(self.order_by.iter().map(Spanned::span))
+                .chain(self.limit.iter().map(Spanned::span))
+                .chain(self.limit_by.iter().map(Spanned::span))
+                .chain(self.offset.iter().map(Spanned::span))
+                .chain(self.fetch.iter().map(Spanned::span)),
+        )
+    }
+}
+
+impl Spanned for With {
+    fn span(&self) -> Span {
+        union_spans(self.cte_tables.iter().map(Spanned::span))
+    }
+}
+
+impl Spanned for Cte {
+    fn span(&self) -> Span {
+        union_spans(
+            core::iter::once(self.alias.span())
+                .chain(core::iter::once(self.query.span()))
+                .chain(self.from.iter().map(Spanned::span)),
+        )
+    }
+}
+
+impl Spanned for SetExpr {
+    fn span(&self) -> Span {
+        match self {
+            SetExpr::Select(select) => select.span(),
+            SetExpr::Query(query) => query.span(),
+            SetExpr::SetOperation { left, right, .. } => left.span().union(&right.span()),
+            SetExpr::Values(values) => values.span(),
+            SetExpr::Insert(statement) | SetExpr::Update(statement) => statement.span(),
+            SetExpr::Table(_) => Span::empty(),
+        }
+    }
+}
+
+impl Spanned for Values {
+    fn span(&self) -> Span {
+        union_spans(
+            self.rows
+                .iter()
+                .flat_map(|row| row.iter())
+                .map(Spanned::span),
+        )
+    }
+}
+
+impl Spanned for Select {
+    fn span(&self) -> Span {
+        let mut spans = Vec::new();
+        spans.extend(self.projection.iter().map(Spanned::span));
+        spans.extend(self.from.iter().map(Spanned::span));
+        spans.extend(self.prewhere.iter().map(Spanned::span));
+        spans.extend(self.selection.iter().map(Spanned::span));
+        if let GroupByExpr::Expressions(exprs, _) = &self.group_by {
+            spans.extend(exprs.iter().map(Spanned::span));
+        }
+        spans.extend(self.cluster_by.iter().map(Spanned::span));
+        spans.extend(self.distribute_by.iter().map(Spanned::span));
+        spans.extend(self.sort_by.iter().map(Spanned::span));
+        spans.extend(self.having.iter().map(Spanned::span));
+        spans.extend(self.qualify.iter().map(Spanned::span));
+        if let Some(connect_by) = &self.connect_by {
+            spans.push(connect_by.condition.span());
+            spans.extend(connect_by.relationships.iter().map(Spanned::span));
+        }
+        Span::union_iter(spans.into_iter())
+    }
+}
+
+impl Spanned for SelectItem {
+    fn span(&self) -> Span {
+        match self {
+            SelectItem::UnnamedExpr(expr) => expr.span(),
+            SelectItem::ExprWithAlias { expr, alias } => expr.span().union(&alias.span()),
+            SelectItem::QualifiedWildcard(name, options) => name.span().union(&options.span()),
+            SelectItem::Wildcard(options) => options.span(),
+        }
+    }
+}
+
+impl Spanned for WildcardAdditionalOptions {
+    fn span(&self) -> Span {
+        union_spans(
+            self.opt_exclude
+                .iter()
+                .map(Spanned::span)
+                .chain(self.opt_except.iter().map(Spanned::span))
+                .chain(self.opt_replace.iter().map(Spanned::span))
+                .chain(self.opt_rename.iter().map(Spanned::span)),
+        )
+    }
+}
+
+impl Spanned for ExcludeSelectItem {
+    fn span(&self) -> Span {
+        match self {
+            ExcludeSelectItem::Single(ident) => ident.span(),
+            ExcludeSelectItem::Multiple(idents) => union_spans(idents.iter().map(Spanned::span)),
+        }
+    }
+}
+
+impl Spanned for ExceptSelectItem {
+    fn span(&self) -> Span {
+        union_spans(
+            core::iter::once(self.first_element.span())
+                .chain(self.additional_elements.iter().map(Spanned::span)),
+        )
+    }
+}
+
+impl Spanned for RenameSelectItem {
+    fn span(&self) -> Span {
+        match self {
+            RenameSelectItem::Single(item) => item.ident.span().union(&item.alias.span()),
+            RenameSelectItem::Multiple(items) => union_spans(
+                items
+                    .iter()
+                    .map(|item| item.ident.span().union(&item.alias.span())),
+            ),
+        }
+    }
+}
+
+impl Spanned for ReplaceSelectItem {
+    fn span(&self) -> Span {
+        union_spans(self.items.iter().map(Spanned::span))
+    }
+}
+
+impl Spanned for ReplaceSelectElement {
+    fn span(&self) -> Span {
+        self.expr.span().union(&self.column_name.span())
+    }
+}
+
+impl Spanned for TableWithJoins {
+    fn span(&self) -> Span {
+        union_spans(
+            core::iter::once(self.relation.span()).chain(self.joins.iter().map(Spanned::span)),
+        )
+    }
+}
+
+impl Spanned for TableFactor {
+    fn span(&self) -> Span {
+        match self {
+            TableFactor::Table {
+                name,
+                alias,
+                args: _,
+                with_hints: _,
+                version: _,
+                with_ordinality: _,
+                partitions: _,
+                json_path: _,
+            } => name.span().union(&alias.span()),
+            TableFactor::Derived {
+                subquery, alias, ..
+            } => subquery.span().union(&alias.span()),
+            TableFactor::TableFunction { expr, alias } => expr.span().union(&alias.span()),
+            TableFactor::UNNEST {
+                alias, array_exprs, ..
+            } => union_spans(
+                array_exprs
+                    .iter()
+                    .map(Spanned::span)
+                    .chain(alias.iter().map(Spanned::span)),
+            ),
+            TableFactor::NestedJoin {
+                table_with_joins,
+                alias,
+            } => table_with_joins.span().union(&alias.span()),
+            _ => Span::empty(),
+        }
+    }
+}
+
+impl Spanned for Join {
+    fn span(&self) -> Span {
+        self.relation.span().union(&self.join_operator.span())
+    }
+}
+
+impl Spanned for JoinOperator {
+    fn span(&self) -> Span {
+        match self {
+            JoinOperator::Inner(c)
+            | JoinOperator::LeftOuter(c)
+            | JoinOperator::RightOuter(c)
+            | JoinOperator::FullOuter(c)
+            | JoinOperator::Semi(c)
+            | JoinOperator::LeftSemi(c)
+            | JoinOperator::RightSemi(c)
+            | JoinOperator::Anti(c)
+            | JoinOperator::LeftAnti(c)
+            | JoinOperator::RightAnti(c) => c.span(),
+            JoinOperator::AsOf {
+                match_condition,
+                constraint,
+            } => match_condition.span().union(&constraint.span()),
+            JoinOperator::CrossJoin | JoinOperator::CrossApply | JoinOperator::OuterApply => {
+                Span::empty()
+            }
+        }
+    }
+}
+
+impl Spanned for JoinConstraint {
+    fn span(&self) -> Span {
+        match self {
+            JoinConstraint::On(expr) => expr.span(),
+            JoinConstraint::Using(idents) => union_spans(idents.iter().map(Spanned::span)),
+            JoinConstraint::Natural | JoinConstraint::None => Span::empty(),
+        }
+    }
+}
+
+impl Spanned for OrderBy {
+    fn span(&self) -> Span {
+        union_spans(self.exprs.iter().map(Spanned::span))
+    }
+}
+
+impl Spanned for OrderByExpr {
+    fn span(&self) -> Span {
+        self.expr.span()
+    }
+}
+
+impl Spanned for Offset {
+    fn span(&self) -> Span {
+        self.value.span()
+    }
+}
+
+impl Spanned for Fetch {
+    fn span(&self) -> Span {
+        self.quantity.span()
+    }
+}
+
+impl Spanned for Function {
+    fn span(&self) -> Span {
+        self.name.span().union(&self.args.span())
+    }
+}
+
+impl Spanned for FunctionArguments {
+    fn span(&self) -> Span {
+        match self {
+            FunctionArguments::None => Span::empty(),
+            FunctionArguments::Subquery(query) => query.span(),
+            FunctionArguments::List(list) => list.span(),
+        }
+    }
+}
+
+impl Spanned for FunctionArgumentList {
+    fn span(&self) -> Span {
+        union_spans(
+            self.args
+                .iter()
+                .map(Spanned::span)
+                .chain(self.clauses.iter().map(|_| Span::empty())),
+        )
+    }
+}
+
+impl Spanned for FunctionArg {
+    fn span(&self) -> Span {
+        match self {
+            FunctionArg::Named { name, arg, .. } => name.span().union(&arg.span()),
+            FunctionArg::Unnamed(arg) => arg.span(),
+        }
+    }
+}
+
+impl Spanned for FunctionArgExpr {
+    fn span(&self) -> Span {
+        match self {
+            FunctionArgExpr::Expr(expr) => expr.span(),
+            FunctionArgExpr::QualifiedWildcard(name) => name.span(),
+            FunctionArgExpr::Wildcard => Span::empty(),
+        }
+    }
+}
+
+impl Spanned for Value {
+    fn span(&self) -> Span {
+        Span::empty()
+    }
+}
+
+impl Spanned for Subscript {
+    fn span(&self) -> Span {
+        match self {
+            Subscript::Index { index } => index.span(),
+            Subscript::Slice {
+                lower_bound,
+                upper_bound,
+                stride,
+            } => union_spans(
+                lower_bound
+                    .iter()
+                    .map(Spanned::span)
+                    .chain(upper_bound.iter().map(Spanned::span))
+                    .chain(stride.iter().map(Spanned::span)),
+            ),
+        }
+    }
+}
+
+impl Spanned for Expr {
+    fn span(&self) -> Span {
+        match self {
+            Expr::Identifier(ident) => ident.span(),
+            Expr::CompoundIdentifier(idents) => union_spans(idents.iter().map(Spanned::span)),
+            Expr::JsonAccess { value, .. } => value.span(),
+            Expr::CompositeAccess { expr, key } => expr.span().union(&key.span()),
+            Expr::IsFalse(expr)
+            | Expr::IsNotFalse(expr)
+            | Expr::IsTrue(expr)
+            | Expr::IsNotTrue(expr)
+            | Expr::IsNull(expr)
+            | Expr::IsNotNull(expr)
+            | Expr::IsUnknown(expr)
+            | Expr::IsNotUnknown(expr)
+            | Expr::Nested(expr)
+            | Expr::UnaryOp { expr, .. }
+            | Expr::Prior(expr)
+            | Expr::OuterJoin(expr) => expr.span(),
+            Expr::AnyOp { left, right, .. } | Expr::AllOp { left, right, .. } => {
+                left.span().union(&right.span())
+            }
+            Expr::IsDistinctFrom(lhs, rhs)
+            | Expr::IsNotDistinctFrom(lhs, rhs)
+            | Expr::BinaryOp {
+                left: lhs,
+                right: rhs,
+                ..
+            } => lhs.span().union(&rhs.span()),
+            Expr::InList { expr, list, .. } => {
+                expr.span().union(&union_spans(list.iter().map(Spanned::span)))
+            }
+            Expr::InSubquery { expr, subquery, .. } => expr.span().union(&subquery.span()),
+            Expr::InUnnest {
+                expr, array_expr, ..
+            } => expr.span().union(&array_expr.span()),
+            Expr::Between {
+                expr, low, high, ..
+            } => expr.span().union(&low.span()).union(&high.span()),
+            Expr::Like { expr, pattern, .. }
+            | Expr::ILike { expr, pattern, .. }
+            | Expr::SimilarTo { expr, pattern, .. } => expr.span().union(&pattern.span()),
+            Expr::Cast { expr, .. }
+            | Expr::Convert { expr, .. }
+            | Expr::AtTimeZone {
+                timestamp: expr, ..
+            } => expr.span(),
+            Expr::Extract { expr, .. } => expr.span(),
+            Expr::Ceil { expr, .. } | Expr::Floor { expr, .. } => expr.span(),
+            Expr::Position { expr, r#in } => expr.span().union(&r#in.span()),
+            Expr::Substring {
+                expr,
+                substring_from,
+                substring_for,
+            } => union_spans(
+                core::iter::once(expr.span())
+                    .chain(substring_from.iter().map(Spanned::span))
+                    .chain(substring_for.iter().map(Spanned::span)),
+            ),
+            Expr::Trim {
+                expr,
+                trim_what,
+                trim_characters,
+                ..
+            } => union_spans(
+                core::iter::once(expr.span())
+                    .chain(trim_what.iter().map(Spanned::span))
+                    .chain(trim_characters.iter().flat_map(|items| items.iter().map(Spanned::span))),
+            ),
+            Expr::Overlay {
+                expr,
+                overlay_what,
+                overlay_from,
+                overlay_for,
+            } => union_spans(
+                core::iter::once(expr.span())
+                    .chain(core::iter::once(overlay_what.span()))
+                    .chain(core::iter::once(overlay_from.span()))
+                    .chain(overlay_for.iter().map(Spanned::span)),
+            ),
+            Expr::Collate { expr, collation } => expr.span().union(&collation.span()),
+            Expr::Value(value) => value.span(),
+            Expr::IntroducedString { value, .. } => value.span(),
+            Expr::TypedString { .. } => Span::empty(),
+            Expr::MapAccess { column, keys } => {
+                column
+                    .span()
+                    .union(&union_spans(keys.iter().map(|k| k.key.span())))
+            }
+            Expr::Function(function) => function.span(),
+            Expr::Method(method) => {
+                method
+                    .expr
+                    .span()
+                    .union(&union_spans(method.method_chain.iter().map(Spanned::span)))
+            }
+            Expr::Case {
+                operand,
+                conditions,
+                results,
+                else_result,
+            } => union_spans(
+                operand
+                    .iter()
+                    .map(Spanned::span)
+                    .chain(conditions.iter().map(Spanned::span))
+                    .chain(results.iter().map(Spanned::span))
+                    .chain(else_result.iter().map(Spanned::span)),
+            ),
+            Expr::Exists { subquery, .. } => subquery.span(),
+            Expr::Subquery(query) => query.span(),
+            Expr::GroupingSets(v) | Expr::Cube(v) | Expr::Rollup(v) => union_spans(
+                v.iter()
+                    .flat_map(|items| items.iter())
+                    .map(Spanned::span),
+            ),
+            Expr::Tuple(v) => union_spans(v.iter().map(Spanned::span)),
+            Expr::Struct { values, .. } => union_spans(values.iter().map(Spanned::span)),
+            Expr::Named { expr, name } => expr.span().union(&name.span()),
+            Expr::Dictionary(v) => union_spans(v.iter().map(|item| item.value.span())),
+            Expr::Map(map) => union_spans(
+                map.entries
+                    .iter()
+                    .flat_map(|entry| [entry.key.span(), entry.value.span()]),
+            ),
+            Expr::Subscript { expr, subscript } => expr.span().union(&subscript.span()),
+            Expr::Array(array) => union_spans(array.elem.iter().map(Spanned::span)),
+            Expr::Interval(interval) => interval.value.span(),
+            Expr::MatchAgainst { columns, .. } => union_spans(columns.iter().map(Spanned::span)),
+            Expr::Wildcard => Span::empty(),
+            Expr::QualifiedWildcard(name) => name.span(),
+            Expr::Lambda(lambda) => {
+                lambda
+                    .body
+                    .span()
+                    .union(&union_spans(lambda.params.iter().map(Spanned::span)))
+            }
+            _ => Span::empty(),
+        }
+    }
+}
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/parser/mod.rs b/app/src/parser/mod.rs
index 6767f35..b1f8ed1 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/parser/mod.rs
+++ b/app/src/parser/mod.rs
@@ -372,6 +372,7 @@ impl<'a> Parser<'a> {
             .map(|token| TokenWithLocation {
                 token,
                 location: Location { line: 0, column: 0 },
+                span: Span::empty(),
             })
             .collect();
         self.with_tokens_with_locations(tokens_with_locations)
@@ -3298,7 +3299,7 @@ impl<'a> Parser<'a> {
             index += 1;
             if let Some(TokenWithLocation {
                 token: Token::Whitespace(_),
-                location: _,
+                ..
             }) = token
             {
                 continue;
@@ -3306,6 +3307,7 @@ impl<'a> Parser<'a> {
             break token.cloned().unwrap_or(TokenWithLocation {
                 token: Token::EOF,
                 location: Location { line: 0, column: 0 },
+                span: Span::empty(),
             });
         })
     }
@@ -3318,13 +3320,14 @@ impl<'a> Parser<'a> {
             match self.tokens.get(index - 1) {
                 Some(TokenWithLocation {
                     token: Token::Whitespace(_),
-                    location: _,
+                    ..
                 }) => continue,
                 non_whitespace => {
                     if n == 0 {
                         return non_whitespace.cloned().unwrap_or(TokenWithLocation {
                             token: Token::EOF,
                             location: Location { line: 0, column: 0 },
+                            span: Span::empty(),
                         });
                     }
                     n -= 1;
@@ -3347,6 +3350,7 @@ impl<'a> Parser<'a> {
             .unwrap_or(TokenWithLocation {
                 token: Token::EOF,
                 location: Location { line: 0, column: 0 },
+                span: Span::empty(),
             })
     }
 
@@ -3375,7 +3379,7 @@ impl<'a> Parser<'a> {
             match self.tokens.get(self.index - 1) {
                 Some(TokenWithLocation {
                     token: Token::Whitespace(_),
-                    location: _,
+                    ..
                 }) => continue,
                 token => {
                     return token
@@ -3401,7 +3405,7 @@ impl<'a> Parser<'a> {
             self.index -= 1;
             if let Some(TokenWithLocation {
                 token: Token::Whitespace(_),
-                location: _,
+                ..
             }) = self.tokens.get(self.index)
             {
                 continue;
@@ -6819,6 +6823,7 @@ impl<'a> Parser<'a> {
                         TokenWithLocation {
                             token: Token::make_keyword(&name.to_string()),
                             location: next_token.location,
+                            span: next_token.span,
                         },
                     );
                 }
@@ -7795,6 +7800,7 @@ impl<'a> Parser<'a> {
                         TokenWithLocation {
                             token: Token::Word(w),
                             location,
+                            span: next_token.span,
                         },
                     )?,
                 },
@@ -7803,6 +7809,7 @@ impl<'a> Parser<'a> {
                     TokenWithLocation {
                         token: Token::Word(w),
                         location,
+                        span: next_token.span,
                     },
                 ),
             },
@@ -7853,7 +7860,7 @@ impl<'a> Parser<'a> {
                 // This because snowflake allows numbers as placeholders
                 let next_token = self.next_token();
                 let ident = match next_token.token {
-                    Token::Word(w) => Ok(w.to_ident()),
+                    Token::Word(w) => Ok(w.to_ident_with_span(next_token.span)),
                     Token::Number(w, false) => Ok(Ident::new(w)),
                     _ => self.expected("placeholder", next_token),
                 }?;
@@ -7865,6 +7872,7 @@ impl<'a> Parser<'a> {
                 TokenWithLocation {
                     token: unexpected,
                     location,
+                    span: next_token.span,
                 },
             ),
         }
@@ -7914,6 +7922,7 @@ impl<'a> Parser<'a> {
                 TokenWithLocation {
                     token: unexpected,
                     location,
+                    span: next_token.span,
                 },
             ),
         }
@@ -8455,6 +8464,7 @@ impl<'a> Parser<'a> {
                         .map(|value| Ident {
                             value: value.into(),
                             quote_style: ident.quote_style,
+                            span: ident.span,
                         })
                         .collect::<Vec<_>>()
                 })
@@ -8468,9 +8478,10 @@ impl<'a> Parser<'a> {
     pub fn parse_identifiers(&mut self) -> Result<Vec<Ident>, ParserError> {
         let mut idents = vec![];
         loop {
-            match self.peek_token().token {
+            let token = self.peek_token();
+            match token.token {
                 Token::Word(w) => {
-                    idents.push(w.to_ident());
+                    idents.push(w.to_ident_with_span(token.span));
                 }
                 Token::EOF | Token::Eq => break,
                 _ => {}
@@ -8523,8 +8534,9 @@ impl<'a> Parser<'a> {
         let mut idents = vec![];
 
         // expecting at least one word for identifier
-        match self.next_token().token {
-            Token::Word(w) => idents.push(w.to_ident()),
+        let token = self.next_token();
+        match token.token {
+            Token::Word(w) => idents.push(w.to_ident_with_span(token.span)),
             Token::EOF => {
                 return Err(ParserError::ParserError(
                     "Empty input when parsing identifier".to_string(),
@@ -8541,8 +8553,10 @@ impl<'a> Parser<'a> {
         loop {
             match self.next_token().token {
                 // ensure that optional period is succeeded by another identifier
-                Token::Period => match self.next_token().token {
-                    Token::Word(w) => idents.push(w.to_ident()),
+                Token::Period => {
+                    let token = self.next_token();
+                    match token.token {
+                        Token::Word(w) => idents.push(w.to_ident_with_span(token.span)),
                     Token::EOF => {
                         return Err(ParserError::ParserError(
                             "Trailing period in identifier".to_string(),
@@ -8553,7 +8567,8 @@ impl<'a> Parser<'a> {
                             "Unexpected token following period in identifier: {token}"
                         )))?
                     }
-                },
+                    }
+                }
                 Token::EOF => break,
                 token => {
                     return Err(ParserError::ParserError(format!(
@@ -8575,7 +8590,7 @@ impl<'a> Parser<'a> {
         let next_token = self.next_token();
         match next_token.token {
             Token::Word(w) => {
-                let mut ident = w.to_ident();
+                let mut ident = w.to_ident_with_span(next_token.span);
 
                 // On BigQuery, hyphens are permitted in unquoted identifiers inside of a FROM or
                 // TABLE clause [0].
@@ -8626,8 +8641,12 @@ impl<'a> Parser<'a> {
                 }
                 Ok(ident)
             }
-            Token::SingleQuotedString(s) => Ok(Ident::with_quote('\'', s)),
-            Token::DoubleQuotedString(s) => Ok(Ident::with_quote('\"', s)),
+            Token::SingleQuotedString(s) => {
+                Ok(Ident::with_quote_and_span('\'', next_token.span, s))
+            }
+            Token::DoubleQuotedString(s) => {
+                Ok(Ident::with_quote_and_span('\"', next_token.span, s))
+            }
             _ => self.expected("identifier", next_token),
         }
     }
@@ -12816,6 +12835,15 @@ impl Word {
         Ident {
             value: self.value.clone(),
             quote_style: self.quote_style,
+            span: Span::empty(),
+        }
+    }
+
+    pub fn to_ident_with_span(&self, span: Span) -> Ident {
+        Ident {
+            value: self.value.clone(),
+            quote_style: self.quote_style,
+            span,
         }
     }
 }
@@ -13389,14 +13417,17 @@ mod tests {
             Ident {
                 value: "CATALOG".to_string(),
                 quote_style: None,
+                span: Span::empty(),
             },
             Ident {
                 value: "F(o)o. \"bar".to_string(),
                 quote_style: Some('"'),
+                span: Span::empty(),
             },
             Ident {
                 value: "table".to_string(),
                 quote_style: None,
+                span: Span::empty(),
             },
         ];
         dialect.run_parser_method(r#"CATALOG."F(o)o. ""bar".table"#, |parser| {
@@ -13409,10 +13440,12 @@ mod tests {
             Ident {
                 value: "CATALOG".to_string(),
                 quote_style: None,
+                span: Span::empty(),
             },
             Ident {
                 value: "table".to_string(),
                 quote_style: None,
+                span: Span::empty(),
             },
         ];
         dialect.run_parser_method("CATALOG . table", |parser| {
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/tokenizer.rs b/app/src/tokenizer.rs
index 05aaf1e..3ca1901 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/src/tokenizer.rs
+++ b/app/src/tokenizer.rs
@@ -422,7 +422,7 @@ impl fmt::Display for Whitespace {
 }
 
 /// Location in input string
-#[derive(Debug, Eq, PartialEq, Clone, Copy)]
+#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash, PartialOrd, Ord)]
 pub struct Location {
     /// Line number, starting from 1
     pub line: u64,
@@ -430,6 +430,22 @@ pub struct Location {
     pub column: u64,
 }
 
+impl Location {
+    pub fn new(line: u64, column: u64) -> Self {
+        Self { line, column }
+    }
+
+    pub fn span_to(self, end: Self) -> Span {
+        Span::new(self, end)
+    }
+}
+
+impl From<(u64, u64)> for Location {
+    fn from((line, column): (u64, u64)) -> Self {
+        Self::new(line, column)
+    }
+}
+
 impl fmt::Display for Location {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         if self.line == 0 {
@@ -444,23 +460,94 @@ impl fmt::Display for Location {
     }
 }
 
+/// A span in the input string, inclusive start and exclusive end.
+#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash, PartialOrd, Ord)]
+pub struct Span {
+    pub start: Location,
+    pub end: Location,
+}
+
+impl Span {
+    pub fn new(start: Location, end: Location) -> Self {
+        Self { start, end }
+    }
+
+    pub fn empty() -> Self {
+        Self {
+            start: Location::new(0, 0),
+            end: Location::new(0, 0),
+        }
+    }
+
+    pub fn is_empty(&self) -> bool {
+        *self == Self::empty()
+    }
+
+    pub fn union(&self, other: &Self) -> Self {
+        if self.is_empty() {
+            return *other;
+        }
+        if other.is_empty() {
+            return *self;
+        }
+
+        let start = if self.start <= other.start {
+            self.start
+        } else {
+            other.start
+        };
+        let end = if self.end >= other.end {
+            self.end
+        } else {
+            other.end
+        };
+        Self::new(start, end)
+    }
+
+    pub fn union_opt(&self, other: &Option<Self>) -> Self {
+        match other {
+            Some(other) => self.union(other),
+            None => *self,
+        }
+    }
+
+    pub fn union_iter<I: Iterator<Item = Span>>(iter: I) -> Span {
+        iter.fold(Span::empty(), |acc, item| acc.union(&item))
+    }
+}
+
 /// A [Token] with [Location] attached to it
 #[derive(Debug, Eq, PartialEq, Clone)]
 pub struct TokenWithLocation {
     pub token: Token,
     pub location: Location,
+    pub span: Span,
 }
 
 impl TokenWithLocation {
     pub fn new(token: Token, line: u64, column: u64) -> TokenWithLocation {
+        let location = Location { line, column };
         TokenWithLocation {
             token,
-            location: Location { line, column },
+            location,
+            span: Span::new(location, location),
         }
     }
 
+    pub fn with_span(token: Token, span: Span) -> TokenWithLocation {
+        TokenWithLocation {
+            token,
+            location: span.start,
+            span,
+        }
+    }
+
+    pub fn at(token: Token, start: Location, end: Location) -> TokenWithLocation {
+        TokenWithLocation::with_span(token, Span::new(start, end))
+    }
+
     pub fn wrap(token: Token) -> TokenWithLocation {
-        TokenWithLocation::new(token, 0, 0)
+        TokenWithLocation::with_span(token, Span::empty())
     }
 }
 
@@ -656,7 +743,12 @@ impl<'a> Tokenizer<'a> {
 
         let mut location = state.location();
         while let Some(token) = self.next_token(&mut state)? {
-            buf.push(TokenWithLocation { token, location });
+            let span = location.span_to(state.location());
+            buf.push(TokenWithLocation {
+                token,
+                location,
+                span,
+            });
 
             location = state.location();
         }
@@ -2669,13 +2761,25 @@ mod tests {
             .tokenize_with_location()
             .unwrap();
         let expected = vec![
-            TokenWithLocation::new(Token::make_keyword("SELECT"), 1, 1),
-            TokenWithLocation::new(Token::Whitespace(Whitespace::Space), 1, 7),
-            TokenWithLocation::new(Token::make_word("a", None), 1, 8),
-            TokenWithLocation::new(Token::Comma, 1, 9),
-            TokenWithLocation::new(Token::Whitespace(Whitespace::Newline), 1, 10),
-            TokenWithLocation::new(Token::Whitespace(Whitespace::Space), 2, 1),
-            TokenWithLocation::new(Token::make_word("b", None), 2, 2),
+            TokenWithLocation::at(Token::make_keyword("SELECT"), (1, 1).into(), (1, 7).into()),
+            TokenWithLocation::at(
+                Token::Whitespace(Whitespace::Space),
+                (1, 7).into(),
+                (1, 8).into(),
+            ),
+            TokenWithLocation::at(Token::make_word("a", None), (1, 8).into(), (1, 9).into()),
+            TokenWithLocation::at(Token::Comma, (1, 9).into(), (1, 10).into()),
+            TokenWithLocation::at(
+                Token::Whitespace(Whitespace::Newline),
+                (1, 10).into(),
+                (2, 1).into(),
+            ),
+            TokenWithLocation::at(
+                Token::Whitespace(Whitespace::Space),
+                (2, 1).into(),
+                (2, 2).into(),
+            ),
+            TokenWithLocation::at(Token::make_word("b", None), (2, 2).into(), (2, 3).into()),
         ];
         compare(expected, tokens);
     }
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_bigquery.rs b/app/tests/sqlparser_bigquery.rs
index d4c178b..6cf08dc 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_bigquery.rs
+++ b/app/tests/sqlparser_bigquery.rs
@@ -677,11 +677,11 @@ fn parse_typed_struct_syntax_bigquery() {
                 Expr::CompoundIdentifier(vec![
                     Ident {
                         value: "t".into(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     },
                     Ident {
                         value: "str_col".into(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     },
                 ]),
             ],
@@ -689,14 +689,14 @@ fn parse_typed_struct_syntax_bigquery() {
                 StructField {
                     field_name: Some(Ident {
                         value: "x".into(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     }),
                     field_type: DataType::Int64
                 },
                 StructField {
                     field_name: Some(Ident {
                         value: "y".into(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     }),
                     field_type: DataType::String(None)
                 },
@@ -708,7 +708,7 @@ fn parse_typed_struct_syntax_bigquery() {
         &Expr::Struct {
             values: vec![Expr::Identifier(Ident {
                 value: "nested_col".into(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             }),],
             fields: vec![
                 StructField {
@@ -739,7 +739,7 @@ fn parse_typed_struct_syntax_bigquery() {
         &Expr::Struct {
             values: vec![Expr::Identifier(Ident {
                 value: "nested_col".into(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             }),],
             fields: vec![
                 StructField {
@@ -986,11 +986,11 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
                 Expr::CompoundIdentifier(vec![
                     Ident {
                         value: "t".into(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     },
                     Ident {
                         value: "str_col".into(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     },
                 ]),
             ],
@@ -998,14 +998,14 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
                 StructField {
                     field_name: Some(Ident {
                         value: "x".into(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     }),
                     field_type: DataType::Int64
                 },
                 StructField {
                     field_name: Some(Ident {
                         value: "y".into(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     }),
                     field_type: DataType::String(None)
                 },
@@ -1017,7 +1017,7 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
         &Expr::Struct {
             values: vec![Expr::Identifier(Ident {
                 value: "nested_col".into(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             }),],
             fields: vec![
                 StructField {
@@ -1048,7 +1048,7 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
         &Expr::Struct {
             values: vec![Expr::Identifier(Ident {
                 value: "nested_col".into(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             }),],
             fields: vec![
                 StructField {
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_clickhouse.rs b/app/tests/sqlparser_clickhouse.rs
index 90af12a..b752915 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_clickhouse.rs
+++ b/app/tests/sqlparser_clickhouse.rs
@@ -44,7 +44,7 @@ fn parse_map_access_expr() {
             projection: vec![UnnamedExpr(MapAccess {
                 column: Box::new(Identifier(Ident {
                     value: "string_values".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 })),
                 keys: vec![MapAccessKey {
                     key: call(
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_common.rs b/app/tests/sqlparser_common.rs
index e22877d..0229b9c 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_common.rs
+++ b/app/tests/sqlparser_common.rs
@@ -1270,7 +1270,7 @@ fn parse_select_with_date_column_name() {
     assert_eq!(
         &Expr::Identifier(Ident {
             value: "date".into(),
-            quote_style: None,
+            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
         }),
         expr_from_projection(only(&select.projection)),
     );
@@ -1788,7 +1788,7 @@ fn parse_null_like() {
             },
             alias: Ident {
                 value: "col_null".to_owned(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             },
         },
         select.projection[0]
@@ -1804,7 +1804,7 @@ fn parse_null_like() {
             },
             alias: Ident {
                 value: "null_col".to_owned(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             },
         },
         select.projection[1]
@@ -2822,7 +2822,7 @@ fn parse_listagg() {
                 OrderByExpr {
                     expr: Expr::Identifier(Ident {
                         value: "id".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     }),
                     asc: None,
                     nulls_first: None,
@@ -2831,7 +2831,7 @@ fn parse_listagg() {
                 OrderByExpr {
                     expr: Expr::Identifier(Ident {
                         value: "username".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     }),
                     asc: None,
                     nulls_first: None,
@@ -4832,7 +4832,7 @@ fn test_parse_named_window() {
                 expr: Expr::Function(Function {
                     name: ObjectName(vec![Ident {
                         value: "MIN".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     }]),
                     parameters: FunctionArguments::None,
                     args: FunctionArguments::List(FunctionArgumentList {
@@ -4840,7 +4840,7 @@ fn test_parse_named_window() {
                         args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
                             Expr::Identifier(Ident {
                                 value: "c12".to_string(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             }),
                         ))],
                         clauses: vec![],
@@ -4849,20 +4849,20 @@ fn test_parse_named_window() {
                     filter: None,
                     over: Some(WindowType::NamedWindow(Ident {
                         value: "window1".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     })),
                     within_group: vec![],
                 }),
                 alias: Ident {
                     value: "min1".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },
             },
             SelectItem::ExprWithAlias {
                 expr: Expr::Function(Function {
                     name: ObjectName(vec![Ident {
                         value: "MAX".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     }]),
                     parameters: FunctionArguments::None,
                     args: FunctionArguments::List(FunctionArgumentList {
@@ -4870,7 +4870,7 @@ fn test_parse_named_window() {
                         args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
                             Expr::Identifier(Ident {
                                 value: "c12".to_string(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             }),
                         ))],
                         clauses: vec![],
@@ -4879,13 +4879,13 @@ fn test_parse_named_window() {
                     filter: None,
                     over: Some(WindowType::NamedWindow(Ident {
                         value: "window2".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     })),
                     within_group: vec![],
                 }),
                 alias: Ident {
                     value: "max1".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },
             },
         ],
@@ -4894,7 +4894,7 @@ fn test_parse_named_window() {
             relation: TableFactor::Table {
                 name: ObjectName(vec![Ident {
                     value: "aggregate_test_100".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 }]),
                 alias: None,
                 args: None,
@@ -4918,7 +4918,7 @@ fn test_parse_named_window() {
             NamedWindowDefinition(
                 Ident {
                     value: "window1".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },
                 NamedWindowExpr::WindowSpec(WindowSpec {
                     window_name: None,
@@ -4926,7 +4926,7 @@ fn test_parse_named_window() {
                     order_by: vec![OrderByExpr {
                         expr: Expr::Identifier(Ident {
                             value: "C12".to_string(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         }),
                         asc: None,
                         nulls_first: None,
@@ -4938,13 +4938,13 @@ fn test_parse_named_window() {
             NamedWindowDefinition(
                 Ident {
                     value: "window2".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },
                 NamedWindowExpr::WindowSpec(WindowSpec {
                     window_name: None,
                     partition_by: vec![Expr::Identifier(Ident {
                         value: "C11".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     })],
                     order_by: vec![],
                     window_frame: None,
@@ -5424,7 +5424,7 @@ fn interval_disallow_interval_expr_gt() {
             op: BinaryOperator::Gt,
             right: Box::new(Expr::Identifier(Ident {
                 value: "x".to_string(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             })),
         }
     )
@@ -5470,14 +5470,14 @@ fn parse_interval_and_or_xor() {
             top_before_distinct: false,
             projection: vec![UnnamedExpr(Expr::Identifier(Ident {
                 value: "col".to_string(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             }))],
             into: None,
             from: vec![TableWithJoins {
                 relation: TableFactor::Table {
                     name: ObjectName(vec![Ident {
                         value: "test".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     }]),
                     alias: None,
                     args: None,
@@ -5495,13 +5495,13 @@ fn parse_interval_and_or_xor() {
                 left: Box::new(Expr::BinaryOp {
                     left: Box::new(Expr::Identifier(Ident {
                         value: "d3_date".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     })),
                     op: BinaryOperator::Gt,
                     right: Box::new(Expr::BinaryOp {
                         left: Box::new(Expr::Identifier(Ident {
                             value: "d1_date".to_string(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         })),
                         op: BinaryOperator::Plus,
                         right: Box::new(Expr::Interval(Interval {
@@ -5519,13 +5519,13 @@ fn parse_interval_and_or_xor() {
                 right: Box::new(Expr::BinaryOp {
                     left: Box::new(Expr::Identifier(Ident {
                         value: "d2_date".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     })),
                     op: BinaryOperator::Gt,
                     right: Box::new(Expr::BinaryOp {
                         left: Box::new(Expr::Identifier(Ident {
                             value: "d1_date".to_string(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         })),
                         op: BinaryOperator::Plus,
                         right: Box::new(Expr::Interval(Interval {
@@ -5616,7 +5616,7 @@ fn parse_at_timezone() {
             ),
             alias: Ident {
                 value: "hour".to_string(),
-                quote_style: Some('"'),
+                quote_style: Some('"'), span: sqlparser::tokenizer::Span::empty(),
             },
         },
         only(&select.projection),
@@ -6636,7 +6636,7 @@ fn parse_recursive_cte() {
         alias: TableAlias {
             name: Ident {
                 value: "nums".to_string(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             },
             columns: vec![TableAliasColumnDef::from_name("val")],
         },
@@ -7631,7 +7631,7 @@ fn lateral_function() {
             relation: TableFactor::Table {
                 name: ObjectName(vec![Ident {
                     value: "customer".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 }]),
                 alias: None,
                 args: None,
@@ -8269,11 +8269,11 @@ fn parse_grant() {
                             columns: Some(vec![
                                 Ident {
                                     value: "shape".into(),
-                                    quote_style: None,
+                                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                                 },
                                 Ident {
                                     value: "size".into(),
-                                    quote_style: None,
+                                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                                 },
                             ])
                         },
@@ -8514,7 +8514,7 @@ fn parse_merge() {
                     alias: Some(TableAlias {
                         name: Ident {
                             value: "stg".to_string(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         },
                         columns: vec![],
                     }),
@@ -9998,11 +9998,11 @@ fn parse_execute_stored_procedure() {
         name: ObjectName(vec![
             Ident {
                 value: "my_schema".to_string(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             },
             Ident {
                 value: "my_stored_procedure".to_string(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             },
         ]),
         parameters: vec![
@@ -11205,7 +11205,7 @@ fn test_extract_seconds_ok() {
         Expr::Extract {
             field: DateTimeField::Custom(Ident {
                 value: "seconds".to_string(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             }),
             syntax: ExtractSyntax::From,
             expr: Box::new(Expr::Cast {
@@ -11230,7 +11230,7 @@ fn test_extract_seconds_single_quote_ok() {
         Expr::Extract {
             field: DateTimeField::Custom(Ident {
                 value: "seconds".to_string(),
-                quote_style: Some('\''),
+                quote_style: Some('\''), span: sqlparser::tokenizer::Span::empty(),
             }),
             syntax: ExtractSyntax::From,
             expr: Box::new(Expr::Cast {
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_duckdb.rs b/app/tests/sqlparser_duckdb.rs
index 73b0f66..109ed6b 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_duckdb.rs
+++ b/app/tests/sqlparser_duckdb.rs
@@ -274,7 +274,7 @@ fn test_select_union_by_name() {
                     relation: TableFactor::Table {
                         name: ObjectName(vec![Ident {
                             value: "capitals".to_string(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         }]),
                         alias: None,
                         args: None,
@@ -316,7 +316,7 @@ fn test_select_union_by_name() {
                     relation: TableFactor::Table {
                         name: ObjectName(vec![Ident {
                             value: "weather".to_string(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         }]),
                         alias: None,
                         args: None,
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_mssql.rs b/app/tests/sqlparser_mssql.rs
index d1d8d12..2429683 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_mssql.rs
+++ b/app/tests/sqlparser_mssql.rs
@@ -206,7 +206,7 @@ fn parse_mssql_openjson() {
             relation: TableFactor::Table {
                 name: ObjectName(vec![Ident {
                     value: "t_test_table".into(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },]),
                 alias: Some(TableAlias {
                     name: Ident {
@@ -227,11 +227,11 @@ fn parse_mssql_openjson() {
                     json_expr: Expr::CompoundIdentifier(vec![
                         Ident {
                             value: "A".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         },
                         Ident {
                             value: "param".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         }
                     ]),
                     json_path: Some(Value::SingleQuotedString("$.config".into())),
@@ -239,7 +239,7 @@ fn parse_mssql_openjson() {
                         OpenJsonTableColumn {
                             name: Ident {
                                 value: "kind".into(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             },
                             r#type: DataType::Varchar(Some(CharacterLength::IntegerLength {
                                 length: 20,
@@ -251,7 +251,7 @@ fn parse_mssql_openjson() {
                         OpenJsonTableColumn {
                             name: Ident {
                                 value: "id_list".into(),
-                                quote_style: Some('['),
+                                quote_style: Some('['), span: sqlparser::tokenizer::Span::empty(),
                             },
                             r#type: DataType::Nvarchar(Some(CharacterLength::Max)),
                             path: Some("$.id_list".into()),
@@ -282,7 +282,7 @@ fn parse_mssql_openjson() {
             relation: TableFactor::Table {
                 name: ObjectName(vec![Ident {
                     value: "t_test_table".into(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },]),
                 alias: Some(TableAlias {
                     name: Ident {
@@ -303,11 +303,11 @@ fn parse_mssql_openjson() {
                     json_expr: Expr::CompoundIdentifier(vec![
                         Ident {
                             value: "A".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         },
                         Ident {
                             value: "param".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         }
                     ]),
                     json_path: None,
@@ -315,7 +315,7 @@ fn parse_mssql_openjson() {
                         OpenJsonTableColumn {
                             name: Ident {
                                 value: "kind".into(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             },
                             r#type: DataType::Varchar(Some(CharacterLength::IntegerLength {
                                 length: 20,
@@ -327,7 +327,7 @@ fn parse_mssql_openjson() {
                         OpenJsonTableColumn {
                             name: Ident {
                                 value: "id_list".into(),
-                                quote_style: Some('['),
+                                quote_style: Some('['), span: sqlparser::tokenizer::Span::empty(),
                             },
                             r#type: DataType::Nvarchar(Some(CharacterLength::Max)),
                             path: Some("$.id_list".into()),
@@ -358,7 +358,7 @@ fn parse_mssql_openjson() {
             relation: TableFactor::Table {
                 name: ObjectName(vec![Ident {
                     value: "t_test_table".into(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },]),
                 alias: Some(TableAlias {
                     name: Ident {
@@ -379,11 +379,11 @@ fn parse_mssql_openjson() {
                     json_expr: Expr::CompoundIdentifier(vec![
                         Ident {
                             value: "A".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         },
                         Ident {
                             value: "param".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         }
                     ]),
                     json_path: None,
@@ -391,7 +391,7 @@ fn parse_mssql_openjson() {
                         OpenJsonTableColumn {
                             name: Ident {
                                 value: "kind".into(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             },
                             r#type: DataType::Varchar(Some(CharacterLength::IntegerLength {
                                 length: 20,
@@ -403,7 +403,7 @@ fn parse_mssql_openjson() {
                         OpenJsonTableColumn {
                             name: Ident {
                                 value: "id_list".into(),
-                                quote_style: Some('['),
+                                quote_style: Some('['), span: sqlparser::tokenizer::Span::empty(),
                             },
                             r#type: DataType::Nvarchar(Some(CharacterLength::Max)),
                             path: None,
@@ -434,7 +434,7 @@ fn parse_mssql_openjson() {
             relation: TableFactor::Table {
                 name: ObjectName(vec![Ident {
                     value: "t_test_table".into(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },]),
                 alias: Some(TableAlias {
                     name: Ident {
@@ -455,11 +455,11 @@ fn parse_mssql_openjson() {
                     json_expr: Expr::CompoundIdentifier(vec![
                         Ident {
                             value: "A".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         },
                         Ident {
                             value: "param".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         }
                     ]),
                     json_path: Some(Value::SingleQuotedString("$.config".into())),
@@ -488,7 +488,7 @@ fn parse_mssql_openjson() {
             relation: TableFactor::Table {
                 name: ObjectName(vec![Ident {
                     value: "t_test_table".into(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },]),
                 alias: Some(TableAlias {
                     name: Ident {
@@ -509,11 +509,11 @@ fn parse_mssql_openjson() {
                     json_expr: Expr::CompoundIdentifier(vec![
                         Ident {
                             value: "A".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         },
                         Ident {
                             value: "param".into(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         }
                     ]),
                     json_path: None,
@@ -1363,11 +1363,11 @@ fn parse_create_table_with_valid_options() {
                 SqlOption::KeyValue {
                     key: Ident {
                         value: "DISTRIBUTION".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     },
                     value: Expr::Identifier(Ident {
                         value: "ROUND_ROBIN".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     })
                 },
                 SqlOption::Partition {
@@ -1410,21 +1410,21 @@ fn parse_create_table_with_valid_options() {
                         ClusteredIndex {
                             name: Ident {
                                 value: "column_a".to_string(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             },
                             asc: Some(true),
                         },
                         ClusteredIndex {
                             name: Ident {
                                 value: "column_b".to_string(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             },
                             asc: Some(false),
                         },
                         ClusteredIndex {
                             name: Ident {
                                 value: "column_c".to_string(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             },
                             asc: None,
                         },
@@ -1437,7 +1437,7 @@ fn parse_create_table_with_valid_options() {
                 SqlOption::KeyValue {
                     key: Ident {
                         value: "DISTRIBUTION".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     },
                     value: Expr::Function(
                         Function {
@@ -1445,7 +1445,7 @@ fn parse_create_table_with_valid_options() {
                                 vec![
                                     Ident {
                                         value: "HASH".to_string(),
-                                        quote_style: None,
+                                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                                     },
                                 ],
                             ),
@@ -1459,7 +1459,7 @@ fn parse_create_table_with_valid_options() {
                                                 Expr::Identifier(
                                                     Ident {
                                                         value: "column_a".to_string(),
-                                                        quote_style: None,
+                                                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                                                     },
                                                 ),
                                             ),
@@ -1469,7 +1469,7 @@ fn parse_create_table_with_valid_options() {
                                                 Expr::Identifier(
                                                     Ident {
                                                         value: "column_b".to_string(),
-                                                        quote_style: None,
+                                                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                                                     },
                                                 ),
                                             ),
@@ -1503,13 +1503,13 @@ fn parse_create_table_with_valid_options() {
                 volatile: false,
                 name: ObjectName(vec![Ident {
                     value: "mytable".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },],),
                 columns: vec![
                     ColumnDef {
                         name: Ident {
                             value: "column_a".to_string(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         },
                         data_type: Int(None,),
                         collation: None,
@@ -1518,7 +1518,7 @@ fn parse_create_table_with_valid_options() {
                     ColumnDef {
                         name: Ident {
                             value: "column_b".to_string(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         },
                         data_type: Int(None,),
                         collation: None,
@@ -1527,7 +1527,7 @@ fn parse_create_table_with_valid_options() {
                     ColumnDef {
                         name: Ident {
                             value: "column_c".to_string(),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         },
                         data_type: Int(None,),
                         collation: None,
@@ -1668,12 +1668,12 @@ fn parse_create_table_with_identity_column() {
                 volatile: false,
                 name: ObjectName(vec![Ident {
                     value: "mytable".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 },],),
                 columns: vec![ColumnDef {
                     name: Ident {
                         value: "columnA".to_string(),
-                        quote_style: None,
+                        quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                     },
                     data_type: Int(None,),
                     collation: None,
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_mysql.rs b/app/tests/sqlparser_mysql.rs
index 3d8b086..3544b6c 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_mysql.rs
+++ b/app/tests/sqlparser_mysql.rs
@@ -1063,7 +1063,7 @@ fn parse_escaped_quote_identifiers_with_escape() {
                 top_before_distinct: false,
                 projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident {
                     value: "quoted ` identifier".into(),
-                    quote_style: Some('`'),
+                    quote_style: Some('`'), span: sqlparser::tokenizer::Span::empty(),
                 }))],
                 into: None,
                 from: vec![],
@@ -1114,7 +1114,7 @@ fn parse_escaped_quote_identifiers_with_no_escape() {
                 top_before_distinct: false,
                 projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident {
                     value: "quoted `` identifier".into(),
-                    quote_style: Some('`'),
+                    quote_style: Some('`'), span: sqlparser::tokenizer::Span::empty(),
                 }))],
                 into: None,
                 from: vec![],
@@ -1158,7 +1158,7 @@ fn parse_escaped_backticks_with_escape() {
                 top_before_distinct: false,
                 projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident {
                     value: "`quoted identifier`".into(),
-                    quote_style: Some('`'),
+                    quote_style: Some('`'), span: sqlparser::tokenizer::Span::empty(),
                 }))],
                 into: None,
                 from: vec![],
@@ -1206,7 +1206,7 @@ fn parse_escaped_backticks_with_no_escape() {
                 top_before_distinct: false,
                 projection: vec![SelectItem::UnnamedExpr(Expr::Identifier(Ident {
                     value: "``quoted identifier``".into(),
-                    quote_style: Some('`'),
+                    quote_style: Some('`'), span: sqlparser::tokenizer::Span::empty(),
                 }))],
                 into: None,
                 from: vec![],
@@ -2186,7 +2186,7 @@ fn parse_alter_table_add_columns() {
                         },
                         column_position: Some(MySQLColumnPosition::After(Ident {
                             value: String::from("foo"),
-                            quote_style: None,
+                            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                         })),
                     },
                 ]
@@ -2246,7 +2246,7 @@ fn parse_alter_table_change_column() {
         options: vec![ColumnOption::NotNull],
         column_position: Some(MySQLColumnPosition::After(Ident {
             value: String::from("foo"),
-            quote_style: None,
+            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
         })),
     };
     let sql4 = "ALTER TABLE orders CHANGE COLUMN description desc TEXT NOT NULL AFTER foo";
@@ -2285,7 +2285,7 @@ fn parse_alter_table_change_column_with_column_position() {
         options: vec![ColumnOption::NotNull],
         column_position: Some(MySQLColumnPosition::After(Ident {
             value: String::from("total_count"),
-            quote_style: None,
+            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
         })),
     };
 
@@ -2341,7 +2341,7 @@ fn parse_alter_table_modify_column() {
         options: vec![ColumnOption::NotNull],
         column_position: Some(MySQLColumnPosition::After(Ident {
             value: String::from("foo"),
-            quote_style: None,
+            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
         })),
     };
     let sql4 = "ALTER TABLE orders MODIFY COLUMN description TEXT NOT NULL AFTER foo";
@@ -2378,7 +2378,7 @@ fn parse_alter_table_modify_column_with_column_position() {
         options: vec![ColumnOption::NotNull],
         column_position: Some(MySQLColumnPosition::After(Ident {
             value: String::from("total_count"),
-            quote_style: None,
+            quote_style: None, span: sqlparser::tokenizer::Span::empty(),
         })),
     };
 
diff --git a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_postgres.rs b/app/tests/sqlparser_postgres.rs
index d27569e..fde5c15 100644
--- a/tmp/agent-patch-flux-pr-1435.1-of-1.2026-02-28__18-27-22__gpt-5-3-codex/app/tests/sqlparser_postgres.rs
+++ b/app/tests/sqlparser_postgres.rs
@@ -1171,14 +1171,14 @@ fn parse_copy_to() {
                             expr: Expr::Value(number("42")),
                             alias: Ident {
                                 value: "a".into(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             },
                         },
                         SelectItem::ExprWithAlias {
                             expr: Expr::Value(Value::SingleQuotedString("hello".into())),
                             alias: Ident {
                                 value: "b".into(),
-                                quote_style: None,
+                                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                             },
                         }
                     ],
@@ -1451,7 +1451,7 @@ fn parse_set_role() {
             context_modifier: ContextModifier::Local,
             role_name: Some(Ident {
                 value: "rolename".to_string(),
-                quote_style: Some('\"'),
+                quote_style: Some('\"'), span: sqlparser::tokenizer::Span::empty(),
             }),
         }
     );
@@ -1465,7 +1465,7 @@ fn parse_set_role() {
             context_modifier: ContextModifier::None,
             role_name: Some(Ident {
                 value: "rolename".to_string(),
-                quote_style: Some('\''),
+                quote_style: Some('\''), span: sqlparser::tokenizer::Span::empty(),
             }),
         }
     );
@@ -3122,7 +3122,7 @@ fn parse_custom_operator() {
         Some(Expr::BinaryOp {
             left: Box::new(Expr::Identifier(Ident {
                 value: "relname".into(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             })),
             op: BinaryOperator::PGCustomBinaryOperator(vec![
                 "database".into(),
@@ -3141,7 +3141,7 @@ fn parse_custom_operator() {
         Some(Expr::BinaryOp {
             left: Box::new(Expr::Identifier(Ident {
                 value: "relname".into(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             })),
             op: BinaryOperator::PGCustomBinaryOperator(vec!["pg_catalog".into(), "~".into()]),
             right: Box::new(Expr::Value(Value::SingleQuotedString("^(table)$".into())))
@@ -3156,7 +3156,7 @@ fn parse_custom_operator() {
         Some(Expr::BinaryOp {
             left: Box::new(Expr::Identifier(Ident {
                 value: "relname".into(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             })),
             op: BinaryOperator::PGCustomBinaryOperator(vec!["~".into()]),
             right: Box::new(Expr::Value(Value::SingleQuotedString("^(table)$".into())))
@@ -3859,7 +3859,7 @@ fn parse_dollar_quoted_string() {
             })),
             alias: Ident {
                 value: "col_name".into(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             },
         }
     );
@@ -5016,7 +5016,7 @@ fn check_arrow_precedence(sql: &str, arrow_operator: BinaryOperator) {
             left: Box::new(Expr::BinaryOp {
                 left: Box::new(Expr::Identifier(Ident {
                     value: "foo".to_string(),
-                    quote_style: None,
+                    quote_style: None, span: sqlparser::tokenizer::Span::empty(),
                 })),
                 op: arrow_operator,
                 right: Box::new(Expr::Value(Value::SingleQuotedString("bar".to_string()))),
@@ -5046,7 +5046,7 @@ fn arrow_cast_precedence() {
         Expr::BinaryOp {
             left: Box::new(Expr::Identifier(Ident {
                 value: "foo".to_string(),
-                quote_style: None,
+                quote_style: None, span: sqlparser::tokenizer::Span::empty(),
             })),
             op: BinaryOperator::Arrow,
             right: Box::new(Expr::Cast {