@@ -89,6 +89,15 @@ macro_rules! dialect_of {
89
89
///
90
90
/// [module level documentation]: crate
91
91
pub trait Dialect : Debug + Any {
92
+ /// Determine the [`TypeId`] of this dialect.
93
+ ///
94
+ /// By default, return the same [`TypeId`] as [`Any::type_id`]. Can be overriden
95
+ /// by dialects that behave like other dialects
96
+ /// (for example when wrapping a dialect).
97
+ fn dialect ( & self ) -> TypeId {
98
+ self . type_id ( )
99
+ }
100
+
92
101
/// Determine if a character starts a quoted identifier. The default
93
102
/// implementation, accepting "double quoted" ids is both ANSI-compliant
94
103
/// and appropriate for most dialects (with the notable exception of
@@ -164,7 +173,7 @@ impl dyn Dialect {
164
173
#[ inline]
165
174
pub fn is < T : Dialect > ( & self ) -> bool {
166
175
// borrowed from `Any` implementation
167
- TypeId :: of :: < T > ( ) == self . type_id ( )
176
+ TypeId :: of :: < T > ( ) == self . dialect ( )
168
177
}
169
178
}
170
179
@@ -248,4 +257,98 @@ mod tests {
248
257
fn parse_dialect ( v : & str ) -> Box < dyn Dialect > {
249
258
dialect_from_str ( v) . unwrap ( )
250
259
}
260
+
261
+ #[ test]
262
+ fn parse_with_wrapped_dialect ( ) {
263
+ /// Wrapper for a dialect. In a real-world example, this wrapper
264
+ /// would tweak the behavior of the dialect. For the test case,
265
+ /// it wraps all methods unaltered.
266
+ #[ derive( Debug ) ]
267
+ struct WrappedDialect ( MySqlDialect ) ;
268
+
269
+ impl Dialect for WrappedDialect {
270
+ fn dialect ( & self ) -> std:: any:: TypeId {
271
+ self . 0 . dialect ( )
272
+ }
273
+
274
+ fn is_identifier_start ( & self , ch : char ) -> bool {
275
+ self . 0 . is_identifier_start ( ch)
276
+ }
277
+
278
+ fn is_delimited_identifier_start ( & self , ch : char ) -> bool {
279
+ self . 0 . is_delimited_identifier_start ( ch)
280
+ }
281
+
282
+ fn is_proper_identifier_inside_quotes (
283
+ & self ,
284
+ chars : std:: iter:: Peekable < std:: str:: Chars < ' _ > > ,
285
+ ) -> bool {
286
+ self . 0 . is_proper_identifier_inside_quotes ( chars)
287
+ }
288
+
289
+ fn supports_filter_during_aggregation ( & self ) -> bool {
290
+ self . 0 . supports_filter_during_aggregation ( )
291
+ }
292
+
293
+ fn supports_within_after_array_aggregation ( & self ) -> bool {
294
+ self . 0 . supports_within_after_array_aggregation ( )
295
+ }
296
+
297
+ fn supports_group_by_expr ( & self ) -> bool {
298
+ self . 0 . supports_group_by_expr ( )
299
+ }
300
+
301
+ fn supports_substring_from_for_expr ( & self ) -> bool {
302
+ self . 0 . supports_substring_from_for_expr ( )
303
+ }
304
+
305
+ fn supports_in_empty_list ( & self ) -> bool {
306
+ self . 0 . supports_in_empty_list ( )
307
+ }
308
+
309
+ fn convert_type_before_value ( & self ) -> bool {
310
+ self . 0 . convert_type_before_value ( )
311
+ }
312
+
313
+ fn parse_prefix (
314
+ & self ,
315
+ parser : & mut sqlparser:: parser:: Parser ,
316
+ ) -> Option < Result < Expr , sqlparser:: parser:: ParserError > > {
317
+ self . 0 . parse_prefix ( parser)
318
+ }
319
+
320
+ fn parse_infix (
321
+ & self ,
322
+ parser : & mut sqlparser:: parser:: Parser ,
323
+ expr : & Expr ,
324
+ precedence : u8 ,
325
+ ) -> Option < Result < Expr , sqlparser:: parser:: ParserError > > {
326
+ self . 0 . parse_infix ( parser, expr, precedence)
327
+ }
328
+
329
+ fn get_next_precedence (
330
+ & self ,
331
+ parser : & sqlparser:: parser:: Parser ,
332
+ ) -> Option < Result < u8 , sqlparser:: parser:: ParserError > > {
333
+ self . 0 . get_next_precedence ( parser)
334
+ }
335
+
336
+ fn parse_statement (
337
+ & self ,
338
+ parser : & mut sqlparser:: parser:: Parser ,
339
+ ) -> Option < Result < Statement , sqlparser:: parser:: ParserError > > {
340
+ self . 0 . parse_statement ( parser)
341
+ }
342
+
343
+ fn is_identifier_part ( & self , ch : char ) -> bool {
344
+ self . 0 . is_identifier_part ( ch)
345
+ }
346
+ }
347
+
348
+ let statement = r#"SELECT 'Wayne\'s World'"# ;
349
+ let res1 = Parser :: parse_sql ( & MySqlDialect { } , statement) ;
350
+ let res2 = Parser :: parse_sql ( & WrappedDialect ( MySqlDialect { } ) , statement) ;
351
+ assert ! ( res1. is_ok( ) ) ;
352
+ assert_eq ! ( res1, res2) ;
353
+ }
251
354
}
0 commit comments