This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 6f8e7b85 Expose values through ValueWithSpan (#2281)
6f8e7b85 is described below
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]