Skip to content

Commit

Permalink
Enhance object name path segments (#1539)
Browse files Browse the repository at this point in the history
  • Loading branch information
ayman-sigma authored Jan 26, 2025
1 parent fd6c98e commit 211b15e
Show file tree
Hide file tree
Showing 20 changed files with 584 additions and 466 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ println!("AST: {:?}", ast);
This outputs

```rust
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 })]
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 })]
```


Expand Down
4 changes: 2 additions & 2 deletions src/ast/helpers/stmt_create_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use crate::parser::ParserError;
/// ```rust
/// use sqlparser::ast::helpers::stmt_create_table::CreateTableBuilder;
/// use sqlparser::ast::{ColumnDef, DataType, Ident, ObjectName};
/// let builder = CreateTableBuilder::new(ObjectName(vec![Ident::new("table_name")]))
/// let builder = CreateTableBuilder::new(ObjectName::from(vec![Ident::new("table_name")]))
/// .if_not_exists(true)
/// .columns(vec![ColumnDef {
/// name: Ident::new("c1"),
Expand Down Expand Up @@ -602,7 +602,7 @@ mod tests {

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

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

Expand Down
32 changes: 31 additions & 1 deletion src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,14 +267,44 @@ impl fmt::Display for Ident {
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ObjectName(pub Vec<Ident>);
pub struct ObjectName(pub Vec<ObjectNamePart>);

impl From<Vec<Ident>> for ObjectName {
fn from(idents: Vec<Ident>) -> Self {
ObjectName(idents.into_iter().map(ObjectNamePart::Identifier).collect())
}
}

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

/// A single part of an ObjectName
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ObjectNamePart {
Identifier(Ident),
}

impl ObjectNamePart {
pub fn as_ident(&self) -> Option<&Ident> {
match self {
ObjectNamePart::Identifier(ident) => Some(ident),
}
}
}

impl fmt::Display for ObjectNamePart {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ObjectNamePart::Identifier(ident) => write!(f, "{}", ident),
}
}
}

/// Represents an Array Expression, either
/// `ARRAY[..]`, or `[..]`
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
Expand Down
40 changes: 24 additions & 16 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ use super::{
FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList, FunctionArguments,
GroupByExpr, HavingBound, IlikeSelectItem, Insert, Interpolate, InterpolateExpr, Join,
JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, MatchRecognizePattern,
Measure, NamedWindowDefinition, ObjectName, 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,
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,
};

/// Given an iterator of spans, return the [Span::union] of all spans.
Expand Down Expand Up @@ -1358,7 +1358,7 @@ impl Spanned for Expr {
.union_opt(&overlay_for.as_ref().map(|i| i.span())),
Expr::Collate { expr, collation } => expr
.span()
.union(&union_spans(collation.0.iter().map(|i| i.span))),
.union(&union_spans(collation.0.iter().map(|i| i.span()))),
Expr::Nested(expr) => expr.span(),
Expr::Value(value) => value.span(),
Expr::TypedString { .. } => Span::empty(),
Expand Down Expand Up @@ -1462,7 +1462,7 @@ impl Spanned for Expr {
object_name
.0
.iter()
.map(|i| i.span)
.map(|i| i.span())
.chain(iter::once(token.0.span)),
),
Expr::OuterJoin(expr) => expr.span(),
Expand Down Expand Up @@ -1507,7 +1507,15 @@ impl Spanned for ObjectName {
fn span(&self) -> Span {
let ObjectName(segments) = self;

union_spans(segments.iter().map(|i| i.span))
union_spans(segments.iter().map(|i| i.span()))
}
}

impl Spanned for ObjectNamePart {
fn span(&self) -> Span {
match self {
ObjectNamePart::Identifier(ident) => ident.span,
}
}
}

Expand Down Expand Up @@ -1538,7 +1546,7 @@ impl Spanned for Function {
union_spans(
name.0
.iter()
.map(|i| i.span)
.map(|i| i.span())
.chain(iter::once(args.span()))
.chain(iter::once(parameters.span()))
.chain(filter.iter().map(|i| i.span()))
Expand Down Expand Up @@ -1624,7 +1632,7 @@ impl Spanned for SelectItem {
object_name
.0
.iter()
.map(|i| i.span)
.map(|i| i.span())
.chain(iter::once(wildcard_additional_options.span())),
),
SelectItem::Wildcard(wildcard_additional_options) => wildcard_additional_options.span(),
Expand Down Expand Up @@ -1734,7 +1742,7 @@ impl Spanned for TableFactor {
} => union_spans(
name.0
.iter()
.map(|i| i.span)
.map(|i| i.span())
.chain(alias.as_ref().map(|alias| {
union_spans(
iter::once(alias.name.span)
Expand Down Expand Up @@ -1779,7 +1787,7 @@ impl Spanned for TableFactor {
} => union_spans(
name.0
.iter()
.map(|i| i.span)
.map(|i| i.span())
.chain(args.iter().map(|i| i.span()))
.chain(alias.as_ref().map(|alias| alias.span())),
),
Expand Down Expand Up @@ -1930,7 +1938,7 @@ impl Spanned for FunctionArgExpr {
match self {
FunctionArgExpr::Expr(expr) => expr.span(),
FunctionArgExpr::QualifiedWildcard(object_name) => {
union_spans(object_name.0.iter().map(|i| i.span))
union_spans(object_name.0.iter().map(|i| i.span()))
}
FunctionArgExpr::Wildcard => Span::empty(),
}
Expand Down Expand Up @@ -2141,7 +2149,7 @@ impl Spanned for TableObject {
fn span(&self) -> Span {
match self {
TableObject::TableName(ObjectName(segments)) => {
union_spans(segments.iter().map(|i| i.span))
union_spans(segments.iter().map(|i| i.span()))
}
TableObject::TableFunction(func) => func.span(),
}
Expand Down
6 changes: 3 additions & 3 deletions src/ast/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,15 +403,15 @@ where
/// ```
/// # use sqlparser::parser::Parser;
/// # use sqlparser::dialect::GenericDialect;
/// # use sqlparser::ast::{ObjectName, visit_relations_mut};
/// # use sqlparser::ast::{ObjectName, ObjectNamePart, Ident, visit_relations_mut};
/// # use core::ops::ControlFlow;
/// let sql = "SELECT a FROM foo";
/// let mut statements = Parser::parse_sql(&GenericDialect{}, sql)
/// .unwrap();
///
/// // visit statements, renaming table foo to bar
/// visit_relations_mut(&mut statements, |table| {
/// table.0[0].value = table.0[0].value.replace("foo", "bar");
/// table.0[0] = ObjectNamePart::Identifier(Ident::new("bar"));
/// ControlFlow::<()>::Continue(())
/// });
///
Expand Down Expand Up @@ -529,7 +529,7 @@ where
/// if matches!(expr, Expr::Identifier(col_name) if col_name.value == "x") {
/// let old_expr = std::mem::replace(expr, Expr::Value(Value::Null));
/// *expr = Expr::Function(Function {
/// name: ObjectName(vec![Ident::new("f")]),
/// name: ObjectName::from(vec![Ident::new("f")]),
/// uses_odbc_syntax: false,
/// args: FunctionArguments::List(FunctionArgumentList {
/// duplicate_treatment: None,
Expand Down
2 changes: 1 addition & 1 deletion src/dialect/snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ pub fn parse_snowflake_stage_name(parser: &mut Parser) -> Result<ObjectName, Par
break;
}
}
Ok(ObjectName(idents))
Ok(ObjectName::from(idents))
}
_ => {
parser.prev_token();
Expand Down
Loading

0 comments on commit 211b15e

Please sign in to comment.