Skip to content

Commit 0ddb853

Browse files
authored
feat: support pg type alias (#933)
1 parent 53593f1 commit 0ddb853

4 files changed

Lines changed: 163 additions & 2 deletions

File tree

src/ast/data_type.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ pub enum DataType {
9797
TinyInt(Option<u64>),
9898
/// Unsigned tiny integer with optional display width e.g. TINYINT UNSIGNED or TINYINT(3) UNSIGNED
9999
UnsignedTinyInt(Option<u64>),
100+
/// Int2 as alias for SmallInt in [postgresql]
101+
/// Note: Int2 mean 2 bytes in postgres (not 2 bits)
102+
/// Int2 with optional display width e.g. INT2 or INT2(5)
103+
///
104+
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
105+
Int2(Option<u64>),
106+
/// Unsigned Int2 with optional display width e.g. INT2 Unsigned or INT2(5) Unsigned
107+
UnsignedInt2(Option<u64>),
100108
/// Small integer with optional display width e.g. SMALLINT or SMALLINT(5)
101109
SmallInt(Option<u64>),
102110
/// Unsigned small integer with optional display width e.g. SMALLINT UNSIGNED or SMALLINT(5) UNSIGNED
@@ -109,27 +117,55 @@ pub enum DataType {
109117
///
110118
/// [1]: https://dev.mysql.com/doc/refman/8.0/en/integer-types.html
111119
UnsignedMediumInt(Option<u64>),
112-
/// Integer with optional display width e.g. INT or INT(11)
120+
/// Int with optional display width e.g. INT or INT(11)
113121
Int(Option<u64>),
122+
/// Int4 as alias for Integer in [postgresql]
123+
/// Note: Int4 mean 4 bytes in postgres (not 4 bits)
124+
/// Int4 with optional display width e.g. Int4 or Int4(11)
125+
///
126+
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
127+
Int4(Option<u64>),
114128
/// Integer with optional display width e.g. INTEGER or INTEGER(11)
115129
Integer(Option<u64>),
116-
/// Unsigned integer with optional display width e.g. INT UNSIGNED or INT(11) UNSIGNED
130+
/// Unsigned int with optional display width e.g. INT UNSIGNED or INT(11) UNSIGNED
117131
UnsignedInt(Option<u64>),
132+
/// Unsigned int4 with optional display width e.g. INT4 UNSIGNED or INT4(11) UNSIGNED
133+
UnsignedInt4(Option<u64>),
118134
/// Unsigned integer with optional display width e.g. INTGER UNSIGNED or INTEGER(11) UNSIGNED
119135
UnsignedInteger(Option<u64>),
120136
/// Big integer with optional display width e.g. BIGINT or BIGINT(20)
121137
BigInt(Option<u64>),
122138
/// Unsigned big integer with optional display width e.g. BIGINT UNSIGNED or BIGINT(20) UNSIGNED
123139
UnsignedBigInt(Option<u64>),
140+
/// Int8 as alias for Bigint in [postgresql]
141+
/// Note: Int8 mean 8 bytes in postgres (not 8 bits)
142+
/// Int8 with optional display width e.g. INT8 or INT8(11)
143+
///
144+
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
145+
Int8(Option<u64>),
146+
/// Unsigned Int8 with optional display width e.g. INT8 UNSIGNED or INT8(11) UNSIGNED
147+
UnsignedInt8(Option<u64>),
148+
/// FLOAT4 as alias for Real in [postgresql]
149+
///
150+
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
151+
FLOAT4,
124152
/// Floating point e.g. REAL
125153
Real,
154+
/// FLOAT8 as alias for Double in [postgresql]
155+
///
156+
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
157+
FLOAT8,
126158
/// Double
127159
Double,
128160
/// Double PRECISION e.g. [standard], [postgresql]
129161
///
130162
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#approximate-numeric-type
131163
/// [postgresql]: https://www.postgresql.org/docs/current/datatype-numeric.html
132164
DoublePrecision,
165+
/// Bool as alias for Boolean in [postgresql]
166+
///
167+
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
168+
Bool,
133169
/// Boolean
134170
Boolean,
135171
/// Date
@@ -213,6 +249,12 @@ impl fmt::Display for DataType {
213249
DataType::UnsignedTinyInt(zerofill) => {
214250
format_type_with_optional_length(f, "TINYINT", zerofill, true)
215251
}
252+
DataType::Int2(zerofill) => {
253+
format_type_with_optional_length(f, "INT2", zerofill, false)
254+
}
255+
DataType::UnsignedInt2(zerofill) => {
256+
format_type_with_optional_length(f, "INT2", zerofill, true)
257+
}
216258
DataType::SmallInt(zerofill) => {
217259
format_type_with_optional_length(f, "SMALLINT", zerofill, false)
218260
}
@@ -229,6 +271,12 @@ impl fmt::Display for DataType {
229271
DataType::UnsignedInt(zerofill) => {
230272
format_type_with_optional_length(f, "INT", zerofill, true)
231273
}
274+
DataType::Int4(zerofill) => {
275+
format_type_with_optional_length(f, "INT4", zerofill, false)
276+
}
277+
DataType::UnsignedInt4(zerofill) => {
278+
format_type_with_optional_length(f, "INT4", zerofill, true)
279+
}
232280
DataType::Integer(zerofill) => {
233281
format_type_with_optional_length(f, "INTEGER", zerofill, false)
234282
}
@@ -241,9 +289,18 @@ impl fmt::Display for DataType {
241289
DataType::UnsignedBigInt(zerofill) => {
242290
format_type_with_optional_length(f, "BIGINT", zerofill, true)
243291
}
292+
DataType::Int8(zerofill) => {
293+
format_type_with_optional_length(f, "INT8", zerofill, false)
294+
}
295+
DataType::UnsignedInt8(zerofill) => {
296+
format_type_with_optional_length(f, "INT8", zerofill, true)
297+
}
244298
DataType::Real => write!(f, "REAL"),
299+
DataType::FLOAT4 => write!(f, "FLOAT4"),
245300
DataType::Double => write!(f, "DOUBLE"),
301+
DataType::FLOAT8 => write!(f, "FLOAT8"),
246302
DataType::DoublePrecision => write!(f, "DOUBLE PRECISION"),
303+
DataType::Bool => write!(f, "BOOL"),
247304
DataType::Boolean => write!(f, "BOOLEAN"),
248305
DataType::Date => write!(f, "DATE"),
249306
DataType::Time(precision, timezone_info) => {

src/keywords.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ define_keywords!(
111111
BINARY,
112112
BLOB,
113113
BLOOMFILTER,
114+
BOOL,
114115
BOOLEAN,
115116
BOTH,
116117
BTREE,
@@ -263,6 +264,8 @@ define_keywords!(
263264
FIRST,
264265
FIRST_VALUE,
265266
FLOAT,
267+
FLOAT4,
268+
FLOAT8,
266269
FLOOR,
267270
FOLLOWING,
268271
FOR,
@@ -317,6 +320,9 @@ define_keywords!(
317320
INSENSITIVE,
318321
INSERT,
319322
INT,
323+
INT2,
324+
INT4,
325+
INT8,
320326
INTEGER,
321327
INTERSECT,
322328
INTERSECTION,

src/parser.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4560,8 +4560,11 @@ impl<'a> Parser<'a> {
45604560
let mut data = match next_token.token {
45614561
Token::Word(w) => match w.keyword {
45624562
Keyword::BOOLEAN => Ok(DataType::Boolean),
4563+
Keyword::BOOL => Ok(DataType::Bool),
45634564
Keyword::FLOAT => Ok(DataType::Float(self.parse_optional_precision()?)),
45644565
Keyword::REAL => Ok(DataType::Real),
4566+
Keyword::FLOAT4 => Ok(DataType::FLOAT4),
4567+
Keyword::FLOAT8 => Ok(DataType::FLOAT8),
45654568
Keyword::DOUBLE => {
45664569
if self.parse_keyword(Keyword::PRECISION) {
45674570
Ok(DataType::DoublePrecision)
@@ -4577,6 +4580,14 @@ impl<'a> Parser<'a> {
45774580
Ok(DataType::TinyInt(optional_precision?))
45784581
}
45794582
}
4583+
Keyword::INT2 => {
4584+
let optional_precision = self.parse_optional_precision();
4585+
if self.parse_keyword(Keyword::UNSIGNED) {
4586+
Ok(DataType::UnsignedInt2(optional_precision?))
4587+
} else {
4588+
Ok(DataType::Int2(optional_precision?))
4589+
}
4590+
}
45804591
Keyword::SMALLINT => {
45814592
let optional_precision = self.parse_optional_precision();
45824593
if self.parse_keyword(Keyword::UNSIGNED) {
@@ -4601,6 +4612,14 @@ impl<'a> Parser<'a> {
46014612
Ok(DataType::Int(optional_precision?))
46024613
}
46034614
}
4615+
Keyword::INT4 => {
4616+
let optional_precision = self.parse_optional_precision();
4617+
if self.parse_keyword(Keyword::UNSIGNED) {
4618+
Ok(DataType::UnsignedInt4(optional_precision?))
4619+
} else {
4620+
Ok(DataType::Int4(optional_precision?))
4621+
}
4622+
}
46044623
Keyword::INTEGER => {
46054624
let optional_precision = self.parse_optional_precision();
46064625
if self.parse_keyword(Keyword::UNSIGNED) {
@@ -4617,6 +4636,14 @@ impl<'a> Parser<'a> {
46174636
Ok(DataType::BigInt(optional_precision?))
46184637
}
46194638
}
4639+
Keyword::INT8 => {
4640+
let optional_precision = self.parse_optional_precision();
4641+
if self.parse_keyword(Keyword::UNSIGNED) {
4642+
Ok(DataType::UnsignedInt8(optional_precision?))
4643+
} else {
4644+
Ok(DataType::Int8(optional_precision?))
4645+
}
4646+
}
46204647
Keyword::VARCHAR => Ok(DataType::Varchar(self.parse_optional_character_length()?)),
46214648
Keyword::NVARCHAR => Ok(DataType::Nvarchar(self.parse_optional_precision()?)),
46224649
Keyword::CHARACTER => {

tests/sqlparser_postgres.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2945,3 +2945,74 @@ fn parse_truncate() {
29452945
truncate
29462946
);
29472947
}
2948+
2949+
#[test]
2950+
fn parse_create_table_with_alias() {
2951+
let sql = "CREATE TABLE public.datatype_aliases
2952+
(
2953+
int8_col INT8,
2954+
int4_col INT4,
2955+
int2_col INT2,
2956+
float8_col FLOAT8,
2957+
float4_col FLOAT4,
2958+
bool_col BOOL,
2959+
);";
2960+
match pg_and_generic().one_statement_parses_to(sql, "") {
2961+
Statement::CreateTable {
2962+
name,
2963+
columns,
2964+
constraints,
2965+
with_options: _with_options,
2966+
if_not_exists: false,
2967+
external: false,
2968+
file_format: None,
2969+
location: None,
2970+
..
2971+
} => {
2972+
assert_eq!("public.datatype_aliases", name.to_string());
2973+
assert_eq!(
2974+
columns,
2975+
vec![
2976+
ColumnDef {
2977+
name: "int8_col".into(),
2978+
data_type: DataType::Int8(None),
2979+
collation: None,
2980+
options: vec![]
2981+
},
2982+
ColumnDef {
2983+
name: "int4_col".into(),
2984+
data_type: DataType::Int4(None),
2985+
collation: None,
2986+
options: vec![]
2987+
},
2988+
ColumnDef {
2989+
name: "int2_col".into(),
2990+
data_type: DataType::Int2(None),
2991+
collation: None,
2992+
options: vec![]
2993+
},
2994+
ColumnDef {
2995+
name: "float8_col".into(),
2996+
data_type: DataType::FLOAT8,
2997+
collation: None,
2998+
options: vec![]
2999+
},
3000+
ColumnDef {
3001+
name: "float4_col".into(),
3002+
data_type: DataType::FLOAT4,
3003+
collation: None,
3004+
options: vec![]
3005+
},
3006+
ColumnDef {
3007+
name: "bool_col".into(),
3008+
data_type: DataType::Bool,
3009+
collation: None,
3010+
options: vec![]
3011+
},
3012+
]
3013+
);
3014+
assert!(constraints.is_empty());
3015+
}
3016+
_ => unreachable!(),
3017+
}
3018+
}

0 commit comments

Comments
 (0)