Skip to content

Commit ce0d34d

Browse files
committed
improve object name parts
1 parent 62eaee6 commit ce0d34d

17 files changed

+447
-400
lines changed

src/ast/helpers/stmt_create_table.rs

Lines changed: 2 additions & 2 deletions
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"),
@@ -539,7 +539,7 @@ mod tests {
539539

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

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

src/ast/mod.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ impl Ident {
166166
quote_style: Some(quote),
167167
}
168168
}
169+
170+
pub fn to_object_name_part(&self) -> ObjectNamePart {
171+
ObjectNamePart::Identifier(self.clone())
172+
}
169173
}
170174

171175
impl From<&str> for Ident {
@@ -195,14 +199,36 @@ impl fmt::Display for Ident {
195199
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
196200
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
197201
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
198-
pub struct ObjectName(pub Vec<Ident>);
202+
pub struct ObjectName(pub Vec<ObjectNamePart>);
203+
204+
impl From<Vec<Ident>> for ObjectName {
205+
fn from(idents: Vec<Ident>) -> Self {
206+
ObjectName(idents.into_iter().map(ObjectNamePart::Identifier).collect())
207+
}
208+
}
199209

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

216+
/// A single part of an ObjectName
217+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
218+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
219+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
220+
pub enum ObjectNamePart {
221+
Identifier(Ident),
222+
}
223+
224+
impl fmt::Display for ObjectNamePart {
225+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226+
match self {
227+
ObjectNamePart::Identifier(ident) => write!(f, "{}", ident),
228+
}
229+
}
230+
}
231+
206232
/// Represents an Array Expression, either
207233
/// `ARRAY[..]`, or `[..]`
208234
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]

