Skip to content

Commit ff403cb

Browse files
committed
Add parse_value_table_mode, mvoe tests, update docs
1 parent 2e00c84 commit ff403cb

File tree

3 files changed

+63
-58
lines changed

3 files changed

+63
-58
lines changed

src/ast/query.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3338,11 +3338,8 @@ impl fmt::Display for OpenJsonTableColumn {
33383338
}
33393339

33403340
/// BigQuery supports ValueTables which have 2 modes:
3341-
/// `SELECT AS STRUCT`
3342-
/// `SELECT AS VALUE`
3343-
///
3344-
/// They can be combined with `[ { ALL | DISTINCT } ]`, e.g.
3345-
/// `SELECT DISTINCT AS STRUCT`
3341+
/// `SELECT [ALL | DISTINCT] AS STRUCT`
3342+
/// `SELECT [ALL | DISTINCT] AS VALUE`
33463343
///
33473344
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#value_tables>
33483345
/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_list>

src/parser/mod.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11505,31 +11505,7 @@ impl<'a> Parser<'a> {
1150511505
}
1150611506

1150711507
let select_token = self.expect_keyword(Keyword::SELECT)?;
11508-
let value_table_mode = if dialect_of!(self is BigQueryDialect) {
11509-
if self.parse_keywords(&[Keyword::DISTINCT, Keyword::AS]) {
11510-
if self.parse_keyword(Keyword::VALUE) {
11511-
Some(ValueTableMode::DistinctAsValue)
11512-
} else if self.parse_keyword(Keyword::STRUCT) {
11513-
Some(ValueTableMode::DistinctAsStruct)
11514-
} else {
11515-
self.expected("VALUE or STRUCT", self.peek_token())?
11516-
}
11517-
} else if self.parse_keyword(Keyword::AS)
11518-
|| self.parse_keywords(&[Keyword::ALL, Keyword::AS])
11519-
{
11520-
if self.parse_keyword(Keyword::VALUE) {
11521-
Some(ValueTableMode::AsValue)
11522-
} else if self.parse_keyword(Keyword::STRUCT) {
11523-
Some(ValueTableMode::AsStruct)
11524-
} else {
11525-
self.expected("VALUE or STRUCT", self.peek_token())?
11526-
}
11527-
} else {
11528-
None
11529-
}
11530-
} else {
11531-
None
11532-
};
11508+
let value_table_mode = self.parse_value_table_mode()?;
1153311509

1153411510
let mut top_before_distinct = false;
1153511511
let mut top = None;
@@ -11705,6 +11681,32 @@ impl<'a> Parser<'a> {
1170511681
})
1170611682
}
1170711683

11684+
fn parse_value_table_mode(&mut self) -> Result<Option<ValueTableMode>, ParserError> {
11685+
if !dialect_of!(self is BigQueryDialect) {
11686+
return Ok(None);
11687+
}
11688+
11689+
let mode = if self.parse_keywords(&[Keyword::DISTINCT, Keyword::AS, Keyword::VALUE]) {
11690+
Some(ValueTableMode::DistinctAsValue)
11691+
} else if self.parse_keywords(&[Keyword::DISTINCT, Keyword::AS, Keyword::STRUCT]) {
11692+
Some(ValueTableMode::DistinctAsStruct)
11693+
} else if self.parse_keywords(&[Keyword::AS, Keyword::VALUE])
11694+
|| self.parse_keywords(&[Keyword::ALL, Keyword::AS, Keyword::VALUE])
11695+
{
11696+
Some(ValueTableMode::AsValue)
11697+
} else if self.parse_keywords(&[Keyword::AS, Keyword::STRUCT])
11698+
|| self.parse_keywords(&[Keyword::ALL, Keyword::AS, Keyword::STRUCT])
11699+
{
11700+
Some(ValueTableMode::AsStruct)
11701+
} else if self.parse_keyword(Keyword::AS) {
11702+
self.expected("VALUE or STRUCT", self.peek_token())?
11703+
} else {
11704+
None
11705+
};
11706+
11707+
Ok(mode)
11708+
}
11709+
1170811710
/// Invoke `f` after first setting the parser's `ParserState` to `state`.
1170911711
///
1171011712
/// Upon return, restores the parser's state to what it started at.

