Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_rowset_sqlite3RowSetInsert.c237 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdlib.h>5#include <string.h>6#include <stdint.h>7#include <limits.h>8 9static sqlite3 *gDb = NULL;10static RowSet *gRowSet = NULL;11 12/* Helpers */13static void rs_create(void){14  gRowSet = sqlite3RowSetInit(gDb);15  TEST_ASSERT_NOT_NULL(gRowSet);16  /* Initial state expectations */17  TEST_ASSERT_NULL(gRowSet->pEntry);18  TEST_ASSERT_NULL(gRowSet->pLast);19  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0);20  TEST_ASSERT((gRowSet->rsFlags & ROWSET_NEXT) == 0);21}22 23static void rs_delete(void){24  if( gRowSet ){25    sqlite3RowSetDelete(gRowSet);26    gRowSet = NULL;27  }28}29 30/* Unity hooks */31void setUp(void) {32  int rc = sqlite3_open(":memory:", &gDb);33  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);34}35 36void tearDown(void) {37  rs_delete();38  if( gDb ){39    sqlite3_close(gDb);40    gDb = NULL;41  }42}43 44/* Tests */45 46void test_sqlite3RowSetInsert_first_insert_initial_conditions(void){47  rs_create();48 49  sqlite3RowSetInsert(gRowSet, (i64)10);50 51  TEST_ASSERT_NOT_NULL(gRowSet->pEntry);52  TEST_ASSERT_NOT_NULL(gRowSet->pLast);53  TEST_ASSERT(gRowSet->pEntry == gRowSet->pLast);54  TEST_ASSERT(gRowSet->pEntry->v == (i64)10);55  TEST_ASSERT_NULL(gRowSet->pEntry->pRight);56  /* Still sorted after a single insert */57  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0);58}59 60void test_sqlite3RowSetInsert_increasing_keeps_sorted_and_links_correct(void){61  rs_create();62 63  const i64 vals[] = {1,2,3,4,5};64  for(size_t i=0;i<sizeof(vals)/sizeof(vals[0]);i++){65    sqlite3RowSetInsert(gRowSet, vals[i]);66    /* Should remain sorted after each strictly increasing insert */67    TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0);68  }69 70  /* Verify linked list order and last pointer */71  struct RowSetEntry *p = gRowSet->pEntry;72  for(size_t i=0;i<sizeof(vals)/sizeof(vals[0]);i++){73    TEST_ASSERT_NOT_NULL(p);74    TEST_ASSERT(p->v == vals[i]);75    if( i < (sizeof(vals)/sizeof(vals[0]))-1 ){76      TEST_ASSERT_NOT_NULL(p->pRight);77    }78    p = p->pRight;79  }80  TEST_ASSERT_NULL(p);81  TEST_ASSERT_NOT_NULL(gRowSet->pLast);82  TEST_ASSERT(gRowSet->pLast->v == vals[sizeof(vals)/sizeof(vals[0]) - 1]);83  TEST_ASSERT_NULL(gRowSet->pLast->pRight);84}85 86void test_sqlite3RowSetInsert_equal_value_clears_sorted_flag(void){87  rs_create();88 89  sqlite3RowSetInsert(gRowSet, (i64)5);90  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0); /* still sorted */91 92  sqlite3RowSetInsert(gRowSet, (i64)5);93  /* Equal to last should clear the sorted flag */94  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) == 0);95 96  /* Verify list is [5,5] */97  struct RowSetEntry *p = gRowSet->pEntry;98  TEST_ASSERT_NOT_NULL(p);99  TEST_ASSERT(p->v == (i64)5);100  TEST_ASSERT_NOT_NULL(p->pRight);101  TEST_ASSERT(p->pRight->v == (i64)5);102  TEST_ASSERT_NULL(p->pRight->pRight);103}104 105void test_sqlite3RowSetInsert_decreasing_value_clears_sorted_flag(void){106  rs_create();107 108  sqlite3RowSetInsert(gRowSet, (i64)10);109  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0);110 111  sqlite3RowSetInsert(gRowSet, (i64)9);112  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) == 0);113 114  /* Verify list is [10,9] */115  struct RowSetEntry *p = gRowSet->pEntry;116  TEST_ASSERT_NOT_NULL(p);117  TEST_ASSERT(p->v == (i64)10);118  TEST_ASSERT_NOT_NULL(p->pRight);119  TEST_ASSERT(p->pRight->v == (i64)9);120  TEST_ASSERT_NULL(p->pRight->pRight);121}122 123void test_sqlite3RowSetInsert_mixed_sequence_flag_transitions(void){124  rs_create();125 126  sqlite3RowSetInsert(gRowSet, (i64)1);127  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0);128 129  sqlite3RowSetInsert(gRowSet, (i64)3);130  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0);131 132  sqlite3RowSetInsert(gRowSet, (i64)2);133  /* Inserting 2 after 3 should clear the sorted flag */134  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) == 0);135 136  /* Verify list order is insertion order [1,3,2] */137  struct RowSetEntry *p = gRowSet->pEntry;138  TEST_ASSERT_NOT_NULL(p);139  TEST_ASSERT(p->v == (i64)1);140  p = p->pRight; TEST_ASSERT_NOT_NULL(p); TEST_ASSERT(p->v == (i64)3);141  p = p->pRight; TEST_ASSERT_NOT_NULL(p); TEST_ASSERT(p->v == (i64)2);142  TEST_ASSERT_NULL(p->pRight);143}144 145void test_sqlite3RowSetInsert_allocation_chunk_after_inline_pool_exhaustion(void){146  rs_create();147 148  /* Capture initial inline fresh-entry pool size */149  unsigned initialFresh = gRowSet->nFresh;150 151  /* Consume all inline entries (if any), but do not trigger chunk alloc yet */152  for(unsigned i = 0; i < initialFresh; i++){153    sqlite3RowSetInsert(gRowSet, (i64)i);154  }155  /* No chunk should be allocated until we try to allocate with nFresh==0 */156  TEST_ASSERT_NULL(gRowSet->pChunk);157 158  /* One more insert should force allocation of a chunk for entries */159  sqlite3RowSetInsert(gRowSet, (i64)7777);160  TEST_ASSERT_NOT_NULL(gRowSet->pChunk);161  TEST_ASSERT_NOT_NULL(gRowSet->pLast);162  TEST_ASSERT(gRowSet->pLast->v == (i64)7777);163}164 165void test_sqlite3RowSetInsert_extreme_values_and_sorted_order_via_next(void){166  rs_create();167 168  const i64 a[] = { (i64)LLONG_MIN, (i64)0, (i64)LLONG_MAX };169  for(size_t i=0;i<3;i++){170    sqlite3RowSetInsert(gRowSet, a[i]);171    TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0);172  }173 174  /* Verify that iteration returns them in the same (sorted) order */175  i64 out = 0;176  int rc;177  for(size_t i=0;i<3;i++){178    rc = sqlite3RowSetNext(gRowSet, &out);179    TEST_ASSERT_EQUAL_INT(1, rc);180    TEST_ASSERT(out == a[i]);181  }182  rc = sqlite3RowSetNext(gRowSet, &out);183  TEST_ASSERT_EQUAL_INT(0, rc);184  /* After draining, RowSet should be cleared */185  TEST_ASSERT_NULL(gRowSet->pEntry);186  TEST_ASSERT_NULL(gRowSet->pChunk);187  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0);188}189 190void test_sqlite3RowSetInsert_unsorted_then_next_sorts_and_clears_memory(void){191  rs_create();192 193  /* Unsorted with duplicates */194  const i64 inVals[] = {5, 3, 3, 4};195  for(size_t i=0;i<sizeof(inVals)/sizeof(inVals[0]);i++){196    sqlite3RowSetInsert(gRowSet, inVals[i]);197  }198  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) == 0);199 200  /* Next should produce sorted unique sequence: 3,4,5 */201  i64 out;202  int rc;203 204  rc = sqlite3RowSetNext(gRowSet, &out);205  TEST_ASSERT_EQUAL_INT(1, rc);206  TEST_ASSERT(out == (i64)3);207 208  rc = sqlite3RowSetNext(gRowSet, &out);209  TEST_ASSERT_EQUAL_INT(1, rc);210  TEST_ASSERT(out == (i64)4);211 212  rc = sqlite3RowSetNext(gRowSet, &out);213  TEST_ASSERT_EQUAL_INT(1, rc);214  TEST_ASSERT(out == (i64)5);215 216  rc = sqlite3RowSetNext(gRowSet, &out);217  TEST_ASSERT_EQUAL_INT(0, rc);218 219  /* Memory should be cleared by sqlite3RowSetNext at end */220  TEST_ASSERT_NULL(gRowSet->pEntry);221  TEST_ASSERT_NULL(gRowSet->pChunk);222  TEST_ASSERT((gRowSet->rsFlags & ROWSET_SORTED) != 0);223}224 225/* Main */226int main(void) {227  UNITY_BEGIN();228  RUN_TEST(test_sqlite3RowSetInsert_first_insert_initial_conditions);229  RUN_TEST(test_sqlite3RowSetInsert_increasing_keeps_sorted_and_links_correct);230  RUN_TEST(test_sqlite3RowSetInsert_equal_value_clears_sorted_flag);231  RUN_TEST(test_sqlite3RowSetInsert_decreasing_value_clears_sorted_flag);232  RUN_TEST(test_sqlite3RowSetInsert_mixed_sequence_flag_transitions);233  RUN_TEST(test_sqlite3RowSetInsert_allocation_chunk_after_inline_pool_exhaustion);234  RUN_TEST(test_sqlite3RowSetInsert_extreme_values_and_sorted_order_via_next);235  RUN_TEST(test_sqlite3RowSetInsert_unsorted_then_next_sorts_and_clears_memory);236  return UNITY_END();237}