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

feat: support pg type alias #932

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 53 additions & 2 deletions src/ast/data_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,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]
/// Note: Int2 mean 2 bytes in postgres (not 2 bits)
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
/// 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 @@ -97,27 +104,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]
/// Note: Int4 mean 4 bytes in postgres (not 4 bits)
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
/// 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]
/// Note: Int8 mean 8 bytes in postgres (not 8 bits)
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
/// 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]
/// [postgresql] : https://www.postgresql.org/docs/15/datatype.html
FLOAT4,
/// Floating point e.g. REAL
Real,
/// FLOAT8 as alias for Double in [postgresql]
/// [postgresql] : https://www.postgresql.org/docs/15/datatype.html
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 @@ -197,6 +227,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 @@ -213,6 +249,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 @@ -225,9 +267,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 @@ -103,6 +103,7 @@ define_keywords!(
BIGINT,
BINARY,
BLOB,
BOOL,
BOOLEAN,
BOTH,
BTREE,
Expand Down Expand Up @@ -242,6 +243,8 @@ define_keywords!(
FIRST,
FIRST_VALUE,
FLOAT,
FLOAT4,
FLOAT8,
FLOOR,
FOLLOWING,
FOR,
Expand Down Expand Up @@ -290,6 +293,9 @@ define_keywords!(
INSENSITIVE,
INSERT,
INT,
INT2,
INT4,
INT8,
INTEGER,
INTERSECT,
INTERSECTION,
Expand Down
28 changes: 28 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3619,15 +3619,19 @@ impl<'a> Parser<'a> {
let mut data = match self.next_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)
} else {
Ok(DataType::Double)
}
}

Keyword::TINYINT => {
let optional_precision = self.parse_optional_precision();
if self.parse_keyword(Keyword::UNSIGNED) {
Expand All @@ -3636,6 +3640,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 @@ -3660,6 +3672,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 @@ -3676,6 +3696,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 @@ -2186,3 +2186,73 @@ fn parse_similar_to() {
chk(false);
chk(true);
}

#[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,
options: vec![]
},
]);
assert!(constraints.is_empty());
}
_ => unreachable!(),
}
}