Skip to content

Commit

Permalink
feat: support pg type alias
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikkon committed Jul 23, 2023
1 parent f60a6f7 commit fe1be7b
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 2 deletions.
55 changes: 53 additions & 2 deletions src/ast/data_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ pub enum DataType {
TinyInt(Option<u64>),
/// Unsigned tiny integer with optional display width e.g. TINYINT UNSIGNED or TINYINT(3) UNSIGNED
UnsignedTinyInt(Option<u64>),
/// Int2 as alias for SmallInt in [postgresql]

Check failure on line 100 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
/// Note: Int2 mean 2 bytes in postgres (not 2 bits)
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html

Check failure on line 102 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
/// Int2 with optional display width e.g. INT2 or INT2(5)
Int2(Option<u64>),
/// Unsigned Int2 with optional display width e.g. INT2 Unsigned or INT2(5) Unsigned
UnsignedInt2(Option<u64>),
/// Small integer with optional display width e.g. SMALLINT or SMALLINT(5)
SmallInt(Option<u64>),
/// Unsigned small integer with optional display width e.g. SMALLINT UNSIGNED or SMALLINT(5) UNSIGNED
Expand All @@ -109,27 +116,50 @@ pub enum DataType {
///
/// [1]: https://dev.mysql.com/doc/refman/8.0/en/integer-types.html
UnsignedMediumInt(Option<u64>),
/// Integer with optional display width e.g. INT or INT(11)
/// Int with optional display width e.g. INT or INT(11)
Int(Option<u64>),
/// Int4 as alias for Integer in [postgresql]

Check failure on line 121 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
/// Note: Int4 mean 4 bytes in postgres (not 4 bits)
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html

Check failure on line 123 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
/// Int4 with optional display width e.g. Int4 or Int4(11)
Int4(Option<u64>),
/// Integer with optional display width e.g. INTEGER or INTEGER(11)
Integer(Option<u64>),
/// Unsigned integer with optional display width e.g. INT UNSIGNED or INT(11) UNSIGNED
/// Unsigned int with optional display width e.g. INT UNSIGNED or INT(11) UNSIGNED
UnsignedInt(Option<u64>),
/// Unsigned int4 with optional display width e.g. INT4 UNSIGNED or INT4(11) UNSIGNED
UnsignedInt4(Option<u64>),
/// Unsigned integer with optional display width e.g. INTGER UNSIGNED or INTEGER(11) UNSIGNED
UnsignedInteger(Option<u64>),
/// Big integer with optional display width e.g. BIGINT or BIGINT(20)
BigInt(Option<u64>),
/// Unsigned big integer with optional display width e.g. BIGINT UNSIGNED or BIGINT(20) UNSIGNED
UnsignedBigInt(Option<u64>),
/// Int8 as alias for Bigint in [postgresql]

Check failure on line 138 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
/// Note: Int8 mean 8 bytes in postgres (not 8 bits)
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html

Check failure on line 140 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
/// Int8 with optional display width e.g. INT8 or INT8(11)
Int8(Option<u64>),
/// Unsigned Int8 with optional display width e.g. INT8 UNSIGNED or INT8(11) UNSIGNED
UnsignedInt8(Option<u64>),
/// FLOAT4 as alias for Real in [postgresql]

Check failure on line 145 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
/// [postgresql] : https://www.postgresql.org/docs/15/datatype.html

Check failure on line 146 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
FLOAT4,
/// Floating point e.g. REAL
Real,
/// FLOAT8 as alias for Double in [postgresql]

Check failure on line 150 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
/// [postgresql] : https://www.postgresql.org/docs/15/datatype.html

Check failure on line 151 in src/ast/data_type.rs

View workflow job for this annotation

GitHub Actions / docs

unresolved link to `postgresql`
FLOAT8,
/// Double
Double,
/// Double PRECISION e.g. [standard], [postgresql]
///
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#approximate-numeric-type
/// [postgresql]: https://www.postgresql.org/docs/current/datatype-numeric.html
DoublePrecision,
/// Bool as alias for Boolean in [postgresql]
/// [postgresql] : https://www.postgresql.org/docs/15/datatype.html
Bool,
/// Boolean
Boolean,
/// Date
Expand Down Expand Up @@ -213,6 +243,12 @@ impl fmt::Display for DataType {
DataType::UnsignedTinyInt(zerofill) => {
format_type_with_optional_length(f, "TINYINT", zerofill, true)
}
DataType::Int2(zerofill) => {
format_type_with_optional_length(f, "INT2", zerofill, false)
}
DataType::UnsignedInt2(zerofill) => {
format_type_with_optional_length(f, "INT2", zerofill, true)
}
DataType::SmallInt(zerofill) => {
format_type_with_optional_length(f, "SMALLINT", zerofill, false)
}
Expand All @@ -229,6 +265,12 @@ impl fmt::Display for DataType {
DataType::UnsignedInt(zerofill) => {
format_type_with_optional_length(f, "INT", zerofill, true)
}
DataType::Int4(zerofill) => {
format_type_with_optional_length(f, "INT4", zerofill, false)
}
DataType::UnsignedInt4(zerofill) => {
format_type_with_optional_length(f, "INT4", zerofill, true)
}
DataType::Integer(zerofill) => {
format_type_with_optional_length(f, "INTEGER", zerofill, false)
}
Expand All @@ -241,9 +283,18 @@ impl fmt::Display for DataType {
DataType::UnsignedBigInt(zerofill) => {
format_type_with_optional_length(f, "BIGINT", zerofill, true)
}
DataType::Int8(zerofill) => {
format_type_with_optional_length(f, "INT8", zerofill, false)
}
DataType::UnsignedInt8(zerofill) => {
format_type_with_optional_length(f, "INT8", zerofill, true)
}
DataType::Real => write!(f, "REAL"),
DataType::FLOAT4 => write!(f, "FLOAT4"),
DataType::Double => write!(f, "DOUBLE"),
DataType::FLOAT8 => write!(f, "FLOAT8"),
DataType::DoublePrecision => write!(f, "DOUBLE PRECISION"),
DataType::Bool => write!(f, "BOOL"),
DataType::Boolean => write!(f, "BOOLEAN"),
DataType::Date => write!(f, "DATE"),
DataType::Time(precision, timezone_info) => {
Expand Down
6 changes: 6 additions & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ define_keywords!(
BINARY,
BLOB,
BLOOMFILTER,
BOOL,
BOOLEAN,
BOTH,
BTREE,
Expand Down Expand Up @@ -263,6 +264,8 @@ define_keywords!(
FIRST,
FIRST_VALUE,
FLOAT,
FLOAT4,
FLOAT8,
FLOOR,
FOLLOWING,
FOR,
Expand Down Expand Up @@ -317,6 +320,9 @@ define_keywords!(
INSENSITIVE,
INSERT,
INT,
INT2,
INT4,
INT8,
INTEGER,
INTERSECT,
INTERSECTION,
Expand Down
27 changes: 27 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4559,8 +4559,11 @@ impl<'a> Parser<'a> {
let mut data = match next_token.token {
Token::Word(w) => match w.keyword {
Keyword::BOOLEAN => Ok(DataType::Boolean),
Keyword::BOOL => Ok(DataType::Bool),
Keyword::FLOAT => Ok(DataType::Float(self.parse_optional_precision()?)),
Keyword::REAL => Ok(DataType::Real),
Keyword::FLOAT4 => Ok(DataType::FLOAT4),
Keyword::FLOAT8 => Ok(DataType::FLOAT8),
Keyword::DOUBLE => {
if self.parse_keyword(Keyword::PRECISION) {
Ok(DataType::DoublePrecision)
Expand All @@ -4576,6 +4579,14 @@ impl<'a> Parser<'a> {
Ok(DataType::TinyInt(optional_precision?))
}
}
Keyword::INT2 => {
let optional_precision = self.parse_optional_precision();
if self.parse_keyword(Keyword::UNSIGNED) {
Ok(DataType::UnsignedInt2(optional_precision?))
} else {
Ok(DataType::Int2(optional_precision?))
}
}
Keyword::SMALLINT => {
let optional_precision = self.parse_optional_precision();
if self.parse_keyword(Keyword::UNSIGNED) {
Expand All @@ -4600,6 +4611,14 @@ impl<'a> Parser<'a> {
Ok(DataType::Int(optional_precision?))
}
}
Keyword::INT4 => {
let optional_precision = self.parse_optional_precision();
if self.parse_keyword(Keyword::UNSIGNED) {
Ok(DataType::UnsignedInt4(optional_precision?))
} else {
Ok(DataType::Int4(optional_precision?))
}
}
Keyword::INTEGER => {
let optional_precision = self.parse_optional_precision();
if self.parse_keyword(Keyword::UNSIGNED) {
Expand All @@ -4616,6 +4635,14 @@ impl<'a> Parser<'a> {
Ok(DataType::BigInt(optional_precision?))
}
}
Keyword::INT8 => {
let optional_precision = self.parse_optional_precision();
if self.parse_keyword(Keyword::UNSIGNED) {
Ok(DataType::UnsignedInt8(optional_precision?))
} else {
Ok(DataType::Int8(optional_precision?))
}
}
Keyword::VARCHAR => Ok(DataType::Varchar(self.parse_optional_character_length()?)),
Keyword::NVARCHAR => Ok(DataType::Nvarchar(self.parse_optional_precision()?)),
Keyword::CHARACTER => {
Expand Down
70 changes: 70 additions & 0 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2945,3 +2945,73 @@ fn parse_truncate() {
truncate
);
}

#[test]
fn parse_create_table_with_alias() {
let sql = "CREATE TABLE public.datatype_aliases
(
int8_col INT8,
int4_col INT4,
int2_col INT2,
float8_col FLOAT8,
float4_col FLOAT4,
bool_col BOOL,
);";
match pg_and_generic().one_statement_parses_to(sql, "") {
Statement::CreateTable {
name,
columns,
constraints,
with_options: _with_options,
if_not_exists: false,
external: false,
file_format: None,
location: None,
..
} => {
assert_eq!("public.datatype_aliases", name.to_string());
assert_eq!(
columns,
vec![
ColumnDef {
name: "int8_col".into(),
data_type: DataType::Int8(None),
collation: None,
options: vec![]
},
ColumnDef {
name: "int4_col".into(),
data_type: DataType::Int4(None),
collation: None,
options: vec![]
},
ColumnDef {
name: "int2_col".into(),
data_type: DataType::Int2(None),
collation: None,
options: vec![]
},
ColumnDef {
name: "float8_col".into(),
data_type: DataType::FLOAT8,
collation: None,
options: vec![]
},
ColumnDef {
name: "float4_col".into(),
data_type: DataType::FLOAT4,
collation: None,
options: vec![]
},
ColumnDef {
name: "bool_col".into(),
data_type: DataType::Bool,
collation: None,

Check failure on line 3009 in tests/sqlparser_postgres.rs

View workflow job for this annotation

GitHub Actions / codestyle

Diff in /home/runner/work/sqlparser-rs/sqlparser-rs/tests/sqlparser_postgres.rs
options: vec![]
},
]);
assert!(constraints.is_empty());
}
_ => unreachable!(),
}

Check failure on line 3016 in tests/sqlparser_postgres.rs

View workflow job for this annotation

GitHub Actions / codestyle

Diff in /home/runner/work/sqlparser-rs/sqlparser-rs/tests/sqlparser_postgres.rs
}

0 comments on commit fe1be7b

Please sign in to comment.