mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-09 21:42:05 +00:00
Add derive based AST visitor (#765)
* Add derive based AST visitor * Fix BigDecimal * Fix no visitor feature * Add test * Rename visit_table to visit_relation * Review feedback * Add pre and post visit Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
parent
3e990466f8
commit
dec3c2b818
16 changed files with 771 additions and 11 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
||||||
# will have compiled files and executables
|
# will have compiled files and executables
|
||||||
/target/
|
/target/
|
||||||
/sqlparser_bench/target/
|
/sqlparser_bench/target/
|
||||||
|
/derive/target/
|
||||||
|
|
||||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||||
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
|
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
|
||||||
|
|
|
@ -5,7 +5,7 @@ version = "0.28.0"
|
||||||
authors = ["Andy Grove <andygrove73@gmail.com>"]
|
authors = ["Andy Grove <andygrove73@gmail.com>"]
|
||||||
homepage = "https://github.com/sqlparser-rs/sqlparser-rs"
|
homepage = "https://github.com/sqlparser-rs/sqlparser-rs"
|
||||||
documentation = "https://docs.rs/sqlparser/"
|
documentation = "https://docs.rs/sqlparser/"
|
||||||
keywords = [ "ansi", "sql", "lexer", "parser" ]
|
keywords = ["ansi", "sql", "lexer", "parser"]
|
||||||
repository = "https://github.com/sqlparser-rs/sqlparser-rs"
|
repository = "https://github.com/sqlparser-rs/sqlparser-rs"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
include = [
|
include = [
|
||||||
|
@ -23,6 +23,7 @@ default = ["std"]
|
||||||
std = []
|
std = []
|
||||||
# Enable JSON output in the `cli` example:
|
# Enable JSON output in the `cli` example:
|
||||||
json_example = ["serde_json", "serde"]
|
json_example = ["serde_json", "serde"]
|
||||||
|
visitor = ["sqlparser_derive"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bigdecimal = { version = "0.3", features = ["serde"], optional = true }
|
bigdecimal = { version = "0.3", features = ["serde"], optional = true }
|
||||||
|
@ -32,6 +33,7 @@ serde = { version = "1.0", features = ["derive"], optional = true }
|
||||||
# of dev-dependencies because of
|
# of dev-dependencies because of
|
||||||
# https://github.com/rust-lang/cargo/issues/1596
|
# https://github.com/rust-lang/cargo/issues/1596
|
||||||
serde_json = { version = "1.0", optional = true }
|
serde_json = { version = "1.0", optional = true }
|
||||||
|
sqlparser_derive = { version = "0.1", path = "derive", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
simple_logger = "4.0"
|
simple_logger = "4.0"
|
||||||
|
|
23
derive/Cargo.toml
Normal file
23
derive/Cargo.toml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
[package]
|
||||||
|
name = "sqlparser_derive"
|
||||||
|
description = "proc macro for sqlparser"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Andy Grove <andygrove73@gmail.com>"]
|
||||||
|
homepage = "https://github.com/sqlparser-rs/sqlparser-rs"
|
||||||
|
documentation = "https://docs.rs/sqlparser/"
|
||||||
|
keywords = ["ansi", "sql", "lexer", "parser"]
|
||||||
|
repository = "https://github.com/sqlparser-rs/sqlparser-rs"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
include = [
|
||||||
|
"src/**/*.rs",
|
||||||
|
"Cargo.toml",
|
||||||
|
]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syn = "1.0"
|
||||||
|
proc-macro2 = "1.0"
|
||||||
|
quote = "1.0"
|
79
derive/README.md
Normal file
79
derive/README.md
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# SQL Parser Derive Macro
|
||||||
|
|
||||||
|
## Visit
|
||||||
|
|
||||||
|
This crate contains a procedural macro that can automatically derive implementations of the `Visit` trait
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[derive(Visit)]
|
||||||
|
struct Foo {
|
||||||
|
boolean: bool,
|
||||||
|
bar: Bar,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Visit)]
|
||||||
|
enum Bar {
|
||||||
|
A(),
|
||||||
|
B(String, bool),
|
||||||
|
C { named: i32 },
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Will generate code akin to
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl Visit for Foo {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
self.boolean.visit(visitor)?;
|
||||||
|
self.bar.visit(visitor)?;
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visit for Bar {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
match self {
|
||||||
|
Self::A() => {}
|
||||||
|
Self::B(_1, _2) => {
|
||||||
|
_1.visit(visitor)?;
|
||||||
|
_2.visit(visitor)?;
|
||||||
|
}
|
||||||
|
Self::C { named } => {
|
||||||
|
named.visit(visitor)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally certain types may wish to call a corresponding method on visitor before recursing
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[derive(Visit)]
|
||||||
|
#[visit(with = "visit_expr")]
|
||||||
|
enum Expr {
|
||||||
|
A(),
|
||||||
|
B(String, #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] ObjectName, bool),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Will generate
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl Visit for Bar {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
visitor.visit_expr(self)?;
|
||||||
|
match self {
|
||||||
|
Self::A() => {}
|
||||||
|
Self::B(_1, _2, _3) => {
|
||||||
|
_1.visit(visitor)?;
|
||||||
|
visitor.visit_relation(_3)?;
|
||||||
|
_2.visit(visitor)?;
|
||||||
|
_3.visit(visitor)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
184
derive/src/lib.rs
Normal file
184
derive/src/lib.rs
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::{format_ident, quote, quote_spanned, ToTokens};
|
||||||
|
use syn::spanned::Spanned;
|
||||||
|
use syn::{
|
||||||
|
parse_macro_input, parse_quote, Attribute, Data, DeriveInput, Fields, GenericParam, Generics,
|
||||||
|
Ident, Index, Lit, Meta, MetaNameValue, NestedMeta,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Implementation of `[#derive(Visit)]`
|
||||||
|
#[proc_macro_derive(Visit, attributes(visit))]
|
||||||
|
pub fn derive_visit(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
|
// Parse the input tokens into a syntax tree.
|
||||||
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
|
let name = input.ident;
|
||||||
|
|
||||||
|
let attributes = Attributes::parse(&input.attrs);
|
||||||
|
// Add a bound `T: HeapSize` to every type parameter T.
|
||||||
|
let generics = add_trait_bounds(input.generics);
|
||||||
|
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
|
let (pre_visit, post_visit) = attributes.visit(quote!(self));
|
||||||
|
let children = visit_children(&input.data);
|
||||||
|
|
||||||
|
let expanded = quote! {
|
||||||
|
// The generated impl.
|
||||||
|
impl #impl_generics sqlparser::ast::Visit for #name #ty_generics #where_clause {
|
||||||
|
fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V) -> ::std::ops::ControlFlow<V::Break> {
|
||||||
|
#pre_visit
|
||||||
|
#children
|
||||||
|
#post_visit
|
||||||
|
::std::ops::ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
proc_macro::TokenStream::from(expanded)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parses attributes that can be provided to this macro
|
||||||
|
///
|
||||||
|
/// `#[visit(leaf, with = "visit_expr")]`
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Attributes {
|
||||||
|
/// Content for the `with` attribute
|
||||||
|
with: Option<Ident>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Attributes {
|
||||||
|
fn parse(attrs: &[Attribute]) -> Self {
|
||||||
|
let mut out = Self::default();
|
||||||
|
for attr in attrs.iter().filter(|a| a.path.is_ident("visit")) {
|
||||||
|
let meta = attr.parse_meta().expect("visit attribute");
|
||||||
|
match meta {
|
||||||
|
Meta::List(l) => {
|
||||||
|
for nested in &l.nested {
|
||||||
|
match nested {
|
||||||
|
NestedMeta::Meta(Meta::NameValue(v)) => out.parse_name_value(v),
|
||||||
|
_ => panic!("Expected #[visit(key = \"value\")]"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => panic!("Expected #[visit(...)]"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates self with a name value attribute
|
||||||
|
fn parse_name_value(&mut self, v: &MetaNameValue) {
|
||||||
|
if v.path.is_ident("with") {
|
||||||
|
match &v.lit {
|
||||||
|
Lit::Str(s) => self.with = Some(format_ident!("{}", s.value(), span = s.span())),
|
||||||
|
_ => panic!("Expected a string value, got {}", v.lit.to_token_stream()),
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
panic!("Unrecognised kv attribute {}", v.path.to_token_stream())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the pre and post visit token streams
|
||||||
|
fn visit(&self, s: TokenStream) -> (Option<TokenStream>, Option<TokenStream>) {
|
||||||
|
let pre_visit = self.with.as_ref().map(|m| {
|
||||||
|
let m = format_ident!("pre_{}", m);
|
||||||
|
quote!(visitor.#m(#s)?;)
|
||||||
|
});
|
||||||
|
let post_visit = self.with.as_ref().map(|m| {
|
||||||
|
let m = format_ident!("post_{}", m);
|
||||||
|
quote!(visitor.#m(#s)?;)
|
||||||
|
});
|
||||||
|
(pre_visit, post_visit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a bound `T: Visit` to every type parameter T.
|
||||||
|
fn add_trait_bounds(mut generics: Generics) -> Generics {
|
||||||
|
for param in &mut generics.params {
|
||||||
|
if let GenericParam::Type(ref mut type_param) = *param {
|
||||||
|
type_param.bounds.push(parse_quote!(sqlparser::ast::Visit));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
generics
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the body of the visit implementation for the given type
|
||||||
|
fn visit_children(data: &Data) -> TokenStream {
|
||||||
|
match data {
|
||||||
|
Data::Struct(data) => match &data.fields {
|
||||||
|
Fields::Named(fields) => {
|
||||||
|
let recurse = fields.named.iter().map(|f| {
|
||||||
|
let name = &f.ident;
|
||||||
|
let attributes = Attributes::parse(&f.attrs);
|
||||||
|
let (pre_visit, post_visit) = attributes.visit(quote!(&self.#name));
|
||||||
|
quote_spanned!(f.span() => #pre_visit sqlparser::ast::Visit::visit(&self.#name, visitor)?; #post_visit)
|
||||||
|
});
|
||||||
|
quote! {
|
||||||
|
#(#recurse)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fields::Unnamed(fields) => {
|
||||||
|
let recurse = fields.unnamed.iter().enumerate().map(|(i, f)| {
|
||||||
|
let index = Index::from(i);
|
||||||
|
let attributes = Attributes::parse(&f.attrs);
|
||||||
|
let (pre_visit, post_visit) = attributes.visit(quote!(&self.#index));
|
||||||
|
quote_spanned!(f.span() => #pre_visit sqlparser::ast::Visit::visit(&self.#index, visitor)?; #post_visit)
|
||||||
|
});
|
||||||
|
quote! {
|
||||||
|
#(#recurse)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fields::Unit => {
|
||||||
|
quote!()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Data::Enum(data) => {
|
||||||
|
let statements = data.variants.iter().map(|v| {
|
||||||
|
let name = &v.ident;
|
||||||
|
match &v.fields {
|
||||||
|
Fields::Named(fields) => {
|
||||||
|
let names = fields.named.iter().map(|f| &f.ident);
|
||||||
|
let visit = fields.named.iter().map(|f| {
|
||||||
|
let name = &f.ident;
|
||||||
|
let attributes = Attributes::parse(&f.attrs);
|
||||||
|
let (pre_visit, post_visit) = attributes.visit(quote!(&#name));
|
||||||
|
quote_spanned!(f.span() => #pre_visit sqlparser::ast::Visit::visit(#name, visitor)?; #post_visit)
|
||||||
|
});
|
||||||
|
|
||||||
|
quote!(
|
||||||
|
Self::#name { #(#names),* } => {
|
||||||
|
#(#visit)*
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Fields::Unnamed(fields) => {
|
||||||
|
let names = fields.unnamed.iter().enumerate().map(|(i, f)| format_ident!("_{}", i, span = f.span()));
|
||||||
|
let visit = fields.unnamed.iter().enumerate().map(|(i, f)| {
|
||||||
|
let name = format_ident!("_{}", i);
|
||||||
|
let attributes = Attributes::parse(&f.attrs);
|
||||||
|
let (pre_visit, post_visit) = attributes.visit(quote!(&#name));
|
||||||
|
quote_spanned!(f.span() => #pre_visit sqlparser::ast::Visit::visit(#name, visitor)?; #post_visit)
|
||||||
|
});
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
Self::#name ( #(#names),*) => {
|
||||||
|
#(#visit)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fields::Unit => {
|
||||||
|
quote! {
|
||||||
|
Self::#name => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
match self {
|
||||||
|
#(#statements),*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Data::Union(_) => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,9 @@ use core::fmt;
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
use sqlparser_derive::Visit;
|
||||||
|
|
||||||
use crate::ast::ObjectName;
|
use crate::ast::ObjectName;
|
||||||
|
|
||||||
use super::value::escape_single_quote_string;
|
use super::value::escape_single_quote_string;
|
||||||
|
@ -24,6 +27,7 @@ use super::value::escape_single_quote_string;
|
||||||
/// SQL data types
|
/// SQL data types
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum DataType {
|
pub enum DataType {
|
||||||
/// Fixed-length character type e.g. CHARACTER(10)
|
/// Fixed-length character type e.g. CHARACTER(10)
|
||||||
Character(Option<CharacterLength>),
|
Character(Option<CharacterLength>),
|
||||||
|
@ -337,6 +341,7 @@ fn format_datetime_precision_and_tz(
|
||||||
/// guarantee compatibility with the input query we must maintain its exact information.
|
/// guarantee compatibility with the input query we must maintain its exact information.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum TimezoneInfo {
|
pub enum TimezoneInfo {
|
||||||
/// No information about time zone. E.g., TIMESTAMP
|
/// No information about time zone. E.g., TIMESTAMP
|
||||||
None,
|
None,
|
||||||
|
@ -384,6 +389,7 @@ impl fmt::Display for TimezoneInfo {
|
||||||
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type
|
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ExactNumberInfo {
|
pub enum ExactNumberInfo {
|
||||||
/// No additional information e.g. `DECIMAL`
|
/// No additional information e.g. `DECIMAL`
|
||||||
None,
|
None,
|
||||||
|
@ -414,6 +420,7 @@ impl fmt::Display for ExactNumberInfo {
|
||||||
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-length
|
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-length
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct CharacterLength {
|
pub struct CharacterLength {
|
||||||
/// Default (if VARYING) or maximum (if not VARYING) length
|
/// Default (if VARYING) or maximum (if not VARYING) length
|
||||||
pub length: u64,
|
pub length: u64,
|
||||||
|
@ -436,6 +443,7 @@ impl fmt::Display for CharacterLength {
|
||||||
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#char-length-units
|
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#char-length-units
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum CharLengthUnits {
|
pub enum CharLengthUnits {
|
||||||
/// CHARACTERS unit
|
/// CHARACTERS unit
|
||||||
Characters,
|
Characters,
|
||||||
|
|
|
@ -20,6 +20,9 @@ use core::fmt;
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
use sqlparser_derive::Visit;
|
||||||
|
|
||||||
use crate::ast::value::escape_single_quote_string;
|
use crate::ast::value::escape_single_quote_string;
|
||||||
use crate::ast::{display_comma_separated, display_separated, DataType, Expr, Ident, ObjectName};
|
use crate::ast::{display_comma_separated, display_separated, DataType, Expr, Ident, ObjectName};
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
|
@ -27,6 +30,7 @@ use crate::tokenizer::Token;
|
||||||
/// An `ALTER TABLE` (`Statement::AlterTable`) operation
|
/// An `ALTER TABLE` (`Statement::AlterTable`) operation
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum AlterTableOperation {
|
pub enum AlterTableOperation {
|
||||||
/// `ADD <table_constraint>`
|
/// `ADD <table_constraint>`
|
||||||
AddConstraint(TableConstraint),
|
AddConstraint(TableConstraint),
|
||||||
|
@ -96,6 +100,7 @@ pub enum AlterTableOperation {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum AlterIndexOperation {
|
pub enum AlterIndexOperation {
|
||||||
RenameIndex { index_name: ObjectName },
|
RenameIndex { index_name: ObjectName },
|
||||||
}
|
}
|
||||||
|
@ -219,6 +224,7 @@ impl fmt::Display for AlterIndexOperation {
|
||||||
/// An `ALTER COLUMN` (`Statement::AlterTable`) operation
|
/// An `ALTER COLUMN` (`Statement::AlterTable`) operation
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum AlterColumnOperation {
|
pub enum AlterColumnOperation {
|
||||||
/// `SET NOT NULL`
|
/// `SET NOT NULL`
|
||||||
SetNotNull,
|
SetNotNull,
|
||||||
|
@ -262,6 +268,7 @@ impl fmt::Display for AlterColumnOperation {
|
||||||
/// `ALTER TABLE ADD <constraint>` statement.
|
/// `ALTER TABLE ADD <constraint>` statement.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum TableConstraint {
|
pub enum TableConstraint {
|
||||||
/// `[ CONSTRAINT <name> ] { PRIMARY KEY | UNIQUE } (<columns>)`
|
/// `[ CONSTRAINT <name> ] { PRIMARY KEY | UNIQUE } (<columns>)`
|
||||||
Unique {
|
Unique {
|
||||||
|
@ -425,6 +432,7 @@ impl fmt::Display for TableConstraint {
|
||||||
/// [1]: https://dev.mysql.com/doc/refman/8.0/en/create-table.html
|
/// [1]: https://dev.mysql.com/doc/refman/8.0/en/create-table.html
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum KeyOrIndexDisplay {
|
pub enum KeyOrIndexDisplay {
|
||||||
/// Nothing to display
|
/// Nothing to display
|
||||||
None,
|
None,
|
||||||
|
@ -460,6 +468,7 @@ impl fmt::Display for KeyOrIndexDisplay {
|
||||||
/// [3]: https://www.postgresql.org/docs/14/sql-createindex.html
|
/// [3]: https://www.postgresql.org/docs/14/sql-createindex.html
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum IndexType {
|
pub enum IndexType {
|
||||||
BTree,
|
BTree,
|
||||||
Hash,
|
Hash,
|
||||||
|
@ -478,6 +487,7 @@ impl fmt::Display for IndexType {
|
||||||
/// SQL column definition
|
/// SQL column definition
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct ColumnDef {
|
pub struct ColumnDef {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub data_type: DataType,
|
pub data_type: DataType,
|
||||||
|
@ -513,6 +523,7 @@ impl fmt::Display for ColumnDef {
|
||||||
/// "column options," and we allow any column option to be named.
|
/// "column options," and we allow any column option to be named.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct ColumnOptionDef {
|
pub struct ColumnOptionDef {
|
||||||
pub name: Option<Ident>,
|
pub name: Option<Ident>,
|
||||||
pub option: ColumnOption,
|
pub option: ColumnOption,
|
||||||
|
@ -528,6 +539,7 @@ impl fmt::Display for ColumnOptionDef {
|
||||||
/// TABLE` statement.
|
/// TABLE` statement.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ColumnOption {
|
pub enum ColumnOption {
|
||||||
/// `NULL`
|
/// `NULL`
|
||||||
Null,
|
Null,
|
||||||
|
@ -617,6 +629,7 @@ fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
|
||||||
/// Used in foreign key constraints in `ON UPDATE` and `ON DELETE` options.
|
/// Used in foreign key constraints in `ON UPDATE` and `ON DELETE` options.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ReferentialAction {
|
pub enum ReferentialAction {
|
||||||
Restrict,
|
Restrict,
|
||||||
Cascade,
|
Cascade,
|
||||||
|
|
|
@ -4,6 +4,9 @@ use alloc::{boxed::Box, format, string::String, vec, vec::Vec};
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
use sqlparser_derive::Visit;
|
||||||
|
|
||||||
use crate::ast::{
|
use crate::ast::{
|
||||||
ColumnDef, FileFormat, HiveDistributionStyle, HiveFormat, ObjectName, OnCommit, Query,
|
ColumnDef, FileFormat, HiveDistributionStyle, HiveFormat, ObjectName, OnCommit, Query,
|
||||||
SqlOption, Statement, TableConstraint,
|
SqlOption, Statement, TableConstraint,
|
||||||
|
@ -40,6 +43,7 @@ use crate::parser::ParserError;
|
||||||
/// [1]: crate::ast::Statement::CreateTable
|
/// [1]: crate::ast::Statement::CreateTable
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct CreateTableBuilder {
|
pub struct CreateTableBuilder {
|
||||||
pub or_replace: bool,
|
pub or_replace: bool,
|
||||||
pub temporary: bool,
|
pub temporary: bool,
|
||||||
|
|
106
src/ast/mod.rs
106
src/ast/mod.rs
|
@ -22,6 +22,9 @@ use core::fmt;
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
use sqlparser_derive::Visit;
|
||||||
|
|
||||||
pub use self::data_type::{
|
pub use self::data_type::{
|
||||||
CharLengthUnits, CharacterLength, DataType, ExactNumberInfo, TimezoneInfo,
|
CharLengthUnits, CharacterLength, DataType, ExactNumberInfo, TimezoneInfo,
|
||||||
};
|
};
|
||||||
|
@ -38,6 +41,9 @@ pub use self::query::{
|
||||||
};
|
};
|
||||||
pub use self::value::{escape_quoted_string, DateTimeField, TrimWhereField, Value};
|
pub use self::value::{escape_quoted_string, DateTimeField, TrimWhereField, Value};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
pub use visitor::*;
|
||||||
|
|
||||||
mod data_type;
|
mod data_type;
|
||||||
mod ddl;
|
mod ddl;
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
|
@ -45,6 +51,9 @@ mod operator;
|
||||||
mod query;
|
mod query;
|
||||||
mod value;
|
mod value;
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
mod visitor;
|
||||||
|
|
||||||
struct DisplaySeparated<'a, T>
|
struct DisplaySeparated<'a, T>
|
||||||
where
|
where
|
||||||
T: fmt::Display,
|
T: fmt::Display,
|
||||||
|
@ -85,6 +94,7 @@ where
|
||||||
/// An identifier, decomposed into its value or character data and the quote style.
|
/// An identifier, decomposed into its value or character data and the quote style.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Ident {
|
pub struct Ident {
|
||||||
/// The value of the identifier without quotes.
|
/// The value of the identifier without quotes.
|
||||||
pub value: String,
|
pub value: String,
|
||||||
|
@ -145,6 +155,7 @@ impl fmt::Display for Ident {
|
||||||
/// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj
|
/// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct ObjectName(pub Vec<Ident>);
|
pub struct ObjectName(pub Vec<Ident>);
|
||||||
|
|
||||||
impl fmt::Display for ObjectName {
|
impl fmt::Display for ObjectName {
|
||||||
|
@ -153,10 +164,11 @@ impl fmt::Display for ObjectName {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
||||||
/// Represents an Array Expression, either
|
/// Represents an Array Expression, either
|
||||||
/// `ARRAY[..]`, or `[..]`
|
/// `ARRAY[..]`, or `[..]`
|
||||||
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Array {
|
pub struct Array {
|
||||||
/// The list of expressions between brackets
|
/// The list of expressions between brackets
|
||||||
pub elem: Vec<Expr>,
|
pub elem: Vec<Expr>,
|
||||||
|
@ -179,6 +191,7 @@ impl fmt::Display for Array {
|
||||||
/// JsonOperator
|
/// JsonOperator
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum JsonOperator {
|
pub enum JsonOperator {
|
||||||
/// -> keeps the value as json
|
/// -> keeps the value as json
|
||||||
Arrow,
|
Arrow,
|
||||||
|
@ -242,6 +255,7 @@ impl fmt::Display for JsonOperator {
|
||||||
/// inappropriate type, like `WHERE 1` or `SELECT 1=1`, as necessary.
|
/// inappropriate type, like `WHERE 1` or `SELECT 1=1`, as necessary.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit), visit(with = "visit_expr"))]
|
||||||
pub enum Expr {
|
pub enum Expr {
|
||||||
/// Identifier e.g. table name or column name
|
/// Identifier e.g. table name or column name
|
||||||
Identifier(Ident),
|
Identifier(Ident),
|
||||||
|
@ -882,6 +896,7 @@ impl fmt::Display for Expr {
|
||||||
/// A window specification (i.e. `OVER (PARTITION BY .. ORDER BY .. etc.)`)
|
/// A window specification (i.e. `OVER (PARTITION BY .. ORDER BY .. etc.)`)
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct WindowSpec {
|
pub struct WindowSpec {
|
||||||
pub partition_by: Vec<Expr>,
|
pub partition_by: Vec<Expr>,
|
||||||
pub order_by: Vec<OrderByExpr>,
|
pub order_by: Vec<OrderByExpr>,
|
||||||
|
@ -927,6 +942,7 @@ impl fmt::Display for WindowSpec {
|
||||||
/// reject invalid bounds like `ROWS UNBOUNDED FOLLOWING` before execution.
|
/// reject invalid bounds like `ROWS UNBOUNDED FOLLOWING` before execution.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct WindowFrame {
|
pub struct WindowFrame {
|
||||||
pub units: WindowFrameUnits,
|
pub units: WindowFrameUnits,
|
||||||
pub start_bound: WindowFrameBound,
|
pub start_bound: WindowFrameBound,
|
||||||
|
@ -952,6 +968,7 @@ impl Default for WindowFrame {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum WindowFrameUnits {
|
pub enum WindowFrameUnits {
|
||||||
Rows,
|
Rows,
|
||||||
Range,
|
Range,
|
||||||
|
@ -971,6 +988,7 @@ impl fmt::Display for WindowFrameUnits {
|
||||||
/// Specifies [WindowFrame]'s `start_bound` and `end_bound`
|
/// Specifies [WindowFrame]'s `start_bound` and `end_bound`
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum WindowFrameBound {
|
pub enum WindowFrameBound {
|
||||||
/// `CURRENT ROW`
|
/// `CURRENT ROW`
|
||||||
CurrentRow,
|
CurrentRow,
|
||||||
|
@ -994,6 +1012,7 @@ impl fmt::Display for WindowFrameBound {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum AddDropSync {
|
pub enum AddDropSync {
|
||||||
ADD,
|
ADD,
|
||||||
DROP,
|
DROP,
|
||||||
|
@ -1012,6 +1031,7 @@ impl fmt::Display for AddDropSync {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ShowCreateObject {
|
pub enum ShowCreateObject {
|
||||||
Event,
|
Event,
|
||||||
Function,
|
Function,
|
||||||
|
@ -1036,6 +1056,7 @@ impl fmt::Display for ShowCreateObject {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum CommentObject {
|
pub enum CommentObject {
|
||||||
Column,
|
Column,
|
||||||
Table,
|
Table,
|
||||||
|
@ -1052,6 +1073,7 @@ impl fmt::Display for CommentObject {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum Password {
|
pub enum Password {
|
||||||
Password(Expr),
|
Password(Expr),
|
||||||
NullPassword,
|
NullPassword,
|
||||||
|
@ -1061,9 +1083,11 @@ pub enum Password {
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit), visit(with = "visit_statement"))]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
/// Analyze (Hive)
|
/// Analyze (Hive)
|
||||||
Analyze {
|
Analyze {
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
partitions: Option<Vec<Expr>>,
|
partitions: Option<Vec<Expr>>,
|
||||||
for_columns: bool,
|
for_columns: bool,
|
||||||
|
@ -1074,11 +1098,13 @@ pub enum Statement {
|
||||||
},
|
},
|
||||||
/// Truncate (Hive)
|
/// Truncate (Hive)
|
||||||
Truncate {
|
Truncate {
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
partitions: Option<Vec<Expr>>,
|
partitions: Option<Vec<Expr>>,
|
||||||
},
|
},
|
||||||
/// Msck (Hive)
|
/// Msck (Hive)
|
||||||
Msck {
|
Msck {
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
repair: bool,
|
repair: bool,
|
||||||
partition_action: Option<AddDropSync>,
|
partition_action: Option<AddDropSync>,
|
||||||
|
@ -1092,6 +1118,7 @@ pub enum Statement {
|
||||||
/// INTO - optional keyword
|
/// INTO - optional keyword
|
||||||
into: bool,
|
into: bool,
|
||||||
/// TABLE
|
/// TABLE
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
/// COLUMNS
|
/// COLUMNS
|
||||||
columns: Vec<Ident>,
|
columns: Vec<Ident>,
|
||||||
|
@ -1119,6 +1146,7 @@ pub enum Statement {
|
||||||
},
|
},
|
||||||
Copy {
|
Copy {
|
||||||
/// TABLE
|
/// TABLE
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
/// COLUMNS
|
/// COLUMNS
|
||||||
columns: Vec<Ident>,
|
columns: Vec<Ident>,
|
||||||
|
@ -1181,6 +1209,7 @@ pub enum Statement {
|
||||||
global: Option<bool>,
|
global: Option<bool>,
|
||||||
if_not_exists: bool,
|
if_not_exists: bool,
|
||||||
/// Table name
|
/// Table name
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
name: ObjectName,
|
name: ObjectName,
|
||||||
/// Optional schema
|
/// Optional schema
|
||||||
columns: Vec<ColumnDef>,
|
columns: Vec<ColumnDef>,
|
||||||
|
@ -1205,6 +1234,7 @@ pub enum Statement {
|
||||||
},
|
},
|
||||||
/// SQLite's `CREATE VIRTUAL TABLE .. USING <module_name> (<module_args>)`
|
/// SQLite's `CREATE VIRTUAL TABLE .. USING <module_name> (<module_args>)`
|
||||||
CreateVirtualTable {
|
CreateVirtualTable {
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
name: ObjectName,
|
name: ObjectName,
|
||||||
if_not_exists: bool,
|
if_not_exists: bool,
|
||||||
module_name: Ident,
|
module_name: Ident,
|
||||||
|
@ -1214,6 +1244,7 @@ pub enum Statement {
|
||||||
CreateIndex {
|
CreateIndex {
|
||||||
/// index name
|
/// index name
|
||||||
name: ObjectName,
|
name: ObjectName,
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
using: Option<Ident>,
|
using: Option<Ident>,
|
||||||
columns: Vec<OrderByExpr>,
|
columns: Vec<OrderByExpr>,
|
||||||
|
@ -1247,6 +1278,7 @@ pub enum Statement {
|
||||||
/// ALTER TABLE
|
/// ALTER TABLE
|
||||||
AlterTable {
|
AlterTable {
|
||||||
/// Table name
|
/// Table name
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
name: ObjectName,
|
name: ObjectName,
|
||||||
operation: AlterTableOperation,
|
operation: AlterTableOperation,
|
||||||
},
|
},
|
||||||
|
@ -1383,6 +1415,7 @@ pub enum Statement {
|
||||||
ShowColumns {
|
ShowColumns {
|
||||||
extended: bool,
|
extended: bool,
|
||||||
full: bool,
|
full: bool,
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
filter: Option<ShowStatementFilter>,
|
filter: Option<ShowStatementFilter>,
|
||||||
},
|
},
|
||||||
|
@ -1498,9 +1531,10 @@ pub enum Statement {
|
||||||
/// EXPLAIN TABLE
|
/// EXPLAIN TABLE
|
||||||
/// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/explain.html>
|
/// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/explain.html>
|
||||||
ExplainTable {
|
ExplainTable {
|
||||||
// If true, query used the MySQL `DESCRIBE` alias for explain
|
/// If true, query used the MySQL `DESCRIBE` alias for explain
|
||||||
describe_alias: bool,
|
describe_alias: bool,
|
||||||
// Table name
|
/// Table name
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
},
|
},
|
||||||
/// EXPLAIN / DESCRIBE for select_statement
|
/// EXPLAIN / DESCRIBE for select_statement
|
||||||
|
@ -1534,19 +1568,22 @@ pub enum Statement {
|
||||||
/// CACHE [ FLAG ] TABLE <table_name> [ OPTIONS('K1' = 'V1', 'K2' = V2) ] [ AS ] [ <query> ]
|
/// CACHE [ FLAG ] TABLE <table_name> [ OPTIONS('K1' = 'V1', 'K2' = V2) ] [ AS ] [ <query> ]
|
||||||
/// Based on Spark SQL,see <https://docs.databricks.com/spark/latest/spark-sql/language-manual/sql-ref-syntax-aux-cache-cache-table.html>
|
/// Based on Spark SQL,see <https://docs.databricks.com/spark/latest/spark-sql/language-manual/sql-ref-syntax-aux-cache-cache-table.html>
|
||||||
Cache {
|
Cache {
|
||||||
// Table flag
|
/// Table flag
|
||||||
table_flag: Option<ObjectName>,
|
table_flag: Option<ObjectName>,
|
||||||
// Table name
|
/// Table name
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
has_as: bool,
|
has_as: bool,
|
||||||
// Table confs
|
/// Table confs
|
||||||
options: Vec<SqlOption>,
|
options: Vec<SqlOption>,
|
||||||
// Cache table as a Query
|
/// Cache table as a Query
|
||||||
query: Option<Query>,
|
query: Option<Query>,
|
||||||
},
|
},
|
||||||
/// UNCACHE TABLE [ IF EXISTS ] <table_name>
|
/// UNCACHE TABLE [ IF EXISTS ] <table_name>
|
||||||
UNCache {
|
UNCache {
|
||||||
// Table name
|
/// Table name
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
table_name: ObjectName,
|
table_name: ObjectName,
|
||||||
if_exists: bool,
|
if_exists: bool,
|
||||||
},
|
},
|
||||||
|
@ -2673,6 +2710,7 @@ impl fmt::Display for Statement {
|
||||||
/// [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
|
/// [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum SequenceOptions {
|
pub enum SequenceOptions {
|
||||||
IncrementBy(Expr, bool),
|
IncrementBy(Expr, bool),
|
||||||
MinValue(MinMaxValue),
|
MinValue(MinMaxValue),
|
||||||
|
@ -2737,6 +2775,7 @@ impl fmt::Display for SequenceOptions {
|
||||||
/// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
|
/// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum MinMaxValue {
|
pub enum MinMaxValue {
|
||||||
// clause is not specified
|
// clause is not specified
|
||||||
Empty,
|
Empty,
|
||||||
|
@ -2748,6 +2787,7 @@ pub enum MinMaxValue {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum OnInsert {
|
pub enum OnInsert {
|
||||||
/// ON DUPLICATE KEY UPDATE (MySQL when the key already exists, then execute an update instead)
|
/// ON DUPLICATE KEY UPDATE (MySQL when the key already exists, then execute an update instead)
|
||||||
|
@ -2758,18 +2798,21 @@ pub enum OnInsert {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct OnConflict {
|
pub struct OnConflict {
|
||||||
pub conflict_target: Option<ConflictTarget>,
|
pub conflict_target: Option<ConflictTarget>,
|
||||||
pub action: OnConflictAction,
|
pub action: OnConflictAction,
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ConflictTarget {
|
pub enum ConflictTarget {
|
||||||
Columns(Vec<Ident>),
|
Columns(Vec<Ident>),
|
||||||
OnConstraint(ObjectName),
|
OnConstraint(ObjectName),
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum OnConflictAction {
|
pub enum OnConflictAction {
|
||||||
DoNothing,
|
DoNothing,
|
||||||
DoUpdate(DoUpdate),
|
DoUpdate(DoUpdate),
|
||||||
|
@ -2777,6 +2820,7 @@ pub enum OnConflictAction {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct DoUpdate {
|
pub struct DoUpdate {
|
||||||
/// Column assignments
|
/// Column assignments
|
||||||
pub assignments: Vec<Assignment>,
|
pub assignments: Vec<Assignment>,
|
||||||
|
@ -2838,6 +2882,7 @@ impl fmt::Display for OnConflictAction {
|
||||||
/// Privileges granted in a GRANT statement or revoked in a REVOKE statement.
|
/// Privileges granted in a GRANT statement or revoked in a REVOKE statement.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum Privileges {
|
pub enum Privileges {
|
||||||
/// All privileges applicable to the object type
|
/// All privileges applicable to the object type
|
||||||
All {
|
All {
|
||||||
|
@ -2874,6 +2919,7 @@ impl fmt::Display for Privileges {
|
||||||
/// Specific direction for FETCH statement
|
/// Specific direction for FETCH statement
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum FetchDirection {
|
pub enum FetchDirection {
|
||||||
Count { limit: Value },
|
Count { limit: Value },
|
||||||
Next,
|
Next,
|
||||||
|
@ -2937,6 +2983,7 @@ impl fmt::Display for FetchDirection {
|
||||||
/// A privilege on a database object (table, sequence, etc.).
|
/// A privilege on a database object (table, sequence, etc.).
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
Connect,
|
Connect,
|
||||||
Create,
|
Create,
|
||||||
|
@ -2986,6 +3033,7 @@ impl fmt::Display for Action {
|
||||||
/// Objects on which privileges are granted in a GRANT statement.
|
/// Objects on which privileges are granted in a GRANT statement.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum GrantObjects {
|
pub enum GrantObjects {
|
||||||
/// Grant privileges on `ALL SEQUENCES IN SCHEMA <schema_name> [, ...]`
|
/// Grant privileges on `ALL SEQUENCES IN SCHEMA <schema_name> [, ...]`
|
||||||
AllSequencesInSchema { schemas: Vec<ObjectName> },
|
AllSequencesInSchema { schemas: Vec<ObjectName> },
|
||||||
|
@ -3032,6 +3080,7 @@ impl fmt::Display for GrantObjects {
|
||||||
/// SQL assignment `foo = expr` as used in SQLUpdate
|
/// SQL assignment `foo = expr` as used in SQLUpdate
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Assignment {
|
pub struct Assignment {
|
||||||
pub id: Vec<Ident>,
|
pub id: Vec<Ident>,
|
||||||
pub value: Expr,
|
pub value: Expr,
|
||||||
|
@ -3045,6 +3094,7 @@ impl fmt::Display for Assignment {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum FunctionArgExpr {
|
pub enum FunctionArgExpr {
|
||||||
Expr(Expr),
|
Expr(Expr),
|
||||||
/// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
|
/// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
|
||||||
|
@ -3065,6 +3115,7 @@ impl fmt::Display for FunctionArgExpr {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum FunctionArg {
|
pub enum FunctionArg {
|
||||||
Named { name: Ident, arg: FunctionArgExpr },
|
Named { name: Ident, arg: FunctionArgExpr },
|
||||||
Unnamed(FunctionArgExpr),
|
Unnamed(FunctionArgExpr),
|
||||||
|
@ -3081,6 +3132,7 @@ impl fmt::Display for FunctionArg {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum CloseCursor {
|
pub enum CloseCursor {
|
||||||
All,
|
All,
|
||||||
Specific { name: Ident },
|
Specific { name: Ident },
|
||||||
|
@ -3098,6 +3150,7 @@ impl fmt::Display for CloseCursor {
|
||||||
/// A function call
|
/// A function call
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub name: ObjectName,
|
pub name: ObjectName,
|
||||||
pub args: Vec<FunctionArg>,
|
pub args: Vec<FunctionArg>,
|
||||||
|
@ -3111,6 +3164,7 @@ pub struct Function {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum AnalyzeFormat {
|
pub enum AnalyzeFormat {
|
||||||
TEXT,
|
TEXT,
|
||||||
GRAPHVIZ,
|
GRAPHVIZ,
|
||||||
|
@ -3152,6 +3206,7 @@ impl fmt::Display for Function {
|
||||||
/// External table's available file format
|
/// External table's available file format
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum FileFormat {
|
pub enum FileFormat {
|
||||||
TEXTFILE,
|
TEXTFILE,
|
||||||
SEQUENCEFILE,
|
SEQUENCEFILE,
|
||||||
|
@ -3181,6 +3236,7 @@ impl fmt::Display for FileFormat {
|
||||||
/// [ WITHIN GROUP (ORDER BY <within_group1>[, ...] ) ]`
|
/// [ WITHIN GROUP (ORDER BY <within_group1>[, ...] ) ]`
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct ListAgg {
|
pub struct ListAgg {
|
||||||
pub distinct: bool,
|
pub distinct: bool,
|
||||||
pub expr: Box<Expr>,
|
pub expr: Box<Expr>,
|
||||||
|
@ -3218,6 +3274,7 @@ impl fmt::Display for ListAgg {
|
||||||
/// The `ON OVERFLOW` clause of a LISTAGG invocation
|
/// The `ON OVERFLOW` clause of a LISTAGG invocation
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ListAggOnOverflow {
|
pub enum ListAggOnOverflow {
|
||||||
/// `ON OVERFLOW ERROR`
|
/// `ON OVERFLOW ERROR`
|
||||||
Error,
|
Error,
|
||||||
|
@ -3255,6 +3312,7 @@ impl fmt::Display for ListAggOnOverflow {
|
||||||
/// ORDER BY position is defined differently for BigQuery, Postgres and Snowflake.
|
/// ORDER BY position is defined differently for BigQuery, Postgres and Snowflake.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct ArrayAgg {
|
pub struct ArrayAgg {
|
||||||
pub distinct: bool,
|
pub distinct: bool,
|
||||||
pub expr: Box<Expr>,
|
pub expr: Box<Expr>,
|
||||||
|
@ -3291,6 +3349,7 @@ impl fmt::Display for ArrayAgg {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ObjectType {
|
pub enum ObjectType {
|
||||||
Table,
|
Table,
|
||||||
View,
|
View,
|
||||||
|
@ -3315,6 +3374,7 @@ impl fmt::Display for ObjectType {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum KillType {
|
pub enum KillType {
|
||||||
Connection,
|
Connection,
|
||||||
Query,
|
Query,
|
||||||
|
@ -3335,6 +3395,7 @@ impl fmt::Display for KillType {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum HiveDistributionStyle {
|
pub enum HiveDistributionStyle {
|
||||||
PARTITIONED {
|
PARTITIONED {
|
||||||
columns: Vec<ColumnDef>,
|
columns: Vec<ColumnDef>,
|
||||||
|
@ -3354,14 +3415,15 @@ pub enum HiveDistributionStyle {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum HiveRowFormat {
|
pub enum HiveRowFormat {
|
||||||
SERDE { class: String },
|
SERDE { class: String },
|
||||||
DELIMITED,
|
DELIMITED,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum HiveIOFormat {
|
pub enum HiveIOFormat {
|
||||||
IOF {
|
IOF {
|
||||||
|
@ -3375,6 +3437,7 @@ pub enum HiveIOFormat {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct HiveFormat {
|
pub struct HiveFormat {
|
||||||
pub row_format: Option<HiveRowFormat>,
|
pub row_format: Option<HiveRowFormat>,
|
||||||
pub storage: Option<HiveIOFormat>,
|
pub storage: Option<HiveIOFormat>,
|
||||||
|
@ -3383,6 +3446,7 @@ pub struct HiveFormat {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct SqlOption {
|
pub struct SqlOption {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub value: Value,
|
pub value: Value,
|
||||||
|
@ -3396,6 +3460,7 @@ impl fmt::Display for SqlOption {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum TransactionMode {
|
pub enum TransactionMode {
|
||||||
AccessMode(TransactionAccessMode),
|
AccessMode(TransactionAccessMode),
|
||||||
IsolationLevel(TransactionIsolationLevel),
|
IsolationLevel(TransactionIsolationLevel),
|
||||||
|
@ -3413,6 +3478,7 @@ impl fmt::Display for TransactionMode {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum TransactionAccessMode {
|
pub enum TransactionAccessMode {
|
||||||
ReadOnly,
|
ReadOnly,
|
||||||
ReadWrite,
|
ReadWrite,
|
||||||
|
@ -3430,6 +3496,7 @@ impl fmt::Display for TransactionAccessMode {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum TransactionIsolationLevel {
|
pub enum TransactionIsolationLevel {
|
||||||
ReadUncommitted,
|
ReadUncommitted,
|
||||||
ReadCommitted,
|
ReadCommitted,
|
||||||
|
@ -3451,6 +3518,7 @@ impl fmt::Display for TransactionIsolationLevel {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ShowStatementFilter {
|
pub enum ShowStatementFilter {
|
||||||
Like(String),
|
Like(String),
|
||||||
ILike(String),
|
ILike(String),
|
||||||
|
@ -3473,6 +3541,7 @@ impl fmt::Display for ShowStatementFilter {
|
||||||
/// https://sqlite.org/lang_conflict.html
|
/// https://sqlite.org/lang_conflict.html
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum SqliteOnConflict {
|
pub enum SqliteOnConflict {
|
||||||
Rollback,
|
Rollback,
|
||||||
Abort,
|
Abort,
|
||||||
|
@ -3496,6 +3565,7 @@ impl fmt::Display for SqliteOnConflict {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum CopyTarget {
|
pub enum CopyTarget {
|
||||||
Stdin,
|
Stdin,
|
||||||
Stdout,
|
Stdout,
|
||||||
|
@ -3527,6 +3597,7 @@ impl fmt::Display for CopyTarget {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum OnCommit {
|
pub enum OnCommit {
|
||||||
DeleteRows,
|
DeleteRows,
|
||||||
PreserveRows,
|
PreserveRows,
|
||||||
|
@ -3538,6 +3609,7 @@ pub enum OnCommit {
|
||||||
/// <https://www.postgresql.org/docs/14/sql-copy.html>
|
/// <https://www.postgresql.org/docs/14/sql-copy.html>
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum CopyOption {
|
pub enum CopyOption {
|
||||||
/// FORMAT format_name
|
/// FORMAT format_name
|
||||||
Format(Ident),
|
Format(Ident),
|
||||||
|
@ -3591,6 +3663,7 @@ impl fmt::Display for CopyOption {
|
||||||
/// <https://www.postgresql.org/docs/8.4/sql-copy.html>
|
/// <https://www.postgresql.org/docs/8.4/sql-copy.html>
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum CopyLegacyOption {
|
pub enum CopyLegacyOption {
|
||||||
/// BINARY
|
/// BINARY
|
||||||
Binary,
|
Binary,
|
||||||
|
@ -3619,6 +3692,7 @@ impl fmt::Display for CopyLegacyOption {
|
||||||
/// <https://www.postgresql.org/docs/8.4/sql-copy.html>
|
/// <https://www.postgresql.org/docs/8.4/sql-copy.html>
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum CopyLegacyCsvOption {
|
pub enum CopyLegacyCsvOption {
|
||||||
/// HEADER
|
/// HEADER
|
||||||
Header,
|
Header,
|
||||||
|
@ -3650,6 +3724,7 @@ impl fmt::Display for CopyLegacyCsvOption {
|
||||||
///
|
///
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum MergeClause {
|
pub enum MergeClause {
|
||||||
MatchedUpdate {
|
MatchedUpdate {
|
||||||
predicate: Option<Expr>,
|
predicate: Option<Expr>,
|
||||||
|
@ -3711,6 +3786,7 @@ impl fmt::Display for MergeClause {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum DiscardObject {
|
pub enum DiscardObject {
|
||||||
ALL,
|
ALL,
|
||||||
PLANS,
|
PLANS,
|
||||||
|
@ -3732,6 +3808,7 @@ impl fmt::Display for DiscardObject {
|
||||||
/// Optional context modifier for statements that can be or `LOCAL`, or `SESSION`.
|
/// Optional context modifier for statements that can be or `LOCAL`, or `SESSION`.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ContextModifier {
|
pub enum ContextModifier {
|
||||||
/// No context defined. Each dialect defines the default in this scenario.
|
/// No context defined. Each dialect defines the default in this scenario.
|
||||||
None,
|
None,
|
||||||
|
@ -3777,6 +3854,7 @@ impl fmt::Display for DropFunctionOption {
|
||||||
/// Function describe in DROP FUNCTION.
|
/// Function describe in DROP FUNCTION.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct DropFunctionDesc {
|
pub struct DropFunctionDesc {
|
||||||
pub name: ObjectName,
|
pub name: ObjectName,
|
||||||
pub args: Option<Vec<OperateFunctionArg>>,
|
pub args: Option<Vec<OperateFunctionArg>>,
|
||||||
|
@ -3795,6 +3873,7 @@ impl fmt::Display for DropFunctionDesc {
|
||||||
/// Function argument in CREATE OR DROP FUNCTION.
|
/// Function argument in CREATE OR DROP FUNCTION.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct OperateFunctionArg {
|
pub struct OperateFunctionArg {
|
||||||
pub mode: Option<ArgMode>,
|
pub mode: Option<ArgMode>,
|
||||||
pub name: Option<Ident>,
|
pub name: Option<Ident>,
|
||||||
|
@ -3843,6 +3922,7 @@ impl fmt::Display for OperateFunctionArg {
|
||||||
/// The mode of an argument in CREATE FUNCTION.
|
/// The mode of an argument in CREATE FUNCTION.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ArgMode {
|
pub enum ArgMode {
|
||||||
In,
|
In,
|
||||||
Out,
|
Out,
|
||||||
|
@ -3862,6 +3942,7 @@ impl fmt::Display for ArgMode {
|
||||||
/// These attributes inform the query optimizer about the behavior of the function.
|
/// These attributes inform the query optimizer about the behavior of the function.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum FunctionBehavior {
|
pub enum FunctionBehavior {
|
||||||
Immutable,
|
Immutable,
|
||||||
Stable,
|
Stable,
|
||||||
|
@ -3880,6 +3961,7 @@ impl fmt::Display for FunctionBehavior {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum FunctionDefinition {
|
pub enum FunctionDefinition {
|
||||||
SingleQuotedDef(String),
|
SingleQuotedDef(String),
|
||||||
DoubleDollarDef(String),
|
DoubleDollarDef(String),
|
||||||
|
@ -3898,6 +3980,7 @@ impl fmt::Display for FunctionDefinition {
|
||||||
/// Postgres: https://www.postgresql.org/docs/15/sql-createfunction.html
|
/// Postgres: https://www.postgresql.org/docs/15/sql-createfunction.html
|
||||||
#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct CreateFunctionBody {
|
pub struct CreateFunctionBody {
|
||||||
/// LANGUAGE lang_name
|
/// LANGUAGE lang_name
|
||||||
pub language: Option<Ident>,
|
pub language: Option<Ident>,
|
||||||
|
@ -3936,6 +4019,7 @@ impl fmt::Display for CreateFunctionBody {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum CreateFunctionUsing {
|
pub enum CreateFunctionUsing {
|
||||||
Jar(String),
|
Jar(String),
|
||||||
File(String),
|
File(String),
|
||||||
|
@ -3958,6 +4042,7 @@ impl fmt::Display for CreateFunctionUsing {
|
||||||
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition
|
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum SchemaName {
|
pub enum SchemaName {
|
||||||
/// Only schema name specified: `<schema name>`.
|
/// Only schema name specified: `<schema name>`.
|
||||||
Simple(ObjectName),
|
Simple(ObjectName),
|
||||||
|
@ -3988,6 +4073,7 @@ impl fmt::Display for SchemaName {
|
||||||
/// [1]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
|
/// [1]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum SearchModifier {
|
pub enum SearchModifier {
|
||||||
/// `IN NATURAL LANGUAGE MODE`.
|
/// `IN NATURAL LANGUAGE MODE`.
|
||||||
InNaturalLanguageMode,
|
InNaturalLanguageMode,
|
||||||
|
|
|
@ -14,14 +14,19 @@ use core::fmt;
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{string::String, vec::Vec};
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
use sqlparser_derive::Visit;
|
||||||
|
|
||||||
use super::display_separated;
|
use super::display_separated;
|
||||||
|
|
||||||
/// Unary operators
|
/// Unary operators
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum UnaryOperator {
|
pub enum UnaryOperator {
|
||||||
Plus,
|
Plus,
|
||||||
Minus,
|
Minus,
|
||||||
|
@ -59,6 +64,7 @@ impl fmt::Display for UnaryOperator {
|
||||||
/// Binary operators
|
/// Binary operators
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum BinaryOperator {
|
pub enum BinaryOperator {
|
||||||
Plus,
|
Plus,
|
||||||
Minus,
|
Minus,
|
||||||
|
|
|
@ -16,12 +16,16 @@ use alloc::{boxed::Box, vec::Vec};
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
use sqlparser_derive::Visit;
|
||||||
|
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
|
|
||||||
/// The most complete variant of a `SELECT` query expression, optionally
|
/// The most complete variant of a `SELECT` query expression, optionally
|
||||||
/// including `WITH`, `UNION` / other set operations, and `ORDER BY`.
|
/// including `WITH`, `UNION` / other set operations, and `ORDER BY`.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Query {
|
pub struct Query {
|
||||||
/// WITH (common table expressions, or CTEs)
|
/// WITH (common table expressions, or CTEs)
|
||||||
pub with: Option<With>,
|
pub with: Option<With>,
|
||||||
|
@ -69,6 +73,7 @@ impl fmt::Display for Query {
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum SetExpr {
|
pub enum SetExpr {
|
||||||
/// Restricted SELECT .. FROM .. HAVING (no ORDER BY or set operations)
|
/// Restricted SELECT .. FROM .. HAVING (no ORDER BY or set operations)
|
||||||
Select(Box<Select>),
|
Select(Box<Select>),
|
||||||
|
@ -117,6 +122,7 @@ impl fmt::Display for SetExpr {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum SetOperator {
|
pub enum SetOperator {
|
||||||
Union,
|
Union,
|
||||||
Except,
|
Except,
|
||||||
|
@ -138,6 +144,7 @@ impl fmt::Display for SetOperator {
|
||||||
// For example, BigQuery does not support `DISTINCT` for `EXCEPT` and `INTERSECT`
|
// For example, BigQuery does not support `DISTINCT` for `EXCEPT` and `INTERSECT`
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum SetQuantifier {
|
pub enum SetQuantifier {
|
||||||
All,
|
All,
|
||||||
Distinct,
|
Distinct,
|
||||||
|
@ -157,6 +164,7 @@ impl fmt::Display for SetQuantifier {
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
/// A [`TABLE` command]( https://www.postgresql.org/docs/current/sql-select.html#SQL-TABLE)
|
/// A [`TABLE` command]( https://www.postgresql.org/docs/current/sql-select.html#SQL-TABLE)
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Table {
|
pub struct Table {
|
||||||
pub table_name: Option<String>,
|
pub table_name: Option<String>,
|
||||||
pub schema_name: Option<String>,
|
pub schema_name: Option<String>,
|
||||||
|
@ -183,6 +191,7 @@ impl fmt::Display for Table {
|
||||||
/// to a set operation like `UNION`.
|
/// to a set operation like `UNION`.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Select {
|
pub struct Select {
|
||||||
pub distinct: bool,
|
pub distinct: bool,
|
||||||
/// MSSQL syntax: `TOP (<N>) [ PERCENT ] [ WITH TIES ]`
|
/// MSSQL syntax: `TOP (<N>) [ PERCENT ] [ WITH TIES ]`
|
||||||
|
@ -267,6 +276,7 @@ impl fmt::Display for Select {
|
||||||
/// A hive LATERAL VIEW with potential column aliases
|
/// A hive LATERAL VIEW with potential column aliases
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct LateralView {
|
pub struct LateralView {
|
||||||
/// LATERAL VIEW
|
/// LATERAL VIEW
|
||||||
pub lateral_view: Expr,
|
pub lateral_view: Expr,
|
||||||
|
@ -300,6 +310,7 @@ impl fmt::Display for LateralView {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct With {
|
pub struct With {
|
||||||
pub recursive: bool,
|
pub recursive: bool,
|
||||||
pub cte_tables: Vec<Cte>,
|
pub cte_tables: Vec<Cte>,
|
||||||
|
@ -322,6 +333,7 @@ impl fmt::Display for With {
|
||||||
/// number of columns in the query matches the number of columns in the query.
|
/// number of columns in the query matches the number of columns in the query.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Cte {
|
pub struct Cte {
|
||||||
pub alias: TableAlias,
|
pub alias: TableAlias,
|
||||||
pub query: Box<Query>,
|
pub query: Box<Query>,
|
||||||
|
@ -341,6 +353,7 @@ impl fmt::Display for Cte {
|
||||||
/// One item of the comma-separated list following `SELECT`
|
/// One item of the comma-separated list following `SELECT`
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum SelectItem {
|
pub enum SelectItem {
|
||||||
/// Any expression, not followed by `[ AS ] alias`
|
/// Any expression, not followed by `[ AS ] alias`
|
||||||
UnnamedExpr(Expr),
|
UnnamedExpr(Expr),
|
||||||
|
@ -355,6 +368,7 @@ pub enum SelectItem {
|
||||||
/// Additional options for wildcards, e.g. Snowflake `EXCLUDE` and Bigquery `EXCEPT`.
|
/// Additional options for wildcards, e.g. Snowflake `EXCLUDE` and Bigquery `EXCEPT`.
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct WildcardAdditionalOptions {
|
pub struct WildcardAdditionalOptions {
|
||||||
/// `[EXCLUDE...]`.
|
/// `[EXCLUDE...]`.
|
||||||
pub opt_exclude: Option<ExcludeSelectItem>,
|
pub opt_exclude: Option<ExcludeSelectItem>,
|
||||||
|
@ -383,6 +397,7 @@ impl fmt::Display for WildcardAdditionalOptions {
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum ExcludeSelectItem {
|
pub enum ExcludeSelectItem {
|
||||||
/// Single column name without parenthesis.
|
/// Single column name without parenthesis.
|
||||||
///
|
///
|
||||||
|
@ -422,6 +437,7 @@ impl fmt::Display for ExcludeSelectItem {
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct ExceptSelectItem {
|
pub struct ExceptSelectItem {
|
||||||
/// First guaranteed column.
|
/// First guaranteed column.
|
||||||
pub fist_elemnt: Ident,
|
pub fist_elemnt: Ident,
|
||||||
|
@ -467,6 +483,7 @@ impl fmt::Display for SelectItem {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct TableWithJoins {
|
pub struct TableWithJoins {
|
||||||
pub relation: TableFactor,
|
pub relation: TableFactor,
|
||||||
pub joins: Vec<Join>,
|
pub joins: Vec<Join>,
|
||||||
|
@ -485,8 +502,10 @@ impl fmt::Display for TableWithJoins {
|
||||||
/// A table name or a parenthesized subquery with an optional alias
|
/// A table name or a parenthesized subquery with an optional alias
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum TableFactor {
|
pub enum TableFactor {
|
||||||
Table {
|
Table {
|
||||||
|
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
|
||||||
name: ObjectName,
|
name: ObjectName,
|
||||||
alias: Option<TableAlias>,
|
alias: Option<TableAlias>,
|
||||||
/// Arguments of a table-valued function, as supported by Postgres
|
/// Arguments of a table-valued function, as supported by Postgres
|
||||||
|
@ -612,6 +631,7 @@ impl fmt::Display for TableFactor {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct TableAlias {
|
pub struct TableAlias {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub columns: Vec<Ident>,
|
pub columns: Vec<Ident>,
|
||||||
|
@ -629,6 +649,7 @@ impl fmt::Display for TableAlias {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Join {
|
pub struct Join {
|
||||||
pub relation: TableFactor,
|
pub relation: TableFactor,
|
||||||
pub join_operator: JoinOperator,
|
pub join_operator: JoinOperator,
|
||||||
|
@ -723,6 +744,7 @@ impl fmt::Display for Join {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum JoinOperator {
|
pub enum JoinOperator {
|
||||||
Inner(JoinConstraint),
|
Inner(JoinConstraint),
|
||||||
LeftOuter(JoinConstraint),
|
LeftOuter(JoinConstraint),
|
||||||
|
@ -745,6 +767,7 @@ pub enum JoinOperator {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum JoinConstraint {
|
pub enum JoinConstraint {
|
||||||
On(Expr),
|
On(Expr),
|
||||||
Using(Vec<Ident>),
|
Using(Vec<Ident>),
|
||||||
|
@ -755,6 +778,7 @@ pub enum JoinConstraint {
|
||||||
/// An `ORDER BY` expression
|
/// An `ORDER BY` expression
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct OrderByExpr {
|
pub struct OrderByExpr {
|
||||||
pub expr: Expr,
|
pub expr: Expr,
|
||||||
/// Optional `ASC` or `DESC`
|
/// Optional `ASC` or `DESC`
|
||||||
|
@ -782,6 +806,7 @@ impl fmt::Display for OrderByExpr {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Offset {
|
pub struct Offset {
|
||||||
pub value: Expr,
|
pub value: Expr,
|
||||||
pub rows: OffsetRows,
|
pub rows: OffsetRows,
|
||||||
|
@ -796,6 +821,7 @@ impl fmt::Display for Offset {
|
||||||
/// Stores the keyword after `OFFSET <number>`
|
/// Stores the keyword after `OFFSET <number>`
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum OffsetRows {
|
pub enum OffsetRows {
|
||||||
/// Omitting ROW/ROWS is non-standard MySQL quirk.
|
/// Omitting ROW/ROWS is non-standard MySQL quirk.
|
||||||
None,
|
None,
|
||||||
|
@ -815,6 +841,7 @@ impl fmt::Display for OffsetRows {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Fetch {
|
pub struct Fetch {
|
||||||
pub with_ties: bool,
|
pub with_ties: bool,
|
||||||
pub percent: bool,
|
pub percent: bool,
|
||||||
|
@ -835,6 +862,7 @@ impl fmt::Display for Fetch {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct LockClause {
|
pub struct LockClause {
|
||||||
pub lock_type: LockType,
|
pub lock_type: LockType,
|
||||||
pub of: Option<ObjectName>,
|
pub of: Option<ObjectName>,
|
||||||
|
@ -856,6 +884,7 @@ impl fmt::Display for LockClause {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum LockType {
|
pub enum LockType {
|
||||||
Share,
|
Share,
|
||||||
Update,
|
Update,
|
||||||
|
@ -873,6 +902,7 @@ impl fmt::Display for LockType {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum NonBlock {
|
pub enum NonBlock {
|
||||||
Nowait,
|
Nowait,
|
||||||
SkipLocked,
|
SkipLocked,
|
||||||
|
@ -890,6 +920,7 @@ impl fmt::Display for NonBlock {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Top {
|
pub struct Top {
|
||||||
/// SQL semantic equivalent of LIMIT but with same structure as FETCH.
|
/// SQL semantic equivalent of LIMIT but with same structure as FETCH.
|
||||||
pub with_ties: bool,
|
pub with_ties: bool,
|
||||||
|
@ -911,6 +942,7 @@ impl fmt::Display for Top {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Values {
|
pub struct Values {
|
||||||
/// Was there an explict ROWs keyword (MySQL)?
|
/// Was there an explict ROWs keyword (MySQL)?
|
||||||
/// <https://dev.mysql.com/doc/refman/8.0/en/values.html>
|
/// <https://dev.mysql.com/doc/refman/8.0/en/values.html>
|
||||||
|
@ -934,6 +966,7 @@ impl fmt::Display for Values {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct SelectInto {
|
pub struct SelectInto {
|
||||||
pub temporary: bool,
|
pub temporary: bool,
|
||||||
pub unlogged: bool,
|
pub unlogged: bool,
|
||||||
|
|
|
@ -16,12 +16,17 @@ use core::fmt;
|
||||||
|
|
||||||
#[cfg(feature = "bigdecimal")]
|
#[cfg(feature = "bigdecimal")]
|
||||||
use bigdecimal::BigDecimal;
|
use bigdecimal::BigDecimal;
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
use sqlparser_derive::Visit;
|
||||||
|
|
||||||
/// Primitive SQL values such as number and string
|
/// Primitive SQL values such as number and string
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
/// Numeric literal
|
/// Numeric literal
|
||||||
#[cfg(not(feature = "bigdecimal"))]
|
#[cfg(not(feature = "bigdecimal"))]
|
||||||
|
@ -68,6 +73,7 @@ impl fmt::Display for Value {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum DateTimeField {
|
pub enum DateTimeField {
|
||||||
Year,
|
Year,
|
||||||
Month,
|
Month,
|
||||||
|
@ -198,6 +204,7 @@ pub fn escape_escaped_string(s: &str) -> EscapeEscapedStringLiteral<'_> {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum TrimWhereField {
|
pub enum TrimWhereField {
|
||||||
Both,
|
Both,
|
||||||
Leading,
|
Leading,
|
||||||
|
|
301
src/ast/visitor.rs
Normal file
301
src/ast/visitor.rs
Normal file
|
@ -0,0 +1,301 @@
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::ast::{Expr, ObjectName, Statement};
|
||||||
|
use core::ops::ControlFlow;
|
||||||
|
|
||||||
|
/// A type that can be visited by a `visitor`
|
||||||
|
pub trait Visit {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Visit> Visit for Option<T> {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
if let Some(s) = self {
|
||||||
|
s.visit(visitor)?;
|
||||||
|
}
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Visit> Visit for Vec<T> {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
for v in self {
|
||||||
|
v.visit(visitor)?;
|
||||||
|
}
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Visit> Visit for Box<T> {
|
||||||
|
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
T::visit(self, visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! visit_noop {
|
||||||
|
($($t:ty),+) => {
|
||||||
|
$(impl Visit for $t {
|
||||||
|
fn visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
})+
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
visit_noop!(u8, u16, u32, u64, i8, i16, i32, i64, char, bool, String);
|
||||||
|
|
||||||
|
#[cfg(feature = "bigdecimal")]
|
||||||
|
visit_noop!(bigdecimal::BigDecimal);
|
||||||
|
|
||||||
|
/// A visitor that can be used to walk an AST tree
|
||||||
|
pub trait Visitor {
|
||||||
|
type Break;
|
||||||
|
|
||||||
|
/// Invoked for any relations (e.g. tables) that appear in the AST before visiting children
|
||||||
|
fn pre_visit_relation(&mut self, _relation: &ObjectName) -> ControlFlow<Self::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked for any relations (e.g. tables) that appear in the AST after visiting children
|
||||||
|
fn post_visit_relation(&mut self, _relation: &ObjectName) -> ControlFlow<Self::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked for any expressions that appear in the AST before visiting children
|
||||||
|
fn pre_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked for any expressions that appear in the AST
|
||||||
|
fn post_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked for any statements that appear in the AST before visiting children
|
||||||
|
fn pre_visit_statement(&mut self, _statement: &Statement) -> ControlFlow<Self::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked for any statements that appear in the AST after visiting children
|
||||||
|
fn post_visit_statement(&mut self, _statement: &Statement) -> ControlFlow<Self::Break> {
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RelationVisitor<F>(F);
|
||||||
|
|
||||||
|
impl<E, F: FnMut(&ObjectName) -> ControlFlow<E>> Visitor for RelationVisitor<F> {
|
||||||
|
type Break = E;
|
||||||
|
|
||||||
|
fn pre_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
|
||||||
|
self.0(relation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invokes the provided closure on all relations present in v
|
||||||
|
pub fn visit_relations<V, E, F>(v: &V, f: F) -> ControlFlow<E>
|
||||||
|
where
|
||||||
|
V: Visit,
|
||||||
|
F: FnMut(&ObjectName) -> ControlFlow<E>,
|
||||||
|
{
|
||||||
|
let mut visitor = RelationVisitor(f);
|
||||||
|
v.visit(&mut visitor)?;
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ExprVisitor<F>(F);
|
||||||
|
|
||||||
|
impl<E, F: FnMut(&Expr) -> ControlFlow<E>> Visitor for ExprVisitor<F> {
|
||||||
|
type Break = E;
|
||||||
|
|
||||||
|
fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
|
||||||
|
self.0(expr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invokes the provided closure on all expressions present in v
|
||||||
|
pub fn visit_expressions<V, E, F>(v: &V, f: F) -> ControlFlow<E>
|
||||||
|
where
|
||||||
|
V: Visit,
|
||||||
|
F: FnMut(&Expr) -> ControlFlow<E>,
|
||||||
|
{
|
||||||
|
let mut visitor = ExprVisitor(f);
|
||||||
|
v.visit(&mut visitor)?;
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StatementVisitor<F>(F);
|
||||||
|
|
||||||
|
impl<E, F: FnMut(&Statement) -> ControlFlow<E>> Visitor for StatementVisitor<F> {
|
||||||
|
type Break = E;
|
||||||
|
|
||||||
|
fn pre_visit_statement(&mut self, statement: &Statement) -> ControlFlow<Self::Break> {
|
||||||
|
self.0(statement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invokes the provided closure on all statements present in v
|
||||||
|
pub fn visit_statements<V, E, F>(v: &V, f: F) -> ControlFlow<E>
|
||||||
|
where
|
||||||
|
V: Visit,
|
||||||
|
F: FnMut(&Statement) -> ControlFlow<E>,
|
||||||
|
{
|
||||||
|
let mut visitor = StatementVisitor(f);
|
||||||
|
v.visit(&mut visitor)?;
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::dialect::GenericDialect;
|
||||||
|
use crate::parser::Parser;
|
||||||
|
use crate::tokenizer::Tokenizer;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct TestVisitor {
|
||||||
|
visited: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitor for TestVisitor {
|
||||||
|
type Break = ();
|
||||||
|
|
||||||
|
fn pre_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
|
||||||
|
self.visited.push(format!("PRE: RELATION: {}", relation));
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn post_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
|
||||||
|
self.visited.push(format!("POST: RELATION: {}", relation));
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
|
||||||
|
self.visited.push(format!("PRE: EXPR: {}", expr));
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn post_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
|
||||||
|
self.visited.push(format!("POST: EXPR: {}", expr));
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pre_visit_statement(&mut self, statement: &Statement) -> ControlFlow<Self::Break> {
|
||||||
|
self.visited.push(format!("PRE: STATEMENT: {}", statement));
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn post_visit_statement(&mut self, statement: &Statement) -> ControlFlow<Self::Break> {
|
||||||
|
self.visited.push(format!("POST: STATEMENT: {}", statement));
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_visit(sql: &str) -> Vec<String> {
|
||||||
|
let dialect = GenericDialect {};
|
||||||
|
let mut tokenizer = Tokenizer::new(&dialect, sql);
|
||||||
|
let tokens = tokenizer.tokenize().unwrap();
|
||||||
|
let s = Parser::new(&dialect)
|
||||||
|
.with_tokens(tokens)
|
||||||
|
.parse_statement()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut visitor = TestVisitor::default();
|
||||||
|
s.visit(&mut visitor);
|
||||||
|
visitor.visited
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sql() {
|
||||||
|
let tests = vec![
|
||||||
|
(
|
||||||
|
"SELECT * from table_name",
|
||||||
|
vec![
|
||||||
|
"PRE: STATEMENT: SELECT * FROM table_name",
|
||||||
|
"PRE: RELATION: table_name",
|
||||||
|
"POST: RELATION: table_name",
|
||||||
|
"POST: STATEMENT: SELECT * FROM table_name",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"SELECT * from t1 join t2 on t1.id = t2.t1_id",
|
||||||
|
vec![
|
||||||
|
"PRE: STATEMENT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id",
|
||||||
|
"PRE: RELATION: t1",
|
||||||
|
"POST: RELATION: t1",
|
||||||
|
"PRE: RELATION: t2",
|
||||||
|
"POST: RELATION: t2",
|
||||||
|
"PRE: EXPR: t1.id = t2.t1_id",
|
||||||
|
"PRE: EXPR: t1.id",
|
||||||
|
"POST: EXPR: t1.id",
|
||||||
|
"PRE: EXPR: t2.t1_id",
|
||||||
|
"POST: EXPR: t2.t1_id",
|
||||||
|
"POST: EXPR: t1.id = t2.t1_id",
|
||||||
|
"POST: STATEMENT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"SELECT * from t1 where EXISTS(SELECT column from t2)",
|
||||||
|
vec![
|
||||||
|
"PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
|
||||||
|
"PRE: RELATION: t1",
|
||||||
|
"POST: RELATION: t1",
|
||||||
|
"PRE: EXPR: EXISTS (SELECT column FROM t2)",
|
||||||
|
"PRE: EXPR: column",
|
||||||
|
"POST: EXPR: column",
|
||||||
|
"PRE: RELATION: t2",
|
||||||
|
"POST: RELATION: t2",
|
||||||
|
"POST: EXPR: EXISTS (SELECT column FROM t2)",
|
||||||
|
"POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"SELECT * from t1 where EXISTS(SELECT column from t2)",
|
||||||
|
vec![
|
||||||
|
"PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
|
||||||
|
"PRE: RELATION: t1",
|
||||||
|
"POST: RELATION: t1",
|
||||||
|
"PRE: EXPR: EXISTS (SELECT column FROM t2)",
|
||||||
|
"PRE: EXPR: column",
|
||||||
|
"POST: EXPR: column",
|
||||||
|
"PRE: RELATION: t2",
|
||||||
|
"POST: RELATION: t2",
|
||||||
|
"POST: EXPR: EXISTS (SELECT column FROM t2)",
|
||||||
|
"POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"SELECT * from t1 where EXISTS(SELECT column from t2) UNION SELECT * from t3",
|
||||||
|
vec![
|
||||||
|
"PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3",
|
||||||
|
"PRE: RELATION: t1",
|
||||||
|
"POST: RELATION: t1",
|
||||||
|
"PRE: EXPR: EXISTS (SELECT column FROM t2)",
|
||||||
|
"PRE: EXPR: column",
|
||||||
|
"POST: EXPR: column",
|
||||||
|
"PRE: RELATION: t2",
|
||||||
|
"POST: RELATION: t2",
|
||||||
|
"POST: EXPR: EXISTS (SELECT column FROM t2)",
|
||||||
|
"PRE: RELATION: t3",
|
||||||
|
"POST: RELATION: t3",
|
||||||
|
"POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (sql, expected) in tests {
|
||||||
|
let actual = do_visit(sql);
|
||||||
|
let actual: Vec<_> = actual.iter().map(|x| x.as_str()).collect();
|
||||||
|
assert_eq!(actual, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,9 @@
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
use sqlparser_derive::Visit;
|
||||||
|
|
||||||
/// Defines a string constant for a single keyword: `kw_def!(SELECT);`
|
/// Defines a string constant for a single keyword: `kw_def!(SELECT);`
|
||||||
/// expands to `pub const SELECT = "SELECT";`
|
/// expands to `pub const SELECT = "SELECT";`
|
||||||
macro_rules! kw_def {
|
macro_rules! kw_def {
|
||||||
|
@ -46,6 +49,7 @@ macro_rules! define_keywords {
|
||||||
),*) => {
|
),*) => {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub enum Keyword {
|
pub enum Keyword {
|
||||||
NoKeyword,
|
NoKeyword,
|
||||||
|
|
|
@ -40,6 +40,9 @@
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
#![allow(clippy::upper_case_acronyms)]
|
#![allow(clippy::upper_case_acronyms)]
|
||||||
|
|
||||||
|
// Allow proc-macros to find this crate
|
||||||
|
extern crate self as sqlparser;
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,9 @@ use core::str::Chars;
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "visitor")]
|
||||||
|
use sqlparser_derive::Visit;
|
||||||
|
|
||||||
use crate::dialect::SnowflakeDialect;
|
use crate::dialect::SnowflakeDialect;
|
||||||
use crate::dialect::{Dialect, MySqlDialect};
|
use crate::dialect::{Dialect, MySqlDialect};
|
||||||
use crate::keywords::{Keyword, ALL_KEYWORDS, ALL_KEYWORDS_INDEX};
|
use crate::keywords::{Keyword, ALL_KEYWORDS, ALL_KEYWORDS_INDEX};
|
||||||
|
@ -38,6 +41,7 @@ use crate::keywords::{Keyword, ALL_KEYWORDS, ALL_KEYWORDS_INDEX};
|
||||||
/// SQL Token enumeration
|
/// SQL Token enumeration
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
/// An end-of-file marker, not a real token
|
/// An end-of-file marker, not a real token
|
||||||
EOF,
|
EOF,
|
||||||
|
@ -264,6 +268,7 @@ impl Token {
|
||||||
/// A keyword (like SELECT) or an optionally quoted SQL identifier
|
/// A keyword (like SELECT) or an optionally quoted SQL identifier
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub struct Word {
|
pub struct Word {
|
||||||
/// The value of the token, without the enclosing quotes, and with the
|
/// The value of the token, without the enclosing quotes, and with the
|
||||||
/// escape sequences (if any) processed (TODO: escapes are not handled)
|
/// escape sequences (if any) processed (TODO: escapes are not handled)
|
||||||
|
@ -302,6 +307,7 @@ impl Word {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit))]
|
||||||
pub enum Whitespace {
|
pub enum Whitespace {
|
||||||
Space,
|
Space,
|
||||||
Newline,
|
Newline,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue