Skip to content

Commit 45776cb

Browse files
committed
Store spans for Value expressions
1 parent 3ace97c commit 45776cb

File tree

4 files changed

+118
-86
lines changed

4 files changed

+118
-86
lines changed

src/ast/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub use self::trigger::{
8686

8787
pub use self::value::{
8888
escape_double_quote_string, escape_quoted_string, DateTimeField, DollarQuotedString,
89-
NormalizationForm, TrimWhereField, Value,
89+
NormalizationForm, TrimWhereField, Value, ValueWrapper,
9090
};
9191

9292
use crate::ast::helpers::key_value_options::KeyValueOptions;
@@ -892,7 +892,7 @@ pub enum Expr {
892892
/// Nested expression e.g. `(foo > bar)` or `(1)`
893893
Nested(Box<Expr>),
894894
/// A literal value, such as string, number, date or NULL
895-
Value(Value),
895+
Value(ValueWrapper),
896896
/// <https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html>
897897
IntroducedString {
898898
introducer: String,
@@ -8733,9 +8733,9 @@ mod tests {
87338733
#[test]
87348734
fn test_interval_display() {
87358735
let interval = Expr::Interval(Interval {
8736-
value: Box::new(Expr::Value(Value::SingleQuotedString(String::from(
8737-
"123:45.67",
8738-
)))),
8736+
value: Box::new(Expr::Value(
8737+
Value::SingleQuotedString(String::from("123:45.67")).with_empty_span(),
8738+
)),
87398739
leading_field: Some(DateTimeField::Minute),
87408740
leading_precision: Some(10),
87418741
last_field: Some(DateTimeField::Second),
@@ -8747,7 +8747,9 @@ mod tests {
87478747
);
87488748

87498749
let interval = Expr::Interval(Interval {
8750-
value: Box::new(Expr::Value(Value::SingleQuotedString(String::from("5")))),
8750+
value: Box::new(Expr::Value(
8751+
Value::SingleQuotedString(String::from("5")).with_empty_span(),
8752+
)),
87518753
leading_field: Some(DateTimeField::Second),
87528754
leading_precision: Some(1),
87538755
last_field: None,

src/ast/spans.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,7 @@ use core::iter;
2121
use crate::tokenizer::Span;
2222

2323
use super::{
24-
dcl::SecondaryRoles, AccessExpr, AlterColumnOperation, AlterIndexOperation,
25-
AlterTableOperation, Array, Assignment, AssignmentTarget, CloseCursor, ClusteredIndex,
26-
ColumnDef, ColumnOption, ColumnOptionDef, ConflictTarget, ConnectBy, ConstraintCharacteristics,
27-
CopySource, CreateIndex, CreateTable, CreateTableOptions, Cte, Delete, DoUpdate,
28-
ExceptSelectItem, ExcludeSelectItem, Expr, ExprWithAlias, Fetch, FromTable, Function,
29-
FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList, FunctionArguments,
30-
GroupByExpr, HavingBound, IlikeSelectItem, Insert, Interpolate, InterpolateExpr, Join,
31-
JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, MatchRecognizePattern,
32-
Measure, NamedWindowDefinition, ObjectName, ObjectNamePart, Offset, OnConflict,
33-
OnConflictAction, OnInsert, OrderBy, OrderByExpr, Partition, PivotValueSource,
34-
ProjectionSelect, Query, ReferentialAction, RenameSelectItem, ReplaceSelectElement,
35-
ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SqlOption, Statement, Subscript,
36-
SymbolDefinition, TableAlias, TableAliasColumnDef, TableConstraint, TableFactor, TableObject,
37-
TableOptionsClustered, TableWithJoins, UpdateTableFromKind, Use, Value, Values, ViewColumnDef,
38-
WildcardAdditionalOptions, With, WithFill,
24+
dcl::SecondaryRoles, value::ValueWrapper, 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, 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
3925
};
4026

4127
/// Given an iterator of spans, return the [Span::union] of all spans.
@@ -1974,10 +1960,14 @@ impl Spanned for TableAliasColumnDef {
19741960
}
19751961
}
19761962

1977-
/// # missing span
1978-
///
1979-
/// The span of a `Value` is currently not implemented, as doing so
1980-
/// requires a breaking changes, which may be done in a future release.
1963+
1964+
impl Spanned for ValueWrapper {
1965+
fn span(&self) -> Span {
1966+
self.span
1967+
}
1968+
}
1969+
1970+
/// The span is stored in the `ValueWrapper` struct
19811971
impl Spanned for Value {
19821972
fn span(&self) -> Span {
19831973
Span::empty() // # todo: Value needs to store spans before this is possible

src/ast/value.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,25 @@ use bigdecimal::BigDecimal;
2626
#[cfg(feature = "serde")]
2727
use serde::{Deserialize, Serialize};
2828

29-
use crate::ast::Ident;
29+
use crate::{ast::Ident, tokenizer::Span};
3030
#[cfg(feature = "visitor")]
3131
use sqlparser_derive::{Visit, VisitMut};
3232

33+
/// Primitive SQL values such as number and string
34+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
35+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
36+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
37+
pub struct ValueWrapper {
38+
pub value: Value,
39+
pub span: Span,
40+
}
41+
42+
impl From<ValueWrapper> for Value {
43+
fn from(value: ValueWrapper) -> Self {
44+
value.value
45+
}
46+
}
47+
3348
/// Primitive SQL values such as number and string
3449
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3550
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -97,6 +112,13 @@ pub enum Value {
97112
Placeholder(String),
98113
}
99114

115+
impl ValueWrapper {
116+
/// If the underlying literal is a string, regardless of quote style, returns the associated string value
117+
pub fn into_string(self) -> Option<String> {
118+
self.value.into_string()
119+
}
120+
}
121+
100122
impl Value {
101123
/// If the underlying literal is a string, regardless of quote style, returns the associated string value
102124
pub fn into_string(self) -> Option<String> {
@@ -121,6 +143,20 @@ impl Value {
121143
_ => None,
122144
}
123145
}
146+
147+
pub fn with_span(self, span: Span) -> ValueWrapper {
148+
ValueWrapper { value: self, span }
149+
}
150+
151+
pub fn with_empty_span(self) -> ValueWrapper {
152+
self.with_span(Span::empty())
153+
}
154+
}
155+
156+
impl fmt::Display for ValueWrapper {
157+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
158+
write!(f, "{}", self.value)
159+
}
124160
}
125161

126162
impl fmt::Display for Value {

0 commit comments

Comments
 (0)