From 646d1e13ca05589e085c9c7ce2f8cfa9ee81ed34 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Tue, 4 Jun 2019 13:56:37 -0400 Subject: [PATCH] Rename ASTNode to Expr The ASTNode enum was confusingly named. In the past, the name made sense, as the enum contained nearly all of the nodes in the AST, but over time, pieces have been split into different structs, like SQLStatement and SQLQuery. The ASTNode enum now contains only contains expression nodes, so Expr is a better name. Also rename the UnnamedExpression and ExpressionWithAlias variants of SQLSelectItem to UnnamedExpr and ExprWithAlias, respectively, to match the new shorthand for the word "expression". --- src/sqlast/ddl.rs | 8 +- src/sqlast/mod.rs | 95 +++++++------ src/sqlast/query.rs | 30 ++--- src/sqlparser.rs | 110 +++++++-------- src/test_utils.rs | 8 +- tests/sqlparser_common.rs | 260 ++++++++++++++++++------------------ tests/sqlparser_mssql.rs | 4 +- tests/sqlparser_postgres.rs | 4 +- 8 files changed, 255 insertions(+), 264 deletions(-) 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,