From cf655ad1a68f4d079019e43c5cda363897cd7a49 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Mon, 24 Jun 2019 12:56:26 -0400 Subject: [PATCH 1/2] Remove "sql" prefix from module names Since this crate only deals with SQL parsing, the modules are understood to refer to SQL and don't need to restate that explicitly. --- examples/cli.rs | 2 +- examples/parse_select.rs | 2 +- src/{sqlast/sqltype.rs => ast/data_type.rs} | 0 src/{sqlast => ast}/ddl.rs | 0 src/{sqlast => ast}/mod.rs | 10 +++++----- src/{sqlast/sql_operator.rs => ast/operator.rs} | 0 src/{sqlast => ast}/query.rs | 0 src/{sqlast => ast}/value.rs | 0 src/dialect/{ansi_sql.rs => ansi.rs} | 0 src/dialect/{generic_sql.rs => generic.rs} | 0 src/dialect/mod.rs | 8 ++++---- src/lib.rs | 8 ++++---- src/{sqlparser.rs => parser.rs} | 4 ++-- src/test_utils.rs | 6 +++--- src/{sqltokenizer.rs => tokenizer.rs} | 0 tests/sqlparser_common.rs | 4 ++-- tests/sqlparser_mssql.rs | 2 +- tests/sqlparser_postgres.rs | 2 +- 18 files changed, 24 insertions(+), 24 deletions(-) rename src/{sqlast/sqltype.rs => ast/data_type.rs} (100%) rename src/{sqlast => ast}/ddl.rs (100%) rename src/{sqlast => ast}/mod.rs (99%) rename src/{sqlast/sql_operator.rs => ast/operator.rs} (100%) rename src/{sqlast => ast}/query.rs (100%) rename src/{sqlast => ast}/value.rs (100%) rename src/dialect/{ansi_sql.rs => ansi.rs} (100%) rename src/dialect/{generic_sql.rs => generic.rs} (100%) rename src/{sqlparser.rs => parser.rs} (99%) rename src/{sqltokenizer.rs => tokenizer.rs} (100%) diff --git a/examples/cli.rs b/examples/cli.rs index f288fd13..b0e171a9 100644 --- a/examples/cli.rs +++ b/examples/cli.rs @@ -19,7 +19,7 @@ use simple_logger; use std::fs; use sqlparser::dialect::*; -use sqlparser::sqlparser::Parser; +use sqlparser::parser::Parser; fn main() { simple_logger::init().unwrap(); diff --git a/examples/parse_select.rs b/examples/parse_select.rs index d79ab26e..cdeba870 100644 --- a/examples/parse_select.rs +++ b/examples/parse_select.rs @@ -13,7 +13,7 @@ #![warn(clippy::all)] use sqlparser::dialect::GenericSqlDialect; -use sqlparser::sqlparser::*; +use sqlparser::parser::*; fn main() { let sql = "SELECT a, b, 123, myfunc(b) \ diff --git a/src/sqlast/sqltype.rs b/src/ast/data_type.rs similarity index 100% rename from src/sqlast/sqltype.rs rename to src/ast/data_type.rs diff --git a/src/sqlast/ddl.rs b/src/ast/ddl.rs similarity index 100% rename from src/sqlast/ddl.rs rename to src/ast/ddl.rs diff --git a/src/sqlast/mod.rs b/src/ast/mod.rs similarity index 99% rename from src/sqlast/mod.rs rename to src/ast/mod.rs index 34efb0f4..273e7bc4 100644 --- a/src/sqlast/mod.rs +++ b/src/ast/mod.rs @@ -12,23 +12,23 @@ //! SQL Abstract Syntax Tree (AST) types +mod data_type; mod ddl; +mod operator; mod query; -mod sql_operator; -mod sqltype; mod value; use std::ops::Deref; +pub use self::data_type::SQLType; pub use self::ddl::{ AlterTableOperation, ColumnOption, ColumnOptionDef, SQLColumnDef, TableConstraint, }; +pub use self::operator::{SQLBinaryOperator, SQLUnaryOperator}; 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}; /// Like `vec.join(", ")`, but for any types implementing ToString. @@ -662,7 +662,7 @@ impl ToString for FileFormat { } } -use crate::sqlparser::ParserError; +use crate::parser::ParserError; use std::str::FromStr; impl FromStr for FileFormat { type Err = ParserError; diff --git a/src/sqlast/sql_operator.rs b/src/ast/operator.rs similarity index 100% rename from src/sqlast/sql_operator.rs rename to src/ast/operator.rs diff --git a/src/sqlast/query.rs b/src/ast/query.rs similarity index 100% rename from src/sqlast/query.rs rename to src/ast/query.rs diff --git a/src/sqlast/value.rs b/src/ast/value.rs similarity index 100% rename from src/sqlast/value.rs rename to src/ast/value.rs diff --git a/src/dialect/ansi_sql.rs b/src/dialect/ansi.rs similarity index 100% rename from src/dialect/ansi_sql.rs rename to src/dialect/ansi.rs diff --git a/src/dialect/generic_sql.rs b/src/dialect/generic.rs similarity index 100% rename from src/dialect/generic_sql.rs rename to src/dialect/generic.rs diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs index 83b93833..66e4398c 100644 --- a/src/dialect/mod.rs +++ b/src/dialect/mod.rs @@ -10,16 +10,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -mod ansi_sql; -mod generic_sql; +mod ansi; +mod generic; pub mod keywords; mod mssql; mod postgresql; use std::fmt::Debug; -pub use self::ansi_sql::AnsiSqlDialect; -pub use self::generic_sql::GenericSqlDialect; +pub use self::ansi::AnsiSqlDialect; +pub use self::generic::GenericSqlDialect; pub use self::mssql::MsSqlDialect; pub use self::postgresql::PostgreSqlDialect; diff --git a/src/lib.rs b/src/lib.rs index cd233152..ad6055da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,7 @@ //! //! ``` //! use sqlparser::dialect::GenericSqlDialect; -//! use sqlparser::sqlparser::Parser; +//! use sqlparser::parser::Parser; //! //! let dialect = GenericSqlDialect {}; // or AnsiSqlDialect //! @@ -34,10 +34,10 @@ //! ``` #![warn(clippy::all)] +pub mod ast; pub mod dialect; -pub mod sqlast; -pub mod sqlparser; -pub mod sqltokenizer; +pub mod parser; +pub mod tokenizer; #[doc(hidden)] // This is required to make utilities accessible by both the crate-internal diff --git a/src/sqlparser.rs b/src/parser.rs similarity index 99% rename from src/sqlparser.rs rename to src/parser.rs index d02c6b71..ce243475 100644 --- a/src/sqlparser.rs +++ b/src/parser.rs @@ -14,10 +14,10 @@ use log::debug; +use super::ast::*; use super::dialect::keywords; use super::dialect::Dialect; -use super::sqlast::*; -use super::sqltokenizer::*; +use super::tokenizer::*; use std::error::Error; #[derive(Debug, Clone, PartialEq)] diff --git a/src/test_utils.rs b/src/test_utils.rs index 5f738d4f..d79ac679 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -12,10 +12,10 @@ use std::fmt::Debug; +use super::ast::*; use super::dialect::*; -use super::sqlast::*; -use super::sqlparser::{Parser, ParserError}; -use super::sqltokenizer::Tokenizer; +use super::parser::{Parser, ParserError}; +use super::tokenizer::Tokenizer; /// Tests use the methods on this struct to invoke the parser on one or /// multiple dialects. diff --git a/src/sqltokenizer.rs b/src/tokenizer.rs similarity index 100% rename from src/sqltokenizer.rs rename to src/tokenizer.rs diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 54235870..2ff9e821 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -20,8 +20,8 @@ use matches::assert_matches; -use sqlparser::sqlast::*; -use sqlparser::sqlparser::*; +use sqlparser::ast::*; +use sqlparser::parser::*; use sqlparser::test_utils::{all_dialects, expr_from_projection, only}; #[test] diff --git a/tests/sqlparser_mssql.rs b/tests/sqlparser_mssql.rs index 5f878b71..c5ac731f 100644 --- a/tests/sqlparser_mssql.rs +++ b/tests/sqlparser_mssql.rs @@ -14,8 +14,8 @@ //! Test SQL syntax specific to Microsoft's T-SQL. The parser based on the //! generic dialect is also tested (on the inputs it can handle). +use sqlparser::ast::*; use sqlparser::dialect::{GenericSqlDialect, MsSqlDialect}; -use sqlparser::sqlast::*; use sqlparser::test_utils::*; #[test] diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index a772f3c0..4266bbe9 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -14,8 +14,8 @@ //! Test SQL syntax specific to PostgreSQL. The parser based on the //! generic dialect is also tested (on the inputs it can handle). +use sqlparser::ast::*; use sqlparser::dialect::{GenericSqlDialect, PostgreSqlDialect}; -use sqlparser::sqlast::*; use sqlparser::test_utils::*; #[test] From ac555d7e860960fad54ed02626f1decdcddb2e5a Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Mon, 24 Jun 2019 13:26:35 -0400 Subject: [PATCH 2/2] Remove "SQL" prefix from types The rationale here is the same as the last commit: since this crate exclusively parses SQL, there's no need to restate that in every type name. (The prefix seems to be an artifact of this crate's history as a submodule of Datafusion, where it was useful to explicitly call out which types were related to SQL parsing.) This commit has the additional benefit of making all type names consistent; over type we'd added some types which were not prefixed with "SQL". --- examples/cli.rs | 4 +- examples/parse_select.rs | 4 +- src/ast/data_type.rs | 58 ++-- src/ast/ddl.rs | 36 +-- src/ast/mod.rs | 276 ++++++++-------- src/ast/operator.rs | 44 +-- src/ast/query.rs | 84 ++--- src/dialect/ansi.rs | 4 +- src/dialect/generic.rs | 4 +- src/dialect/mod.rs | 4 +- src/lib.rs | 4 +- src/parser.rs | 384 +++++++++++----------- src/test_utils.rs | 22 +- src/tokenizer.rs | 48 +-- tests/sqlparser_common.rs | 611 ++++++++++++++++++------------------ tests/sqlparser_mssql.rs | 8 +- tests/sqlparser_postgres.rs | 59 ++-- 17 files changed, 818 insertions(+), 836 deletions(-) diff --git a/examples/cli.rs b/examples/cli.rs index b0e171a9..77a0b501 100644 --- a/examples/cli.rs +++ b/examples/cli.rs @@ -30,10 +30,10 @@ fn main() { ); let dialect: Box = match std::env::args().nth(2).unwrap_or_default().as_ref() { - "--ansi" => Box::new(AnsiSqlDialect {}), + "--ansi" => Box::new(AnsiDialect {}), "--postgres" => Box::new(PostgreSqlDialect {}), "--ms" => Box::new(MsSqlDialect {}), - "--generic" | "" => Box::new(GenericSqlDialect {}), + "--generic" | "" => Box::new(GenericDialect {}), s => panic!("Unexpected parameter: {}", s), }; diff --git a/examples/parse_select.rs b/examples/parse_select.rs index cdeba870..539d9165 100644 --- a/examples/parse_select.rs +++ b/examples/parse_select.rs @@ -12,7 +12,7 @@ #![warn(clippy::all)] -use sqlparser::dialect::GenericSqlDialect; +use sqlparser::dialect::GenericDialect; use sqlparser::parser::*; fn main() { @@ -21,7 +21,7 @@ fn main() { WHERE a > b AND b < 100 \ ORDER BY a DESC, b"; - let dialect = GenericSqlDialect {}; + let dialect = GenericDialect {}; let ast = Parser::parse_sql(&dialect, sql.to_string()).unwrap(); diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index 5b63f1db..4aede859 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -10,11 +10,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::SQLObjectName; +use super::ObjectName; /// SQL data types #[derive(Debug, Clone, PartialEq, Hash)] -pub enum SQLType { +pub enum DataType { /// Fixed-length character type e.g. CHAR(10) Char(Option), /// Variable-length character type e.g. VARCHAR(10) @@ -60,44 +60,44 @@ pub enum SQLType { /// Bytea Bytea, /// Custom type such as enums - Custom(SQLObjectName), + Custom(ObjectName), /// Arrays - Array(Box), + Array(Box), } -impl ToString for SQLType { +impl ToString for DataType { fn to_string(&self) -> String { match self { - SQLType::Char(size) => format_type_with_optional_length("char", size), - SQLType::Varchar(size) => format_type_with_optional_length("character varying", size), - SQLType::Uuid => "uuid".to_string(), - SQLType::Clob(size) => format!("clob({})", size), - SQLType::Binary(size) => format!("binary({})", size), - SQLType::Varbinary(size) => format!("varbinary({})", size), - SQLType::Blob(size) => format!("blob({})", size), - SQLType::Decimal(precision, scale) => { + DataType::Char(size) => format_type_with_optional_length("char", size), + DataType::Varchar(size) => format_type_with_optional_length("character varying", size), + DataType::Uuid => "uuid".to_string(), + DataType::Clob(size) => format!("clob({})", size), + DataType::Binary(size) => format!("binary({})", size), + DataType::Varbinary(size) => format!("varbinary({})", size), + DataType::Blob(size) => format!("blob({})", size), + DataType::Decimal(precision, scale) => { if let Some(scale) = scale { format!("numeric({},{})", precision.unwrap(), scale) } else { format_type_with_optional_length("numeric", precision) } } - SQLType::Float(size) => format_type_with_optional_length("float", size), - SQLType::SmallInt => "smallint".to_string(), - SQLType::Int => "int".to_string(), - SQLType::BigInt => "bigint".to_string(), - SQLType::Real => "real".to_string(), - SQLType::Double => "double".to_string(), - SQLType::Boolean => "boolean".to_string(), - SQLType::Date => "date".to_string(), - SQLType::Time => "time".to_string(), - SQLType::Timestamp => "timestamp".to_string(), - SQLType::Interval => "interval".to_string(), - SQLType::Regclass => "regclass".to_string(), - SQLType::Text => "text".to_string(), - SQLType::Bytea => "bytea".to_string(), - SQLType::Array(ty) => format!("{}[]", ty.to_string()), - SQLType::Custom(ty) => ty.to_string(), + DataType::Float(size) => format_type_with_optional_length("float", size), + DataType::SmallInt => "smallint".to_string(), + DataType::Int => "int".to_string(), + DataType::BigInt => "bigint".to_string(), + DataType::Real => "real".to_string(), + DataType::Double => "double".to_string(), + DataType::Boolean => "boolean".to_string(), + DataType::Date => "date".to_string(), + DataType::Time => "time".to_string(), + DataType::Timestamp => "timestamp".to_string(), + DataType::Interval => "interval".to_string(), + DataType::Regclass => "regclass".to_string(), + DataType::Text => "text".to_string(), + DataType::Bytea => "bytea".to_string(), + DataType::Array(ty) => format!("{}[]", ty.to_string()), + DataType::Custom(ty) => ty.to_string(), } } } diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index e39e533b..3f7c4281 100644 --- a/src/ast/ddl.rs +++ b/src/ast/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::{Expr, SQLIdent, SQLObjectName, SQLType}; +use super::{DataType, Expr, Ident, ObjectName}; /// An `ALTER TABLE` (`SQLStatement::SQLAlterTable`) operation #[derive(Debug, Clone, PartialEq, Hash)] @@ -8,7 +8,7 @@ pub enum AlterTableOperation { /// `ADD ` AddConstraint(TableConstraint), /// TODO: implement `DROP CONSTRAINT ` - DropConstraint { name: SQLIdent }, + DropConstraint { name: Ident }, } impl ToString for AlterTableOperation { @@ -26,22 +26,22 @@ impl ToString for AlterTableOperation { pub enum TableConstraint { /// `[ CONSTRAINT ] { PRIMARY KEY | UNIQUE } ()` Unique { - name: Option, - columns: Vec, + name: Option, + columns: Vec, /// Whether this is a `PRIMARY KEY` or just a `UNIQUE` constraint is_primary: bool, }, /// A referential integrity constraint (`[ CONSTRAINT ] FOREIGN KEY () /// REFERENCES ()`) ForeignKey { - name: Option, - columns: Vec, - foreign_table: SQLObjectName, - referred_columns: Vec, + name: Option, + columns: Vec, + foreign_table: ObjectName, + referred_columns: Vec, }, /// `[ CONSTRAINT ] CHECK ()` Check { - name: Option, + name: Option, expr: Box, }, } @@ -82,14 +82,14 @@ impl ToString for TableConstraint { /// SQL column definition #[derive(Debug, Clone, PartialEq, Hash)] -pub struct SQLColumnDef { - pub name: SQLIdent, - pub data_type: SQLType, - pub collation: Option, +pub struct ColumnDef { + pub name: Ident, + pub data_type: DataType, + pub collation: Option, pub options: Vec, } -impl ToString for SQLColumnDef { +impl ToString for ColumnDef { fn to_string(&self) -> String { format!( "{} {}{}", @@ -122,7 +122,7 @@ impl ToString for SQLColumnDef { /// "column options," and we allow any column option to be named. #[derive(Debug, Clone, PartialEq, Hash)] pub struct ColumnOptionDef { - pub name: Option, + pub name: Option, pub option: ColumnOption, } @@ -153,8 +153,8 @@ pub enum ColumnOption { /// A referential integrity constraint (`[FOREIGN KEY REFERENCES /// ()`). ForeignKey { - foreign_table: SQLObjectName, - referred_columns: Vec, + foreign_table: ObjectName, + referred_columns: Vec, }, // `CHECK ()` Check(Expr), @@ -187,7 +187,7 @@ impl ToString for ColumnOption { } } -fn format_constraint_name(name: &Option) -> String { +fn format_constraint_name(name: &Option) -> String { name.as_ref() .map(|name| format!("CONSTRAINT {} ", name)) .unwrap_or_default() diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 273e7bc4..cac2ccff 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -20,14 +20,14 @@ mod value; use std::ops::Deref; -pub use self::data_type::SQLType; +pub use self::data_type::DataType; pub use self::ddl::{ - AlterTableOperation, ColumnOption, ColumnOptionDef, SQLColumnDef, TableConstraint, + AlterTableOperation, ColumnDef, ColumnOption, ColumnOptionDef, TableConstraint, }; -pub use self::operator::{SQLBinaryOperator, SQLUnaryOperator}; +pub use self::operator::{BinaryOperator, UnaryOperator}; pub use self::query::{ - Cte, Fetch, Join, JoinConstraint, JoinOperator, SQLOrderByExpr, SQLQuery, SQLSelect, - SQLSelectItem, SQLSetExpr, SQLSetOperator, SQLValues, TableAlias, TableFactor, TableWithJoins, + Cte, Fetch, Join, JoinConstraint, JoinOperator, OrderByExpr, Query, Select, SelectItem, + SetExpr, SetOperator, TableAlias, TableFactor, TableWithJoins, Values, }; pub use self::value::{SQLDateTimeField, Value}; @@ -45,7 +45,7 @@ where } /// Identifier name, in the originally quoted form (e.g. `"id"`) -pub type SQLIdent = String; +pub type Ident = String; /// An SQL expression of any type. /// @@ -55,76 +55,76 @@ pub type SQLIdent = String; #[derive(Debug, Clone, PartialEq, Hash)] pub enum Expr { /// Identifier e.g. table name or column name - SQLIdentifier(SQLIdent), + Identifier(Ident), /// Unqualified wildcard (`*`). SQL allows this in limited contexts, such as: /// - right after `SELECT` (which is represented as a [SQLSelectItem::Wildcard] instead) /// - or as part of an aggregate function, e.g. `COUNT(*)`, /// /// ...but we currently also accept it in contexts where it doesn't make /// sense, such as `* + *` - SQLWildcard, + Wildcard, /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`. /// (Same caveats apply to SQLQualifiedWildcard as to SQLWildcard.) - SQLQualifiedWildcard(Vec), + QualifiedWildcard(Vec), /// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col` - SQLCompoundIdentifier(Vec), + CompoundIdentifier(Vec), /// `IS NULL` expression - SQLIsNull(Box), + IsNull(Box), /// `IS NOT NULL` expression - SQLIsNotNull(Box), + IsNotNull(Box), /// `[ NOT ] IN (val1, val2, ...)` - SQLInList { + InList { expr: Box, list: Vec, negated: bool, }, /// `[ NOT ] IN (SELECT ...)` - SQLInSubquery { + InSubquery { expr: Box, - subquery: Box, + subquery: Box, negated: bool, }, /// ` [ NOT ] BETWEEN AND ` - SQLBetween { + Between { expr: Box, negated: bool, low: Box, high: Box, }, /// Binary operation e.g. `1 + 1` or `foo > bar` - SQLBinaryOp { + BinaryOp { left: Box, - op: SQLBinaryOperator, + op: BinaryOperator, right: Box, }, /// Unary operation e.g. `NOT foo` - SQLUnaryOp { - op: SQLUnaryOperator, - expr: Box, - }, + UnaryOp { op: UnaryOperator, expr: Box }, /// CAST an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))` - SQLCast { expr: Box, data_type: SQLType }, - SQLExtract { + Cast { + expr: Box, + data_type: DataType, + }, + Extract { field: SQLDateTimeField, expr: Box, }, /// `expr COLLATE collation` - SQLCollate { + Collate { expr: Box, - collation: SQLObjectName, + collation: ObjectName, }, /// Nested expression e.g. `(foo > bar)` or `(1)` - SQLNested(Box), + Nested(Box), /// SQLValue - SQLValue(Value), + Value(Value), /// Scalar function call e.g. `LEFT(foo, 5)` - SQLFunction(SQLFunction), + Function(Function), /// `CASE [] WHEN THEN ... [ELSE ] END` /// /// Note we only recognize a complete single expression as ``, /// not `< 0` nor `1, 2, 3` as allowed in a `` per /// - SQLCase { + Case { operand: Option>, conditions: Vec, results: Vec, @@ -132,22 +132,22 @@ pub enum Expr { }, /// An exists expression `EXISTS(SELECT ...)`, used in expressions like /// `WHERE EXISTS (SELECT ...)`. - SQLExists(Box), + Exists(Box), /// A parenthesized subquery `(SELECT ...)`, used in expression like /// `SELECT (subquery) AS x` or `WHERE (subquery) = x` - SQLSubquery(Box), + Subquery(Box), } impl ToString for Expr { fn to_string(&self) -> String { match self { - 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::Identifier(s) => s.to_string(), + Expr::Wildcard => "*".to_string(), + Expr::QualifiedWildcard(q) => q.join(".") + ".*", + Expr::CompoundIdentifier(s) => s.join("."), + Expr::IsNull(ast) => format!("{} IS NULL", ast.as_ref().to_string()), + Expr::IsNotNull(ast) => format!("{} IS NOT NULL", ast.as_ref().to_string()), + Expr::InList { expr, list, negated, @@ -157,7 +157,7 @@ impl ToString for Expr { if *negated { "NOT " } else { "" }, comma_separated_string(list) ), - Expr::SQLInSubquery { + Expr::InSubquery { expr, subquery, negated, @@ -167,7 +167,7 @@ impl ToString for Expr { if *negated { "NOT " } else { "" }, subquery.to_string() ), - Expr::SQLBetween { + Expr::Between { expr, negated, low, @@ -179,32 +179,32 @@ impl ToString for Expr { low.to_string(), high.to_string() ), - Expr::SQLBinaryOp { left, op, right } => format!( + Expr::BinaryOp { left, op, right } => format!( "{} {} {}", left.as_ref().to_string(), op.to_string(), right.as_ref().to_string() ), - Expr::SQLUnaryOp { op, expr } => { + Expr::UnaryOp { op, expr } => { format!("{} {}", op.to_string(), expr.as_ref().to_string()) } - Expr::SQLCast { expr, data_type } => format!( + Expr::Cast { expr, data_type } => format!( "CAST({} AS {})", expr.as_ref().to_string(), data_type.to_string() ), - Expr::SQLExtract { field, expr } => { + Expr::Extract { field, expr } => { format!("EXTRACT({} FROM {})", field.to_string(), expr.to_string()) } - Expr::SQLCollate { expr, collation } => format!( + Expr::Collate { expr, collation } => format!( "{} COLLATE {}", expr.as_ref().to_string(), collation.to_string() ), - Expr::SQLNested(ast) => format!("({})", ast.as_ref().to_string()), - Expr::SQLValue(v) => v.to_string(), - Expr::SQLFunction(f) => f.to_string(), - Expr::SQLCase { + Expr::Nested(ast) => format!("({})", ast.as_ref().to_string()), + Expr::Value(v) => v.to_string(), + Expr::Function(f) => f.to_string(), + Expr::Case { operand, conditions, results, @@ -225,21 +225,21 @@ impl ToString for Expr { } s + " END" } - Expr::SQLExists(s) => format!("EXISTS ({})", s.to_string()), - Expr::SQLSubquery(s) => format!("({})", s.to_string()), + Expr::Exists(s) => format!("EXISTS ({})", s.to_string()), + Expr::Subquery(s) => format!("({})", s.to_string()), } } } /// A window specification (i.e. `OVER (PARTITION BY .. ORDER BY .. etc.)`) #[derive(Debug, Clone, PartialEq, Hash)] -pub struct SQLWindowSpec { +pub struct WindowSpec { pub partition_by: Vec, - pub order_by: Vec, - pub window_frame: Option, + pub order_by: Vec, + pub window_frame: Option, } -impl ToString for SQLWindowSpec { +impl ToString for WindowSpec { fn to_string(&self) -> String { let mut clauses = vec![]; if !self.partition_by.is_empty() { @@ -277,39 +277,39 @@ impl ToString for SQLWindowSpec { /// Specifies the data processed by a window function, e.g. /// `RANGE UNBOUNDED PRECEDING` or `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`. #[derive(Debug, Clone, PartialEq, Hash)] -pub struct SQLWindowFrame { - pub units: SQLWindowFrameUnits, - pub start_bound: SQLWindowFrameBound, +pub struct WindowFrame { + pub units: WindowFrameUnits, + pub start_bound: WindowFrameBound, /// The right bound of the `BETWEEN .. AND` clause. - pub end_bound: Option, + pub end_bound: Option, // TBD: EXCLUDE } #[derive(Debug, Clone, PartialEq, Hash)] -pub enum SQLWindowFrameUnits { +pub enum WindowFrameUnits { Rows, Range, Groups, } -impl ToString for SQLWindowFrameUnits { +impl ToString for WindowFrameUnits { fn to_string(&self) -> String { match self { - SQLWindowFrameUnits::Rows => "ROWS".to_string(), - SQLWindowFrameUnits::Range => "RANGE".to_string(), - SQLWindowFrameUnits::Groups => "GROUPS".to_string(), + WindowFrameUnits::Rows => "ROWS".to_string(), + WindowFrameUnits::Range => "RANGE".to_string(), + WindowFrameUnits::Groups => "GROUPS".to_string(), } } } -impl FromStr for SQLWindowFrameUnits { +impl FromStr for WindowFrameUnits { type Err = ParserError; fn from_str(s: &str) -> Result { match s { - "ROWS" => Ok(SQLWindowFrameUnits::Rows), - "RANGE" => Ok(SQLWindowFrameUnits::Range), - "GROUPS" => Ok(SQLWindowFrameUnits::Groups), + "ROWS" => Ok(WindowFrameUnits::Rows), + "RANGE" => Ok(WindowFrameUnits::Range), + "GROUPS" => Ok(WindowFrameUnits::Groups), _ => Err(ParserError::ParserError(format!( "Expected ROWS, RANGE, or GROUPS, found: {}", s @@ -319,7 +319,7 @@ impl FromStr for SQLWindowFrameUnits { } #[derive(Debug, Clone, PartialEq, Hash)] -pub enum SQLWindowFrameBound { +pub enum WindowFrameBound { /// "CURRENT ROW" CurrentRow, /// " PRECEDING" or "UNBOUNDED PRECEDING" @@ -329,14 +329,14 @@ pub enum SQLWindowFrameBound { Following(Option), } -impl ToString for SQLWindowFrameBound { +impl ToString for WindowFrameBound { fn to_string(&self) -> String { match self { - SQLWindowFrameBound::CurrentRow => "CURRENT ROW".to_string(), - SQLWindowFrameBound::Preceding(None) => "UNBOUNDED PRECEDING".to_string(), - SQLWindowFrameBound::Following(None) => "UNBOUNDED FOLLOWING".to_string(), - SQLWindowFrameBound::Preceding(Some(n)) => format!("{} PRECEDING", n), - SQLWindowFrameBound::Following(Some(n)) => format!("{} FOLLOWING", n), + WindowFrameBound::CurrentRow => "CURRENT ROW".to_string(), + WindowFrameBound::Preceding(None) => "UNBOUNDED PRECEDING".to_string(), + WindowFrameBound::Following(None) => "UNBOUNDED FOLLOWING".to_string(), + WindowFrameBound::Preceding(Some(n)) => format!("{} PRECEDING", n), + WindowFrameBound::Following(Some(n)) => format!("{} FOLLOWING", n), } } } @@ -344,91 +344,91 @@ impl ToString for SQLWindowFrameBound { /// A top-level statement (SELECT, INSERT, CREATE, etc.) #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq, Hash)] -pub enum SQLStatement { +pub enum Statement { /// SELECT - SQLQuery(Box), + Query(Box), /// INSERT - SQLInsert { + Insert { /// TABLE - table_name: SQLObjectName, + table_name: ObjectName, /// COLUMNS - columns: Vec, + columns: Vec, /// A SQL query that specifies what to insert - source: Box, + source: Box, }, - SQLCopy { + Copy { /// TABLE - table_name: SQLObjectName, + table_name: ObjectName, /// COLUMNS - columns: Vec, + columns: Vec, /// VALUES a vector of values to be copied values: Vec>, }, /// UPDATE - SQLUpdate { + Update { /// TABLE - table_name: SQLObjectName, + table_name: ObjectName, /// Column assignments - assignments: Vec, + assignments: Vec, /// WHERE selection: Option, }, /// DELETE - SQLDelete { + Delete { /// FROM - table_name: SQLObjectName, + table_name: ObjectName, /// WHERE selection: Option, }, /// CREATE VIEW - SQLCreateView { + CreateView { /// View name - name: SQLObjectName, - columns: Vec, - query: Box, + name: ObjectName, + columns: Vec, + query: Box, materialized: bool, - with_options: Vec, + with_options: Vec, }, /// CREATE TABLE - SQLCreateTable { + CreateTable { /// Table name - name: SQLObjectName, + name: ObjectName, /// Optional schema - columns: Vec, + columns: Vec, constraints: Vec, - with_options: Vec, + with_options: Vec, external: bool, file_format: Option, location: Option, }, /// ALTER TABLE - SQLAlterTable { + AlterTable { /// Table name - name: SQLObjectName, + name: ObjectName, operation: AlterTableOperation, }, /// DROP TABLE - SQLDrop { - object_type: SQLObjectType, + Drop { + object_type: ObjectType, if_exists: bool, - names: Vec, + names: Vec, cascade: bool, }, /// `{ BEGIN [ TRANSACTION | WORK ] | START TRANSACTION } ...` - SQLStartTransaction { modes: Vec }, + StartTransaction { modes: Vec }, /// `SET TRANSACTION ...` - SQLSetTransaction { modes: Vec }, + SetTransaction { modes: Vec }, /// `COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]` - SQLCommit { chain: bool }, + Commit { chain: bool }, /// `ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]` - SQLRollback { chain: bool }, + Rollback { chain: bool }, } -impl ToString for SQLStatement { +impl ToString for Statement { fn to_string(&self) -> String { match self { - SQLStatement::SQLQuery(s) => s.to_string(), - SQLStatement::SQLInsert { + Statement::Query(s) => s.to_string(), + Statement::Insert { table_name, columns, source, @@ -440,7 +440,7 @@ impl ToString for SQLStatement { s += &source.to_string(); s } - SQLStatement::SQLCopy { + Statement::Copy { table_name, columns, values, @@ -463,7 +463,7 @@ impl ToString for SQLStatement { s += "\n\\."; s } - SQLStatement::SQLUpdate { + Statement::Update { table_name, assignments, selection, @@ -478,7 +478,7 @@ impl ToString for SQLStatement { } s } - SQLStatement::SQLDelete { + Statement::Delete { table_name, selection, } => { @@ -488,7 +488,7 @@ impl ToString for SQLStatement { } s } - SQLStatement::SQLCreateView { + Statement::CreateView { name, columns, query, @@ -515,7 +515,7 @@ impl ToString for SQLStatement { query.to_string(), ) } - SQLStatement::SQLCreateTable { + Statement::CreateTable { name, columns, constraints, @@ -546,10 +546,10 @@ impl ToString for SQLStatement { } s } - SQLStatement::SQLAlterTable { name, operation } => { + Statement::AlterTable { name, operation } => { format!("ALTER TABLE {} {}", name.to_string(), operation.to_string()) } - SQLStatement::SQLDrop { + Statement::Drop { object_type, if_exists, names, @@ -561,7 +561,7 @@ impl ToString for SQLStatement { comma_separated_string(names), if *cascade { " CASCADE" } else { "" }, ), - SQLStatement::SQLStartTransaction { modes } => format!( + Statement::StartTransaction { modes } => format!( "START TRANSACTION{}", if modes.is_empty() { "".into() @@ -569,7 +569,7 @@ impl ToString for SQLStatement { format!(" {}", comma_separated_string(modes)) } ), - SQLStatement::SQLSetTransaction { modes } => format!( + Statement::SetTransaction { modes } => format!( "SET TRANSACTION{}", if modes.is_empty() { "".into() @@ -577,10 +577,10 @@ impl ToString for SQLStatement { format!(" {}", comma_separated_string(modes)) } ), - SQLStatement::SQLCommit { chain } => { + Statement::Commit { chain } => { format!("COMMIT{}", if *chain { " AND CHAIN" } else { "" },) } - SQLStatement::SQLRollback { chain } => { + Statement::Rollback { chain } => { format!("ROLLBACK{}", if *chain { " AND CHAIN" } else { "" },) } } @@ -589,9 +589,9 @@ impl ToString for SQLStatement { /// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj #[derive(Debug, Clone, PartialEq, Hash)] -pub struct SQLObjectName(pub Vec); +pub struct ObjectName(pub Vec); -impl ToString for SQLObjectName { +impl ToString for ObjectName { fn to_string(&self) -> String { self.0.join(".") } @@ -599,12 +599,12 @@ impl ToString for SQLObjectName { /// SQL assignment `foo = expr` as used in SQLUpdate #[derive(Debug, Clone, PartialEq, Hash)] -pub struct SQLAssignment { - pub id: SQLIdent, +pub struct Assignment { + pub id: Ident, pub value: Expr, } -impl ToString for SQLAssignment { +impl ToString for Assignment { fn to_string(&self) -> String { format!("{} = {}", self.id, self.value.to_string()) } @@ -612,15 +612,15 @@ impl ToString for SQLAssignment { /// SQL function #[derive(Debug, Clone, PartialEq, Hash)] -pub struct SQLFunction { - pub name: SQLObjectName, +pub struct Function { + pub name: ObjectName, pub args: Vec, - pub over: Option, + pub over: Option, // aggregate functions may specify eg `COUNT(DISTINCT x)` pub distinct: bool, } -impl ToString for SQLFunction { +impl ToString for Function { fn to_string(&self) -> String { let mut s = format!( "{}({}{})", @@ -686,27 +686,27 @@ impl FromStr for FileFormat { } #[derive(Debug, Clone, PartialEq, Hash)] -pub enum SQLObjectType { +pub enum ObjectType { Table, View, } -impl SQLObjectType { +impl ObjectType { fn to_string(&self) -> String { match self { - SQLObjectType::Table => "TABLE".into(), - SQLObjectType::View => "VIEW".into(), + ObjectType::Table => "TABLE".into(), + ObjectType::View => "VIEW".into(), } } } #[derive(Debug, Clone, PartialEq, Hash)] -pub struct SQLOption { - pub name: SQLIdent, +pub struct SqlOption { + pub name: Ident, pub value: Value, } -impl ToString for SQLOption { +impl ToString for SqlOption { fn to_string(&self) -> String { format!("{} = {}", self.name.to_string(), self.value.to_string()) } diff --git a/src/ast/operator.rs b/src/ast/operator.rs index 4845d062..32626e4f 100644 --- a/src/ast/operator.rs +++ b/src/ast/operator.rs @@ -12,25 +12,25 @@ /// Unary operators #[derive(Debug, Clone, PartialEq, Hash)] -pub enum SQLUnaryOperator { +pub enum UnaryOperator { Plus, Minus, Not, } -impl ToString for SQLUnaryOperator { +impl ToString for UnaryOperator { fn to_string(&self) -> String { match self { - SQLUnaryOperator::Plus => "+".to_string(), - SQLUnaryOperator::Minus => "-".to_string(), - SQLUnaryOperator::Not => "NOT".to_string(), + UnaryOperator::Plus => "+".to_string(), + UnaryOperator::Minus => "-".to_string(), + UnaryOperator::Not => "NOT".to_string(), } } } /// Binary operators #[derive(Debug, Clone, PartialEq, Hash)] -pub enum SQLBinaryOperator { +pub enum BinaryOperator { Plus, Minus, Multiply, @@ -48,24 +48,24 @@ pub enum SQLBinaryOperator { NotLike, } -impl ToString for SQLBinaryOperator { +impl ToString for BinaryOperator { fn to_string(&self) -> String { match self { - 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(), + BinaryOperator::Plus => "+".to_string(), + BinaryOperator::Minus => "-".to_string(), + BinaryOperator::Multiply => "*".to_string(), + BinaryOperator::Divide => "/".to_string(), + BinaryOperator::Modulus => "%".to_string(), + BinaryOperator::Gt => ">".to_string(), + BinaryOperator::Lt => "<".to_string(), + BinaryOperator::GtEq => ">=".to_string(), + BinaryOperator::LtEq => "<=".to_string(), + BinaryOperator::Eq => "=".to_string(), + BinaryOperator::NotEq => "<>".to_string(), + BinaryOperator::And => "AND".to_string(), + BinaryOperator::Or => "OR".to_string(), + BinaryOperator::Like => "LIKE".to_string(), + BinaryOperator::NotLike => "NOT LIKE".to_string(), } } } diff --git a/src/ast/query.rs b/src/ast/query.rs index e8d0cd08..2d09d821 100644 --- a/src/ast/query.rs +++ b/src/ast/query.rs @@ -15,13 +15,13 @@ use super::*; /// The most complete variant of a `SELECT` query expression, optionally /// including `WITH`, `UNION` / other set operations, and `ORDER BY`. #[derive(Debug, Clone, PartialEq, Hash)] -pub struct SQLQuery { +pub struct Query { /// WITH (common table expressions, or CTEs) pub ctes: Vec, /// SELECT or UNION / EXCEPT / INTECEPT - pub body: SQLSetExpr, + pub body: SetExpr, /// ORDER BY - pub order_by: Vec, + pub order_by: Vec, /// `LIMIT { | ALL }` pub limit: Option, /// `OFFSET { ROW | ROWS }` @@ -30,7 +30,7 @@ pub struct SQLQuery { pub fetch: Option, } -impl ToString for SQLQuery { +impl ToString for Query { fn to_string(&self) -> String { let mut s = String::new(); if !self.ctes.is_empty() { @@ -57,30 +57,30 @@ impl ToString for SQLQuery { /// A node in a tree, representing a "query body" expression, roughly: /// `SELECT ... [ {UNION|EXCEPT|INTERSECT} SELECT ...]` #[derive(Debug, Clone, PartialEq, Hash)] -pub enum SQLSetExpr { +pub enum SetExpr { /// Restricted SELECT .. FROM .. HAVING (no ORDER BY or set operations) - Select(Box), + Select(Box