From cdd271490bf644d64af410148eca3b86d47460bf Mon Sep 17 00:00:00 2001 From: javrucebo Date: Sat, 27 Jan 2018 00:33:23 +0100 Subject: [PATCH] Allow more variations of LIMIT/OFFSET In addtion to already supported LIMIT/OFFSET variants allow more to be parsed Legacy: - LIMIT int - LIMIT int OFFSET int Enhancement: - OFFSET int (no limit) - LIMIT ALL (no limit) - LIMIT NULL (no limit) - LIMIT ALL OFFSET int (no limit, but offset) - LIMIT NULL OFFSET int (no limit, but offset) Also ensures negative limits / offsets are set to kNoLimit/kNoOffset --- src/parser/bison_parser.y | 5 ++++ src/sql/statements.cpp | 4 +-- test/select_tests.cpp | 59 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/parser/bison_parser.y b/src/parser/bison_parser.y index 02ae8e3..3469546 100755 --- a/src/parser/bison_parser.y +++ b/src/parser/bison_parser.y @@ -711,6 +711,11 @@ opt_top: opt_limit: LIMIT int_literal { $$ = new LimitDescription($2->ival, kNoOffset); delete $2; } | LIMIT int_literal OFFSET int_literal { $$ = new LimitDescription($2->ival, $4->ival); delete $2; delete $4; } + | OFFSET int_literal { $$ = new LimitDescription(kNoLimit, $2->ival); delete $2; } + | LIMIT ALL { $$ = nullptr; } + | LIMIT NULL { $$ = nullptr; } + | LIMIT ALL OFFSET int_literal { $$ = new LimitDescription(kNoLimit, $4->ival); delete $4; } + | LIMIT NULL OFFSET int_literal { $$ = new LimitDescription(kNoLimit, $4->ival);; delete $4; } | /* empty */ { $$ = nullptr; } ; diff --git a/src/sql/statements.cpp b/src/sql/statements.cpp index 380db06..458a846 100755 --- a/src/sql/statements.cpp +++ b/src/sql/statements.cpp @@ -156,8 +156,8 @@ namespace hsql { // LimitDescription LimitDescription::LimitDescription(int64_t limit, int64_t offset) : - limit(limit), - offset(offset) {} + limit(limit >= 0 ? limit : kNoLimit), + offset(offset > 0 ? offset : kNoOffset) {} // GroypByDescription GroupByDescription::GroupByDescription() : diff --git a/test/select_tests.cpp b/test/select_tests.cpp index 744cb46..ecf544e 100644 --- a/test/select_tests.cpp +++ b/test/select_tests.cpp @@ -438,4 +438,61 @@ TEST(JoinTypes) { stmt = (SelectStatement*) result.getStatement(11); ASSERT_NULL(stmt->fromTable->join); -} \ No newline at end of file +} + +TEST(SetLimitOffset) { + SelectStatement* stmt; + + TEST_PARSE_SQL_QUERY("select a from t1 limit 1; \ + select a from t1 limit 1 offset 1; \ + select a from t1 limit 0; \ + select a from t1 limit 0 offset 1; \ + select a from t1 limit 1 offset 0; \ + select a from t1 limit ALL offset 1; \ + select a from t1 limit NULL offset 1; \ + select a from t1 offset 1; \ + select top 10 a from t1; \ + select top 20 a from t1 limit 10;", + result, 10); + + stmt = (SelectStatement*) result.getStatement(0); + ASSERT_EQ(stmt->limit->limit, 1); + ASSERT_EQ(stmt->limit->offset, kNoOffset); + + stmt = (SelectStatement*) result.getStatement(1); + ASSERT_EQ(stmt->limit->limit, 1); + ASSERT_EQ(stmt->limit->offset, 1); + + stmt = (SelectStatement*) result.getStatement(2); + ASSERT_EQ(stmt->limit->limit, 0); + ASSERT_EQ(stmt->limit->offset, kNoOffset); + + stmt = (SelectStatement*) result.getStatement(3); + ASSERT_EQ(stmt->limit->limit, 0); + ASSERT_EQ(stmt->limit->offset, 1); + + stmt = (SelectStatement*) result.getStatement(4); + ASSERT_EQ(stmt->limit->limit, 1); + ASSERT_EQ(stmt->limit->offset, kNoOffset); + + stmt = (SelectStatement*) result.getStatement(5); + ASSERT_EQ(stmt->limit->limit, kNoLimit); + ASSERT_EQ(stmt->limit->offset, 1); + + stmt = (SelectStatement*) result.getStatement(6); + ASSERT_EQ(stmt->limit->limit, kNoLimit); + ASSERT_EQ(stmt->limit->offset, 1); + + stmt = (SelectStatement*) result.getStatement(7); + ASSERT_EQ(stmt->limit->limit, kNoLimit); + ASSERT_EQ(stmt->limit->offset, 1); + + stmt = (SelectStatement*) result.getStatement(8); + ASSERT_EQ(stmt->limit->limit, 10); + ASSERT_EQ(stmt->limit->offset, kNoOffset); + + stmt = (SelectStatement*) result.getStatement(9); + ASSERT_EQ(stmt->limit->limit, 10); + ASSERT_EQ(stmt->limit->offset, kNoOffset); +} +