Skip to content

Commit ddaf134

Browse files
authored
Revert "BigQuery: Add support for select expr star (apache#1680)"
This reverts commit 73dbd91.
1 parent 09dfc94 commit ddaf134

10 files changed

+59
-185
lines changed

src/ast/mod.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,12 @@ pub use self::query::{
6868
NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset, OffsetRows, OpenJsonTableColumn,
6969
OrderBy, OrderByExpr, PivotValueSource, ProjectionSelect, Query, RenameSelectItem,
7070
RepetitionQuantifier, ReplaceSelectElement, ReplaceSelectItem, RowsPerMatch, Select,
71-
SelectInto, SelectItem, SelectItemQualifiedWildcardKind, SetExpr, SetOperator, SetQuantifier,
72-
Setting, SymbolDefinition, Table, TableAlias, TableAliasColumnDef, TableFactor,
73-
TableFunctionArgs, TableIndexHintForClause, TableIndexHintType, TableIndexHints,
74-
TableIndexType, TableSample, TableSampleBucket, TableSampleKind, TableSampleMethod,
75-
TableSampleModifier, TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier,
76-
TableSampleUnit, TableVersion, TableWithJoins, Top, TopQuantity, UpdateTableFromKind,
77-
ValueTableMode, Values, WildcardAdditionalOptions, With, WithFill,
71+
SelectInto, SelectItem, SetExpr, SetOperator, SetQuantifier, Setting, SymbolDefinition, Table,
72+
TableAlias, TableAliasColumnDef, TableFactor, TableFunctionArgs, TableIndexHintForClause,
73+
TableIndexHintType, TableIndexHints, TableIndexType, TableSample, TableSampleBucket,
74+
TableSampleKind, TableSampleMethod, TableSampleModifier, TableSampleQuantity, TableSampleSeed,
75+
TableSampleSeedModifier, TableSampleUnit, TableVersion, TableWithJoins, Top, TopQuantity,
76+
UpdateTableFromKind, ValueTableMode, Values, WildcardAdditionalOptions, With, WithFill,
7877
};
7978

8079
pub use self::trigger::{

src/ast/query.rs

+4-30
Original file line numberDiff line numberDiff line change
@@ -586,20 +586,6 @@ impl fmt::Display for Cte {
586586
}
587587
}
588588

589-
/// Represents an expression behind a wildcard expansion in a projection.
590-
/// `SELECT T.* FROM T;
591-
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
592-
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
593-
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
594-
pub enum SelectItemQualifiedWildcardKind {
595-
/// Expression is an object name.
596-
/// e.g. `alias.*` or even `schema.table.*`
597-
ObjectName(ObjectName),
598-
/// Select star on an arbitrary expression.
599-
/// e.g. `STRUCT<STRING>('foo').*`
600-
Expr(Expr),
601-
}
602-
603589
/// One item of the comma-separated list following `SELECT`
604590
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
605591
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@@ -609,24 +595,12 @@ pub enum SelectItem {
609595
UnnamedExpr(Expr),
610596
/// An expression, followed by `[ AS ] alias`
611597
ExprWithAlias { expr: Expr, alias: Ident },
612-
/// An expression, followed by a wildcard expansion.
613-
/// e.g. `alias.*`, `STRUCT<STRING>('foo').*`
614-
QualifiedWildcard(SelectItemQualifiedWildcardKind, WildcardAdditionalOptions),
598+
/// `alias.*` or even `schema.table.*`
599+
QualifiedWildcard(ObjectName, WildcardAdditionalOptions),
615600
/// An unqualified `*`
616601
Wildcard(WildcardAdditionalOptions),
617602
}
618603

