Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge upstream #28

Merged
merged 111 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
2296de2
Add fn support_group_by_expr to Dialect trait (#896)
jdye64 Jun 15, 2023
75f18ec
Add support for DuckDB's CREATE MACRO statements (#897)
MartinNowak Jun 21, 2023
f72b5a5
Support basic CREATE PROCEDURE of MSSQL (#900)
delsehi Jun 22, 2023
8877cba
fix: unary negation operator with operators: `Mul`, `Div` and `Mod` (…
izveigor Jun 22, 2023
04c9fba
update parse STRICT tables (#903)
parkma99 Jun 23, 2023
631edda
Update CHANGELOG.md for version `0.35.0` (#904)
alamb Jun 23, 2023
efd8cb7
chore: Release sqlparser version 0.35.0
alamb Jun 23, 2023
9effeba
feat: add deltalake keywords (#906)
roeap Jun 29, 2023
f05f71e
Support `ALTER VIEW`, MySQL syntax (#907)
liadgiladi Jun 29, 2023
20ac38b
Support multi args for unnest (#909)
jayzhan211 Jun 30, 2023
a50671d
feat: support PGOverlap operator (#912)
izveigor Jul 6, 2023
4efe55d
Remove most instances of `#[cfg(feature(bigdecimal))]` in tests (#910)
alamb Jul 17, 2023
653346c
Upgrade bigdecimal to 0.4.1 (#921)
jinlee0 Jul 17, 2023
d6ebb58
Fix dependabot by removing rust-toolchain toml (#922)
alamb Jul 17, 2023
c8b6e7f
feat: comments for all operators (#917)
izveigor Jul 17, 2023
df45db1
fix: parsing `JsonOperator` (#913)
izveigor Jul 17, 2023
c454518
Clean up JSON operator tokenizing code (#923)
alamb Jul 17, 2023
eb28848
Support UNION (ALL) BY NAME syntax (#915)
parkma99 Jul 18, 2023
f98a2f9
feat: mysql no-escape mode (#870)
canalun Jul 19, 2023
a452054
CHANGELOG for 0.36.0 (#924)
alamb Jul 19, 2023
e36b34d
chore: Release sqlparser version 0.36.0
alamb Jul 19, 2023
3a41215
fix parsing of identifiers after `%` symbol (#927)
alamb Jul 21, 2023
91ef061
Changelog for 0.36.1 (#928)
alamb Jul 21, 2023
f60a6f7
chore: Release sqlparser version 0.36.1
alamb Jul 21, 2023
53593f1
Fix parsing of datetime functions without parenthesis (#930)
lovasoa Jul 26, 2023
0ddb853
feat: support pg type alias (#933)
Kikkon Jul 27, 2023
10a6ec5
Fix "BEGIN TRANSACTION" being serialized as "START TRANSACTION" (#935)
lovasoa Jul 27, 2023
eb4be98
Support `DROP TEMPORARY TABLE`, MySQL syntax (#916)
liadgiladi Aug 7, 2023
173a6db
Fix: use Rust idiomatic capitalization for newly added `DataType` enu…
Kikkon Aug 7, 2023
8bbb853
Fix SUBSTRING from/to argument construction for mssql (#947)
jmaness Aug 17, 2023
83e3067
Add support for table-level comments (#946)
ehoeve Aug 17, 2023
a7d2858
Minor: clarify the value of the special flag (#948)
alamb Aug 17, 2023
a49ea19
feat: add `ALTER ROLE` syntax of PostgreSQL and MS SQL Server (#942)
r4ntix Aug 17, 2023
9a39afb
feat: support more Postgres index syntax (#943)
ForbesLindesay Aug 17, 2023
41e47cc
add a test for mssql table name in square brackets (#952)
lovasoa Aug 21, 2023
9500649
Add support for MySQL auto_increment offset (#950)
ehoeve Aug 21, 2023
1ea8858
Table time travel clause support, add `visit_table_factor` to Visitor…
gruuya Aug 22, 2023
a2533c2
Changelog for version 0.37.0 (#953)
alamb Aug 22, 2023
b8a58bb
chore: Release sqlparser version 0.37.0
alamb Aug 22, 2023
9c2e8bc
Break test and coverage test into separate jobs (#949)
alamb Aug 22, 2023
4a2fa66
[cli] add --sqlite param (#956)
ddol Aug 25, 2023
14da37d
Fix Rust 1.72 clippy lints (#957)
alamb Aug 25, 2023
4c3a4ad
Update release documentation (#954)
alamb Aug 25, 2023
b02c3f8
feat: show location info in parse errors (#958)
MartinNowak Sep 7, 2023
e0afd4b
`ANY` and `ALL` contains their operators (#963)
SeanTroyUWO Sep 7, 2023
25e037c
feat: allow multiple actions in one `ALTER TABLE` statement (#960)
ForbesLindesay Sep 7, 2023
2593dcf
Add missing token loc in parse err msg (#965)
ding-young Sep 8, 2023
bb7b05e
feat: Group By All (#964)
berkaysynnada Sep 8, 2023
0480ee9
feat: Add support for parsing the syntax of MySQL UNIQUE KEY. (#962)
artorias1024 Sep 8, 2023
a16791d
Support `UNNEST` as a table factor for PostgreSQL (#968)
hexedpackets Sep 14, 2023
f6e4be4
Support mysql `partition` to table selection (#959)
chunshao90 Sep 14, 2023
71c35d4
Add support for == operator for Sqlite (#970)
marhoily Sep 20, 2023
521ffa9
Changelog for 0.38.0 release (#973)
alamb Sep 21, 2023
7723ea5
chore: Release sqlparser version 0.38.0
alamb Sep 21, 2023
495d0a0
Add support for ATTACH DATABASE (#989)
lovasoa Oct 2, 2023
e718ce6
bigquery: EXTRACT support For DAYOFWEEK, DAYOFYEAR, ISOWEEK, TIME (#…
lustefaniak Oct 2, 2023
4903bd4
Add test for clickhouse: tokenize `==` as Token::DoubleEq (#981)
lustefaniak Oct 2, 2023
ed39329
Add JumpWire to users in README (#990)
hexedpackets Oct 2, 2023
6ffc3b3
Support DELETE with ORDER BY and LIMIT (MySQL) (#992)
ulrichsg Oct 2, 2023
993769e
Add support for mixed BigQuery table name quoting (#971)
iffyio Oct 2, 2023
2786c7e
clickhouse: add support for LIMIT BY (#977)
lustefaniak Oct 2, 2023
40e2ecb
snowflake: support for UNPIVOT and a fix for chained PIVOTs (#983)
jmhain Oct 2, 2023
c811e22
redshift: add support for CREATE VIEW … WITH NO SCHEMA BINDING (#979)
lustefaniak Oct 2, 2023
02f3d78
Fix for clippy 1.73 (#995)
alamb Oct 5, 2023
5263da6
Handle CREATE [TEMPORARY|TEMP] VIEW [IF NOT EXISTS] (#993)
gabivlj Oct 5, 2023
83cb734
Support Snowflake/BigQuery TRIM. (#975)
zdenal Oct 6, 2023
c68e977
Support bigquery `CAST AS x [STRING|DATE] FORMAT` syntax (#978)
lustefaniak Oct 20, 2023
88510f6
fix column `COLLATE` not displayed (#1012)
lustefaniak Oct 20, 2023
c03586b
Support mysql `RLIKE` and `REGEXP` binary operators (#1017)
lovasoa Oct 20, 2023
5c10668
Add support for UNION DISTINCT BY NAME syntax (#997)
alexander-beedie Oct 23, 2023
56f24ce
Support subquery as function arg w/o parens in Snowflake dialect (#996)
jmhain Oct 23, 2023
e857a45
Support `SELECT * EXCEPT/REPLACE` syntax from ClickHouse (#1013)
lustefaniak Oct 23, 2023
ce62fe6
Support `FILTER` in over clause (#1007)
lovasoa Oct 23, 2023
2798b65
snowflake/generic: `position` can be the name of a column (#1022)
alamb Oct 23, 2023
8b2a248
parse SQLite pragma statement (#969)
marhoily Oct 23, 2023
6739d37
Add docstrings for `Dialect`s, update README (#1016)
alamb Oct 23, 2023
86aa1b9
Support `INSERT IGNORE` in `MySql` and `GenericDialect` (#1004)
emin100 Oct 24, 2023
5709053
Test that `regexp` can be used as an identifier in postgres (#1018)
lovasoa Oct 24, 2023
9832adb
Support "with" identifiers surrounded by backticks in `GenericDialect…
bitemyapp Oct 24, 2023
004a8dc
Support multiple `PARTITION` statements in `ALTER TABLE ADD` statemen…
bitemyapp Oct 24, 2023
c5a7d6c
Support for single-quoted identifiers (#1021)
lovasoa Oct 24, 2023
8262abc
Improve documentation on Parser::consume_token and friends (#994)
alamb Oct 24, 2023
b89edaa
Support `IGNORE|RESPECT` NULLs clause in window functions (#998)
yuval-illumex Oct 24, 2023
7993384
Support `date` 'key' when using semi structured data (#1023)
yuval-illumex Oct 24, 2023
65317ed
Support Snowflake - allow number as placeholder (e.g. `:1`) (#1001)
yuval-illumex Oct 25, 2023
2f437db
Support for BigQuery `struct`, `array` and `bytes` , `int64`, `float…
iffyio Oct 25, 2023
7b3cc18
snowflake: Fix handling of `/~%` in the stage name (#1009)
lustefaniak Oct 26, 2023
8164b7c
common: Make sure + - * / % binary operators work the same in all dia…
lustefaniak Oct 27, 2023
254ccfb
snowflake: add support for LATERAL FLATTEN and similar (#1026)
lustefaniak Oct 27, 2023
cf37c01
CHANGELOG for 0.39.0 release (#1029)
alamb Oct 27, 2023
2f0c99c
chore: Release sqlparser version 0.39.0
alamb Oct 27, 2023
4cdaa40
Support `IN ()` syntax of SQLite, alternate proposal (#1028)
alamb Oct 29, 2023
ff8312b
add support for MAX as a character length (#1038)
lovasoa Nov 10, 2023
953c833
Support mssql json and xml extensions (#1043)
lovasoa Nov 18, 2023
c887c4e
Add PRQLto list of users (#1031)
vanillajonathan Nov 18, 2023
5a3f193
Fix extra whitespace printed before `ON CONFLICT` (#1037)
CDThomas Nov 20, 2023
dc2ceed
snowflake: PIVOT on derived table factors (#1027)
lustefaniak Nov 20, 2023
c0c2d58
Support global and session parts in show variables for mysql and gene…
emin100 Nov 20, 2023
c905ee0
Support `CONVERT` expressions (#1048)
lovasoa Nov 20, 2023
5bdf2e6
Add support for release and rollback to savepoint syntax (#1045)
CDThomas Nov 21, 2023
3d2773a
Support `INSERT INTO ... DEFAULT VALUES ...` (#1036)
CDThomas Nov 21, 2023
541d684
Adds support for PostgreSQL "END" (#1035)
tobyhede Nov 21, 2023
640b939
Add support for generated virtual columns with expression (#1051)
takluyver Nov 22, 2023
86aa044
add {pre,post}_visit_query to Visitor (#1044)
jmhain Nov 27, 2023
64eccdb
Document round trip ability (#1052)
alamb Nov 27, 2023
a765146
Prepare for `0.40.0` release, derive `0.2.0` release (#1053)
alamb Nov 27, 2023
b69aed9
Update sqlparser-derive version (#1055)
alamb Nov 27, 2023
28e0a7c
Update sqlparser to version `0.40.0` (#1056)
alamb Nov 27, 2023
8d97330
Update sqlparser-derive to use `syn 2.0` (#1040)
serprex Nov 27, 2023
95f587b
Merge remote-tracking branch 'upstream/main' into v40
serprex Dec 9, 2023
5ee679f
cargo fmt
serprex Dec 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rust 1.73.0
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,29 @@ 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.40.0] 2023-11-27

### Added
* Add `{pre,post}_visit_query` to `Visitor` (#1044) - Thanks @jmhain
* Support generated virtual columns with expression (#1051) - Thanks @takluyver
* Support PostgreSQL `END` (#1035) - Thanks @tobyhede
* Support `INSERT INTO ... DEFAULT VALUES ...` (#1036) - Thanks @CDThomas
* Support `RELEASE` and `ROLLBACK TO SAVEPOINT` (#1045) - Thanks @CDThomas
* Support `CONVERT` expressions (#1048) - Thanks @lovasoa
* Support `GLOBAL` and `SESSION` parts in `SHOW VARIABLES` for mysql and generic - Thanks @emin100
* Support snowflake `PIVOT` on derived table factors (#1027) - Thanks @lustefaniak
* Support mssql json and xml extensions (#1043) - Thanks @lovasoa
* Support for `MAX` as a character length (#1038) - Thanks @lovasoa
* Support `IN ()` syntax of SQLite (#1028) - Thanks @alamb

### Fixed
* Fix extra whitespace printed before `ON CONFLICT` (#1037) - Thanks @CDThomas

### Changed
* Document round trip ability (#1052) - Thanks @alamb
* Add PRQL to list of users (#1031) - Thanks @vanillajonathan

## [0.39.0] 2023-10-27

### Added
Expand Down
4 changes: 2 additions & 2 deletions 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.39.0"
version = "0.40.0"
authors = ["Andy Grove <[email protected]>"]
homepage = "https://github.com/sqlparser-rs/sqlparser-rs"
documentation = "https://docs.rs/sqlparser/"
Expand Down Expand Up @@ -34,7 +34,7 @@ serde = { version = "1.0", features = ["derive"], optional = true }
# of dev-dependencies because of
# https://github.com/rust-lang/cargo/issues/1596
serde_json = { version = "1.0", optional = true }
sqlparser_derive = { version = "0.1.1", path = "derive", optional = true }
sqlparser_derive = { version = "0.2.0", path = "derive", optional = true }

[dev-dependencies]
simple_logger = "4.0"
Expand Down
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,28 @@ This crate avoids semantic analysis because it varies drastically
between dialects and implementations. If you want to do semantic
analysis, feel free to use this project as a base.

## Preserves Syntax Round Trip

This crate allows users to recover the original SQL text (with normalized
whitespace and keyword capitalization), which is useful for tools that
analyze and manipulate SQL.

This means that other than whitespace and the capitalization of keywords, the
following should hold true for all SQL:

```rust
// Parse SQL
let ast = Parser::parse_sql(&GenericDialect, sql).unwrap();

// The original SQL text can be generated from the AST
assert_eq!(ast[0].to_string(), sql);
```

There are still some cases in this crate where different SQL with seemingly
similar semantics are represented with the same AST. We welcome PRs to fix such
issues and distinguish different syntaxes in the AST.


## SQL compliance

SQL was first standardized in 1987, and revisions of the standard have been
Expand Down Expand Up @@ -93,7 +115,7 @@ $ cargo run --features json_example --example cli FILENAME.sql [--dialectname]
## Users

This parser is currently being used by the [DataFusion] query engine,
[LocustDB], [Ballista], [GlueSQL], [Opteryx], and [JumpWire].
[LocustDB], [Ballista], [GlueSQL], [Opteryx], [PRQL], and [JumpWire].

If your project is using sqlparser-rs feel free to make a PR to add it
to this list.
Expand Down Expand Up @@ -188,6 +210,7 @@ licensed as above, without any additional terms or conditions.
[Ballista]: https://github.com/apache/arrow-ballista
[GlueSQL]: https://github.com/gluesql/gluesql
[Opteryx]: https://github.com/mabel-dev/opteryx
[PRQL]: https://github.com/PRQL/prql
[JumpWire]: https://github.com/extragoodlabs/jumpwire
[Pratt Parser]: https://tdop.github.io/
[sql-2016-grammar]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html
Expand Down
4 changes: 2 additions & 2 deletions derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "sqlparser_derive"
description = "proc macro for sqlparser"
version = "0.1.1"
version = "0.2.1"
authors = ["sqlparser-rs authors"]
homepage = "https://github.com/sqlparser-rs/sqlparser-rs"
documentation = "https://docs.rs/sqlparser_derive/"
Expand All @@ -18,6 +18,6 @@ edition = "2021"
proc-macro = true

[dependencies]
syn = "1.0"
syn = { version = "2.0", default-features = false, features = ["printing", "parsing", "derive", "proc-macro"] }
proc-macro2 = "1.0"
quote = "1.0"
93 changes: 81 additions & 12 deletions derive/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,33 +48,102 @@ impl Visit for Bar {
}
```

Additionally certain types may wish to call a corresponding method on visitor before recursing
Some types may wish to call a corresponding method on the visitor:

```rust
#[derive(Visit, VisitMut)]
#[visit(with = "visit_expr")]
enum Expr {
A(),
B(String, #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] ObjectName, bool),
IsNull(Box<Expr>),
..
}
```

Will generate
This will result in the following sequence of visitor calls when an `IsNull`
expression is visited

```
visitor.pre_visit_expr(<is null expr>)
visitor.pre_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null expr>)
```

For some types it is only appropriate to call a particular visitor method in
some contexts. For example, not every `ObjectName` refers to a relation.

In these cases, the `visit` attribute can be used on the field for which we'd
like to call the method:

```rust
impl Visit for Bar {
#[derive(Visit, VisitMut)]
#[visit(with = "visit_table_factor")]
pub enum TableFactor {
Table {
#[visit(with = "visit_relation")]
name: ObjectName,
alias: Option<TableAlias>,
},
..
}
```

This will generate

```rust
impl Visit for TableFactor {
fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
visitor.visit_expr(self)?;
visitor.pre_visit_table_factor(self)?;
match self {
Self::A() => {}
Self::B(_1, _2, _3) => {
_1.visit(visitor)?;
visitor.visit_relation(_3)?;
_2.visit(visitor)?;
_3.visit(visitor)?;
Self::Table { name, alias } => {
visitor.pre_visit_relation(name)?;
alias.visit(name)?;
visitor.post_visit_relation(name)?;
alias.visit(visitor)?;
}
}
visitor.post_visit_table_factor(self)?;
ControlFlow::Continue(())
}
}
```

Note that annotating both the type and the field is incorrect as it will result
in redundant calls to the method. For example

```rust
#[derive(Visit, VisitMut)]
#[visit(with = "visit_expr")]
enum Expr {
IsNull(#[visit(with = "visit_expr")] Box<Expr>),
..
}
```

will result in these calls to the visitor


```
visitor.pre_visit_expr(<is null expr>)
visitor.pre_visit_expr(<is null operand>)
visitor.pre_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null operand>)
visitor.post_visit_expr(<is null expr>)
```

## Releasing

This crate's release is not automated. Instead it is released manually as needed

Steps:
1. Update the version in `Cargo.toml`
2. Update the corresponding version in `../Cargo.toml`
3. Commit via PR
4. Publish to crates.io:

```shell
# update to latest checked in main branch and publish via
cargo publish
```

52 changes: 29 additions & 23 deletions derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ 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,
parse::{Parse, ParseStream},
parse_macro_input, parse_quote, Attribute, Data, DeriveInput,
Fields, GenericParam, Generics, Ident, Index, LitStr, Meta, Token
};

/// Implementation of `[#derive(Visit)]`
Expand Down Expand Up @@ -84,38 +85,43 @@ struct Attributes {
with: Option<Ident>,
}

struct WithIdent {
with: Option<Ident>,
}
impl Parse for WithIdent {
fn parse(input: ParseStream) -> Result<Self, syn::Error> {
let mut result = WithIdent { with: None };
let ident = input.parse::<Ident>()?;
if ident != "with" {
return Err(syn::Error::new(ident.span(), "Expected identifier to be `with`"));
}
input.parse::<Token!(=)>()?;
let s = input.parse::<LitStr>()?;
result.with = Some(format_ident!("{}", s.value(), span = s.span()));
Ok(result)
}
}

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\")]"),
for attr in attrs {
if let Meta::List(ref metalist) = attr.meta {
if metalist.path.is_ident("visit") {
match syn::parse2::<WithIdent>(metalist.tokens.clone()) {
Ok(with_ident) => {
out.with = with_ident.with;
}
Err(e) => {
panic!("{}", e);
}
}
}
_ => 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| {
Expand Down
29 changes: 20 additions & 9 deletions src/ast/data_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,14 +374,14 @@ impl fmt::Display for DataType {
}
write!(f, ")")
}
DataType::SnowflakeTimestamp => write!(f, "TIMESTAMP_NTZ"),
DataType::Struct(fields) => {
if !fields.is_empty() {
write!(f, "STRUCT<{}>", display_comma_separated(fields))
} else {
write!(f, "STRUCT")
}
}
DataType::SnowflakeTimestamp => write!(f, "TIMESTAMP_NTZ"),
}
}
}
Expand Down Expand Up @@ -521,18 +521,29 @@ impl fmt::Display for ExactNumberInfo {
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CharacterLength {
/// Default (if VARYING) or maximum (if not VARYING) length
pub length: u64,
/// Optional unit. If not informed, the ANSI handles it as CHARACTERS implicitly
pub unit: Option<CharLengthUnits>,
pub enum CharacterLength {
IntegerLength {
/// Default (if VARYING) or maximum (if not VARYING) length
length: u64,
/// Optional unit. If not informed, the ANSI handles it as CHARACTERS implicitly
unit: Option<CharLengthUnits>,
},
/// VARCHAR(MAX) or NVARCHAR(MAX), used in T-SQL (Miscrosoft SQL Server)
Max,
}

impl fmt::Display for CharacterLength {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.length)?;
if let Some(unit) = &self.unit {
write!(f, " {unit}")?;
match self {
CharacterLength::IntegerLength { length, unit } => {
write!(f, "{}", length)?;
if let Some(unit) = unit {
write!(f, " {unit}")?;
}
}
CharacterLength::Max => {
write!(f, "MAX")?;
}
}
Ok(())
}
Expand Down
Loading
Loading