Skip to content

Commit c279417

Browse files
committed
[Oracle] Parse CONNECT BY before GROUP BY
1 parent 40243b6 commit c279417

3 files changed

Lines changed: 31 additions & 23 deletions

File tree

src/ast/query.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ pub struct Select {
374374
pub prewhere: Option<Expr>,
375375
/// WHERE
376376
pub selection: Option<Expr>,
377+
/// STARTING WITH .. CONNECT BY
378+
pub connect_by: Option<ConnectBy>,
377379
/// GROUP BY
378380
pub group_by: GroupByExpr,
379381
/// CLUSTER BY (Hive)
@@ -395,8 +397,6 @@ pub struct Select {
395397
pub window_before_qualify: bool,
396398
/// BigQuery syntax: `SELECT AS VALUE | SELECT AS STRUCT`
397399
pub value_table_mode: Option<ValueTableMode>,
398-
/// STARTING WITH .. CONNECT BY
399-
pub connect_by: Option<ConnectBy>,
400400
/// Was this a FROM-first query?
401401
pub flavor: SelectFlavor,
402402
}
@@ -475,6 +475,10 @@ impl fmt::Display for Select {
475475
SpaceOrNewline.fmt(f)?;
476476
Indent(selection).fmt(f)?;
477477
}
478+
if let Some(ref connect_by) = self.connect_by {
479+
SpaceOrNewline.fmt(f)?;
480+
connect_by.fmt(f)?;
481+
}
478482
match &self.group_by {
479483
GroupByExpr::All(_) => {
480484
SpaceOrNewline.fmt(f)?;
@@ -538,10 +542,6 @@ impl fmt::Display for Select {
538542
display_comma_separated(&self.named_window).fmt(f)?;
539543
}
540544
}
541-
if let Some(ref connect_by) = self.connect_by {
542-
SpaceOrNewline.fmt(f)?;
543-
connect_by.fmt(f)?;
544-
}
545545
Ok(())
546546
}
547547
}

src/parser/mod.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13977,6 +13977,17 @@ impl<'a> Parser<'a> {
1397713977
None
1397813978
};
1397913979

13980+
let connect_by = if self.dialect.supports_connect_by()
13981+
&& self
13982+
.parse_one_of_keywords(&[Keyword::START, Keyword::CONNECT])
13983+
.is_some()
13984+
{
13985+
self.prev_token();
13986+
Some(self.parse_connect_by()?)
13987+
} else {
13988+
None
13989+
};
13990+
1398013991
let group_by = self
1398113992
.parse_optional_group_by()?
1398213993
.unwrap_or_else(|| GroupByExpr::Expressions(vec![], vec![]));
@@ -14029,17 +14040,6 @@ impl<'a> Parser<'a> {
1402914040
Default::default()
1403014041
};
1403114042

14032-
let connect_by = if self.dialect.supports_connect_by()
14033-
&& self
14034-
.parse_one_of_keywords(&[Keyword::START, Keyword::CONNECT])
14035-
.is_some()
14036-
{
14037-
self.prev_token();
14038-
Some(self.parse_connect_by()?)
14039-
} else {
14040-
None
14041-
};
14042-
1404314043
Ok(Select {
1404414044
select_token: AttachedToken(select_token),
1404514045
optimizer_hint,

tests/sqlparser_common.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12628,6 +12628,8 @@ fn parse_map_access_expr() {
1262812628

1262912629
#[test]
1263012630
fn parse_connect_by() {
12631+
let dialects = all_dialects_where(|d| d.supports_connect_by());
12632+
1263112633
let expect_query = Select {
1263212634
select_token: AttachedToken::empty(),
1263312635
optimizer_hint: None,
@@ -12685,7 +12687,7 @@ fn parse_connect_by() {
1268512687
);
1268612688

1268712689
assert_eq!(
12688-
all_dialects_where(|d| d.supports_connect_by()).verified_only_select(connect_by_1),
12690+
dialects.verified_only_select(connect_by_1),
1268912691
expect_query
1269012692
);
1269112693

@@ -12697,8 +12699,7 @@ fn parse_connect_by() {
1269712699
"ORDER BY employee_id"
1269812700
);
1269912701
assert_eq!(
12700-
all_dialects_where(|d| d.supports_connect_by())
12701-
.verified_only_select_with_canonical(connect_by_2, connect_by_1),
12702+
dialects.verified_only_select_with_canonical(connect_by_2, connect_by_1),
1270212703
expect_query
1270312704
);
1270412705

@@ -12711,7 +12712,7 @@ fn parse_connect_by() {
1271112712
"ORDER BY employee_id"
1271212713
);
1271312714
assert_eq!(
12714-
all_dialects_where(|d| d.supports_connect_by()).verified_only_select(connect_by_3),
12715+
dialects.verified_only_select(connect_by_3),
1271512716
Select {
1271612717
select_token: AttachedToken::empty(),
1271712718
optimizer_hint: None,
@@ -12773,7 +12774,7 @@ fn parse_connect_by() {
1277312774
"WHERE employee_id <> 42 ",
1277412775
"ORDER BY employee_id"
1277512776
);
12776-
all_dialects_where(|d| d.supports_connect_by())
12777+
dialects
1277712778
.parse_sql_statements(connect_by_4)
1277812779
.expect_err("should have failed");
1277912780

@@ -12791,7 +12792,7 @@ fn parse_connect_by() {
1279112792
// no START WITH and NOCYCLE
1279212793
let connect_by_5 = "SELECT child, parent FROM t CONNECT BY NOCYCLE parent = PRIOR child";
1279312794
assert_eq!(
12794-
all_dialects_where(|d| d.supports_connect_by()).verified_only_select(connect_by_5),
12795+
dialects.verified_only_select(connect_by_5),
1279512796
Select {
1279612797
select_token: AttachedToken::empty(),
1279712798
optimizer_hint: None,
@@ -12832,6 +12833,13 @@ fn parse_connect_by() {
1283212833
flavor: SelectFlavor::Standard,
1283312834
}
1283412835
);
12836+
12837+
// ~ CONNECT BY after WHERE and before GROUP BY
12838+
dialects.verified_only_select("SELECT 0 FROM t WHERE 1 = 1 CONNECT BY 2 = 2 GROUP BY 3");
12839+
dialects.verified_only_select("SELECT 0 FROM t WHERE 1 = 1 START WITH 'a' = 'a' CONNECT BY 2 = 2 GROUP BY 3");
12840+
dialects.verified_only_select_with_canonical(
12841+
"SELECT 0 FROM t WHERE 1 = 1 CONNECT BY 2 = 2 START WITH 'a' = 'a' GROUP BY 3",
12842+
"SELECT 0 FROM t WHERE 1 = 1 START WITH 'a' = 'a' CONNECT BY 2 = 2 GROUP BY 3");
1283512843
}
1283612844

1283712845
#[test]

0 commit comments

Comments
 (0)