From 9335c346d923d1439243e59e95eabde51e539fb4 Mon Sep 17 00:00:00 2001 From: Taehoon Moon Date: Fri, 5 Jun 2020 18:05:56 +0900 Subject: [PATCH 1/2] Add serde support to AST structs and enums Apply serde to AST structs and enums to be serializable/deserializable. serde support is optional, can be activated by feature named "serde". --- Cargo.toml | 1 + src/ast/data_type.rs | 3 +++ src/ast/ddl.rs | 8 ++++++++ src/ast/mod.rs | 22 ++++++++++++++++++++++ src/ast/operator.rs | 4 ++++ src/ast/query.rs | 20 ++++++++++++++++++++ src/ast/value.rs | 4 ++++ 7 files changed, 62 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 895f07f6a..c2587ec2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ path = "src/lib.rs" [dependencies] bigdecimal = { version = "0.1.0", optional = true } log = "0.4.5" +serde = { version = "1.0", features = ["derive"], optional = true } [dev-dependencies] simple_logger = "1.0.1" diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index cfbc2147d..fc8b98c55 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -11,10 +11,13 @@ // limitations under the License. use super::ObjectName; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use std::fmt; /// SQL data types #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum DataType { /// Fixed-length character type e.g. CHAR(10) Char(Option), diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 776927669..d7503ba77 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -13,10 +13,13 @@ //! AST types specific to CREATE/ALTER variants of [Statement] //! (commonly referred to as Data Definition Language, or DDL) use super::{display_comma_separated, DataType, Expr, Ident, ObjectName}; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use std::fmt; /// An `ALTER TABLE` (`Statement::AlterTable`) operation #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum AlterTableOperation { /// `ADD ` AddConstraint(TableConstraint), @@ -36,6 +39,7 @@ impl fmt::Display for AlterTableOperation { /// A table-level constraint, specified in a `CREATE TABLE` or an /// `ALTER TABLE ADD ` statement. #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TableConstraint { /// `[ CONSTRAINT ] { PRIMARY KEY | UNIQUE } ()` Unique { @@ -95,6 +99,7 @@ impl fmt::Display for TableConstraint { /// SQL column definition #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ColumnDef { pub name: Ident, pub data_type: DataType, @@ -129,6 +134,7 @@ impl fmt::Display for ColumnDef { /// non-constraint options, lumping them all together under the umbrella of /// "column options," and we allow any column option to be named. #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ColumnOptionDef { pub name: Option, pub option: ColumnOption, @@ -143,6 +149,7 @@ impl fmt::Display for ColumnOptionDef { /// `ColumnOption`s are modifiers that follow a column definition in a `CREATE /// TABLE` statement. #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum ColumnOption { /// `NULL` Null, @@ -220,6 +227,7 @@ fn display_constraint_name<'a>(name: &'a Option) -> impl fmt::Display + ' /// /// Used in foreign key constraints in `ON UPDATE` and `ON DELETE` options. #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum ReferentialAction { Restrict, Cascade, diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 2dbf42b29..c04fb0269 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -18,6 +18,8 @@ mod operator; mod query; mod value; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use std::fmt; pub use self::data_type::DataType; @@ -71,6 +73,7 @@ where /// An identifier, decomposed into its value or character data and the quote style. #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Ident { /// The value of the identifier without quotes. pub value: String, @@ -127,6 +130,7 @@ impl fmt::Display for Ident { /// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ObjectName(pub Vec); impl fmt::Display for ObjectName { @@ -141,6 +145,7 @@ impl fmt::Display for ObjectName { /// (e.g. boolean vs string), so the caller must handle expressions of /// inappropriate type, like `WHERE 1` or `SELECT 1=1`, as necessary. #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Expr { /// Identifier e.g. table name or column name Identifier(Ident), @@ -308,6 +313,7 @@ impl fmt::Display for Expr { /// A window specification (i.e. `OVER (PARTITION BY .. ORDER BY .. etc.)`) #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct WindowSpec { pub partition_by: Vec, pub order_by: Vec, @@ -353,6 +359,7 @@ impl fmt::Display for WindowSpec { /// Note: The parser does not validate the specified bounds; the caller should /// reject invalid bounds like `ROWS UNBOUNDED FOLLOWING` before execution. #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct WindowFrame { pub units: WindowFrameUnits, pub start_bound: WindowFrameBound, @@ -364,6 +371,7 @@ pub struct WindowFrame { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum WindowFrameUnits { Rows, Range, @@ -398,6 +406,7 @@ impl FromStr for WindowFrameUnits { /// Specifies [WindowFrame]'s `start_bound` and `end_bound` #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum WindowFrameBound { /// `CURRENT ROW` CurrentRow, @@ -422,6 +431,7 @@ impl fmt::Display for WindowFrameBound { /// A top-level statement (SELECT, INSERT, CREATE, etc.) #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Statement { /// SELECT Query(Box), @@ -766,6 +776,7 @@ impl fmt::Display for Statement { /// SQL assignment `foo = expr` as used in SQLUpdate #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Assignment { pub id: Ident, pub value: Expr, @@ -779,6 +790,7 @@ impl fmt::Display for Assignment { /// A function call #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Function { pub name: ObjectName, pub args: Vec, @@ -805,6 +817,7 @@ impl fmt::Display for Function { /// External table's available file format #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum FileFormat { TEXTFILE, SEQUENCEFILE, @@ -856,6 +869,7 @@ impl FromStr for FileFormat { /// A `LISTAGG` invocation `LISTAGG( [ DISTINCT ] [, ] [ON OVERFLOW ] ) ) /// [ WITHIN GROUP (ORDER BY [, ...] ) ]` #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ListAgg { pub distinct: bool, pub expr: Box, @@ -892,6 +906,7 @@ impl fmt::Display for ListAgg { /// The `ON OVERFLOW` clause of a LISTAGG invocation #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum ListAggOnOverflow { /// `ON OVERFLOW ERROR` Error, @@ -925,6 +940,7 @@ impl fmt::Display for ListAggOnOverflow { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum ObjectType { Table, View, @@ -944,6 +960,7 @@ impl fmt::Display for ObjectType { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct SqlOption { pub name: Ident, pub value: Value, @@ -956,6 +973,7 @@ impl fmt::Display for SqlOption { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TransactionMode { AccessMode(TransactionAccessMode), IsolationLevel(TransactionIsolationLevel), @@ -972,6 +990,7 @@ impl fmt::Display for TransactionMode { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TransactionAccessMode { ReadOnly, ReadWrite, @@ -988,6 +1007,7 @@ impl fmt::Display for TransactionAccessMode { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TransactionIsolationLevel { ReadUncommitted, ReadCommitted, @@ -1008,6 +1028,7 @@ impl fmt::Display for TransactionIsolationLevel { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum ShowStatementFilter { Like(String), Where(Expr), @@ -1024,6 +1045,7 @@ impl fmt::Display for ShowStatementFilter { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum SetVariableValue { Ident(Ident), Literal(Value), diff --git a/src/ast/operator.rs b/src/ast/operator.rs index c9f5eb2e9..63e75eead 100644 --- a/src/ast/operator.rs +++ b/src/ast/operator.rs @@ -10,10 +10,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; use std::fmt; /// Unary operators #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum UnaryOperator { Plus, Minus, @@ -32,6 +35,7 @@ impl fmt::Display for UnaryOperator { /// Binary operators #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum BinaryOperator { Plus, Minus, diff --git a/src/ast/query.rs b/src/ast/query.rs index a5918f1a3..73477b126 100644 --- a/src/ast/query.rs +++ b/src/ast/query.rs @@ -11,10 +11,13 @@ // limitations under the License. use super::*; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; /// The most complete variant of a `SELECT` query expression, optionally /// including `WITH`, `UNION` / other set operations, and `ORDER BY`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Query { /// WITH (common table expressions, or CTEs) pub ctes: Vec, @@ -55,6 +58,7 @@ impl fmt::Display for Query { /// A node in a tree, representing a "query body" expression, roughly: /// `SELECT ... [ {UNION|EXCEPT|INTERSECT} SELECT ...]` #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum SetExpr { /// Restricted SELECT .. FROM .. HAVING (no ORDER BY or set operations) Select(Box