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
This commit is contained in:
javrucebo 2018-01-27 00:33:23 +01:00
parent 36628dc005
commit cdd271490b
3 changed files with 65 additions and 3 deletions

View File

@ -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; }
;

View File

@ -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() :

View File

@ -438,4 +438,61 @@ TEST(JoinTypes) {
stmt = (SelectStatement*) result.getStatement(11);
ASSERT_NULL(stmt->fromTable->join);
}
}
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);
}