Correct order of arguments in LIMIT x,y , restrict to MySql and generic dialects (#642)

* 613 Fixing MySQL LIMIT syntax

* 613 Reducing logic to real case scenario

* 613 Adding syntax to generic dialect
This commit is contained in:
AugustoFKL 2022-10-01 18:23:06 -03:00 committed by GitHub
parent fb5a9747ae
commit 3beecc0a7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 16 deletions

View file

@ -24,6 +24,9 @@ use core::fmt;
use log::debug; use log::debug;
use IsLateral::*;
use IsOptional::*;
use crate::ast::*; use crate::ast::*;
use crate::dialect::*; use crate::dialect::*;
use crate::keywords::{self, Keyword}; use crate::keywords::{self, Keyword};
@ -57,15 +60,11 @@ pub enum IsOptional {
Mandatory, Mandatory,
} }
use IsOptional::*;
pub enum IsLateral { pub enum IsLateral {
Lateral, Lateral,
NotLateral, NotLateral,
} }
use IsLateral::*;
pub enum WildcardExpr { pub enum WildcardExpr {
Expr(Expr), Expr(Expr),
QualifiedWildcard(ObjectName), QualifiedWildcard(ObjectName),
@ -3762,9 +3761,18 @@ impl<'a> Parser<'a> {
offset = Some(self.parse_offset()?) offset = Some(self.parse_offset()?)
} }
if offset.is_none() && self.consume_token(&Token::Comma) { if dialect_of!(self is GenericDialect | MySqlDialect)
// mysql style LIMIT 10, offset 5 && limit.is_some()
offset = Some(self.parse_offset()?) && offset.is_none()
&& self.consume_token(&Token::Comma)
{
// MySQL style LIMIT x,y => LIMIT y OFFSET x.
// Check <https://dev.mysql.com/doc/refman/8.0/en/select.html> for more details.
offset = Some(Offset {
value: limit.unwrap(),
rows: OffsetRows::None,
});
limit = Some(self.parse_expr()?);
} }
} }
@ -5197,9 +5205,10 @@ impl Word {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use crate::test_utils::{all_dialects, TestedDialects}; use crate::test_utils::{all_dialects, TestedDialects};
use super::*;
#[test] #[test]
fn test_prev_index() { fn test_prev_index() {
let sql = "SELECT version"; let sql = "SELECT version";

View file

@ -1593,14 +1593,6 @@ fn parse_limit_accepts_all() {
); );
} }
#[test]
fn parse_limit_my_sql_syntax() {
one_statement_parses_to(
"SELECT id, fname, lname FROM customer LIMIT 5, 10",
"SELECT id, fname, lname FROM customer LIMIT 5 OFFSET 10",
);
}
#[test] #[test]
fn parse_cast() { fn parse_cast() {
let sql = "SELECT CAST(id AS BIGINT) FROM customer"; let sql = "SELECT CAST(id AS BIGINT) FROM customer";

View file

@ -1065,6 +1065,14 @@ fn parse_set_names() {
assert_eq!(stmt, Statement::SetNamesDefault {}); assert_eq!(stmt, Statement::SetNamesDefault {});
} }
#[test]
fn parse_limit_my_sql_syntax() {
mysql_and_generic().one_statement_parses_to(
"SELECT id, fname, lname FROM customer LIMIT 5, 10",
"SELECT id, fname, lname FROM customer LIMIT 10 OFFSET 5",
);
}
fn mysql() -> TestedDialects { fn mysql() -> TestedDialects {
TestedDialects { TestedDialects {
dialects: vec![Box::new(MySqlDialect {})], dialects: vec![Box::new(MySqlDialect {})],