From 9e33cea9b8c19e16bcedde1d65693ca4d0406aae Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Wed, 5 Jun 2019 12:21:38 -0400 Subject: [PATCH 1/2] Standardize BinaryOp and UnaryOp nodes These were previously called "BinaryExpr" and "Unary"; besides being inconsistent, it's also not correct to say "binary expression" or "unary expression", as it's the operators that have arities, not the expression. Adjust the naming of the variants accordingly. --- src/sqlast/mod.rs | 22 +++++------ src/sqlparser.rs | 12 +++--- tests/sqlparser_common.rs | 82 +++++++++++++++++++-------------------- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/sqlast/mod.rs b/src/sqlast/mod.rs index f38b04e4f..917d12477 100644 --- a/src/sqlast/mod.rs +++ b/src/sqlast/mod.rs @@ -89,12 +89,17 @@ pub enum ASTNode { low: Box, high: Box, }, - /// Binary expression e.g. `1 + 1` or `foo > bar` - SQLBinaryExpr { + /// Binary operation e.g. `1 + 1` or `foo > bar` + SQLBinaryOp { left: Box, op: SQLOperator, right: Box, }, + /// Unary operation e.g. `NOT foo` + SQLUnaryOp { + op: SQLOperator, + expr: Box, + }, /// CAST an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))` SQLCast { expr: Box, @@ -111,11 +116,6 @@ pub enum ASTNode { }, /// Nested expression e.g. `(foo > bar)` or `(1)` SQLNested(Box), - /// Unary expression - SQLUnary { - operator: SQLOperator, - expr: Box, - }, /// SQLValue SQLValue(Value), /// Scalar function call e.g. `LEFT(foo, 5)` @@ -179,12 +179,15 @@ impl ToString for ASTNode { low.to_string(), high.to_string() ), - ASTNode::SQLBinaryExpr { left, op, right } => format!( + ASTNode::SQLBinaryOp { left, op, right } => format!( "{} {} {}", left.as_ref().to_string(), op.to_string(), right.as_ref().to_string() ), + ASTNode::SQLUnaryOp { op, expr } => { + format!("{} {}", op.to_string(), expr.as_ref().to_string()) + } ASTNode::SQLCast { expr, data_type } => format!( "CAST({} AS {})", expr.as_ref().to_string(), @@ -199,9 +202,6 @@ impl ToString for ASTNode { collation.to_string() ), ASTNode::SQLNested(ast) => format!("({})", ast.as_ref().to_string()), - ASTNode::SQLUnary { operator, expr } => { - format!("{} {}", operator.to_string(), expr.as_ref().to_string()) - } ASTNode::SQLValue(v) => v.to_string(), ASTNode::SQLFunction(f) => f.to_string(), ASTNode::SQLCase { diff --git a/src/sqlparser.rs b/src/sqlparser.rs index e1907f23a..9bf5bf940 100644 --- a/src/sqlparser.rs +++ b/src/sqlparser.rs @@ -183,8 +183,8 @@ impl Parser { "EXISTS" => self.parse_exists_expression(), "EXTRACT" => self.parse_extract_expression(), "INTERVAL" => self.parse_literal_interval(), - "NOT" => Ok(ASTNode::SQLUnary { - operator: SQLOperator::Not, + "NOT" => Ok(ASTNode::SQLUnaryOp { + op: SQLOperator::Not, expr: Box::new(self.parse_subexpr(Self::UNARY_NOT_PREC)?), }), "TIME" => Ok(ASTNode::SQLValue(Value::Time(self.parse_literal_string()?))), @@ -224,13 +224,13 @@ impl Parser { }, // End of Token::SQLWord Token::Mult => Ok(ASTNode::SQLWildcard), tok @ Token::Minus | tok @ Token::Plus => { - let operator = if tok == Token::Plus { + let op = if tok == Token::Plus { SQLOperator::Plus } else { SQLOperator::Minus }; - Ok(ASTNode::SQLUnary { - operator, + Ok(ASTNode::SQLUnaryOp { + op, expr: Box::new(self.parse_subexpr(Self::PLUS_MINUS_PREC)?), }) } @@ -541,7 +541,7 @@ impl Parser { }; if let Some(op) = regular_binary_operator { - Ok(ASTNode::SQLBinaryExpr { + Ok(ASTNode::SQLBinaryOp { left: Box::new(expr), op, right: Box::new(self.parse_subexpr(precedence)?), diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 594a3bda8..5d0737858 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -181,7 +181,7 @@ fn parse_where_delete_statement() { assert_eq!(SQLObjectName(vec!["foo".to_string()]), table_name); assert_eq!( - SQLBinaryExpr { + SQLBinaryOp { left: Box::new(SQLIdentifier("name".to_string())), op: Eq, right: Box::new(SQLValue(Value::Long(5))), @@ -282,7 +282,7 @@ 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::SQLBinaryExpr { + expr: ASTNode::SQLBinaryOp { ref op, ref right, .. }, ref alias, @@ -336,8 +336,8 @@ fn parse_select_count_distinct() { assert_eq!( &ASTNode::SQLFunction(SQLFunction { name: SQLObjectName(vec!["COUNT".to_string()]), - args: vec![ASTNode::SQLUnary { - operator: SQLOperator::Plus, + args: vec![ASTNode::SQLUnaryOp { + op: SQLOperator::Plus, expr: Box::new(ASTNode::SQLIdentifier("x".to_string())) }], over: None, @@ -409,7 +409,7 @@ fn parse_escaped_single_quote_string_predicate() { WHERE salary <> 'Jim''s salary'"; let ast = verified_only_select(sql); assert_eq!( - Some(SQLBinaryExpr { + Some(SQLBinaryOp { left: Box::new(SQLIdentifier("salary".to_string())), op: NotEq, right: Box::new(SQLValue(Value::SingleQuotedString( @@ -426,10 +426,10 @@ fn parse_compound_expr_1() { use self::SQLOperator::*; let sql = "a + b * c"; assert_eq!( - SQLBinaryExpr { + SQLBinaryOp { left: Box::new(SQLIdentifier("a".to_string())), op: Plus, - right: Box::new(SQLBinaryExpr { + right: Box::new(SQLBinaryOp { left: Box::new(SQLIdentifier("b".to_string())), op: Multiply, right: Box::new(SQLIdentifier("c".to_string())) @@ -445,8 +445,8 @@ fn parse_compound_expr_2() { use self::SQLOperator::*; let sql = "a * b + c"; assert_eq!( - SQLBinaryExpr { - left: Box::new(SQLBinaryExpr { + SQLBinaryOp { + left: Box::new(SQLBinaryOp { left: Box::new(SQLIdentifier("a".to_string())), op: Multiply, right: Box::new(SQLIdentifier("b".to_string())) @@ -464,14 +464,14 @@ fn parse_unary_math() { use self::SQLOperator::*; let sql = "- a + - b"; assert_eq!( - SQLBinaryExpr { - left: Box::new(SQLUnary { - operator: Minus, + SQLBinaryOp { + left: Box::new(SQLUnaryOp { + op: Minus, expr: Box::new(SQLIdentifier("a".to_string())), }), op: Plus, - right: Box::new(SQLUnary { - operator: Minus, + right: Box::new(SQLUnaryOp { + op: Minus, expr: Box::new(SQLIdentifier("b".to_string())), }), }, @@ -504,15 +504,15 @@ fn parse_not_precedence() { use self::ASTNode::*; // 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), SQLBinaryExpr { + assert_matches!(verified_expr(sql), SQLBinaryOp { op: SQLOperator::Or, .. }); // But NOT has lower precedence than comparison operators, so the following parses as NOT (a IS NULL) let sql = "NOT a IS NULL"; - assert_matches!(verified_expr(sql), SQLUnary { - operator: SQLOperator::Not, + assert_matches!(verified_expr(sql), SQLUnaryOp { + op: SQLOperator::Not, .. }); @@ -520,8 +520,8 @@ fn parse_not_precedence() { let sql = "NOT 1 NOT BETWEEN 1 AND 2"; assert_eq!( verified_expr(sql), - SQLUnary { - operator: SQLOperator::Not, + SQLUnaryOp { + op: SQLOperator::Not, expr: Box::new(SQLBetween { expr: Box::new(SQLValue(Value::Long(1))), low: Box::new(SQLValue(Value::Long(1))), @@ -535,9 +535,9 @@ fn parse_not_precedence() { let sql = "NOT 'a' NOT LIKE 'b'"; assert_eq!( verified_expr(sql), - SQLUnary { - operator: SQLOperator::Not, - expr: Box::new(SQLBinaryExpr { + SQLUnaryOp { + op: SQLOperator::Not, + expr: Box::new(SQLBinaryOp { left: Box::new(SQLValue(Value::SingleQuotedString("a".into()))), op: SQLOperator::NotLike, right: Box::new(SQLValue(Value::SingleQuotedString("b".into()))), @@ -549,8 +549,8 @@ fn parse_not_precedence() { let sql = "NOT a NOT IN ('a')"; assert_eq!( verified_expr(sql), - SQLUnary { - operator: SQLOperator::Not, + SQLUnaryOp { + op: SQLOperator::Not, expr: Box::new(SQLInList { expr: Box::new(SQLIdentifier("a".into())), list: vec![SQLValue(Value::SingleQuotedString("a".into()))], @@ -569,7 +569,7 @@ fn parse_like() { ); let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLBinaryExpr { + ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLIdentifier("name".to_string())), op: if negated { SQLOperator::NotLike @@ -591,7 +591,7 @@ fn parse_like() { ); let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLIsNull(Box::new(ASTNode::SQLBinaryExpr { + ASTNode::SQLIsNull(Box::new(ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLIdentifier("name".to_string())), op: if negated { SQLOperator::NotLike @@ -678,12 +678,12 @@ fn parse_between_with_expr() { assert_eq!( ASTNode::SQLIsNull(Box::new(ASTNode::SQLBetween { expr: Box::new(ASTNode::SQLValue(Value::Long(1))), - low: Box::new(SQLBinaryExpr { + low: Box::new(SQLBinaryOp { left: Box::new(ASTNode::SQLValue(Value::Long(1))), op: Plus, right: Box::new(ASTNode::SQLValue(Value::Long(2))), }), - high: Box::new(SQLBinaryExpr { + high: Box::new(SQLBinaryOp { left: Box::new(ASTNode::SQLValue(Value::Long(3))), op: Plus, right: Box::new(ASTNode::SQLValue(Value::Long(4))), @@ -696,15 +696,15 @@ 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::SQLBinaryExpr { - left: Box::new(ASTNode::SQLBinaryExpr { + ASTNode::SQLBinaryOp { + left: Box::new(ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLValue(Value::Long(1))), op: SQLOperator::Eq, right: Box::new(ASTNode::SQLValue(Value::Long(1))), }), op: SQLOperator::And, right: Box::new(ASTNode::SQLBetween { - expr: Box::new(ASTNode::SQLBinaryExpr { + expr: Box::new(ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLValue(Value::Long(1))), op: SQLOperator::Plus, right: Box::new(ASTNode::SQLIdentifier("x".to_string())), @@ -1368,14 +1368,14 @@ fn parse_parens() { use self::SQLOperator::*; let sql = "(a + b) - (c + d)"; assert_eq!( - SQLBinaryExpr { - left: Box::new(SQLNested(Box::new(SQLBinaryExpr { + SQLBinaryOp { + left: Box::new(SQLNested(Box::new(SQLBinaryOp { left: Box::new(SQLIdentifier("a".to_string())), op: Plus, right: Box::new(SQLIdentifier("b".to_string())) }))), op: Minus, - right: Box::new(SQLNested(Box::new(SQLBinaryExpr { + right: Box::new(SQLNested(Box::new(SQLBinaryOp { left: Box::new(SQLIdentifier("c".to_string())), op: Plus, right: Box::new(SQLIdentifier("d".to_string())) @@ -1388,7 +1388,7 @@ fn parse_parens() { #[test] fn parse_searched_case_expression() { 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::{SQLBinaryExpr, SQLCase, SQLIdentifier, SQLIsNull, SQLValue}; + use self::ASTNode::{SQLBinaryOp, SQLCase, SQLIdentifier, SQLIsNull, SQLValue}; use self::SQLOperator::*; let select = verified_only_select(sql); assert_eq!( @@ -1396,12 +1396,12 @@ fn parse_searched_case_expression() { operand: None, conditions: vec![ SQLIsNull(Box::new(SQLIdentifier("bar".to_string()))), - SQLBinaryExpr { + SQLBinaryOp { left: Box::new(SQLIdentifier("bar".to_string())), op: Eq, right: Box::new(SQLValue(Value::Long(0))) }, - SQLBinaryExpr { + SQLBinaryOp { left: Box::new(SQLIdentifier("bar".to_string())), op: GtEq, right: Box::new(SQLValue(Value::Long(0))) @@ -1555,7 +1555,7 @@ fn parse_joins_on() { args: vec![], with_hints: vec![], }, - join_operator: f(JoinConstraint::On(ASTNode::SQLBinaryExpr { + join_operator: f(JoinConstraint::On(ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLIdentifier("c1".into())), op: SQLOperator::Eq, right: Box::new(ASTNode::SQLIdentifier("c2".into())), @@ -1920,7 +1920,7 @@ fn parse_multiple_statements() { fn parse_scalar_subqueries() { use self::ASTNode::*; let sql = "(SELECT 1) + (SELECT 2)"; - assert_matches!(verified_expr(sql), SQLBinaryExpr { + assert_matches!(verified_expr(sql), SQLBinaryOp { op: SQLOperator::Plus, .. //left: box SQLSubquery { .. }, //right: box SQLSubquery { .. }, @@ -1940,8 +1940,8 @@ fn parse_exists_subquery() { let sql = "SELECT * FROM t WHERE NOT EXISTS (SELECT 1)"; let select = verified_only_select(sql); assert_eq!( - ASTNode::SQLUnary { - operator: SQLOperator::Not, + ASTNode::SQLUnaryOp { + op: SQLOperator::Not, expr: Box::new(ASTNode::SQLExists(Box::new(expected_inner))), }, select.selection.unwrap(), From ae25dce24659d0edbf681811191dbb6df768c1e7 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Wed, 5 Jun 2019 12:31:13 -0400 Subject: [PATCH 2/2] Split operators by arity It is useful downstream to have two separate enums, one for unary operators and one for binary operators, so that the compiler can check exhaustiveness. Otherwise downstream consumers need to manually encode which operators are unary and which operators are binary when matching on an Operator enum. --- src/sqlast/mod.rs | 7 ++--- src/sqlast/sql_operator.rs | 56 ++++++++++++++++++++++++------------- src/sqlparser.rs | 36 ++++++++++++------------ tests/sqlparser_common.rs | 57 +++++++++++++++++++------------------- 4 files changed, 85 insertions(+), 71 deletions(-) diff --git a/src/sqlast/mod.rs b/src/sqlast/mod.rs index 917d12477..99968a8db 100644 --- a/src/sqlast/mod.rs +++ b/src/sqlast/mod.rs @@ -27,11 +27,10 @@ pub use self::query::{ Cte, Fetch, Join, JoinConstraint, JoinOperator, SQLOrderByExpr, SQLQuery, SQLSelect, SQLSelectItem, SQLSetExpr, SQLSetOperator, SQLValues, TableAlias, TableFactor, TableWithJoins, }; +pub use self::sql_operator::{SQLBinaryOperator, SQLUnaryOperator}; pub use self::sqltype::SQLType; pub use self::value::{SQLDateTimeField, Value}; -pub use self::sql_operator::SQLOperator; - /// Like `vec.join(", ")`, but for any types implementing ToString. fn comma_separated_string(iter: I) -> String where @@ -92,12 +91,12 @@ pub enum ASTNode { /// Binary operation e.g. `1 + 1` or `foo > bar` SQLBinaryOp { left: Box, - op: SQLOperator, + op: SQLBinaryOperator, right: Box, }, /// Unary operation e.g. `NOT foo` SQLUnaryOp { - op: SQLOperator, + op: SQLUnaryOperator, expr: Box, }, /// CAST an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))` diff --git a/src/sqlast/sql_operator.rs b/src/sqlast/sql_operator.rs index d080c7b1b..4845d0623 100644 --- a/src/sqlast/sql_operator.rs +++ b/src/sqlast/sql_operator.rs @@ -10,9 +10,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -/// SQL Operator +/// Unary operators #[derive(Debug, Clone, PartialEq, Hash)] -pub enum SQLOperator { +pub enum SQLUnaryOperator { + Plus, + Minus, + Not, +} + +impl ToString for SQLUnaryOperator { + fn to_string(&self) -> String { + match self { + SQLUnaryOperator::Plus => "+".to_string(), + SQLUnaryOperator::Minus => "-".to_string(), + SQLUnaryOperator::Not => "NOT".to_string(), + } + } +} + +/// Binary operators +#[derive(Debug, Clone, PartialEq, Hash)] +pub enum SQLBinaryOperator { Plus, Minus, Multiply, @@ -26,30 +44,28 @@ pub enum SQLOperator { NotEq, And, Or, - Not, Like, NotLike, } -impl ToString for SQLOperator { +impl ToString for SQLBinaryOperator { fn to_string(&self) -> String { match self { - SQLOperator::Plus => "+".to_string(), - SQLOperator::Minus => "-".to_string(), - SQLOperator::Multiply => "*".to_string(), - SQLOperator::Divide => "/".to_string(), - SQLOperator::Modulus => "%".to_string(), - SQLOperator::Gt => ">".to_string(), - SQLOperator::Lt => "<".to_string(), - SQLOperator::GtEq => ">=".to_string(), - SQLOperator::LtEq => "<=".to_string(), - SQLOperator::Eq => "=".to_string(), - SQLOperator::NotEq => "<>".to_string(), - SQLOperator::And => "AND".to_string(), - SQLOperator::Or => "OR".to_string(), - SQLOperator::Not => "NOT".to_string(), - SQLOperator::Like => "LIKE".to_string(), - SQLOperator::NotLike => "NOT LIKE".to_string(), + SQLBinaryOperator::Plus => "+".to_string(), + SQLBinaryOperator::Minus => "-".to_string(), + SQLBinaryOperator::Multiply => "*".to_string(), + SQLBinaryOperator::Divide => "/".to_string(), + SQLBinaryOperator::Modulus => "%".to_string(), + SQLBinaryOperator::Gt => ">".to_string(), + SQLBinaryOperator::Lt => "<".to_string(), + SQLBinaryOperator::GtEq => ">=".to_string(), + SQLBinaryOperator::LtEq => "<=".to_string(), + SQLBinaryOperator::Eq => "=".to_string(), + SQLBinaryOperator::NotEq => "<>".to_string(), + SQLBinaryOperator::And => "AND".to_string(), + SQLBinaryOperator::Or => "OR".to_string(), + SQLBinaryOperator::Like => "LIKE".to_string(), + SQLBinaryOperator::NotLike => "NOT LIKE".to_string(), } } } diff --git a/src/sqlparser.rs b/src/sqlparser.rs index 9bf5bf940..2836b8d15 100644 --- a/src/sqlparser.rs +++ b/src/sqlparser.rs @@ -184,7 +184,7 @@ impl Parser { "EXTRACT" => self.parse_extract_expression(), "INTERVAL" => self.parse_literal_interval(), "NOT" => Ok(ASTNode::SQLUnaryOp { - op: SQLOperator::Not, + op: SQLUnaryOperator::Not, expr: Box::new(self.parse_subexpr(Self::UNARY_NOT_PREC)?), }), "TIME" => Ok(ASTNode::SQLValue(Value::Time(self.parse_literal_string()?))), @@ -225,9 +225,9 @@ impl Parser { Token::Mult => Ok(ASTNode::SQLWildcard), tok @ Token::Minus | tok @ Token::Plus => { let op = if tok == Token::Plus { - SQLOperator::Plus + SQLUnaryOperator::Plus } else { - SQLOperator::Minus + SQLUnaryOperator::Minus }; Ok(ASTNode::SQLUnaryOp { op, @@ -513,24 +513,24 @@ impl Parser { let tok = self.next_token().unwrap(); // safe as EOF's precedence is the lowest let regular_binary_operator = match tok { - Token::Eq => Some(SQLOperator::Eq), - Token::Neq => Some(SQLOperator::NotEq), - Token::Gt => Some(SQLOperator::Gt), - Token::GtEq => Some(SQLOperator::GtEq), - Token::Lt => Some(SQLOperator::Lt), - Token::LtEq => Some(SQLOperator::LtEq), - Token::Plus => Some(SQLOperator::Plus), - Token::Minus => Some(SQLOperator::Minus), - Token::Mult => Some(SQLOperator::Multiply), - Token::Mod => Some(SQLOperator::Modulus), - Token::Div => Some(SQLOperator::Divide), + Token::Eq => Some(SQLBinaryOperator::Eq), + Token::Neq => Some(SQLBinaryOperator::NotEq), + Token::Gt => Some(SQLBinaryOperator::Gt), + Token::GtEq => Some(SQLBinaryOperator::GtEq), + Token::Lt => Some(SQLBinaryOperator::Lt), + Token::LtEq => Some(SQLBinaryOperator::LtEq), + Token::Plus => Some(SQLBinaryOperator::Plus), + Token::Minus => Some(SQLBinaryOperator::Minus), + Token::Mult => Some(SQLBinaryOperator::Multiply), + Token::Mod => Some(SQLBinaryOperator::Modulus), + Token::Div => Some(SQLBinaryOperator::Divide), Token::SQLWord(ref k) => match k.keyword.as_ref() { - "AND" => Some(SQLOperator::And), - "OR" => Some(SQLOperator::Or), - "LIKE" => Some(SQLOperator::Like), + "AND" => Some(SQLBinaryOperator::And), + "OR" => Some(SQLBinaryOperator::Or), + "LIKE" => Some(SQLBinaryOperator::Like), "NOT" => { if self.parse_keyword("LIKE") { - Some(SQLOperator::NotLike) + Some(SQLBinaryOperator::NotLike) } else { None } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 5d0737858..4b2ab958c 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -169,7 +169,7 @@ fn parse_delete_statement() { #[test] fn parse_where_delete_statement() { use self::ASTNode::*; - use self::SQLOperator::*; + use self::SQLBinaryOperator::*; let sql = "DELETE FROM foo WHERE name = 5"; match verified_stmt(sql) { @@ -288,7 +288,7 @@ fn parse_column_aliases() { ref alias, } = only(&select.projection) { - assert_eq!(&SQLOperator::Plus, op); + assert_eq!(&SQLBinaryOperator::Plus, op); assert_eq!(&ASTNode::SQLValue(Value::Long(1)), right.as_ref()); assert_eq!("newname", alias); } else { @@ -337,7 +337,7 @@ fn parse_select_count_distinct() { &ASTNode::SQLFunction(SQLFunction { name: SQLObjectName(vec!["COUNT".to_string()]), args: vec![ASTNode::SQLUnaryOp { - op: SQLOperator::Plus, + op: SQLUnaryOperator::Plus, expr: Box::new(ASTNode::SQLIdentifier("x".to_string())) }], over: None, @@ -404,7 +404,7 @@ fn parse_projection_nested_type() { #[test] fn parse_escaped_single_quote_string_predicate() { use self::ASTNode::*; - use self::SQLOperator::*; + use self::SQLBinaryOperator::*; let sql = "SELECT id, fname, lname FROM customer \ WHERE salary <> 'Jim''s salary'"; let ast = verified_only_select(sql); @@ -423,7 +423,7 @@ fn parse_escaped_single_quote_string_predicate() { #[test] fn parse_compound_expr_1() { use self::ASTNode::*; - use self::SQLOperator::*; + use self::SQLBinaryOperator::*; let sql = "a + b * c"; assert_eq!( SQLBinaryOp { @@ -442,7 +442,7 @@ fn parse_compound_expr_1() { #[test] fn parse_compound_expr_2() { use self::ASTNode::*; - use self::SQLOperator::*; + use self::SQLBinaryOperator::*; let sql = "a * b + c"; assert_eq!( SQLBinaryOp { @@ -461,17 +461,16 @@ fn parse_compound_expr_2() { #[test] fn parse_unary_math() { use self::ASTNode::*; - use self::SQLOperator::*; let sql = "- a + - b"; assert_eq!( SQLBinaryOp { left: Box::new(SQLUnaryOp { - op: Minus, + op: SQLUnaryOperator::Minus, expr: Box::new(SQLIdentifier("a".to_string())), }), - op: Plus, + op: SQLBinaryOperator::Plus, right: Box::new(SQLUnaryOp { - op: Minus, + op: SQLUnaryOperator::Minus, expr: Box::new(SQLIdentifier("b".to_string())), }), }, @@ -505,14 +504,14 @@ fn parse_not_precedence() { // 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 { - op: SQLOperator::Or, + op: SQLBinaryOperator::Or, .. }); // But NOT has lower precedence than comparison operators, so the following parses as NOT (a IS NULL) let sql = "NOT a IS NULL"; assert_matches!(verified_expr(sql), SQLUnaryOp { - op: SQLOperator::Not, + op: SQLUnaryOperator::Not, .. }); @@ -521,7 +520,7 @@ fn parse_not_precedence() { assert_eq!( verified_expr(sql), SQLUnaryOp { - op: SQLOperator::Not, + op: SQLUnaryOperator::Not, expr: Box::new(SQLBetween { expr: Box::new(SQLValue(Value::Long(1))), low: Box::new(SQLValue(Value::Long(1))), @@ -536,10 +535,10 @@ fn parse_not_precedence() { assert_eq!( verified_expr(sql), SQLUnaryOp { - op: SQLOperator::Not, + op: SQLUnaryOperator::Not, expr: Box::new(SQLBinaryOp { left: Box::new(SQLValue(Value::SingleQuotedString("a".into()))), - op: SQLOperator::NotLike, + op: SQLBinaryOperator::NotLike, right: Box::new(SQLValue(Value::SingleQuotedString("b".into()))), }), }, @@ -550,7 +549,7 @@ fn parse_not_precedence() { assert_eq!( verified_expr(sql), SQLUnaryOp { - op: SQLOperator::Not, + op: SQLUnaryOperator::Not, expr: Box::new(SQLInList { expr: Box::new(SQLIdentifier("a".into())), list: vec![SQLValue(Value::SingleQuotedString("a".into()))], @@ -572,9 +571,9 @@ fn parse_like() { ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLIdentifier("name".to_string())), op: if negated { - SQLOperator::NotLike + SQLBinaryOperator::NotLike } else { - SQLOperator::Like + SQLBinaryOperator::Like }, right: Box::new(ASTNode::SQLValue(Value::SingleQuotedString( "%a".to_string() @@ -594,9 +593,9 @@ fn parse_like() { ASTNode::SQLIsNull(Box::new(ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLIdentifier("name".to_string())), op: if negated { - SQLOperator::NotLike + SQLBinaryOperator::NotLike } else { - SQLOperator::Like + SQLBinaryOperator::Like }, right: Box::new(ASTNode::SQLValue(Value::SingleQuotedString( "%a".to_string() @@ -672,7 +671,7 @@ fn parse_between() { #[test] fn parse_between_with_expr() { use self::ASTNode::*; - use self::SQLOperator::*; + 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!( @@ -699,14 +698,14 @@ fn parse_between_with_expr() { ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLValue(Value::Long(1))), - op: SQLOperator::Eq, + op: SQLBinaryOperator::Eq, right: Box::new(ASTNode::SQLValue(Value::Long(1))), }), - op: SQLOperator::And, + op: SQLBinaryOperator::And, right: Box::new(ASTNode::SQLBetween { expr: Box::new(ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLValue(Value::Long(1))), - op: SQLOperator::Plus, + op: SQLBinaryOperator::Plus, right: Box::new(ASTNode::SQLIdentifier("x".to_string())), }), low: Box::new(ASTNode::SQLValue(Value::Long(1))), @@ -1365,7 +1364,7 @@ fn parse_delimited_identifiers() { #[test] fn parse_parens() { use self::ASTNode::*; - use self::SQLOperator::*; + use self::SQLBinaryOperator::*; let sql = "(a + b) - (c + d)"; assert_eq!( SQLBinaryOp { @@ -1389,7 +1388,7 @@ fn parse_parens() { fn parse_searched_case_expression() { 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::SQLOperator::*; + use self::SQLBinaryOperator::*; let select = verified_only_select(sql); assert_eq!( &SQLCase { @@ -1557,7 +1556,7 @@ fn parse_joins_on() { }, join_operator: f(JoinConstraint::On(ASTNode::SQLBinaryOp { left: Box::new(ASTNode::SQLIdentifier("c1".into())), - op: SQLOperator::Eq, + op: SQLBinaryOperator::Eq, right: Box::new(ASTNode::SQLIdentifier("c2".into())), })), } @@ -1921,7 +1920,7 @@ fn parse_scalar_subqueries() { use self::ASTNode::*; let sql = "(SELECT 1) + (SELECT 2)"; assert_matches!(verified_expr(sql), SQLBinaryOp { - op: SQLOperator::Plus, .. + op: SQLBinaryOperator::Plus, .. //left: box SQLSubquery { .. }, //right: box SQLSubquery { .. }, }); @@ -1941,7 +1940,7 @@ fn parse_exists_subquery() { let select = verified_only_select(sql); assert_eq!( ASTNode::SQLUnaryOp { - op: SQLOperator::Not, + op: SQLUnaryOperator::Not, expr: Box::new(ASTNode::SQLExists(Box::new(expected_inner))), }, select.selection.unwrap(),