Expand handling of `LIMIT 1, 2` handling to include sqlite (#1447)

diff --git a/src/dialect/clickhouse.rs b/src/dialect/clickhouse.rs
index ee8ee94..0c8f080 100644
--- a/src/dialect/clickhouse.rs
+++ b/src/dialect/clickhouse.rs
@@ -46,4 +46,8 @@
     fn require_interval_qualifier(&self) -> bool {
         true
     }
+
+    fn supports_limit_comma(&self) -> bool {
+        true
+    }
 }
diff --git a/src/dialect/generic.rs b/src/dialect/generic.rs
index bea56d0..8bec45b 100644
--- a/src/dialect/generic.rs
+++ b/src/dialect/generic.rs
@@ -99,4 +99,8 @@
     fn supports_explain_with_utility_options(&self) -> bool {
         true
     }
+
+    fn supports_limit_comma(&self) -> bool {
+        true
+    }
 }
diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs
index 90dffe8..29ad0b9 100644
--- a/src/dialect/mod.rs
+++ b/src/dialect/mod.rs
@@ -67,7 +67,7 @@
 /// 1. user defined [`Dialect`]s can customize the parsing behavior
 /// 2. The differences between dialects can be clearly documented in the trait
 ///
-/// `dialect_of!(parser Is SQLiteDialect |  GenericDialect)` evaluates
+/// `dialect_of!(parser is SQLiteDialect |  GenericDialect)` evaluates
 /// to `true` if `parser.dialect` is one of the [`Dialect`]s specified.
 macro_rules! dialect_of {
     ( $parsed_dialect: ident is $($dialect_type: ty)|+ ) => {
@@ -323,6 +323,11 @@
         false
     }
 
+    /// Does the dialect support parsing `LIMIT 1, 2` as `LIMIT 2 OFFSET 1`?
+    fn supports_limit_comma(&self) -> bool {
+        false
+    }
+
     /// Does the dialect support trailing commas in the projection list?
     fn supports_projection_trailing_commas(&self) -> bool {
         self.supports_trailing_commas()
diff --git a/src/dialect/mysql.rs b/src/dialect/mysql.rs
index 2b5e42e..d1bf333 100644
--- a/src/dialect/mysql.rs
+++ b/src/dialect/mysql.rs
@@ -93,6 +93,10 @@
     fn require_interval_qualifier(&self) -> bool {
         true
     }
+
+    fn supports_limit_comma(&self) -> bool {
+        true
+    }
 }
 
 /// `LOCK TABLES`
diff --git a/src/dialect/sqlite.rs b/src/dialect/sqlite.rs
index d3813d9..5c563bf 100644
--- a/src/dialect/sqlite.rs
+++ b/src/dialect/sqlite.rs
@@ -73,4 +73,8 @@
     fn supports_in_empty_list(&self) -> bool {
         true
     }
+
+    fn supports_limit_comma(&self) -> bool {
+        true
+    }
 }
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index a60dea3..a4445e0 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -8739,7 +8739,7 @@
                     offset = Some(self.parse_offset()?)
                 }
 
-                if dialect_of!(self is GenericDialect | MySqlDialect | ClickHouseDialect)
+                if self.dialect.supports_limit_comma()
                     && limit.is_some()
                     && offset.is_none()
                     && self.consume_token(&Token::Comma)
