// Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #[macro_use] mod test_utils; use test_utils::*; use sqlparser::ast::*; use sqlparser::dialect::{DuckDbDialect, GenericDialect}; fn duckdb() -> TestedDialects { TestedDialects { dialects: vec![Box::new(DuckDbDialect {})], options: None, } } fn duckdb_and_generic() -> TestedDialects { TestedDialects { dialects: vec![Box::new(DuckDbDialect {}), Box::new(GenericDialect {})], options: None, } } #[test] fn test_select_wildcard_with_exclude() { let select = duckdb().verified_only_select("SELECT * EXCLUDE (col_a) FROM data"); let expected = SelectItem::Wildcard(WildcardAdditionalOptions { opt_exclude: Some(ExcludeSelectItem::Multiple(vec![Ident::new("col_a")])), ..Default::default() }); assert_eq!(expected, select.projection[0]); let select = duckdb().verified_only_select("SELECT name.* EXCLUDE department_id FROM employee_table"); let expected = SelectItem::QualifiedWildcard( ObjectName(vec![Ident::new("name")]), WildcardAdditionalOptions { opt_exclude: Some(ExcludeSelectItem::Single(Ident::new("department_id"))), ..Default::default() }, ); assert_eq!(expected, select.projection[0]); let select = duckdb() .verified_only_select("SELECT * EXCLUDE (department_id, employee_id) FROM employee_table"); let expected = SelectItem::Wildcard(WildcardAdditionalOptions { opt_exclude: Some(ExcludeSelectItem::Multiple(vec![ Ident::new("department_id"), Ident::new("employee_id"), ])), ..Default::default() }); assert_eq!(expected, select.projection[0]); } #[test] fn parse_div_infix() { duckdb_and_generic().verified_stmt(r#"SELECT 5 // 2"#); } #[test] fn test_create_macro() { let macro_ = duckdb().verified_stmt("CREATE MACRO schema.add(a, b) AS a + b"); let expected = Statement::CreateMacro { or_replace: false, temporary: false, name: ObjectName(vec![Ident::new("schema"), Ident::new("add")]), args: Some(vec![MacroArg::new("a"), MacroArg::new("b")]), definition: MacroDefinition::Expr(Expr::BinaryOp { left: Box::new(Expr::Identifier(Ident::new("a"))), op: BinaryOperator::Plus, right: Box::new(Expr::Identifier(Ident::new("b"))), }), }; assert_eq!(expected, macro_); } #[test] fn test_create_macro_default_args() { let macro_ = duckdb().verified_stmt("CREATE MACRO add_default(a, b := 5) AS a + b"); let expected = Statement::CreateMacro { or_replace: false, temporary: false, name: ObjectName(vec![Ident::new("add_default")]), args: Some(vec![ MacroArg::new("a"), MacroArg { name: Ident::new("b"), default_expr: Some(Expr::Value(Value::Number( #[cfg(not(feature = "bigdecimal"))] 5.to_string(), #[cfg(feature = "bigdecimal")] bigdecimal::BigDecimal::from(5), false, ))), }, ]), definition: MacroDefinition::Expr(Expr::BinaryOp { left: Box::new(Expr::Identifier(Ident::new("a"))), op: BinaryOperator::Plus, right: Box::new(Expr::Identifier(Ident::new("b"))), }), }; assert_eq!(expected, macro_); } #[test] fn test_create_table_macro() { let query = "SELECT col1_value AS column1, col2_value AS column2 UNION ALL SELECT 'Hello' AS col1_value, 456 AS col2_value"; let macro_ = duckdb().verified_stmt( &("CREATE OR REPLACE TEMPORARY MACRO dynamic_table(col1_value, col2_value) AS TABLE " .to_string() + query), ); let expected = Statement::CreateMacro { or_replace: true, temporary: true, name: ObjectName(vec![Ident::new("dynamic_table")]), args: Some(vec![ MacroArg::new("col1_value"), MacroArg::new("col2_value"), ]), definition: MacroDefinition::Table(duckdb().verified_query(query)), }; assert_eq!(expected, macro_); }