This is an automated email from the ASF dual-hosted git repository.
iffyio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 9020385c Add span for `Expr::TypedString` (#1919)
9020385c is described below
commit 9020385c027239979adbef5506c7be4a07cc594c
Author: feral-dot-io <[email protected]>
AuthorDate: Thu Jul 3 16:24:51 2025 +0000
Add span for `Expr::TypedString` (#1919)
---
src/ast/mod.rs | 2 +-
src/ast/spans.rs | 1 -
src/parser/mod.rs | 5 +-
tests/sqlparser_bigquery.rs | 77 +++++++++++++++++++++++-------
tests/sqlparser_common.rs | 106 +++++++++++++++++++++++++++++++++---------
tests/sqlparser_databricks.rs | 6 ++-
tests/sqlparser_postgres.rs | 5 +-
7 files changed, 155 insertions(+), 47 deletions(-)
diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index 9e502260..d7e342bd 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -996,7 +996,7 @@ pub enum Expr {
data_type: DataType,
/// The value of the constant.
/// Hint: you can unwrap the string value using `value.into_string()`.
- value: Value,
+ value: ValueWithSpan,
},
/// Scalar function call e.g. `LEFT(foo, 5)`
Function(Function),
diff --git a/src/ast/spans.rs b/src/ast/spans.rs
index f8ffeb54..0895b844 100644
--- a/src/ast/spans.rs
+++ b/src/ast/spans.rs
@@ -1415,7 +1415,6 @@ impl Spanned for AssignmentTarget {
/// f.e. `IS NULL <expr>` reports as `<expr>::span`.
///
/// Missing spans:
-/// - [Expr::TypedString] # missing span for data_type
/// - [Expr::MatchAgainst] # MySQL specific
/// - [Expr::RLike] # MySQL specific
/// - [Expr::Struct] # BigQuery specific
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index bfd75385..f38a360e 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -1521,7 +1521,7 @@ impl<'a> Parser<'a> {
DataType::Custom(..) => parser_err!("dummy", loc),
data_type => Ok(Expr::TypedString {
data_type,
- value: parser.parse_value()?.value,
+ value: parser.parse_value()?,
}),
}
})?;
@@ -1708,10 +1708,9 @@ impl<'a> Parser<'a> {
}
fn parse_geometric_type(&mut self, kind: GeometricTypeKind) ->
Result<Expr, ParserError> {
- let value: Value = self.parse_value()?.value;
Ok(Expr::TypedString {
data_type: DataType::GeometricType(kind),
- value,
+ value: self.parse_value()?,
})
}
diff --git a/tests/sqlparser_bigquery.rs b/tests/sqlparser_bigquery.rs
index 2bcdb4e5..2ba54d3e 100644
--- a/tests/sqlparser_bigquery.rs
+++ b/tests/sqlparser_bigquery.rs
@@ -906,7 +906,10 @@ fn parse_typed_struct_syntax_bigquery() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::Datetime(None),
- value: Value::SingleQuotedString("1999-01-01
01:23:34.45".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1999-01-01
01:23:34.45".into()),
+ span: Span::empty(),
+ },
}],
fields: vec![StructField {
field_name: None,
@@ -965,9 +968,12 @@ fn parse_typed_struct_syntax_bigquery() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::JSON,
- value: Value::SingleQuotedString(
- r#"{"class" : {"students" : [{"name" : "Jane"}]}}"#.into()
- )
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(
+ r#"{"class" : {"students" : [{"name" :
"Jane"}]}}"#.into()
+ ),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -998,7 +1004,12 @@ fn parse_typed_struct_syntax_bigquery() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::Timestamp(None, TimezoneInfo::None),
- value: Value::SingleQuotedString("2008-12-25 15:30:00
America/Los_Angeles".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(
+ "2008-12-25 15:30:00 America/Los_Angeles".into()
+ ),
+ span: Span::empty(),
+ },
}],
fields: vec![StructField {
field_name: None,
@@ -1013,7 +1024,10 @@ fn parse_typed_struct_syntax_bigquery() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::Time(None, TimezoneInfo::None),
- value: Value::SingleQuotedString("15:30:00".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("15:30:00".into()),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -1031,7 +1045,10 @@ fn parse_typed_struct_syntax_bigquery() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::Numeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString("1".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1".into()),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -1045,7 +1062,10 @@ fn parse_typed_struct_syntax_bigquery() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString("1".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1".into()),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -1219,7 +1239,10 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::Datetime(None),
- value: Value::SingleQuotedString("1999-01-01
01:23:34.45".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1999-01-01
01:23:34.45".into()),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -1278,9 +1301,12 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::JSON,
- value: Value::SingleQuotedString(
- r#"{"class" : {"students" : [{"name" : "Jane"}]}}"#.into()
- )
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(
+ r#"{"class" : {"students" : [{"name" :
"Jane"}]}}"#.into()
+ ),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -1311,7 +1337,12 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::Timestamp(None, TimezoneInfo::None),
- value: Value::SingleQuotedString("2008-12-25 15:30:00
America/Los_Angeles".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(
+ "2008-12-25 15:30:00 America/Los_Angeles".into()
+ ),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -1326,7 +1357,10 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::Time(None, TimezoneInfo::None),
- value: Value::SingleQuotedString("15:30:00".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("15:30:00".into()),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -1344,7 +1378,10 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::Numeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString("1".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1".into()),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -1358,7 +1395,10 @@ fn parse_typed_struct_syntax_bigquery_and_generic() {
&Expr::Struct {
values: vec![Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString("1".into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1".into()),
+ span: Span::empty(),
+ }
}],
fields: vec![StructField {
field_name: None,
@@ -2393,7 +2433,10 @@ fn test_triple_quote_typed_strings() {
assert_eq!(
Expr::TypedString {
data_type: DataType::JSON,
- value: Value::TripleDoubleQuotedString(r#"{"foo":"bar's"}"#.into())
+ value: ValueWithSpan {
+ value:
Value::TripleDoubleQuotedString(r#"{"foo":"bar's"}"#.into()),
+ span: Span::empty(),
+ }
},
expr
);
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 9ca985b3..ac461bb2 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -5851,7 +5851,10 @@ fn parse_literal_date() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::Date,
- value: Value::SingleQuotedString("1999-01-01".into()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1999-01-01".into()),
+ span: Span::empty(),
+ }
},
expr_from_projection(only(&select.projection)),
);
@@ -5864,7 +5867,10 @@ fn parse_literal_time() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::Time(None, TimezoneInfo::None),
- value: Value::SingleQuotedString("01:23:34".into()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("01:23:34".into()),
+ span: Span::empty(),
+ },
},
expr_from_projection(only(&select.projection)),
);
@@ -5877,7 +5883,10 @@ fn parse_literal_datetime() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::Datetime(None),
- value: Value::SingleQuotedString("1999-01-01 01:23:34.45".into()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1999-01-01
01:23:34.45".into()),
+ span: Span::empty(),
+ },
},
expr_from_projection(only(&select.projection)),
);
@@ -5890,7 +5899,10 @@ fn parse_literal_timestamp_without_time_zone() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::Timestamp(None, TimezoneInfo::None),
- value: Value::SingleQuotedString("1999-01-01 01:23:34".into()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1999-01-01 01:23:34".into()),
+ span: Span::empty(),
+ },
},
expr_from_projection(only(&select.projection)),
);
@@ -5905,7 +5917,10 @@ fn parse_literal_timestamp_with_time_zone() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::Timestamp(None, TimezoneInfo::Tz),
- value: Value::SingleQuotedString("1999-01-01 01:23:34Z".into()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1999-01-01
01:23:34Z".into()),
+ span: Span::empty(),
+ },
},
expr_from_projection(only(&select.projection)),
);
@@ -6477,8 +6492,9 @@ fn parse_json_keyword() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::JSON,
- value: Value::SingleQuotedString(
- r#"{
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(
+ r#"{
"id": 10,
"type": "fruit",
"name": "apple",
@@ -6498,8 +6514,10 @@ fn parse_json_keyword() {
]
}
}"#
- .to_string()
- )
+ .to_string()
+ ),
+ span: Span::empty(),
+ }
},
expr_from_projection(only(&select.projection)),
);
@@ -6511,7 +6529,10 @@ fn parse_typed_strings() {
assert_eq!(
Expr::TypedString {
data_type: DataType::JSON,
- value: Value::SingleQuotedString(r#"{"foo":"bar"}"#.into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(r#"{"foo":"bar"}"#.into()),
+ span: Span::empty(),
+ }
},
expr
);
@@ -6529,7 +6550,10 @@ fn parse_bignumeric_keyword() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString(r#"0"#.into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(r#"0"#.into()),
+ span: Span::empty(),
+ }
},
expr_from_projection(only(&select.projection)),
);
@@ -6540,7 +6564,10 @@ fn parse_bignumeric_keyword() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString(r#"123456"#.into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(r#"123456"#.into()),
+ span: Span::empty(),
+ }
},
expr_from_projection(only(&select.projection)),
);
@@ -6551,7 +6578,10 @@ fn parse_bignumeric_keyword() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString(r#"-3.14"#.into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(r#"-3.14"#.into()),
+ span: Span::empty(),
+ }
},
expr_from_projection(only(&select.projection)),
);
@@ -6562,7 +6592,10 @@ fn parse_bignumeric_keyword() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString(r#"-0.54321"#.into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(r#"-0.54321"#.into()),
+ span: Span::empty(),
+ }
},
expr_from_projection(only(&select.projection)),
);
@@ -6573,7 +6606,10 @@ fn parse_bignumeric_keyword() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString(r#"1.23456e05"#.into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(r#"1.23456e05"#.into()),
+ span: Span::empty(),
+ }
},
expr_from_projection(only(&select.projection)),
);
@@ -6584,7 +6620,10 @@ fn parse_bignumeric_keyword() {
assert_eq!(
&Expr::TypedString {
data_type: DataType::BigNumeric(ExactNumberInfo::None),
- value: Value::SingleQuotedString(r#"-9.876e-3"#.into())
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString(r#"-9.876e-3"#.into()),
+ span: Span::empty(),
+ }
},
expr_from_projection(only(&select.projection)),
);
@@ -14833,7 +14872,10 @@ fn test_geometry_type() {
all_dialects_where(|d|
d.supports_geometric_types()).verified_expr(sql),
Expr::TypedString {
data_type: DataType::GeometricType(GeometricTypeKind::Point),
- value: Value::SingleQuotedString("1,2".to_string()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1,2".to_string()),
+ span: Span::empty(),
+ },
}
);
@@ -14842,7 +14884,10 @@ fn test_geometry_type() {
all_dialects_where(|d|
d.supports_geometric_types()).verified_expr(sql),
Expr::TypedString {
data_type: DataType::GeometricType(GeometricTypeKind::Line),
- value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ span: Span::empty(),
+ },
}
);
@@ -14851,7 +14896,10 @@ fn test_geometry_type() {
all_dialects_where(|d|
d.supports_geometric_types()).verified_expr(sql),
Expr::TypedString {
data_type:
DataType::GeometricType(GeometricTypeKind::GeometricPath),
- value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ span: Span::empty(),
+ },
}
);
let sql = "box '1,2,3,4'";
@@ -14859,7 +14907,10 @@ fn test_geometry_type() {
all_dialects_where(|d|
d.supports_geometric_types()).verified_expr(sql),
Expr::TypedString {
data_type:
DataType::GeometricType(GeometricTypeKind::GeometricBox),
- value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ span: Span::empty(),
+ },
}
);
@@ -14868,7 +14919,10 @@ fn test_geometry_type() {
all_dialects_where(|d|
d.supports_geometric_types()).verified_expr(sql),
Expr::TypedString {
data_type: DataType::GeometricType(GeometricTypeKind::Circle),
- value: Value::SingleQuotedString("1,2,3".to_string()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1,2,3".to_string()),
+ span: Span::empty(),
+ },
}
);
@@ -14877,7 +14931,10 @@ fn test_geometry_type() {
all_dialects_where(|d|
d.supports_geometric_types()).verified_expr(sql),
Expr::TypedString {
data_type: DataType::GeometricType(GeometricTypeKind::Polygon),
- value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ span: Span::empty(),
+ },
}
);
let sql = "lseg '1,2,3,4'";
@@ -14885,7 +14942,10 @@ fn test_geometry_type() {
all_dialects_where(|d|
d.supports_geometric_types()).verified_expr(sql),
Expr::TypedString {
data_type: DataType::GeometricType(GeometricTypeKind::LineSegment),
- value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("1,2,3,4".to_string()),
+ span: Span::empty(),
+ },
}
);
}
diff --git a/tests/sqlparser_databricks.rs b/tests/sqlparser_databricks.rs
index baf279fa..a27e0699 100644
--- a/tests/sqlparser_databricks.rs
+++ b/tests/sqlparser_databricks.rs
@@ -19,6 +19,7 @@ use sqlparser::ast::helpers::attached_token::AttachedToken;
use sqlparser::ast::*;
use sqlparser::dialect::{DatabricksDialect, GenericDialect};
use sqlparser::parser::ParserError;
+use sqlparser::tokenizer::Span;
use test_utils::*;
#[macro_use]
@@ -328,7 +329,10 @@ fn data_type_timestamp_ntz() {
databricks().verified_expr("TIMESTAMP_NTZ '2025-03-29T18:52:00'"),
Expr::TypedString {
data_type: DataType::TimestampNtz,
- value: Value::SingleQuotedString("2025-03-29T18:52:00".to_owned())
+ value: ValueWithSpan {
+ value:
Value::SingleQuotedString("2025-03-29T18:52:00".to_owned()),
+ span: Span::empty(),
+ }
}
);
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 16ba5f23..db5c1611 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -5257,7 +5257,10 @@ fn parse_at_time_zone() {
left: Box::new(Expr::AtTimeZone {
timestamp: Box::new(Expr::TypedString {
data_type: DataType::Timestamp(None, TimezoneInfo::None),
- value: Value::SingleQuotedString("2001-09-28
01:00".to_string()),
+ value: ValueWithSpan {
+ value: Value::SingleQuotedString("2001-09-28
01:00".to_string()),
+ span: Span::empty(),
+ },
}),
time_zone: Box::new(Expr::Cast {
kind: CastKind::DoubleColon,
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]