This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch 
gh-readonly-queue/main/pr-2281-df0d56cfa28ae556a4dd3740c6150af46415bf12
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git

commit 6f8e7b85c2570bff270989a2dfb93f7c4921e854
Author: xitep <[email protected]>
AuthorDate: Fri Mar 27 10:37:44 2026 +0100

    Expose values through ValueWithSpan (#2281)
---
 src/ast/helpers/key_value_options.rs |   6 +-
 src/ast/mod.rs                       |  46 +++++++-------
 src/ast/query.rs                     |  16 ++---
 src/ast/spans.rs                     |  12 +---
 src/ast/value.rs                     |  31 +++++++---
 src/ast/visitor.rs                   |  18 +++---
 src/dialect/snowflake.rs             |  15 +++--
 src/parser/alter.rs                  |   2 +-
 src/parser/mod.rs                    | 109 ++++++++++++++++----------------
 tests/sqlparser_common.rs            |  80 ++++++++++++++----------
 tests/sqlparser_mssql.rs             |   4 +-
 tests/sqlparser_mysql.rs             |  11 ++--
 tests/sqlparser_postgres.rs          |   2 +-
 tests/sqlparser_redshift.rs          |   2 +-
 tests/sqlparser_snowflake.rs         | 116 +++++++++++++++++++----------------
 15 files changed, 256 insertions(+), 214 deletions(-)

diff --git a/src/ast/helpers/key_value_options.rs 
b/src/ast/helpers/key_value_options.rs
index e8e543b0..2aa59d9d 100644
--- a/src/ast/helpers/key_value_options.rs
+++ b/src/ast/helpers/key_value_options.rs
@@ -29,7 +29,7 @@ use serde::{Deserialize, Serialize};
 #[cfg(feature = "visitor")]
 use sqlparser_derive::{Visit, VisitMut};
 
-use crate::ast::{display_comma_separated, display_separated, Value};
+use crate::ast::{display_comma_separated, display_separated, ValueWithSpan};
 
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -75,9 +75,9 @@ pub struct KeyValueOption {
 /// The kind of value for a key-value option.
 pub enum KeyValueOptionKind {
     /// A single value.
-    Single(Value),
+    Single(ValueWithSpan),
     /// Multiple values.
-    Multi(Vec<Value>),
+    Multi(Vec<ValueWithSpan>),
     /// A nested list of key-value options.
     KeyValueOptions(Box<KeyValueOptions>),
 }
diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index 36c41d6c..d7a3679a 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -624,9 +624,9 @@ impl fmt::Display for MapEntry {
 #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub enum CastFormat {
     /// A simple cast format specified by a `Value`.
-    Value(Value),
+    Value(ValueWithSpan),
     /// A cast format with an explicit time zone: `(format, timezone)`.
-    ValueAtTimeZone(Value, Value),
+    ValueAtTimeZone(ValueWithSpan, ValueWithSpan),
 }
 
 /// An element of a JSON path.
@@ -778,7 +778,7 @@ pub enum CeilFloorKind {
     /// `CEIL( <expr> TO <DateTimeField>)`
     DateTimeField(DateTimeField),
     /// `CEIL( <expr> [, <scale>])`
-    Scale(Value),
+    Scale(ValueWithSpan),
 }
 
 /// A WHEN clause in a CASE expression containing both
@@ -956,7 +956,7 @@ pub enum Expr {
         /// Pattern expression.
         pattern: Box<Expr>,
         /// Optional escape character.
-        escape_char: Option<Value>,
+        escape_char: Option<ValueWithSpan>,
     },
     /// `ILIKE` (case-insensitive `LIKE`)
     ILike {
@@ -970,7 +970,7 @@ pub enum Expr {
         /// Pattern expression.
         pattern: Box<Expr>,
         /// Optional escape character.
-        escape_char: Option<Value>,
+        escape_char: Option<ValueWithSpan>,
     },
     /// `SIMILAR TO` regex
     SimilarTo {
@@ -981,7 +981,7 @@ pub enum Expr {
         /// Pattern expression.
         pattern: Box<Expr>,
         /// Optional escape character.
-        escape_char: Option<Value>,
+        escape_char: Option<ValueWithSpan>,
     },
     /// MySQL: `RLIKE` regex or `REGEXP` regex
     RLike {
@@ -1146,12 +1146,12 @@ pub enum Expr {
     /// TRIM(<expr>, [, characters]) -- PostgreSQL, DuckDB, Snowflake, 
BigQuery, Generic
     /// ```
     Trim {
-        /// The expression to trim from.
-        expr: Box<Expr>,
         /// Which side to trim: `BOTH`, `LEADING`, or `TRAILING`.
         trim_where: Option<TrimWhereField>,
-        /// Optional expression specifying what to trim from the value.
+        /// Optional expression specifying what to trim from the value `expr`.
         trim_what: Option<Box<Expr>>,
+        /// The expression to trim from.
+        expr: Box<Expr>,
         /// Optional list of characters to trim (dialect-specific).
         trim_characters: Option<Vec<Expr>>,
     },
@@ -1292,7 +1292,7 @@ pub enum Expr {
         /// `(<col>, <col>, ...)`.
         columns: Vec<ObjectName>,
         /// `<expr>`.
-        match_value: Value,
+        match_value: ValueWithSpan,
         /// `<search modifier>`
         opt_search_modifier: Option<SearchModifier>,
     },
@@ -3295,7 +3295,7 @@ pub enum Set {
         /// Transaction modes (e.g., ISOLATION LEVEL, READ ONLY).
         modes: Vec<TransactionMode>,
         /// Optional snapshot value for transaction snapshot control.
-        snapshot: Option<Value>,
+        snapshot: Option<ValueWithSpan>,
         /// `true` when the `SESSION` keyword was used.
         session: bool,
     },
@@ -4630,7 +4630,7 @@ pub enum Statement {
         /// Pragma name (possibly qualified).
         name: ObjectName,
         /// Optional pragma value.
-        value: Option<Value>,
+        value: Option<ValueWithSpan>,
         /// Whether the pragma used `=`.
         is_eq: bool,
     },
@@ -6752,7 +6752,7 @@ pub enum FetchDirection {
     /// Fetch a specific count of rows.
     Count {
         /// The limit value for the count.
-        limit: Value,
+        limit: ValueWithSpan,
     },
     /// Fetch the next row.
     Next,
@@ -6765,12 +6765,12 @@ pub enum FetchDirection {
     /// Fetch an absolute row by index.
     Absolute {
         /// The absolute index value.
-        limit: Value,
+        limit: ValueWithSpan,
     },
     /// Fetch a row relative to the current position.
     Relative {
         /// The relative offset value.
-        limit: Value,
+        limit: ValueWithSpan,
     },
     /// Fetch all rows.
     All,
@@ -6779,7 +6779,7 @@ pub enum FetchDirection {
     /// Fetch forward by an optional limit.
     Forward {
         /// Optional forward limit.
-        limit: Option<Value>,
+        limit: Option<ValueWithSpan>,
     },
     /// Fetch all forward rows.
     ForwardAll,
@@ -6788,7 +6788,7 @@ pub enum FetchDirection {
     /// Fetch backward by an optional limit.
     Backward {
         /// Optional backward limit.
-        limit: Option<Value>,
+        limit: Option<ValueWithSpan>,
     },
     /// Fetch all backward rows.
     BackwardAll,
@@ -8116,7 +8116,7 @@ pub enum FunctionArgumentClause {
     /// The `SEPARATOR` clause to the [`GROUP_CONCAT`] function in MySQL.
     ///
     /// [`GROUP_CONCAT`]: 
https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat
-    Separator(Value),
+    Separator(ValueWithSpan),
     /// The `ON NULL` clause for some JSON functions.
     ///
     /// [MSSQL 
`JSON_ARRAY`](https://learn.microsoft.com/en-us/sql/t-sql/functions/json-array-transact-sql?view=sql-server-ver16)
@@ -9465,7 +9465,7 @@ impl fmt::Display for CopyLegacyOption {
 #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub struct FileSize {
     /// Numeric size value.
-    pub size: Value,
+    pub size: ValueWithSpan,
     /// Optional unit for the size (MB or GB).
     pub unit: Option<FileSizeUnit>,
 }
@@ -10654,11 +10654,11 @@ pub struct ShowStatementOptions {
     /// Optional scope to show in (for example: TABLE, SCHEMA).
     pub show_in: Option<ShowStatementIn>,
     /// Optional `STARTS WITH` filter value.
-    pub starts_with: Option<Value>,
+    pub starts_with: Option<ValueWithSpan>,
     /// Optional `LIMIT` expression.
     pub limit: Option<Expr>,
     /// Optional `FROM` value used with `LIMIT`.
-    pub limit_from: Option<Value>,
+    pub limit_from: Option<ValueWithSpan>,
     /// Optional filter position (infix or suffix) for `LIKE`/`FILTER`.
     pub filter_position: Option<ShowStatementFilterPosition>,
 }
@@ -11474,7 +11474,7 @@ pub struct AlterUserRemoveRoleDelegation {
 #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub struct AlterUserAddMfaMethodOtp {
     /// Optional OTP count parameter.
-    pub count: Option<Value>,
+    pub count: Option<ValueWithSpan>,
 }
 
 /// ```sql
@@ -11795,7 +11795,7 @@ pub struct VacuumStatement {
     /// Optional table to run `VACUUM` on.
     pub table_name: Option<ObjectName>,
     /// Optional threshold value (percent) for `TO threshold PERCENT`.
-    pub threshold: Option<Value>,
+    pub threshold: Option<ValueWithSpan>,
     /// Whether `BOOST` was specified.
     pub boost: bool,
 }
diff --git a/src/ast/query.rs b/src/ast/query.rs
index ca74db44..a52d518b 100644
--- a/src/ast/query.rs
+++ b/src/ast/query.rs
@@ -1552,7 +1552,7 @@ pub enum TableFactor {
         json_expr: Expr,
         /// The path to the array or object to be iterated over.
         /// It must evaluate to a json array or object.
-        json_path: Value,
+        json_path: ValueWithSpan,
         /// The columns to be extracted from each element of the array or 
object.
         /// Each column must have a name and a type.
         columns: Vec<JsonTableColumn>,
@@ -1573,7 +1573,7 @@ pub enum TableFactor {
         json_expr: Expr,
         /// The path to the array or object to be iterated over.
         /// It must evaluate to a json array or object.
-        json_path: Option<Value>,
+        json_path: Option<ValueWithSpan>,
         /// The columns to be extracted from each element of the array or 
object.
         /// Each column must have a name and a type.
         columns: Vec<OpenJsonTableColumn>,
@@ -1833,7 +1833,7 @@ pub struct TableSampleSeed {
     /// Seed modifier (e.g. `REPEATABLE` or `SEED`).
     pub modifier: TableSampleSeedModifier,
     /// The seed value expression.
-    pub value: Value,
+    pub value: ValueWithSpan,
 }
 
 impl fmt::Display for TableSampleSeed {
@@ -1889,9 +1889,9 @@ impl fmt::Display for TableSampleUnit {
 /// Bucket-based sampling clause: `BUCKET <bucket> OUT OF <total> [ON <expr>]`.
 pub struct TableSampleBucket {
     /// The bucket index expression.
-    pub bucket: Value,
+    pub bucket: ValueWithSpan,
     /// The total number of buckets expression.
-    pub total: Value,
+    pub total: ValueWithSpan,
     /// Optional `ON <expr>` specification.
     pub on: Option<Expr>,
 }
@@ -3979,7 +3979,7 @@ impl fmt::Display for JsonTableColumn {
 /// A nested column in a `JSON_TABLE` column list.
 pub struct JsonTableNestedColumn {
     /// JSON path expression (must be a literal `Value`).
-    pub path: Value,
+    pub path: ValueWithSpan,
     /// Columns extracted from the matched nested array.
     pub columns: Vec<JsonTableColumn>,
 }
@@ -4011,7 +4011,7 @@ pub struct JsonTableNamedColumn {
     /// The type of the column to be extracted.
     pub r#type: DataType,
     /// The path to the column to be extracted. Must be a literal string.
-    pub path: Value,
+    pub path: ValueWithSpan,
     /// true if the column is a boolean set to true if the given path exists
     pub exists: bool,
     /// The empty handling clause of the column
@@ -4050,7 +4050,7 @@ pub enum JsonTableColumnErrorHandling {
     /// `NULL` — return NULL when the path does not match.
     Null,
     /// `DEFAULT <value>` — use the provided `Value` as a default.
-    Default(Value),
+    Default(ValueWithSpan),
     /// `ERROR` — raise an error.
     Error,
 }
diff --git a/src/ast/spans.rs b/src/ast/spans.rs
index 2af57d98..d80a3f4d 100644
--- a/src/ast/spans.rs
+++ b/src/ast/spans.rs
@@ -46,8 +46,8 @@ use super::{
     RenameSelectItem, ReplaceSelectElement, ReplaceSelectItem, Select, 
SelectInto, SelectItem,
     SetExpr, SqlOption, Statement, Subscript, SymbolDefinition, TableAlias, 
TableAliasColumnDef,
     TableConstraint, TableFactor, TableObject, TableOptionsClustered, 
TableWithJoins, Update,
-    UpdateTableFromKind, Use, Value, Values, ViewColumnDef, WhileStatement,
-    WildcardAdditionalOptions, With, WithFill,
+    UpdateTableFromKind, Use, Values, ViewColumnDef, WhileStatement, 
WildcardAdditionalOptions,
+    With, WithFill,
 };
 
 /// Given an iterator of spans, return the [Span::union] of all spans.
@@ -2185,13 +2185,6 @@ impl Spanned for ValueWithSpan {
     }
 }
 
-/// The span is stored in the `ValueWrapper` struct
-impl Spanned for Value {
-    fn span(&self) -> Span {
-        Span::empty() // # todo: Value needs to store spans before this is 
possible
-    }
-}
-
 impl Spanned for Join {
     fn span(&self) -> Span {
         let Join {
@@ -2565,6 +2558,7 @@ impl Spanned for comments::CommentWithSpan {
 
 #[cfg(test)]
 pub mod tests {
+    use crate::ast::Value;
     use crate::dialect::{Dialect, GenericDialect, SnowflakeDialect};
     use crate::parser::Parser;
     use crate::tokenizer::{Location, Span};
diff --git a/src/ast/value.rs b/src/ast/value.rs
index 8879a252..5f069f36 100644
--- a/src/ast/value.rs
+++ b/src/ast/value.rs
@@ -18,7 +18,10 @@
 #[cfg(not(feature = "std"))]
 use alloc::string::String;
 
-use core::fmt;
+use core::{
+    fmt,
+    ops::{Deref, DerefMut},
+};
 
 #[cfg(feature = "bigdecimal")]
 use bigdecimal::BigDecimal;
@@ -67,7 +70,11 @@ use sqlparser_derive::{Visit, VisitMut};
 /// A `Value` paired with its source `Span` location.
 #[derive(Debug, Clone, Eq)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+#[cfg_attr(
+    feature = "visitor",
+    derive(Visit, VisitMut),
+    visit(with = "visit_value")
+)]
 pub struct ValueWithSpan {
     /// The wrapped `Value`.
     pub value: Value,
@@ -111,14 +118,24 @@ impl From<ValueWithSpan> for Value {
     }
 }
 
+impl Deref for ValueWithSpan {
+    type Target = Value;
+
+    fn deref(&self) -> &Self::Target {
+        &self.value
+    }
+}
+
+impl DerefMut for ValueWithSpan {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.value
+    }
+}
+
 /// Primitive SQL values such as number and string
 #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[cfg_attr(
-    feature = "visitor",
-    derive(Visit, VisitMut),
-    visit(with = "visit_value")
-)]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
 pub enum Value {
     /// Numeric literal
     #[cfg(not(feature = "bigdecimal"))]
diff --git a/src/ast/visitor.rs b/src/ast/visitor.rs
index 5f9b3748..30673dfa 100644
--- a/src/ast/visitor.rs
+++ b/src/ast/visitor.rs
@@ -17,7 +17,7 @@
 
 //! Recursive visitors for ast Nodes. See [`Visitor`] for more details.
 
-use crate::ast::{Expr, ObjectName, Query, Select, Statement, TableFactor, 
Value};
+use crate::ast::{Expr, ObjectName, Query, Select, Statement, TableFactor, 
ValueWithSpan};
 use core::ops::ControlFlow;
 
 /// A type that can be visited by a [`Visitor`]. See [`Visitor`] for
@@ -258,12 +258,12 @@ pub trait Visitor {
     }
 
     /// Invoked for any Value that appear in the AST before visiting children
-    fn pre_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break> {
+    fn pre_visit_value(&mut self, _value: &ValueWithSpan) -> 
ControlFlow<Self::Break> {
         ControlFlow::Continue(())
     }
 
     /// Invoked for any Value that appear in the AST after visiting children
-    fn post_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break> 
{
+    fn post_visit_value(&mut self, _value: &ValueWithSpan) -> 
ControlFlow<Self::Break> {
         ControlFlow::Continue(())
     }
 }
@@ -386,12 +386,12 @@ pub trait VisitorMut {
     }
 
     /// Invoked for any value that appear in the AST before visiting children
-    fn pre_visit_value(&mut self, _value: &mut Value) -> 
ControlFlow<Self::Break> {
+    fn pre_visit_value(&mut self, _value: &mut ValueWithSpan) -> 
ControlFlow<Self::Break> {
         ControlFlow::Continue(())
     }
 
     /// Invoked for any statements that appear in the AST after visiting 
children
-    fn post_visit_value(&mut self, _value: &mut Value) -> 
ControlFlow<Self::Break> {
+    fn post_visit_value(&mut self, _value: &mut ValueWithSpan) -> 
ControlFlow<Self::Break> {
         ControlFlow::Continue(())
     }
 }
@@ -1015,7 +1015,7 @@ mod tests {
 
 #[cfg(test)]
 mod visit_mut_tests {
-    use crate::ast::{Statement, Value, VisitMut, VisitorMut};
+    use crate::ast::{Statement, Value, ValueWithSpan, VisitMut, VisitorMut};
     use crate::dialect::GenericDialect;
     use crate::parser::Parser;
     use crate::tokenizer::Tokenizer;
@@ -1029,13 +1029,13 @@ mod visit_mut_tests {
     impl VisitorMut for MutatorVisitor {
         type Break = ();
 
-        fn pre_visit_value(&mut self, value: &mut Value) -> 
ControlFlow<Self::Break> {
+        fn pre_visit_value(&mut self, value: &mut ValueWithSpan) -> 
ControlFlow<Self::Break> {
             self.index += 1;
-            *value = Value::SingleQuotedString(format!("REDACTED_{}", 
self.index));
+            value.value = Value::SingleQuotedString(format!("REDACTED_{}", 
self.index));
             ControlFlow::Continue(())
         }
 
-        fn post_visit_value(&mut self, _value: &mut Value) -> 
ControlFlow<Self::Break> {
+        fn post_visit_value(&mut self, _value: &mut ValueWithSpan) -> 
ControlFlow<Self::Break> {
             ControlFlow::Continue(())
         }
     }
diff --git a/src/dialect/snowflake.rs b/src/dialect/snowflake.rs
index 416e5051..1ac21d00 100644
--- a/src/dialect/snowflake.rs
+++ b/src/dialect/snowflake.rs
@@ -39,8 +39,8 @@ use crate::ast::{
 use crate::dialect::{Dialect, Precedence};
 use crate::keywords::Keyword;
 use crate::parser::{IsOptional, Parser, ParserError};
-use crate::tokenizer::Token;
 use crate::tokenizer::TokenWithSpan;
+use crate::tokenizer::{Span, Token};
 #[cfg(not(feature = "std"))]
 use alloc::boxed::Box;
 #[cfg(not(feature = "std"))]
@@ -1634,8 +1634,8 @@ fn parse_session_options(
     let mut options: Vec<KeyValueOption> = Vec::new();
     let empty = String::new;
     loop {
-        let next_token = parser.peek_token();
-        match next_token.token {
+        let peeked_token = parser.peek_token();
+        match peeked_token.token {
             Token::SemiColon | Token::EOF => break,
             Token::Comma => {
                 parser.advance_token();
@@ -1649,12 +1649,17 @@ fn parse_session_options(
                 } else {
                     options.push(KeyValueOption {
                         option_name: key.value,
-                        option_value: 
KeyValueOptionKind::Single(Value::Placeholder(empty())),
+                        option_value: KeyValueOptionKind::Single(
+                            Value::Placeholder(empty()).with_span(Span {
+                                start: peeked_token.span.end,
+                                end: peeked_token.span.end,
+                            }),
+                        ),
                     });
                 }
             }
             _ => {
-                return parser.expected("another option or end of statement", 
next_token);
+                return parser.expected("another option or end of statement", 
peeked_token);
             }
         }
     }
diff --git a/src/parser/alter.rs b/src/parser/alter.rs
index ce1220e1..4000eb26 100644
--- a/src/parser/alter.rs
+++ b/src/parser/alter.rs
@@ -219,7 +219,7 @@ impl Parser<'_> {
             if self.parse_keywords(&[Keyword::ADD, Keyword::MFA, 
Keyword::METHOD, Keyword::OTP]) {
                 let count = if self.parse_keyword(Keyword::COUNT) {
                     self.expect_token(&Token::Eq)?;
-                    Some(self.parse_value()?.into())
+                    Some(self.parse_value()?)
                 } else {
                     None
                 };
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 3a970f7a..6282ed3d 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -2689,7 +2689,7 @@ impl<'a> Parser<'a> {
     /// Parse an optional `FORMAT` clause for `CAST` expressions.
     pub fn parse_optional_cast_format(&mut self) -> Result<Option<CastFormat>, 
ParserError> {
         if self.parse_keyword(Keyword::FORMAT) {
-            let value = self.parse_value()?.value;
+            let value = self.parse_value()?;
             match self.parse_optional_time_zone()? {
                 Some(tz) => Ok(Some(CastFormat::ValueAtTimeZone(value, tz))),
                 None => Ok(Some(CastFormat::Value(value))),
@@ -2700,9 +2700,9 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse an optional `AT TIME ZONE` clause.
-    pub fn parse_optional_time_zone(&mut self) -> Result<Option<Value>, 
ParserError> {
+    pub fn parse_optional_time_zone(&mut self) -> 
Result<Option<ValueWithSpan>, ParserError> {
         if self.parse_keywords(&[Keyword::AT, Keyword::TIME, Keyword::ZONE]) {
-            self.parse_value().map(|v| Some(v.value))
+            self.parse_value().map(Some)
         } else {
             Ok(None)
         }
@@ -2834,13 +2834,13 @@ impl<'a> Parser<'a> {
             CeilFloorKind::DateTimeField(self.parse_date_time_field()?)
         } else if self.consume_token(&Token::Comma) {
             // Parse `CEIL/FLOOR(expr, scale)`
-            match self.parse_value()?.value {
-                Value::Number(n, s) => CeilFloorKind::Scale(Value::Number(n, 
s)),
-                _ => {
-                    return Err(ParserError::ParserError(
-                        "Scale field can only be of number type".to_string(),
-                    ))
-                }
+            let v = self.parse_value()?;
+            if matches!(v.value, Value::Number(_, _)) {
+                CeilFloorKind::Scale(v)
+            } else {
+                return Err(ParserError::ParserError(
+                    "Scale field can only be of number type".to_string(),
+                ));
             }
         } else {
             CeilFloorKind::DateTimeField(DateTimeField::NoDateTime)
@@ -3192,7 +3192,7 @@ impl<'a> Parser<'a> {
         self.expect_token(&Token::LParen)?;
 
         // MySQL is too permissive about the value, IMO we can't validate it 
perfectly on syntax level.
-        let match_value = self.parse_value()?.value;
+        let match_value = self.parse_value()?;
 
         let in_natural_language_mode_keywords = &[
             Keyword::IN,
@@ -4088,9 +4088,9 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse the `ESCAPE CHAR` portion of `LIKE`, `ILIKE`, and `SIMILAR TO`
-    pub fn parse_escape_char(&mut self) -> Result<Option<Value>, ParserError> {
+    pub fn parse_escape_char(&mut self) -> Result<Option<ValueWithSpan>, 
ParserError> {
         if self.parse_keyword(Keyword::ESCAPE) {
-            Ok(Some(self.parse_value()?.into()))
+            Ok(Some(self.parse_value()?))
         } else {
             Ok(None)
         }
@@ -7846,11 +7846,11 @@ impl<'a> Parser<'a> {
             FetchDirection::Last
         } else if self.parse_keyword(Keyword::ABSOLUTE) {
             FetchDirection::Absolute {
-                limit: self.parse_number_value()?.value,
+                limit: self.parse_number_value()?,
             }
         } else if self.parse_keyword(Keyword::RELATIVE) {
             FetchDirection::Relative {
-                limit: self.parse_number_value()?.value,
+                limit: self.parse_number_value()?,
             }
         } else if self.parse_keyword(Keyword::FORWARD) {
             if self.parse_keyword(Keyword::ALL) {
@@ -7858,7 +7858,7 @@ impl<'a> Parser<'a> {
             } else {
                 FetchDirection::Forward {
                     // TODO: Support optional
-                    limit: Some(self.parse_number_value()?.value),
+                    limit: Some(self.parse_number_value()?),
                 }
             }
         } else if self.parse_keyword(Keyword::BACKWARD) {
@@ -7867,14 +7867,14 @@ impl<'a> Parser<'a> {
             } else {
                 FetchDirection::Backward {
                     // TODO: Support optional
-                    limit: Some(self.parse_number_value()?.value),
+                    limit: Some(self.parse_number_value()?),
                 }
             }
         } else if self.parse_keyword(Keyword::ALL) {
             FetchDirection::All
         } else {
             FetchDirection::Count {
-                limit: self.parse_number_value()?.value,
+                limit: self.parse_number_value()?,
             }
         };
 
@@ -11392,7 +11392,7 @@ impl<'a> Parser<'a> {
             }
             Some(Keyword::MAXFILESIZE) => {
                 let _ = self.parse_keyword(Keyword::AS);
-                let size = self.parse_number_value()?.value;
+                let size = self.parse_number_value()?;
                 let unit = match self.parse_one_of_keywords(&[Keyword::MB, 
Keyword::GB]) {
                     Some(Keyword::MB) => Some(FileSizeUnit::MB),
                     Some(Keyword::GB) => Some(FileSizeUnit::GB),
@@ -11465,7 +11465,7 @@ impl<'a> Parser<'a> {
     }
 
     fn parse_file_size(&mut self) -> Result<FileSize, ParserError> {
-        let size = self.parse_number_value()?.value;
+        let size = self.parse_number_value()?;
         let unit = self.maybe_parse_file_size_unit();
         Ok(FileSize { size, unit })
     }
@@ -14847,7 +14847,7 @@ impl<'a> Parser<'a> {
             .into());
         } else if self.parse_keyword(Keyword::TRANSACTION) {
             if self.parse_keyword(Keyword::SNAPSHOT) {
-                let snapshot_id = self.parse_value()?.value;
+                let snapshot_id = self.parse_value()?;
                 return Ok(Set::SetTransaction {
                     modes: vec![],
                     snapshot: Some(snapshot_id),
@@ -15682,7 +15682,7 @@ impl<'a> Parser<'a> {
         } else if self.parse_keyword_with_tokens(Keyword::JSON_TABLE, 
&[Token::LParen]) {
             let json_expr = self.parse_expr()?;
             self.expect_token(&Token::Comma)?;
-            let json_path = self.parse_value()?.value;
+            let json_path = self.parse_value()?;
             self.expect_keyword_is(Keyword::COLUMNS)?;
             self.expect_token(&Token::LParen)?;
             let columns = 
self.parse_comma_separated(Parser::parse_json_table_column_def)?;
@@ -15866,9 +15866,9 @@ impl<'a> Parser<'a> {
         let parenthesized = self.consume_token(&Token::LParen);
 
         let (quantity, bucket) = if parenthesized && 
self.parse_keyword(Keyword::BUCKET) {
-            let selected_bucket = self.parse_number_value()?.value;
+            let selected_bucket = self.parse_number_value()?;
             self.expect_keywords(&[Keyword::OUT, Keyword::OF])?;
-            let total = self.parse_number_value()?.value;
+            let total = self.parse_number_value()?;
             let on = if self.parse_keyword(Keyword::ON) {
                 Some(self.parse_expr()?)
             } else {
@@ -15946,7 +15946,7 @@ impl<'a> Parser<'a> {
         modifier: TableSampleSeedModifier,
     ) -> Result<TableSampleSeed, ParserError> {
         self.expect_token(&Token::LParen)?;
-        let value = self.parse_number_value()?.value;
+        let value = self.parse_number_value()?;
         self.expect_token(&Token::RParen)?;
         Ok(TableSampleSeed { modifier, value })
     }
@@ -15957,7 +15957,7 @@ impl<'a> Parser<'a> {
         self.expect_token(&Token::LParen)?;
         let json_expr = self.parse_expr()?;
         let json_path = if self.consume_token(&Token::Comma) {
-            Some(self.parse_value()?.value)
+            Some(self.parse_value()?)
         } else {
             None
         };
@@ -16419,7 +16419,7 @@ impl<'a> Parser<'a> {
     pub fn parse_json_table_column_def(&mut self) -> Result<JsonTableColumn, 
ParserError> {
         if self.parse_keyword(Keyword::NESTED) {
             let _has_path_keyword = self.parse_keyword(Keyword::PATH);
-            let path = self.parse_value()?.value;
+            let path = self.parse_value()?;
             self.expect_keyword_is(Keyword::COLUMNS)?;
             let columns = self.parse_parenthesized(|p| {
                 p.parse_comma_separated(Self::parse_json_table_column_def)
@@ -16437,7 +16437,7 @@ impl<'a> Parser<'a> {
         let r#type = self.parse_data_type()?;
         let exists = self.parse_keyword(Keyword::EXISTS);
         self.expect_keyword_is(Keyword::PATH)?;
-        let path = self.parse_value()?.value;
+        let path = self.parse_value()?;
         let mut on_empty = None;
         let mut on_error = None;
         while let Some(error_handling) = 
self.parse_json_table_column_error_handling()? {
@@ -16494,7 +16494,7 @@ impl<'a> Parser<'a> {
         } else if self.parse_keyword(Keyword::ERROR) {
             JsonTableColumnErrorHandling::Error
         } else if self.parse_keyword(Keyword::DEFAULT) {
-            JsonTableColumnErrorHandling::Default(self.parse_value()?.value)
+            JsonTableColumnErrorHandling::Default(self.parse_value()?)
         } else {
             return Ok(None);
         };
@@ -17965,7 +17965,7 @@ impl<'a> Parser<'a> {
         if dialect_of!(self is GenericDialect | MySqlDialect)
             && self.parse_keyword(Keyword::SEPARATOR)
         {
-            
clauses.push(FunctionArgumentClause::Separator(self.parse_value()?.value));
+            
clauses.push(FunctionArgumentClause::Separator(self.parse_value()?));
         }
 
         if let Some(on_overflow) = self.parse_listagg_on_overflow()? {
@@ -19024,12 +19024,13 @@ impl<'a> Parser<'a> {
         })
     }
 
-    fn parse_pragma_value(&mut self) -> Result<Value, ParserError> {
-        match self.parse_value()?.value {
-            v @ Value::SingleQuotedString(_) => Ok(v),
-            v @ Value::DoubleQuotedString(_) => Ok(v),
-            v @ Value::Number(_, _) => Ok(v),
-            v @ Value::Placeholder(_) => Ok(v),
+    fn parse_pragma_value(&mut self) -> Result<ValueWithSpan, ParserError> {
+        let v = self.parse_value()?;
+        match &v.value {
+            Value::SingleQuotedString(_) => Ok(v),
+            Value::DoubleQuotedString(_) => Ok(v),
+            Value::Number(_, _) => Ok(v),
+            Value::Placeholder(_) => Ok(v),
             _ => {
                 self.prev_token();
                 self.expected_ref("number or string or ? placeholder", 
self.peek_token_ref())
@@ -19809,7 +19810,7 @@ impl<'a> Parser<'a> {
                     let threshold = if self.parse_keyword(Keyword::TO) {
                         let value = self.parse_value()?;
                         self.expect_keyword(Keyword::PERCENT)?;
-                        Some(value.value)
+                        Some(value)
                     } else {
                         None
                     };
@@ -19937,9 +19938,9 @@ impl<'a> Parser<'a> {
         }))
     }
 
-    fn maybe_parse_show_stmt_starts_with(&mut self) -> Result<Option<Value>, 
ParserError> {
+    fn maybe_parse_show_stmt_starts_with(&mut self) -> 
Result<Option<ValueWithSpan>, ParserError> {
         if self.parse_keywords(&[Keyword::STARTS, Keyword::WITH]) {
-            Ok(Some(self.parse_value()?.value))
+            Ok(Some(self.parse_value()?))
         } else {
             Ok(None)
         }
@@ -19953,9 +19954,9 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn maybe_parse_show_stmt_from(&mut self) -> Result<Option<Value>, 
ParserError> {
+    fn maybe_parse_show_stmt_from(&mut self) -> Result<Option<ValueWithSpan>, 
ParserError> {
         if self.parse_keyword(Keyword::FROM) {
-            Ok(Some(self.parse_value()?.value))
+            Ok(Some(self.parse_value()?))
         } else {
             Ok(None)
         }
@@ -20018,30 +20019,31 @@ impl<'a> Parser<'a> {
         key: &Word,
     ) -> Result<KeyValueOption, ParserError> {
         self.expect_token(&Token::Eq)?;
-        match self.peek_token().token {
+        let peeked_token = self.peek_token();
+        match peeked_token.token {
             Token::SingleQuotedString(_) => Ok(KeyValueOption {
                 option_name: key.value.clone(),
-                option_value: 
KeyValueOptionKind::Single(self.parse_value()?.into()),
+                option_value: KeyValueOptionKind::Single(self.parse_value()?),
             }),
             Token::Word(word)
                 if word.keyword == Keyword::TRUE || word.keyword == 
Keyword::FALSE =>
             {
                 Ok(KeyValueOption {
                     option_name: key.value.clone(),
-                    option_value: 
KeyValueOptionKind::Single(self.parse_value()?.into()),
+                    option_value: 
KeyValueOptionKind::Single(self.parse_value()?),
                 })
             }
             Token::Number(..) => Ok(KeyValueOption {
                 option_name: key.value.clone(),
-                option_value: 
KeyValueOptionKind::Single(self.parse_value()?.into()),
+                option_value: KeyValueOptionKind::Single(self.parse_value()?),
             }),
             Token::Word(word) => {
                 self.next_token();
                 Ok(KeyValueOption {
                     option_name: key.value.clone(),
-                    option_value: 
KeyValueOptionKind::Single(Value::Placeholder(
-                        word.value.clone(),
-                    )),
+                    option_value: KeyValueOptionKind::Single(
+                        
Value::Placeholder(word.value.clone()).with_span(peeked_token.span),
+                    ),
                 })
             }
             Token::LParen => {
@@ -20054,13 +20056,10 @@ impl<'a> Parser<'a> {
                     parser.expect_token(&Token::RParen)?;
                     values
                 })? {
-                    Some(values) => {
-                        let values = values.into_iter().map(|v| 
v.value).collect();
-                        Ok(KeyValueOption {
-                            option_name: key.value.clone(),
-                            option_value: KeyValueOptionKind::Multi(values),
-                        })
-                    }
+                    Some(values) => Ok(KeyValueOption {
+                        option_name: key.value.clone(),
+                        option_value: KeyValueOptionKind::Multi(values),
+                    }),
                     None => Ok(KeyValueOption {
                         option_name: key.value.clone(),
                         option_value: 
KeyValueOptionKind::KeyValueOptions(Box::new(
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index cff29bfe..17f368bb 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -2104,7 +2104,7 @@ fn parse_ilike() {
                 pattern: Box::new(Expr::Value(
                     
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
                 )),
-                escape_char: Some(Value::SingleQuotedString('^'.to_string())),
+                escape_char: 
Some(Value::SingleQuotedString('^'.to_string()).with_empty_span()),
                 any: false,
             },
             select.selection.unwrap()
@@ -2168,7 +2168,7 @@ fn parse_like() {
                 pattern: Box::new(Expr::Value(
                     
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
                 )),
-                escape_char: Some(Value::SingleQuotedString('^'.to_string())),
+                escape_char: 
Some(Value::SingleQuotedString('^'.to_string()).with_empty_span()),
                 any: false,
             },
             select.selection.unwrap()
@@ -2231,7 +2231,7 @@ fn parse_similar_to() {
                 pattern: Box::new(Expr::Value(
                     
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
                 )),
-                escape_char: Some(Value::SingleQuotedString('^'.to_string())),
+                escape_char: 
Some(Value::SingleQuotedString('^'.to_string()).with_empty_span()),
             },
             select.selection.unwrap()
         );
@@ -2248,7 +2248,7 @@ fn parse_similar_to() {
                 pattern: Box::new(Expr::Value(
                     
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
                 )),
-                escape_char: Some(Value::Null),
+                escape_char: Some(Value::Null.with_empty_span()),
             },
             select.selection.unwrap()
         );
@@ -2266,7 +2266,7 @@ fn parse_similar_to() {
                 pattern: Box::new(Expr::Value(
                     
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
                 )),
-                escape_char: Some(Value::SingleQuotedString('^'.to_string())),
+                escape_char: 
Some(Value::SingleQuotedString('^'.to_string()).with_empty_span()),
             })),
             select.selection.unwrap()
         );
@@ -3324,7 +3324,9 @@ fn parse_ceil_scale() {
     assert_eq!(
         &Expr::Ceil {
             expr: Box::new(Expr::Identifier(Ident::new("d"))),
-            field: 
CeilFloorKind::Scale(Value::Number(bigdecimal::BigDecimal::from(2), false)),
+            field: CeilFloorKind::Scale(
+                Value::Number(bigdecimal::BigDecimal::from(2), 
false).with_empty_span()
+            ),
         },
         expr_from_projection(only(&select.projection)),
     );
@@ -3333,7 +3335,7 @@ fn parse_ceil_scale() {
     assert_eq!(
         &Expr::Ceil {
             expr: Box::new(Expr::Identifier(Ident::new("d"))),
-            field: CeilFloorKind::Scale(Value::Number(2.to_string(), false)),
+            field: CeilFloorKind::Scale(Value::Number(2.to_string(), 
false).with_empty_span()),
         },
         expr_from_projection(only(&select.projection)),
     );
@@ -3348,7 +3350,9 @@ fn parse_floor_scale() {
     assert_eq!(
         &Expr::Floor {
             expr: Box::new(Expr::Identifier(Ident::new("d"))),
-            field: 
CeilFloorKind::Scale(Value::Number(bigdecimal::BigDecimal::from(2), false)),
+            field: CeilFloorKind::Scale(
+                Value::Number(bigdecimal::BigDecimal::from(2), 
false).with_empty_span()
+            ),
         },
         expr_from_projection(only(&select.projection)),
     );
@@ -3357,7 +3361,7 @@ fn parse_floor_scale() {
     assert_eq!(
         &Expr::Floor {
             expr: Box::new(Expr::Identifier(Ident::new("d"))),
-            field: CeilFloorKind::Scale(Value::Number(2.to_string(), false)),
+            field: CeilFloorKind::Scale(Value::Number(2.to_string(), 
false).with_empty_span()),
         },
         expr_from_projection(only(&select.projection)),
     );
@@ -17666,19 +17670,21 @@ fn parse_create_user() {
                     options: vec![
                         KeyValueOption {
                             option_name: "PASSWORD".to_string(),
-                            option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                                "secret".to_string()
-                            )),
+                            option_value: KeyValueOptionKind::Single(
+                                
Value::SingleQuotedString("secret".to_string()).with_empty_span()
+                            ),
                         },
                         KeyValueOption {
                             option_name: "MUST_CHANGE_PASSWORD".to_string(),
-                            option_value: 
KeyValueOptionKind::Single(Value::Boolean(false)),
+                            option_value: KeyValueOptionKind::Single(
+                                Value::Boolean(false).with_empty_span()
+                            ),
                         },
                         KeyValueOption {
                             option_name: "TYPE".to_string(),
-                            option_value: 
KeyValueOptionKind::Single(Value::Placeholder(
-                                "SERVICE".to_string()
-                            )),
+                            option_value: KeyValueOptionKind::Single(
+                                
Value::Placeholder("SERVICE".to_string()).with_empty_span()
+                            ),
                         },
                     ],
                 },
@@ -17691,15 +17697,15 @@ fn parse_create_user() {
                     options: vec![
                         KeyValueOption {
                             option_name: "t1".to_string(),
-                            option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                                "v1".to_string()
-                            )),
+                            option_value: KeyValueOptionKind::Single(
+                                
Value::SingleQuotedString("v1".to_string()).with_empty_span()
+                            ),
                         },
                         KeyValueOption {
                             option_name: "t2".to_string(),
-                            option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                                "v2".to_string()
-                            )),
+                            option_value: KeyValueOptionKind::Single(
+                                
Value::SingleQuotedString("v2".to_string()).with_empty_span()
+                            ),
                         },
                     ]
                 }
@@ -18325,9 +18331,9 @@ fn test_parse_alter_user() {
                 alter.set_tag.options,
                 vec![KeyValueOption {
                     option_name: "k1".to_string(),
-                    option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                        "v1".to_string()
-                    )),
+                    option_value: KeyValueOptionKind::Single(
+                        
Value::SingleQuotedString("v1".to_string()).with_empty_span()
+                    ),
                 },]
             );
         }
@@ -18361,17 +18367,21 @@ fn test_parse_alter_user() {
                     options: vec![
                         KeyValueOption {
                             option_name: "PASSWORD".to_string(),
-                            option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                                "secret".to_string()
-                            )),
+                            option_value: KeyValueOptionKind::Single(
+                                
Value::SingleQuotedString("secret".to_string()).with_empty_span()
+                            ),
                         },
                         KeyValueOption {
                             option_name: "MUST_CHANGE_PASSWORD".to_string(),
-                            option_value: 
KeyValueOptionKind::Single(Value::Boolean(true)),
+                            option_value: KeyValueOptionKind::Single(
+                                Value::Boolean(true).with_empty_span()
+                            ),
                         },
                         KeyValueOption {
                             option_name: "MINS_TO_UNLOCK".to_string(),
-                            option_value: 
KeyValueOptionKind::Single(number("10")),
+                            option_value: KeyValueOptionKind::Single(
+                                number("10").with_empty_span()
+                            ),
                         },
                     ]
                 }
@@ -18398,7 +18408,8 @@ fn test_parse_alter_user() {
                     option_name: "DEFAULT_SECONDARY_ROLES".to_string(),
                     option_value: 
KeyValueOptionKind::Multi(vec![Value::SingleQuotedString(
                         "ALL".to_string()
-                    )])
+                    )
+                    .with_empty_span()])
                 }]
             );
         }
@@ -18422,9 +18433,9 @@ fn test_parse_alter_user() {
                         options: vec![
                             KeyValueOption {
                                 option_name: "TYPE".to_string(),
-                                option_value: 
KeyValueOptionKind::Single(Value::Placeholder(
-                                    "AWS".to_string()
-                                )),
+                                option_value: KeyValueOptionKind::Single(
+                                    
Value::Placeholder("AWS".to_string()).with_empty_span()
+                                ),
                             },
                             KeyValueOption {
                                 option_name: "ARN".to_string(),
@@ -18432,6 +18443,7 @@ fn test_parse_alter_user() {
                                     Value::SingleQuotedString(
                                         
"arn:aws:iam::123456789:r1/".to_string()
                                     )
+                                    .with_empty_span()
                                 ),
                             },
                         ]
diff --git a/tests/sqlparser_mssql.rs b/tests/sqlparser_mssql.rs
index 733923f4..e8ed7949 100644
--- a/tests/sqlparser_mssql.rs
+++ b/tests/sqlparser_mssql.rs
@@ -496,7 +496,7 @@ fn parse_mssql_openjson() {
                     json_expr: Expr::CompoundIdentifier(
                         vec![Ident::new("A"), Ident::new("param"),]
                     ),
-                    json_path: 
Some(Value::SingleQuotedString("$.config".into())),
+                    json_path: 
Some(Value::SingleQuotedString("$.config".into()).with_empty_span()),
                     columns: vec![
                         OpenJsonTableColumn {
                             name: Ident::new("kind"),
@@ -658,7 +658,7 @@ fn parse_mssql_openjson() {
                     json_expr: Expr::CompoundIdentifier(
                         vec![Ident::new("A"), Ident::new("param"),]
                     ),
-                    json_path: 
Some(Value::SingleQuotedString("$.config".into())),
+                    json_path: 
Some(Value::SingleQuotedString("$.config".into()).with_empty_span()),
                     columns: vec![],
                     alias: table_alias(true, "B")
                 },
diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs
index 6c59997c..269787c2 100644
--- a/tests/sqlparser_mysql.rs
+++ b/tests/sqlparser_mysql.rs
@@ -3810,14 +3810,14 @@ fn parse_json_table() {
             .relation,
         TableFactor::JsonTable {
             json_expr: 
Expr::Value((Value::SingleQuotedString("[1,2]".to_string())).with_empty_span()),
-            json_path: Value::SingleQuotedString("$[*]".to_string()),
+            json_path: 
Value::SingleQuotedString("$[*]".to_string()).with_empty_span(),
             columns: vec![
                 JsonTableColumn::Named(JsonTableNamedColumn {
                     name: Ident::new("x"),
                     r#type: DataType::Int(None),
-                    path: Value::SingleQuotedString("$".to_string()),
+                    path: 
Value::SingleQuotedString("$".to_string()).with_empty_span(),
                     exists: false,
-                    on_empty: 
Some(JsonTableColumnErrorHandling::Default(Value::SingleQuotedString("0".to_string()))),
+                    on_empty: 
Some(JsonTableColumnErrorHandling::Default(Value::SingleQuotedString("0".to_string()).with_empty_span())),
                     on_error: Some(JsonTableColumnErrorHandling::Null),
                 }),
             ],
@@ -4233,7 +4233,10 @@ fn parse_match_against_with_alias() {
                             Ident::new("ReferenceID")
                         ])]
                     );
-                    assert_eq!(match_value, 
Value::SingleQuotedString("AAA".to_owned()));
+                    assert_eq!(
+                        match_value,
+                        
Value::SingleQuotedString("AAA".to_owned()).with_empty_span()
+                    );
                     assert_eq!(opt_search_modifier, 
Some(SearchModifier::InBooleanMode));
                 }
                 _ => unreachable!(),
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 9a4ff418..af0f2be3 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -3287,7 +3287,7 @@ fn test_transaction_statement() {
         statement,
         Statement::Set(Set::SetTransaction {
             modes: vec![],
-            snapshot: 
Some(Value::SingleQuotedString(String::from("000003A1-1"))),
+            snapshot: 
Some(Value::SingleQuotedString(String::from("000003A1-1")).with_empty_span()),
             session: false
         })
     );
diff --git a/tests/sqlparser_redshift.rs b/tests/sqlparser_redshift.rs
index 319a818c..e68368fd 100644
--- a/tests/sqlparser_redshift.rs
+++ b/tests/sqlparser_redshift.rs
@@ -446,7 +446,7 @@ fn parse_vacuum() {
                     Ident::new("tbl1"),
                 ]))
             );
-            assert_eq!(v.threshold, Some(number("20")));
+            assert_eq!(v.threshold, Some(number("20").with_empty_span()));
             assert!(v.boost);
         }
         _ => unreachable!(),
diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs
index 666876fa..790bf151 100644
--- a/tests/sqlparser_snowflake.rs
+++ b/tests/sqlparser_snowflake.rs
@@ -2043,27 +2043,27 @@ fn test_create_stage_with_stage_params() {
             );
             assert!(stage_params.credentials.options.contains(&KeyValueOption {
                 option_name: "AWS_KEY_ID".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    "1a2b3c".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString("1a2b3c".to_string()).with_empty_span()
+                ),
             }));
             assert!(stage_params.credentials.options.contains(&KeyValueOption {
                 option_name: "AWS_SECRET_KEY".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    "4x5y6z".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString("4x5y6z".to_string()).with_empty_span()
+                ),
             }));
             assert!(stage_params.encryption.options.contains(&KeyValueOption {
                 option_name: "MASTER_KEY".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    "key".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString("key".to_string()).with_empty_span()
+                ),
             }));
             assert!(stage_params.encryption.options.contains(&KeyValueOption {
                 option_name: "TYPE".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    "AWS_SSE_KMS".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString("AWS_SSE_KMS".to_string()).with_empty_span()
+                ),
             }));
         }
         _ => unreachable!(),
@@ -2087,17 +2087,17 @@ fn test_create_stage_with_directory_table_params() {
         } => {
             assert!(directory_table_params.options.contains(&KeyValueOption {
                 option_name: "ENABLE".to_string(),
-                option_value: KeyValueOptionKind::Single(Value::Boolean(true)),
+                option_value: 
KeyValueOptionKind::Single(Value::Boolean(true).with_empty_span()),
             }));
             assert!(directory_table_params.options.contains(&KeyValueOption {
                 option_name: "REFRESH_ON_CREATE".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::Boolean(false)),
+                option_value: 
KeyValueOptionKind::Single(Value::Boolean(false).with_empty_span()),
             }));
             assert!(directory_table_params.options.contains(&KeyValueOption {
                 option_name: "NOTIFICATION_INTEGRATION".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    "some-string".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString("some-string".to_string()).with_empty_span()
+                ),
             }));
         }
         _ => unreachable!(),
@@ -2117,17 +2117,21 @@ fn test_create_stage_with_file_format() {
         Statement::CreateStage { file_format, .. } => {
             assert!(file_format.options.contains(&KeyValueOption {
                 option_name: "COMPRESSION".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::Placeholder("AUTO".to_string())),
+                option_value: KeyValueOptionKind::Single(
+                    Value::Placeholder("AUTO".to_string()).with_empty_span()
+                ),
             }));
             assert!(file_format.options.contains(&KeyValueOption {
                 option_name: "BINARY_FORMAT".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::Placeholder("HEX".to_string())),
+                option_value: KeyValueOptionKind::Single(
+                    Value::Placeholder("HEX".to_string()).with_empty_span()
+                ),
             }));
             assert!(file_format.options.contains(&KeyValueOption {
                 option_name: "ESCAPE".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    r#"\\"#.to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString(r#"\\"#.to_string()).with_empty_span()
+                ),
             }));
         }
         _ => unreachable!(),
@@ -2149,13 +2153,13 @@ fn test_create_stage_with_copy_options() {
         Statement::CreateStage { copy_options, .. } => {
             assert!(copy_options.options.contains(&KeyValueOption {
                 option_name: "ON_ERROR".to_string(),
-                option_value: KeyValueOptionKind::Single(Value::Placeholder(
-                    "CONTINUE".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::Placeholder("CONTINUE".to_string()).with_empty_span()
+                ),
             }));
             assert!(copy_options.options.contains(&KeyValueOption {
                 option_name: "FORCE".to_string(),
-                option_value: KeyValueOptionKind::Single(Value::Boolean(true)),
+                option_value: 
KeyValueOptionKind::Single(Value::Boolean(true).with_empty_span()),
             }));
         }
         _ => unreachable!(),
@@ -2286,27 +2290,27 @@ fn test_copy_into_with_stage_params() {
             );
             assert!(stage_params.credentials.options.contains(&KeyValueOption {
                 option_name: "AWS_KEY_ID".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    "1a2b3c".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString("1a2b3c".to_string()).with_empty_span()
+                ),
             }));
             assert!(stage_params.credentials.options.contains(&KeyValueOption {
                 option_name: "AWS_SECRET_KEY".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    "4x5y6z".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString("4x5y6z".to_string()).with_empty_span()
+                ),
             }));
             assert!(stage_params.encryption.options.contains(&KeyValueOption {
                 option_name: "MASTER_KEY".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    "key".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString("key".to_string()).with_empty_span()
+                ),
             }));
             assert!(stage_params.encryption.options.contains(&KeyValueOption {
                 option_name: "TYPE".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    "AWS_SSE_KMS".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString("AWS_SSE_KMS".to_string()).with_empty_span()
+                ),
             }));
         }
         _ => unreachable!(),
@@ -2457,17 +2461,21 @@ fn test_copy_into_file_format() {
         Statement::CopyIntoSnowflake { file_format, .. } => {
             assert!(file_format.options.contains(&KeyValueOption {
                 option_name: "COMPRESSION".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::Placeholder("AUTO".to_string())),
+                option_value: KeyValueOptionKind::Single(
+                    Value::Placeholder("AUTO".to_string()).with_empty_span()
+                ),
             }));
             assert!(file_format.options.contains(&KeyValueOption {
                 option_name: "BINARY_FORMAT".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::Placeholder("HEX".to_string())),
+                option_value: KeyValueOptionKind::Single(
+                    Value::Placeholder("HEX".to_string()).with_empty_span()
+                ),
             }));
             assert!(file_format.options.contains(&KeyValueOption {
                 option_name: "ESCAPE".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    r#"\\"#.to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString(r#"\\"#.to_string()).with_empty_span()
+                ),
             }));
         }
         _ => unreachable!(),
@@ -2495,17 +2503,21 @@ fn test_copy_into_file_format() {
         Statement::CopyIntoSnowflake { file_format, .. } => {
             assert!(file_format.options.contains(&KeyValueOption {
                 option_name: "COMPRESSION".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::Placeholder("AUTO".to_string())),
+                option_value: KeyValueOptionKind::Single(
+                    Value::Placeholder("AUTO".to_string()).with_empty_span()
+                ),
             }));
             assert!(file_format.options.contains(&KeyValueOption {
                 option_name: "BINARY_FORMAT".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::Placeholder("HEX".to_string())),
+                option_value: KeyValueOptionKind::Single(
+                    Value::Placeholder("HEX".to_string()).with_empty_span()
+                ),
             }));
             assert!(file_format.options.contains(&KeyValueOption {
                 option_name: "ESCAPE".to_string(),
-                option_value: 
KeyValueOptionKind::Single(Value::SingleQuotedString(
-                    r#"\\"#.to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::SingleQuotedString(r#"\\"#.to_string()).with_empty_span()
+                ),
             }));
         }
         _ => unreachable!(),
@@ -2526,13 +2538,13 @@ fn test_copy_into_copy_options() {
         Statement::CopyIntoSnowflake { copy_options, .. } => {
             assert!(copy_options.options.contains(&KeyValueOption {
                 option_name: "ON_ERROR".to_string(),
-                option_value: KeyValueOptionKind::Single(Value::Placeholder(
-                    "CONTINUE".to_string()
-                )),
+                option_value: KeyValueOptionKind::Single(
+                    
Value::Placeholder("CONTINUE".to_string()).with_empty_span()
+                ),
             }));
             assert!(copy_options.options.contains(&KeyValueOption {
                 option_name: "FORCE".to_string(),
-                option_value: KeyValueOptionKind::Single(Value::Boolean(true)),
+                option_value: 
KeyValueOptionKind::Single(Value::Boolean(true).with_empty_span()),
             }));
         }
         _ => unreachable!(),


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to