619-
impl fmt::Display for SelectItemQualifiedWildcardKind {
620-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
621-
match &self {
622-
SelectItemQualifiedWildcardKind::ObjectName(object_name) => {
623-
write!(f, "{object_name}.*")
624-
}
625-
SelectItemQualifiedWildcardKind::Expr(expr) => write!(f, "{expr}.*"),
626-
}
627-
}
628-
}
629-
630604
/// Single aliased identifier
631605
///
632606
/// # Syntax
@@ -893,8 +867,8 @@ impl fmt::Display for SelectItem {
893867
match &self {
894868
SelectItem::UnnamedExpr(expr) => write!(f, "{expr}"),
895869
SelectItem::ExprWithAlias { expr, alias } => write!(f, "{expr} AS {alias}"),
896-
SelectItem::QualifiedWildcard(kind, additional_options) => {
897-
write!(f, "{kind}")?;
870+
SelectItem::QualifiedWildcard(prefix, additional_options) => {
871+
write!(f, "{prefix}.*")?;
898872
write!(f, "{additional_options}")?;
899873
Ok(())
900874
}

src/ast/spans.rs

+34-15
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18-
use crate::ast::query::SelectItemQualifiedWildcardKind;
19-
use core::iter;
20-
2118
use crate::tokenizer::Span;
19+
use core::iter;
2220

2321
use super::{
2422
dcl::SecondaryRoles, AccessExpr, AlterColumnOperation, AlterIndexOperation,
@@ -385,6 +383,33 @@ impl Spanned for Statement {
385383
.chain(to.iter().map(|i| i.span())),
386384
),
387385
Statement::CreateTable(create_table) => create_table.span(),
386+
Statement::CreateIcebergTable {
387+
or_replace: _,
388+
if_not_exists: _,
389+
name,
390+
columns,
391+
constraints,
392+
with_options,
393+
comment: _,
394+
cluster_by: _,
395+
external_volume: _,
396+
catalog: _,
397+
base_location: _,
398+
catalog_sync: _,
399+
storage_serialization_policy: _,
400+
data_retention_time_in_days: _,
401+
max_data_extension_time_in_days: _,
402+
change_tracking: _,
403+
copy_grants: _,
404+
with_row_access_policy: _,
405+
with_aggregation_policy: _,
406+
with_tags: _,
407+
} => union_spans(
408+
core::iter::once(name.span())
409+
.chain(columns.iter().map(|i| i.span()))
410+
.chain(constraints.iter().map(|i| i.span()))
411+
.chain(with_options.iter().map(|i| i.span())),
412+
),
388413
Statement::CreateVirtualTable {
389414
name,
390415
if_not_exists: _,
@@ -490,6 +515,7 @@ impl Spanned for Statement {
490515
Statement::DropPolicy { .. } => Span::empty(),
491516
Statement::ShowDatabases { .. } => Span::empty(),
492517
Statement::ShowSchemas { .. } => Span::empty(),
518+
Statement::ShowObjects { .. } => Span::empty(),
493519
Statement::ShowViews { .. } => Span::empty(),
494520
Statement::LISTEN { .. } => Span::empty(),
495521
Statement::NOTIFY { .. } => Span::empty(),
@@ -1624,23 +1650,16 @@ impl Spanned for JsonPathElem {
16241650
}
16251651
}
16261652

1627-
impl Spanned for SelectItemQualifiedWildcardKind {
1628-
fn span(&self) -> Span {
1629-
match self {
1630-
SelectItemQualifiedWildcardKind::ObjectName(object_name) => object_name.span(),
1631-
SelectItemQualifiedWildcardKind::Expr(expr) => expr.span(),
1632-
}
1633-
}
1634-
}
1635-
16361653
impl Spanned for SelectItem {
16371654
fn span(&self) -> Span {
16381655
match self {
16391656
SelectItem::UnnamedExpr(expr) => expr.span(),
16401657
SelectItem::ExprWithAlias { expr, alias } => expr.span().union(&alias.span),
1641-
SelectItem::QualifiedWildcard(kind, wildcard_additional_options) => union_spans(
1642-
[kind.span()]
1643-
.into_iter()
1658+
SelectItem::QualifiedWildcard(object_name, wildcard_additional_options) => union_spans(
1659+
object_name
1660+
.0
1661+
.iter()
1662+
.map(|i| i.span())
16441663
.chain(iter::once(wildcard_additional_options.span())),
16451664
),
16461665
SelectItem::Wildcard(wildcard_additional_options) => wildcard_additional_options.span(),

src/dialect/bigquery.rs

-5
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,6 @@ impl Dialect for BigQueryDialect {
8383
true
8484
}
8585

86-
/// See <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_expression_star>
87-
fn supports_select_expr_star(&self) -> bool {
88-
true
89-
}
90-
9186
// See <https://cloud.google.com/bigquery/docs/access-historical-data>
9287
fn supports_timestamp_versioning(&self) -> bool {
9388
true

src/dialect/mod.rs

-11
Original file line numberDiff line numberDiff line change
@@ -447,17 +447,6 @@ pub trait Dialect: Debug + Any {
447447
false
448448
}
449449

450-
/// Return true if the dialect supports wildcard expansion on
451-
/// arbitrary expressions in projections.
452-
///
453-
/// Example:
454-
/// ```sql
455-
/// SELECT STRUCT<STRING>('foo').* FROM T
456-
/// ```
457-
fn supports_select_expr_star(&self) -> bool {
458-
false
459-
}
460-
461450
/// Does the dialect support MySQL-style `'user'@'host'` grantee syntax?
462451
fn supports_user_host_grantee(&self) -> bool {
463452
false

src/parser/mod.rs

+7-23
Original file line numberDiff line numberDiff line change
@@ -1528,17 +1528,10 @@ impl<'a> Parser<'a> {
15281528
// function array_agg traverses this control flow
15291529
if dialect_of!(self is PostgreSqlDialect) {
15301530
ending_wildcard = Some(next_token);
1531+
break;
15311532
} else {
1532-
// Put back the consumed .* tokens before exiting.
1533-
// If this expression is being parsed in the
1534-
// context of a projection, then this could imply
1535-
// a wildcard expansion. For example:
1536-
// `SELECT STRUCT('foo').* FROM T`
1537-
self.prev_token(); // *
1538-
self.prev_token(); // .
1533+
return self.expected("an identifier after '.'", next_token);
15391534
}
1540-
1541-
break;
15421535
}
15431536
Token::SingleQuotedString(s) => {
15441537
let expr = Expr::Identifier(Ident::with_quote('\'', s));
@@ -1575,18 +1568,18 @@ impl<'a> Parser<'a> {
15751568
} else {
15761569
self.parse_function(ObjectName::from(id_parts))
15771570
}
1578-
} else if chain.is_empty() {
1579-
Ok(root)
15801571
} else {
15811572
if Self::is_all_ident(&root, &chain) {
15821573
return Ok(Expr::CompoundIdentifier(Self::exprs_to_idents(
15831574
root, chain,
15841575
)?));
15851576
}
1586-
1577+
if chain.is_empty() {
1578+
return Ok(root);
1579+
}
15871580
Ok(Expr::CompoundFieldAccess {
15881581
root: Box::new(root),
1589-
access_chain: chain,
1582+
access_chain: chain.clone(),
15901583
})
15911584
}
15921585
}
@@ -12942,7 +12935,7 @@ impl<'a> Parser<'a> {
1294212935
pub fn parse_select_item(&mut self) -> Result<SelectItem, ParserError> {
1294312936
match self.parse_wildcard_expr()? {
1294412937
Expr::QualifiedWildcard(prefix, token) => Ok(SelectItem::QualifiedWildcard(
12945-
SelectItemQualifiedWildcardKind::ObjectName(prefix),
12938+
prefix,
1294612939
self.parse_wildcard_additional_options(token.0)?,
1294712940
)),
1294812941
Expr::Wildcard(token) => Ok(SelectItem::Wildcard(
@@ -12972,15 +12965,6 @@ impl<'a> Parser<'a> {
1297212965
alias,
1297312966
})
1297412967
}
12975-
expr if self.dialect.supports_select_expr_star()
12976-
&& self.consume_tokens(&[Token::Period, Token::Mul]) =>
12977-
{
12978-
let wildcard_token = self.get_previous_token().clone();
12979-
Ok(SelectItem::QualifiedWildcard(
12980-
SelectItemQualifiedWildcardKind::Expr(expr),
12981-
self.parse_wildcard_additional_options(wildcard_token)?,
12982-
))
12983-
}
1298412968
expr => self
1298512969
.maybe_parse_select_item_alias()
1298612970
.map(|alias| match alias {

tests/sqlparser_bigquery.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,9 @@ fn parse_hyphenated_table_identifiers() {
15401540
]))
15411541
})
15421542
);
1543+
1544+
let error_sql = "select foo-bar.* from foo-bar";
1545+
assert!(bigquery().parse_sql_statements(error_sql).is_err());
15431546
}
15441547

15451548
#[test]
@@ -2201,14 +2204,6 @@ fn parse_extract_weekday() {
22012204
);
22022205
}
22032206

2204-
#[test]
2205-
fn bigquery_select_expr_star() {
2206-
bigquery()
2207-
.verified_only_select("SELECT STRUCT<STRING>((SELECT foo FROM T WHERE true)).* FROM T");
2208-
bigquery().verified_only_select("SELECT [STRUCT<STRING>('foo')][0].* EXCEPT (foo) FROM T");
2209-
bigquery().verified_only_select("SELECT myfunc()[0].* FROM T");
2210-
}
2211-
22122207
#[test]
22132208
fn test_select_as_struct() {
22142209
bigquery().verified_only_select("SELECT * FROM (SELECT AS VALUE STRUCT(123 AS a, false AS b))");

tests/sqlparser_common.rs

+2-83
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,7 @@ fn parse_select_wildcard() {
10021002
let select = verified_only_select(sql);
10031003
assert_eq!(
10041004
&SelectItem::QualifiedWildcard(
1005-
SelectItemQualifiedWildcardKind::ObjectName(ObjectName::from(vec![Ident::new("foo")])),
1005+
ObjectName::from(vec![Ident::new("foo")]),
10061006
WildcardAdditionalOptions::default()
10071007
),
10081008
only(&select.projection)
@@ -1012,10 +1012,7 @@ fn parse_select_wildcard() {
10121012
let select = verified_only_select(sql);
10131013
assert_eq!(
10141014
&SelectItem::QualifiedWildcard(
1015-
SelectItemQualifiedWildcardKind::ObjectName(ObjectName::from(vec![
1016-
Ident::new("myschema"),
1017-
Ident::new("mytable"),
1018-
])),
1015+
ObjectName::from(vec![Ident::new("myschema"), Ident::new("mytable"),]),
10191016
WildcardAdditionalOptions::default(),
10201017
),
10211018
only(&select.projection)
@@ -1060,84 +1057,6 @@ fn parse_column_aliases() {
10601057
one_statement_parses_to("SELECT a.col + 1 newname FROM foo AS a", sql);
10611058
}
10621059

1063-
#[test]
1064-
fn parse_select_expr_star() {
1065-
let dialects = all_dialects_where(|d| d.supports_select_expr_star());
1066-
1067-
// Identifier wildcard expansion.
1068-
let select = dialects.verified_only_select("SELECT foo.bar.* FROM T");
1069-
let SelectItem::QualifiedWildcard(SelectItemQualifiedWildcardKind::ObjectName(object_name), _) =
1070-
only(&select.projection)
1071-
else {
1072-
unreachable!(
1073-
"expected wildcard select item: got {:?}",
1074-
&select.projection[0]
1075-
)
1076-
};
1077-
assert_eq!(
1078-
&ObjectName::from(
1079-
["foo", "bar"]
1080-
.into_iter()
1081-
.map(Ident::new)
1082-
.collect::<Vec<_>>()
1083-
),
1084-
object_name
1085-
);
1086-
1087-
// Arbitrary compound expression with wildcard expansion.
1088-
let select = dialects.verified_only_select("SELECT foo - bar.* FROM T");
1089-
let SelectItem::QualifiedWildcard(
1090-
SelectItemQualifiedWildcardKind::Expr(Expr::BinaryOp { left, op, right }),
1091-
_,
1092-
) = only(&select.projection)
1093-
else {
1094-
unreachable!(
1095-
"expected wildcard select item: got {:?}",
1096-
&select.projection[0]
1097-
)
1098-
};
1099-
let (Expr::Identifier(left), BinaryOperator::Minus, Expr::Identifier(right)) =
1100-
(left.as_ref(), op, right.as_ref())
1101-
else {
1102-
unreachable!("expected binary op expr: got {:?}", &select.projection[0])
1103-
};
1104-
assert_eq!(&Ident::new("foo"), left);
1105-
assert_eq!(&Ident::new("bar"), right);
1106-
1107-
// Arbitrary expression wildcard expansion.
1108-
let select = dialects.verified_only_select("SELECT myfunc().foo.* FROM T");
1109-
let SelectItem::QualifiedWildcard(
1110-
SelectItemQualifiedWildcardKind::Expr(Expr::CompoundFieldAccess { root, access_chain }),
1111-
_,
1112-
) = only(&select.projection)
1113-
else {
1114-
unreachable!("expected wildcard expr: got {:?}", &select.projection[0])
1115-
};
1116-
assert!(matches!(root.as_ref(), Expr::Function(_)));
1117-
assert_eq!(1, access_chain.len());
1118-
assert!(matches!(
1119-
&access_chain[0],
1120-
AccessExpr::Dot(Expr::Identifier(_))
1121-
));
1122-
1123-
dialects.one_statement_parses_to(
1124-
"SELECT 2. * 3 FROM T",
1125-
#[cfg(feature = "bigdecimal")]
1126-
"SELECT 2 * 3 FROM T",
1127-
#[cfg(not(feature = "bigdecimal"))]
1128-
"SELECT 2. * 3 FROM T",
1129-
);
1130-
dialects.verified_only_select("SELECT myfunc().* FROM T");
1131-
dialects.verified_only_select("SELECT myfunc().* EXCEPT (foo) FROM T");
1132-
1133-
// Invalid
1134-
let res = dialects.parse_sql_statements("SELECT foo.*.* FROM T");
1135-
assert_eq!(
1136-
ParserError::ParserError("Expected: end of statement, found: .".to_string()),
1137-
res.unwrap_err()
1138-
);
1139-
}
1140-
11411060
#[test]
11421061
fn test_eof_after_as() {
11431062
let res = parse_sql_statements("SELECT foo AS");

tests/sqlparser_duckdb.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ fn test_select_wildcard_with_exclude() {
160160
let select =
161161
duckdb().verified_only_select("SELECT name.* EXCLUDE department_id FROM employee_table");
162162
let expected = SelectItem::QualifiedWildcard(
163-
SelectItemQualifiedWildcardKind::ObjectName(ObjectName::from(vec![Ident::new("name")])),
163+
ObjectName::from(vec![Ident::new("name")]),
164164
WildcardAdditionalOptions {
165165
opt_exclude: Some(ExcludeSelectItem::Single(Ident::new("department_id"))),
166166
..Default::default()

0 commit comments

Comments
 (0)