mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
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".
This commit is contained in:
parent
cf655ad1a6
commit
ac555d7e86
17 changed files with 818 additions and 836 deletions
|
@ -30,10 +30,10 @@ fn main() {
|
|||
);
|
||||
|
||||
let dialect: Box<dyn Dialect> = 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),
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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<u64>),
|
||||
/// 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<SQLType>),
|
||||
Array(Box<DataType>),
|
||||
}
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <table_constraint>`
|
||||
AddConstraint(TableConstraint),
|
||||
/// TODO: implement `DROP CONSTRAINT <name>`
|
||||
DropConstraint { name: SQLIdent },
|
||||
DropConstraint { name: Ident },
|
||||
}
|
||||
|
||||
impl ToString for AlterTableOperation {
|
||||
|
@ -26,22 +26,22 @@ impl ToString for AlterTableOperation {
|
|||
pub enum TableConstraint {
|
||||
/// `[ CONSTRAINT <name> ] { PRIMARY KEY | UNIQUE } (<columns>)`
|
||||
Unique {
|
||||
name: Option<SQLIdent>,
|
||||
columns: Vec<SQLIdent>,
|
||||
name: Option<Ident>,
|
||||
columns: Vec<Ident>,
|
||||
/// Whether this is a `PRIMARY KEY` or just a `UNIQUE` constraint
|
||||
is_primary: bool,
|
||||
},
|
||||
/// A referential integrity constraint (`[ CONSTRAINT <name> ] FOREIGN KEY (<columns>)
|
||||
/// REFERENCES <foreign_table> (<referred_columns>)`)
|
||||
ForeignKey {
|
||||
name: Option<SQLIdent>,
|
||||
columns: Vec<SQLIdent>,
|
||||
foreign_table: SQLObjectName,
|
||||
referred_columns: Vec<SQLIdent>,
|
||||
name: Option<Ident>,
|
||||
columns: Vec<Ident>,
|
||||
foreign_table: ObjectName,
|
||||
referred_columns: Vec<Ident>,
|
||||
},
|
||||
/// `[ CONSTRAINT <name> ] CHECK (<expr>)`
|
||||
Check {
|
||||
name: Option<SQLIdent>,
|
||||
name: Option<Ident>,
|
||||
expr: Box<Expr>,
|
||||
},
|
||||
}
|
||||
|
@ -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<SQLObjectName>,
|
||||
pub struct ColumnDef {
|
||||
pub name: Ident,
|
||||
pub data_type: DataType,
|
||||
pub collation: Option<ObjectName>,
|
||||
pub options: Vec<ColumnOptionDef>,
|
||||
}
|
||||
|
||||
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<SQLIdent>,
|
||||
pub name: Option<Ident>,
|
||||
pub option: ColumnOption,
|
||||
}
|
||||
|
||||
|
@ -153,8 +153,8 @@ pub enum ColumnOption {
|
|||
/// A referential integrity constraint (`[FOREIGN KEY REFERENCES
|
||||
/// <foreign_table> (<referred_columns>)`).
|
||||
ForeignKey {
|
||||
foreign_table: SQLObjectName,
|
||||
referred_columns: Vec<SQLIdent>,
|
||||
foreign_table: ObjectName,
|
||||
referred_columns: Vec<Ident>,
|
||||
},
|
||||
// `CHECK (<expr>)`
|
||||
Check(Expr),
|
||||
|
@ -187,7 +187,7 @@ impl ToString for ColumnOption {
|
|||
}
|
||||
}
|
||||
|
||||
fn format_constraint_name(name: &Option<SQLIdent>) -> String {
|
||||
fn format_constraint_name(name: &Option<Ident>) -> String {
|
||||
name.as_ref()
|
||||
.map(|name| format!("CONSTRAINT {} ", name))
|
||||
.unwrap_or_default()
|
||||
|
|
276
src/ast/mod.rs
276
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<SQLIdent>),
|
||||
QualifiedWildcard(Vec<Ident>),
|
||||
/// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
|
||||
SQLCompoundIdentifier(Vec<SQLIdent>),
|
||||
CompoundIdentifier(Vec<Ident>),
|
||||
/// `IS NULL` expression
|
||||
SQLIsNull(Box<Expr>),
|
||||
IsNull(Box<Expr>),
|
||||
/// `IS NOT NULL` expression
|
||||
SQLIsNotNull(Box<Expr>),
|
||||
IsNotNull(Box<Expr>),
|
||||
/// `[ NOT ] IN (val1, val2, ...)`
|
||||
SQLInList {
|
||||
InList {
|
||||
expr: Box<Expr>,
|
||||
list: Vec<Expr>,
|
||||
negated: bool,
|
||||
},
|
||||
/// `[ NOT ] IN (SELECT ...)`
|
||||
SQLInSubquery {
|
||||
InSubquery {
|
||||
expr: Box<Expr>,
|
||||
subquery: Box<SQLQuery>,
|
||||
subquery: Box<Query>,
|
||||
negated: bool,
|
||||
},
|
||||
/// `<expr> [ NOT ] BETWEEN <low> AND <high>`
|
||||
SQLBetween {
|
||||
Between {
|
||||
expr: Box<Expr>,
|
||||
negated: bool,
|
||||
low: Box<Expr>,
|
||||
high: Box<Expr>,
|
||||
},
|
||||
/// Binary operation e.g. `1 + 1` or `foo > bar`
|
||||
SQLBinaryOp {
|
||||
BinaryOp {
|
||||
left: Box<Expr>,
|
||||
op: SQLBinaryOperator,
|
||||
op: BinaryOperator,
|
||||
right: Box<Expr>,
|
||||
},
|
||||
/// Unary operation e.g. `NOT foo`
|
||||
SQLUnaryOp {
|
||||
op: SQLUnaryOperator,
|
||||
expr: Box<Expr>,
|
||||
},
|
||||
UnaryOp { op: UnaryOperator, expr: Box<Expr> },
|
||||
/// CAST an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))`
|
||||
SQLCast { expr: Box<Expr>, data_type: SQLType },
|
||||
SQLExtract {
|
||||
Cast {
|
||||
expr: Box<Expr>,
|
||||
data_type: DataType,
|
||||
},
|
||||
Extract {
|
||||
field: SQLDateTimeField,
|
||||
expr: Box<Expr>,
|
||||
},
|
||||
/// `expr COLLATE collation`
|
||||
SQLCollate {
|
||||
Collate {
|
||||
expr: Box<Expr>,
|
||||
collation: SQLObjectName,
|
||||
collation: ObjectName,
|
||||
},
|
||||
/// Nested expression e.g. `(foo > bar)` or `(1)`
|
||||
SQLNested(Box<Expr>),
|
||||
Nested(Box<Expr>),
|
||||
/// SQLValue
|
||||
SQLValue(Value),
|
||||
Value(Value),
|
||||
/// Scalar function call e.g. `LEFT(foo, 5)`
|
||||
SQLFunction(SQLFunction),
|
||||
Function(Function),
|
||||
/// `CASE [<operand>] WHEN <condition> THEN <result> ... [ELSE <result>] END`
|
||||
///
|
||||
/// Note we only recognize a complete single expression as `<condition>`,
|
||||
/// not `< 0` nor `1, 2, 3` as allowed in a `<simple when clause>` per
|
||||
/// <https://jakewheat.github.io/sql-overview/sql-2011-foundation-grammar.html#simple-when-clause>
|
||||
SQLCase {
|
||||
Case {
|
||||
operand: Option<Box<Expr>>,
|
||||
conditions: Vec<Expr>,
|
||||
results: Vec<Expr>,
|
||||
|
@ -132,22 +132,22 @@ pub enum Expr {
|
|||
},
|
||||
/// An exists expression `EXISTS(SELECT ...)`, used in expressions like
|
||||
/// `WHERE EXISTS (SELECT ...)`.
|
||||
SQLExists(Box<SQLQuery>),
|
||||
Exists(Box<Query>),
|
||||
/// A parenthesized subquery `(SELECT ...)`, used in expression like
|
||||
/// `SELECT (subquery) AS x` or `WHERE (subquery) = x`
|
||||
SQLSubquery(Box<SQLQuery>),
|
||||
Subquery(Box<Query>),
|
||||
}
|
||||
|
||||
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<Expr>,
|
||||
pub order_by: Vec<SQLOrderByExpr>,
|
||||
pub window_frame: Option<SQLWindowFrame>,
|
||||
pub order_by: Vec<OrderByExpr>,
|
||||
pub window_frame: Option<WindowFrame>,
|
||||
}
|
||||
|
||||
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<SQLWindowFrameBound>,
|
||||
pub end_bound: Option<WindowFrameBound>,
|
||||
// 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<Self, Self::Err> {
|
||||
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,
|
||||
/// "<N> PRECEDING" or "UNBOUNDED PRECEDING"
|
||||
|
@ -329,14 +329,14 @@ pub enum SQLWindowFrameBound {
|
|||
Following(Option<u64>),
|
||||
}
|
||||
|
||||
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<SQLQuery>),
|
||||
Query(Box<Query>),
|
||||
/// INSERT
|
||||
SQLInsert {
|
||||
Insert {
|
||||
/// TABLE
|
||||
table_name: SQLObjectName,
|
||||
table_name: ObjectName,
|
||||
/// COLUMNS
|
||||
columns: Vec<SQLIdent>,
|
||||
columns: Vec<Ident>,
|
||||
/// A SQL query that specifies what to insert
|
||||
source: Box<SQLQuery>,
|
||||
source: Box<Query>,
|
||||
},
|
||||
SQLCopy {
|
||||
Copy {
|
||||
/// TABLE
|
||||
table_name: SQLObjectName,
|
||||
table_name: ObjectName,
|
||||
/// COLUMNS
|
||||
columns: Vec<SQLIdent>,
|
||||
columns: Vec<Ident>,
|
||||
/// VALUES a vector of values to be copied
|
||||
values: Vec<Option<String>>,
|
||||
},
|
||||
/// UPDATE
|
||||
SQLUpdate {
|
||||
Update {
|
||||
/// TABLE
|
||||
table_name: SQLObjectName,
|
||||
table_name: ObjectName,
|
||||
/// Column assignments
|
||||
assignments: Vec<SQLAssignment>,
|
||||
assignments: Vec<Assignment>,
|
||||
/// WHERE
|
||||
selection: Option<Expr>,
|
||||
},
|
||||
/// DELETE
|
||||
SQLDelete {
|
||||
Delete {
|
||||
/// FROM
|
||||
table_name: SQLObjectName,
|
||||
table_name: ObjectName,
|
||||
/// WHERE
|
||||
selection: Option<Expr>,
|
||||
},
|
||||
/// CREATE VIEW
|
||||
SQLCreateView {
|
||||
CreateView {
|
||||
/// View name
|
||||
name: SQLObjectName,
|
||||
columns: Vec<SQLIdent>,
|
||||
query: Box<SQLQuery>,
|
||||
name: ObjectName,
|
||||
columns: Vec<Ident>,
|
||||
query: Box<Query>,
|
||||
materialized: bool,
|
||||
with_options: Vec<SQLOption>,
|
||||
with_options: Vec<SqlOption>,
|
||||
},
|
||||
/// CREATE TABLE
|
||||
SQLCreateTable {
|
||||
CreateTable {
|
||||
/// Table name
|
||||
name: SQLObjectName,
|
||||
name: ObjectName,
|
||||
/// Optional schema
|
||||
columns: Vec<SQLColumnDef>,
|
||||
columns: Vec<ColumnDef>,
|
||||
constraints: Vec<TableConstraint>,
|
||||
with_options: Vec<SQLOption>,
|
||||
with_options: Vec<SqlOption>,
|
||||
external: bool,
|
||||
file_format: Option<FileFormat>,
|
||||
location: Option<String>,
|
||||
},
|
||||
/// 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<SQLObjectName>,
|
||||
names: Vec<ObjectName>,
|
||||
cascade: bool,
|
||||
},
|
||||
/// `{ BEGIN [ TRANSACTION | WORK ] | START TRANSACTION } ...`
|
||||
SQLStartTransaction { modes: Vec<TransactionMode> },
|
||||
StartTransaction { modes: Vec<TransactionMode> },
|
||||
/// `SET TRANSACTION ...`
|
||||
SQLSetTransaction { modes: Vec<TransactionMode> },
|
||||
SetTransaction { modes: Vec<TransactionMode> },
|
||||
/// `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<SQLIdent>);
|
||||
pub struct ObjectName(pub Vec<Ident>);
|
||||
|
||||
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<Expr>,
|
||||
pub over: Option<SQLWindowSpec>,
|
||||
pub over: Option<WindowSpec>,
|
||||
// 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())
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Cte>,
|
||||
/// SELECT or UNION / EXCEPT / INTECEPT
|
||||
pub body: SQLSetExpr,
|
||||
pub body: SetExpr,
|
||||
/// ORDER BY
|
||||
pub order_by: Vec<SQLOrderByExpr>,
|
||||
pub order_by: Vec<OrderByExpr>,
|
||||
/// `LIMIT { <N> | ALL }`
|
||||
pub limit: Option<Expr>,
|
||||
/// `OFFSET <N> { ROW | ROWS }`
|
||||
|
@ -30,7 +30,7 @@ pub struct SQLQuery {
|
|||
pub fetch: Option<Fetch>,
|
||||
}
|
||||
|
||||
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<SQLSelect>),
|
||||
Select(Box<Select>),
|
||||
/// Parenthesized SELECT subquery, which may include more set operations
|
||||
/// in its body and an optional ORDER BY / LIMIT.
|
||||
Query(Box<SQLQuery>),
|
||||
Query(Box<Query>),
|
||||
/// UNION/EXCEPT/INTERSECT of two queries
|
||||
SetOperation {
|
||||
op: SQLSetOperator,
|
||||
op: SetOperator,
|
||||
all: bool,
|
||||
left: Box<SQLSetExpr>,
|
||||
right: Box<SQLSetExpr>,
|
||||
left: Box<SetExpr>,
|
||||
right: Box<SetExpr>,
|
||||
},
|
||||
Values(SQLValues),
|
||||
Values(Values),
|
||||
// TODO: ANSI SQL supports `TABLE` here.
|
||||
}
|
||||
|
||||
impl ToString for SQLSetExpr {
|
||||
impl ToString for SetExpr {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
SQLSetExpr::Select(s) => s.to_string(),
|
||||
SQLSetExpr::Query(q) => format!("({})", q.to_string()),
|
||||
SQLSetExpr::Values(v) => v.to_string(),
|
||||
SQLSetExpr::SetOperation {
|
||||
SetExpr::Select(s) => s.to_string(),
|
||||
SetExpr::Query(q) => format!("({})", q.to_string()),
|
||||
SetExpr::Values(v) => v.to_string(),
|
||||
SetExpr::SetOperation {
|
||||
left,
|
||||
right,
|
||||
op,
|
||||
|
@ -100,18 +100,18 @@ impl ToString for SQLSetExpr {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub enum SQLSetOperator {
|
||||
pub enum SetOperator {
|
||||
Union,
|
||||
Except,
|
||||
Intersect,
|
||||
}
|
||||
|
||||
impl ToString for SQLSetOperator {
|
||||
impl ToString for SetOperator {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
SQLSetOperator::Union => "UNION".to_string(),
|
||||
SQLSetOperator::Except => "EXCEPT".to_string(),
|
||||
SQLSetOperator::Intersect => "INTERSECT".to_string(),
|
||||
SetOperator::Union => "UNION".to_string(),
|
||||
SetOperator::Except => "EXCEPT".to_string(),
|
||||
SetOperator::Intersect => "INTERSECT".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,10 +120,10 @@ impl ToString for SQLSetOperator {
|
|||
/// appear either as the only body item of an `SQLQuery`, or as an operand
|
||||
/// to a set operation like `UNION`.
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct SQLSelect {
|
||||
pub struct Select {
|
||||
pub distinct: bool,
|
||||
/// projection expressions
|
||||
pub projection: Vec<SQLSelectItem>,
|
||||
pub projection: Vec<SelectItem>,
|
||||
/// FROM
|
||||
pub from: Vec<TableWithJoins>,
|
||||
/// WHERE
|
||||
|
@ -134,7 +134,7 @@ pub struct SQLSelect {
|
|||
pub having: Option<Expr>,
|
||||
}
|
||||
|
||||
impl ToString for SQLSelect {
|
||||
impl ToString for Select {
|
||||
fn to_string(&self) -> String {
|
||||
let mut s = format!(
|
||||
"SELECT{} {}",
|
||||
|
@ -164,7 +164,7 @@ impl ToString for SQLSelect {
|
|||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct Cte {
|
||||
pub alias: TableAlias,
|
||||
pub query: SQLQuery,
|
||||
pub query: Query,
|
||||
}
|
||||
|
||||
impl ToString for Cte {
|
||||
|
@ -175,26 +175,26 @@ impl ToString for Cte {
|
|||
|
||||
/// One item of the comma-separated list following `SELECT`
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub enum SQLSelectItem {
|
||||
pub enum SelectItem {
|
||||
/// Any expression, not followed by `[ AS ] alias`
|
||||
UnnamedExpr(Expr),
|
||||
/// An expression, followed by `[ AS ] alias`
|
||||
ExprWithAlias { expr: Expr, alias: SQLIdent },
|
||||
ExprWithAlias { expr: Expr, alias: Ident },
|
||||
/// `alias.*` or even `schema.table.*`
|
||||
QualifiedWildcard(SQLObjectName),
|
||||
QualifiedWildcard(ObjectName),
|
||||
/// An unqualified `*`
|
||||
Wildcard,
|
||||
}
|
||||
|
||||
impl ToString for SQLSelectItem {
|
||||
impl ToString for SelectItem {
|
||||
fn to_string(&self) -> String {
|
||||
match &self {
|
||||
SQLSelectItem::UnnamedExpr(expr) => expr.to_string(),
|
||||
SQLSelectItem::ExprWithAlias { expr, alias } => {
|
||||
SelectItem::UnnamedExpr(expr) => expr.to_string(),
|
||||
SelectItem::ExprWithAlias { expr, alias } => {
|
||||
format!("{} AS {}", expr.to_string(), alias)
|
||||
}
|
||||
SQLSelectItem::QualifiedWildcard(prefix) => format!("{}.*", prefix.to_string()),
|
||||
SQLSelectItem::Wildcard => "*".to_string(),
|
||||
SelectItem::QualifiedWildcard(prefix) => format!("{}.*", prefix.to_string()),
|
||||
SelectItem::Wildcard => "*".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ impl ToString for TableWithJoins {
|
|||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub enum TableFactor {
|
||||
Table {
|
||||
name: SQLObjectName,
|
||||
name: ObjectName,
|
||||
alias: Option<TableAlias>,
|
||||
/// Arguments of a table-valued function, as supported by Postgres
|
||||
/// and MSSQL. Note that deprecated MSSQL `FROM foo (NOLOCK)` syntax
|
||||
|
@ -230,7 +230,7 @@ pub enum TableFactor {
|
|||
},
|
||||
Derived {
|
||||
lateral: bool,
|
||||
subquery: Box<SQLQuery>,
|
||||
subquery: Box<Query>,
|
||||
alias: Option<TableAlias>,
|
||||
},
|
||||
/// Represents a parenthesized join expression, such as
|
||||
|
@ -285,8 +285,8 @@ impl ToString for TableFactor {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct TableAlias {
|
||||
pub name: SQLIdent,
|
||||
pub columns: Vec<SQLIdent>,
|
||||
pub name: Ident,
|
||||
pub columns: Vec<Ident>,
|
||||
}
|
||||
|
||||
impl ToString for TableAlias {
|
||||
|
@ -368,18 +368,18 @@ pub enum JoinOperator {
|
|||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub enum JoinConstraint {
|
||||
On(Expr),
|
||||
Using(Vec<SQLIdent>),
|
||||
Using(Vec<Ident>),
|
||||
Natural,
|
||||
}
|
||||
|
||||
/// SQL ORDER BY expression
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct SQLOrderByExpr {
|
||||
pub struct OrderByExpr {
|
||||
pub expr: Expr,
|
||||
pub asc: Option<bool>,
|
||||
}
|
||||
|
||||
impl ToString for SQLOrderByExpr {
|
||||
impl ToString for OrderByExpr {
|
||||
fn to_string(&self) -> String {
|
||||
match self.asc {
|
||||
Some(true) => format!("{} ASC", self.expr.to_string()),
|
||||
|
@ -414,9 +414,9 @@ impl ToString for Fetch {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct SQLValues(pub Vec<Vec<Expr>>);
|
||||
pub struct Values(pub Vec<Vec<Expr>>);
|
||||
|
||||
impl ToString for SQLValues {
|
||||
impl ToString for Values {
|
||||
fn to_string(&self) -> String {
|
||||
let rows = self
|
||||
.0
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
use crate::dialect::Dialect;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AnsiSqlDialect {}
|
||||
pub struct AnsiDialect {}
|
||||
|
||||
impl Dialect for AnsiSqlDialect {
|
||||
impl Dialect for AnsiDialect {
|
||||
fn is_identifier_start(&self, ch: char) -> bool {
|
||||
(ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
use crate::dialect::Dialect;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GenericSqlDialect {}
|
||||
pub struct GenericDialect {}
|
||||
|
||||
impl Dialect for GenericSqlDialect {
|
||||
impl Dialect for GenericDialect {
|
||||
fn is_identifier_start(&self, ch: char) -> bool {
|
||||
(ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_' || ch == '#' || ch == '@'
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ mod postgresql;
|
|||
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub use self::ansi::AnsiSqlDialect;
|
||||
pub use self::generic::GenericSqlDialect;
|
||||
pub use self::ansi::AnsiDialect;
|
||||
pub use self::generic::GenericDialect;
|
||||
pub use self::mssql::MsSqlDialect;
|
||||
pub use self::postgresql::PostgreSqlDialect;
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
//! Syntax Tree (AST).
|
||||
//!
|
||||
//! ```
|
||||
//! use sqlparser::dialect::GenericSqlDialect;
|
||||
//! use sqlparser::dialect::GenericDialect;
|
||||
//! use sqlparser::parser::Parser;
|
||||
//!
|
||||
//! let dialect = GenericSqlDialect {}; // or AnsiSqlDialect
|
||||
//! let dialect = GenericDialect {}; // or AnsiSqlDialect
|
||||
//!
|
||||
//! let sql = "SELECT a, b, 123, myfunc(b) \
|
||||
//! FROM table_1 \
|
||||
|
|
384
src/parser.rs
384
src/parser.rs
File diff suppressed because it is too large
Load diff
|
@ -57,7 +57,7 @@ impl TestedDialects {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn parse_sql_statements(&self, sql: &str) -> Result<Vec<SQLStatement>, ParserError> {
|
||||
pub fn parse_sql_statements(&self, sql: &str) -> Result<Vec<Statement>, ParserError> {
|
||||
self.one_of_identical_results(|dialect| Parser::parse_sql(dialect, sql.to_string()))
|
||||
// To fail the `ensure_multiple_dialects_are_tested` test:
|
||||
// Parser::parse_sql(&**self.dialects.first().unwrap(), sql.to_string())
|
||||
|
@ -66,7 +66,7 @@ impl TestedDialects {
|
|||
/// Ensures that `sql` parses as a single statement, optionally checking
|
||||
/// that converting AST back to string equals to `canonical` (unless an
|
||||
/// empty canonical string is provided).
|
||||
pub fn one_statement_parses_to(&self, sql: &str, canonical: &str) -> SQLStatement {
|
||||
pub fn one_statement_parses_to(&self, sql: &str, canonical: &str) -> Statement {
|
||||
let mut statements = self.parse_sql_statements(&sql).unwrap();
|
||||
assert_eq!(statements.len(), 1);
|
||||
|
||||
|
@ -79,24 +79,24 @@ impl TestedDialects {
|
|||
|
||||
/// Ensures that `sql` parses as a single SQLStatement, and is not modified
|
||||
/// after a serialization round-trip.
|
||||
pub fn verified_stmt(&self, query: &str) -> SQLStatement {
|
||||
pub fn verified_stmt(&self, query: &str) -> Statement {
|
||||
self.one_statement_parses_to(query, query)
|
||||
}
|
||||
|
||||
/// Ensures that `sql` parses as a single SQLQuery, and is not modified
|
||||
/// after a serialization round-trip.
|
||||
pub fn verified_query(&self, sql: &str) -> SQLQuery {
|
||||
pub fn verified_query(&self, sql: &str) -> Query {
|
||||
match self.verified_stmt(sql) {
|
||||
SQLStatement::SQLQuery(query) => *query,
|
||||
Statement::Query(query) => *query,
|
||||
_ => panic!("Expected SQLQuery"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures that `sql` parses as a single SQLSelect, and is not modified
|
||||
/// after a serialization round-trip.
|
||||
pub fn verified_only_select(&self, query: &str) -> SQLSelect {
|
||||
pub fn verified_only_select(&self, query: &str) -> Select {
|
||||
match self.verified_query(query).body {
|
||||
SQLSetExpr::Select(s) => *s,
|
||||
SetExpr::Select(s) => *s,
|
||||
_ => panic!("Expected SQLSetExpr::Select"),
|
||||
}
|
||||
}
|
||||
|
@ -113,10 +113,10 @@ impl TestedDialects {
|
|||
pub fn all_dialects() -> TestedDialects {
|
||||
TestedDialects {
|
||||
dialects: vec![
|
||||
Box::new(GenericSqlDialect {}),
|
||||
Box::new(GenericDialect {}),
|
||||
Box::new(PostgreSqlDialect {}),
|
||||
Box::new(MsSqlDialect {}),
|
||||
Box::new(AnsiSqlDialect {}),
|
||||
Box::new(AnsiDialect {}),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -130,9 +130,9 @@ pub fn only<T>(v: impl IntoIterator<Item = T>) -> T {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expr_from_projection(item: &SQLSelectItem) -> &Expr {
|
||||
pub fn expr_from_projection(item: &SelectItem) -> &Expr {
|
||||
match item {
|
||||
SQLSelectItem::UnnamedExpr(expr) => expr,
|
||||
SelectItem::UnnamedExpr(expr) => expr,
|
||||
_ => panic!("Expected UnnamedExpr"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ use super::dialect::Dialect;
|
|||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Token {
|
||||
/// A keyword (like SELECT) or an optionally quoted SQL identifier
|
||||
SQLWord(SQLWord),
|
||||
Word(Word),
|
||||
/// An unsigned numeric literal
|
||||
Number(String),
|
||||
/// A character that could not be tokenized
|
||||
|
@ -92,7 +92,7 @@ pub enum Token {
|
|||
impl ToString for Token {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
Token::SQLWord(ref w) => w.to_string(),
|
||||
Token::Word(ref w) => w.to_string(),
|
||||
Token::Number(ref n) => n.to_string(),
|
||||
Token::Char(ref c) => c.to_string(),
|
||||
Token::SingleQuotedString(ref s) => format!("'{}'", s),
|
||||
|
@ -137,7 +137,7 @@ impl Token {
|
|||
// not fast but I want the simplicity for now while I experiment with pluggable
|
||||
// dialects
|
||||
let is_keyword = quote_style == None && ALL_KEYWORDS.contains(&word_uppercase.as_str());
|
||||
Token::SQLWord(SQLWord {
|
||||
Token::Word(Word {
|
||||
value: word.to_string(),
|
||||
quote_style,
|
||||
keyword: if is_keyword {
|
||||
|
@ -151,7 +151,7 @@ impl Token {
|
|||
|
||||
/// A keyword (like SELECT) or an optionally quoted SQL identifier
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct SQLWord {
|
||||
pub struct Word {
|
||||
/// The value of the token, without the enclosing quotes, and with the
|
||||
/// escape sequences (if any) processed (TODO: escapes are not handled)
|
||||
pub value: String,
|
||||
|
@ -164,18 +164,18 @@ pub struct SQLWord {
|
|||
pub keyword: String,
|
||||
}
|
||||
|
||||
impl ToString for SQLWord {
|
||||
impl ToString for Word {
|
||||
fn to_string(&self) -> String {
|
||||
match self.quote_style {
|
||||
Some(s) if s == '"' || s == '[' || s == '`' => {
|
||||
format!("{}{}{}", s, self.value, SQLWord::matching_end_quote(s))
|
||||
format!("{}{}{}", s, self.value, Word::matching_end_quote(s))
|
||||
}
|
||||
None => self.value.clone(),
|
||||
_ => panic!("Unexpected quote_style!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl SQLWord {
|
||||
impl Word {
|
||||
fn matching_end_quote(ch: char) -> char {
|
||||
match ch {
|
||||
'"' => '"', // ANSI and most dialects
|
||||
|
@ -244,8 +244,8 @@ impl<'a> Tokenizer<'a> {
|
|||
}
|
||||
|
||||
Token::Whitespace(Whitespace::Tab) => self.col += 4,
|
||||
Token::SQLWord(w) if w.quote_style == None => self.col += w.value.len() as u64,
|
||||
Token::SQLWord(w) if w.quote_style != None => self.col += w.value.len() as u64 + 2,
|
||||
Token::Word(w) if w.quote_style == None => self.col += w.value.len() as u64,
|
||||
Token::Word(w) if w.quote_style != None => self.col += w.value.len() as u64 + 2,
|
||||
Token::Number(s) => self.col += s.len() as u64,
|
||||
Token::SingleQuotedString(s) => self.col += s.len() as u64,
|
||||
_ => self.col += 1,
|
||||
|
@ -318,7 +318,7 @@ impl<'a> Tokenizer<'a> {
|
|||
// delimited (quoted) identifier
|
||||
quote_start if self.dialect.is_delimited_identifier_start(quote_start) => {
|
||||
chars.next(); // consume the opening quote
|
||||
let quote_end = SQLWord::matching_end_quote(quote_start);
|
||||
let quote_end = Word::matching_end_quote(quote_start);
|
||||
let s = peeking_take_while(chars, |ch| ch != quote_end);
|
||||
if chars.next() == Some(quote_end) {
|
||||
Ok(Some(Token::make_word(&s, Some(quote_start))))
|
||||
|
@ -520,13 +520,13 @@ fn peeking_take_while(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::super::dialect::GenericSqlDialect;
|
||||
use super::super::dialect::GenericDialect;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn tokenize_select_1() {
|
||||
let sql = String::from("SELECT 1");
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
|
||||
|
@ -542,7 +542,7 @@ mod tests {
|
|||
#[test]
|
||||
fn tokenize_scalar_function() {
|
||||
let sql = String::from("SELECT sqrt(1)");
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
|
||||
|
@ -561,7 +561,7 @@ mod tests {
|
|||
#[test]
|
||||
fn tokenize_simple_select() {
|
||||
let sql = String::from("SELECT * FROM customer WHERE id = 1 LIMIT 5");
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
|
||||
|
@ -593,7 +593,7 @@ mod tests {
|
|||
#[test]
|
||||
fn tokenize_string_predicate() {
|
||||
let sql = String::from("SELECT * FROM customer WHERE salary != 'Not Provided'");
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
|
||||
|
@ -622,7 +622,7 @@ mod tests {
|
|||
fn tokenize_invalid_string() {
|
||||
let sql = String::from("\nمصطفىh");
|
||||
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
println!("tokens: {:#?}", tokens);
|
||||
|
@ -642,7 +642,7 @@ mod tests {
|
|||
fn tokenize_invalid_string_cols() {
|
||||
let sql = String::from("\n\nSELECT * FROM table\tمصطفىh");
|
||||
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
println!("tokens: {:#?}", tokens);
|
||||
|
@ -670,7 +670,7 @@ mod tests {
|
|||
#[test]
|
||||
fn tokenize_is_null() {
|
||||
let sql = String::from("a IS NULL");
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
|
||||
|
@ -689,7 +689,7 @@ mod tests {
|
|||
fn tokenize_comment() {
|
||||
let sql = String::from("0--this is a comment\n1");
|
||||
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
let expected = vec![
|
||||
|
@ -706,7 +706,7 @@ mod tests {
|
|||
fn tokenize_comment_at_eof() {
|
||||
let sql = String::from("--this is a comment");
|
||||
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
let expected = vec![Token::Whitespace(Whitespace::SingleLineComment(
|
||||
|
@ -719,7 +719,7 @@ mod tests {
|
|||
fn tokenize_multiline_comment() {
|
||||
let sql = String::from("0/*multi-line\n* /comment*/1");
|
||||
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
let expected = vec![
|
||||
|
@ -736,7 +736,7 @@ mod tests {
|
|||
fn tokenize_multiline_comment_with_even_asterisks() {
|
||||
let sql = String::from("\n/** Comment **/\n");
|
||||
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
let expected = vec![
|
||||
|
@ -751,7 +751,7 @@ mod tests {
|
|||
fn tokenize_mismatched_quotes() {
|
||||
let sql = String::from("\"foo");
|
||||
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
assert_eq!(
|
||||
tokenizer.tokenize(),
|
||||
|
@ -765,7 +765,7 @@ mod tests {
|
|||
fn tokenize_newlines() {
|
||||
let sql = String::from("line1\nline2\rline3\r\nline4\r");
|
||||
|
||||
let dialect = GenericSqlDialect {};
|
||||
let dialect = GenericDialect {};
|
||||
let mut tokenizer = Tokenizer::new(&dialect, &sql);
|
||||
let tokens = tokenizer.tokenize().unwrap();
|
||||
let expected = vec![
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,7 +15,7 @@
|
|||
//! generic dialect is also tested (on the inputs it can handle).
|
||||
|
||||
use sqlparser::ast::*;
|
||||
use sqlparser::dialect::{GenericSqlDialect, MsSqlDialect};
|
||||
use sqlparser::dialect::{GenericDialect, MsSqlDialect};
|
||||
use sqlparser::test_utils::*;
|
||||
|
||||
#[test]
|
||||
|
@ -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!(
|
||||
&Expr::SQLIdentifier("@@version".to_string()),
|
||||
&Expr::Identifier("@@version".to_string()),
|
||||
expr_from_projection(&select.projection[0]),
|
||||
);
|
||||
assert_eq!(
|
||||
&Expr::SQLIdentifier("_foo$123".to_string()),
|
||||
&Expr::Identifier("_foo$123".to_string()),
|
||||
expr_from_projection(&select.projection[1]),
|
||||
);
|
||||
assert_eq!(2, select.projection.len());
|
||||
|
@ -75,6 +75,6 @@ fn ms() -> TestedDialects {
|
|||
}
|
||||
fn ms_and_generic() -> TestedDialects {
|
||||
TestedDialects {
|
||||
dialects: vec![Box::new(MsSqlDialect {}), Box::new(GenericSqlDialect {})],
|
||||
dialects: vec![Box::new(MsSqlDialect {}), Box::new(GenericDialect {})],
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
//! generic dialect is also tested (on the inputs it can handle).
|
||||
|
||||
use sqlparser::ast::*;
|
||||
use sqlparser::dialect::{GenericSqlDialect, PostgreSqlDialect};
|
||||
use sqlparser::dialect::{GenericDialect, PostgreSqlDialect};
|
||||
use sqlparser::test_utils::*;
|
||||
|
||||
#[test]
|
||||
|
@ -33,7 +33,7 @@ fn parse_create_table_with_defaults() {
|
|||
active integer NOT NULL
|
||||
) WITH (fillfactor = 20, user_catalog_table = true, autovacuum_vacuum_threshold = 100)";
|
||||
match pg_and_generic().one_statement_parses_to(sql, "") {
|
||||
SQLStatement::SQLCreateTable {
|
||||
Statement::CreateTable {
|
||||
name,
|
||||
columns,
|
||||
constraints,
|
||||
|
@ -46,9 +46,9 @@ fn parse_create_table_with_defaults() {
|
|||
assert_eq!(
|
||||
columns,
|
||||
vec![
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "customer_id".into(),
|
||||
data_type: SQLType::Int,
|
||||
data_type: DataType::Int,
|
||||
collation: None,
|
||||
options: vec![ColumnOptionDef {
|
||||
name: None,
|
||||
|
@ -57,56 +57,56 @@ fn parse_create_table_with_defaults() {
|
|||
)
|
||||
}],
|
||||
},
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "store_id".into(),
|
||||
data_type: SQLType::SmallInt,
|
||||
data_type: DataType::SmallInt,
|
||||
collation: None,
|
||||
options: vec![ColumnOptionDef {
|
||||
name: None,
|
||||
option: ColumnOption::NotNull,
|
||||
}],
|
||||
},
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "first_name".into(),
|
||||
data_type: SQLType::Varchar(Some(45)),
|
||||
data_type: DataType::Varchar(Some(45)),
|
||||
collation: None,
|
||||
options: vec![ColumnOptionDef {
|
||||
name: None,
|
||||
option: ColumnOption::NotNull,
|
||||
}],
|
||||
},
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "last_name".into(),
|
||||
data_type: SQLType::Varchar(Some(45)),
|
||||
collation: Some(SQLObjectName(vec!["\"es_ES\"".into()])),
|
||||
data_type: DataType::Varchar(Some(45)),
|
||||
collation: Some(ObjectName(vec!["\"es_ES\"".into()])),
|
||||
options: vec![ColumnOptionDef {
|
||||
name: None,
|
||||
option: ColumnOption::NotNull,
|
||||
}],
|
||||
},
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "email".into(),
|
||||
data_type: SQLType::Varchar(Some(50)),
|
||||
data_type: DataType::Varchar(Some(50)),
|
||||
collation: None,
|
||||
options: vec![],
|
||||
},
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "address_id".into(),
|
||||
data_type: SQLType::SmallInt,
|
||||
data_type: DataType::SmallInt,
|
||||
collation: None,
|
||||
options: vec![ColumnOptionDef {
|
||||
name: None,
|
||||
option: ColumnOption::NotNull
|
||||
}],
|
||||
},
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "activebool".into(),
|
||||
data_type: SQLType::Boolean,
|
||||
data_type: DataType::Boolean,
|
||||
collation: None,
|
||||
options: vec![
|
||||
ColumnOptionDef {
|
||||
name: None,
|
||||
option: ColumnOption::Default(Expr::SQLValue(Value::Boolean(true))),
|
||||
option: ColumnOption::Default(Expr::Value(Value::Boolean(true))),
|
||||
},
|
||||
ColumnOptionDef {
|
||||
name: None,
|
||||
|
@ -114,9 +114,9 @@ fn parse_create_table_with_defaults() {
|
|||
}
|
||||
],
|
||||
},
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "create_date".into(),
|
||||
data_type: SQLType::Date,
|
||||
data_type: DataType::Date,
|
||||
collation: None,
|
||||
options: vec![
|
||||
ColumnOptionDef {
|
||||
|
@ -131,9 +131,9 @@ fn parse_create_table_with_defaults() {
|
|||
}
|
||||
],
|
||||
},
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "last_update".into(),
|
||||
data_type: SQLType::Timestamp,
|
||||
data_type: DataType::Timestamp,
|
||||
collation: None,
|
||||
options: vec![
|
||||
ColumnOptionDef {
|
||||
|
@ -146,9 +146,9 @@ fn parse_create_table_with_defaults() {
|
|||
}
|
||||
],
|
||||
},
|
||||
SQLColumnDef {
|
||||
ColumnDef {
|
||||
name: "active".into(),
|
||||
data_type: SQLType::Int,
|
||||
data_type: DataType::Int,
|
||||
collation: None,
|
||||
options: vec![ColumnOptionDef {
|
||||
name: None,
|
||||
|
@ -161,15 +161,15 @@ fn parse_create_table_with_defaults() {
|
|||
assert_eq!(
|
||||
with_options,
|
||||
vec![
|
||||
SQLOption {
|
||||
SqlOption {
|
||||
name: "fillfactor".into(),
|
||||
value: Value::Long(20)
|
||||
},
|
||||
SQLOption {
|
||||
SqlOption {
|
||||
name: "user_catalog_table".into(),
|
||||
value: Value::Boolean(true)
|
||||
},
|
||||
SQLOption {
|
||||
SqlOption {
|
||||
name: "autovacuum_vacuum_threshold".into(),
|
||||
value: Value::Long(100)
|
||||
},
|
||||
|
@ -259,9 +259,6 @@ fn pg() -> TestedDialects {
|
|||
|
||||
fn pg_and_generic() -> TestedDialects {
|
||||
TestedDialects {
|
||||
dialects: vec![
|
||||
Box::new(PostgreSqlDialect {}),
|
||||
Box::new(GenericSqlDialect {}),
|
||||
],
|
||||
dialects: vec![Box::new(PostgreSqlDialect {}), Box::new(GenericDialect {})],
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue