mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-15 03:30:16 +00:00
redshift: add support for CREATE VIEW … WITH NO SCHEMA BINDING (#979)
This commit is contained in:
parent
40e2ecbdf3
commit
c811e22605
5 changed files with 46 additions and 2 deletions
|
@ -577,7 +577,7 @@ pub enum Expr {
|
||||||
///
|
///
|
||||||
/// Syntax:
|
/// Syntax:
|
||||||
/// ```sql
|
/// ```sql
|
||||||
/// MARCH (<col>, <col>, ...) AGAINST (<expr> [<search modifier>])
|
/// MATCH (<col>, <col>, ...) AGAINST (<expr> [<search modifier>])
|
||||||
///
|
///
|
||||||
/// <col> = CompoundIdentifier
|
/// <col> = CompoundIdentifier
|
||||||
/// <expr> = String literal
|
/// <expr> = String literal
|
||||||
|
@ -1316,6 +1316,8 @@ pub enum Statement {
|
||||||
query: Box<Query>,
|
query: Box<Query>,
|
||||||
with_options: Vec<SqlOption>,
|
with_options: Vec<SqlOption>,
|
||||||
cluster_by: Vec<Ident>,
|
cluster_by: Vec<Ident>,
|
||||||
|
/// if true, has RedShift [`WITH NO SCHEMA BINDING`] clause <https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_VIEW.html>
|
||||||
|
with_no_schema_binding: bool,
|
||||||
},
|
},
|
||||||
/// CREATE TABLE
|
/// CREATE TABLE
|
||||||
CreateTable {
|
CreateTable {
|
||||||
|
@ -2271,6 +2273,7 @@ impl fmt::Display for Statement {
|
||||||
materialized,
|
materialized,
|
||||||
with_options,
|
with_options,
|
||||||
cluster_by,
|
cluster_by,
|
||||||
|
with_no_schema_binding,
|
||||||
} => {
|
} => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
@ -2288,7 +2291,11 @@ impl fmt::Display for Statement {
|
||||||
if !cluster_by.is_empty() {
|
if !cluster_by.is_empty() {
|
||||||
write!(f, " CLUSTER BY ({})", display_comma_separated(cluster_by))?;
|
write!(f, " CLUSTER BY ({})", display_comma_separated(cluster_by))?;
|
||||||
}
|
}
|
||||||
write!(f, " AS {query}")
|
write!(f, " AS {query}")?;
|
||||||
|
if *with_no_schema_binding {
|
||||||
|
write!(f, " WITH NO SCHEMA BINDING")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
Statement::CreateTable {
|
Statement::CreateTable {
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -110,6 +110,7 @@ define_keywords!(
|
||||||
BIGINT,
|
BIGINT,
|
||||||
BIGNUMERIC,
|
BIGNUMERIC,
|
||||||
BINARY,
|
BINARY,
|
||||||
|
BINDING,
|
||||||
BLOB,
|
BLOB,
|
||||||
BLOOMFILTER,
|
BLOOMFILTER,
|
||||||
BOOL,
|
BOOL,
|
||||||
|
|
|
@ -2974,6 +2974,15 @@ impl<'a> Parser<'a> {
|
||||||
self.expect_keyword(Keyword::AS)?;
|
self.expect_keyword(Keyword::AS)?;
|
||||||
let query = Box::new(self.parse_query()?);
|
let query = Box::new(self.parse_query()?);
|
||||||
// Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
|
// Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
|
||||||
|
|
||||||
|
let with_no_schema_binding = dialect_of!(self is RedshiftSqlDialect | GenericDialect)
|
||||||
|
&& self.parse_keywords(&[
|
||||||
|
Keyword::WITH,
|
||||||
|
Keyword::NO,
|
||||||
|
Keyword::SCHEMA,
|
||||||
|
Keyword::BINDING,
|
||||||
|
]);
|
||||||
|
|
||||||
Ok(Statement::CreateView {
|
Ok(Statement::CreateView {
|
||||||
name,
|
name,
|
||||||
columns,
|
columns,
|
||||||
|
@ -2982,6 +2991,7 @@ impl<'a> Parser<'a> {
|
||||||
or_replace,
|
or_replace,
|
||||||
with_options,
|
with_options,
|
||||||
cluster_by,
|
cluster_by,
|
||||||
|
with_no_schema_binding,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5320,6 +5320,7 @@ fn parse_create_view() {
|
||||||
materialized,
|
materialized,
|
||||||
with_options,
|
with_options,
|
||||||
cluster_by,
|
cluster_by,
|
||||||
|
with_no_schema_binding: late_binding,
|
||||||
} => {
|
} => {
|
||||||
assert_eq!("myschema.myview", name.to_string());
|
assert_eq!("myschema.myview", name.to_string());
|
||||||
assert_eq!(Vec::<Ident>::new(), columns);
|
assert_eq!(Vec::<Ident>::new(), columns);
|
||||||
|
@ -5328,6 +5329,7 @@ fn parse_create_view() {
|
||||||
assert!(!or_replace);
|
assert!(!or_replace);
|
||||||
assert_eq!(with_options, vec![]);
|
assert_eq!(with_options, vec![]);
|
||||||
assert_eq!(cluster_by, vec![]);
|
assert_eq!(cluster_by, vec![]);
|
||||||
|
assert!(!late_binding);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -5368,6 +5370,7 @@ fn parse_create_view_with_columns() {
|
||||||
query,
|
query,
|
||||||
materialized,
|
materialized,
|
||||||
cluster_by,
|
cluster_by,
|
||||||
|
with_no_schema_binding: late_binding,
|
||||||
} => {
|
} => {
|
||||||
assert_eq!("v", name.to_string());
|
assert_eq!("v", name.to_string());
|
||||||
assert_eq!(columns, vec![Ident::new("has"), Ident::new("cols")]);
|
assert_eq!(columns, vec![Ident::new("has"), Ident::new("cols")]);
|
||||||
|
@ -5376,6 +5379,7 @@ fn parse_create_view_with_columns() {
|
||||||
assert!(!materialized);
|
assert!(!materialized);
|
||||||
assert!(!or_replace);
|
assert!(!or_replace);
|
||||||
assert_eq!(cluster_by, vec![]);
|
assert_eq!(cluster_by, vec![]);
|
||||||
|
assert!(!late_binding);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -5393,6 +5397,7 @@ fn parse_create_or_replace_view() {
|
||||||
query,
|
query,
|
||||||
materialized,
|
materialized,
|
||||||
cluster_by,
|
cluster_by,
|
||||||
|
with_no_schema_binding: late_binding,
|
||||||
} => {
|
} => {
|
||||||
assert_eq!("v", name.to_string());
|
assert_eq!("v", name.to_string());
|
||||||
assert_eq!(columns, vec![]);
|
assert_eq!(columns, vec![]);
|
||||||
|
@ -5401,6 +5406,7 @@ fn parse_create_or_replace_view() {
|
||||||
assert!(!materialized);
|
assert!(!materialized);
|
||||||
assert!(or_replace);
|
assert!(or_replace);
|
||||||
assert_eq!(cluster_by, vec![]);
|
assert_eq!(cluster_by, vec![]);
|
||||||
|
assert!(!late_binding);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -5422,6 +5428,7 @@ fn parse_create_or_replace_materialized_view() {
|
||||||
query,
|
query,
|
||||||
materialized,
|
materialized,
|
||||||
cluster_by,
|
cluster_by,
|
||||||
|
with_no_schema_binding: late_binding,
|
||||||
} => {
|
} => {
|
||||||
assert_eq!("v", name.to_string());
|
assert_eq!("v", name.to_string());
|
||||||
assert_eq!(columns, vec![]);
|
assert_eq!(columns, vec![]);
|
||||||
|
@ -5430,6 +5437,7 @@ fn parse_create_or_replace_materialized_view() {
|
||||||
assert!(materialized);
|
assert!(materialized);
|
||||||
assert!(or_replace);
|
assert!(or_replace);
|
||||||
assert_eq!(cluster_by, vec![]);
|
assert_eq!(cluster_by, vec![]);
|
||||||
|
assert!(!late_binding);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -5447,6 +5455,7 @@ fn parse_create_materialized_view() {
|
||||||
materialized,
|
materialized,
|
||||||
with_options,
|
with_options,
|
||||||
cluster_by,
|
cluster_by,
|
||||||
|
with_no_schema_binding: late_binding,
|
||||||
} => {
|
} => {
|
||||||
assert_eq!("myschema.myview", name.to_string());
|
assert_eq!("myschema.myview", name.to_string());
|
||||||
assert_eq!(Vec::<Ident>::new(), columns);
|
assert_eq!(Vec::<Ident>::new(), columns);
|
||||||
|
@ -5455,6 +5464,7 @@ fn parse_create_materialized_view() {
|
||||||
assert_eq!(with_options, vec![]);
|
assert_eq!(with_options, vec![]);
|
||||||
assert!(!or_replace);
|
assert!(!or_replace);
|
||||||
assert_eq!(cluster_by, vec![]);
|
assert_eq!(cluster_by, vec![]);
|
||||||
|
assert!(!late_binding);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -5472,6 +5482,7 @@ fn parse_create_materialized_view_with_cluster_by() {
|
||||||
materialized,
|
materialized,
|
||||||
with_options,
|
with_options,
|
||||||
cluster_by,
|
cluster_by,
|
||||||
|
with_no_schema_binding: late_binding,
|
||||||
} => {
|
} => {
|
||||||
assert_eq!("myschema.myview", name.to_string());
|
assert_eq!("myschema.myview", name.to_string());
|
||||||
assert_eq!(Vec::<Ident>::new(), columns);
|
assert_eq!(Vec::<Ident>::new(), columns);
|
||||||
|
@ -5480,6 +5491,7 @@ fn parse_create_materialized_view_with_cluster_by() {
|
||||||
assert_eq!(with_options, vec![]);
|
assert_eq!(with_options, vec![]);
|
||||||
assert!(!or_replace);
|
assert!(!or_replace);
|
||||||
assert_eq!(cluster_by, vec![Ident::new("foo")]);
|
assert_eq!(cluster_by, vec![Ident::new("foo")]);
|
||||||
|
assert!(!late_binding);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ mod test_utils;
|
||||||
use test_utils::*;
|
use test_utils::*;
|
||||||
|
|
||||||
use sqlparser::ast::*;
|
use sqlparser::ast::*;
|
||||||
|
use sqlparser::dialect::GenericDialect;
|
||||||
use sqlparser::dialect::RedshiftSqlDialect;
|
use sqlparser::dialect::RedshiftSqlDialect;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -272,6 +273,13 @@ fn redshift() -> TestedDialects {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn redshift_and_generic() -> TestedDialects {
|
||||||
|
TestedDialects {
|
||||||
|
dialects: vec![Box::new(RedshiftSqlDialect {}), Box::new(GenericDialect {})],
|
||||||
|
options: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sharp() {
|
fn test_sharp() {
|
||||||
let sql = "SELECT #_of_values";
|
let sql = "SELECT #_of_values";
|
||||||
|
@ -281,3 +289,9 @@ fn test_sharp() {
|
||||||
select.projection[0]
|
select.projection[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_view_with_no_schema_binding() {
|
||||||
|
redshift_and_generic()
|
||||||
|
.verified_stmt("CREATE VIEW myevent AS SELECT eventname FROM event WITH NO SCHEMA BINDING");
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue