From e779642091e567828fa06213c163618b0dd65b0b Mon Sep 17 00:00:00 2001 From: adam Date: Mon, 29 Oct 2012 13:10:50 +0700 Subject: [PATCH] Fix query skip bug + test case --- tcejdb/ejdb.c | 29 +++++++++++++++++++++-------- tcejdb/testejdb/t2.c | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/tcejdb/ejdb.c b/tcejdb/ejdb.c index a973728..9f5768e 100644 --- a/tcejdb/ejdb.c +++ b/tcejdb/ejdb.c @@ -1286,7 +1286,7 @@ static TCLIST* _qrysearch(EJCOLL *jcoll, const EJQ *q, uint32_t *outcount, int q for (int i = 0; i < ofsz; ++i) assert(ofs[i] != NULL); } - if (!onlycount && aofsz > 0 && (!midx || mqf->orderseq != 1)) { //Main index is not main order field + if (!onlycount && aofsz > 0 && (!midx || mqf->orderseq != 1)) { //Main index is not the main order field all = true; //Need all records for ordering for some other fields } @@ -1315,7 +1315,7 @@ static TCLIST* _qrysearch(EJCOLL *jcoll, const EJQ *q, uint32_t *outcount, int q #define JBQREGREC(_bsbuf, _bsbufsz) \ ++count; \ - if (!onlycount && count > skip) { \ + if (!onlycount && (all || count > skip)) { \ TCLISTPUSH(res, _bsbuf, _bsbufsz); \ } \ if (_bsbuf) { \ @@ -1690,12 +1690,25 @@ finish: if (max < UINT_MAX && max > skip) { max = max - skip; } - if (res && TCLISTNUM(res) > max) { //truncate resulting list if max specified - int end = res->start + res->num; - TCLISTDATUM *array = res->array; - for (int i = (res->start + max); i < end; i++) { - TCFREE(array[i].ptr); - --(res->num); + if (res) { + if (all) { //skipping results after full sorting with skip > 0 + for (int i = 0; i < skip && res->num > 0; ++i) { + TCFREE(res->array[res->start].ptr); + ++(res->start); + --(res->num); + } + } + if ((res->start & 0xff) == 0 && res->start > (res->num >> 1)) { + memmove(res->array, res->array + res->start, res->num * sizeof (res->array[0])); + res->start = 0; + } + if (TCLISTNUM(res) > max) { //truncate results if max specified + int end = res->start + res->num; + TCLISTDATUM *array = res->array; + for (int i = (res->start + max); i < end; i++) { + TCFREE(array[i].ptr); + --(res->num); + } } } count = (skip < count) ? count - skip : 0; diff --git a/tcejdb/testejdb/t2.c b/tcejdb/testejdb/t2.c index fb176d2..f9e86eb 100644 --- a/tcejdb/testejdb/t2.c +++ b/tcejdb/testejdb/t2.c @@ -1902,7 +1902,7 @@ void testQuery24() { bson bshints; bson_init_as_query(&bshints); bson_append_start_object(&bshints, "$orderby"); - bson_append_int(&bshints, "name", -1); //DESC order on dblscore + bson_append_int(&bshints, "name", -1); //DESC order on name bson_append_finish_object(&bshints); bson_append_long(&bshints, "$skip", 1); bson_finish(&bshints); @@ -1947,7 +1947,7 @@ void testQuery24() { bson_init_as_query(&bshints); bson_append_start_object(&bshints, "$orderby"); - bson_append_int(&bshints, "name", -1); //DESC order on dblscore + bson_append_int(&bshints, "name", -1); //DESC order on name bson_append_finish_object(&bshints); bson_append_long(&bshints, "$skip", 1); bson_append_long(&bshints, "$max", 2); @@ -2061,6 +2061,43 @@ void testQuery24() { tclistdel(q1res); tcxstrdel(log); ejdbquerydel(q1); + + + bson_init_as_query(&bsq1); + bson_finish(&bsq1); + CU_ASSERT_FALSE_FATAL(bsq1.err); + + bson_init_as_query(&bshints); + bson_append_start_object(&bshints, "$orderby"); + bson_append_int(&bshints, "name", 1); //ASC + bson_append_finish_object(&bshints); + bson_append_long(&bshints, "$skip", 3); + bson_finish(&bshints); + CU_ASSERT_FALSE_FATAL(bshints.err); + + q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, &bshints); + CU_ASSERT_PTR_NOT_NULL_FATAL(q1); + + count = 0; + log = tcxstrnew(); + q1res = ejdbqrysearch(contacts, q1, &count, 0, log); + //fprintf(stderr, "%s", TCXSTRPTR(log)); + + CU_ASSERT_EQUAL(count, 1); + CU_ASSERT_TRUE(TCLISTNUM(q1res) == 1); + + for (int i = 0; i < TCLISTNUM(q1res); ++i) { + if (i == TCLISTNUM(q1res) - 1) { + CU_ASSERT_FALSE(bson_compare_string("Антонов", TCLISTVALPTR(q1res, i), "name")); + } + } + + bson_destroy(&bsq1); + bson_destroy(&bshints); + tclistdel(q1res); + tcxstrdel(log); + ejdbquerydel(q1); + } void testQuery25() { //$or -- 2.7.4