Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 29b4ce8

Browse files
authored
Replace type_id() by trait method to allow wrapping dialects (#1065)
1 parent e027b3c commit 29b4ce8

File tree

1 file changed

+104
-1
lines changed

1 file changed

+104
-1
lines changed

src/dialect/mod.rs

+104-1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ macro_rules! dialect_of {
8989
///
9090
/// [module level documentation]: crate
9191
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+
92101
/// Determine if a character starts a quoted identifier. The default
93102
/// implementation, accepting "double quoted" ids is both ANSI-compliant
94103
/// and appropriate for most dialects (with the notable exception of
@@ -164,7 +173,7 @@ impl dyn Dialect {
164173
#[inline]
165174
pub fn is<T: Dialect>(&self) -> bool {
166175
// borrowed from `Any` implementation
167-
TypeId::of::<T>() == self.type_id()
176+
TypeId::of::<T>() == self.dialect()
168177
}
169178
}
170179

@@ -248,4 +257,98 @@ mod tests {
248257
fn parse_dialect(v: &str) -> Box<dyn Dialect> {
249258
dialect_from_str(v).unwrap()
250259
}
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+
}
251354
}

0 commit comments

Comments
 (0)