Skip to content

Commit 211b15e

Browse files
authored
Enhance object name path segments (#1539)
1 parent fd6c98e commit 211b15e

20 files changed

+584
-466
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ println!("AST: {:?}", ast);
5353
This outputs
5454

5555
```rust
56-
AST: [Query(Query { ctes: [], body: Select(Select { distinct: false, projection: [UnnamedExpr(Identifier("a")), UnnamedExpr(Identifier("b")), UnnamedExpr(Value(Long(123))), UnnamedExpr(Function(Function { name: ObjectName(["myfunc"]), args: [Identifier("b")], filter: None, over: None, distinct: false }))], from: [TableWithJoins { relation: Table { name: ObjectName(["table_1"]), alias: None, args: [], with_hints: [] }, joins: [] }], selection: Some(BinaryOp { left: BinaryOp { left: Identifier("a"), op: Gt, right: Identifier("b") }, op: And, right: BinaryOp { left: Identifier("b"), op: Lt, right: Value(Long(100)) } }), group_by: [], having: None }), order_by: [OrderByExpr { expr: Identifier("a"), asc: Some(false) }, OrderByExpr { expr: Identifier("b"), asc: None }], limit: None, offset: None, fetch: None })]
56+
AST: [Query(Query { ctes: [], body: Select(Select { distinct: false, projection: [UnnamedExpr(Identifier("a")), UnnamedExpr(Identifier("b")), UnnamedExpr(Value(Long(123))), UnnamedExpr(Function(Function { name:ObjectName([Identifier(Ident { value: "myfunc", quote_style: None })]), args: [Identifier("b")], filter: None, over: None, distinct: false }))], from: [TableWithJoins { relation: Table { name: ObjectName([Identifier(Ident { value: "table_1", quote_style: None })]), alias: None, args: [], with_hints: [] }, joins: [] }], selection: Some(BinaryOp { left: BinaryOp { left: Identifier("a"), op: Gt, right: Identifier("b") }, op: And, right: BinaryOp { left: Identifier("b"), op: Lt, right: Value(Long(100)) } }), group_by: [], having: None }), order_by: [OrderByExpr { expr: Identifier("a"), asc: Some(false) }, OrderByExpr { expr: Identifier("b"), asc: None }], limit: None, offset: None, fetch: None })]
5757
```
5858

5959

src/ast/helpers/stmt_create_table.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use crate::parser::ParserError;
4242
/// ```rust
4343
/// use sqlparser::ast::helpers::stmt_create_table::CreateTableBuilder;
4444
/// use sqlparser::ast::{ColumnDef, DataType, Ident, ObjectName};
45-
/// let builder = CreateTableBuilder::new(ObjectName(vec![Ident::new("table_name")]))
45+
/// let builder = CreateTableBuilder::new(ObjectName::from(vec![Ident::new("table_name")]))
4646
/// .if_not_exists(true)
4747
/// .columns(vec![ColumnDef {
4848
/// name: Ident::new("c1"),
@@ -602,7 +602,7 @@ mod tests {
602602

603603
#[test]
604604
pub fn test_from_valid_statement() {
605-
let builder = CreateTableBuilder::new(ObjectName(vec![Ident::new("table_name")]));
605+
let builder = CreateTableBuilder::new(ObjectName::from(vec![Ident::new("table_name")]));
606606

607607
let stmt = builder.clone().build();
608608

src/ast/mod.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,44 @@ impl fmt::Display for Ident {
267267
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
268268
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
269269
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
270-
pub struct ObjectName(pub Vec<Ident>);
270+
pub struct ObjectName(pub Vec<ObjectNamePart>);
271+
272+
impl From<Vec<Ident>> for ObjectName {
273+
fn from(idents: Vec<Ident>) -> Self {
274+
ObjectName(idents.into_iter().map(ObjectNamePart::Identifier).collect())
275+
}
276+
}
271277

272278
impl fmt::Display for ObjectName {
273279
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
274280
write!(f, "{}", display_separated(&self.0, "."))
275281
}
276282
}
277283

284+
/// A single part of an ObjectName
285+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
286+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
287+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
288+
pub enum ObjectNamePart {
289+
Identifier(Ident),
290+
}
291+
292+
impl ObjectNamePart {
293+
pub fn as_ident(&self) -> Option<&Ident> {
294+
match self {
295+
ObjectNamePart::Identifier(ident) => Some(ident),
296+
}
297+
}
298+
}
299+
300+
impl fmt::Display for ObjectNamePart {
301+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
302+
match self {
303+
ObjectNamePart::Identifier(ident) => write!(f, "{}", ident),
304+
}
305+
}
306+
}
307+
278308
/// Represents an Array Expression, either
279309
/// `ARRAY[..]`, or `[..]`
280310
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]

src/ast/spans.rs

+24-16
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ use super::{
2828
FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList, FunctionArguments,
2929
GroupByExpr, HavingBound, IlikeSelectItem, Insert, Interpolate, InterpolateExpr, Join,
3030
JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, MatchRecognizePattern,
31-
Measure, NamedWindowDefinition, ObjectName, Offset, OnConflict, OnConflictAction, OnInsert,
32-
OrderBy, OrderByExpr, Partition, PivotValueSource, ProjectionSelect, Query, ReferentialAction,
33-
RenameSelectItem, ReplaceSelectElement, ReplaceSelectItem, Select, SelectInto, SelectItem,
34-
SetExpr, SqlOption, Statement, Subscript, SymbolDefinition, TableAlias, TableAliasColumnDef,
35-
TableConstraint, TableFactor, TableObject, TableOptionsClustered, TableWithJoins,
36-
UpdateTableFromKind, Use, Value, Values, ViewColumnDef, WildcardAdditionalOptions, With,
37-
WithFill,
31+
Measure, NamedWindowDefinition, ObjectName, ObjectNamePart, Offset, OnConflict,
32+
OnConflictAction, OnInsert, OrderBy, OrderByExpr, Partition, PivotValueSource,
33+
ProjectionSelect, Query, ReferentialAction, RenameSelectItem, ReplaceSelectElement,
34+
ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SqlOption, Statement, Subscript,
35+
SymbolDefinition, TableAlias, TableAliasColumnDef, TableConstraint, TableFactor, TableObject,
36+
TableOptionsClustered, TableWithJoins, UpdateTableFromKind, Use, Value, Values, ViewColumnDef,
37+
WildcardAdditionalOptions, With, WithFill,
3838
};
3939

4040
/// Given an iterator of spans, return the [Span::union] of all spans.
@@ -1358,7 +1358,7 @@ impl Spanned for Expr {
13581358
.union_opt(&overlay_for.as_ref().map(|i| i.span())),
13591359
Expr::Collate { expr, collation } => expr
13601360
.span()
1361-
.union(&union_spans(collation.0.iter().map(|i| i.span))),
1361+
.union(&union_spans(collation.0.iter().map(|i| i.span()))),
13621362
Expr::Nested(expr) => expr.span(),
13631363
Expr::Value(value) => value.span(),
13641364
Expr::TypedString { .. } => Span::empty(),
@@ -1462,7 +1462,7 @@ impl Spanned for Expr {
14621462
object_name
14631463
.0
14641464
.iter()
1465-
.map(|i| i.span)
1465+
.map(|i| i.span())
14661466
.chain(iter::once(token.0.span)),
14671467
),
14681468
Expr::OuterJoin(expr) => expr.span(),
@@ -1507,7 +1507,15 @@ impl Spanned for ObjectName {
15071507
fn span(&self) -> Span {
15081508
let ObjectName(segments) = self;
15091509

1510-
union_spans(segments.iter().map(|i| i.span))
1510+
union_spans(segments.iter().map(|i| i.span()))
1511+
}
1512+
}
1513+
1514+
impl Spanned for ObjectNamePart {
1515+
fn span(&self) -> Span {
1516+
match self {
1517+
ObjectNamePart::Identifier(ident) => ident.span,
1518+
}
15111519
}
15121520
}
15131521

@@ -1538,7 +1546,7 @@ impl Spanned for Function {
15381546
union_spans(
15391547
name.0
15401548
.iter()
1541-
.map(|i| i.span)
1549+
.map(|i| i.span())
15421550
.chain(iter::once(args.span()))
15431551
.chain(iter::once(parameters.span()))
15441552
.chain(filter.iter().map(|i| i.span()))
@@ -1624,7 +1632,7 @@ impl Spanned for SelectItem {
16241632
object_name
16251633
.0
16261634
.iter()
1627-
.map(|i| i.span)
1635+
.map(|i| i.span())
16281636
.chain(iter::once(wildcard_additional_options.span())),
16291637
),
16301638
SelectItem::Wildcard(wildcard_additional_options) => wildcard_additional_options.span(),
@@ -1734,7 +1742,7 @@ impl Spanned for TableFactor {
17341742
} => union_spans(
17351743
name.0
17361744
.iter()
1737-
.map(|i| i.span)
1745+
.map(|i| i.span())
17381746
.chain(alias.as_ref().map(|alias| {
17391747
union_spans(
17401748
iter::once(alias.name.span)
@@ -1779,7 +1787,7 @@ impl Spanned for TableFactor {
17791787
} => union_spans(
17801788
name.0
17811789
.iter()
1782-
.map(|i| i.span)
1790+
.map(|i| i.span())
17831791
.chain(args.iter().map(|i| i.span()))
17841792
.chain(alias.as_ref().map(|alias| alias.span())),
17851793
),
@@ -1930,7 +1938,7 @@ impl Spanned for FunctionArgExpr {
19301938
match self {
19311939
FunctionArgExpr::Expr(expr) => expr.span(),
19321940
FunctionArgExpr::QualifiedWildcard(object_name) => {
1933-
union_spans(object_name.0.iter().map(|i| i.span))
1941+
union_spans(object_name.0.iter().map(|i| i.span()))
19341942
}
19351943
FunctionArgExpr::Wildcard => Span::empty(),
19361944
}
@@ -2141,7 +2149,7 @@ impl Spanned for TableObject {
21412149
fn span(&self) -> Span {
21422150
match self {
21432151
TableObject::TableName(ObjectName(segments)) => {
2144-
union_spans(segments.iter().map(|i| i.span))
2152+
union_spans(segments.iter().map(|i| i.span()))
21452153
}
21462154
TableObject::TableFunction(func) => func.span(),
21472155
}

src/ast/visitor.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -403,15 +403,15 @@ where
403403
/// ```
404404
/// # use sqlparser::parser::Parser;
405405
/// # use sqlparser::dialect::GenericDialect;
406-
/// # use sqlparser::ast::{ObjectName, visit_relations_mut};
406+
/// # use sqlparser::ast::{ObjectName, ObjectNamePart, Ident, visit_relations_mut};
407407
/// # use core::ops::ControlFlow;
408408
/// let sql = "SELECT a FROM foo";
409409
/// let mut statements = Parser::parse_sql(&GenericDialect{}, sql)
410410
/// .unwrap();
411411
///
412412
/// // visit statements, renaming table foo to bar
413413
/// visit_relations_mut(&mut statements, |table| {
414-
/// table.0[0].value = table.0[0].value.replace("foo", "bar");
414+
/// table.0[0] = ObjectNamePart::Identifier(Ident::new("bar"));
415415
/// ControlFlow::<()>::Continue(())
416416
/// });
417417
///
@@ -529,7 +529,7 @@ where
529529
/// if matches!(expr, Expr::Identifier(col_name) if col_name.value == "x") {
530530
/// let old_expr = std::mem::replace(expr, Expr::Value(Value::Null));
531531
/// *expr = Expr::Function(Function {
532-
/// name: ObjectName(vec![Ident::new("f")]),
532+
/// name: ObjectName::from(vec![Ident::new("f")]),
533533
/// uses_odbc_syntax: false,
534534
/// args: FunctionArguments::List(FunctionArgumentList {
535535
/// duplicate_treatment: None,

src/dialect/snowflake.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ pub fn parse_snowflake_stage_name(parser: &mut Parser) -> Result<ObjectName, Par
651651
break;
652652
}
653653
}
654-
Ok(ObjectName(idents))
654+
Ok(ObjectName::from(idents))
655655
}
656656
_ => {
657657
parser.prev_token();

0 commit comments

Comments
 (0)