Store spans for Value expressions (#1738)

This commit is contained in:
Ophir LOJKINE 2025-02-25 07:33:57 +01:00 committed by GitHub
parent aab12add36
commit c335c8883b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 1620 additions and 1042 deletions

View file

@ -86,7 +86,7 @@ pub use self::trigger::{
pub use self::value::{
escape_double_quote_string, escape_quoted_string, DateTimeField, DollarQuotedString,
NormalizationForm, TrimWhereField, Value,
NormalizationForm, TrimWhereField, Value, ValueWithSpan,
};
use crate::ast::helpers::key_value_options::KeyValueOptions;
@ -908,7 +908,7 @@ pub enum Expr {
/// Nested expression e.g. `(foo > bar)` or `(1)`
Nested(Box<Expr>),
/// A literal value, such as string, number, date or NULL
Value(Value),
Value(ValueWithSpan),
/// <https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html>
IntroducedString {
introducer: String,
@ -1051,6 +1051,13 @@ pub enum Expr {
Lambda(LambdaFunction),
}
impl Expr {
/// Creates a new [`Expr::Value`]
pub fn value(value: impl Into<ValueWithSpan>) -> Self {
Expr::Value(value.into())
}
}
/// The contents inside the `[` and `]` in a subscript expression.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -8789,9 +8796,9 @@ mod tests {
#[test]
fn test_interval_display() {
let interval = Expr::Interval(Interval {
value: Box::new(Expr::Value(Value::SingleQuotedString(String::from(
"123:45.67",
)))),
value: Box::new(Expr::Value(
Value::SingleQuotedString(String::from("123:45.67")).with_empty_span(),
)),
leading_field: Some(DateTimeField::Minute),
leading_precision: Some(10),
last_field: Some(DateTimeField::Second),
@ -8803,7 +8810,9 @@ mod tests {
);
let interval = Expr::Interval(Interval {
value: Box::new(Expr::Value(Value::SingleQuotedString(String::from("5")))),
value: Box::new(Expr::Value(
Value::SingleQuotedString(String::from("5")).with_empty_span(),
)),
leading_field: Some(DateTimeField::Second),
leading_precision: Some(1),
last_field: None,

View file

@ -21,21 +21,21 @@ use core::iter;
use crate::tokenizer::Span;
use super::{
dcl::SecondaryRoles, AccessExpr, AlterColumnOperation, AlterIndexOperation,
AlterTableOperation, Array, Assignment, AssignmentTarget, CloseCursor, ClusteredIndex,
ColumnDef, ColumnOption, ColumnOptionDef, ConflictTarget, ConnectBy, ConstraintCharacteristics,
CopySource, CreateIndex, CreateTable, CreateTableOptions, Cte, Delete, DoUpdate,
ExceptSelectItem, ExcludeSelectItem, Expr, ExprWithAlias, Fetch, FromTable, Function,
FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList, FunctionArguments,
GroupByExpr, HavingBound, IlikeSelectItem, Insert, Interpolate, InterpolateExpr, Join,
JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, MatchRecognizePattern,
Measure, NamedWindowDefinition, ObjectName, ObjectNamePart, Offset, OnConflict,
OnConflictAction, OnInsert, OrderBy, OrderByExpr, OrderByKind, Partition, PivotValueSource,
ProjectionSelect, Query, ReferentialAction, RenameSelectItem, ReplaceSelectElement,
ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SqlOption, Statement, Subscript,
SymbolDefinition, TableAlias, TableAliasColumnDef, TableConstraint, TableFactor, TableObject,
TableOptionsClustered, TableWithJoins, UpdateTableFromKind, Use, Value, Values, ViewColumnDef,
WildcardAdditionalOptions, With, WithFill,
dcl::SecondaryRoles, value::ValueWithSpan, AccessExpr, AlterColumnOperation,
AlterIndexOperation, AlterTableOperation, Array, Assignment, AssignmentTarget, CloseCursor,
ClusteredIndex, ColumnDef, ColumnOption, ColumnOptionDef, ConflictTarget, ConnectBy,
ConstraintCharacteristics, CopySource, CreateIndex, CreateTable, CreateTableOptions, Cte,
Delete, DoUpdate, ExceptSelectItem, ExcludeSelectItem, Expr, ExprWithAlias, Fetch, FromTable,
Function, FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList,
FunctionArguments, GroupByExpr, HavingBound, IlikeSelectItem, Insert, Interpolate,
InterpolateExpr, Join, JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView,
MatchRecognizePattern, Measure, NamedWindowDefinition, ObjectName, ObjectNamePart, Offset,
OnConflict, OnConflictAction, OnInsert, OrderBy, OrderByExpr, OrderByKind, Partition,
PivotValueSource, ProjectionSelect, Query, ReferentialAction, RenameSelectItem,
ReplaceSelectElement, ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SqlOption,
Statement, Subscript, SymbolDefinition, TableAlias, TableAliasColumnDef, TableConstraint,
TableFactor, TableObject, TableOptionsClustered, TableWithJoins, UpdateTableFromKind, Use,
Value, Values, ViewColumnDef, WildcardAdditionalOptions, With, WithFill,
};
/// Given an iterator of spans, return the [Span::union] of all spans.
@ -1978,10 +1978,13 @@ impl Spanned for TableAliasColumnDef {
}
}
/// # missing span
///
/// The span of a `Value` is currently not implemented, as doing so
/// requires a breaking changes, which may be done in a future release.
impl Spanned for ValueWithSpan {
fn span(&self) -> Span {
self.span
}
}
/// 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

View file

@ -26,10 +26,88 @@ use bigdecimal::BigDecimal;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::ast::Ident;
use crate::{ast::Ident, tokenizer::Span};
#[cfg(feature = "visitor")]
use sqlparser_derive::{Visit, VisitMut};
/// Wraps a primitive SQL [`Value`] with its [`Span`] location
///
/// # Example: create a `ValueWithSpan` from a `Value`
/// ```
/// # use sqlparser::ast::{Value, ValueWithSpan};
/// # use sqlparser::tokenizer::{Location, Span};
/// let value = Value::SingleQuotedString(String::from("endpoint"));
/// // from line 1, column 1 to line 1, column 7
/// let span = Span::new(Location::new(1, 1), Location::new(1, 7));
/// let value_with_span = value.with_span(span);
/// ```
///
/// # Example: create a `ValueWithSpan` from a `Value` with an empty span
///
/// You can call [`Value::with_empty_span`] to create a `ValueWithSpan` with an empty span
/// ```
/// # use sqlparser::ast::{Value, ValueWithSpan};
/// # use sqlparser::tokenizer::{Location, Span};
/// let value = Value::SingleQuotedString(String::from("endpoint"));
/// let value_with_span = value.with_empty_span();
/// assert_eq!(value_with_span.span, Span::empty());
/// ```
///
/// You can also use the [`From`] trait to convert `ValueWithSpan` to/from `Value`s
/// ```
/// # use sqlparser::ast::{Value, ValueWithSpan};
/// # use sqlparser::tokenizer::{Location, Span};
/// let value = Value::SingleQuotedString(String::from("endpoint"));
/// // converting `Value` to `ValueWithSpan` results in an empty span
/// let value_with_span: ValueWithSpan = value.into();
/// assert_eq!(value_with_span.span, Span::empty());
/// // convert back to `Value`
/// let value: Value = value_with_span.into();
/// ```
#[derive(Debug, Clone, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ValueWithSpan {
pub value: Value,
pub span: Span,
}
impl PartialEq for ValueWithSpan {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl Ord for ValueWithSpan {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.value.cmp(&other.value)
}
}
impl PartialOrd for ValueWithSpan {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(Ord::cmp(self, other))
}
}
impl core::hash::Hash for ValueWithSpan {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.value.hash(state);
}
}
impl From<Value> for ValueWithSpan {
fn from(value: Value) -> Self {
value.with_empty_span()
}
}
impl From<ValueWithSpan> for Value {
fn from(value: ValueWithSpan) -> Self {
value.value
}
}
/// Primitive SQL values such as number and string
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -102,6 +180,13 @@ pub enum Value {
Placeholder(String),
}
impl ValueWithSpan {
/// If the underlying literal is a string, regardless of quote style, returns the associated string value
pub fn into_string(self) -> Option<String> {
self.value.into_string()
}
}
impl Value {
/// If the underlying literal is a string, regardless of quote style, returns the associated string value
pub fn into_string(self) -> Option<String> {
@ -126,6 +211,20 @@ impl Value {
_ => None,
}
}
pub fn with_span(self, span: Span) -> ValueWithSpan {
ValueWithSpan { value: self, span }
}
pub fn with_empty_span(self) -> ValueWithSpan {
self.with_span(Span::empty())
}
}
impl fmt::Display for ValueWithSpan {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}
}
impl fmt::Display for Value {

View file

@ -547,7 +547,7 @@ where
///
/// visit_expressions_mut(&mut statements, |expr| {
/// if matches!(expr, Expr::Identifier(col_name) if col_name.value == "x") {
/// let old_expr = std::mem::replace(expr, Expr::Value(Value::Null));
/// let old_expr = std::mem::replace(expr, Expr::value(Value::Null));
/// *expr = Expr::Function(Function {
/// name: ObjectName::from(vec![Ident::new("f")]),
/// uses_odbc_syntax: false,

View file

@ -1315,7 +1315,7 @@ impl<'a> Parser<'a> {
DataType::Custom(..) => parser_err!("dummy", loc),
data_type => Ok(Expr::TypedString {
data_type,
value: parser.parse_value()?,
value: parser.parse_value()?.value,
}),
}
})?;
@ -1503,7 +1503,7 @@ impl<'a> Parser<'a> {
}
fn parse_geometric_type(&mut self, kind: GeometricTypeKind) -> Result<Expr, ParserError> {
let value: Value = self.parse_value()?;
let value: Value = self.parse_value()?.value;
Ok(Expr::TypedString {
data_type: DataType::GeometricType(kind),
value,
@ -2089,7 +2089,7 @@ impl<'a> Parser<'a> {
pub fn parse_optional_cast_format(&mut self) -> Result<Option<CastFormat>, ParserError> {
if self.parse_keyword(Keyword::FORMAT) {
let value = self.parse_value()?;
let value = self.parse_value()?.value;
match self.parse_optional_time_zone()? {
Some(tz) => Ok(Some(CastFormat::ValueAtTimeZone(value, tz))),
None => Ok(Some(CastFormat::Value(value))),
@ -2101,7 +2101,7 @@ impl<'a> Parser<'a> {
pub fn parse_optional_time_zone(&mut self) -> Result<Option<Value>, ParserError> {
if self.parse_keywords(&[Keyword::AT, Keyword::TIME, Keyword::ZONE]) {
self.parse_value().map(Some)
self.parse_value().map(|v| Some(v.value))
} else {
Ok(None)
}
@ -2230,7 +2230,7 @@ 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()? {
match self.parse_value()?.value {
Value::Number(n, s) => CeilFloorKind::Scale(Value::Number(n, s)),
_ => {
return Err(ParserError::ParserError(
@ -2566,7 +2566,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()?;
let match_value = self.parse_value()?.value;
let in_natural_language_mode_keywords = &[
Keyword::IN,
@ -6324,11 +6324,11 @@ impl<'a> Parser<'a> {
FetchDirection::Last
} else if self.parse_keyword(Keyword::ABSOLUTE) {
FetchDirection::Absolute {
limit: self.parse_number_value()?,
limit: self.parse_number_value()?.value,
}
} else if self.parse_keyword(Keyword::RELATIVE) {
FetchDirection::Relative {
limit: self.parse_number_value()?,
limit: self.parse_number_value()?.value,
}
} else if self.parse_keyword(Keyword::FORWARD) {
if self.parse_keyword(Keyword::ALL) {
@ -6336,7 +6336,7 @@ impl<'a> Parser<'a> {
} else {
FetchDirection::Forward {
// TODO: Support optional
limit: Some(self.parse_number_value()?),
limit: Some(self.parse_number_value()?.value),
}
}
} else if self.parse_keyword(Keyword::BACKWARD) {
@ -6345,14 +6345,14 @@ impl<'a> Parser<'a> {
} else {
FetchDirection::Backward {
// TODO: Support optional
limit: Some(self.parse_number_value()?),
limit: Some(self.parse_number_value()?.value),
}
}
} else if self.parse_keyword(Keyword::ALL) {
FetchDirection::All
} else {
FetchDirection::Count {
limit: self.parse_number_value()?,
limit: self.parse_number_value()?.value,
}
};
@ -7345,7 +7345,7 @@ impl<'a> Parser<'a> {
};
self.expect_keyword_is(Keyword::INTO)?;
let num_buckets = self.parse_number_value()?;
let num_buckets = self.parse_number_value()?.value;
self.expect_keyword_is(Keyword::BUCKETS)?;
Some(ClusteredBy {
columns,
@ -8579,21 +8579,22 @@ impl<'a> Parser<'a> {
}
/// Parse a literal value (numbers, strings, date/time, booleans)
pub fn parse_value(&mut self) -> Result<Value, ParserError> {
pub fn parse_value(&mut self) -> Result<ValueWithSpan, ParserError> {
let next_token = self.next_token();
let span = next_token.span;
let ok_value = |value: Value| Ok(value.with_span(span));
match next_token.token {
Token::Word(w) => match w.keyword {
Keyword::TRUE if self.dialect.supports_boolean_literals() => {
Ok(Value::Boolean(true))
ok_value(Value::Boolean(true))
}
Keyword::FALSE if self.dialect.supports_boolean_literals() => {
Ok(Value::Boolean(false))
ok_value(Value::Boolean(false))
}
Keyword::NULL => Ok(Value::Null),
Keyword::NULL => ok_value(Value::Null),
Keyword::NoKeyword if w.quote_style.is_some() => match w.quote_style {
Some('"') => Ok(Value::DoubleQuotedString(w.value)),
Some('\'') => Ok(Value::SingleQuotedString(w.value)),
Some('"') => ok_value(Value::DoubleQuotedString(w.value)),
Some('\'') => ok_value(Value::SingleQuotedString(w.value)),
_ => self.expected(
"A value?",
TokenWithSpan {
@ -8613,45 +8614,51 @@ impl<'a> Parser<'a> {
// The call to n.parse() returns a bigdecimal when the
// bigdecimal feature is enabled, and is otherwise a no-op
// (i.e., it returns the input string).
Token::Number(n, l) => Ok(Value::Number(Self::parse(n, span.start)?, l)),
Token::SingleQuotedString(ref s) => Ok(Value::SingleQuotedString(s.to_string())),
Token::DoubleQuotedString(ref s) => Ok(Value::DoubleQuotedString(s.to_string())),
Token::Number(n, l) => ok_value(Value::Number(Self::parse(n, span.start)?, l)),
Token::SingleQuotedString(ref s) => ok_value(Value::SingleQuotedString(s.to_string())),
Token::DoubleQuotedString(ref s) => ok_value(Value::DoubleQuotedString(s.to_string())),
Token::TripleSingleQuotedString(ref s) => {
Ok(Value::TripleSingleQuotedString(s.to_string()))
ok_value(Value::TripleSingleQuotedString(s.to_string()))
}
Token::TripleDoubleQuotedString(ref s) => {
Ok(Value::TripleDoubleQuotedString(s.to_string()))
ok_value(Value::TripleDoubleQuotedString(s.to_string()))
}
Token::DollarQuotedString(ref s) => Ok(Value::DollarQuotedString(s.clone())),
Token::DollarQuotedString(ref s) => ok_value(Value::DollarQuotedString(s.clone())),
Token::SingleQuotedByteStringLiteral(ref s) => {
Ok(Value::SingleQuotedByteStringLiteral(s.clone()))
ok_value(Value::SingleQuotedByteStringLiteral(s.clone()))
}
Token::DoubleQuotedByteStringLiteral(ref s) => {
Ok(Value::DoubleQuotedByteStringLiteral(s.clone()))
ok_value(Value::DoubleQuotedByteStringLiteral(s.clone()))
}
Token::TripleSingleQuotedByteStringLiteral(ref s) => {
Ok(Value::TripleSingleQuotedByteStringLiteral(s.clone()))
ok_value(Value::TripleSingleQuotedByteStringLiteral(s.clone()))
}
Token::TripleDoubleQuotedByteStringLiteral(ref s) => {
Ok(Value::TripleDoubleQuotedByteStringLiteral(s.clone()))
ok_value(Value::TripleDoubleQuotedByteStringLiteral(s.clone()))
}
Token::SingleQuotedRawStringLiteral(ref s) => {
Ok(Value::SingleQuotedRawStringLiteral(s.clone()))
ok_value(Value::SingleQuotedRawStringLiteral(s.clone()))
}
Token::DoubleQuotedRawStringLiteral(ref s) => {
Ok(Value::DoubleQuotedRawStringLiteral(s.clone()))
ok_value(Value::DoubleQuotedRawStringLiteral(s.clone()))
}
Token::TripleSingleQuotedRawStringLiteral(ref s) => {
Ok(Value::TripleSingleQuotedRawStringLiteral(s.clone()))
ok_value(Value::TripleSingleQuotedRawStringLiteral(s.clone()))
}
Token::TripleDoubleQuotedRawStringLiteral(ref s) => {
Ok(Value::TripleDoubleQuotedRawStringLiteral(s.clone()))
ok_value(Value::TripleDoubleQuotedRawStringLiteral(s.clone()))
}
Token::NationalStringLiteral(ref s) => Ok(Value::NationalStringLiteral(s.to_string())),
Token::EscapedStringLiteral(ref s) => Ok(Value::EscapedStringLiteral(s.to_string())),
Token::UnicodeStringLiteral(ref s) => Ok(Value::UnicodeStringLiteral(s.to_string())),
Token::HexStringLiteral(ref s) => Ok(Value::HexStringLiteral(s.to_string())),
Token::Placeholder(ref s) => Ok(Value::Placeholder(s.to_string())),
Token::NationalStringLiteral(ref s) => {
ok_value(Value::NationalStringLiteral(s.to_string()))
}
Token::EscapedStringLiteral(ref s) => {
ok_value(Value::EscapedStringLiteral(s.to_string()))
}
Token::UnicodeStringLiteral(ref s) => {
ok_value(Value::UnicodeStringLiteral(s.to_string()))
}
Token::HexStringLiteral(ref s) => ok_value(Value::HexStringLiteral(s.to_string())),
Token::Placeholder(ref s) => ok_value(Value::Placeholder(s.to_string())),
tok @ Token::Colon | tok @ Token::AtSign => {
// Not calling self.parse_identifier(false)? because only in placeholder we want to check numbers as idfentifies
// This because snowflake allows numbers as placeholders
@ -8662,7 +8669,7 @@ impl<'a> Parser<'a> {
_ => self.expected("placeholder", next_token),
}?;
let placeholder = tok.to_string() + &ident.value;
Ok(Value::Placeholder(placeholder))
ok_value(Value::Placeholder(placeholder))
}
unexpected => self.expected(
"a value",
@ -8675,10 +8682,11 @@ impl<'a> Parser<'a> {
}
/// Parse an unsigned numeric literal
pub fn parse_number_value(&mut self) -> Result<Value, ParserError> {
match self.parse_value()? {
v @ Value::Number(_, _) => Ok(v),
v @ Value::Placeholder(_) => Ok(v),
pub fn parse_number_value(&mut self) -> Result<ValueWithSpan, ParserError> {
let value_wrapper = self.parse_value()?;
match &value_wrapper.value {
Value::Number(_, _) => Ok(value_wrapper),
Value::Placeholder(_) => Ok(value_wrapper),
_ => {
self.prev_token();
self.expected("literal number", self.peek_token())
@ -8736,15 +8744,16 @@ impl<'a> Parser<'a> {
/// e.g. `CREATE FUNCTION ... AS $$ body $$`.
fn parse_create_function_body_string(&mut self) -> Result<Expr, ParserError> {
let peek_token = self.peek_token();
let span = peek_token.span;
match peek_token.token {
Token::DollarQuotedString(s) if dialect_of!(self is PostgreSqlDialect | GenericDialect) =>
{
self.next_token();
Ok(Expr::Value(Value::DollarQuotedString(s)))
Ok(Expr::Value(Value::DollarQuotedString(s).with_span(span)))
}
_ => Ok(Expr::Value(Value::SingleQuotedString(
self.parse_literal_string()?,
))),
_ => Ok(Expr::Value(
Value::SingleQuotedString(self.parse_literal_string()?).with_span(span),
)),
}
}
@ -10268,7 +10277,7 @@ impl<'a> Parser<'a> {
let key_values = self.parse_comma_separated(|p| {
let key = p.parse_identifier()?;
p.expect_token(&Token::Eq)?;
let value = p.parse_value()?;
let value = p.parse_value()?.value;
Ok(Setting { key, value })
})?;
Some(key_values)
@ -10990,7 +10999,7 @@ impl<'a> Parser<'a> {
})
} else if variable.to_string() == "TRANSACTION" && modifier.is_none() {
if self.parse_keyword(Keyword::SNAPSHOT) {
let snapshot_id = self.parse_value()?;
let snapshot_id = self.parse_value()?.value;
return Ok(Statement::SetTransaction {
modes: vec![],
snapshot: Some(snapshot_id),
@ -11655,7 +11664,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()?;
let json_path = self.parse_value()?.value;
self.expect_keyword_is(Keyword::COLUMNS)?;
self.expect_token(&Token::LParen)?;
let columns = self.parse_comma_separated(Parser::parse_json_table_column_def)?;
@ -11790,9 +11799,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()?;
let selected_bucket = self.parse_number_value()?.value;
self.expect_keywords(&[Keyword::OUT, Keyword::OF])?;
let total = self.parse_number_value()?;
let total = self.parse_number_value()?.value;
let on = if self.parse_keyword(Keyword::ON) {
Some(self.parse_expr()?)
} else {
@ -11810,8 +11819,9 @@ impl<'a> Parser<'a> {
let value = match self.maybe_parse(|p| p.parse_expr())? {
Some(num) => num,
None => {
if let Token::Word(w) = self.next_token().token {
Expr::Value(Value::Placeholder(w.value))
let next_token = self.next_token();
if let Token::Word(w) = next_token.token {
Expr::Value(Value::Placeholder(w.value).with_span(next_token.span))
} else {
return parser_err!(
"Expecting number or byte length e.g. 100M",
@ -11869,7 +11879,7 @@ impl<'a> Parser<'a> {
modifier: TableSampleSeedModifier,
) -> Result<TableSampleSeed, ParserError> {
self.expect_token(&Token::LParen)?;
let value = self.parse_number_value()?;
let value = self.parse_number_value()?.value;
self.expect_token(&Token::RParen)?;
Ok(TableSampleSeed { modifier, value })
}
@ -11880,7 +11890,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()?)
Some(self.parse_value()?.value)
} else {
None
};
@ -12149,7 +12159,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()?;
let path = self.parse_value()?.value;
self.expect_keyword_is(Keyword::COLUMNS)?;
let columns = self.parse_parenthesized(|p| {
p.parse_comma_separated(Self::parse_json_table_column_def)
@ -12167,7 +12177,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()?;
let path = self.parse_value()?.value;
let mut on_empty = None;
let mut on_error = None;
while let Some(error_handling) = self.parse_json_table_column_error_handling()? {
@ -12224,7 +12234,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()?)
JsonTableColumnErrorHandling::Default(self.parse_value()?.value)
} else {
return Ok(None);
};
@ -13299,7 +13309,7 @@ impl<'a> Parser<'a> {
if dialect_of!(self is GenericDialect | MySqlDialect)
&& self.parse_keyword(Keyword::SEPARATOR)
{
clauses.push(FunctionArgumentClause::Separator(self.parse_value()?));
clauses.push(FunctionArgumentClause::Separator(self.parse_value()?.value));
}
if let Some(on_overflow) = self.parse_listagg_on_overflow()? {
@ -14183,7 +14193,7 @@ impl<'a> Parser<'a> {
}
fn parse_pragma_value(&mut self) -> Result<Value, ParserError> {
match self.parse_value()? {
match self.parse_value()?.value {
v @ Value::SingleQuotedString(_) => Ok(v),
v @ Value::DoubleQuotedString(_) => Ok(v),
v @ Value::Number(_, _) => Ok(v),
@ -14643,7 +14653,7 @@ impl<'a> Parser<'a> {
fn maybe_parse_show_stmt_starts_with(&mut self) -> Result<Option<Value>, ParserError> {
if self.parse_keywords(&[Keyword::STARTS, Keyword::WITH]) {
Ok(Some(self.parse_value()?))
Ok(Some(self.parse_value()?.value))
} else {
Ok(None)
}
@ -14659,7 +14669,7 @@ impl<'a> Parser<'a> {
fn maybe_parse_show_stmt_from(&mut self) -> Result<Option<Value>, ParserError> {
if self.parse_keyword(Keyword::FROM) {
Ok(Some(self.parse_value()?))
Ok(Some(self.parse_value()?.value))
} else {
Ok(None)
}

File diff suppressed because it is too large Load diff

View file

@ -55,7 +55,10 @@ fn parse_map_access_expr() {
"indexOf",
[
Expr::Identifier(Ident::new("string_names")),
Expr::Value(Value::SingleQuotedString("endpoint".to_string()))
Expr::Value(
(Value::SingleQuotedString("endpoint".to_string()))
.with_empty_span()
)
]
),
})],
@ -71,7 +74,9 @@ fn parse_map_access_expr() {
left: Box::new(BinaryOp {
left: Box::new(Identifier(Ident::new("id"))),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(Value::SingleQuotedString("test".to_string()))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("test".to_string())).with_empty_span()
)),
}),
op: BinaryOperator::And,
right: Box::new(BinaryOp {
@ -82,13 +87,18 @@ fn parse_map_access_expr() {
"indexOf",
[
Expr::Identifier(Ident::new("string_name")),
Expr::Value(Value::SingleQuotedString("app".to_string()))
Expr::Value(
(Value::SingleQuotedString("app".to_string()))
.with_empty_span()
)
]
),
})],
}),
op: BinaryOperator::NotEq,
right: Box::new(Expr::Value(Value::SingleQuotedString("foo".to_string()))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("foo".to_string())).with_empty_span()
)),
}),
}),
group_by: GroupByExpr::Expressions(vec![], vec![]),
@ -114,8 +124,8 @@ fn parse_array_expr() {
assert_eq!(
&Expr::Array(Array {
elem: vec![
Expr::Value(Value::SingleQuotedString("1".to_string())),
Expr::Value(Value::SingleQuotedString("2".to_string())),
Expr::Value((Value::SingleQuotedString("1".to_string())).with_empty_span()),
Expr::Value((Value::SingleQuotedString("2".to_string())).with_empty_span()),
],
named: false,
}),
@ -1016,17 +1026,15 @@ fn parse_select_parametric_function() {
assert_eq!(parameters.args.len(), 2);
assert_eq!(
parameters.args[0],
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(Value::Number(
"0.5".parse().unwrap(),
false
))))
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
(Value::Number("0.5".parse().unwrap(), false)).with_empty_span()
)))
);
assert_eq!(
parameters.args[1],
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(Value::Number(
"0.6".parse().unwrap(),
false
))))
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
(Value::Number("0.6".parse().unwrap(), false)).with_empty_span()
)))
);
}
_ => unreachable!(),
@ -1078,9 +1086,9 @@ fn parse_select_order_by_with_fill_interpolate() {
nulls_first: Some(true),
},
with_fill: Some(WithFill {
from: Some(Expr::Value(number("10"))),
to: Some(Expr::Value(number("20"))),
step: Some(Expr::Value(number("2"))),
from: Some(Expr::value(number("10"))),
to: Some(Expr::value(number("20"))),
step: Some(Expr::value(number("2"))),
}),
},
OrderByExpr {
@ -1090,9 +1098,9 @@ fn parse_select_order_by_with_fill_interpolate() {
nulls_first: Some(false),
},
with_fill: Some(WithFill {
from: Some(Expr::Value(number("30"))),
to: Some(Expr::Value(number("40"))),
step: Some(Expr::Value(number("3"))),
from: Some(Expr::value(number("30"))),
to: Some(Expr::value(number("40"))),
step: Some(Expr::value(number("3"))),
}),
},
]),
@ -1102,14 +1110,14 @@ fn parse_select_order_by_with_fill_interpolate() {
expr: Some(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("col1"))),
op: BinaryOperator::Plus,
right: Box::new(Expr::Value(number("1"))),
right: Box::new(Expr::value(number("1"))),
}),
}])
})
},
select.order_by.expect("ORDER BY expected")
);
assert_eq!(Some(Expr::Value(number("2"))), select.limit);
assert_eq!(Some(Expr::value(number("2"))), select.limit);
}
#[test]
@ -1150,9 +1158,9 @@ fn parse_with_fill() {
let select = clickhouse().verified_query(sql);
assert_eq!(
Some(WithFill {
from: Some(Expr::Value(number("10"))),
to: Some(Expr::Value(number("20"))),
step: Some(Expr::Value(number("2"))),
from: Some(Expr::value(number("10"))),
to: Some(Expr::value(number("20"))),
step: Some(Expr::value(number("2"))),
})
.as_ref(),
match select.order_by.expect("ORDER BY expected").kind {
@ -1193,7 +1201,7 @@ fn parse_interpolate_body_with_columns() {
expr: Some(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("col1"))),
op: BinaryOperator::Plus,
right: Box::new(Expr::Value(number("1"))),
right: Box::new(Expr::value(number("1"))),
}),
},
InterpolateExpr {
@ -1205,7 +1213,7 @@ fn parse_interpolate_body_with_columns() {
expr: Some(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("col4"))),
op: BinaryOperator::Plus,
right: Box::new(Expr::Value(number("4"))),
right: Box::new(Expr::value(number("4"))),
}),
},
])
@ -1260,7 +1268,9 @@ fn test_prewhere() {
Some(&BinaryOp {
left: Box::new(Identifier(Ident::new("x"))),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(Value::Number("1".parse().unwrap(), false))),
right: Box::new(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)),
})
);
let selection = query.as_ref().body.as_select().unwrap().selection.as_ref();
@ -1269,7 +1279,9 @@ fn test_prewhere() {
Some(&BinaryOp {
left: Box::new(Identifier(Ident::new("y"))),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(Value::Number("2".parse().unwrap(), false))),
right: Box::new(Expr::Value(
(Value::Number("2".parse().unwrap(), false)).with_empty_span()
)),
})
);
}
@ -1285,13 +1297,17 @@ fn test_prewhere() {
left: Box::new(BinaryOp {
left: Box::new(Identifier(Ident::new("x"))),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(Value::Number("1".parse().unwrap(), false))),
right: Box::new(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)),
}),
op: BinaryOperator::And,
right: Box::new(BinaryOp {
left: Box::new(Identifier(Ident::new("y"))),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(Value::Number("2".parse().unwrap(), false))),
right: Box::new(Expr::Value(
(Value::Number("2".parse().unwrap(), false)).with_empty_span()
)),
}),
})
);
@ -1399,10 +1415,9 @@ fn parse_create_table_on_commit_and_as_query() {
assert_eq!(on_commit, Some(OnCommit::PreserveRows));
assert_eq!(
query.unwrap().body.as_select().unwrap().projection,
vec![UnnamedExpr(Expr::Value(Value::Number(
"1".parse().unwrap(),
false
)))]
vec![UnnamedExpr(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
))]
);
}
_ => unreachable!(),
@ -1415,9 +1430,9 @@ fn parse_freeze_and_unfreeze_partition() {
for operation_name in &["FREEZE", "UNFREEZE"] {
let sql = format!("ALTER TABLE t {operation_name} PARTITION '2024-08-14'");
let expected_partition = Partition::Expr(Expr::Value(Value::SingleQuotedString(
"2024-08-14".to_string(),
)));
let expected_partition = Partition::Expr(Expr::Value(
Value::SingleQuotedString("2024-08-14".to_string()).with_empty_span(),
));
match clickhouse_and_generic().verified_stmt(&sql) {
Statement::AlterTable { operations, .. } => {
assert_eq!(operations.len(), 1);
@ -1445,9 +1460,9 @@ fn parse_freeze_and_unfreeze_partition() {
match clickhouse_and_generic().verified_stmt(&sql) {
Statement::AlterTable { operations, .. } => {
assert_eq!(operations.len(), 1);
let expected_partition = Partition::Expr(Expr::Value(Value::SingleQuotedString(
"2024-08-14".to_string(),
)));
let expected_partition = Partition::Expr(Expr::Value(
Value::SingleQuotedString("2024-08-14".to_string()).with_empty_span(),
));
let expected_operation = if operation_name == &"FREEZE" {
AlterTableOperation::FreezePartition {
partition: expected_partition,

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,7 @@ fn custom_prefix_parser() -> Result<(), ParserError> {
fn parse_prefix(&self, parser: &mut Parser) -> Option<Result<Expr, ParserError>> {
if parser.consume_token(&Token::Number("1".to_string(), false)) {
Some(Ok(Expr::Value(Value::Null)))
Some(Ok(Expr::Value(Value::Null.with_empty_span())))
} else {
None
}

View file

@ -47,7 +47,9 @@ fn test_databricks_identifiers() {
databricks()
.verified_only_select(r#"SELECT "Ä""#)
.projection[0],
SelectItem::UnnamedExpr(Expr::Value(Value::DoubleQuotedString("Ä".to_owned())))
SelectItem::UnnamedExpr(Expr::Value(
(Value::DoubleQuotedString("Ä".to_owned())).with_empty_span()
))
);
}
@ -62,9 +64,9 @@ fn test_databricks_exists() {
call(
"array",
[
Expr::Value(number("1")),
Expr::Value(number("2")),
Expr::Value(number("3"))
Expr::value(number("1")),
Expr::value(number("2")),
Expr::value(number("3"))
]
),
Expr::Lambda(LambdaFunction {
@ -99,8 +101,8 @@ fn test_databricks_lambdas() {
call(
"array",
[
Expr::Value(Value::SingleQuotedString("Hello".to_owned())),
Expr::Value(Value::SingleQuotedString("World".to_owned()))
Expr::value(Value::SingleQuotedString("Hello".to_owned())),
Expr::value(Value::SingleQuotedString("World".to_owned()))
]
),
Expr::Lambda(LambdaFunction {
@ -114,7 +116,7 @@ fn test_databricks_lambdas() {
op: BinaryOperator::Eq,
right: Box::new(Expr::Identifier(Ident::new("p2")))
},
result: Expr::Value(number("0"))
result: Expr::value(number("0"))
},
CaseWhen {
condition: Expr::BinaryOp {
@ -130,11 +132,11 @@ fn test_databricks_lambdas() {
},
result: Expr::UnaryOp {
op: UnaryOperator::Minus,
expr: Box::new(Expr::Value(number("1")))
expr: Box::new(Expr::value(number("1")))
}
},
],
else_result: Some(Box::new(Expr::Value(number("1"))))
else_result: Some(Box::new(Expr::value(number("1"))))
})
})
]
@ -154,12 +156,12 @@ fn test_values_clause() {
explicit_row: false,
rows: vec![
vec![
Expr::Value(Value::DoubleQuotedString("one".to_owned())),
Expr::Value(number("1")),
Expr::Value((Value::DoubleQuotedString("one".to_owned())).with_empty_span()),
Expr::value(number("1")),
],
vec![
Expr::Value(Value::SingleQuotedString("two".to_owned())),
Expr::Value(number("2")),
Expr::Value((Value::SingleQuotedString("two".to_owned())).with_empty_span()),
Expr::value(number("2")),
],
],
};
@ -286,8 +288,8 @@ fn parse_databricks_struct_function() {
.projection[0],
SelectItem::UnnamedExpr(Expr::Struct {
values: vec![
Expr::Value(number("1")),
Expr::Value(Value::SingleQuotedString("foo".to_string()))
Expr::value(number("1")),
Expr::Value((Value::SingleQuotedString("foo".to_string())).with_empty_span())
],
fields: vec![]
})
@ -299,14 +301,17 @@ fn parse_databricks_struct_function() {
SelectItem::UnnamedExpr(Expr::Struct {
values: vec![
Expr::Named {
expr: Expr::Value(number("1")).into(),
expr: Expr::value(number("1")).into(),
name: Ident::new("one")
},
Expr::Named {
expr: Expr::Value(Value::SingleQuotedString("foo".to_string())).into(),
expr: Expr::Value(
(Value::SingleQuotedString("foo".to_string())).with_empty_span()
)
.into(),
name: Ident::new("foo")
},
Expr::Value(Value::Boolean(false))
Expr::Value((Value::Boolean(false)).with_empty_span())
],
fields: vec![]
})

View file

@ -210,7 +210,7 @@ fn test_create_macro_default_args() {
MacroArg::new("a"),
MacroArg {
name: Ident::new("b"),
default_expr: Some(Expr::Value(number("5"))),
default_expr: Some(Expr::value(number("5"))),
},
]),
definition: MacroDefinition::Expr(Expr::BinaryOp {
@ -363,15 +363,15 @@ fn test_duckdb_struct_literal() {
&Expr::Dictionary(vec![
DictionaryField {
key: Ident::with_quote('\'', "a"),
value: Box::new(Expr::Value(number("1"))),
value: Box::new(Expr::value(number("1"))),
},
DictionaryField {
key: Ident::with_quote('\'', "b"),
value: Box::new(Expr::Value(number("2"))),
value: Box::new(Expr::value(number("2"))),
},
DictionaryField {
key: Ident::with_quote('\'', "c"),
value: Box::new(Expr::Value(number("3"))),
value: Box::new(Expr::value(number("3"))),
},
],),
expr_from_projection(&select.projection[0])
@ -381,7 +381,9 @@ fn test_duckdb_struct_literal() {
&Expr::Array(Array {
elem: vec![Expr::Dictionary(vec![DictionaryField {
key: Ident::with_quote('\'', "a"),
value: Box::new(Expr::Value(Value::SingleQuotedString("abc".to_string()))),
value: Box::new(Expr::Value(
(Value::SingleQuotedString("abc".to_string())).with_empty_span()
)),
},],)],
named: false
}),
@ -391,7 +393,7 @@ fn test_duckdb_struct_literal() {
&Expr::Dictionary(vec![
DictionaryField {
key: Ident::with_quote('\'', "a"),
value: Box::new(Expr::Value(number("1"))),
value: Box::new(Expr::value(number("1"))),
},
DictionaryField {
key: Ident::with_quote('\'', "b"),
@ -410,11 +412,14 @@ fn test_duckdb_struct_literal() {
&Expr::Dictionary(vec![
DictionaryField {
key: Ident::with_quote('\'', "a"),
value: Expr::Value(number("1")).into(),
value: Expr::value(number("1")).into(),
},
DictionaryField {
key: Ident::with_quote('\'', "b"),
value: Expr::Value(Value::SingleQuotedString("abc".to_string())).into(),
value: Expr::Value(
(Value::SingleQuotedString("abc".to_string())).with_empty_span()
)
.into(),
},
],),
expr_from_projection(&select.projection[3])
@ -431,7 +436,7 @@ fn test_duckdb_struct_literal() {
key: Ident::with_quote('\'', "a"),
value: Expr::Dictionary(vec![DictionaryField {
key: Ident::with_quote('\'', "aa"),
value: Expr::Value(number("1")).into(),
value: Expr::value(number("1")).into(),
}],)
.into(),
}],),
@ -594,16 +599,16 @@ fn test_duckdb_named_argument_function_with_assignment_operator() {
args: vec![
FunctionArg::Named {
name: Ident::new("a"),
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
"1".to_owned()
))),
arg: FunctionArgExpr::Expr(Expr::Value(
(Value::SingleQuotedString("1".to_owned())).with_empty_span()
)),
operator: FunctionArgOperator::Assignment
},
FunctionArg::Named {
name: Ident::new("b"),
arg: FunctionArgExpr::Expr(Expr::Value(Value::SingleQuotedString(
"2".to_owned()
))),
arg: FunctionArgExpr::Expr(Expr::Value(
(Value::SingleQuotedString("2".to_owned())).with_empty_span()
)),
operator: FunctionArgOperator::Assignment
},
],
@ -632,14 +637,14 @@ fn test_array_index() {
&Expr::CompoundFieldAccess {
root: Box::new(Expr::Array(Array {
elem: vec![
Expr::Value(Value::SingleQuotedString("a".to_owned())),
Expr::Value(Value::SingleQuotedString("b".to_owned())),
Expr::Value(Value::SingleQuotedString("c".to_owned()))
Expr::Value((Value::SingleQuotedString("a".to_owned())).with_empty_span()),
Expr::Value((Value::SingleQuotedString("b".to_owned())).with_empty_span()),
Expr::Value((Value::SingleQuotedString("c".to_owned())).with_empty_span())
],
named: false
})),
access_chain: vec![AccessExpr::Subscript(Subscript::Index {
index: Expr::Value(number("3"))
index: Expr::value(number("3"))
})]
},
expr

View file

@ -409,7 +409,8 @@ fn parse_create_function() {
assert_eq!(
function_body,
Some(CreateFunctionBody::AsBeforeOptions(Expr::Value(
Value::SingleQuotedString("org.random.class.Name".to_string())
(Value::SingleQuotedString("org.random.class.Name".to_string()))
.with_empty_span()
)))
);
assert_eq!(

View file

@ -68,7 +68,7 @@ fn parse_table_time_travel() {
args: None,
with_hints: vec![],
version: Some(TableVersion::ForSystemTimeAsOf(Expr::Value(
Value::SingleQuotedString(version)
(Value::SingleQuotedString(version)).with_empty_span()
))),
partitions: vec![],
with_ordinality: false,
@ -121,7 +121,9 @@ fn parse_create_procedure() {
distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::Value(number("1")))],
projection: vec![SelectItem::UnnamedExpr(Expr::Value(
(number("1")).with_empty_span()
))],
into: None,
from: vec![],
lateral_views: vec![],
@ -473,7 +475,9 @@ fn parse_mssql_top_paren() {
let select = ms_and_generic().verified_only_select(sql);
let top = select.top.unwrap();
assert_eq!(
Some(TopQuantity::Expr(Expr::Value(number("5")))),
Some(TopQuantity::Expr(Expr::Value(
(number("5")).with_empty_span()
))),
top.quantity
);
assert!(!top.percent);
@ -485,7 +489,9 @@ fn parse_mssql_top_percent() {
let select = ms_and_generic().verified_only_select(sql);
let top = select.top.unwrap();
assert_eq!(
Some(TopQuantity::Expr(Expr::Value(number("5")))),
Some(TopQuantity::Expr(Expr::Value(
(number("5")).with_empty_span()
))),
top.quantity
);
assert!(top.percent);
@ -497,7 +503,9 @@ fn parse_mssql_top_with_ties() {
let select = ms_and_generic().verified_only_select(sql);
let top = select.top.unwrap();
assert_eq!(
Some(TopQuantity::Expr(Expr::Value(number("5")))),
Some(TopQuantity::Expr(Expr::Value(
(number("5")).with_empty_span()
))),
top.quantity
);
assert!(top.with_ties);
@ -509,7 +517,9 @@ fn parse_mssql_top_percent_with_ties() {
let select = ms_and_generic().verified_only_select(sql);
let top = select.top.unwrap();
assert_eq!(
Some(TopQuantity::Expr(Expr::Value(number("10")))),
Some(TopQuantity::Expr(Expr::Value(
(number("10")).with_empty_span()
))),
top.quantity
);
assert!(top.percent);
@ -746,7 +756,10 @@ fn parse_mssql_json_object() {
assert!(matches!(
args[0],
FunctionArg::ExprNamed {
name: Expr::Value(Value::SingleQuotedString(_)),
name: Expr::Value(ValueWithSpan {
value: Value::SingleQuotedString(_),
span: _
}),
arg: FunctionArgExpr::Expr(Expr::Function(_)),
operator: FunctionArgOperator::Colon
}
@ -762,7 +775,10 @@ fn parse_mssql_json_object() {
assert!(matches!(
args[2],
FunctionArg::ExprNamed {
name: Expr::Value(Value::SingleQuotedString(_)),
name: Expr::Value(ValueWithSpan {
value: Value::SingleQuotedString(_),
span: _
}),
arg: FunctionArgExpr::Expr(Expr::Subquery(_)),
operator: FunctionArgOperator::Colon
}
@ -793,7 +809,10 @@ fn parse_mssql_json_object() {
assert!(matches!(
args[0],
FunctionArg::ExprNamed {
name: Expr::Value(Value::SingleQuotedString(_)),
name: Expr::Value(ValueWithSpan {
value: Value::SingleQuotedString(_),
span: _
}),
arg: FunctionArgExpr::Expr(Expr::CompoundIdentifier(_)),
operator: FunctionArgOperator::Colon
}
@ -801,7 +820,10 @@ fn parse_mssql_json_object() {
assert!(matches!(
args[1],
FunctionArg::ExprNamed {
name: Expr::Value(Value::SingleQuotedString(_)),
name: Expr::Value(ValueWithSpan {
value: Value::SingleQuotedString(_),
span: _
}),
arg: FunctionArgExpr::Expr(Expr::CompoundIdentifier(_)),
operator: FunctionArgOperator::Colon
}
@ -809,7 +831,10 @@ fn parse_mssql_json_object() {
assert!(matches!(
args[2],
FunctionArg::ExprNamed {
name: Expr::Value(Value::SingleQuotedString(_)),
name: Expr::Value(ValueWithSpan {
value: Value::SingleQuotedString(_),
span: _
}),
arg: FunctionArgExpr::Expr(Expr::CompoundIdentifier(_)),
operator: FunctionArgOperator::Colon
}
@ -830,11 +855,17 @@ fn parse_mssql_json_array() {
assert_eq!(
&[
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
Value::SingleQuotedString("a".into())
(Value::SingleQuotedString("a".into())).with_empty_span()
))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
(number("1")).with_empty_span()
))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
(Value::Null).with_empty_span()
))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
(number("2")).with_empty_span()
))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("1")))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(Value::Null))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("2")))),
],
&args[..]
);
@ -856,11 +887,17 @@ fn parse_mssql_json_array() {
assert_eq!(
&[
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
Value::SingleQuotedString("a".into())
(Value::SingleQuotedString("a".into())).with_empty_span()
))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
(number("1")).with_empty_span()
))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
(Value::Null).with_empty_span()
))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
(number("2")).with_empty_span()
))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("1")))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(Value::Null))),
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("2")))),
],
&args[..]
);
@ -915,7 +952,7 @@ fn parse_mssql_json_array() {
}) => {
assert_eq!(
&FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
Value::SingleQuotedString("a".into())
(Value::SingleQuotedString("a".into())).with_empty_span()
))),
&args[0]
);
@ -942,7 +979,7 @@ fn parse_mssql_json_array() {
}) => {
assert_eq!(
&FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
Value::SingleQuotedString("a".into())
(Value::SingleQuotedString("a".into())).with_empty_span()
))),
&args[0]
);
@ -964,7 +1001,9 @@ fn parse_mssql_json_array() {
..
}) => {
assert_eq!(
&FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("1")))),
&FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
(number("1")).with_empty_span()
))),
&args[0]
);
assert!(matches!(
@ -1042,15 +1081,15 @@ fn parse_convert() {
unreachable!()
};
assert!(!is_try);
assert_eq!(Expr::Value(number("1")), *expr);
assert_eq!(Expr::value(number("1")), *expr);
assert_eq!(Some(DataType::Int(None)), data_type);
assert!(charset.is_none());
assert!(target_before_value);
assert_eq!(
vec![
Expr::Value(number("2")),
Expr::Value(number("3")),
Expr::Value(Value::Null),
Expr::value(number("2")),
Expr::value(number("3")),
Expr::Value((Value::Null).with_empty_span()),
],
styles
);
@ -1089,8 +1128,12 @@ fn parse_substring_in_select() {
quote_style: None,
span: Span::empty(),
})),
substring_from: Some(Box::new(Expr::Value(number("0")))),
substring_for: Some(Box::new(Expr::Value(number("1")))),
substring_from: Some(Box::new(Expr::Value(
(number("0")).with_empty_span()
))),
substring_for: Some(Box::new(Expr::Value(
(number("1")).with_empty_span()
))),
special: true,
})],
into: None,
@ -1179,9 +1222,9 @@ fn parse_mssql_declare() {
span: Span::empty(),
}],
data_type: Some(Text),
assignment: Some(MsSqlAssignment(Box::new(Expr::Value(SingleQuotedString(
"foobar".to_string()
))))),
assignment: Some(MsSqlAssignment(Box::new(Expr::Value(
(SingleQuotedString("foobar".to_string())).with_empty_span()
)))),
declare_type: None,
binary: None,
sensitive: None,
@ -1215,7 +1258,9 @@ fn parse_mssql_declare() {
local: false,
hivevar: false,
variables: OneOrManyWithParens::One(ObjectName::from(vec![Ident::new("@bar")])),
value: vec![Expr::Value(Value::Number("2".parse().unwrap(), false))],
value: vec![Expr::Value(
(Value::Number("2".parse().unwrap(), false)).with_empty_span()
)],
},
Statement::Query(Box::new(Query {
with: None,
@ -1236,7 +1281,9 @@ fn parse_mssql_declare() {
projection: vec![SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("@bar"))),
op: BinaryOperator::Multiply,
right: Box::new(Expr::Value(Value::Number("4".parse().unwrap(), false))),
right: Box::new(Expr::Value(
(Value::Number("4".parse().unwrap(), false)).with_empty_span()
)),
})],
into: None,
from: vec![],
@ -1268,11 +1315,15 @@ fn test_parse_raiserror() {
assert_eq!(
s,
Statement::RaisError {
message: Box::new(Expr::Value(Value::SingleQuotedString(
"This is a test".to_string()
))),
severity: Box::new(Expr::Value(Value::Number("16".parse().unwrap(), false))),
state: Box::new(Expr::Value(Value::Number("1".parse().unwrap(), false))),
message: Box::new(Expr::Value(
(Value::SingleQuotedString("This is a test".to_string())).with_empty_span()
)),
severity: Box::new(Expr::Value(
(Value::Number("16".parse().unwrap(), false)).with_empty_span()
)),
state: Box::new(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)),
arguments: vec![],
options: vec![],
}
@ -1347,7 +1398,7 @@ fn parse_create_table_with_valid_options() {
SqlOption::Partition {
column_name: "column_a".into(),
range_direction: None,
for_values: vec![Expr::Value(test_utils::number("10")), Expr::Value(test_utils::number("11"))] ,
for_values: vec![Expr::Value((test_utils::number("10")).with_empty_span()), Expr::Value((test_utils::number("11")).with_empty_span())] ,
},
],
),
@ -1358,8 +1409,8 @@ fn parse_create_table_with_valid_options() {
column_name: "column_a".into(),
range_direction: Some(PartitionRangeDirection::Left),
for_values: vec![
Expr::Value(test_utils::number("10")),
Expr::Value(test_utils::number("11")),
Expr::Value((test_utils::number("10")).with_empty_span()),
Expr::Value((test_utils::number("11")).with_empty_span()),
],
}
],
@ -1630,8 +1681,8 @@ fn parse_create_table_with_identity_column() {
IdentityProperty {
parameters: Some(IdentityPropertyFormatKind::FunctionCall(
IdentityParameters {
seed: Expr::Value(number("1")),
increment: Expr::Value(number("1")),
seed: Expr::value(number("1")),
increment: Expr::value(number("1")),
},
)),
order: None,

View file

@ -52,11 +52,11 @@ fn parse_literal_string() {
let select = mysql().verified_only_select(sql);
assert_eq!(2, select.projection.len());
assert_eq!(
&Expr::Value(Value::SingleQuotedString("single".to_string())),
&Expr::Value((Value::SingleQuotedString("single".to_string())).with_empty_span()),
expr_from_projection(&select.projection[0])
);
assert_eq!(
&Expr::Value(Value::DoubleQuotedString("double".to_string())),
&Expr::Value((Value::DoubleQuotedString("double".to_string())).with_empty_span()),
expr_from_projection(&select.projection[1])
);
}
@ -621,7 +621,7 @@ fn parse_set_variables() {
local: true,
hivevar: false,
variables: OneOrManyWithParens::One(ObjectName::from(vec!["autocommit".into()])),
value: vec![Expr::Value(number("1"))],
value: vec![Expr::value(number("1"))],
}
);
}
@ -986,7 +986,9 @@ fn parse_create_table_both_options_and_as_query() {
assert_eq!(collation, Some("utf8mb4_0900_ai_ci".to_string()));
assert_eq!(
query.unwrap().body.as_select().unwrap().projection,
vec![SelectItem::UnnamedExpr(Expr::Value(number("1")))]
vec![SelectItem::UnnamedExpr(Expr::Value(
(number("1")).with_empty_span()
))]
);
}
_ => unreachable!(),
@ -1413,18 +1415,25 @@ fn parse_simple_insert() {
explicit_row: false,
rows: vec![
vec![
Expr::Value(Value::SingleQuotedString(
"Test Some Inserts".to_string()
)),
Expr::Value(number("1"))
Expr::Value(
(Value::SingleQuotedString("Test Some Inserts".to_string()))
.with_empty_span()
),
Expr::value(number("1"))
],
vec![
Expr::Value(Value::SingleQuotedString("Test Entry 2".to_string())),
Expr::Value(number("2"))
Expr::Value(
(Value::SingleQuotedString("Test Entry 2".to_string()))
.with_empty_span()
),
Expr::value(number("2"))
],
vec![
Expr::Value(Value::SingleQuotedString("Test Entry 3".to_string())),
Expr::Value(number("3"))
Expr::Value(
(Value::SingleQuotedString("Test Entry 3".to_string()))
.with_empty_span()
),
Expr::value(number("3"))
]
]
})),
@ -1471,8 +1480,11 @@ fn parse_ignore_insert() {
body: Box::new(SetExpr::Values(Values {
explicit_row: false,
rows: vec![vec![
Expr::Value(Value::SingleQuotedString("Test Some Inserts".to_string())),
Expr::Value(number("1"))
Expr::Value(
(Value::SingleQuotedString("Test Some Inserts".to_string()))
.with_empty_span()
),
Expr::value(number("1"))
]]
})),
order_by: None,
@ -1518,8 +1530,11 @@ fn parse_priority_insert() {
body: Box::new(SetExpr::Values(Values {
explicit_row: false,
rows: vec![vec![
Expr::Value(Value::SingleQuotedString("Test Some Inserts".to_string())),
Expr::Value(number("1"))
Expr::Value(
(Value::SingleQuotedString("Test Some Inserts".to_string()))
.with_empty_span()
),
Expr::value(number("1"))
]]
})),
order_by: None,
@ -1562,8 +1577,11 @@ fn parse_priority_insert() {
body: Box::new(SetExpr::Values(Values {
explicit_row: false,
rows: vec![vec![
Expr::Value(Value::SingleQuotedString("Test Some Inserts".to_string())),
Expr::Value(number("1"))
Expr::Value(
(Value::SingleQuotedString("Test Some Inserts".to_string()))
.with_empty_span()
),
Expr::value(number("1"))
]]
})),
order_by: None,
@ -1611,9 +1629,9 @@ fn parse_insert_as() {
with: None,
body: Box::new(SetExpr::Values(Values {
explicit_row: false,
rows: vec![vec![Expr::Value(Value::SingleQuotedString(
"2024-01-01".to_string()
))]]
rows: vec![vec![Expr::Value(
(Value::SingleQuotedString("2024-01-01".to_string())).with_empty_span()
)]]
})),
order_by: None,
limit: None,
@ -1672,8 +1690,11 @@ fn parse_insert_as() {
body: Box::new(SetExpr::Values(Values {
explicit_row: false,
rows: vec![vec![
Expr::Value(number("1")),
Expr::Value(Value::SingleQuotedString("2024-01-01".to_string()))
Expr::value(number("1")),
Expr::Value(
(Value::SingleQuotedString("2024-01-01".to_string()))
.with_empty_span()
)
]]
})),
order_by: None,
@ -1720,8 +1741,11 @@ fn parse_replace_insert() {
body: Box::new(SetExpr::Values(Values {
explicit_row: false,
rows: vec![vec![
Expr::Value(Value::SingleQuotedString("Test Some Inserts".to_string())),
Expr::Value(number("1"))
Expr::Value(
(Value::SingleQuotedString("Test Some Inserts".to_string()))
.with_empty_span()
),
Expr::value(number("1"))
]]
})),
order_by: None,
@ -1816,16 +1840,20 @@ fn parse_insert_with_on_duplicate_update() {
body: Box::new(SetExpr::Values(Values {
explicit_row: false,
rows: vec![vec![
Expr::Value(Value::SingleQuotedString(
"accounting_manager".to_string()
)),
Expr::Value(Value::SingleQuotedString(
Expr::Value(
(Value::SingleQuotedString("accounting_manager".to_string()))
.with_empty_span()
),
Expr::Value(
(Value::SingleQuotedString(
"Some description about the group".to_string()
)),
Expr::Value(Value::Boolean(true)),
Expr::Value(Value::Boolean(true)),
Expr::Value(Value::Boolean(true)),
Expr::Value(Value::Boolean(true)),
))
.with_empty_span()
),
Expr::Value((Value::Boolean(true)).with_empty_span()),
Expr::Value((Value::Boolean(true)).with_empty_span()),
Expr::Value((Value::Boolean(true)).with_empty_span()),
Expr::Value((Value::Boolean(true)).with_empty_span()),
]]
})),
order_by: None,
@ -1946,7 +1974,7 @@ fn parse_select_with_concatenation_of_exp_number_and_numeric_prefix_column() {
top: None,
top_before_distinct: false,
projection: vec![
SelectItem::UnnamedExpr(Expr::Value(number("123e4"))),
SelectItem::UnnamedExpr(Expr::value(number("123e4"))),
SelectItem::UnnamedExpr(Expr::Identifier(Ident::new("123col_$@123abc")))
],
into: None,
@ -2063,7 +2091,7 @@ fn parse_update_with_joins() {
Ident::new("o"),
Ident::new("completed")
])),
value: Expr::Value(Value::Boolean(true))
value: Expr::Value((Value::Boolean(true)).with_empty_span())
}],
assignments
);
@ -2074,7 +2102,9 @@ fn parse_update_with_joins() {
Ident::new("firstname")
])),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(Value::SingleQuotedString("Peter".to_string())))
right: Box::new(Expr::Value(
(Value::SingleQuotedString("Peter".to_string())).with_empty_span()
))
}),
selection
);
@ -2114,7 +2144,7 @@ fn parse_delete_with_limit() {
let sql = "DELETE FROM customers LIMIT 100";
match mysql().verified_stmt(sql) {
Statement::Delete(Delete { limit, .. }) => {
assert_eq!(Some(Expr::Value(number("100"))), limit);
assert_eq!(Some(Expr::value(number("100"))), limit);
}
_ => unreachable!(),
}
@ -2462,8 +2492,12 @@ fn parse_substring_in_select() {
quote_style: None,
span: Span::empty(),
})),
substring_from: Some(Box::new(Expr::Value(number("0")))),
substring_for: Some(Box::new(Expr::Value(number("1")))),
substring_from: Some(Box::new(Expr::Value(
(number("0")).with_empty_span()
))),
substring_for: Some(Box::new(Expr::Value(
(number("1")).with_empty_span()
))),
special: true,
})],
into: None,
@ -2937,7 +2971,7 @@ fn parse_json_table() {
.from[0]
.relation,
TableFactor::JsonTable {
json_expr: Expr::Value(Value::SingleQuotedString("[1,2]".to_string())),
json_expr: Expr::Value((Value::SingleQuotedString("[1,2]".to_string())).with_empty_span()),
json_path: Value::SingleQuotedString("$[*]".to_string()),
columns: vec![
JsonTableColumn::Named(JsonTableNamedColumn {
@ -2975,33 +3009,33 @@ fn parse_logical_xor() {
let select = mysql_and_generic().verified_only_select(sql);
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Value(Value::Boolean(true))),
left: Box::new(Expr::Value((Value::Boolean(true)).with_empty_span())),
op: BinaryOperator::Xor,
right: Box::new(Expr::Value(Value::Boolean(true))),
right: Box::new(Expr::Value((Value::Boolean(true)).with_empty_span())),
}),
select.projection[0]
);
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Value(Value::Boolean(false))),
left: Box::new(Expr::Value((Value::Boolean(false)).with_empty_span())),
op: BinaryOperator::Xor,
right: Box::new(Expr::Value(Value::Boolean(false))),
right: Box::new(Expr::Value((Value::Boolean(false)).with_empty_span())),
}),
select.projection[1]
);
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Value(Value::Boolean(true))),
left: Box::new(Expr::Value((Value::Boolean(true)).with_empty_span())),
op: BinaryOperator::Xor,
right: Box::new(Expr::Value(Value::Boolean(false))),
right: Box::new(Expr::Value((Value::Boolean(false)).with_empty_span())),
}),
select.projection[2]
);
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Value(Value::Boolean(false))),
left: Box::new(Expr::Value((Value::Boolean(false)).with_empty_span())),
op: BinaryOperator::Xor,
right: Box::new(Expr::Value(Value::Boolean(true))),
right: Box::new(Expr::Value((Value::Boolean(true)).with_empty_span())),
}),
select.projection[3]
);
@ -3013,7 +3047,7 @@ fn parse_bitstring_literal() {
assert_eq!(
select.projection,
vec![SelectItem::UnnamedExpr(Expr::Value(
Value::SingleQuotedByteStringLiteral("111".to_string())
(Value::SingleQuotedByteStringLiteral("111".to_string())).with_empty_span()
))]
);
}

