diff --git a/Cargo.toml b/Cargo.toml index f7e08b494..922fc92b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ version = "0.27.0" authors = ["Andy Grove "] homepage = "https://github.com/sqlparser-rs/sqlparser-rs" documentation = "https://docs.rs/sqlparser/" -keywords = [ "ansi", "sql", "lexer", "parser" ] +keywords = ["ansi", "sql", "lexer", "parser"] repository = "https://github.com/sqlparser-rs/sqlparser-rs" license = "Apache-2.0" include = [ @@ -32,6 +32,7 @@ serde = { version = "1.0", features = ["derive"], optional = true } # of dev-dependencies because of # https://github.com/rust-lang/cargo/issues/1596 serde_json = { version = "1.0", optional = true } +derive-visitor = { version = "0.3.0", optional = true } [dev-dependencies] simple_logger = "4.0" diff --git a/README.md b/README.md index 6e9f6290d..618d49264 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,25 @@ This outputs AST: [Query(Query { ctes: [], body: Select(Select { distinct: false, projection: [UnnamedExpr(Identifier("a")), UnnamedExpr(Identifier("b")), UnnamedExpr(Value(Long(123))), UnnamedExpr(Function(Function { name: ObjectName(["myfunc"]), args: [Identifier("b")], over: None, distinct: false }))], from: [TableWithJoins { relation: Table { name: ObjectName(["table_1"]), alias: None, args: [], with_hints: [] }, joins: [] }], selection: Some(BinaryOp { left: BinaryOp { left: Identifier("a"), op: Gt, right: Identifier("b") }, op: And, right: BinaryOp { left: Identifier("b"), op: Lt, right: Value(Long(100)) } }), group_by: [], having: None }), order_by: [OrderByExpr { expr: Identifier("a"), asc: Some(false) }, OrderByExpr { expr: Identifier("b"), asc: None }], limit: None, offset: None, fetch: None })] ``` +### Analyzing and transforming the AST + +Once you have an abstract syntax tree, you can analyze and transform it +using the optional [`derive-visitor`](https://github.com/nikis05/derive-visitor) feature. + +For instance, if you want to rename all identifiers in a query: + +```rust +use sqlparser::{dialect::GenericDialect, parser::Parser, ast::Ident}; + use derive_visitor::{visitor_enter_fn_mut, DriveMut}; + +let mut statements = Parser::parse_sql(&GenericDialect, "select xxx").unwrap(); +statements[0].drive_mut(&mut visitor_enter_fn_mut(|ident: &mut Ident| { + ident.value = ident.value.replace("xxx", "yyy"); +})); +assert_eq!(statements[0].to_string(), "SELECT yyy"); +``` + + ## Command line To parse a file and dump the results as JSON: ``` diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index 12a95a4fc..4aa090e66 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -17,6 +17,9 @@ use core::fmt; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +#[cfg(feature = "derive-visitor")] +use derive_visitor::{Drive, DriveMut}; + use crate::ast::ObjectName; use super::value::escape_single_quote_string; @@ -24,6 +27,7 @@ use super::value::escape_single_quote_string; /// SQL data types #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum DataType { /// Fixed-length character type e.g. CHARACTER(10) Character(Option), @@ -36,37 +40,37 @@ pub enum DataType { /// Variable-length character type e.g. VARCHAR(10) Varchar(Option), /// Variable-length character type e.g. NVARCHAR(10) - Nvarchar(Option), + Nvarchar(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Uuid type Uuid, /// Large character object with optional length e.g. CHARACTER LARGE OBJECT, CHARACTER LARGE OBJECT(1000), [standard] /// /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type - CharacterLargeObject(Option), + CharacterLargeObject(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Large character object with optional length e.g. CHAR LARGE OBJECT, CHAR LARGE OBJECT(1000), [standard] /// /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type - CharLargeObject(Option), + CharLargeObject(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Large character object with optional length e.g. CLOB, CLOB(1000), [standard] /// /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type /// [Oracle]: https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html - Clob(Option), + Clob(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Fixed-length binary type with optional length e.g. [standard], [MS SQL Server] /// /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type /// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16 - Binary(Option), + Binary(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Variable-length binary with optional length type e.g. [standard], [MS SQL Server] /// /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type /// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16 - Varbinary(Option), + Varbinary(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Large binary object with optional length e.g. BLOB, BLOB(1000), [standard], [Oracle] /// /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-large-object-string-type /// [Oracle]: https://docs.oracle.com/javadb/10.8.3.0/ref/rrefblob.html - Blob(Option), + Blob(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Numeric type with optional precision and scale e.g. NUMERIC(10,2), [standard][1] /// /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type @@ -80,35 +84,35 @@ pub enum DataType { /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type Dec(ExactNumberInfo), /// Floating point with optional precision e.g. FLOAT(8) - Float(Option), + Float(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Tiny integer with optional display width e.g. TINYINT or TINYINT(3) - TinyInt(Option), + TinyInt(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Unsigned tiny integer with optional display width e.g. TINYINT UNSIGNED or TINYINT(3) UNSIGNED - UnsignedTinyInt(Option), + UnsignedTinyInt(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Small integer with optional display width e.g. SMALLINT or SMALLINT(5) - SmallInt(Option), + SmallInt(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Unsigned small integer with optional display width e.g. SMALLINT UNSIGNED or SMALLINT(5) UNSIGNED - UnsignedSmallInt(Option), + UnsignedSmallInt(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// MySQL medium integer ([1]) with optional display width e.g. MEDIUMINT or MEDIUMINT(5) /// /// [1]: https://dev.mysql.com/doc/refman/8.0/en/integer-types.html - MediumInt(Option), + MediumInt(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Unsigned medium integer ([1]) with optional display width e.g. MEDIUMINT UNSIGNED or MEDIUMINT(5) UNSIGNED /// /// [1]: https://dev.mysql.com/doc/refman/8.0/en/integer-types.html - UnsignedMediumInt(Option), + UnsignedMediumInt(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Integer with optional display width e.g. INT or INT(11) - Int(Option), + Int(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Integer with optional display width e.g. INTEGER or INTEGER(11) - Integer(Option), + Integer(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Unsigned integer with optional display width e.g. INT UNSIGNED or INT(11) UNSIGNED - UnsignedInt(Option), + UnsignedInt(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Unsigned integer with optional display width e.g. INTGER UNSIGNED or INTEGER(11) UNSIGNED - UnsignedInteger(Option), + UnsignedInteger(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Big integer with optional display width e.g. BIGINT or BIGINT(20) - BigInt(Option), + BigInt(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Unsigned big integer with optional display width e.g. BIGINT UNSIGNED or BIGINT(20) UNSIGNED - UnsignedBigInt(Option), + UnsignedBigInt(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Floating point e.g. REAL Real, /// Double @@ -125,15 +129,21 @@ pub enum DataType { /// Time with optional time precision and time zone information e.g. [standard][1]. /// /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type - Time(Option, TimezoneInfo), + Time( + #[cfg_attr(feature = "derive-visitor", drive(skip))] Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] TimezoneInfo, + ), /// Datetime with optional time precision e.g. [MySQL][1]. /// /// [1]: https://dev.mysql.com/doc/refman/8.0/en/datetime.html - Datetime(Option), + Datetime(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option), /// Timestamp with optional time precision and time zone information e.g. [standard][1]. /// /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type - Timestamp(Option, TimezoneInfo), + Timestamp( + #[cfg_attr(feature = "derive-visitor", drive(skip))] Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] TimezoneInfo, + ), /// Interval Interval, /// Regclass used in postgresql serial @@ -145,13 +155,16 @@ pub enum DataType { /// Bytea Bytea, /// Custom type such as enums - Custom(ObjectName, Vec), + Custom( + ObjectName, + #[cfg_attr(feature = "derive-visitor", drive(skip))] Vec, + ), /// Arrays Array(Option>), /// Enums - Enum(Vec), + Enum(#[cfg_attr(feature = "derive-visitor", drive(skip))] Vec), /// Set - Set(Vec), + Set(#[cfg_attr(feature = "derive-visitor", drive(skip))] Vec), } impl fmt::Display for DataType { @@ -384,13 +397,17 @@ impl fmt::Display for TimezoneInfo { /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum ExactNumberInfo { /// No additional information e.g. `DECIMAL` None, /// Only precision information e.g. `DECIMAL(10)` - Precision(u64), + Precision(#[cfg_attr(feature = "derive-visitor", drive(skip))] u64), /// Precision and scale information e.g. `DECIMAL(10,2)` - PrecisionAndScale(u64, u64), + PrecisionAndScale( + #[cfg_attr(feature = "derive-visitor", drive(skip))] u64, + #[cfg_attr(feature = "derive-visitor", drive(skip))] u64, + ), } impl fmt::Display for ExactNumberInfo { @@ -414,8 +431,10 @@ impl fmt::Display for ExactNumberInfo { /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-length #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct CharacterLength { /// Default (if VARYING) or maximum (if not VARYING) length + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub length: u64, /// Optional unit. If not informed, the ANSI handles it as CHARACTERS implicitly pub unit: Option, @@ -436,6 +455,7 @@ impl fmt::Display for CharacterLength { /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#char-length-units #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum CharLengthUnits { /// CHARACTERS unit Characters, diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 3203f0e20..1dcec27c3 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -20,6 +20,9 @@ use core::fmt; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +#[cfg(feature = "derive-visitor")] +use derive_visitor::{Drive, DriveMut}; + use crate::ast::value::escape_single_quote_string; use crate::ast::{display_comma_separated, display_separated, DataType, Expr, Ident, ObjectName}; use crate::tokenizer::Token; @@ -27,6 +30,7 @@ use crate::tokenizer::Token; /// An `ALTER TABLE` (`Statement::AlterTable`) operation #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum AlterTableOperation { /// `ADD ` AddConstraint(TableConstraint), @@ -34,14 +38,18 @@ pub enum AlterTableOperation { AddColumn { column_def: ColumnDef }, /// `DROP CONSTRAINT [ IF EXISTS ] ` DropConstraint { + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_exists: bool, name: Ident, + #[cfg_attr(feature = "derive-visitor", drive(skip))] cascade: bool, }, /// `DROP [ COLUMN ] [ IF EXISTS ] [ CASCADE ]` DropColumn { column_name: Ident, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_exists: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] cascade: bool, }, /// `DROP PRIMARY KEY` @@ -55,11 +63,13 @@ pub enum AlterTableOperation { }, /// Add Partitions AddPartitions { + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_not_exists: bool, new_partitions: Vec, }, DropPartitions { partitions: Vec, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_exists: bool, }, /// `RENAME [ COLUMN ] TO ` @@ -183,6 +193,7 @@ impl fmt::Display for AlterTableOperation { /// An `ALTER COLUMN` (`Statement::AlterTable`) operation #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum AlterColumnOperation { /// `SET NOT NULL` SetNotNull, @@ -226,12 +237,14 @@ impl fmt::Display for AlterColumnOperation { /// `ALTER TABLE ADD ` statement. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum TableConstraint { /// `[ CONSTRAINT ] { PRIMARY KEY | UNIQUE } ()` Unique { name: Option, columns: Vec, /// Whether this is a `PRIMARY KEY` or just a `UNIQUE` constraint + #[cfg_attr(feature = "derive-visitor", drive(skip))] is_primary: bool, }, /// A referential integrity constraint (`[ CONSTRAINT ] FOREIGN KEY () @@ -260,6 +273,7 @@ pub enum TableConstraint { /// [1]: https://dev.mysql.com/doc/refman/8.0/en/create-table.html Index { /// Whether this index starts with KEY (true) or INDEX (false), to maintain the same syntax. + #[cfg_attr(feature = "derive-visitor", drive(skip))] display_as_key: bool, /// Index name. name: Option, @@ -284,6 +298,7 @@ pub enum TableConstraint { /// [1]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-natural-language.html FulltextOrSpatial { /// Whether this is a `FULLTEXT` (true) or `SPATIAL` (false) definition. + #[cfg_attr(feature = "derive-visitor", drive(skip))] fulltext: bool, /// Whether the type is followed by the keyword `KEY`, `INDEX`, or no keyword at all. index_type_display: KeyOrIndexDisplay, @@ -389,6 +404,7 @@ impl fmt::Display for TableConstraint { /// [1]: https://dev.mysql.com/doc/refman/8.0/en/create-table.html #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum KeyOrIndexDisplay { /// Nothing to display None, @@ -424,6 +440,7 @@ impl fmt::Display for KeyOrIndexDisplay { /// [3]: https://www.postgresql.org/docs/14/sql-createindex.html #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum IndexType { BTree, Hash, @@ -442,6 +459,7 @@ impl fmt::Display for IndexType { /// SQL column definition #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct ColumnDef { pub name: Ident, pub data_type: DataType, @@ -477,6 +495,7 @@ impl fmt::Display for ColumnDef { /// "column options," and we allow any column option to be named. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct ColumnOptionDef { pub name: Option, pub option: ColumnOption, @@ -492,6 +511,7 @@ impl fmt::Display for ColumnOptionDef { /// TABLE` statement. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum ColumnOption { /// `NULL` Null, @@ -501,6 +521,7 @@ pub enum ColumnOption { Default(Expr), /// `{ PRIMARY KEY | UNIQUE }` Unique { + #[cfg_attr(feature = "derive-visitor", drive(skip))] is_primary: bool, }, /// A referential integrity constraint (`[FOREIGN KEY REFERENCES @@ -521,7 +542,7 @@ pub enum ColumnOption { /// - ... DialectSpecific(Vec), CharacterSet(ObjectName), - Comment(String), + Comment(#[cfg_attr(feature = "derive-visitor", drive(skip))] String), } impl fmt::Display for ColumnOption { @@ -579,6 +600,7 @@ fn display_constraint_name(name: &'_ 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))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum ReferentialAction { Restrict, Cascade, diff --git a/src/ast/mod.rs b/src/ast/mod.rs index f568c3960..5627ce712 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -35,7 +35,13 @@ pub use self::query::{ OrderByExpr, Query, Select, SelectInto, SelectItem, SetExpr, SetOperator, SetQuantifier, TableAlias, TableFactor, TableWithJoins, Top, Values, With, }; + pub use self::value::{escape_quoted_string, DateTimeField, TrimWhereField, Value}; +#[cfg(feature = "derive-visitor")] +pub use derive_visitor::{ + visitor_enter_fn, visitor_enter_fn_mut, visitor_fn, visitor_fn_mut, Drive, DriveMut, + Event as VisitorEvent, Visitor, VisitorMut, +}; mod data_type; mod ddl; @@ -84,11 +90,14 @@ 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))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct Ident { /// The value of the identifier without quotes. + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub value: String, /// The starting quote if any. Valid quote characters are the single quote, /// double quote, backtick, and opening square bracket. + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub quote_style: Option, } @@ -144,6 +153,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))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct ObjectName(pub Vec); impl fmt::Display for ObjectName { @@ -154,6 +164,7 @@ impl fmt::Display for ObjectName { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] /// Represents an Array Expression, either /// `ARRAY[..]`, or `[..]` pub struct Array { @@ -161,6 +172,7 @@ pub struct Array { pub elem: Vec, /// `true` for `ARRAY[..]`, `false` for `[..]` + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub named: bool, } @@ -178,6 +190,7 @@ impl fmt::Display for Array { /// JsonOperator #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum JsonOperator { /// -> keeps the value as json Arrow, @@ -220,6 +233,7 @@ impl fmt::Display for JsonOperator { /// inappropriate type, like `WHERE 1` or `SELECT 1=1`, as necessary. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum Expr { /// Identifier e.g. table name or column name Identifier(Ident), @@ -257,23 +271,27 @@ pub enum Expr { InList { expr: Box, list: Vec, + #[cfg_attr(feature = "derive-visitor", drive(skip))] negated: bool, }, /// `[ NOT ] IN (SELECT ...)` InSubquery { expr: Box, subquery: Box, + #[cfg_attr(feature = "derive-visitor", drive(skip))] negated: bool, }, /// `[ NOT ] IN UNNEST(array_expression)` InUnnest { expr: Box, array_expr: Box, + #[cfg_attr(feature = "derive-visitor", drive(skip))] negated: bool, }, /// ` [ NOT ] BETWEEN AND ` Between { expr: Box, + #[cfg_attr(feature = "derive-visitor", drive(skip))] negated: bool, low: Box, high: Box, @@ -286,23 +304,29 @@ pub enum Expr { }, /// LIKE Like { + #[cfg_attr(feature = "derive-visitor", drive(skip))] negated: bool, expr: Box, pattern: Box, + #[cfg_attr(feature = "derive-visitor", drive(skip))] escape_char: Option, }, /// ILIKE (case-insensitive LIKE) ILike { + #[cfg_attr(feature = "derive-visitor", drive(skip))] negated: bool, expr: Box, pattern: Box, + #[cfg_attr(feature = "derive-visitor", drive(skip))] escape_char: Option, }, /// SIMILAR TO regex SimilarTo { + #[cfg_attr(feature = "derive-visitor", drive(skip))] negated: bool, expr: Box, pattern: Box, + #[cfg_attr(feature = "derive-visitor", drive(skip))] escape_char: Option, }, /// Any operation e.g. `1 ANY (1)` or `foo > ANY(bar)`, It will be wrapped in the right side of BinaryExpr @@ -332,6 +356,7 @@ pub enum Expr { /// AT a timestamp to a different timezone e.g. `FROM_UNIXTIME(0) AT TIME ZONE 'UTC-06:00'` AtTimeZone { timestamp: Box, + #[cfg_attr(feature = "derive-visitor", drive(skip))] time_zone: String, }, /// EXTRACT(DateTimeField FROM ) @@ -385,7 +410,11 @@ pub enum Expr { /// A constant of form ` 'value'`. /// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`), /// as well as constants of other types (a non-standard PostgreSQL extension). - TypedString { data_type: DataType, value: String }, + TypedString { + data_type: DataType, + #[cfg_attr(feature = "derive-visitor", drive(skip))] + value: String, + }, /// Access a map-like object by field (e.g. `column['field']` or `column[4]` /// Note that depending on the dialect, struct like accesses may be /// parsed as [`ArrayIndex`] or [`MapAccess`] @@ -408,7 +437,11 @@ pub enum Expr { }, /// An exists expression `[ NOT ] EXISTS(SELECT ...)`, used in expressions like /// `WHERE [ NOT ] EXISTS (SELECT ...)`. - Exists { subquery: Box, negated: bool }, + Exists { + subquery: Box, + #[cfg_attr(feature = "derive-visitor", drive(skip))] + negated: bool, + }, /// A parenthesized subquery `(SELECT ...)`, used in expression like /// `SELECT (subquery) AS x` or `WHERE (subquery) = x` Subquery(Box), @@ -441,12 +474,14 @@ pub enum Expr { Interval { value: Box, leading_field: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] leading_precision: Option, last_field: Option, /// The seconds precision can be specified in SQL source as /// `INTERVAL '__' SECOND(_, x)` (in which case the `leading_field` /// will be `Second` and the `last_field` will be `None`), /// or as `__ TO SECOND(x)`. + #[cfg_attr(feature = "derive-visitor", drive(skip))] fractional_seconds_precision: Option, }, } @@ -825,6 +860,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))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct WindowSpec { pub partition_by: Vec, pub order_by: Vec, @@ -870,6 +906,7 @@ impl fmt::Display for WindowSpec { /// reject invalid bounds like `ROWS UNBOUNDED FOLLOWING` before execution. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct WindowFrame { pub units: WindowFrameUnits, pub start_bound: WindowFrameBound, @@ -895,6 +932,7 @@ impl Default for WindowFrame { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum WindowFrameUnits { Rows, Range, @@ -914,6 +952,7 @@ impl fmt::Display for WindowFrameUnits { /// Specifies [WindowFrame]'s `start_bound` and `end_bound` #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum WindowFrameBound { /// `CURRENT ROW` CurrentRow, @@ -937,6 +976,7 @@ impl fmt::Display for WindowFrameBound { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum AddDropSync { ADD, DROP, @@ -955,6 +995,7 @@ impl fmt::Display for AddDropSync { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum ShowCreateObject { Event, Function, @@ -979,6 +1020,7 @@ impl fmt::Display for ShowCreateObject { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum CommentObject { Column, Table, @@ -995,6 +1037,7 @@ impl fmt::Display for CommentObject { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum Password { Password(Expr), NullPassword, @@ -1004,15 +1047,20 @@ pub enum Password { #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum Statement { /// Analyze (Hive) Analyze { table_name: ObjectName, partitions: Option>, + #[cfg_attr(feature = "derive-visitor", drive(skip))] for_columns: bool, columns: Vec, + #[cfg_attr(feature = "derive-visitor", drive(skip))] cache_metadata: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] noscan: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] compute_statistics: bool, }, /// Truncate (Hive) @@ -1023,6 +1071,7 @@ pub enum Statement { /// Msck (Hive) Msck { table_name: ObjectName, + #[cfg_attr(feature = "derive-visitor", drive(skip))] repair: bool, partition_action: Option, }, @@ -1033,12 +1082,14 @@ pub enum Statement { /// Only for Sqlite or: Option, /// INTO - optional keyword + #[cfg_attr(feature = "derive-visitor", drive(skip))] into: bool, /// TABLE table_name: ObjectName, /// COLUMNS columns: Vec, /// Overwrite (Hive) + #[cfg_attr(feature = "derive-visitor", drive(skip))] overwrite: bool, /// A SQL query that specifies what to insert source: Box, @@ -1047,6 +1098,7 @@ pub enum Statement { /// Columns defined after PARTITION after_columns: Vec, /// whether the insert has the table keyword (Hive) + #[cfg_attr(feature = "derive-visitor", drive(skip))] table: bool, on: Option, /// RETURNING @@ -1054,8 +1106,11 @@ pub enum Statement { }, // TODO: Support ROW FORMAT Directory { + #[cfg_attr(feature = "derive-visitor", drive(skip))] overwrite: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] local: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] path: String, file_format: Option, source: Box, @@ -1066,6 +1121,7 @@ pub enum Statement { /// COLUMNS columns: Vec, /// If true, is a 'COPY TO' statement. If false is a 'COPY FROM' + #[cfg_attr(feature = "derive-visitor", drive(skip))] to: bool, /// The source of 'COPY FROM', or the target of 'COPY TO' target: CopyTarget, @@ -1074,6 +1130,7 @@ pub enum Statement { /// WITH options (before PostgreSQL version 9.0) legacy_options: Vec, /// VALUES a vector of values to be copied + #[cfg_attr(feature = "derive-visitor", drive(skip))] values: Vec>, }, /// Close - closes the portal underlying an open cursor. @@ -1107,7 +1164,9 @@ pub enum Statement { }, /// CREATE VIEW CreateView { + #[cfg_attr(feature = "derive-visitor", drive(skip))] or_replace: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] materialized: bool, /// View name name: ObjectName, @@ -1117,10 +1176,15 @@ pub enum Statement { }, /// CREATE TABLE CreateTable { + #[cfg_attr(feature = "derive-visitor", drive(skip))] or_replace: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] temporary: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] external: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] global: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_not_exists: bool, /// Table name name: ObjectName, @@ -1132,22 +1196,30 @@ pub enum Statement { table_properties: Vec, with_options: Vec, file_format: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] location: Option, query: Option>, + #[cfg_attr(feature = "derive-visitor", drive(skip))] without_rowid: bool, like: Option, clone: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] engine: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] default_charset: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] collation: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] on_commit: Option, /// Click house "ON CLUSTER" clause: /// + #[cfg_attr(feature = "derive-visitor", drive(skip))] on_cluster: Option, }, /// SQLite's `CREATE VIRTUAL TABLE .. USING ()` CreateVirtualTable { name: ObjectName, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_not_exists: bool, module_name: Ident, module_args: Vec, @@ -1158,22 +1230,32 @@ pub enum Statement { name: ObjectName, table_name: ObjectName, columns: Vec, + #[cfg_attr(feature = "derive-visitor", drive(skip))] unique: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_not_exists: bool, }, /// CREATE ROLE /// See [postgres](https://www.postgresql.org/docs/current/sql-createrole.html) CreateRole { names: Vec, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_not_exists: bool, // Postgres + #[cfg_attr(feature = "derive-visitor", drive(skip))] login: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] inherit: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] bypassrls: Option, password: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] superuser: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] create_db: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] create_role: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] replication: Option, connection_limit: Option, valid_until: Option, @@ -1196,17 +1278,21 @@ pub enum Statement { /// The type of the object to drop: TABLE, VIEW, etc. object_type: ObjectType, /// An optional `IF EXISTS` clause. (Non-standard.) + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_exists: bool, /// One or more objects to drop. (ANSI SQL requires exactly one.) names: Vec, /// Whether `CASCADE` was specified. This will be `false` when /// `RESTRICT` or no drop behavior at all was specified. + #[cfg_attr(feature = "derive-visitor", drive(skip))] cascade: bool, /// Whether `RESTRICT` was specified. This will be `false` when /// `CASCADE` or no drop behavior at all was specified. + #[cfg_attr(feature = "derive-visitor", drive(skip))] restrict: bool, /// Hive allows you specify whether the table's stored data will be /// deleted along with the dropped table + #[cfg_attr(feature = "derive-visitor", drive(skip))] purge: bool, }, /// DECLARE - Declaring Cursor Variables @@ -1217,18 +1303,22 @@ pub enum Statement { /// Cursor name name: Ident, /// Causes the cursor to return data in binary rather than in text format. + #[cfg_attr(feature = "derive-visitor", drive(skip))] binary: bool, /// None = Not specified /// Some(true) = INSENSITIVE /// Some(false) = ASENSITIVE + #[cfg_attr(feature = "derive-visitor", drive(skip))] sensitive: Option, /// None = Not specified /// Some(true) = SCROLL /// Some(false) = NO SCROLL + #[cfg_attr(feature = "derive-visitor", drive(skip))] scroll: Option, /// None = Not specified /// Some(true) = WITH HOLD, specifies that the cursor can continue to be used after the transaction that created it successfully commits /// Some(false) = WITHOUT HOLD, specifies that the cursor cannot be used outside of the transaction that created it + #[cfg_attr(feature = "derive-visitor", drive(skip))] hold: Option, query: Box, }, @@ -1266,7 +1356,9 @@ pub enum Statement { /// least MySQL and PostgreSQL. Not all MySQL-specific syntatic forms are /// supported yet. SetVariable { + #[cfg_attr(feature = "derive-visitor", drive(skip))] local: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] hivevar: bool, variable: ObjectName, value: Vec, @@ -1275,7 +1367,9 @@ pub enum Statement { /// /// Note: this is a MySQL-specific statement. SetNames { + #[cfg_attr(feature = "derive-visitor", drive(skip))] charset_name: String, + #[cfg_attr(feature = "derive-visitor", drive(skip))] collation_name: Option, }, /// SET NAMES DEFAULT @@ -1305,7 +1399,9 @@ pub enum Statement { /// /// Note: this is a MySQL-specific statement. ShowColumns { + #[cfg_attr(feature = "derive-visitor", drive(skip))] extended: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] full: bool, table_name: ObjectName, filter: Option, @@ -1314,7 +1410,9 @@ pub enum Statement { /// /// Note: this is a MySQL-specific statement. ShowTables { + #[cfg_attr(feature = "derive-visitor", drive(skip))] extended: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] full: bool, db_name: Option, filter: Option, @@ -1333,6 +1431,7 @@ pub enum Statement { SetTransaction { modes: Vec, snapshot: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] session: bool, }, /// `COMMENT ON ...` @@ -1341,31 +1440,44 @@ pub enum Statement { Comment { object_type: CommentObject, object_name: ObjectName, + #[cfg_attr(feature = "derive-visitor", drive(skip))] comment: Option, }, /// `COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]` - Commit { chain: bool }, + Commit { + #[cfg_attr(feature = "derive-visitor", drive(skip))] + chain: bool, + }, /// `ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]` - Rollback { chain: bool }, + Rollback { + #[cfg_attr(feature = "derive-visitor", drive(skip))] + chain: bool, + }, /// CREATE SCHEMA CreateSchema { /// ` | AUTHORIZATION | AUTHORIZATION ` schema_name: SchemaName, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_not_exists: bool, }, /// CREATE DATABASE CreateDatabase { db_name: ObjectName, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_not_exists: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] location: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] managed_location: Option, }, /// CREATE FUNCTION /// /// Hive: https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction CreateFunction { + #[cfg_attr(feature = "derive-visitor", drive(skip))] temporary: bool, name: ObjectName, + #[cfg_attr(feature = "derive-visitor", drive(skip))] class_name: String, using: Option, }, @@ -1379,6 +1491,7 @@ pub enum Statement { privileges: Privileges, objects: GrantObjects, grantees: Vec, + #[cfg_attr(feature = "derive-visitor", drive(skip))] with_grant_option: bool, granted_by: Option, }, @@ -1388,12 +1501,17 @@ pub enum Statement { objects: GrantObjects, grantees: Vec, granted_by: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] cascade: bool, }, /// `DEALLOCATE [ PREPARE ] { name | ALL }` /// /// Note: this is a PostgreSQL-specific statement. - Deallocate { name: Ident, prepare: bool }, + Deallocate { + name: Ident, + #[cfg_attr(feature = "derive-visitor", drive(skip))] + prepare: bool, + }, /// `EXECUTE name [ ( parameter [, ...] ) ]` /// /// Note: this is a PostgreSQL-specific statement. @@ -1413,12 +1531,14 @@ pub enum Statement { Kill { modifier: Option, // processlist_id + #[cfg_attr(feature = "derive-visitor", drive(skip))] id: u64, }, /// EXPLAIN TABLE /// Note: this is a MySQL-specific statement. See ExplainTable { // If true, query used the MySQL `DESCRIBE` alias for explain + #[cfg_attr(feature = "derive-visitor", drive(skip))] describe_alias: bool, // Table name table_name: ObjectName, @@ -1426,10 +1546,13 @@ pub enum Statement { /// EXPLAIN / DESCRIBE for select_statement Explain { // If true, query used the MySQL `DESCRIBE` alias for explain + #[cfg_attr(feature = "derive-visitor", drive(skip))] describe_alias: bool, /// Carry out the command and show actual run times and other statistics. + #[cfg_attr(feature = "derive-visitor", drive(skip))] analyze: bool, // Display additional information regarding the plan. + #[cfg_attr(feature = "derive-visitor", drive(skip))] verbose: bool, /// A SQL query that specifies what to explain statement: Box, @@ -1441,6 +1564,7 @@ pub enum Statement { // MERGE INTO statement, based on Snowflake. See Merge { // optional INTO keyword + #[cfg_attr(feature = "derive-visitor", drive(skip))] into: bool, // Specifies the table to merge table: TableFactor, @@ -1458,6 +1582,7 @@ pub enum Statement { table_flag: Option, // Table name table_name: ObjectName, + #[cfg_attr(feature = "derive-visitor", drive(skip))] has_as: bool, // Table confs options: Vec, @@ -1468,12 +1593,15 @@ pub enum Statement { UNCache { // Table name table_name: ObjectName, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_exists: bool, }, ///CreateSequence -- define a new sequence /// CREATE [ { TEMPORARY | TEMP } ] SEQUENCE [ IF NOT EXISTS ] CreateSequence { + #[cfg_attr(feature = "derive-visitor", drive(skip))] temporary: bool, + #[cfg_attr(feature = "derive-visitor", drive(skip))] if_not_exists: bool, name: ObjectName, data_type: Option, @@ -2546,17 +2674,24 @@ impl fmt::Display for Statement { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] /// Can use to describe options in create sequence or table column type identity /// [ INCREMENT [ BY ] increment ] /// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] /// [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ] pub enum SequenceOptions { - IncrementBy(Expr, bool), + IncrementBy( + Expr, + #[cfg_attr(feature = "derive-visitor", drive(skip))] bool, + ), MinValue(MinMaxValue), MaxValue(MinMaxValue), - StartWith(Expr, bool), + StartWith( + Expr, + #[cfg_attr(feature = "derive-visitor", drive(skip))] bool, + ), Cache(Expr), - Cycle(bool), + Cycle(#[cfg_attr(feature = "derive-visitor", drive(skip))] bool), } impl fmt::Display for SequenceOptions { @@ -2612,6 +2747,7 @@ impl fmt::Display for SequenceOptions { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] /// Can use to describe options in create sequence or table column type identity /// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] pub enum MinMaxValue { @@ -2625,6 +2761,7 @@ pub enum MinMaxValue { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] #[non_exhaustive] pub enum OnInsert { /// ON DUPLICATE KEY UPDATE (MySQL when the key already exists, then execute an update instead) @@ -2635,12 +2772,14 @@ pub enum OnInsert { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct OnConflict { pub conflict_target: Vec, pub action: OnConflictAction, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum OnConflictAction { DoNothing, DoUpdate(Vec), @@ -2679,10 +2818,12 @@ impl fmt::Display for OnConflictAction { /// Privileges granted in a GRANT statement or revoked in a REVOKE statement. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum Privileges { /// All privileges applicable to the object type All { /// Optional keyword from the spec, ignored in practice + #[cfg_attr(feature = "derive-visitor", drive(skip))] with_privileges_keyword: bool, }, /// Specific privileges (e.g. `SELECT`, `INSERT`) @@ -2715,6 +2856,7 @@ impl fmt::Display for Privileges { /// Specific direction for FETCH statement #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum FetchDirection { Count { limit: Value }, Next, @@ -2778,6 +2920,7 @@ impl fmt::Display for FetchDirection { /// A privilege on a database object (table, sequence, etc.). #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum Action { Connect, Create, @@ -2827,6 +2970,7 @@ impl fmt::Display for Action { /// Objects on which privileges are granted in a GRANT statement. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum GrantObjects { /// Grant privileges on `ALL SEQUENCES IN SCHEMA [, ...]` AllSequencesInSchema { schemas: Vec }, @@ -2873,6 +3017,7 @@ impl fmt::Display for GrantObjects { /// SQL assignment `foo = expr` as used in SQLUpdate #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct Assignment { pub id: Vec, pub value: Expr, @@ -2886,6 +3031,7 @@ impl fmt::Display for Assignment { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum FunctionArgExpr { Expr(Expr), /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`. @@ -2906,6 +3052,7 @@ impl fmt::Display for FunctionArgExpr { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum FunctionArg { Named { name: Ident, arg: FunctionArgExpr }, Unnamed(FunctionArgExpr), @@ -2922,6 +3069,7 @@ impl fmt::Display for FunctionArg { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum CloseCursor { All, Specific { name: Ident }, @@ -2939,19 +3087,23 @@ impl fmt::Display for CloseCursor { /// A function call #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct Function { pub name: ObjectName, pub args: Vec, pub over: Option, // aggregate functions may specify eg `COUNT(DISTINCT x)` + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub distinct: bool, // Some functions must be called without trailing parentheses, for example Postgres // do it for current_catalog, current_schema, etc. This flags is used for formatting. + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub special: bool, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum AnalyzeFormat { TEXT, GRAPHVIZ, @@ -2993,6 +3145,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))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum FileFormat { TEXTFILE, SEQUENCEFILE, @@ -3022,7 +3175,9 @@ impl fmt::Display for FileFormat { /// [ WITHIN GROUP (ORDER BY [, ...] ) ]` #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct ListAgg { + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub distinct: bool, pub expr: Box, pub separator: Option>, @@ -3059,6 +3214,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))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum ListAggOnOverflow { /// `ON OVERFLOW ERROR` Error, @@ -3066,6 +3222,7 @@ pub enum ListAggOnOverflow { /// `ON OVERFLOW TRUNCATE [ ] WITH[OUT] COUNT` Truncate { filler: Option>, + #[cfg_attr(feature = "derive-visitor", drive(skip))] with_count: bool, }, } @@ -3096,11 +3253,14 @@ impl fmt::Display for ListAggOnOverflow { /// ORDER BY position is defined differently for BigQuery, Postgres and Snowflake. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct ArrayAgg { + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub distinct: bool, pub expr: Box, pub order_by: Option>, pub limit: Option>, + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub within_group: bool, // order by is used inside a within group or not } @@ -3132,6 +3292,7 @@ impl fmt::Display for ArrayAgg { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum ObjectType { Table, View, @@ -3156,6 +3317,7 @@ impl fmt::Display for ObjectType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum KillType { Connection, Query, @@ -3176,6 +3338,7 @@ impl fmt::Display for KillType { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum HiveDistributionStyle { PARTITIONED { columns: Vec, @@ -3183,11 +3346,13 @@ pub enum HiveDistributionStyle { CLUSTERED { columns: Vec, sorted_by: Vec, + #[cfg_attr(feature = "derive-visitor", drive(skip))] num_buckets: i32, }, SKEWED { columns: Vec, on: Vec, + #[cfg_attr(feature = "derive-visitor", drive(skip))] stored_as_directories: bool, }, NONE, @@ -3195,14 +3360,19 @@ pub enum HiveDistributionStyle { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum HiveRowFormat { - SERDE { class: String }, + SERDE { + #[cfg_attr(feature = "derive-visitor", drive(skip))] + class: String, + }, DELIMITED, } #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] #[allow(clippy::large_enum_variant)] pub enum HiveIOFormat { IOF { @@ -3216,14 +3386,17 @@ pub enum HiveIOFormat { #[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct HiveFormat { pub row_format: Option, pub storage: Option, + #[cfg_attr(feature = "derive-visitor", drive(skip))] pub location: Option, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct SqlOption { pub name: Ident, pub value: Value, @@ -3237,6 +3410,7 @@ impl fmt::Display for SqlOption { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum TransactionMode { AccessMode(TransactionAccessMode), IsolationLevel(TransactionIsolationLevel), @@ -3254,6 +3428,7 @@ impl fmt::Display for TransactionMode { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum TransactionAccessMode { ReadOnly, ReadWrite, @@ -3271,6 +3446,7 @@ impl fmt::Display for TransactionAccessMode { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum TransactionIsolationLevel { ReadUncommitted, ReadCommitted, @@ -3292,9 +3468,10 @@ impl fmt::Display for TransactionIsolationLevel { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum ShowStatementFilter { - Like(String), - ILike(String), + Like(#[cfg_attr(feature = "derive-visitor", drive(skip))] String), + ILike(#[cfg_attr(feature = "derive-visitor", drive(skip))] String), Where(Expr), } @@ -3314,6 +3491,7 @@ impl fmt::Display for ShowStatementFilter { /// https://sqlite.org/lang_conflict.html #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum SqliteOnConflict { Rollback, Abort, @@ -3337,15 +3515,18 @@ impl fmt::Display for SqliteOnConflict { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum CopyTarget { Stdin, Stdout, File { /// The path name of the input or output file. + #[cfg_attr(feature = "derive-visitor", drive(skip))] filename: String, }, Program { /// A command to execute + #[cfg_attr(feature = "derive-visitor", drive(skip))] command: String, }, } @@ -3368,6 +3549,7 @@ impl fmt::Display for CopyTarget { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum OnCommit { DeleteRows, PreserveRows, @@ -3379,21 +3561,22 @@ pub enum OnCommit { /// #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum CopyOption { /// FORMAT format_name Format(Ident), /// FREEZE \[ boolean \] - Freeze(bool), + Freeze(#[cfg_attr(feature = "derive-visitor", drive(skip))] bool), /// DELIMITER 'delimiter_character' - Delimiter(char), + Delimiter(#[cfg_attr(feature = "derive-visitor", drive(skip))] char), /// NULL 'null_string' - Null(String), + Null(#[cfg_attr(feature = "derive-visitor", drive(skip))] String), /// HEADER \[ boolean \] - Header(bool), + Header(#[cfg_attr(feature = "derive-visitor", drive(skip))] bool), /// QUOTE 'quote_character' - Quote(char), + Quote(#[cfg_attr(feature = "derive-visitor", drive(skip))] char), /// ESCAPE 'escape_character' - Escape(char), + Escape(#[cfg_attr(feature = "derive-visitor", drive(skip))] char), /// FORCE_QUOTE { ( column_name [, ...] ) | * } ForceQuote(Vec), /// FORCE_NOT_NULL ( column_name [, ...] ) @@ -3401,7 +3584,7 @@ pub enum CopyOption { /// FORCE_NULL ( column_name [, ...] ) ForceNull(Vec), /// ENCODING 'encoding_name' - Encoding(String), + Encoding(#[cfg_attr(feature = "derive-visitor", drive(skip))] String), } impl fmt::Display for CopyOption { @@ -3432,13 +3615,14 @@ impl fmt::Display for CopyOption { /// #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum CopyLegacyOption { /// BINARY Binary, /// DELIMITER \[ AS \] 'delimiter_character' - Delimiter(char), + Delimiter(#[cfg_attr(feature = "derive-visitor", drive(skip))] char), /// NULL \[ AS \] 'null_string' - Null(String), + Null(#[cfg_attr(feature = "derive-visitor", drive(skip))] String), /// CSV ... Csv(Vec), } @@ -3460,13 +3644,14 @@ impl fmt::Display for CopyLegacyOption { /// #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum CopyLegacyCsvOption { /// HEADER Header, /// QUOTE \[ AS \] 'quote_character' - Quote(char), + Quote(#[cfg_attr(feature = "derive-visitor", drive(skip))] char), /// ESCAPE \[ AS \] 'escape_character' - Escape(char), + Escape(#[cfg_attr(feature = "derive-visitor", drive(skip))] char), /// FORCE QUOTE { column_name [, ...] | * } ForceQuote(Vec), /// FORCE NOT NULL column_name [, ...] @@ -3491,6 +3676,7 @@ impl fmt::Display for CopyLegacyCsvOption { /// #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum MergeClause { MatchedUpdate { predicate: Option, @@ -3552,6 +3738,7 @@ impl fmt::Display for MergeClause { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum DiscardObject { ALL, PLANS, @@ -3573,6 +3760,7 @@ impl fmt::Display for DiscardObject { /// Optional context modifier for statements that can be or `LOCAL`, or `SESSION`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum ContextModifier { /// No context defined. Each dialect defines the default in this scenario. None, @@ -3600,10 +3788,11 @@ impl fmt::Display for ContextModifier { #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum CreateFunctionUsing { - Jar(String), - File(String), - Archive(String), + Jar(#[cfg_attr(feature = "derive-visitor", drive(skip))] String), + File(#[cfg_attr(feature = "derive-visitor", drive(skip))] String), + Archive(#[cfg_attr(feature = "derive-visitor", drive(skip))] String), } impl fmt::Display for CreateFunctionUsing { @@ -3622,6 +3811,7 @@ impl fmt::Display for CreateFunctionUsing { /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum SchemaName { /// Only schema name specified: ``. Simple(ObjectName), diff --git a/src/ast/operator.rs b/src/ast/operator.rs index 1c96ebbcb..5505f74b9 100644 --- a/src/ast/operator.rs +++ b/src/ast/operator.rs @@ -17,11 +17,15 @@ use alloc::{string::String, vec::Vec}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +#[cfg(feature = "derive-visitor")] +use derive_visitor::{Drive, DriveMut}; + use super::display_separated; /// Unary operators #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum UnaryOperator { Plus, Minus, @@ -59,6 +63,7 @@ impl fmt::Display for UnaryOperator { /// Binary operators #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum BinaryOperator { Plus, Minus, @@ -90,7 +95,7 @@ pub enum BinaryOperator { /// /// See [CREATE OPERATOR](https://www.postgresql.org/docs/current/sql-createoperator.html) /// for more information. - PGCustomBinaryOperator(Vec), + PGCustomBinaryOperator(#[cfg_attr(feature = "derive-visitor", drive(skip))] Vec), } impl fmt::Display for BinaryOperator { diff --git a/src/ast/query.rs b/src/ast/query.rs index 4f3d79cdf..fe6d57ff0 100644 --- a/src/ast/query.rs +++ b/src/ast/query.rs @@ -16,12 +16,16 @@ use alloc::{boxed::Box, vec::Vec}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +#[cfg(feature = "derive-visitor")] +use derive_visitor::{Drive, DriveMut}; + use crate::ast::*; /// 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))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub struct Query { /// WITH (common table expressions, or CTEs) pub with: Option, @@ -69,6 +73,7 @@ impl fmt::Display for Query { #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))] pub enum SetExpr { /// Restricted SELECT .. FROM .. HAVING (no ORDER BY or set operations) Select(Box