tests/sqlparser_bigquery.rs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,16 +2313,46 @@ fn bigquery_select_expr_star() {
23132313

23142314
#[test]
23152315
fn test_select_as_struct() {
2316-
bigquery().verified_only_select("SELECT * FROM (SELECT AS VALUE STRUCT(123 AS a, false AS b))");
2316+
for (sql, parse_to) in [
2317+
(
2318+
"SELECT * FROM (SELECT AS STRUCT STRUCT(123 AS a, false AS b))",
2319+
"SELECT * FROM (SELECT AS STRUCT STRUCT(123 AS a, false AS b))",
2320+
),
2321+
(
2322+
"SELECT * FROM (SELECT DISTINCT AS STRUCT STRUCT(123 AS a, false AS b))",
2323+
"SELECT * FROM (SELECT DISTINCT AS STRUCT STRUCT(123 AS a, false AS b))",
2324+
),
2325+
(
2326+
"SELECT * FROM (SELECT ALL AS STRUCT STRUCT(123 AS a, false AS b))",
2327+
"SELECT * FROM (SELECT AS STRUCT STRUCT(123 AS a, false AS b))",
2328+
),
2329+
] {
2330+
bigquery().one_statement_parses_to(sql, parse_to);
2331+
}
2332+
23172333
let select = bigquery().verified_only_select("SELECT AS STRUCT 1 AS a, 2 AS b");
23182334
assert_eq!(Some(ValueTableMode::AsStruct), select.value_table_mode);
23192335
}
23202336

23212337
#[test]
23222338
fn test_select_as_value() {
2323-
bigquery().verified_only_select(
2324-
"SELECT * FROM (SELECT AS VALUE STRUCT(5 AS star_rating, false AS up_down_rating))",
2325-
);
2339+
for (sql, parse_to) in [
2340+
(
2341+
"SELECT * FROM (SELECT AS VALUE STRUCT(5 AS star_rating, false AS up_down_rating))",
2342+
"SELECT * FROM (SELECT AS VALUE STRUCT(5 AS star_rating, false AS up_down_rating))",
2343+
),
2344+
(
2345+
"SELECT * FROM (SELECT DISTINCT AS VALUE STRUCT(5 AS star_rating, false AS up_down_rating))",
2346+
"SELECT * FROM (SELECT DISTINCT AS VALUE STRUCT(5 AS star_rating, false AS up_down_rating))",
2347+
),
2348+
(
2349+
"SELECT * FROM (SELECT ALL AS VALUE STRUCT(5 AS star_rating, false AS up_down_rating))",
2350+
"SELECT * FROM (SELECT AS VALUE STRUCT(5 AS star_rating, false AS up_down_rating))",
2351+
),
2352+
] {
2353+
bigquery().one_statement_parses_to(sql, parse_to);
2354+
}
2355+
23262356
let select = bigquery().verified_only_select("SELECT AS VALUE STRUCT(1 AS a, 2 AS b) AS xyz");
23272357
assert_eq!(Some(ValueTableMode::AsValue), select.value_table_mode);
23282358
}
@@ -2377,27 +2407,3 @@ fn test_any_type() {
23772407
fn test_any_type_dont_break_custom_type() {
23782408
bigquery_and_generic().verified_stmt("CREATE TABLE foo (x ANY)");
23792409
}
2380-
2381-
#[test]
2382-
fn test_select_distinct_or_all_as_struct_or_value() {
2383-
for sql in [
2384-
"SELECT DISTINCT AS STRUCT a, ABS(b) FROM UNNEST(c) AS T",
2385-
"SELECT DISTINCT AS VALUE a, ABS(b) FROM UNNEST(c) AS T",
2386-
"SELECT ARRAY(SELECT DISTINCT AS STRUCT a, b, ABS(c) AS c, ABS(d) AS d FROM UNNEST(e) AS T)",
2387-
] {
2388-
bigquery().verified_stmt(sql);
2389-
}
2390-
2391-
for (sql, parse_to) in [
2392-
(
2393-
"SELECT ALL AS STRUCT a, ABS(b) FROM UNNEST(c) AS T",
2394-
"SELECT AS STRUCT a, ABS(b) FROM UNNEST(c) AS T",
2395-
),
2396-
(
2397-
"SELECT ALL AS VALUE a, ABS(b) FROM UNNEST(c) AS T",
2398-
"SELECT AS VALUE a, ABS(b) FROM UNNEST(c) AS T",
2399-
),
2400-
] {
2401-
bigquery().one_statement_parses_to(sql, parse_to);
2402-
}
2403-
}

0 commit comments

Comments
 (0)