View file

@ -436,7 +436,9 @@ fn parse_create_table_with_defaults() {
options: vec![
ColumnOptionDef {
name: None,
option: ColumnOption::Default(Expr::Value(Value::Boolean(true))),
option: ColumnOption::Default(Expr::Value(
(Value::Boolean(true)).with_empty_span()
)),
},
ColumnOptionDef {
name: None,
@ -488,15 +490,15 @@ fn parse_create_table_with_defaults() {
vec![
SqlOption::KeyValue {
key: "fillfactor".into(),
value: Expr::Value(number("20"))
value: Expr::value(number("20"))
},
SqlOption::KeyValue {
key: "user_catalog_table".into(),
value: Expr::Value(Value::Boolean(true))
value: Expr::Value((Value::Boolean(true)).with_empty_span())
},
SqlOption::KeyValue {
key: "autovacuum_vacuum_threshold".into(),
value: Expr::Value(number("100"))
value: Expr::value(number("100"))
},
]
);
@ -768,7 +770,8 @@ fn parse_alter_table_alter_column() {
) {
AlterTableOperation::AlterColumn { column_name, op } => {
assert_eq!("is_active", column_name.to_string());
let using_expr = Expr::Value(Value::SingleQuotedString("text".to_string()));
let using_expr =
Expr::Value(Value::SingleQuotedString("text".to_string()).with_empty_span());
assert_eq!(
op,
AlterColumnOperation::SetDataType {
@ -1280,7 +1283,7 @@ fn parse_copy_to() {
top_before_distinct: false,
projection: vec![
SelectItem::ExprWithAlias {
expr: Expr::Value(number("42")),
expr: Expr::value(number("42")),
alias: Ident {
value: "a".into(),
quote_style: None,
@ -1288,7 +1291,9 @@ fn parse_copy_to() {
},
},
SelectItem::ExprWithAlias {
expr: Expr::Value(Value::SingleQuotedString("hello".into())),
expr: Expr::Value(
(Value::SingleQuotedString("hello".into())).with_empty_span()
),
alias: Ident {
value: "b".into(),
quote_style: None,
@ -1446,7 +1451,9 @@ fn parse_set() {
local: false,
hivevar: false,
variables: OneOrManyWithParens::One(ObjectName::from(vec![Ident::new("a")])),
value: vec![Expr::Value(Value::SingleQuotedString("b".into()))],
value: vec![Expr::Value(
(Value::SingleQuotedString("b".into())).with_empty_span()
)],
}
);
@ -1457,7 +1464,7 @@ fn parse_set() {
local: false,
hivevar: false,
variables: OneOrManyWithParens::One(ObjectName::from(vec![Ident::new("a")])),
value: vec![Expr::Value(number("0"))],
value: vec![Expr::value(number("0"))],
}
);
@ -1518,7 +1525,7 @@ fn parse_set() {
Ident::new("reducer"),
Ident::new("parallelism")
])),
value: vec![Expr::Value(Value::Boolean(false))],
value: vec![Expr::Value((Value::Boolean(false)).with_empty_span())],
}
);
@ -1670,8 +1677,8 @@ fn parse_execute() {
Statement::Execute {
name: Some(ObjectName::from(vec!["a".into()])),
parameters: vec![
Expr::Value(number("1")),
Expr::Value(Value::SingleQuotedString("t".to_string()))
Expr::value(number("1")),
Expr::Value((Value::SingleQuotedString("t".to_string())).with_empty_span())
],
has_parentheses: true,
using: vec![],
@ -1692,7 +1699,9 @@ fn parse_execute() {
ExprWithAlias {
expr: Expr::Cast {
kind: CastKind::Cast,
expr: Box::new(Expr::Value(Value::Number("1337".parse().unwrap(), false))),
expr: Box::new(Expr::Value(
(Value::Number("1337".parse().unwrap(), false)).with_empty_span()
)),
data_type: DataType::SmallInt(None),
format: None
},
@ -1701,7 +1710,9 @@ fn parse_execute() {
ExprWithAlias {
expr: Expr::Cast {
kind: CastKind::Cast,
expr: Box::new(Expr::Value(Value::Number("7331".parse().unwrap(), false))),
expr: Box::new(Expr::Value(
(Value::Number("7331".parse().unwrap(), false)).with_empty_span()
)),
data_type: DataType::SmallInt(None),
format: None
},
@ -1899,7 +1910,9 @@ fn parse_pg_on_conflict() {
target: AssignmentTarget::ColumnName(ObjectName::from(
vec!["dname".into()]
)),
value: Expr::Value(Value::Placeholder("$1".to_string()))
value: Expr::Value(
(Value::Placeholder("$1".to_string())).with_empty_span()
)
},],
selection: Some(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident {
@ -1908,7 +1921,9 @@ fn parse_pg_on_conflict() {
span: Span::empty(),
})),
op: BinaryOperator::Gt,
right: Box::new(Expr::Value(Value::Placeholder("$2".to_string())))
right: Box::new(Expr::Value(
(Value::Placeholder("$2".to_string())).with_empty_span()
))
})
}),
action
@ -1942,7 +1957,9 @@ fn parse_pg_on_conflict() {
target: AssignmentTarget::ColumnName(ObjectName::from(
vec!["dname".into()]
)),
value: Expr::Value(Value::Placeholder("$1".to_string()))
value: Expr::Value(
(Value::Placeholder("$1".to_string())).with_empty_span()
)
},],
selection: Some(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident {
@ -1951,7 +1968,9 @@ fn parse_pg_on_conflict() {
span: Span::empty(),
})),
op: BinaryOperator::Gt,
right: Box::new(Expr::Value(Value::Placeholder("$2".to_string())))
right: Box::new(Expr::Value(
(Value::Placeholder("$2".to_string())).with_empty_span()
))
})
}),
action
@ -2167,9 +2186,13 @@ fn parse_pg_regex_match_ops() {
let select = pg().verified_only_select(&format!("SELECT 'abc' {} '^a'", &str_op));
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Value(Value::SingleQuotedString("abc".into()))),
left: Box::new(Expr::Value(
(Value::SingleQuotedString("abc".into())).with_empty_span()
)),
op: op.clone(),
right: Box::new(Expr::Value(Value::SingleQuotedString("^a".into()))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("^a".into())).with_empty_span()
)),
}),
select.projection[0]
);
@ -2189,9 +2212,13 @@ fn parse_pg_like_match_ops() {
let select = pg().verified_only_select(&format!("SELECT 'abc' {} 'a_c%'", &str_op));
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Value(Value::SingleQuotedString("abc".into()))),
left: Box::new(Expr::Value(
(Value::SingleQuotedString("abc".into())).with_empty_span()
)),
op: op.clone(),
right: Box::new(Expr::Value(Value::SingleQuotedString("a_c%".into()))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("a_c%".into())).with_empty_span()
)),
}),
select.projection[0]
);
@ -2201,7 +2228,7 @@ fn parse_pg_like_match_ops() {
#[test]
fn parse_array_index_expr() {
let num: Vec<Expr> = (0..=10)
.map(|s| Expr::Value(number(&s.to_string())))
.map(|s| Expr::Value(number(&s.to_string()).with_empty_span()))
.collect();
let sql = "SELECT foo[0] FROM foos";
@ -2312,7 +2339,7 @@ fn parse_array_subscript() {
(
"(ARRAY[1, 2, 3, 4, 5, 6])[2]",
Subscript::Index {
index: Expr::Value(number("2")),
index: Expr::value(number("2")),
},
),
(
@ -2324,17 +2351,17 @@ fn parse_array_subscript() {
(
"(ARRAY[1, 2, 3, 4, 5, 6])[2:5]",
Subscript::Slice {
lower_bound: Some(Expr::Value(number("2"))),
upper_bound: Some(Expr::Value(number("5"))),
lower_bound: Some(Expr::value(number("2"))),
upper_bound: Some(Expr::value(number("5"))),
stride: None,
},
),
(
"(ARRAY[1, 2, 3, 4, 5, 6])[2:5:3]",
Subscript::Slice {
lower_bound: Some(Expr::Value(number("2"))),
upper_bound: Some(Expr::Value(number("5"))),
stride: Some(Expr::Value(number("3"))),
lower_bound: Some(Expr::value(number("2"))),
upper_bound: Some(Expr::value(number("5"))),
stride: Some(Expr::value(number("3"))),
},
),
(
@ -2343,12 +2370,12 @@ fn parse_array_subscript() {
lower_bound: Some(Expr::BinaryOp {
left: Box::new(call("array_length", [Expr::Identifier(Ident::new("arr"))])),
op: BinaryOperator::Minus,
right: Box::new(Expr::Value(number("3"))),
right: Box::new(Expr::value(number("3"))),
}),
upper_bound: Some(Expr::BinaryOp {
left: Box::new(call("array_length", [Expr::Identifier(Ident::new("arr"))])),
op: BinaryOperator::Minus,
right: Box::new(Expr::Value(number("1"))),
right: Box::new(Expr::value(number("1"))),
}),
stride: None,
},
@ -2357,14 +2384,14 @@ fn parse_array_subscript() {
"(ARRAY[1, 2, 3, 4, 5, 6])[:5]",
Subscript::Slice {
lower_bound: None,
upper_bound: Some(Expr::Value(number("5"))),
upper_bound: Some(Expr::value(number("5"))),
stride: None,
},
),
(
"(ARRAY[1, 2, 3, 4, 5, 6])[2:]",
Subscript::Slice {
lower_bound: Some(Expr::Value(number("2"))),
lower_bound: Some(Expr::value(number("2"))),
upper_bound: None,
stride: None,
},
@ -2400,19 +2427,19 @@ fn parse_array_multi_subscript() {
root: Box::new(call(
"make_array",
vec![
Expr::Value(number("1")),
Expr::Value(number("2")),
Expr::Value(number("3"))
Expr::value(number("1")),
Expr::value(number("2")),
Expr::value(number("3"))
]
)),
access_chain: vec![
AccessExpr::Subscript(Subscript::Slice {
lower_bound: Some(Expr::Value(number("1"))),
upper_bound: Some(Expr::Value(number("2"))),
lower_bound: Some(Expr::value(number("1"))),
upper_bound: Some(Expr::value(number("2"))),
stride: None,
}),
AccessExpr::Subscript(Subscript::Index {
index: Expr::Value(number("2")),
index: Expr::value(number("2")),
}),
],
},
@ -2655,7 +2682,9 @@ fn parse_array_subquery_expr() {
distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::Value(number("1")))],
projection: vec![SelectItem::UnnamedExpr(Expr::Value(
(number("1")).with_empty_span()
))],
into: None,
from: vec![],
lateral_views: vec![],
@ -2678,7 +2707,9 @@ fn parse_array_subquery_expr() {
distinct: None,
top: None,
top_before_distinct: false,
projection: vec![SelectItem::UnnamedExpr(Expr::Value(number("2")))],
projection: vec![SelectItem::UnnamedExpr(Expr::Value(
(number("2")).with_empty_span()
))],
into: None,
from: vec![],
lateral_views: vec![],
@ -2750,7 +2781,9 @@ fn test_json() {
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("params"))),
op: BinaryOperator::LongArrow,
right: Box::new(Expr::Value(Value::SingleQuotedString("name".to_string()))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("name".to_string())).with_empty_span()
)),
}),
select.projection[0]
);
@ -2761,7 +2794,9 @@ fn test_json() {
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("params"))),
op: BinaryOperator::Arrow,
right: Box::new(Expr::Value(Value::SingleQuotedString("name".to_string()))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("name".to_string())).with_empty_span()
)),
}),
select.projection[0]
);
@ -2773,12 +2808,14 @@ fn test_json() {
left: Box::new(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("info"))),
op: BinaryOperator::Arrow,
right: Box::new(Expr::Value(Value::SingleQuotedString("items".to_string())))
right: Box::new(Expr::Value(
(Value::SingleQuotedString("items".to_string())).with_empty_span()
))
}),
op: BinaryOperator::LongArrow,
right: Box::new(Expr::Value(Value::SingleQuotedString(
"product".to_string()
))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("product".to_string())).with_empty_span()
)),
}),
select.projection[0]
);
@ -2790,7 +2827,7 @@ fn test_json() {
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("obj"))),
op: BinaryOperator::Arrow,
right: Box::new(Expr::Value(number("42"))),
right: Box::new(Expr::value(number("42"))),
}),
select.projection[0]
);
@ -2815,9 +2852,9 @@ fn test_json() {
left: Box::new(Expr::Identifier(Ident::new("obj"))),
op: BinaryOperator::Arrow,
right: Box::new(Expr::BinaryOp {
left: Box::new(Expr::Value(number("3"))),
left: Box::new(Expr::value(number("3"))),
op: BinaryOperator::Multiply,
right: Box::new(Expr::Value(number("2"))),
right: Box::new(Expr::value(number("2"))),
}),
}),
select.projection[0]
@ -2829,9 +2866,9 @@ fn test_json() {
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("info"))),
op: BinaryOperator::HashArrow,
right: Box::new(Expr::Value(Value::SingleQuotedString(
"{a,b,c}".to_string()
))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("{a,b,c}".to_string())).with_empty_span()
)),
}),
select.projection[0]
);
@ -2842,9 +2879,9 @@ fn test_json() {
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("info"))),
op: BinaryOperator::HashLongArrow,
right: Box::new(Expr::Value(Value::SingleQuotedString(
"{a,b,c}".to_string()
))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("{a,b,c}".to_string())).with_empty_span()
)),
}),
select.projection[0]
);
@ -2855,9 +2892,9 @@ fn test_json() {
Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("info"))),
op: BinaryOperator::AtArrow,
right: Box::new(Expr::Value(Value::SingleQuotedString(
"{\"a\": 1}".to_string()
))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("{\"a\": 1}".to_string())).with_empty_span()
)),
},
select.selection.unwrap(),
);
@ -2866,9 +2903,9 @@ fn test_json() {
let select = pg().verified_only_select(sql);
assert_eq!(
Expr::BinaryOp {
left: Box::new(Expr::Value(Value::SingleQuotedString(
"{\"a\": 1}".to_string()
))),
left: Box::new(Expr::Value(
(Value::SingleQuotedString("{\"a\": 1}".to_string())).with_empty_span()
)),
op: BinaryOperator::ArrowAt,
right: Box::new(Expr::Identifier(Ident::new("info"))),
},
@ -2883,8 +2920,8 @@ fn test_json() {
op: BinaryOperator::HashMinus,
right: Box::new(Expr::Array(Array {
elem: vec![
Expr::Value(Value::SingleQuotedString("a".to_string())),
Expr::Value(Value::SingleQuotedString("b".to_string())),
Expr::Value((Value::SingleQuotedString("a".to_string())).with_empty_span()),
Expr::Value((Value::SingleQuotedString("b".to_string())).with_empty_span()),
],
named: true,
})),
@ -2898,7 +2935,9 @@ fn test_json() {
Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::from("info"))),
op: BinaryOperator::AtQuestion,
right: Box::new(Expr::Value(Value::SingleQuotedString("$.a".to_string())),),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("$.a".to_string())).with_empty_span()
),),
},
select.selection.unwrap(),
);
@ -2909,7 +2948,9 @@ fn test_json() {
Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::from("info"))),
op: BinaryOperator::AtAt,
right: Box::new(Expr::Value(Value::SingleQuotedString("$.a".to_string())),),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("$.a".to_string())).with_empty_span()
),),
},
select.selection.unwrap(),
);
@ -2920,7 +2961,9 @@ fn test_json() {
Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("info"))),
op: BinaryOperator::Question,
right: Box::new(Expr::Value(Value::SingleQuotedString("b".to_string()))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("b".to_string())).with_empty_span()
)),
},
select.selection.unwrap(),
);
@ -2933,8 +2976,8 @@ fn test_json() {
op: BinaryOperator::QuestionAnd,
right: Box::new(Expr::Array(Array {
elem: vec![
Expr::Value(Value::SingleQuotedString("b".to_string())),
Expr::Value(Value::SingleQuotedString("c".to_string()))
Expr::Value((Value::SingleQuotedString("b".to_string())).with_empty_span()),
Expr::Value((Value::SingleQuotedString("c".to_string())).with_empty_span())
],
named: true
}))
@ -2950,8 +2993,8 @@ fn test_json() {
op: BinaryOperator::QuestionPipe,
right: Box::new(Expr::Array(Array {
elem: vec![
Expr::Value(Value::SingleQuotedString("b".to_string())),
Expr::Value(Value::SingleQuotedString("c".to_string()))
Expr::Value((Value::SingleQuotedString("b".to_string())).with_empty_span()),
Expr::Value((Value::SingleQuotedString("c".to_string())).with_empty_span())
],
named: true
}))
@ -3025,7 +3068,7 @@ fn test_composite_value() {
access_chain: vec![AccessExpr::Dot(Expr::Identifier(Ident::new("price")))]
}),
op: BinaryOperator::Gt,
right: Box::new(Expr::Value(number("9")))
right: Box::new(Expr::value(number("9")))
}
);
@ -3045,8 +3088,12 @@ fn test_composite_value() {
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Array(
Array {
elem: vec![
Expr::Value(Value::SingleQuotedString("i".to_string())),
Expr::Value(Value::SingleQuotedString("i".to_string())),
Expr::Value(
(Value::SingleQuotedString("i".to_string())).with_empty_span()
),
Expr::Value(
(Value::SingleQuotedString("i".to_string())).with_empty_span()
),
],
named: true
}
@ -3106,27 +3153,27 @@ fn parse_escaped_literal_string() {
let select = pg_and_generic().verified_only_select(sql);
assert_eq!(6, select.projection.len());
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("s1 \n s1".to_string())),
&Expr::Value((Value::EscapedStringLiteral("s1 \n s1".to_string())).with_empty_span()),
expr_from_projection(&select.projection[0])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("s2 \\n s2".to_string())),
&Expr::Value((Value::EscapedStringLiteral("s2 \\n s2".to_string())).with_empty_span()),
expr_from_projection(&select.projection[1])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("s3 \\\n s3".to_string())),
&Expr::Value((Value::EscapedStringLiteral("s3 \\\n s3".to_string())).with_empty_span()),
expr_from_projection(&select.projection[2])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("s4 \\\\n s4".to_string())),
&Expr::Value((Value::EscapedStringLiteral("s4 \\\\n s4".to_string())).with_empty_span()),
expr_from_projection(&select.projection[3])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("'".to_string())),
&Expr::Value((Value::EscapedStringLiteral("'".to_string())).with_empty_span()),
expr_from_projection(&select.projection[4])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("foo \\".to_string())),
&Expr::Value((Value::EscapedStringLiteral("foo \\".to_string())).with_empty_span()),
expr_from_projection(&select.projection[5])
);
@ -3144,31 +3191,31 @@ fn parse_escaped_literal_string() {
let select = pg_and_generic().verified_only_select_with_canonical(sql, canonical);
assert_eq!(7, select.projection.len());
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("\u{0001}".to_string())),
&Expr::Value((Value::EscapedStringLiteral("\u{0001}".to_string())).with_empty_span()),
expr_from_projection(&select.projection[0])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("\u{10ffff}".to_string())),
&Expr::Value((Value::EscapedStringLiteral("\u{10ffff}".to_string())).with_empty_span()),
expr_from_projection(&select.projection[1])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("\u{000c}".to_string())),
&Expr::Value((Value::EscapedStringLiteral("\u{000c}".to_string())).with_empty_span()),
expr_from_projection(&select.projection[2])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("%".to_string())),
&Expr::Value((Value::EscapedStringLiteral("%".to_string())).with_empty_span()),
expr_from_projection(&select.projection[3])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("\u{0002}".to_string())),
&Expr::Value((Value::EscapedStringLiteral("\u{0002}".to_string())).with_empty_span()),
expr_from_projection(&select.projection[4])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("%".to_string())),
&Expr::Value((Value::EscapedStringLiteral("%".to_string())).with_empty_span()),
expr_from_projection(&select.projection[5])
);
assert_eq!(
&Expr::Value(Value::EscapedStringLiteral("%".to_string())),
&Expr::Value((Value::EscapedStringLiteral("%".to_string())).with_empty_span()),
expr_from_projection(&select.projection[6])
);
@ -3310,7 +3357,9 @@ fn parse_custom_operator() {
"pg_catalog".into(),
"~".into()
]),
right: Box::new(Expr::Value(Value::SingleQuotedString("^(table)$".into())))
right: Box::new(Expr::Value(
(Value::SingleQuotedString("^(table)$".into())).with_empty_span()
))
})
);
@ -3326,7 +3375,9 @@ fn parse_custom_operator() {
span: Span::empty(),
})),
op: BinaryOperator::PGCustomBinaryOperator(vec!["pg_catalog".into(), "~".into()]),
right: Box::new(Expr::Value(Value::SingleQuotedString("^(table)$".into())))
right: Box::new(Expr::Value(
(Value::SingleQuotedString("^(table)$".into())).with_empty_span()
))
})
);
@ -3342,7 +3393,9 @@ fn parse_custom_operator() {
span: Span::empty(),
})),
op: BinaryOperator::PGCustomBinaryOperator(vec!["~".into()]),
right: Box::new(Expr::Value(Value::SingleQuotedString("^(table)$".into())))
right: Box::new(Expr::Value(
(Value::SingleQuotedString("^(table)$".into())).with_empty_span()
))
})
);
}
@ -3428,9 +3481,9 @@ fn parse_create_role() {
assert_eq!(*bypassrls, Some(true));
assert_eq!(
*password,
Some(Password::Password(Expr::Value(Value::SingleQuotedString(
"abcdef".into()
))))
Some(Password::Password(Expr::Value(
(Value::SingleQuotedString("abcdef".into())).with_empty_span()
)))
);
assert_eq!(*superuser, Some(true));
assert_eq!(*create_db, Some(false));
@ -3439,7 +3492,9 @@ fn parse_create_role() {
assert_eq!(*connection_limit, None);
assert_eq!(
*valid_until,
Some(Expr::Value(Value::SingleQuotedString("2025-01-01".into())))
Some(Expr::Value(
(Value::SingleQuotedString("2025-01-01".into())).with_empty_span()
))
);
assert_eq_vec(&["role1", "role2"], in_role);
assert!(in_group.is_empty());
@ -3521,13 +3576,15 @@ fn parse_alter_role() {
RoleOption::Login(true),
RoleOption::Replication(true),
RoleOption::BypassRLS(true),
RoleOption::ConnectionLimit(Expr::Value(number("100"))),
RoleOption::ConnectionLimit(Expr::value(number("100"))),
RoleOption::Password({
Password::Password(Expr::Value(Value::SingleQuotedString("abcdef".into())))
Password::Password(Expr::Value(
(Value::SingleQuotedString("abcdef".into())).with_empty_span(),
))
}),
RoleOption::ValidUntil(Expr::Value(Value::SingleQuotedString(
"2025-01-01".into(),
)))
RoleOption::ValidUntil(Expr::Value(
(Value::SingleQuotedString("2025-01-01".into(),)).with_empty_span()
))
]
},
}
@ -3593,7 +3650,9 @@ fn parse_alter_role() {
quote_style: None,
span: Span::empty(),
}]),
config_value: SetConfigValue::Value(Expr::Value(number("100000"))),
config_value: SetConfigValue::Value(Expr::Value(
(number("100000")).with_empty_span()
)),
in_database: Some(ObjectName::from(vec![Ident {
value: "database_name".into(),
quote_style: None,
@ -3618,7 +3677,9 @@ fn parse_alter_role() {
quote_style: None,
span: Span::empty(),
}]),
config_value: SetConfigValue::Value(Expr::Value(number("100000"))),
config_value: SetConfigValue::Value(Expr::Value(
(number("100000")).with_empty_span()
)),
in_database: Some(ObjectName::from(vec![Ident {
value: "database_name".into(),
quote_style: None,
@ -3799,7 +3860,7 @@ fn parse_create_function() {
called_on_null: Some(FunctionCalledOnNull::Strict),
parallel: Some(FunctionParallel::Safe),
function_body: Some(CreateFunctionBody::AsBeforeOptions(Expr::Value(
Value::SingleQuotedString("select $1 + $2;".into())
(Value::SingleQuotedString("select $1 + $2;".into())).with_empty_span()
))),
if_not_exists: false,
using: None,
@ -3862,7 +3923,9 @@ fn parse_drop_function() {
mode: Some(ArgMode::In),
name: Some("b".into()),
data_type: DataType::Integer(None),
default_expr: Some(Expr::Value(Value::Number("1".parse().unwrap(), false))),
default_expr: Some(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)),
}
]),
}],
@ -3888,10 +3951,9 @@ fn parse_drop_function() {
mode: Some(ArgMode::In),
name: Some("b".into()),
data_type: DataType::Integer(None),
default_expr: Some(Expr::Value(Value::Number(
"1".parse().unwrap(),
false
))),
default_expr: Some(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)),
}
]),
},
@ -3907,10 +3969,9 @@ fn parse_drop_function() {
mode: Some(ArgMode::In),
name: Some("b".into()),
data_type: DataType::Integer(None),
default_expr: Some(Expr::Value(Value::Number(
"1".parse().unwrap(),
false
))),
default_expr: Some(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)),
}
]),
}
@ -3956,7 +4017,9 @@ fn parse_drop_procedure() {
mode: Some(ArgMode::In),
name: Some("b".into()),
data_type: DataType::Integer(None),
default_expr: Some(Expr::Value(Value::Number("1".parse().unwrap(), false))),
default_expr: Some(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)),
}
]),
}],
@ -3982,10 +4045,9 @@ fn parse_drop_procedure() {
mode: Some(ArgMode::In),
name: Some("b".into()),
data_type: DataType::Integer(None),
default_expr: Some(Expr::Value(Value::Number(
"1".parse().unwrap(),
false
))),
default_expr: Some(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)),
}
]),
},
@ -4001,10 +4063,9 @@ fn parse_drop_procedure() {
mode: Some(ArgMode::In),
name: Some("b".into()),
data_type: DataType::Integer(None),
default_expr: Some(Expr::Value(Value::Number(
"1".parse().unwrap(),
false
))),
default_expr: Some(Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)),
}
]),
}
@ -4041,36 +4102,48 @@ fn parse_dollar_quoted_string() {
};
assert_eq!(
&Expr::Value(Value::DollarQuotedString(DollarQuotedString {
&Expr::Value(
(Value::DollarQuotedString(DollarQuotedString {
tag: None,
value: "hello".into()
})),
}))
.with_empty_span()
),
expr_from_projection(&projection[0])
);
assert_eq!(
&Expr::Value(Value::DollarQuotedString(DollarQuotedString {
&Expr::Value(
(Value::DollarQuotedString(DollarQuotedString {
tag: Some("tag_name".into()),
value: "world".into()
})),
}))
.with_empty_span()
),
expr_from_projection(&projection[1])
);
assert_eq!(
&Expr::Value(Value::DollarQuotedString(DollarQuotedString {
&Expr::Value(
(Value::DollarQuotedString(DollarQuotedString {
tag: None,
value: "Foo$Bar".into()
})),
}))
.with_empty_span()
),
expr_from_projection(&projection[2])
);
assert_eq!(
projection[3],
SelectItem::ExprWithAlias {
expr: Expr::Value(Value::DollarQuotedString(DollarQuotedString {
expr: Expr::Value(
(Value::DollarQuotedString(DollarQuotedString {
tag: None,
value: "Foo$Bar".into(),
})),
}))
.with_empty_span()
),
alias: Ident {
value: "col_name".into(),
quote_style: None,
@ -4081,18 +4154,24 @@ fn parse_dollar_quoted_string() {
assert_eq!(
expr_from_projection(&projection[4]),
&Expr::Value(Value::DollarQuotedString(DollarQuotedString {
&Expr::Value(
(Value::DollarQuotedString(DollarQuotedString {
tag: None,
value: "".into()
})),
}))
.with_empty_span()
),
);
assert_eq!(
expr_from_projection(&projection[5]),
&Expr::Value(Value::DollarQuotedString(DollarQuotedString {
&Expr::Value(
(Value::DollarQuotedString(DollarQuotedString {
tag: Some("tag_name".into()),
value: "".into()
})),
}))
.with_empty_span()
),
);
}
@ -4438,7 +4517,7 @@ fn test_simple_postgres_insert_with_alias() {
explicit_row: false,
rows: vec![vec![
Expr::Identifier(Ident::new("DEFAULT")),
Expr::Value(Value::Number("123".to_string(), false))
Expr::Value((Value::Number("123".to_string(), false)).with_empty_span())
]]
})),
order_by: None,
@ -4508,10 +4587,10 @@ fn test_simple_postgres_insert_with_alias() {
explicit_row: false,
rows: vec![vec![
Expr::Identifier(Ident::new("DEFAULT")),
Expr::Value(Value::Number(
bigdecimal::BigDecimal::new(123.into(), 0),
false
))
Expr::Value(
(Value::Number(bigdecimal::BigDecimal::new(123.into(), 0), false))
.with_empty_span()
)
]]
})),
order_by: None,
@ -4580,7 +4659,9 @@ fn test_simple_insert_with_quoted_alias() {
explicit_row: false,
rows: vec![vec![
Expr::Identifier(Ident::new("DEFAULT")),
Expr::Value(Value::SingleQuotedString("0123".to_string()))
Expr::Value(
(Value::SingleQuotedString("0123".to_string())).with_empty_span()
)
]]
})),
order_by: None,
@ -4650,18 +4731,18 @@ fn parse_at_time_zone() {
}),
time_zone: Box::new(Expr::Cast {
kind: CastKind::DoubleColon,
expr: Box::new(Expr::Value(Value::SingleQuotedString(
"America/Los_Angeles".to_owned(),
))),
expr: Box::new(Expr::Value(
Value::SingleQuotedString("America/Los_Angeles".to_owned()).with_empty_span(),
)),
data_type: DataType::Text,
format: None,
}),
}),
op: BinaryOperator::Plus,
right: Box::new(Expr::Interval(Interval {
value: Box::new(Expr::Value(Value::SingleQuotedString(
"23 hours".to_owned(),
))),
value: Box::new(Expr::Value(
Value::SingleQuotedString("23 hours".to_owned()).with_empty_span(),
)),
leading_field: None,
leading_precision: None,
last_field: None,
@ -4685,11 +4766,13 @@ fn parse_create_table_with_options() {
vec![
SqlOption::KeyValue {
key: "foo".into(),
value: Expr::Value(Value::SingleQuotedString("bar".into())),
value: Expr::Value(
(Value::SingleQuotedString("bar".into())).with_empty_span()
),
},
SqlOption::KeyValue {
key: "a".into(),
value: Expr::Value(number("123")),
value: Expr::value(number("123")),
},
],
with_options
@ -4735,7 +4818,10 @@ fn test_table_unnest_with_ordinality() {
#[test]
fn test_escaped_string_literal() {
match pg().verified_expr(r#"E'\n'"#) {
Expr::Value(Value::EscapedStringLiteral(s)) => {
Expr::Value(ValueWithSpan {
value: Value::EscapedStringLiteral(s),
span: _,
}) => {
assert_eq!("\n", s);
}
_ => unreachable!(),
@ -4790,7 +4876,7 @@ fn parse_create_after_update_trigger_with_condition() {
Ident::new("balance"),
])),
op: BinaryOperator::Gt,
right: Box::new(Expr::Value(number("10000"))),
right: Box::new(Expr::value(number("10000"))),
}))),
exec_body: TriggerExecBody {
exec_type: TriggerExecBodyType::Function,
@ -5155,7 +5241,7 @@ fn parse_trigger_related_functions() {
return_type: Some(DataType::Trigger),
function_body: Some(
CreateFunctionBody::AsBeforeOptions(
Expr::Value(
Expr::Value((
Value::DollarQuotedString(
DollarQuotedString {
value: "\n BEGIN\n -- Check that empname and salary are given\n IF NEW.empname IS NULL THEN\n RAISE EXCEPTION 'empname cannot be null';\n END IF;\n IF NEW.salary IS NULL THEN\n RAISE EXCEPTION '% cannot have null salary', NEW.empname;\n END IF;\n\n -- Who works for us when they must pay for it?\n IF NEW.salary < 0 THEN\n RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;\n END IF;\n\n -- Remember who changed the payroll when\n NEW.last_date := current_timestamp;\n NEW.last_user := current_user;\n RETURN NEW;\n END;\n ".to_owned(),
@ -5163,8 +5249,8 @@ fn parse_trigger_related_functions() {
"emp_stamp".to_owned(),
),
},
),
),
)
).with_empty_span()),
),
),
behavior: None,
@ -5231,7 +5317,10 @@ fn test_unicode_string_literal() {
];
for (input, expected) in pairs {
match pg_and_generic().verified_expr(input) {
Expr::Value(Value::UnicodeStringLiteral(s)) => {
Expr::Value(ValueWithSpan {
value: Value::UnicodeStringLiteral(s),
span: _,
}) => {
assert_eq!(expected, s);
}
_ => unreachable!(),
@ -5250,10 +5339,14 @@ fn check_arrow_precedence(sql: &str, arrow_operator: BinaryOperator) {
span: Span::empty(),
})),
op: arrow_operator,
right: Box::new(Expr::Value(Value::SingleQuotedString("bar".to_string()))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("bar".to_string())).with_empty_span()
)),
}),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(Value::SingleQuotedString("spam".to_string()))),
right: Box::new(Expr::Value(
(Value::SingleQuotedString("spam".to_string())).with_empty_span()
)),
}
)
}
@ -5283,7 +5376,9 @@ fn arrow_cast_precedence() {
op: BinaryOperator::Arrow,
right: Box::new(Expr::Cast {
kind: CastKind::DoubleColon,
expr: Box::new(Expr::Value(Value::SingleQuotedString("bar".to_string()))),
expr: Box::new(Expr::Value(
(Value::SingleQuotedString("bar".to_string())).with_empty_span()
)),
data_type: DataType::Text,
format: None,
}),
@ -5410,7 +5505,7 @@ fn parse_bitstring_literal() {
assert_eq!(
select.projection,
vec![SelectItem::UnnamedExpr(Expr::Value(
Value::SingleQuotedByteStringLiteral("111".to_string())
(Value::SingleQuotedByteStringLiteral("111".to_string())).with_empty_span()
))]
);
}

View file

@ -208,7 +208,7 @@ fn test_redshift_json_path() {
path: JsonPath {
path: vec![
JsonPathElem::Bracket {
key: Expr::Value(number("0"))
key: Expr::value(number("0"))
},
JsonPathElem::Dot {
key: "o_orderkey".to_string(),
@ -231,10 +231,12 @@ fn test_redshift_json_path() {
path: JsonPath {
path: vec![
JsonPathElem::Bracket {
key: Expr::Value(number("0"))
key: Expr::value(number("0"))
},
JsonPathElem::Bracket {
key: Expr::Value(Value::SingleQuotedString("id".to_owned()))
key: Expr::Value(
(Value::SingleQuotedString("id".to_owned())).with_empty_span()
)
}
]
}
@ -255,10 +257,12 @@ fn test_redshift_json_path() {
path: JsonPath {
path: vec![
JsonPathElem::Bracket {
key: Expr::Value(number("0"))
key: Expr::value(number("0"))
},
JsonPathElem::Bracket {
key: Expr::Value(Value::SingleQuotedString("id".to_owned()))
key: Expr::Value(
(Value::SingleQuotedString("id".to_owned())).with_empty_span()
)
}
]
}
@ -279,7 +283,7 @@ fn test_redshift_json_path() {
path: JsonPath {
path: vec![
JsonPathElem::Bracket {
key: Expr::Value(number("0"))
key: Expr::value(number("0"))
},
JsonPathElem::Dot {
key: "id".to_string(),
@ -306,7 +310,7 @@ fn test_parse_json_path_from() {
&Some(JsonPath {
path: vec![
JsonPathElem::Bracket {
key: Expr::Value(number("0"))
key: Expr::value(number("0"))
},
JsonPathElem::Dot {
key: "a".to_string(),
@ -330,14 +334,16 @@ fn test_parse_json_path_from() {
&Some(JsonPath {
path: vec![
JsonPathElem::Bracket {
key: Expr::Value(number("0"))
key: Expr::value(number("0"))
},
JsonPathElem::Dot {
key: "a".to_string(),
quoted: false
},
JsonPathElem::Bracket {
key: Expr::Value(Value::Number("1".parse().unwrap(), false))
key: Expr::Value(
(Value::Number("1".parse().unwrap(), false)).with_empty_span()
)
},
JsonPathElem::Dot {
key: "b".to_string(),

View file

@ -570,8 +570,8 @@ fn test_snowflake_create_table_with_autoincrement_columns() {
IdentityProperty {
parameters: Some(IdentityPropertyFormatKind::FunctionCall(
IdentityParameters {
seed: Expr::Value(number("100")),
increment: Expr::Value(number("1")),
seed: Expr::value(number("100")),
increment: Expr::value(number("1")),
}
)),
order: Some(IdentityPropertyOrder::NoOrder),
@ -602,8 +602,12 @@ fn test_snowflake_create_table_with_autoincrement_columns() {
parameters: Some(
IdentityPropertyFormatKind::StartAndIncrement(
IdentityParameters {
seed: Expr::Value(number("100")),
increment: Expr::Value(number("1")),
seed: Expr::Value(
(number("100")).with_empty_span()
),
increment: Expr::Value(
(number("1")).with_empty_span()
),
}
)
),
@ -1108,9 +1112,9 @@ fn parse_semi_structured_data_traversal() {
path: JsonPath {
path: vec![JsonPathElem::Bracket {
key: Expr::BinaryOp {
left: Box::new(Expr::Value(number("2"))),
left: Box::new(Expr::value(number("2"))),
op: BinaryOperator::Plus,
right: Box::new(Expr::Value(number("2")))
right: Box::new(Expr::value(number("2")))
},
}]
},
@ -1188,7 +1192,7 @@ fn parse_semi_structured_data_traversal() {
quoted: false,
},
JsonPathElem::Bracket {
key: Expr::Value(number("0")),
key: Expr::value(number("0")),
},
JsonPathElem::Dot {
key: "bar".to_owned(),
@ -1210,7 +1214,7 @@ fn parse_semi_structured_data_traversal() {
path: JsonPath {
path: vec![
JsonPathElem::Bracket {
key: Expr::Value(number("0")),
key: Expr::value(number("0")),
},
JsonPathElem::Dot {
key: "foo".to_owned(),
@ -1276,7 +1280,7 @@ fn parse_semi_structured_data_traversal() {
}),
path: JsonPath {
path: vec![JsonPathElem::Bracket {
key: Expr::Value(number("1"))
key: Expr::value(number("1"))
}]
}
}
@ -1661,13 +1665,13 @@ fn parse_snowflake_declare_result_set() {
(
"DECLARE res RESULTSET DEFAULT 42",
"res",
Some(DeclareAssignment::Default(Expr::Value(number("42")).into())),
Some(DeclareAssignment::Default(Expr::value(number("42")).into())),
),
(
"DECLARE res RESULTSET := 42",
"res",
Some(DeclareAssignment::DuckAssignment(
Expr::Value(number("42")).into(),
Expr::value(number("42")).into(),
)),
),
("DECLARE res RESULTSET", "res", None),
@ -1717,8 +1721,8 @@ fn parse_snowflake_declare_exception() {
"ex",
Some(DeclareAssignment::Expr(
Expr::Tuple(vec![
Expr::Value(number("42")),
Expr::Value(Value::SingleQuotedString("ERROR".to_string())),
Expr::value(number("42")),
Expr::Value((Value::SingleQuotedString("ERROR".to_string())).with_empty_span()),
])
.into(),
)),
@ -1754,13 +1758,13 @@ fn parse_snowflake_declare_variable() {
"DECLARE profit TEXT DEFAULT 42",
"profit",
Some(DataType::Text),
Some(DeclareAssignment::Default(Expr::Value(number("42")).into())),
Some(DeclareAssignment::Default(Expr::value(number("42")).into())),
),
(
"DECLARE profit DEFAULT 42",
"profit",
None,
Some(DeclareAssignment::Default(Expr::Value(number("42")).into())),
Some(DeclareAssignment::Default(Expr::value(number("42")).into())),
),
("DECLARE profit TEXT", "profit", Some(DataType::Text), None),
("DECLARE profit", "profit", None, None),
@ -2509,10 +2513,14 @@ fn test_snowflake_trim() {
let select = snowflake().verified_only_select(sql_only_select);
assert_eq!(
&Expr::Trim {
expr: Box::new(Expr::Value(Value::SingleQuotedString("xyz".to_owned()))),
expr: Box::new(Expr::Value(
(Value::SingleQuotedString("xyz".to_owned())).with_empty_span()
)),
trim_where: None,
trim_what: None,
trim_characters: Some(vec![Expr::Value(Value::SingleQuotedString("a".to_owned()))]),
trim_characters: Some(vec![Expr::Value(
(Value::SingleQuotedString("a".to_owned())).with_empty_span()
)]),
},
expr_from_projection(only(&select.projection))
);
@ -2530,7 +2538,7 @@ fn test_number_placeholder() {
let sql_only_select = "SELECT :1";
let select = snowflake().verified_only_select(sql_only_select);
assert_eq!(
&Expr::Value(Value::Placeholder(":1".into())),
&Expr::Value((Value::Placeholder(":1".into())).with_empty_span()),
expr_from_projection(only(&select.projection))
);
@ -2676,7 +2684,7 @@ fn parse_comma_outer_join() {
"myudf",
[Expr::UnaryOp {
op: UnaryOperator::Plus,
expr: Box::new(Expr::Value(number("42")))
expr: Box::new(Expr::value(number("42")))
}]
)),
})

View file

@ -369,7 +369,9 @@ fn test_placeholder() {
let ast = sqlite().verified_only_select(sql);
assert_eq!(
ast.projection[0],
UnnamedExpr(Expr::Value(Value::Placeholder("@xxx".into()))),
UnnamedExpr(Expr::Value(
(Value::Placeholder("@xxx".into())).with_empty_span()
)),
);
}
@ -446,7 +448,11 @@ fn parse_attach_database() {
match verified_stmt {
Statement::AttachDatabase {
schema_name,
database_file_name: Expr::Value(Value::SingleQuotedString(literal_name)),
database_file_name:
Expr::Value(ValueWithSpan {
value: Value::SingleQuotedString(literal_name),
span: _,
}),
database: true,
} => {
assert_eq!(schema_name.value, "test");
@ -469,8 +475,8 @@ fn parse_update_tuple_row_values() {
ObjectName::from(vec![Ident::new("b"),]),
]),
value: Expr::Tuple(vec![
Expr::Value(Value::Number("1".parse().unwrap(), false)),
Expr::Value(Value::Number("2".parse().unwrap(), false))
Expr::Value((Value::Number("1".parse().unwrap(), false)).with_empty_span()),
Expr::Value((Value::Number("2".parse().unwrap(), false)).with_empty_span())
])
}],
selection: None,
@ -530,7 +536,12 @@ fn test_dollar_identifier_as_placeholder() {
Expr::BinaryOp { op, left, right } => {
assert_eq!(op, BinaryOperator::Eq);
assert_eq!(left, Box::new(Expr::Identifier(Ident::new("id"))));
assert_eq!(right, Box::new(Expr::Value(Placeholder("$id".to_string()))));
assert_eq!(
right,
Box::new(Expr::Value(
(Placeholder("$id".to_string())).with_empty_span()
))
);
}
_ => unreachable!(),
}
@ -540,7 +551,12 @@ fn test_dollar_identifier_as_placeholder() {
Expr::BinaryOp { op, left, right } => {
assert_eq!(op, BinaryOperator::Eq);
assert_eq!(left, Box::new(Expr::Identifier(Ident::new("id"))));
assert_eq!(right, Box::new(Expr::Value(Placeholder("$$".to_string()))));
assert_eq!(
right,
Box::new(Expr::Value(
(Placeholder("$$".to_string())).with_empty_span()
))
);
}
_ => unreachable!(),
}