Skip to content

Commit

Permalink
Merge branch 'main' into ast-visitor
Browse files Browse the repository at this point in the history
  • Loading branch information
lovasoa committed Oct 5, 2022
2 parents 4507be8 + f7f14df commit 5effedd
Show file tree
Hide file tree
Showing 9 changed files with 392 additions and 88 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@ Given that the parser produces a typed AST, any changes to the AST will technica
## [Unreleased]
Check https://github.com/sqlparser-rs/sqlparser-rs/commits/main for undocumented changes.

## [0.25.0] 2022-10-03

### Added

* Support `AUTHORIZATION` clause in `CREATE SCHEMA` statements (#646) - Thanks @AugustoFKL
* Support optional precision for `CLOB` and `BLOB` (#639) - Thanks @AugustoFKL
* Support optional precision in `VARBINARY` and `BINARY` (#637) - Thanks @AugustoFKL


### Changed
* `TIMESTAMP` and `TIME` parsing preserve zone information (#646) - Thanks @AugustoFKL

### Fixed

* Correct order of arguments when parsing `LIMIT x,y` , restrict to `MySql` and `Generic` dialects - Thanks @AugustoFKL


## [0.24.0] 2022-09-29

### Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "sqlparser"
description = "Extensible SQL Lexer and Parser with support for ANSI SQL:2011"
version = "0.24.0"
version = "0.25.0"
authors = ["Andy Grove <andygrove73@gmail.com>"]
homepage = "https://github.com/sqlparser-rs/sqlparser-rs"
documentation = "https://docs.rs/sqlparser/"
Expand Down
115 changes: 93 additions & 22 deletions src/ast/data_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,40 @@ use super::value::escape_single_quote_string;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))]
pub enum DataType {
/// Fixed-length character type e.g. CHAR(10)
/// Fixed-length character type e.g. CHARACTER(10)
Character(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Fixed-length char type e.g. CHAR(10)
Char(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Character varying type e.g. CHARACTER VARYING(10)
CharacterVarying(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Char varying type e.g. CHAR VARYING(10)
CharVarying(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Variable-length character type e.g. VARCHAR(10)
Varchar(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Variable-length character type e.g. NVARCHAR(10)
Nvarchar(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Uuid type
Uuid,
/// Large character object e.g. CLOB(1000)
Clob(#[cfg_attr(feature = "derive-visitor", drive(skip))] u64),
/// Fixed-length binary type e.g. BINARY(10)
Binary(#[cfg_attr(feature = "derive-visitor", drive(skip))] u64),
/// Variable-length binary type e.g. VARBINARY(10)
Varbinary(#[cfg_attr(feature = "derive-visitor", drive(skip))] u64),
/// Large binary object e.g. BLOB(1000)
Blob(#[cfg_attr(feature = "derive-visitor", drive(skip))] u64),
/// Large character object with optional length e.g. CLOB, CLOB(1000), [standard], [Oracle]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type
/// [Oracle]: https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html
Clob(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Fixed-length binary type with optional length e.g. [standard], [MS SQL Server]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
/// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16
Binary(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Variable-length binary with optional length type e.g. [standard], [MS SQL Server]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
/// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16
Varbinary(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Large binary object with optional length e.g. BLOB, BLOB(1000), [standard], [Oracle]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-large-object-string-type
/// [Oracle]: https://docs.oracle.com/javadb/10.8.3.0/ref/rrefblob.html
Blob(#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>),
/// Decimal type with optional precision and scale e.g. DECIMAL(10,2)
Decimal(
#[cfg_attr(feature = "derive-visitor", drive(skip))] Option<u64>,
Expand Down Expand Up @@ -94,13 +112,11 @@ pub enum DataType {
/// Date
Date,
/// Time
Time,
Time(#[cfg_attr(feature = "derive-visitor", drive(skip))] TimezoneInfo),
/// Datetime
Datetime,
/// Timestamp [Without Time Zone]
Timestamp,
/// Timestamp With Time Zone
TimestampTz,
/// Timestamp
Timestamp(#[cfg_attr(feature = "derive-visitor", drive(skip))] TimezoneInfo),
/// Interval
Interval,
/// Regclass used in postgresql serial
Expand All @@ -124,18 +140,27 @@ pub enum DataType {
impl fmt::Display for DataType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DataType::Character(size) => {
format_type_with_optional_length(f, "CHARACTER", size, false)
}
DataType::Char(size) => format_type_with_optional_length(f, "CHAR", size, false),
DataType::Varchar(size) => {
DataType::CharacterVarying(size) => {
format_type_with_optional_length(f, "CHARACTER VARYING", size, false)
}
DataType::CharVarying(size) => {
format_type_with_optional_length(f, "CHAR VARYING", size, false)
}
DataType::Varchar(size) => format_type_with_optional_length(f, "VARCHAR", size, false),
DataType::Nvarchar(size) => {
format_type_with_optional_length(f, "NVARCHAR", size, false)
}
DataType::Uuid => write!(f, "UUID"),
DataType::Clob(size) => write!(f, "CLOB({})", size),
DataType::Binary(size) => write!(f, "BINARY({})", size),
DataType::Varbinary(size) => write!(f, "VARBINARY({})", size),
DataType::Blob(size) => write!(f, "BLOB({})", size),
DataType::Clob(size) => format_type_with_optional_length(f, "CLOB", size, false),
DataType::Binary(size) => format_type_with_optional_length(f, "BINARY", size, false),
DataType::Varbinary(size) => {
format_type_with_optional_length(f, "VARBINARY", size, false)
}
DataType::Blob(size) => format_type_with_optional_length(f, "BLOB", size, false),
DataType::Decimal(precision, scale) => {
if let Some(scale) = scale {
write!(f, "NUMERIC({},{})", precision.unwrap(), scale)
Expand Down Expand Up @@ -183,10 +208,9 @@ impl fmt::Display for DataType {
DataType::DoublePrecision => write!(f, "DOUBLE PRECISION"),
DataType::Boolean => write!(f, "BOOLEAN"),
DataType::Date => write!(f, "DATE"),
DataType::Time => write!(f, "TIME"),
DataType::Time(timezone_info) => write!(f, "TIME{}", timezone_info),
DataType::Datetime => write!(f, "DATETIME"),
DataType::Timestamp => write!(f, "TIMESTAMP"),
DataType::TimestampTz => write!(f, "TIMESTAMPTZ"),
DataType::Timestamp(timezone_info) => write!(f, "TIMESTAMP{}", timezone_info),
DataType::Interval => write!(f, "INTERVAL"),
DataType::Regclass => write!(f, "REGCLASS"),
DataType::Text => write!(f, "TEXT"),
Expand Down Expand Up @@ -233,3 +257,50 @@ fn format_type_with_optional_length(
}
Ok(())
}

/// Timestamp and Time data types information about TimeZone formatting.
///
/// This is more related to a display information than real differences between each variant. To
/// guarantee compatibility with the input query we must maintain its exact information.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TimezoneInfo {
/// No information about time zone. E.g., TIMESTAMP
None,
/// Temporal type 'WITH TIME ZONE'. E.g., TIMESTAMP WITH TIME ZONE, [standard], [Oracle]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type
/// [Oracle]: https://docs.oracle.com/en/database/oracle/oracle-database/12.2/nlspg/datetime-data-types-and-time-zone-support.html#GUID-3F1C388E-C651-43D5-ADBC-1A49E5C2CA05
WithTimeZone,
/// Temporal type 'WITHOUT TIME ZONE'. E.g., TIME WITHOUT TIME ZONE, [standard], [Postgresql]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type
/// [Postgresql]: https://www.postgresql.org/docs/current/datatype-datetime.html
WithoutTimeZone,
/// Postgresql specific `WITH TIME ZONE` formatting, for both TIME and TIMESTAMP. E.g., TIMETZ, [Postgresql]
///
/// [Postgresql]: https://www.postgresql.org/docs/current/datatype-datetime.html
Tz,
}

impl fmt::Display for TimezoneInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TimezoneInfo::None => {
write!(f, "")
}
TimezoneInfo::WithTimeZone => {
write!(f, " WITH TIME ZONE")
}
TimezoneInfo::WithoutTimeZone => {
write!(f, " WITHOUT TIME ZONE")
}
TimezoneInfo::Tz => {
// TZ is the only one that is displayed BEFORE the precision, so the datatype display
// must be aware of that. Check <https://www.postgresql.org/docs/14/datatype-datetime.html>
// for more information
write!(f, "TZ")
}
}
}
}
35 changes: 34 additions & 1 deletion src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub use derive_visitor::{
};

pub use self::data_type::DataType;
pub use self::data_type::TimezoneInfo;
pub use self::ddl::{
AlterColumnOperation, AlterTableOperation, ColumnDef, ColumnOption, ColumnOptionDef,
ReferentialAction, TableConstraint,
Expand Down Expand Up @@ -1406,7 +1407,8 @@ pub enum Statement {
},
/// CREATE SCHEMA
CreateSchema {
schema_name: ObjectName,
/// `<schema name> | AUTHORIZATION <schema authorization identifier> | <schema name> AUTHORIZATION <schema authorization identifier>`
schema_name: SchemaName,
#[cfg_attr(feature = "derive-visitor", drive(skip))]
if_not_exists: bool,
},
Expand Down Expand Up @@ -3446,6 +3448,37 @@ impl fmt::Display for CreateFunctionUsing {
}
}

/// Schema possible naming variants ([1]).
///
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "derive-visitor", derive(Drive, DriveMut))]
pub enum SchemaName {
/// Only schema name specified: `<schema name>`.
Simple(ObjectName),
/// Only authorization identifier specified: `AUTHORIZATION <schema authorization identifier>`.
UnnamedAuthorization(Ident),
/// Both schema name and authorization identifier specified: `<schema name> AUTHORIZATION <schema authorization identifier>`.
NamedAuthorization(ObjectName, Ident),
}

impl fmt::Display for SchemaName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SchemaName::Simple(name) => {
write!(f, "{name}")
}
SchemaName::UnnamedAuthorization(authorization) => {
write!(f, "AUTHORIZATION {authorization}")
}
SchemaName::NamedAuthorization(name, authorization) => {
write!(f, "{name} AUTHORIZATION {authorization}")
}
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
1 change: 1 addition & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ define_keywords!(
TIME,
TIMESTAMP,
TIMESTAMPTZ,
TIMETZ,
TIMEZONE,
TIMEZONE_HOUR,
TIMEZONE_MINUTE,
Expand Down
Loading

0 comments on commit 5effedd

Please sign in to comment.