diff --git a/src/test_utils.rs b/src/test_utils.rs
index eb03523..e588b35 100644
--- a/src/test_utils.rs
+++ b/src/test_utils.rs
@@ -47,6 +47,14 @@
 }
 
 impl TestedDialects {
+    /// Create a TestedDialects with default options and the given dialects.
+    pub fn new(dialects: Vec<Box<dyn Dialect>>) -> Self {
+        Self {
+            dialects,
+            options: None,
+        }
+    }
+
     fn new_parser<'a>(&self, dialect: &'a dyn Dialect) -> Parser<'a> {
         let parser = Parser::new(dialect);
         if let Some(options) = &self.options {
@@ -211,24 +219,21 @@
 
 /// Returns all available dialects.
 pub fn all_dialects() -> TestedDialects {
-    let all_dialects = vec![
-        Box::new(GenericDialect {}) as Box<dyn Dialect>,
-        Box::new(PostgreSqlDialect {}) as Box<dyn Dialect>,
-        Box::new(MsSqlDialect {}) as Box<dyn Dialect>,
-        Box::new(AnsiDialect {}) as Box<dyn Dialect>,
-        Box::new(SnowflakeDialect {}) as Box<dyn Dialect>,
-        Box::new(HiveDialect {}) as Box<dyn Dialect>,
-        Box::new(RedshiftSqlDialect {}) as Box<dyn Dialect>,
-        Box::new(MySqlDialect {}) as Box<dyn Dialect>,
-        Box::new(BigQueryDialect {}) as Box<dyn Dialect>,
-        Box::new(SQLiteDialect {}) as Box<dyn Dialect>,
-        Box::new(DuckDbDialect {}) as Box<dyn Dialect>,
-        Box::new(DatabricksDialect {}) as Box<dyn Dialect>,
-    ];
-    TestedDialects {
-        dialects: all_dialects,
-        options: None,
-    }
+    TestedDialects::new(vec![
+        Box::new(GenericDialect {}),
+        Box::new(PostgreSqlDialect {}),
+        Box::new(MsSqlDialect {}),
+        Box::new(AnsiDialect {}),
+        Box::new(SnowflakeDialect {}),
+        Box::new(HiveDialect {}),
+        Box::new(RedshiftSqlDialect {}),
+        Box::new(MySqlDialect {}),
+        Box::new(BigQueryDialect {}),
+        Box::new(SQLiteDialect {}),
+        Box::new(DuckDbDialect {}),
+        Box::new(DatabricksDialect {}),
+        Box::new(ClickHouseDialect {}),
+    ])
 }
 
 /// Returns all dialects matching the given predicate.
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 2935298..2677c19 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -6832,7 +6832,9 @@
 #[test]
 fn parse_create_view_with_columns() {
     let sql = "CREATE VIEW v (has, cols) AS SELECT 1, 2";
-    match verified_stmt(sql) {
+    // TODO: why does this fail for ClickHouseDialect? (#1449)
+    // match all_dialects().verified_stmt(sql) {
+    match all_dialects_except(|d| d.is::<ClickHouseDialect>()).verified_stmt(sql) {
         Statement::CreateView {
             name,
             columns,
@@ -8624,17 +8626,26 @@
 
 #[test]
 fn parse_offset_and_limit() {
-    let sql = "SELECT foo FROM bar LIMIT 2 OFFSET 2";
+    let sql = "SELECT foo FROM bar LIMIT 1 OFFSET 2";
     let expect = Some(Offset {
         value: Expr::Value(number("2")),
         rows: OffsetRows::None,
     });
     let ast = verified_query(sql);
     assert_eq!(ast.offset, expect);
-    assert_eq!(ast.limit, Some(Expr::Value(number("2"))));
+    assert_eq!(ast.limit, Some(Expr::Value(number("1"))));
 
     // different order is OK
-    one_statement_parses_to("SELECT foo FROM bar OFFSET 2 LIMIT 2", sql);
+    one_statement_parses_to("SELECT foo FROM bar OFFSET 2 LIMIT 1", sql);
+
+    // mysql syntax is ok for some dialects
+    TestedDialects::new(vec![
+        Box::new(GenericDialect {}),
+        Box::new(MySqlDialect {}),
+        Box::new(SQLiteDialect {}),
+        Box::new(ClickHouseDialect {}),
+    ])
+    .one_statement_parses_to("SELECT foo FROM bar LIMIT 2, 1", sql);
 
     // expressions are allowed
     let sql = "SELECT foo FROM bar LIMIT 1 + 2 OFFSET 3 * 4";