@@ -29,22 +29,40 @@ use super::value::escape_single_quote_string;
29
29
#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
30
30
#[ cfg_attr( feature = "derive-visitor" , derive( Drive , DriveMut ) ) ]
31
31
pub enum DataType {
32
- /// Fixed-length character type e.g. CHAR(10)
32
+ /// Fixed-length character type e.g. CHARACTER(10)
33
+ Character ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
34
+ /// Fixed-length char type e.g. CHAR(10)
33
35
Char ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
36
+ /// Character varying type e.g. CHARACTER VARYING(10)
37
+ CharacterVarying ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
38
+ /// Char varying type e.g. CHAR VARYING(10)
39
+ CharVarying ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
34
40
/// Variable-length character type e.g. VARCHAR(10)
35
41
Varchar ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
36
42
/// Variable-length character type e.g. NVARCHAR(10)
37
43
Nvarchar ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
38
44
/// Uuid type
39
45
Uuid ,
40
- /// Large character object e.g. CLOB(1000)
41
- Clob ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] u64 ) ,
42
- /// Fixed-length binary type e.g. BINARY(10)
43
- Binary ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] u64 ) ,
44
- /// Variable-length binary type e.g. VARBINARY(10)
45
- Varbinary ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] u64 ) ,
46
- /// Large binary object e.g. BLOB(1000)
47
- Blob ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] u64 ) ,
46
+ /// Large character object with optional length e.g. CLOB, CLOB(1000), [standard], [Oracle]
47
+ ///
48
+ /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#character-large-object-type
49
+ /// [Oracle]: https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html
50
+ Clob ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
51
+ /// Fixed-length binary type with optional length e.g. [standard], [MS SQL Server]
52
+ ///
53
+ /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
54
+ /// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16
55
+ Binary ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
56
+ /// Variable-length binary with optional length type e.g. [standard], [MS SQL Server]
57
+ ///
58
+ /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-string-type
59
+ /// [MS SQL Server]: https://learn.microsoft.com/pt-br/sql/t-sql/data-types/binary-and-varbinary-transact-sql?view=sql-server-ver16
60
+ Varbinary ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
61
+ /// Large binary object with optional length e.g. BLOB, BLOB(1000), [standard], [Oracle]
62
+ ///
63
+ /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-large-object-string-type
64
+ /// [Oracle]: https://docs.oracle.com/javadb/10.8.3.0/ref/rrefblob.html
65
+ Blob ( #[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ) ,
48
66
/// Decimal type with optional precision and scale e.g. DECIMAL(10,2)
49
67
Decimal (
50
68
#[ cfg_attr( feature = "derive-visitor" , drive( skip) ) ] Option < u64 > ,
@@ -94,13 +112,11 @@ pub enum DataType {
94
112
/// Date
95
113
Date ,
96
114
/// Time
97
- Time ,
115
+ Time ( TimezoneInfo ) ,
98
116
/// Datetime
99
117
Datetime ,
100
- /// Timestamp [Without Time Zone]
101
- Timestamp ,
102
- /// Timestamp With Time Zone
103
- TimestampTz ,
118
+ /// Timestamp
119
+ Timestamp ( TimezoneInfo ) ,
104
120
/// Interval
105
121
Interval ,
106
122
/// Regclass used in postgresql serial
@@ -124,18 +140,27 @@ pub enum DataType {
124
140
impl fmt:: Display for DataType {
125
141
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
126
142
match self {
143
+ DataType :: Character ( size) => {
144
+ format_type_with_optional_length ( f, "CHARACTER" , size, false )
145
+ }
127
146
DataType :: Char ( size) => format_type_with_optional_length ( f, "CHAR" , size, false ) ,
128
- DataType :: Varchar ( size) => {
147
+ DataType :: CharacterVarying ( size) => {
129
148
format_type_with_optional_length ( f, "CHARACTER VARYING" , size, false )
130
149
}
150
+ DataType :: CharVarying ( size) => {
151
+ format_type_with_optional_length ( f, "CHAR VARYING" , size, false )
152
+ }
153
+ DataType :: Varchar ( size) => format_type_with_optional_length ( f, "VARCHAR" , size, false ) ,
131
154
DataType :: Nvarchar ( size) => {
132
155
format_type_with_optional_length ( f, "NVARCHAR" , size, false )
133
156
}
134
157
DataType :: Uuid => write ! ( f, "UUID" ) ,
135
- DataType :: Clob ( size) => write ! ( f, "CLOB({})" , size) ,
136
- DataType :: Binary ( size) => write ! ( f, "BINARY({})" , size) ,
137
- DataType :: Varbinary ( size) => write ! ( f, "VARBINARY({})" , size) ,
138
- DataType :: Blob ( size) => write ! ( f, "BLOB({})" , size) ,
158
+ DataType :: Clob ( size) => format_type_with_optional_length ( f, "CLOB" , size, false ) ,
159
+ DataType :: Binary ( size) => format_type_with_optional_length ( f, "BINARY" , size, false ) ,
160
+ DataType :: Varbinary ( size) => {
161
+ format_type_with_optional_length ( f, "VARBINARY" , size, false )
162
+ }
163
+ DataType :: Blob ( size) => format_type_with_optional_length ( f, "BLOB" , size, false ) ,
139
164
DataType :: Decimal ( precision, scale) => {
140
165
if let Some ( scale) = scale {
141
166
write ! ( f, "NUMERIC({},{})" , precision. unwrap( ) , scale)
@@ -183,10 +208,9 @@ impl fmt::Display for DataType {
183
208
DataType :: DoublePrecision => write ! ( f, "DOUBLE PRECISION" ) ,
184
209
DataType :: Boolean => write ! ( f, "BOOLEAN" ) ,
185
210
DataType :: Date => write ! ( f, "DATE" ) ,
186
- DataType :: Time => write ! ( f, "TIME" ) ,
211
+ DataType :: Time ( timezone_info ) => write ! ( f, "TIME{}" , timezone_info ) ,
187
212
DataType :: Datetime => write ! ( f, "DATETIME" ) ,
188
- DataType :: Timestamp => write ! ( f, "TIMESTAMP" ) ,
189
- DataType :: TimestampTz => write ! ( f, "TIMESTAMPTZ" ) ,
213
+ DataType :: Timestamp ( timezone_info) => write ! ( f, "TIMESTAMP{}" , timezone_info) ,
190
214
DataType :: Interval => write ! ( f, "INTERVAL" ) ,
191
215
DataType :: Regclass => write ! ( f, "REGCLASS" ) ,
192
216
DataType :: Text => write ! ( f, "TEXT" ) ,
@@ -233,3 +257,50 @@ fn format_type_with_optional_length(
233
257
}
234
258
Ok ( ( ) )
235
259
}
260
+
261
+ /// Timestamp and Time data types information about TimeZone formatting.
262
+ ///
263
+ /// This is more related to a display information than real differences between each variant. To
264
+ /// guarantee compatibility with the input query we must maintain its exact information.
265
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
266
+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
267
+ pub enum TimezoneInfo {
268
+ /// No information about time zone. E.g., TIMESTAMP
269
+ None ,
270
+ /// Temporal type 'WITH TIME ZONE'. E.g., TIMESTAMP WITH TIME ZONE, [standard], [Oracle]
271
+ ///
272
+ /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type
273
+ /// [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
274
+ WithTimeZone ,
275
+ /// Temporal type 'WITHOUT TIME ZONE'. E.g., TIME WITHOUT TIME ZONE, [standard], [Postgresql]
276
+ ///
277
+ /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#datetime-type
278
+ /// [Postgresql]: https://www.postgresql.org/docs/current/datatype-datetime.html
279
+ WithoutTimeZone ,
280
+ /// Postgresql specific `WITH TIME ZONE` formatting, for both TIME and TIMESTAMP. E.g., TIMETZ, [Postgresql]
281
+ ///
282
+ /// [Postgresql]: https://www.postgresql.org/docs/current/datatype-datetime.html
283
+ Tz ,
284
+ }
285
+
286
+ impl fmt:: Display for TimezoneInfo {
287
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
288
+ match self {
289
+ TimezoneInfo :: None => {
290
+ write ! ( f, "" )
291
+ }
292
+ TimezoneInfo :: WithTimeZone => {
293
+ write ! ( f, " WITH TIME ZONE" )
294
+ }
295
+ TimezoneInfo :: WithoutTimeZone => {
296
+ write ! ( f, " WITHOUT TIME ZONE" )
297
+ }
298
+ TimezoneInfo :: Tz => {
299
+ // TZ is the only one that is displayed BEFORE the precision, so the datatype display
300
+ // must be aware of that. Check <https://www.postgresql.org/docs/14/datatype-datetime.html>
301
+ // for more information
302
+ write ! ( f, "TZ" )
303
+ }
304
+ }
305
+ }
306
+ }
0 commit comments