diff --git a/src/sqlast/ddl.rs b/src/sqlast/ddl.rs index 266a42550..e39e533be 100644 --- a/src/sqlast/ddl.rs +++ b/src/sqlast/ddl.rs @@ -1,6 +1,6 @@ //! AST types specific to CREATE/ALTER variants of `SQLStatement` //! (commonly referred to as Data Definition Language, or DDL) -use super::{ASTNode, SQLIdent, SQLObjectName, SQLType}; +use super::{Expr, SQLIdent, SQLObjectName, SQLType}; /// An `ALTER TABLE` (`SQLStatement::SQLAlterTable`) operation #[derive(Debug, Clone, PartialEq, Hash)] @@ -42,7 +42,7 @@ pub enum TableConstraint { /// `[ CONSTRAINT ] CHECK ()` Check { name: Option, - expr: Box, + expr: Box, }, } @@ -145,7 +145,7 @@ pub enum ColumnOption { /// `NOT NULL` NotNull, /// `DEFAULT ` - Default(ASTNode), + Default(Expr), /// `{ PRIMARY KEY | UNIQUE }` Unique { is_primary: bool, @@ -157,7 +157,7 @@ pub enum ColumnOption { referred_columns: Vec, }, // `CHECK ()` - Check(ASTNode), + Check(Expr), } impl ToString for ColumnOption { diff --git a/src/sqlast/mod.rs b/src/sqlast/mod.rs index 8de3a8032..34efb0f4c 100644 --- a/src/sqlast/mod.rs +++ b/src/sqlast/mod.rs @@ -53,7 +53,7 @@ pub type SQLIdent = String; /// (e.g. boolean vs string), so the caller must handle expressions of /// inappropriate type, like `WHERE 1` or `SELECT 1=1`, as necessary. #[derive(Debug, Clone, PartialEq, Hash)] -pub enum ASTNode { +pub enum Expr { /// Identifier e.g. table name or column name SQLIdentifier(SQLIdent), /// Unqualified wildcard (`*`). SQL allows this in limited contexts, such as: @@ -69,55 +69,52 @@ pub enum ASTNode { /// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col` SQLCompoundIdentifier(Vec), /// `IS NULL` expression - SQLIsNull(Box), + SQLIsNull(Box), /// `IS NOT NULL` expression - SQLIsNotNull(Box), + SQLIsNotNull(Box), /// `[ NOT ] IN (val1, val2, ...)` SQLInList { - expr: Box, - list: Vec, + expr: Box, + list: Vec, negated: bool, }, /// `[ NOT ] IN (SELECT ...)` SQLInSubquery { - expr: Box, + expr: Box, subquery: Box, negated: bool, }, /// ` [ NOT ] BETWEEN AND ` SQLBetween { - expr: Box, + expr: Box, negated: bool, - low: Box, - high: Box, + low: Box, + high: Box, }, /// Binary operation e.g. `1 + 1` or `foo > bar` SQLBinaryOp { - left: Box, + left: Box, op: SQLBinaryOperator, - right: Box, + right: Box, }, /// Unary operation e.g. `NOT foo` SQLUnaryOp { op: SQLUnaryOperator, - expr: Box, + expr: Box, }, /// CAST an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))` - SQLCast { - expr: Box, - data_type: SQLType, - }, + SQLCast { expr: Box, data_type: SQLType }, SQLExtract { field: SQLDateTimeField, - expr: Box, + expr: Box, }, /// `expr COLLATE collation` SQLCollate { - expr: Box, + expr: Box, collation: SQLObjectName, }, /// Nested expression e.g. `(foo > bar)` or `(1)` - SQLNested(Box), + SQLNested(Box), /// SQLValue SQLValue(Value), /// Scalar function call e.g. `LEFT(foo, 5)` @@ -128,10 +125,10 @@ pub enum ASTNode { /// not `< 0` nor `1, 2, 3` as allowed in a `` per /// SQLCase { - operand: Option>, - conditions: Vec, - results: Vec, - else_result: Option>, + operand: Option>, + conditions: Vec, + results: Vec, + else_result: Option>, }, /// An exists expression `EXISTS(SELECT ...)`, used in expressions like /// `WHERE EXISTS (SELECT ...)`. @@ -141,16 +138,16 @@ pub enum ASTNode { SQLSubquery(Box), } -impl ToString for ASTNode { +impl ToString for Expr { fn to_string(&self) -> String { match self { - ASTNode::SQLIdentifier(s) => s.to_string(), - ASTNode::SQLWildcard => "*".to_string(), - ASTNode::SQLQualifiedWildcard(q) => q.join(".") + ".*", - ASTNode::SQLCompoundIdentifier(s) => s.join("."), - ASTNode::SQLIsNull(ast) => format!("{} IS NULL", ast.as_ref().to_string()), - ASTNode::SQLIsNotNull(ast) => format!("{} IS NOT NULL", ast.as_ref().to_string()), - ASTNode::SQLInList { + Expr::SQLIdentifier(s) => s.to_string(), + Expr::SQLWildcard => "*".to_string(), + Expr::SQLQualifiedWildcard(q) => q.join(".") + ".*", + Expr::SQLCompoundIdentifier(s) => s.join("."), + Expr::SQLIsNull(ast) => format!("{} IS NULL", ast.as_ref().to_string()), + Expr::SQLIsNotNull(ast) => format!("{} IS NOT NULL", ast.as_ref().to_string()), + Expr::SQLInList { expr, list, negated, @@ -160,7 +157,7 @@ impl ToString for ASTNode { if *negated { "NOT " } else { "" }, comma_separated_string(list) ), - ASTNode::SQLInSubquery { + Expr::SQLInSubquery { expr, subquery, negated, @@ -170,7 +167,7 @@ impl ToString for ASTNode { if *negated { "NOT " } else { "" }, subquery.to_string() ), - ASTNode::SQLBetween { + Expr::SQLBetween { expr, negated, low, @@ -182,32 +179,32 @@ impl ToString for ASTNode { low.to_string(), high.to_string() ), - ASTNode::SQLBinaryOp { left, op, right } => format!( + Expr::SQLBinaryOp { left, op, right } => format!( "{} {} {}", left.as_ref().to_string(), op.to_string(), right.as_ref().to_string() ), - ASTNode::SQLUnaryOp { op, expr } => { + Expr::SQLUnaryOp { op, expr } => { format!("{} {}", op.to_string(), expr.as_ref().to_string()) } - ASTNode::SQLCast { expr, data_type } => format!( + Expr::SQLCast { expr, data_type } => format!( "CAST({} AS {})", expr.as_ref().to_string(), data_type.to_string() ), - ASTNode::SQLExtract { field, expr } => { + Expr::SQLExtract { field, expr } => { format!("EXTRACT({} FROM {})", field.to_string(), expr.to_string()) } - ASTNode::SQLCollate { expr, collation } => format!( + Expr::SQLCollate { expr, collation } => format!( "{} COLLATE {}", expr.as_ref().to_string(), collation.to_string() ), - ASTNode::SQLNested(ast) => format!("({})", ast.as_ref().to_string()), - ASTNode::SQLValue(v) => v.to_string(), - ASTNode::SQLFunction(f) => f.to_string(), - ASTNode::SQLCase { + Expr::SQLNested(ast) => format!("({})", ast.as_ref().to_string()), + Expr::SQLValue(v) => v.to_string(), + Expr::SQLFunction(f) => f.to_string(), + Expr::SQLCase { operand, conditions, results, @@ -228,8 +225,8 @@ impl ToString for ASTNode { } s + " END" } - ASTNode::SQLExists(s) => format!("EXISTS ({})", s.to_string()), - ASTNode::SQLSubquery(s) => format!("({})", s.to_string()), + Expr::SQLExists(s) => format!("EXISTS ({})", s.to_string()), + Expr::SQLSubquery(s) => format!("({})", s.to_string()), } } } @@ -237,7 +234,7 @@ impl ToString for ASTNode { /// A window specification (i.e. `OVER (PARTITION BY .. ORDER BY .. etc.)`) #[derive(Debug, Clone, PartialEq, Hash)] pub struct SQLWindowSpec { - pub partition_by: Vec, + pub partition_by: Vec, pub order_by: Vec, pub window_frame: Option, } @@ -374,14 +371,14 @@ pub enum SQLStatement { /// Column assignments assignments: Vec, /// WHERE - selection: Option, + selection: Option, }, /// DELETE SQLDelete { /// FROM table_name: SQLObjectName, /// WHERE - selection: Option, + selection: Option, }, /// CREATE VIEW SQLCreateView { @@ -604,7 +601,7 @@ impl ToString for SQLObjectName { #[derive(Debug, Clone, PartialEq, Hash)] pub struct SQLAssignment { pub id: SQLIdent, - pub value: ASTNode, + pub value: Expr, } impl ToString for SQLAssignment { @@ -617,7 +614,7 @@ impl ToString for SQLAssignment { #[derive(Debug, Clone, PartialEq, Hash)] pub struct SQLFunction { pub name: SQLObjectName, - pub args: Vec, + pub args: Vec, pub over: Option, // aggregate functions may specify eg `COUNT(DISTINCT x)` pub distinct: bool, diff --git a/src/sqlast/query.rs b/src/sqlast/query.rs index 4c23c0af1..c02447a9b 100644 --- a/src/sqlast/query.rs +++ b/src/sqlast/query.rs @@ -23,9 +23,9 @@ pub struct SQLQuery { /// ORDER BY pub order_by: Vec, /// `LIMIT { | ALL }` - pub limit: Option, + pub limit: Option, /// `OFFSET { ROW | ROWS }` - pub offset: Option, + pub offset: Option, /// `FETCH { FIRST | NEXT } [ PERCENT ] { ROW | ROWS } | { ONLY | WITH TIES }` pub fetch: Option, } @@ -127,11 +127,11 @@ pub struct SQLSelect { /// FROM pub from: Vec, /// WHERE - pub selection: Option, + pub selection: Option, /// GROUP BY - pub group_by: Vec, + pub group_by: Vec, /// HAVING - pub having: Option, + pub having: Option, } impl ToString for SQLSelect { @@ -177,9 +177,9 @@ impl ToString for Cte { #[derive(Debug, Clone, PartialEq, Hash)] pub enum SQLSelectItem { /// Any expression, not followed by `[ AS ] alias` - UnnamedExpression(ASTNode), + UnnamedExpr(Expr), /// An expression, followed by `[ AS ] alias` - ExpressionWithAlias { expr: ASTNode, alias: SQLIdent }, + ExprWithAlias { expr: Expr, alias: SQLIdent }, /// `alias.*` or even `schema.table.*` QualifiedWildcard(SQLObjectName), /// An unqualified `*` @@ -189,8 +189,8 @@ pub enum SQLSelectItem { impl ToString for SQLSelectItem { fn to_string(&self) -> String { match &self { - SQLSelectItem::UnnamedExpression(expr) => expr.to_string(), - SQLSelectItem::ExpressionWithAlias { expr, alias } => { + SQLSelectItem::UnnamedExpr(expr) => expr.to_string(), + SQLSelectItem::ExprWithAlias { expr, alias } => { format!("{} AS {}", expr.to_string(), alias) } SQLSelectItem::QualifiedWildcard(prefix) => format!("{}.*", prefix.to_string()), @@ -224,9 +224,9 @@ pub enum TableFactor { /// Arguments of a table-valued function, as supported by Postgres /// and MSSQL. Note that deprecated MSSQL `FROM foo (NOLOCK)` syntax /// will also be parsed as `args`. - args: Vec, + args: Vec, /// MSSQL-specific `WITH (...)` hints such as NOLOCK. - with_hints: Vec, + with_hints: Vec, }, Derived { lateral: bool, @@ -361,7 +361,7 @@ pub enum JoinOperator { #[derive(Debug, Clone, PartialEq, Hash)] pub enum JoinConstraint { - On(ASTNode), + On(Expr), Using(Vec), Natural, } @@ -369,7 +369,7 @@ pub enum JoinConstraint { /// SQL ORDER BY expression #[derive(Debug, Clone, PartialEq, Hash)] pub struct SQLOrderByExpr { - pub expr: ASTNode, + pub expr: Expr, pub asc: Option, } @@ -387,7 +387,7 @@ impl ToString for SQLOrderByExpr { pub struct Fetch { pub with_ties: bool, pub percent: bool, - pub quantity: Option, + pub quantity: Option, } impl ToString for Fetch { @@ -408,7 +408,7 @@ impl ToString for Fetch { } #[derive(Debug, Clone, PartialEq, Hash)] -pub struct SQLValues(pub Vec>); +pub struct SQLValues(pub Vec>); impl ToString for SQLValues { fn to_string(&self) -> String { diff --git a/src/sqlparser.rs b/src/sqlparser.rs index 7802e5b85..a3ffd7ea3 100644 --- a/src/sqlparser.rs +++ b/src/sqlparser.rs @@ -151,12 +151,12 @@ impl Parser { } /// Parse a new expression - pub fn parse_expr(&mut self) -> Result { + pub fn parse_expr(&mut self) -> Result { self.parse_subexpr(0) } /// Parse tokens until the precedence changes - pub fn parse_subexpr(&mut self, precedence: u8) -> Result { + pub fn parse_subexpr(&mut self, precedence: u8) -> Result { debug!("parsing expr"); let mut expr = self.parse_prefix()?; debug!("prefix: {:?}", expr); @@ -173,7 +173,7 @@ impl Parser { } /// Parse an expression prefix - pub fn parse_prefix(&mut self) -> Result { + pub fn parse_prefix(&mut self) -> Result { let tok = self .next_token() .ok_or_else(|| ParserError::ParserError("Unexpected EOF".to_string()))?; @@ -183,18 +183,18 @@ impl Parser { self.prev_token(); self.parse_sql_value() } - "CASE" => self.parse_case_expression(), - "CAST" => self.parse_cast_expression(), - "DATE" => Ok(ASTNode::SQLValue(Value::Date(self.parse_literal_string()?))), - "EXISTS" => self.parse_exists_expression(), - "EXTRACT" => self.parse_extract_expression(), + "CASE" => self.parse_case_expr(), + "CAST" => self.parse_cast_expr(), + "DATE" => Ok(Expr::SQLValue(Value::Date(self.parse_literal_string()?))), + "EXISTS" => self.parse_exists_expr(), + "EXTRACT" => self.parse_extract_expr(), "INTERVAL" => self.parse_literal_interval(), - "NOT" => Ok(ASTNode::SQLUnaryOp { + "NOT" => Ok(Expr::SQLUnaryOp { op: SQLUnaryOperator::Not, expr: Box::new(self.parse_subexpr(Self::UNARY_NOT_PREC)?), }), - "TIME" => Ok(ASTNode::SQLValue(Value::Time(self.parse_literal_string()?))), - "TIMESTAMP" => Ok(ASTNode::SQLValue(Value::Timestamp( + "TIME" => Ok(Expr::SQLValue(Value::Time(self.parse_literal_string()?))), + "TIMESTAMP" => Ok(Expr::SQLValue(Value::Timestamp( self.parse_literal_string()?, ))), // Here `w` is a word, check if it's a part of a multi-part @@ -217,25 +217,25 @@ impl Parser { } } if ends_with_wildcard { - Ok(ASTNode::SQLQualifiedWildcard(id_parts)) + Ok(Expr::SQLQualifiedWildcard(id_parts)) } else if self.consume_token(&Token::LParen) { self.prev_token(); self.parse_function(SQLObjectName(id_parts)) } else { - Ok(ASTNode::SQLCompoundIdentifier(id_parts)) + Ok(Expr::SQLCompoundIdentifier(id_parts)) } } - _ => Ok(ASTNode::SQLIdentifier(w.as_sql_ident())), + _ => Ok(Expr::SQLIdentifier(w.as_sql_ident())), }, }, // End of Token::SQLWord - Token::Mult => Ok(ASTNode::SQLWildcard), + Token::Mult => Ok(Expr::SQLWildcard), tok @ Token::Minus | tok @ Token::Plus => { let op = if tok == Token::Plus { SQLUnaryOperator::Plus } else { SQLUnaryOperator::Minus }; - Ok(ASTNode::SQLUnaryOp { + Ok(Expr::SQLUnaryOp { op, expr: Box::new(self.parse_subexpr(Self::PLUS_MINUS_PREC)?), }) @@ -250,9 +250,9 @@ impl Parser { Token::LParen => { let expr = if self.parse_keyword("SELECT") || self.parse_keyword("WITH") { self.prev_token(); - ASTNode::SQLSubquery(Box::new(self.parse_query()?)) + Expr::SQLSubquery(Box::new(self.parse_query()?)) } else { - ASTNode::SQLNested(Box::new(self.parse_expr()?)) + Expr::SQLNested(Box::new(self.parse_expr()?)) }; self.expect_token(&Token::RParen)?; Ok(expr) @@ -261,7 +261,7 @@ impl Parser { }?; if self.parse_keyword("COLLATE") { - Ok(ASTNode::SQLCollate { + Ok(Expr::SQLCollate { expr: Box::new(expr), collation: self.parse_object_name()?, }) @@ -270,7 +270,7 @@ impl Parser { } } - pub fn parse_function(&mut self, name: SQLObjectName) -> Result { + pub fn parse_function(&mut self, name: SQLObjectName) -> Result { self.expect_token(&Token::LParen)?; let all = self.parse_keyword("ALL"); let distinct = self.parse_keyword("DISTINCT"); @@ -306,7 +306,7 @@ impl Parser { None }; - Ok(ASTNode::SQLFunction(SQLFunction { + Ok(Expr::SQLFunction(SQLFunction { name, args, over, @@ -366,7 +366,7 @@ impl Parser { } } - pub fn parse_case_expression(&mut self) -> Result { + pub fn parse_case_expr(&mut self) -> Result { let mut operand = None; if !self.parse_keyword("WHEN") { operand = Some(Box::new(self.parse_expr()?)); @@ -388,7 +388,7 @@ impl Parser { None }; self.expect_keyword("END")?; - Ok(ASTNode::SQLCase { + Ok(Expr::SQLCase { operand, conditions, results, @@ -397,33 +397,33 @@ impl Parser { } /// Parse a SQL CAST function e.g. `CAST(expr AS FLOAT)` - pub fn parse_cast_expression(&mut self) -> Result { + pub fn parse_cast_expr(&mut self) -> Result { self.expect_token(&Token::LParen)?; let expr = self.parse_expr()?; self.expect_keyword("AS")?; let data_type = self.parse_data_type()?; self.expect_token(&Token::RParen)?; - Ok(ASTNode::SQLCast { + Ok(Expr::SQLCast { expr: Box::new(expr), data_type, }) } /// Parse a SQL EXISTS expression e.g. `WHERE EXISTS(SELECT ...)`. - pub fn parse_exists_expression(&mut self) -> Result { + pub fn parse_exists_expr(&mut self) -> Result { self.expect_token(&Token::LParen)?; - let exists_node = ASTNode::SQLExists(Box::new(self.parse_query()?)); + let exists_node = Expr::SQLExists(Box::new(self.parse_query()?)); self.expect_token(&Token::RParen)?; Ok(exists_node) } - pub fn parse_extract_expression(&mut self) -> Result { + pub fn parse_extract_expr(&mut self) -> Result { self.expect_token(&Token::LParen)?; let field = self.parse_date_time_field()?; self.expect_keyword("FROM")?; let expr = self.parse_expr()?; self.expect_token(&Token::RParen)?; - Ok(ASTNode::SQLExtract { + Ok(Expr::SQLExtract { field, expr: Box::new(expr), }) @@ -462,7 +462,7 @@ impl Parser { /// 6. `INTERVAL '1:1' HOUR (5) TO MINUTE (5)` /// /// Note that we do not currently attempt to parse the quoted value. - pub fn parse_literal_interval(&mut self) -> Result { + pub fn parse_literal_interval(&mut self) -> Result { // The SQL standard allows an optional sign before the value string, but // it is not clear if any implementations support that syntax, so we // don't currently try to parse it. (The sign can instead be included @@ -504,7 +504,7 @@ impl Parser { } }; - Ok(ASTNode::SQLValue(Value::Interval { + Ok(Expr::SQLValue(Value::Interval { value, leading_field, leading_precision, @@ -514,7 +514,7 @@ impl Parser { } /// Parse an operator following an expression - pub fn parse_infix(&mut self, expr: ASTNode, precedence: u8) -> Result { + pub fn parse_infix(&mut self, expr: Expr, precedence: u8) -> Result { debug!("parsing infix"); let tok = self.next_token().unwrap(); // safe as EOF's precedence is the lowest @@ -547,7 +547,7 @@ impl Parser { }; if let Some(op) = regular_binary_operator { - Ok(ASTNode::SQLBinaryOp { + Ok(Expr::SQLBinaryOp { left: Box::new(expr), op, right: Box::new(self.parse_subexpr(precedence)?), @@ -556,9 +556,9 @@ impl Parser { match k.keyword.as_ref() { "IS" => { if self.parse_keyword("NULL") { - Ok(ASTNode::SQLIsNull(Box::new(expr))) + Ok(Expr::SQLIsNull(Box::new(expr))) } else if self.parse_keywords(vec!["NOT", "NULL"]) { - Ok(ASTNode::SQLIsNotNull(Box::new(expr))) + Ok(Expr::SQLIsNotNull(Box::new(expr))) } else { self.expected("NULL or NOT NULL after IS", self.peek_token()) } @@ -586,17 +586,17 @@ impl Parser { } /// Parses the parens following the `[ NOT ] IN` operator - pub fn parse_in(&mut self, expr: ASTNode, negated: bool) -> Result { + pub fn parse_in(&mut self, expr: Expr, negated: bool) -> Result { self.expect_token(&Token::LParen)?; let in_op = if self.parse_keyword("SELECT") || self.parse_keyword("WITH") { self.prev_token(); - ASTNode::SQLInSubquery { + Expr::SQLInSubquery { expr: Box::new(expr), subquery: Box::new(self.parse_query()?), negated, } } else { - ASTNode::SQLInList { + Expr::SQLInList { expr: Box::new(expr), list: self.parse_expr_list()?, negated, @@ -607,13 +607,13 @@ impl Parser { } /// Parses `BETWEEN AND `, assuming the `BETWEEN` keyword was already consumed - pub fn parse_between(&mut self, expr: ASTNode, negated: bool) -> Result { + pub fn parse_between(&mut self, expr: Expr, negated: bool) -> Result { // Stop parsing subexpressions for and on tokens with // precedence lower than that of `BETWEEN`, such as `AND`, `IS`, etc. let low = self.parse_subexpr(Self::BETWEEN_PREC)?; self.expect_keyword("AND")?; let high = self.parse_subexpr(Self::BETWEEN_PREC)?; - Ok(ASTNode::SQLBetween { + Ok(Expr::SQLBetween { expr: Box::new(expr), negated, low: Box::new(low), @@ -622,8 +622,8 @@ impl Parser { } /// Parse a postgresql casting style which is in the form of `expr::datatype` - pub fn parse_pg_cast(&mut self, expr: ASTNode) -> Result { - Ok(ASTNode::SQLCast { + pub fn parse_pg_cast(&mut self, expr: Expr) -> Result { + Ok(Expr::SQLCast { expr: Box::new(expr), data_type: self.parse_data_type()?, }) @@ -1132,8 +1132,8 @@ impl Parser { Ok(values) } - fn parse_sql_value(&mut self) -> Result { - Ok(ASTNode::SQLValue(self.parse_value()?)) + fn parse_sql_value(&mut self) -> Result { + Ok(Expr::SQLValue(self.parse_value()?)) } fn parse_tab_value(&mut self) -> Result>, ParserError> { @@ -1826,8 +1826,8 @@ impl Parser { } /// Parse a comma-delimited list of SQL expressions - pub fn parse_expr_list(&mut self) -> Result, ParserError> { - let mut expr_list: Vec = vec![]; + pub fn parse_expr_list(&mut self) -> Result, ParserError> { + let mut expr_list: Vec = vec![]; loop { expr_list.push(self.parse_expr()?); if !self.consume_token(&Token::Comma) { @@ -1837,7 +1837,7 @@ impl Parser { Ok(expr_list) } - pub fn parse_optional_args(&mut self) -> Result, ParserError> { + pub fn parse_optional_args(&mut self) -> Result, ParserError> { if self.consume_token(&Token::RParen) { Ok(vec![]) } else { @@ -1852,18 +1852,18 @@ impl Parser { let mut projections: Vec = vec![]; loop { let expr = self.parse_expr()?; - if let ASTNode::SQLWildcard = expr { + if let Expr::SQLWildcard = expr { projections.push(SQLSelectItem::Wildcard); - } else if let ASTNode::SQLQualifiedWildcard(prefix) = expr { + } else if let Expr::SQLQualifiedWildcard(prefix) = expr { projections.push(SQLSelectItem::QualifiedWildcard(SQLObjectName(prefix))); } else { // `expr` is a regular SQL expression and can be followed by an alias if let Some(alias) = self.parse_optional_alias(keywords::RESERVED_FOR_COLUMN_ALIAS)? { - projections.push(SQLSelectItem::ExpressionWithAlias { expr, alias }); + projections.push(SQLSelectItem::ExprWithAlias { expr, alias }); } else { - projections.push(SQLSelectItem::UnnamedExpression(expr)); + projections.push(SQLSelectItem::UnnamedExpr(expr)); } } @@ -1897,20 +1897,20 @@ impl Parser { } /// Parse a LIMIT clause - pub fn parse_limit(&mut self) -> Result, ParserError> { + pub fn parse_limit(&mut self) -> Result, ParserError> { if self.parse_keyword("ALL") { Ok(None) } else { self.parse_literal_uint() - .map(|n| Some(ASTNode::SQLValue(Value::Long(n)))) + .map(|n| Some(Expr::SQLValue(Value::Long(n)))) } } /// Parse an OFFSET clause - pub fn parse_offset(&mut self) -> Result { + pub fn parse_offset(&mut self) -> Result { let value = self .parse_literal_uint() - .map(|n| ASTNode::SQLValue(Value::Long(n)))?; + .map(|n| Expr::SQLValue(Value::Long(n)))?; self.expect_one_of_keywords(&["ROW", "ROWS"])?; Ok(value) } diff --git a/src/test_utils.rs b/src/test_utils.rs index 09065b269..5f738d4f2 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -103,7 +103,7 @@ impl TestedDialects { /// Ensures that `sql` parses as an expression, and is not modified /// after a serialization round-trip. - pub fn verified_expr(&self, sql: &str) -> ASTNode { + pub fn verified_expr(&self, sql: &str) -> Expr { let ast = self.run_parser_method(sql, Parser::parse_expr).unwrap(); assert_eq!(sql, &ast.to_string(), "round-tripping without changes"); ast @@ -130,9 +130,9 @@ pub fn only(v: impl IntoIterator) -> T { } } -pub fn expr_from_projection(item: &SQLSelectItem) -> &ASTNode { +pub fn expr_from_projection(item: &SQLSelectItem) -> &Expr { match item { - SQLSelectItem::UnnamedExpression(expr) => expr, - _ => panic!("Expected UnnamedExpression"), + SQLSelectItem::UnnamedExpr(expr) => expr, + _ => panic!("Expected UnnamedExpr"), } } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 139c91e07..c115ea5f6 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -27,9 +27,9 @@ use sqlparser::test_utils::{all_dialects, expr_from_projection, only}; #[test] fn parse_insert_values() { let row = vec![ - ASTNode::SQLValue(Value::Long(1)), - ASTNode::SQLValue(Value::Long(2)), - ASTNode::SQLValue(Value::Long(3)), + Expr::SQLValue(Value::Long(1)), + Expr::SQLValue(Value::Long(2)), + Expr::SQLValue(Value::Long(3)), ]; let rows1 = vec![row.clone()]; let rows2 = vec![row.clone(), row]; @@ -58,7 +58,7 @@ fn parse_insert_values() { sql: &str, expected_table_name: &str, expected_columns: &[String], - expected_rows: &[Vec], + expected_rows: &[Vec], ) { match verified_stmt(sql) { SQLStatement::SQLInsert { @@ -109,19 +109,19 @@ fn parse_update() { vec![ SQLAssignment { id: "a".into(), - value: ASTNode::SQLValue(Value::Long(1)), + value: Expr::SQLValue(Value::Long(1)), }, SQLAssignment { id: "b".into(), - value: ASTNode::SQLValue(Value::Long(2)), + value: Expr::SQLValue(Value::Long(2)), }, SQLAssignment { id: "c".into(), - value: ASTNode::SQLValue(Value::Long(3)), + value: Expr::SQLValue(Value::Long(3)), }, ] ); - assert_eq!(selection.unwrap(), ASTNode::SQLIdentifier("d".into())); + assert_eq!(selection.unwrap(), Expr::SQLIdentifier("d".into())); } _ => unreachable!(), } @@ -168,7 +168,7 @@ fn parse_delete_statement() { #[test] fn parse_where_delete_statement() { - use self::ASTNode::*; + use self::Expr::*; use self::SQLBinaryOperator::*; let sql = "DELETE FROM foo WHERE name = 5"; @@ -208,17 +208,17 @@ fn parse_simple_select() { assert_eq!(false, select.distinct); assert_eq!(3, select.projection.len()); let select = verified_query(sql); - assert_eq!(Some(ASTNode::SQLValue(Value::Long(5))), select.limit); + assert_eq!(Some(Expr::SQLValue(Value::Long(5))), select.limit); } #[test] fn parse_limit_is_not_an_alias() { // In dialects supporting LIMIT it shouldn't be parsed as a table alias let ast = verified_query("SELECT id FROM customer LIMIT 1"); - assert_eq!(Some(ASTNode::SQLValue(Value::Long(1))), ast.limit); + assert_eq!(Some(Expr::SQLValue(Value::Long(1))), ast.limit); let ast = verified_query("SELECT 1 LIMIT 5"); - assert_eq!(Some(ASTNode::SQLValue(Value::Long(5))), ast.limit); + assert_eq!(Some(Expr::SQLValue(Value::Long(5))), ast.limit); } #[test] @@ -227,7 +227,7 @@ fn parse_select_distinct() { let select = verified_only_select(sql); assert_eq!(true, select.distinct); assert_eq!( - &SQLSelectItem::UnnamedExpression(ASTNode::SQLIdentifier("name".to_string())), + &SQLSelectItem::UnnamedExpr(Expr::SQLIdentifier("name".to_string())), only(&select.projection) ); } @@ -281,18 +281,18 @@ fn parse_count_wildcard() { fn parse_column_aliases() { let sql = "SELECT a.col + 1 AS newname FROM foo AS a"; let select = verified_only_select(sql); - if let SQLSelectItem::ExpressionWithAlias { - expr: ASTNode::SQLBinaryOp { + if let SQLSelectItem::ExprWithAlias { + expr: Expr::SQLBinaryOp { ref op, ref right, .. }, ref alias, } = only(&select.projection) { assert_eq!(&SQLBinaryOperator::Plus, op); - assert_eq!(&ASTNode::SQLValue(Value::Long(1)), right.as_ref()); + assert_eq!(&Expr::SQLValue(Value::Long(1)), right.as_ref()); assert_eq!("newname", alias); } else { - panic!("Expected ExpressionWithAlias") + panic!("Expected ExprWithAlias") } // alias without AS is parsed correctly: @@ -319,9 +319,9 @@ fn parse_select_count_wildcard() { let sql = "SELECT COUNT(*) FROM customer"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLFunction(SQLFunction { + &Expr::SQLFunction(SQLFunction { name: SQLObjectName(vec!["COUNT".to_string()]), - args: vec![ASTNode::SQLWildcard], + args: vec![Expr::SQLWildcard], over: None, distinct: false, }), @@ -334,11 +334,11 @@ fn parse_select_count_distinct() { let sql = "SELECT COUNT(DISTINCT + x) FROM customer"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLFunction(SQLFunction { + &Expr::SQLFunction(SQLFunction { name: SQLObjectName(vec!["COUNT".to_string()]), - args: vec![ASTNode::SQLUnaryOp { + args: vec![Expr::SQLUnaryOp { op: SQLUnaryOperator::Plus, - expr: Box::new(ASTNode::SQLIdentifier("x".to_string())) + expr: Box::new(Expr::SQLIdentifier("x".to_string())) }], over: None, distinct: true, @@ -382,7 +382,7 @@ fn parse_collate() { let sql = "SELECT name COLLATE \"de_DE\" FROM customer"; assert_matches!( only(&all_dialects().verified_only_select(sql).projection), - SQLSelectItem::UnnamedExpression(ASTNode::SQLCollate { .. }) + SQLSelectItem::UnnamedExpr(Expr::SQLCollate { .. }) ); } @@ -406,14 +406,14 @@ fn parse_null_in_select() { let sql = "SELECT NULL"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLValue(Value::Null), + &Expr::SQLValue(Value::Null), expr_from_projection(only(&select.projection)), ); } #[test] fn parse_escaped_single_quote_string_predicate() { - use self::ASTNode::*; + use self::Expr::*; use self::SQLBinaryOperator::*; let sql = "SELECT id, fname, lname FROM customer \ WHERE salary <> 'Jim''s salary'"; @@ -432,7 +432,7 @@ fn parse_escaped_single_quote_string_predicate() { #[test] fn parse_compound_expr_1() { - use self::ASTNode::*; + use self::Expr::*; use self::SQLBinaryOperator::*; let sql = "a + b * c"; assert_eq!( @@ -451,7 +451,7 @@ fn parse_compound_expr_1() { #[test] fn parse_compound_expr_2() { - use self::ASTNode::*; + use self::Expr::*; use self::SQLBinaryOperator::*; let sql = "a * b + c"; assert_eq!( @@ -470,7 +470,7 @@ fn parse_compound_expr_2() { #[test] fn parse_unary_math() { - use self::ASTNode::*; + use self::Expr::*; let sql = "- a + - b"; assert_eq!( SQLBinaryOp { @@ -490,7 +490,7 @@ fn parse_unary_math() { #[test] fn parse_is_null() { - use self::ASTNode::*; + use self::Expr::*; let sql = "a IS NULL"; assert_eq!( SQLIsNull(Box::new(SQLIdentifier("a".to_string()))), @@ -500,7 +500,7 @@ fn parse_is_null() { #[test] fn parse_is_not_null() { - use self::ASTNode::*; + use self::Expr::*; let sql = "a IS NOT NULL"; assert_eq!( SQLIsNotNull(Box::new(SQLIdentifier("a".to_string()))), @@ -510,7 +510,7 @@ fn parse_is_not_null() { #[test] fn parse_not_precedence() { - use self::ASTNode::*; + use self::Expr::*; // NOT has higher precedence than OR/AND, so the following must parse as (NOT true) OR true let sql = "NOT true OR true"; assert_matches!(verified_expr(sql), SQLBinaryOp { @@ -578,16 +578,14 @@ fn parse_like() { ); let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLBinaryOp { - left: Box::new(ASTNode::SQLIdentifier("name".to_string())), + Expr::SQLBinaryOp { + left: Box::new(Expr::SQLIdentifier("name".to_string())), op: if negated { SQLBinaryOperator::NotLike } else { SQLBinaryOperator::Like }, - right: Box::new(ASTNode::SQLValue(Value::SingleQuotedString( - "%a".to_string() - ))), + right: Box::new(Expr::SQLValue(Value::SingleQuotedString("%a".to_string()))), }, select.selection.unwrap() ); @@ -600,16 +598,14 @@ fn parse_like() { ); let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLIsNull(Box::new(ASTNode::SQLBinaryOp { - left: Box::new(ASTNode::SQLIdentifier("name".to_string())), + Expr::SQLIsNull(Box::new(Expr::SQLBinaryOp { + left: Box::new(Expr::SQLIdentifier("name".to_string())), op: if negated { SQLBinaryOperator::NotLike } else { SQLBinaryOperator::Like }, - right: Box::new(ASTNode::SQLValue(Value::SingleQuotedString( - "%a".to_string() - ))), + right: Box::new(Expr::SQLValue(Value::SingleQuotedString("%a".to_string()))), })), select.selection.unwrap() ); @@ -627,11 +623,11 @@ fn parse_in_list() { ); let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLInList { - expr: Box::new(ASTNode::SQLIdentifier("segment".to_string())), + Expr::SQLInList { + expr: Box::new(Expr::SQLIdentifier("segment".to_string())), list: vec![ - ASTNode::SQLValue(Value::SingleQuotedString("HIGH".to_string())), - ASTNode::SQLValue(Value::SingleQuotedString("MED".to_string())), + Expr::SQLValue(Value::SingleQuotedString("HIGH".to_string())), + Expr::SQLValue(Value::SingleQuotedString("MED".to_string())), ], negated, }, @@ -647,8 +643,8 @@ fn parse_in_subquery() { let sql = "SELECT * FROM customers WHERE segment IN (SELECT segm FROM bar)"; let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLInSubquery { - expr: Box::new(ASTNode::SQLIdentifier("segment".to_string())), + Expr::SQLInSubquery { + expr: Box::new(Expr::SQLIdentifier("segment".to_string())), subquery: Box::new(verified_query("SELECT segm FROM bar")), negated: false, }, @@ -665,10 +661,10 @@ fn parse_between() { ); let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLBetween { - expr: Box::new(ASTNode::SQLIdentifier("age".to_string())), - low: Box::new(ASTNode::SQLValue(Value::Long(25))), - high: Box::new(ASTNode::SQLValue(Value::Long(32))), + Expr::SQLBetween { + expr: Box::new(Expr::SQLIdentifier("age".to_string())), + low: Box::new(Expr::SQLValue(Value::Long(25))), + high: Box::new(Expr::SQLValue(Value::Long(32))), negated, }, select.selection.unwrap() @@ -680,22 +676,22 @@ fn parse_between() { #[test] fn parse_between_with_expr() { - use self::ASTNode::*; + use self::Expr::*; use self::SQLBinaryOperator::*; let sql = "SELECT * FROM t WHERE 1 BETWEEN 1 + 2 AND 3 + 4 IS NULL"; let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLIsNull(Box::new(ASTNode::SQLBetween { - expr: Box::new(ASTNode::SQLValue(Value::Long(1))), + Expr::SQLIsNull(Box::new(Expr::SQLBetween { + expr: Box::new(Expr::SQLValue(Value::Long(1))), low: Box::new(SQLBinaryOp { - left: Box::new(ASTNode::SQLValue(Value::Long(1))), + left: Box::new(Expr::SQLValue(Value::Long(1))), op: Plus, - right: Box::new(ASTNode::SQLValue(Value::Long(2))), + right: Box::new(Expr::SQLValue(Value::Long(2))), }), high: Box::new(SQLBinaryOp { - left: Box::new(ASTNode::SQLValue(Value::Long(3))), + left: Box::new(Expr::SQLValue(Value::Long(3))), op: Plus, - right: Box::new(ASTNode::SQLValue(Value::Long(4))), + right: Box::new(Expr::SQLValue(Value::Long(4))), }), negated: false, })), @@ -705,21 +701,21 @@ fn parse_between_with_expr() { let sql = "SELECT * FROM t WHERE 1 = 1 AND 1 + x BETWEEN 1 AND 2"; let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLBinaryOp { - left: Box::new(ASTNode::SQLBinaryOp { - left: Box::new(ASTNode::SQLValue(Value::Long(1))), + Expr::SQLBinaryOp { + left: Box::new(Expr::SQLBinaryOp { + left: Box::new(Expr::SQLValue(Value::Long(1))), op: SQLBinaryOperator::Eq, - right: Box::new(ASTNode::SQLValue(Value::Long(1))), + right: Box::new(Expr::SQLValue(Value::Long(1))), }), op: SQLBinaryOperator::And, - right: Box::new(ASTNode::SQLBetween { - expr: Box::new(ASTNode::SQLBinaryOp { - left: Box::new(ASTNode::SQLValue(Value::Long(1))), + right: Box::new(Expr::SQLBetween { + expr: Box::new(Expr::SQLBinaryOp { + left: Box::new(Expr::SQLValue(Value::Long(1))), op: SQLBinaryOperator::Plus, - right: Box::new(ASTNode::SQLIdentifier("x".to_string())), + right: Box::new(Expr::SQLIdentifier("x".to_string())), }), - low: Box::new(ASTNode::SQLValue(Value::Long(1))), - high: Box::new(ASTNode::SQLValue(Value::Long(2))), + low: Box::new(Expr::SQLValue(Value::Long(1))), + high: Box::new(Expr::SQLValue(Value::Long(2))), negated: false, }), }, @@ -734,15 +730,15 @@ fn parse_select_order_by() { assert_eq!( vec![ SQLOrderByExpr { - expr: ASTNode::SQLIdentifier("lname".to_string()), + expr: Expr::SQLIdentifier("lname".to_string()), asc: Some(true), }, SQLOrderByExpr { - expr: ASTNode::SQLIdentifier("fname".to_string()), + expr: Expr::SQLIdentifier("fname".to_string()), asc: Some(false), }, SQLOrderByExpr { - expr: ASTNode::SQLIdentifier("id".to_string()), + expr: Expr::SQLIdentifier("id".to_string()), asc: None, }, ], @@ -763,17 +759,17 @@ fn parse_select_order_by_limit() { assert_eq!( vec![ SQLOrderByExpr { - expr: ASTNode::SQLIdentifier("lname".to_string()), + expr: Expr::SQLIdentifier("lname".to_string()), asc: Some(true), }, SQLOrderByExpr { - expr: ASTNode::SQLIdentifier("fname".to_string()), + expr: Expr::SQLIdentifier("fname".to_string()), asc: Some(false), }, ], select.order_by ); - assert_eq!(Some(ASTNode::SQLValue(Value::Long(2))), select.limit); + assert_eq!(Some(Expr::SQLValue(Value::Long(2))), select.limit); } #[test] @@ -782,8 +778,8 @@ fn parse_select_group_by() { let select = verified_only_select(sql); assert_eq!( vec![ - ASTNode::SQLIdentifier("lname".to_string()), - ASTNode::SQLIdentifier("fname".to_string()), + Expr::SQLIdentifier("lname".to_string()), + Expr::SQLIdentifier("fname".to_string()), ], select.group_by ); @@ -794,15 +790,15 @@ fn parse_select_having() { let sql = "SELECT foo FROM bar GROUP BY foo HAVING COUNT(*) > 1"; let select = verified_only_select(sql); assert_eq!( - Some(ASTNode::SQLBinaryOp { - left: Box::new(ASTNode::SQLFunction(SQLFunction { + Some(Expr::SQLBinaryOp { + left: Box::new(Expr::SQLFunction(SQLFunction { name: SQLObjectName(vec!["COUNT".to_string()]), - args: vec![ASTNode::SQLWildcard], + args: vec![Expr::SQLWildcard], over: None, distinct: false })), op: SQLBinaryOperator::Gt, - right: Box::new(ASTNode::SQLValue(Value::Long(1))) + right: Box::new(Expr::SQLValue(Value::Long(1))) }), select.having ); @@ -825,8 +821,8 @@ fn parse_cast() { let sql = "SELECT CAST(id AS bigint) FROM customer"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLCast { - expr: Box::new(ASTNode::SQLIdentifier("id".to_string())), + &Expr::SQLCast { + expr: Box::new(Expr::SQLIdentifier("id".to_string())), data_type: SQLType::BigInt }, expr_from_projection(only(&select.projection)) @@ -854,9 +850,9 @@ fn parse_extract() { let sql = "SELECT EXTRACT(YEAR FROM d)"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLExtract { + &Expr::SQLExtract { field: SQLDateTimeField::Year, - expr: Box::new(ASTNode::SQLIdentifier("d".to_string())), + expr: Box::new(Expr::SQLIdentifier("d".to_string())), }, expr_from_projection(only(&select.projection)), ); @@ -1141,9 +1137,9 @@ fn parse_scalar_function_in_projection() { let sql = "SELECT sqrt(id) FROM foo"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLFunction(SQLFunction { + &Expr::SQLFunction(SQLFunction { name: SQLObjectName(vec!["sqrt".to_string()]), - args: vec![ASTNode::SQLIdentifier("id".to_string())], + args: vec![Expr::SQLIdentifier("id".to_string())], over: None, distinct: false, }), @@ -1164,13 +1160,13 @@ fn parse_window_functions() { let select = verified_only_select(sql); assert_eq!(4, select.projection.len()); assert_eq!( - &ASTNode::SQLFunction(SQLFunction { + &Expr::SQLFunction(SQLFunction { name: SQLObjectName(vec!["row_number".to_string()]), args: vec![], over: Some(SQLWindowSpec { partition_by: vec![], order_by: vec![SQLOrderByExpr { - expr: ASTNode::SQLIdentifier("dt".to_string()), + expr: Expr::SQLIdentifier("dt".to_string()), asc: Some(false) }], window_frame: None, @@ -1194,15 +1190,15 @@ fn parse_literal_string() { let select = verified_only_select(sql); assert_eq!(3, select.projection.len()); assert_eq!( - &ASTNode::SQLValue(Value::SingleQuotedString("one".to_string())), + &Expr::SQLValue(Value::SingleQuotedString("one".to_string())), expr_from_projection(&select.projection[0]) ); assert_eq!( - &ASTNode::SQLValue(Value::NationalStringLiteral("national string".to_string())), + &Expr::SQLValue(Value::NationalStringLiteral("national string".to_string())), expr_from_projection(&select.projection[1]) ); assert_eq!( - &ASTNode::SQLValue(Value::HexStringLiteral("deadBEEF".to_string())), + &Expr::SQLValue(Value::HexStringLiteral("deadBEEF".to_string())), expr_from_projection(&select.projection[2]) ); @@ -1214,7 +1210,7 @@ fn parse_literal_date() { let sql = "SELECT DATE '1999-01-01'"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLValue(Value::Date("1999-01-01".into())), + &Expr::SQLValue(Value::Date("1999-01-01".into())), expr_from_projection(only(&select.projection)), ); } @@ -1224,7 +1220,7 @@ fn parse_literal_time() { let sql = "SELECT TIME '01:23:34'"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLValue(Value::Time("01:23:34".into())), + &Expr::SQLValue(Value::Time("01:23:34".into())), expr_from_projection(only(&select.projection)), ); } @@ -1234,7 +1230,7 @@ fn parse_literal_timestamp() { let sql = "SELECT TIMESTAMP '1999-01-01 01:23:34'"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLValue(Value::Timestamp("1999-01-01 01:23:34".into())), + &Expr::SQLValue(Value::Timestamp("1999-01-01 01:23:34".into())), expr_from_projection(only(&select.projection)), ); } @@ -1244,7 +1240,7 @@ fn parse_literal_interval() { let sql = "SELECT INTERVAL '1-1' YEAR TO MONTH"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLValue(Value::Interval { + &Expr::SQLValue(Value::Interval { value: "1-1".into(), leading_field: SQLDateTimeField::Year, leading_precision: None, @@ -1257,7 +1253,7 @@ fn parse_literal_interval() { let sql = "SELECT INTERVAL '01:01.01' MINUTE (5) TO SECOND (5)"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLValue(Value::Interval { + &Expr::SQLValue(Value::Interval { value: "01:01.01".into(), leading_field: SQLDateTimeField::Minute, leading_precision: Some(5), @@ -1270,7 +1266,7 @@ fn parse_literal_interval() { let sql = "SELECT INTERVAL '1' SECOND (5, 4)"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLValue(Value::Interval { + &Expr::SQLValue(Value::Interval { value: "1".into(), leading_field: SQLDateTimeField::Second, leading_precision: Some(5), @@ -1283,7 +1279,7 @@ fn parse_literal_interval() { let sql = "SELECT INTERVAL '10' HOUR"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLValue(Value::Interval { + &Expr::SQLValue(Value::Interval { value: "10".into(), leading_field: SQLDateTimeField::Hour, leading_precision: None, @@ -1296,7 +1292,7 @@ fn parse_literal_interval() { let sql = "SELECT INTERVAL '10' HOUR (1)"; let select = verified_only_select(sql); assert_eq!( - &ASTNode::SQLValue(Value::Interval { + &Expr::SQLValue(Value::Interval { value: "10".into(), leading_field: SQLDateTimeField::Hour, leading_precision: Some(1), @@ -1369,11 +1365,11 @@ fn parse_delimited_identifiers() { // check SELECT assert_eq!(3, select.projection.len()); assert_eq!( - &ASTNode::SQLCompoundIdentifier(vec![r#""alias""#.to_string(), r#""bar baz""#.to_string()]), + &Expr::SQLCompoundIdentifier(vec![r#""alias""#.to_string(), r#""bar baz""#.to_string()]), expr_from_projection(&select.projection[0]), ); assert_eq!( - &ASTNode::SQLFunction(SQLFunction { + &Expr::SQLFunction(SQLFunction { name: SQLObjectName(vec![r#""myfun""#.to_string()]), args: vec![], over: None, @@ -1382,11 +1378,11 @@ fn parse_delimited_identifiers() { expr_from_projection(&select.projection[1]), ); match &select.projection[2] { - SQLSelectItem::ExpressionWithAlias { expr, alias } => { - assert_eq!(&ASTNode::SQLIdentifier(r#""simple id""#.to_string()), expr); + SQLSelectItem::ExprWithAlias { expr, alias } => { + assert_eq!(&Expr::SQLIdentifier(r#""simple id""#.to_string()), expr); assert_eq!(r#""column alias""#, alias); } - _ => panic!("Expected ExpressionWithAlias"), + _ => panic!("Expected ExprWithAlias"), } verified_stmt(r#"CREATE TABLE "foo" ("bar" "int")"#); @@ -1396,7 +1392,7 @@ fn parse_delimited_identifiers() { #[test] fn parse_parens() { - use self::ASTNode::*; + use self::Expr::*; use self::SQLBinaryOperator::*; let sql = "(a + b) - (c + d)"; assert_eq!( @@ -1418,9 +1414,9 @@ fn parse_parens() { } #[test] -fn parse_searched_case_expression() { +fn parse_searched_case_expr() { let sql = "SELECT CASE WHEN bar IS NULL THEN 'null' WHEN bar = 0 THEN '=0' WHEN bar >= 0 THEN '>=0' ELSE '<0' END FROM foo"; - use self::ASTNode::{SQLBinaryOp, SQLCase, SQLIdentifier, SQLIsNull, SQLValue}; + use self::Expr::{SQLBinaryOp, SQLCase, SQLIdentifier, SQLIsNull, SQLValue}; use self::SQLBinaryOperator::*; let select = verified_only_select(sql); assert_eq!( @@ -1453,11 +1449,11 @@ fn parse_searched_case_expression() { } #[test] -fn parse_simple_case_expression() { +fn parse_simple_case_expr() { // ANSI calls a CASE expression with an operand "" let sql = "SELECT CASE foo WHEN 1 THEN 'Y' ELSE 'N' END"; let select = verified_only_select(sql); - use self::ASTNode::{SQLCase, SQLIdentifier, SQLValue}; + use self::Expr::{SQLCase, SQLIdentifier, SQLValue}; assert_eq!( &SQLCase { operand: Some(Box::new(SQLIdentifier("foo".to_string()))), @@ -1587,10 +1583,10 @@ fn parse_joins_on() { args: vec![], with_hints: vec![], }, - join_operator: f(JoinConstraint::On(ASTNode::SQLBinaryOp { - left: Box::new(ASTNode::SQLIdentifier("c1".into())), + join_operator: f(JoinConstraint::On(Expr::SQLBinaryOp { + left: Box::new(Expr::SQLIdentifier("c1".into())), op: SQLBinaryOperator::Eq, - right: Box::new(ASTNode::SQLIdentifier("c2".into())), + right: Box::new(Expr::SQLIdentifier("c2".into())), })), } } @@ -1834,7 +1830,7 @@ fn parse_ctes() { let sql = &format!("SELECT ({})", with); let select = verified_only_select(sql); match expr_from_projection(only(&select.projection)) { - ASTNode::SQLSubquery(ref subquery) => { + Expr::SQLSubquery(ref subquery) => { assert_ctes_in_select(&cte_sqls, subquery.as_ref()); } _ => panic!("Expected subquery"), @@ -1991,7 +1987,7 @@ fn parse_multiple_statements() { #[test] fn parse_scalar_subqueries() { - use self::ASTNode::*; + use self::Expr::*; let sql = "(SELECT 1) + (SELECT 2)"; assert_matches!(verified_expr(sql), SQLBinaryOp { op: SQLBinaryOperator::Plus, .. @@ -2006,16 +2002,16 @@ fn parse_exists_subquery() { let sql = "SELECT * FROM t WHERE EXISTS (SELECT 1)"; let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLExists(Box::new(expected_inner.clone())), + Expr::SQLExists(Box::new(expected_inner.clone())), select.selection.unwrap(), ); let sql = "SELECT * FROM t WHERE NOT EXISTS (SELECT 1)"; let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLUnaryOp { + Expr::SQLUnaryOp { op: SQLUnaryOperator::Not, - expr: Box::new(ASTNode::SQLExists(Box::new(expected_inner))), + expr: Box::new(Expr::SQLExists(Box::new(expected_inner))), }, select.selection.unwrap(), ); @@ -2208,26 +2204,26 @@ fn parse_invalid_subquery_without_parens() { #[test] fn parse_offset() { let ast = verified_query("SELECT foo FROM bar OFFSET 2 ROWS"); - assert_eq!(ast.offset, Some(ASTNode::SQLValue(Value::Long(2)))); + assert_eq!(ast.offset, Some(Expr::SQLValue(Value::Long(2)))); let ast = verified_query("SELECT foo FROM bar WHERE foo = 4 OFFSET 2 ROWS"); - assert_eq!(ast.offset, Some(ASTNode::SQLValue(Value::Long(2)))); + assert_eq!(ast.offset, Some(Expr::SQLValue(Value::Long(2)))); let ast = verified_query("SELECT foo FROM bar ORDER BY baz OFFSET 2 ROWS"); - assert_eq!(ast.offset, Some(ASTNode::SQLValue(Value::Long(2)))); + assert_eq!(ast.offset, Some(Expr::SQLValue(Value::Long(2)))); let ast = verified_query("SELECT foo FROM bar WHERE foo = 4 ORDER BY baz OFFSET 2 ROWS"); - assert_eq!(ast.offset, Some(ASTNode::SQLValue(Value::Long(2)))); + assert_eq!(ast.offset, Some(Expr::SQLValue(Value::Long(2)))); let ast = verified_query("SELECT foo FROM (SELECT * FROM bar OFFSET 2 ROWS) OFFSET 2 ROWS"); - assert_eq!(ast.offset, Some(ASTNode::SQLValue(Value::Long(2)))); + assert_eq!(ast.offset, Some(Expr::SQLValue(Value::Long(2)))); match ast.body { SQLSetExpr::Select(s) => match only(s.from).relation { TableFactor::Derived { subquery, .. } => { - assert_eq!(subquery.offset, Some(ASTNode::SQLValue(Value::Long(2)))); + assert_eq!(subquery.offset, Some(Expr::SQLValue(Value::Long(2)))); } _ => panic!("Test broke"), }, _ => panic!("Test broke"), } let ast = verified_query("SELECT 'foo' OFFSET 0 ROWS"); - assert_eq!(ast.offset, Some(ASTNode::SQLValue(Value::Long(0)))); + assert_eq!(ast.offset, Some(Expr::SQLValue(Value::Long(0)))); } #[test] @@ -2243,7 +2239,7 @@ fn parse_fetch() { const FETCH_FIRST_TWO_ROWS_ONLY: Fetch = Fetch { with_ties: false, percent: false, - quantity: Some(ASTNode::SQLValue(Value::Long(2))), + quantity: Some(Expr::SQLValue(Value::Long(2))), }; let ast = verified_query("SELECT foo FROM bar FETCH FIRST 2 ROWS ONLY"); assert_eq!(ast.fetch, Some(FETCH_FIRST_TWO_ROWS_ONLY)); @@ -2270,7 +2266,7 @@ fn parse_fetch() { Some(Fetch { with_ties: true, percent: false, - quantity: Some(ASTNode::SQLValue(Value::Long(2))), + quantity: Some(Expr::SQLValue(Value::Long(2))), }) ); let ast = verified_query("SELECT foo FROM bar FETCH FIRST 50 PERCENT ROWS ONLY"); @@ -2279,13 +2275,13 @@ fn parse_fetch() { Some(Fetch { with_ties: false, percent: true, - quantity: Some(ASTNode::SQLValue(Value::Long(50))), + quantity: Some(Expr::SQLValue(Value::Long(50))), }) ); let ast = verified_query( "SELECT foo FROM bar WHERE foo = 4 ORDER BY baz OFFSET 2 ROWS FETCH FIRST 2 ROWS ONLY", ); - assert_eq!(ast.offset, Some(ASTNode::SQLValue(Value::Long(2)))); + assert_eq!(ast.offset, Some(Expr::SQLValue(Value::Long(2)))); assert_eq!(ast.fetch, Some(FETCH_FIRST_TWO_ROWS_ONLY)); let ast = verified_query( "SELECT foo FROM (SELECT * FROM bar FETCH FIRST 2 ROWS ONLY) FETCH FIRST 2 ROWS ONLY", @@ -2301,12 +2297,12 @@ fn parse_fetch() { _ => panic!("Test broke"), } let ast = verified_query("SELECT foo FROM (SELECT * FROM bar OFFSET 2 ROWS FETCH FIRST 2 ROWS ONLY) OFFSET 2 ROWS FETCH FIRST 2 ROWS ONLY"); - assert_eq!(ast.offset, Some(ASTNode::SQLValue(Value::Long(2)))); + assert_eq!(ast.offset, Some(Expr::SQLValue(Value::Long(2)))); assert_eq!(ast.fetch, Some(FETCH_FIRST_TWO_ROWS_ONLY)); match ast.body { SQLSetExpr::Select(s) => match only(s.from).relation { TableFactor::Derived { subquery, .. } => { - assert_eq!(subquery.offset, Some(ASTNode::SQLValue(Value::Long(2)))); + assert_eq!(subquery.offset, Some(Expr::SQLValue(Value::Long(2)))); assert_eq!(subquery.fetch, Some(FETCH_FIRST_TWO_ROWS_ONLY)); } _ => panic!("Test broke"), @@ -2354,7 +2350,7 @@ fn lateral_derived() { let join = &from.joins[0]; assert_eq!( join.join_operator, - JoinOperator::LeftOuter(JoinConstraint::On(ASTNode::SQLValue(Value::Boolean(true)))) + JoinOperator::LeftOuter(JoinConstraint::On(Expr::SQLValue(Value::Boolean(true)))) ); if let TableFactor::Derived { lateral, @@ -2545,6 +2541,6 @@ fn verified_only_select(query: &str) -> SQLSelect { all_dialects().verified_only_select(query) } -fn verified_expr(query: &str) -> ASTNode { +fn verified_expr(query: &str) -> Expr { all_dialects().verified_expr(query) } diff --git a/tests/sqlparser_mssql.rs b/tests/sqlparser_mssql.rs index 2241a226d..84d290361 100644 --- a/tests/sqlparser_mssql.rs +++ b/tests/sqlparser_mssql.rs @@ -23,11 +23,11 @@ fn parse_mssql_identifiers() { let sql = "SELECT @@version, _foo$123 FROM ##temp"; let select = ms_and_generic().verified_only_select(sql); assert_eq!( - &ASTNode::SQLIdentifier("@@version".to_string()), + &Expr::SQLIdentifier("@@version".to_string()), expr_from_projection(&select.projection[0]), ); assert_eq!( - &ASTNode::SQLIdentifier("_foo$123".to_string()), + &Expr::SQLIdentifier("_foo$123".to_string()), expr_from_projection(&select.projection[1]), ); assert_eq!(2, select.projection.len()); diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index a373f0e4a..a772f3c0d 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -106,9 +106,7 @@ fn parse_create_table_with_defaults() { options: vec![ ColumnOptionDef { name: None, - option: ColumnOption::Default(ASTNode::SQLValue(Value::Boolean( - true - ))), + option: ColumnOption::Default(Expr::SQLValue(Value::Boolean(true))), }, ColumnOptionDef { name: None,