mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-22 15:04:04 +00:00
Implement FROM-first selects (#1713)
This commit is contained in:
parent
cad49232c1
commit
46cfcfe8f7
13 changed files with 184 additions and 9 deletions
|
@ -68,8 +68,8 @@ pub use self::query::{
|
||||||
NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset, OffsetRows, OpenJsonTableColumn,
|
NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset, OffsetRows, OpenJsonTableColumn,
|
||||||
OrderBy, OrderByExpr, PivotValueSource, ProjectionSelect, Query, RenameSelectItem,
|
OrderBy, OrderByExpr, PivotValueSource, ProjectionSelect, Query, RenameSelectItem,
|
||||||
RepetitionQuantifier, ReplaceSelectElement, ReplaceSelectItem, RowsPerMatch, Select,
|
RepetitionQuantifier, ReplaceSelectElement, ReplaceSelectItem, RowsPerMatch, Select,
|
||||||
SelectInto, SelectItem, SelectItemQualifiedWildcardKind, SetExpr, SetOperator, SetQuantifier,
|
SelectFlavor, SelectInto, SelectItem, SelectItemQualifiedWildcardKind, SetExpr, SetOperator,
|
||||||
Setting, SymbolDefinition, Table, TableAlias, TableAliasColumnDef, TableFactor,
|
SetQuantifier, Setting, SymbolDefinition, Table, TableAlias, TableAliasColumnDef, TableFactor,
|
||||||
TableFunctionArgs, TableIndexHintForClause, TableIndexHintType, TableIndexHints,
|
TableFunctionArgs, TableIndexHintForClause, TableIndexHintType, TableIndexHints,
|
||||||
TableIndexType, TableSample, TableSampleBucket, TableSampleKind, TableSampleMethod,
|
TableIndexType, TableSample, TableSampleBucket, TableSampleKind, TableSampleMethod,
|
||||||
TableSampleModifier, TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier,
|
TableSampleModifier, TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier,
|
||||||
|
|
|
@ -275,6 +275,19 @@ impl fmt::Display for Table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// What did this select look like?
|
||||||
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||||
|
pub enum SelectFlavor {
|
||||||
|
/// `SELECT *`
|
||||||
|
Standard,
|
||||||
|
/// `FROM ... SELECT *`
|
||||||
|
FromFirst,
|
||||||
|
/// `FROM *`
|
||||||
|
FromFirstNoSelect,
|
||||||
|
}
|
||||||
|
|
||||||
/// A restricted variant of `SELECT` (without CTEs/`ORDER BY`), which may
|
/// A restricted variant of `SELECT` (without CTEs/`ORDER BY`), which may
|
||||||
/// appear either as the only body item of a `Query`, or as an operand
|
/// appear either as the only body item of a `Query`, or as an operand
|
||||||
/// to a set operation like `UNION`.
|
/// to a set operation like `UNION`.
|
||||||
|
@ -328,11 +341,23 @@ pub struct Select {
|
||||||
pub value_table_mode: Option<ValueTableMode>,
|
pub value_table_mode: Option<ValueTableMode>,
|
||||||
/// STARTING WITH .. CONNECT BY
|
/// STARTING WITH .. CONNECT BY
|
||||||
pub connect_by: Option<ConnectBy>,
|
pub connect_by: Option<ConnectBy>,
|
||||||
|
/// Was this a FROM-first query?
|
||||||
|
pub flavor: SelectFlavor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Select {
|
impl fmt::Display for Select {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "SELECT")?;
|
match self.flavor {
|
||||||
|
SelectFlavor::Standard => {
|
||||||
|
write!(f, "SELECT")?;
|
||||||
|
}
|
||||||
|
SelectFlavor::FromFirst => {
|
||||||
|
write!(f, "FROM {} SELECT", display_comma_separated(&self.from))?;
|
||||||
|
}
|
||||||
|
SelectFlavor::FromFirstNoSelect => {
|
||||||
|
write!(f, "FROM {}", display_comma_separated(&self.from))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(value_table_mode) = self.value_table_mode {
|
if let Some(value_table_mode) = self.value_table_mode {
|
||||||
write!(f, " {value_table_mode}")?;
|
write!(f, " {value_table_mode}")?;
|
||||||
|
@ -360,7 +385,7 @@ impl fmt::Display for Select {
|
||||||
write!(f, " {into}")?;
|
write!(f, " {into}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.from.is_empty() {
|
if self.flavor == SelectFlavor::Standard && !self.from.is_empty() {
|
||||||
write!(f, " FROM {}", display_comma_separated(&self.from))?;
|
write!(f, " FROM {}", display_comma_separated(&self.from))?;
|
||||||
}
|
}
|
||||||
if !self.lateral_views.is_empty() {
|
if !self.lateral_views.is_empty() {
|
||||||
|
|
|
@ -2077,6 +2077,7 @@ impl Spanned for Select {
|
||||||
value_table_mode: _, // todo, BigQuery specific
|
value_table_mode: _, // todo, BigQuery specific
|
||||||
connect_by,
|
connect_by,
|
||||||
top_before_distinct: _,
|
top_before_distinct: _,
|
||||||
|
flavor: _,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
union_spans(
|
union_spans(
|
||||||
|
|
|
@ -75,4 +75,8 @@ impl Dialect for ClickHouseDialect {
|
||||||
fn supports_lambda_functions(&self) -> bool {
|
fn supports_lambda_functions(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn supports_from_first_select(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,4 +85,8 @@ impl Dialect for DuckDbDialect {
|
||||||
fn supports_array_typedef_size(&self) -> bool {
|
fn supports_array_typedef_size(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn supports_from_first_select(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -463,6 +463,17 @@ pub trait Dialect: Debug + Any {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return true if the dialect supports "FROM-first" selects.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```sql
|
||||||
|
/// FROM table
|
||||||
|
/// SELECT *
|
||||||
|
/// ```
|
||||||
|
fn supports_from_first_select(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Does the dialect support MySQL-style `'user'@'host'` grantee syntax?
|
/// Does the dialect support MySQL-style `'user'@'host'` grantee syntax?
|
||||||
fn supports_user_host_grantee(&self) -> bool {
|
fn supports_user_host_grantee(&self) -> bool {
|
||||||
false
|
false
|
||||||
|
|
|
@ -528,7 +528,7 @@ impl<'a> Parser<'a> {
|
||||||
Keyword::DESCRIBE => self.parse_explain(DescribeAlias::Describe),
|
Keyword::DESCRIBE => self.parse_explain(DescribeAlias::Describe),
|
||||||
Keyword::EXPLAIN => self.parse_explain(DescribeAlias::Explain),
|
Keyword::EXPLAIN => self.parse_explain(DescribeAlias::Explain),
|
||||||
Keyword::ANALYZE => self.parse_analyze(),
|
Keyword::ANALYZE => self.parse_analyze(),
|
||||||
Keyword::SELECT | Keyword::WITH | Keyword::VALUES => {
|
Keyword::SELECT | Keyword::WITH | Keyword::VALUES | Keyword::FROM => {
|
||||||
self.prev_token();
|
self.prev_token();
|
||||||
self.parse_query().map(Statement::Query)
|
self.parse_query().map(Statement::Query)
|
||||||
}
|
}
|
||||||
|
@ -10218,7 +10218,9 @@ impl<'a> Parser<'a> {
|
||||||
pub fn parse_query_body(&mut self, precedence: u8) -> Result<Box<SetExpr>, ParserError> {
|
pub fn parse_query_body(&mut self, precedence: u8) -> Result<Box<SetExpr>, ParserError> {
|
||||||
// We parse the expression using a Pratt parser, as in `parse_expr()`.
|
// We parse the expression using a Pratt parser, as in `parse_expr()`.
|
||||||
// Start by parsing a restricted SELECT or a `(subquery)`:
|
// Start by parsing a restricted SELECT or a `(subquery)`:
|
||||||
let expr = if self.peek_keyword(Keyword::SELECT) {
|
let expr = if self.peek_keyword(Keyword::SELECT)
|
||||||
|
|| (self.peek_keyword(Keyword::FROM) && self.dialect.supports_from_first_select())
|
||||||
|
{
|
||||||
SetExpr::Select(self.parse_select().map(Box::new)?)
|
SetExpr::Select(self.parse_select().map(Box::new)?)
|
||||||
} else if self.consume_token(&Token::LParen) {
|
} else if self.consume_token(&Token::LParen) {
|
||||||
// CTEs are not allowed here, but the parser currently accepts them
|
// CTEs are not allowed here, but the parser currently accepts them
|
||||||
|
@ -10317,6 +10319,39 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Parse a restricted `SELECT` statement (no CTEs / `UNION` / `ORDER BY`)
|
/// Parse a restricted `SELECT` statement (no CTEs / `UNION` / `ORDER BY`)
|
||||||
pub fn parse_select(&mut self) -> Result<Select, ParserError> {
|
pub fn parse_select(&mut self) -> Result<Select, ParserError> {
|
||||||
|
let mut from_first = None;
|
||||||
|
|
||||||
|
if self.dialect.supports_from_first_select() && self.peek_keyword(Keyword::FROM) {
|
||||||
|
let from_token = self.expect_keyword(Keyword::FROM)?;
|
||||||
|
let from = self.parse_table_with_joins()?;
|
||||||
|
if !self.peek_keyword(Keyword::SELECT) {
|
||||||
|
return Ok(Select {
|
||||||
|
select_token: AttachedToken(from_token),
|
||||||
|
distinct: None,
|
||||||
|
top: None,
|
||||||
|
top_before_distinct: false,
|
||||||
|
projection: vec![],
|
||||||
|
into: None,
|
||||||
|
from,
|
||||||
|
lateral_views: vec![],
|
||||||
|
prewhere: None,
|
||||||
|
selection: None,
|
||||||
|
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||||
|
cluster_by: vec![],
|
||||||
|
distribute_by: vec![],
|
||||||
|
sort_by: vec![],
|
||||||
|
having: None,
|
||||||
|
named_window: vec![],
|
||||||
|
window_before_qualify: false,
|
||||||
|
qualify: None,
|
||||||
|
value_table_mode: None,
|
||||||
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::FromFirstNoSelect,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
from_first = Some(from);
|
||||||
|
}
|
||||||
|
|
||||||
let select_token = self.expect_keyword(Keyword::SELECT)?;
|
let select_token = self.expect_keyword(Keyword::SELECT)?;
|
||||||
let value_table_mode =
|
let value_table_mode =
|
||||||
if dialect_of!(self is BigQueryDialect) && self.parse_keyword(Keyword::AS) {
|
if dialect_of!(self is BigQueryDialect) && self.parse_keyword(Keyword::AS) {
|
||||||
|
@ -10371,10 +10406,12 @@ impl<'a> Parser<'a> {
|
||||||
// otherwise they may be parsed as an alias as part of the `projection`
|
// otherwise they may be parsed as an alias as part of the `projection`
|
||||||
// or `from`.
|
// or `from`.
|
||||||
|
|
||||||
let from = if self.parse_keyword(Keyword::FROM) {
|
let (from, from_first) = if let Some(from) = from_first.take() {
|
||||||
self.parse_table_with_joins()?
|
(from, true)
|
||||||
|
} else if self.parse_keyword(Keyword::FROM) {
|
||||||
|
(self.parse_table_with_joins()?, false)
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
(vec![], false)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut lateral_views = vec![];
|
let mut lateral_views = vec![];
|
||||||
|
@ -10506,6 +10543,11 @@ impl<'a> Parser<'a> {
|
||||||
qualify,
|
qualify,
|
||||||
value_table_mode,
|
value_table_mode,
|
||||||
connect_by,
|
connect_by,
|
||||||
|
flavor: if from_first {
|
||||||
|
SelectFlavor::FromFirst
|
||||||
|
} else {
|
||||||
|
SelectFlavor::Standard
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ fn parse_map_access_expr() {
|
||||||
qualify: None,
|
qualify: None,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
},
|
},
|
||||||
select
|
select
|
||||||
);
|
);
|
||||||
|
|
|
@ -461,6 +461,7 @@ fn parse_update_set_from() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -5289,6 +5290,7 @@ fn test_parse_named_window() {
|
||||||
window_before_qualify: true,
|
window_before_qualify: true,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
};
|
};
|
||||||
assert_eq!(actual_select_only, expected);
|
assert_eq!(actual_select_only, expected);
|
||||||
}
|
}
|
||||||
|
@ -5915,6 +5917,7 @@ fn parse_interval_and_or_xor() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -8022,6 +8025,7 @@ fn lateral_function() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
};
|
};
|
||||||
assert_eq!(actual_select_only, expected);
|
assert_eq!(actual_select_only, expected);
|
||||||
}
|
}
|
||||||
|
@ -8919,6 +8923,7 @@ fn parse_merge() {
|
||||||
qualify: None,
|
qualify: None,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -10703,6 +10708,7 @@ fn parse_unload() {
|
||||||
qualify: None,
|
qualify: None,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
with: None,
|
with: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -10913,6 +10919,7 @@ fn parse_connect_by() {
|
||||||
))))),
|
))))),
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
};
|
};
|
||||||
|
|
||||||
let connect_by_1 = concat!(
|
let connect_by_1 = concat!(
|
||||||
|
@ -10997,6 +11004,7 @@ fn parse_connect_by() {
|
||||||
))))),
|
))))),
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -11860,6 +11868,7 @@ fn test_extract_seconds_ok() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -13592,3 +13601,65 @@ fn test_lambdas() {
|
||||||
);
|
);
|
||||||
dialects.verified_expr("transform(array(1, 2, 3), x -> x + 1)");
|
dialects.verified_expr("transform(array(1, 2, 3), x -> x + 1)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_select_from_first() {
|
||||||
|
let dialects = all_dialects_where(|d| d.supports_from_first_select());
|
||||||
|
let q1 = "FROM capitals";
|
||||||
|
let q2 = "FROM capitals SELECT *";
|
||||||
|
|
||||||
|
for (q, flavor, projection) in [
|
||||||
|
(q1, SelectFlavor::FromFirstNoSelect, vec![]),
|
||||||
|
(
|
||||||
|
q2,
|
||||||
|
SelectFlavor::FromFirst,
|
||||||
|
vec![SelectItem::Wildcard(WildcardAdditionalOptions::default())],
|
||||||
|
),
|
||||||
|
] {
|
||||||
|
let ast = dialects.verified_query(q);
|
||||||
|
let expected = Query {
|
||||||
|
with: None,
|
||||||
|
body: Box::new(SetExpr::Select(Box::new(Select {
|
||||||
|
select_token: AttachedToken::empty(),
|
||||||
|
distinct: None,
|
||||||
|
top: None,
|
||||||
|
projection,
|
||||||
|
top_before_distinct: false,
|
||||||
|
into: None,
|
||||||
|
from: vec![TableWithJoins {
|
||||||
|
relation: table_from_name(ObjectName::from(vec![Ident {
|
||||||
|
value: "capitals".to_string(),
|
||||||
|
quote_style: None,
|
||||||
|
span: Span::empty(),
|
||||||
|
}])),
|
||||||
|
joins: vec![],
|
||||||
|
}],
|
||||||
|
lateral_views: vec![],
|
||||||
|
prewhere: None,
|
||||||
|
selection: None,
|
||||||
|
group_by: GroupByExpr::Expressions(vec![], vec![]),
|
||||||
|
cluster_by: vec![],
|
||||||
|
distribute_by: vec![],
|
||||||
|
sort_by: vec![],
|
||||||
|
having: None,
|
||||||
|
named_window: vec![],
|
||||||
|
window_before_qualify: false,
|
||||||
|
qualify: None,
|
||||||
|
value_table_mode: None,
|
||||||
|
connect_by: None,
|
||||||
|
flavor,
|
||||||
|
}))),
|
||||||
|
order_by: None,
|
||||||
|
limit: None,
|
||||||
|
offset: None,
|
||||||
|
fetch: None,
|
||||||
|
locks: vec![],
|
||||||
|
limit_by: vec![],
|
||||||
|
for_clause: None,
|
||||||
|
settings: None,
|
||||||
|
format_clause: None,
|
||||||
|
};
|
||||||
|
assert_eq!(expected, ast);
|
||||||
|
assert_eq!(ast.to_string(), q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -288,6 +288,7 @@ fn test_select_union_by_name() {
|
||||||
qualify: None,
|
qualify: None,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
right: Box::<SetExpr>::new(SetExpr::Select(Box::new(Select {
|
right: Box::<SetExpr>::new(SetExpr::Select(Box::new(Select {
|
||||||
select_token: AttachedToken::empty(),
|
select_token: AttachedToken::empty(),
|
||||||
|
@ -317,6 +318,7 @@ fn test_select_union_by_name() {
|
||||||
qualify: None,
|
qualify: None,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
});
|
});
|
||||||
assert_eq!(ast.body, expected);
|
assert_eq!(ast.body, expected);
|
||||||
|
|
|
@ -137,6 +137,7 @@ fn parse_create_procedure() {
|
||||||
qualify: None,
|
qualify: None,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
})))
|
})))
|
||||||
}))],
|
}))],
|
||||||
params: Some(vec![
|
params: Some(vec![
|
||||||
|
@ -1114,6 +1115,7 @@ fn parse_substring_in_select() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -1251,6 +1253,7 @@ fn parse_mssql_declare() {
|
||||||
qualify: None,
|
qualify: None,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
})))
|
})))
|
||||||
}))
|
}))
|
||||||
],
|
],
|
||||||
|
|
|
@ -1111,6 +1111,7 @@ fn parse_escaped_quote_identifiers_with_escape() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -1164,6 +1165,7 @@ fn parse_escaped_quote_identifiers_with_no_escape() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -1211,6 +1213,7 @@ fn parse_escaped_backticks_with_escape() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -1262,6 +1265,7 @@ fn parse_escaped_backticks_with_no_escape() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -1931,6 +1935,7 @@ fn parse_select_with_numeric_prefix_column_name() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
})))
|
})))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1983,6 +1988,7 @@ fn parse_select_with_concatenation_of_exp_number_and_numeric_prefix_column() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
})))
|
})))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2503,6 +2509,7 @@ fn parse_substring_in_select() {
|
||||||
qualify: None,
|
qualify: None,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -2799,6 +2806,7 @@ fn parse_hex_string_introducer() {
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
into: None,
|
into: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
|
|
@ -1315,6 +1315,7 @@ fn parse_copy_to() {
|
||||||
qualify: None,
|
qualify: None,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
limit: None,
|
limit: None,
|
||||||
|
@ -2666,6 +2667,7 @@ fn parse_array_subquery_expr() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
right: Box::new(SetExpr::Select(Box::new(Select {
|
right: Box::new(SetExpr::Select(Box::new(Select {
|
||||||
select_token: AttachedToken::empty(),
|
select_token: AttachedToken::empty(),
|
||||||
|
@ -2688,6 +2690,7 @@ fn parse_array_subquery_expr() {
|
||||||
window_before_qualify: false,
|
window_before_qualify: false,
|
||||||
value_table_mode: None,
|
value_table_mode: None,
|
||||||
connect_by: None,
|
connect_by: None,
|
||||||
|
flavor: SelectFlavor::Standard,
|
||||||
}))),
|
}))),
|
||||||
}),
|
}),
|
||||||
order_by: None,
|
order_by: None,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue