Skip to content

Commit c86c679

Browse files
committed
[Oracle] Parse CONNECT BY before GROUP BY
1 parent 327e2c8 commit c86c679

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
@@ -14000,6 +14000,17 @@ impl<'a> Parser<'a> {
1400014000
None
1400114001
};
1400214002

14003+
let connect_by = if self.dialect.supports_connect_by()
14004+
&& self
14005+
.parse_one_of_keywords(&[Keyword::START, Keyword::CONNECT])
14006+
.is_some()
14007+
{
14008+
self.prev_token();
14009+
Some(self.parse_connect_by()?)
14010+
} else {
14011+
None
14012+
};
14013+
1400314014
let group_by = self
1400414015
.parse_optional_group_by()?
1400514016
.unwrap_or_else(|| GroupByExpr::Expressions(vec![], vec![]));
@@ -14052,17 +14063,6 @@ impl<'a> Parser<'a> {
1405214063
Default::default()
1405314064
};
1405414065

14055-
let connect_by = if self.dialect.supports_connect_by()
14056-
&& self
14057-
.parse_one_of_keywords(&[Keyword::START, Keyword::CONNECT])
14058-
.is_some()
14059-
{
14060-
self.prev_token();
14061-
Some(self.parse_connect_by()?)
14062-
} else {
14063-
None
14064-
};
14065-
1406614066
Ok(Select {
1406714067
select_token: AttachedToken(select_token),
1406814068
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)