Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance object name path segments #1539

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -539,7 +539,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
24 changes: 23 additions & 1 deletion src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,36 @@ 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 fmt::Display for ObjectNamePart {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ObjectNamePart::Identifier(ident) => write!(f, "{}", ident),
ayman-sigma marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

/// Represents an Array Expression, either
/// `ARRAY[..]`, or `[..]`
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
Expand Down
36 changes: 22 additions & 14 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ use super::{
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, TableOptionsClustered, TableWithJoins, Use, Value, Values, ViewColumnDef,
WildcardAdditionalOptions, With, WithFill,
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, TableOptionsClustered, TableWithJoins, Use, Value, Values,
ViewColumnDef, WildcardAdditionalOptions, With, WithFill,
};

/// Given an iterator of spans, return the [Span::union] of all spans.
Expand Down Expand Up @@ -1302,7 +1302,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 @@ -1411,7 +1411,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 @@ -1447,7 +1447,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 @@ -1477,7 +1485,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 @@ -1563,7 +1571,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 @@ -1672,7 +1680,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 @@ -1717,7 +1725,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 @@ -1868,7 +1876,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
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")]),
/// args: FunctionArguments::List(FunctionArgumentList {
/// duplicate_treatment: None,
/// args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(old_expr))],
Expand Down
2 changes: 1 addition & 1 deletion src/dialect/snowflake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,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