src/dialect/snowflake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ pub fn parse_snowflake_stage_name(parser: &mut Parser) -> Result<ObjectName, Par
491491
break;
492492
}
493493
}
494-
Ok(ObjectName(idents))
494+
Ok(ObjectName::from(idents))
495495
}
496496
_ => {
497497
parser.prev_token();

src/parser/mod.rs

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ impl<'a> Parser<'a> {
930930
id_parts.push(Ident::with_quote('\'', s))
931931
}
932932
Token::Mul => {
933-
return Ok(Expr::QualifiedWildcard(ObjectName(id_parts)));
933+
return Ok(Expr::QualifiedWildcard(ObjectName::from(id_parts)));
934934
}
935935
_ => {
936936
return self
@@ -1076,7 +1076,7 @@ impl<'a> Parser<'a> {
10761076
if dialect_of!(self is PostgreSqlDialect | GenericDialect) =>
10771077
{
10781078
Ok(Expr::Function(Function {
1079-
name: ObjectName(vec![w.to_ident()]),
1079+
name: ObjectName::from(vec![w.to_ident()]),
10801080
parameters: FunctionArguments::None,
10811081
args: FunctionArguments::None,
10821082
null_treatment: None,
@@ -1090,7 +1090,7 @@ impl<'a> Parser<'a> {
10901090
| Keyword::CURRENT_DATE
10911091
| Keyword::LOCALTIME
10921092
| Keyword::LOCALTIMESTAMP => {
1093-
self.parse_time_functions(ObjectName(vec![w.to_ident()]))
1093+
self.parse_time_functions(ObjectName::from(vec![w.to_ident()]))
10941094
}
10951095
Keyword::CASE => self.parse_case_expr(),
10961096
Keyword::CONVERT => self.parse_convert_expr(false),
@@ -1134,7 +1134,7 @@ impl<'a> Parser<'a> {
11341134
let query = self.parse_query()?;
11351135
self.expect_token(&Token::RParen)?;
11361136
Ok(Expr::Function(Function {
1137-
name: ObjectName(vec![w.to_ident()]),
1137+
name: ObjectName::from(vec![w.to_ident()]),
11381138
parameters: FunctionArguments::None,
11391139
args: FunctionArguments::Subquery(query),
11401140
filter: None,
@@ -1190,7 +1190,7 @@ impl<'a> Parser<'a> {
11901190
}
11911191

11921192
if ends_with_wildcard {
1193-
Ok(Expr::QualifiedWildcard(ObjectName(id_parts)))
1193+
Ok(Expr::QualifiedWildcard(ObjectName::from(id_parts)))
11941194
} else if self.consume_token(&Token::LParen) {
11951195
if dialect_of!(self is SnowflakeDialect | MsSqlDialect)
11961196
&& self.consume_tokens(&[Token::Plus, Token::RParen])
@@ -1203,7 +1203,7 @@ impl<'a> Parser<'a> {
12031203
)))
12041204
} else {
12051205
self.prev_token();
1206-
self.parse_function(ObjectName(id_parts))
1206+
self.parse_function(ObjectName::from(id_parts))
12071207
}
12081208
} else {
12091209
Ok(Expr::CompoundIdentifier(id_parts))
@@ -1420,7 +1420,7 @@ impl<'a> Parser<'a> {
14201420
Token::Word(word) => word.to_ident(),
14211421
_ => return p.expected("identifier", tok),
14221422
};
1423-
let func = match p.parse_function(ObjectName(vec![name]))? {
1423+
let func = match p.parse_function(ObjectName::from(vec![name]))? {
14241424
Expr::Function(func) => func,
14251425
_ => return p.expected("function", p.peek_token()),
14261426
};
@@ -1898,7 +1898,7 @@ impl<'a> Parser<'a> {
18981898
Some(expr) => Ok(expr),
18991899
// Snowflake supports `position` as an ordinary function call
19001900
// without the special `IN` syntax.
1901-
None => self.parse_function(ObjectName(vec![ident])),
1901+
None => self.parse_function(ObjectName::from(vec![ident])),
19021902
}
19031903
}
19041904

@@ -3592,6 +3592,24 @@ impl<'a> Parser<'a> {
35923592
Ok(values)
35933593
}
35943594

3595+
pub fn parse_period_separated<T, F>(&mut self, mut f: F) -> Result<Vec<T>, ParserError>
3596+
where
3597+
F: FnMut(&mut Parser<'a>) -> Result<T, ParserError>,
3598+
{
3599+
let mut values = vec![];
3600+
loop {
3601+
values.push(f(self)?);
3602+
if !self.consume_token(&Token::Period) {
3603+
break;
3604+
}
3605+
}
3606+
Ok(values)
3607+
}
3608+
3609+
pub fn parse_period_separated_identifiers(&mut self) -> Result<Vec<Ident>, ParserError> {
3610+
self.parse_period_separated(|p| p.parse_identifier(false))
3611+
}
3612+
35953613
/// Parse a keyword-separated list of 1+ items accepted by `F`
35963614
pub fn parse_keyword_separated<T, F>(
35973615
&mut self,
@@ -4294,7 +4312,10 @@ impl<'a> Parser<'a> {
42944312
let mut data_type = self.parse_data_type()?;
42954313
if let DataType::Custom(n, _) = &data_type {
42964314
// the first token is actually a name
4297-
name = Some(n.0[0].clone());
4315+
match n.0[0].clone() {
4316+
ObjectNamePart::Identifier(ident) => name = Some(ident),
4317+
}
4318+
// name = Some(n.0[0].clone());
42984319
data_type = self.parse_data_type()?;
42994320
}
43004321

@@ -8375,7 +8396,7 @@ impl<'a> Parser<'a> {
83758396
.collect()
83768397
}
83778398

8378-
Ok(ObjectName(idents))
8399+
Ok(ObjectName::from(idents))
83798400
}
83808401

83818402
/// Parse identifiers
@@ -9606,7 +9627,7 @@ impl<'a> Parser<'a> {
96069627
}
96079628

96089629
let variables = if self.parse_keywords(&[Keyword::TIME, Keyword::ZONE]) {
9609-
OneOrManyWithParens::One(ObjectName(vec!["TIMEZONE".into()]))
9630+
OneOrManyWithParens::One(ObjectName::from(vec!["TIMEZONE".into()]))
96109631
} else if self.dialect.supports_parenthesized_set_variables()
96119632
&& self.consume_token(&Token::LParen)
96129633
{
@@ -9615,7 +9636,7 @@ impl<'a> Parser<'a> {
96159636
parser.parse_identifier(false)
96169637
})?
96179638
.into_iter()
9618-
.map(|ident| ObjectName(vec![ident]))
9639+
.map(|ident| ObjectName::from(vec![ident]))
96199640
.collect(),
96209641
);
96219642
self.expect_token(&Token::RParen)?;
@@ -10727,7 +10748,7 @@ impl<'a> Parser<'a> {
1072710748
Token::Word(w) => Ok(w.value),
1072810749
_ => self.expected("a function identifier", self.peek_token()),
1072910750
}?;
10730-
let expr = self.parse_function(ObjectName(vec![Ident::new(function_name)]))?;
10751+
let expr = self.parse_function(ObjectName::from(vec![Ident::new(function_name)]))?;
1073110752
let alias = if self.parse_keyword(Keyword::AS) {
1073210753
Some(self.parse_identifier(false)?)
1073310754
} else {
@@ -10778,7 +10799,7 @@ impl<'a> Parser<'a> {
1077810799
self.expect_token(&Token::LParen)?;
1077910800
let aggregate_functions = self.parse_comma_separated(Self::parse_aliased_function_call)?;
1078010801
self.expect_keyword(Keyword::FOR)?;
10781-
let value_column = self.parse_object_name(false)?.0;
10802+
let value_column = self.parse_period_separated_identifiers()?;
1078210803
self.expect_keyword(Keyword::IN)?;
1078310804

1078410805
self.expect_token(&Token::LParen)?;
@@ -12288,7 +12309,7 @@ impl<'a> Parser<'a> {
1228812309
// [ OWNED BY { table_name.column_name | NONE } ]
1228912310
let owned_by = if self.parse_keywords(&[Keyword::OWNED, Keyword::BY]) {
1229012311
if self.parse_keywords(&[Keyword::NONE]) {
12291-
Some(ObjectName(vec![Ident::new("NONE")]))
12312+
Some(ObjectName::from(vec![Ident::new("NONE")]))
1229212313
} else {
1229312314
Some(self.parse_object_name(false)?)
1229412315
}
@@ -12579,7 +12600,7 @@ impl<'a> Parser<'a> {
1257912600
.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN])
1258012601
.is_some()
1258112602
{
12582-
parent_name.0.insert(0, self.parse_identifier(false)?);
12603+
parent_name.0.insert(0, self.parse_identifier(false)?.to_object_name_part());
1258312604
}
1258412605
(None, Some(parent_name))
1258512606
}
@@ -12884,14 +12905,14 @@ mod tests {
1288412905
test_parse_data_type!(
1288512906
dialect,
1288612907
"GEOMETRY",
12887-
DataType::Custom(ObjectName(vec!["GEOMETRY".into()]), vec![])
12908+
DataType::Custom(ObjectName::from(vec!["GEOMETRY".into()]), vec![])
1288812909
);
1288912910

1289012911
test_parse_data_type!(
1289112912
dialect,
1289212913
"GEOMETRY(POINT)",
1289312914
DataType::Custom(
12894-
ObjectName(vec!["GEOMETRY".into()]),
12915+
ObjectName::from(vec!["GEOMETRY".into()]),
1289512916
vec!["POINT".to_string()]
1289612917
)
1289712918
);
@@ -12900,7 +12921,7 @@ mod tests {
1290012921
dialect,
1290112922
"GEOMETRY(POINT, 4326)",
1290212923
DataType::Custom(
12903-
ObjectName(vec!["GEOMETRY".into()]),
12924+
ObjectName::from(vec!["GEOMETRY".into()]),
1290412925
vec!["POINT".to_string(), "4326".to_string()]
1290512926
)
1290612927
);
@@ -13036,7 +13057,7 @@ mod tests {
1303613057
}};
1303713058
}
1303813059

13039-
let dummy_name = ObjectName(vec![Ident::new("dummy_name")]);
13060+
let dummy_name = ObjectName::from(vec![Ident::new("dummy_name")]);
1304013061
let dummy_authorization = Ident::new("dummy_authorization");
1304113062

1304213063
test_parse_schema_name!(

src/test_utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ pub fn table_alias(name: impl Into<String>) -> Option<TableAlias> {
338338

339339
pub fn table(name: impl Into<String>) -> TableFactor {
340340
TableFactor::Table {
341-
name: ObjectName(vec![Ident::new(name.into())]),
341+
name: ObjectName::from(vec![Ident::new(name.into())]),
342342
alias: None,
343343
args: None,
344344
with_hints: vec![],
@@ -350,7 +350,7 @@ pub fn table(name: impl Into<String>) -> TableFactor {
350350

351351
pub fn table_with_alias(name: impl Into<String>, alias: impl Into<String>) -> TableFactor {
352352
TableFactor::Table {
353-
name: ObjectName(vec![Ident::new(name)]),
353+
name: ObjectName::from(vec![Ident::new(name)]),
354354
alias: Some(TableAlias {
355355
name: Ident::new(alias),
356356
columns: vec![],
@@ -373,7 +373,7 @@ pub fn join(relation: TableFactor) -> Join {
373373

374374
pub fn call(function: &str, args: impl IntoIterator<Item = Expr>) -> Expr {
375375
Expr::Function(Function {
376-
name: ObjectName(vec![Ident::new(function)]),
376+
name: ObjectName::from(vec![Ident::new(function)]),
377377
parameters: FunctionArguments::None,
378378
args: FunctionArguments::List(FunctionArgumentList {
379379
duplicate_treatment: None,

0 commit comments

Comments
 (0)